Skip to content

Instantly share code, notes, and snippets.

@metaleap
Created October 25, 2012 05:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save metaleap/3950516 to your computer and use it in GitHub Desktop.
Save metaleap/3950516 to your computer and use it in GitHub Desktop.
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
Copy link
Author

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