Минимальная Go Ошибка сегментации программы OpenGL - PullRequest
2 голосов
/ 09 февраля 2020

LearnOpenGL.com имеет учебник «Окно приветствия» здесь .

В конце учебника есть ссылка на исходный код здесь . Я попытался перенести это на Go. Согласно учебному пособию, результатом должно быть окно с неизменной плоской цветовой заливкой. Вместо этого я получаю ошибку сегментации. Трассировка стека указывает на эту строку:

gl.ClearColor(0.2, 0.3, 0.3, 1.0)

Мои вопросы: есть ли пропущенное состояние GL, которое необходимо настроить перед вызовом gl.ClearColor в Go программе OpenGL, и почему пример C работает здесь, а пример Go не работает?

Я запускаю этот код на Fedora 31 Desktop, Cinnamon Spin. Моя Go версия - 1.13.7.

Минимальный воспроизводимый код:

package main

import (
    "fmt"
    "log"
    "runtime"

    "github.com/go-gl/gl/v3.3-core/gl"
    "github.com/go-gl/glfw/v3.3/glfw"
)

func init() {
    runtime.LockOSThread()
}

func KeyHandler(w *glfw.Window, key glfw.Key, scan int, action glfw.Action, mods glfw.ModifierKey) {
    if key == glfw.KeyEscape && action == glfw.Press {
        fmt.Println("Escape pressed")
        w.SetShouldClose(true)
    }
}

func Resize(w *glfw.Window, width int, height int) {
    gl.Viewport(0, 0, int32(width), int32(height))
}

func main() {
    err := glfw.Init()
    if err != nil {
        log.Fatalln(err)
    }
    defer glfw.Terminate()
    glfw.WindowHint(glfw.ContextVersionMajor, 3)
    glfw.WindowHint(glfw.ContextVersionMinor, 3)
    glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
    wwidth, wheight := 800, 600
    w, err := glfw.CreateWindow(wheight, wwidth, "example", nil, nil)
    if err != nil {
        log.Fatalf("Failed to create window: %s", err)
    }
    w.MakeContextCurrent()
    w.SetFramebufferSizeCallback(Resize)
    glfw.SwapInterval(1)
    w.SetKeyCallback(KeyHandler)
    for !w.ShouldClose() {
        gl.ClearColor(0.2, 0.3, 0.3, 1.0)
        gl.Clear(gl.COLOR_BUFFER_BIT)
        w.SwapBuffers()
        glfw.PollEvents()
    }
}

Трассировка стека:

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x0]

runtime stack:
runtime.throw(0x525f18, 0x2a)
    /usr/local/go/src/runtime/panic.go:774 +0x72
runtime.sigpanic()
    /usr/local/go/src/runtime/signal_unix.go:378 +0x47c
runtime.asmcgocall(0x4761f1, 0x1)
    /usr/local/go/src/runtime/asm_amd64.s:659 +0x70

goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x4c51b0, 0xc000052eb8, 0x0)
    /usr/local/go/src/runtime/cgocall.go:128 +0x5b fp=0xc000052e88 sp=0xc000052e50 pc=0x4275db
github.com/go-gl/gl/v3.3-core/gl._Cfunc_glowClearColor(0x0, 0x3e99999a3e4ccccd, 0x3f8000003e99999a)
    _cgo_gotypes.go:3778 +0x45 fp=0xc000052eb8 sp=0xc000052e88 pc=0x4be1e5
github.com/go-gl/gl/v3.3-core/gl.ClearColor(...)
    /home/jrefior/home/go/pkg/mod/github.com/go-gl/gl@v0.0.0-20190320180904-bf2b1f2f34d7/v3.3-core/gl/package.go:8700
main.main()
    /home/jrefior/home/opengl/window01/main.go:46 +0x235 fp=0xc000052f60 sp=0xc000052eb8 pc=0x4c4915
runtime.main()
    /usr/local/go/src/runtime/proc.go:203 +0x21e fp=0xc000052fe0 sp=0xc000052f60 pc=0x4505fe
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc000052fe8 sp=0xc000052fe0 pc=0x478cc1

1 Ответ

3 голосов
/ 09 февраля 2020

Вы неправильно инициализируете привязки Go GL. В документации четко указано:

import "github.com/go-gl/gl/v3.3-core/gl"

func main() {
  window := ... // Open a window.
  window.MakeContextCurrent()

  // Important! Call gl.Init only under the presence of an active OpenGL context,
  // i.e., after MakeContextCurrent.
  if err := gl.Init(); err != nil {
      log.Fatalln(err)
  }
}

Функция init запрашивает указатели функций для всех функций GL (которые на windows зависят от контекста GL, поэтому он требует текущего контекста GL). Обратите внимание, что учебник, который вы связали, использует gladLoadGLLoader для той же цели, просто через код, сгенерированный генератором загрузчика glad GL .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...