Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Simple OpenGL 2D drawing
package main
import (
"fmt"
"strings"
gl "github.com/chsc/gogl/gl42"
glfw "github.com/go-gl/glfw"
glutil "github.com/go3d/go-util/gl"
)
type tGeometry struct {
glVerts []gl.Float
glNumVerts gl.Sizei
glMode gl.Enum
glVertBuf gl.Uint
}
var (
faceTri, faceQuad = &tGeometry {}, &tGeometry {}
useStrictCoreProfile = false // set this to true to see the problem...
isFirstLoop = true // only output glLastError in the loop's first iteration
lastErr error
shaderProg *glutil.TShaderProgram
srcVertShader = "in vec3 aPos; void main () { gl_Position = vec4(aPos, 1.0); }"
srcFragShader = "out vec4 oColor; void main () { oColor = vec4(0.0, 0.6, 0.9, 1.0); }"
)
func compileShaders () (err error) {
var glStatus gl.Int
var glFrag = gl.CreateShader(gl.FRAGMENT_SHADER)
var glVert = gl.CreateShader(gl.VERTEX_SHADER)
glutil.ShaderSource("test", glFrag, srcFragShader, nil, false, "150")
gl.CompileShader(glFrag)
if gl.GetShaderiv(glFrag, gl.COMPILE_STATUS, &glStatus); glStatus == 0 {
err = fmt.Errorf("SHADER %s: %s\n", "Frag", glutil.ShaderInfoLog(glFrag, true)); return
}
glutil.ShaderSource("test", glVert, srcVertShader, nil, false, "150")
gl.CompileShader(glVert)
if gl.GetShaderiv(glVert, gl.COMPILE_STATUS, &glStatus); glStatus == 0 {
err = fmt.Errorf("SHADER %s: %s\n", "Vert", glutil.ShaderInfoLog(glVert, true)); return
}
if shaderProg, err = glutil.NewShaderProgram("test", 0, glFrag, 0, 0, 0, glVert); err == nil {
err = shaderProg.SetAttrLocations("aPos")
}
return
}
func deleteGeometry () {
gl.DeleteBuffers(1, &faceTri.glVertBuf)
gl.DeleteBuffers(1, &faceQuad.glVertBuf)
}
func renderGeometry (mesh *tGeometry) {
gl.BindBuffer(gl.ARRAY_BUFFER, mesh.glVertBuf)
if isFirstLoop { logLastGlError("render.BindBuffer(buf)") }
gl.VertexAttribPointer(shaderProg.AttrLocs["aPos"], 3, gl.FLOAT, gl.FALSE, 0, gl.Pointer(nil))
if isFirstLoop { logLastGlError("render.VertexAttribPointer()") }
gl.DrawArrays(mesh.glMode, 0, mesh.glNumVerts)
if isFirstLoop { logLastGlError("render.DrawArrays()") }
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
if isFirstLoop { logLastGlError("render.BindBuffer(0)") }
}
func setupGeometry () {
var z gl.Float = -1
faceTri.glMode, faceTri.glNumVerts, faceTri.glVerts = gl.TRIANGLES, 3, []gl.Float {
0, 1, z,
-1, -1, z,
1, -1, z,
}
uploadGeometry(faceTri)
faceQuad.glMode, faceQuad.glNumVerts, faceQuad.glVerts = gl.TRIANGLE_STRIP, 4, []gl.Float {
0.5, 0.5, z,
-0.5, 0.5, z,
0.5, -0.5, z,
-0.5, -0.5, z,
}
uploadGeometry(faceQuad)
}
func uploadGeometry (mesh *tGeometry) {
gl.GenBuffers(1, &mesh.glVertBuf)
gl.BindBuffer(gl.ARRAY_BUFFER, mesh.glVertBuf)
gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(4 * len(mesh.glVerts)), gl.Pointer(&mesh.glVerts[0]), gl.STATIC_DRAW)
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
}
func logLastGlError (step string) {
if lastErr = glutil.LastError(step); lastErr != nil { fmt.Printf("LASTERR: %v\n", lastErr) }
}
func main () {
var err error
var looping = true
defer fmt.Println("EXIT")
if err = glfw.Init(); err != nil { panic(err) }
defer glfw.Terminate()
glfw.OpenWindowHint(glfw.FsaaSamples, 0)
if useStrictCoreProfile {
glfw.OpenWindowHint(glfw.OpenGLVersionMajor, 3)
glfw.OpenWindowHint(glfw.OpenGLVersionMinor, 2)
glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
// if runtime.GOOS == "darwin" { glfw.OpenWindowHint(glfw.OpenGLForwardCompat, 1) }
}
if err = glfw.OpenWindow(1280, 720, 8, 8, 8, 0, 24, 8, glfw.Windowed); err != nil { panic(err) }
defer glfw.CloseWindow()
glfw.Enable(glfw.StickyKeys)
if err = gl.Init(); (err != nil) && (strings.Index(err.Error(), "VERSION_") < 0) { panic(err) }
defer logLastGlError("(post loop)")
glutil.SetVersion()
fmt.Printf("GLCONN: %v\n", glutil.GlConnInfo())
gl.ClearColor(0.3, 0.1, 0.0, 1.0)
gl.Enable(gl.DEPTH_TEST)
gl.FrontFace(gl.CCW)
gl.CullFace(gl.BACK)
gl.Disable(gl.CULL_FACE)
if err = compileShaders(); err != nil { panic(err) }
setupGeometry()
logLastGlError("(pre loop)")
for looping {
gl.UseProgram(shaderProg.Program)
if isFirstLoop { logLastGlError("gl.UseProgram") }
gl.Viewport(0, 0, 1280, 720)
if isFirstLoop { logLastGlError("gl.ViewPort") }
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
if isFirstLoop { logLastGlError("gl.Clear") }
renderGeometry(faceTri)
renderGeometry(faceQuad)
if (glfw.WindowParam(glfw.Opened) != 1) || (glfw.Key(glfw.KeyEsc) == glfw.KeyPress) {
looping = false
} else {
glfw.SwapBuffers()
}
isFirstLoop = false
}
}
@metaleap
Owner

With useStrictCoreProfile set to false, the program outputs no error messages to the console and draws a quad and a triangle: http://dl.dropbox.com/u/136375/gl-quad-tri.png

With useStrictCoreProfile set to true, it clears the background color but does not draw the tri & quad, console output is this:

GLCONN: OpenGL 3.2.0 @ NVIDIA Corporation GeForce GT 640M LE/PCIe/SSE2 (GLSL: 1.50 NVIDIA via Cg compiler)
LASTERR: OpenGL error at step 'render.VertexAttribPointer()':   GL_INVALID_OPERATION
LASTERR: OpenGL error at step 'render.DrawArrays()':    GL_INVALID_OPERATION
LASTERR: OpenGL error at step 'render.VertexAttribPointer()':   GL_INVALID_OPERATION
LASTERR: OpenGL error at step 'render.DrawArrays()':    GL_INVALID_OPERATION
LASTERR: OpenGL error at step '(post loop)':    GL_INVALID_OPERATION
EXIT

... if a 4.2 strict core profile is requested instead of 3.2, same issue. Applies to 3 different nvidia GPUs so I assume I'm not conforming to the strict core profile properly.

@metaleap
Owner

Note, you won't find a glEnableVertexAttribArray call in the above Gist, as it's inside the glutil package I'm importing -- but this does get called as the last step in this Gist's compileShaders() func.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.