去go-gl OpenGL渲染问题

时间:2016-06-17 03:20:08

标签: opengl go opengl-4

我有一个原本完全正常工作的程序,可以使用go-gl OpenGL包装器绘制一个三角形。在玩代码的过程中,事情开始变得怪异。有时形状会被渲染,然后就不会了。有时保存文件然后再次运行代码会有效,有时候也会失败。在此过程中,文件从工作到损坏没有任何更改。 glfw窗口仍显示背景颜色,并填充我使用的顶点数组。我不确定这是否是我的代码中的一个简单错误,或者它是否与硬件相关。

不确定这是否有帮助,但我使用最新的Atom编辑器和Go-Plus插件。在此先感谢您的帮助!

package main

import (
    "fmt"
    "log"
    "runtime"

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

const vertexSource = `
#version 330
in vec2 position;
void main() {
    gl_Position = vec4(position,0.0, 1.0);
}
` + "\x00"

const fragmentSource = `
#version 330
uniform vec3 triangleColor;
out vec4 outputColor;
void main() {
    outputColor = vec4(triangleColor,1.0);
}
` + "\x00"

var vao, vbo uint32
var vertices = []float32{
    0.0, 0.5,
    0.5, -0.5,
    -0.5, -0.5,
}

func init() {
    runtime.LockOSThread()
}

func main() {
    if err := glfw.Init(); err != nil {
        log.Fatalln("failed to initalize GL window:", err)
    }
    defer glfw.Terminate()

    glfw.WindowHint(glfw.Resizable, glfw.True)
    glfw.WindowHint(glfw.ContextVersionMajor, 4)
    glfw.WindowHint(glfw.ContextVersionMinor, 1)
    glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
    glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)

    windowHeight := 800
    windowWidth := 800

    window, err := glfw.CreateWindow(windowWidth, windowHeight, "HelloGL2.0", nil, nil)
    if err != nil {
        panic(err)
    }
    window.MakeContextCurrent()

    if err := gl.Init(); err != nil {
        panic(err)
    } else {
        fmt.Println("OpenGL Version:", gl.GoStr(gl.GetString(gl.VERSION)))
    }

    gl.GenVertexArrays(1, &vao)
    gl.BindVertexArray(vao)

    gl.GenBuffers(1, &vbo)

    gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
    gl.BufferData(gl.ARRAY_BUFFER, len(vertices), gl.Ptr(vertices), gl.STREAM_DRAW)

    vertexShader := gl.CreateShader(gl.VERTEX_SHADER)
    vcsources, free := gl.Strs(vertexSource)
    gl.ShaderSource(vertexShader, 1, vcsources, nil)
    free()
    gl.CompileShader(vertexShader)
    fragmentShader := gl.CreateShader(gl.FRAGMENT_SHADER)
    fcsources, free := gl.Strs(fragmentSource)
    gl.ShaderSource(fragmentShader, 1, fcsources, nil)
    gl.CompileShader(fragmentShader)

    shaderProgram := gl.CreateProgram()
    gl.AttachShader(shaderProgram, vertexShader)
    gl.AttachShader(shaderProgram, fragmentShader)
    gl.BindFragDataLocation(shaderProgram, 0, gl.Str("outputColor\x00"))
    gl.LinkProgram(shaderProgram)
    gl.UseProgram(shaderProgram)

    posAttrib := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("position\x00")))
    gl.EnableVertexAttribArray(posAttrib)
    gl.VertexAttribPointer(posAttrib, 2.0, gl.FLOAT, false, 0.0, gl.PtrOffset(0))

    gl.GetUniformLocation(shaderProgram, gl.Str("triangleColor\x00"))

    //GL_STATIC_DRAW: The vertex data will be uploaded once and drawn many times (e.g. the world).
    //GL_DYNAMIC_DRAW: The vertex data will be changed from time to time, but drawn many times more than that.
    //GL_STREAM_DRAW: The vertex data will change almost every time it's drawn (e.g. user interface).

    for !window.ShouldClose() {
        //gl.Uniform3f(uniColor, 2.0, 0.0, 1.0)

        gl.ClearColor(0.9, 1.0, 0.3, 1.0)
        gl.Clear(gl.COLOR_BUFFER_BIT)

        gl.DrawArrays(gl.TRIANGLES, 0, 3)

        window.SwapBuffers()
        glfw.PollEvents()
    }

    gl.DeleteProgram(shaderProgram)
    gl.DeleteShader(fragmentShader)
    gl.DeleteShader(vertexShader)
    gl.DeleteBuffers(1, &vbo)
    gl.DeleteVertexArrays(1, &vao)

    fmt.Println("Exiting!")

    window.Destroy()

}

1 个答案:

答案 0 :(得分:0)

你的代码给了我:

./gl.go:76: undefined: gl.Strs
./gl.go:81: undefined: gl.Strs

考虑使用我的代码加载和编译着色器:

func NewProgram(vertexShaderSource, fragmentShaderSource string) (uint32, error) {
    vertexShader, err := CompileShader(vertexShaderSource, gl.VERTEX_SHADER)
    if err != nil {
        return 0, err
    }

    fragmentShader, err := CompileShader(fragmentShaderSource, gl.FRAGMENT_SHADER)
    if err != nil {
        return 0, err
    }

    program := gl.CreateProgram()

    gl.AttachShader(program, vertexShader)
    gl.AttachShader(program, fragmentShader)
    gl.LinkProgram(program)

    var status int32
    gl.GetProgramiv(program, gl.LINK_STATUS, &status)
    if status == gl.FALSE {
        var logLength int32
        gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength)

        log := strings.Repeat("\x00", int(logLength+1))
        gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log))

        return 0, errors.New(fmt.Sprintf("failed to link program: %v", log))
    }

    gl.DeleteShader(vertexShader)
    gl.DeleteShader(fragmentShader)

    return program, nil
}

func CompileShader(source string, shaderType uint32) (uint32, error) {
    shader := gl.CreateShader(shaderType)

    csource := gl.Str(source)
    gl.ShaderSource(shader, 1, &csource, nil)
    gl.CompileShader(shader)

    var status int32
    gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status)
    if status == gl.FALSE {
        var logLength int32
        gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength)

        log := strings.Repeat("\x00", int(logLength+1))
        gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log))

        return 0, fmt.Errorf("failed to compile %v: %v", source, log)
    }

    return shader, nil
}