func main() { if err := glfw.Init(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } defer glfw.Terminate() glfw.OpenWindowHint(glfw.FsaaSamples, 4) glfw.OpenWindowHint(glfw.OpenGLVersionMajor, 3) glfw.OpenWindowHint(glfw.OpenGLVersionMinor, 3) glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) if err := glfw.OpenWindow(1024, 768, 0, 0, 0, 0, 32, 0, glfw.Windowed); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } gl.Init() gl.GetError() // Ignore error glfw.SetWindowTitle("Tutorial 01") glfw.Enable(glfw.StickyKeys) gl.ClearColor(0., 0., 0.4, 0.) // Equivalent to a do... while for ok := true; ok; ok = (glfw.Key(glfw.KeyEsc) != glfw.KeyPress && glfw.WindowParam(glfw.Opened) == gl.TRUE) { glfw.SwapBuffers() } }
func main() { if err := glfw.Init(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } defer glfw.Terminate() glfw.OpenWindowHint(glfw.FsaaSamples, 4) glfw.OpenWindowHint(glfw.OpenGLVersionMajor, 3) glfw.OpenWindowHint(glfw.OpenGLVersionMinor, 3) glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) if err := glfw.OpenWindow(1024, 768, 0, 0, 0, 0, 32, 0, glfw.Windowed); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } gl.Init() // Can't find gl.GLEW_OK or any variation, not sure how to check if this worked gl.GetError() // Ignore error glfw.SetWindowTitle("Tutorial 02") glfw.Enable(glfw.StickyKeys) gl.ClearColor(0., 0., 0.4, 0.) prog := helper.MakeProgram("SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader") vBufferData := [...]float32{ -1., -1., 0., 1., -1., 0., 0., 1., 0.} vertexArray := gl.GenVertexArray() vertexArray.Bind() buffer := gl.GenBuffer() buffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, len(vBufferData)*4, &vBufferData, gl.STATIC_DRAW) // Equivalent to a do... while for ok := true; ok; ok = (glfw.Key(glfw.KeyEsc) != glfw.KeyPress && glfw.WindowParam(glfw.Opened) == gl.TRUE) { gl.Clear(gl.COLOR_BUFFER_BIT) prog.Use() attribLoc := gl.AttribLocation(0) attribLoc.EnableArray() buffer.Bind(gl.ARRAY_BUFFER) attribLoc.AttribPointer(3, gl.FLOAT, false, 0, nil) gl.DrawArrays(gl.TRIANGLES, 0, 3) attribLoc.DisableArray() glfw.SwapBuffers() } }
func main() { var err error if err = glfw.Init(); err != nil { fmt.Fprintf(os.Stderr, "[e] %v\n", err) return } // Ensure glfw is cleanly terminated on exit. defer glfw.Terminate() if err = glfw.OpenWindow(256, 256, 8, 8, 8, 0, 0, 0, glfw.Windowed); err != nil { fmt.Fprintf(os.Stderr, "[e] %v\n", err) return } // Ensure window is cleanly closed on exit. defer glfw.CloseWindow() // Enable vertical sync on cards that support it. glfw.SetSwapInterval(1) // Set window title glfw.SetWindowTitle("Simple GLFW window") // Hook some events to demonstrate use of callbacks. // These are not necessary if you don't need them. glfw.SetWindowSizeCallback(onResize) glfw.SetWindowCloseCallback(onClose) glfw.SetMouseButtonCallback(onMouseBtn) glfw.SetMouseWheelCallback(onMouseWheel) glfw.SetKeyCallback(onKey) glfw.SetCharCallback(onChar) // Start loop running := true for running { // OpenGL rendering goes here. // Swap front and back rendering buffers. This also implicitly calls // glfw.PollEvents(), so we have valid key/mouse/joystick states after // this. This behavior can be disabled by calling glfw.Disable with the // argument glfw.AutoPollEvents. You must be sure to manually call // PollEvents() or WaitEvents() in this case. glfw.SwapBuffers() // Break out of loop when Escape key is pressed, or window is closed. running = glfw.Key(glfw.KeyEsc) == 0 && glfw.WindowParam(glfw.Opened) == 1 } }
func Run() { running = true for running { start := time.Now() escPressed := glfw.Key(glfw.KeyEsc) windowOpen := glfw.WindowParam(glfw.Opened) running = escPressed == 0 && windowOpen == 1 select { case data := <-ScreenOutputChan: drawFrame(data.Pixels) drawInfoBox(3, 3, 12, data.IterNr, data.NThreads, data.ExecTime) glfw.SwapBuffers() default: // Non blocking! glfw.PollEvents() } // Limit to 60hz elapsed := time.Since(start) timeToSleep := 16*time.Millisecond - elapsed if timeToSleep > 0 { time.Sleep(timeToSleep) } } }
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 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 !gl.Util.Init() { panic("Failed to initialize at least OpenGL 3.2 or higher.") } defer logLastGlError("(post loop)") 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() defer deleteGeometry() logLastGlError("(pre loop)") for looping { gl.UseProgram(shaderProg) 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) if isFirstLoop { logLastGlError("renderGeometry(faceTri)") } renderGeometry(faceQuad) if isFirstLoop { logLastGlError("renderGeometry(faceQuad)") } if (glfw.WindowParam(glfw.Opened) != 1) || (glfw.Key(glfw.KeyEsc) == glfw.KeyPress) { looping = false } else { glfw.SwapBuffers() } isFirstLoop = false } logLastGlError("post-loop") }
func main() { if err := glfw.Init(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } defer glfw.Terminate() glfw.OpenWindowHint(glfw.FsaaSamples, 4) glfw.OpenWindowHint(glfw.OpenGLVersionMajor, 3) glfw.OpenWindowHint(glfw.OpenGLVersionMinor, 3) glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) if err := glfw.OpenWindow(1024, 768, 0, 0, 0, 0, 32, 0, glfw.Windowed); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } glfw.SetSwapInterval(0) //gl.GlewExperimental(true) gl.Init() // Can't find gl.GLEW_OK or any variation, not sure how to check if this worked gl.GetError() // ignore error, since we're telling it to use CoreProfile above, we get "invalid enumerant" (GLError 1280) which freaks the OpenGLSentinel out glfw.SetWindowTitle("Tutorial 07") glfw.Enable(glfw.StickyKeys) glfw.Disable(glfw.MouseCursor) // Not in the original tutorial, but IMO it SHOULD be there glfw.SetMousePos(1024.0/2.0, 768.0/2.0) gl.ClearColor(0., 0., 0.4, 0.) gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.Enable(gl.CULL_FACE) camera := input.NewCamera() vertexArray := gl.GenVertexArray() defer vertexArray.Delete() vertexArray.Bind() prog := helper.MakeProgram("TransformVertexShader.vertexshader", "TextureFragmentShader.fragmentshader") defer prog.Delete() matrixID := prog.GetUniformLocation("MVP") texture := helper.MakeTextureFromTGA("uvmap.tga") // Had to convert to tga, go-gl is missing the texture method for DDS right now defer texture.Delete() texSampler := prog.GetUniformLocation("myTextureSampler") meshObj := objloader.LoadObject("cube.obj") vertices, uvs := meshObj.Vertices, meshObj.UVs vertexBuffer := gl.GenBuffer() defer vertexBuffer.Delete() vertexBuffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*3*4, vertices, gl.STATIC_DRAW) uvBuffer := gl.GenBuffer() defer uvBuffer.Delete() uvBuffer.Bind(gl.ARRAY_BUFFER) // UV doesn't seem to care gl.BufferData(gl.ARRAY_BUFFER, len(uvs)*2*4, uvs, gl.STATIC_DRAW) // Equivalent to a do... while for ok := true; ok; ok = (glfw.Key(glfw.KeyEsc) != glfw.KeyPress && glfw.WindowParam(glfw.Opened) == gl.TRUE && glfw.Key('Q') != glfw.KeyPress) { func() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) prog.Use() defer gl.ProgramUnuse() view, proj := camera.ComputeViewPerspective() model := mathgl.Ident4f() MVP := proj.Mul4(view).Mul4(model) matrixID.UniformMatrix4fv(false, MVP) gl.ActiveTexture(gl.TEXTURE0) texture.Bind(gl.TEXTURE_2D) defer texture.Unbind(gl.TEXTURE_2D) texSampler.Uniform1i(0) vertexAttrib := gl.AttribLocation(0) vertexAttrib.EnableArray() defer vertexAttrib.DisableArray() vertexBuffer.Bind(gl.ARRAY_BUFFER) defer vertexBuffer.Unbind(gl.ARRAY_BUFFER) vertexAttrib.AttribPointer(3, gl.FLOAT, false, 0, nil) uvAttrib := gl.AttribLocation(1) uvAttrib.EnableArray() defer uvAttrib.DisableArray() uvBuffer.Bind(gl.ARRAY_BUFFER) defer uvBuffer.Unbind(gl.ARRAY_BUFFER) uvAttrib.AttribPointer(2, gl.FLOAT, false, 0, nil) gl.DrawArrays(gl.TRIANGLES, 0, len(vertices)) glfw.SwapBuffers() }() // Defers unbinds and disables to here, end of the loop } }
// Check whether a key is pressed. func (c *Controller) Key(key int) int { return glfw.Key(key) }
func New(width int, height int, title string) *Window { var err error window := &Window{width: width, height: height, title: title} // initialize logger logf, err := os.OpenFile("window.log", os.O_WRONLY|os.O_CREATE, 0640) logger := log.New(logf, "", log.Ldate|log.Ltime) if err = glfw.Init(); err != nil { fmt.Fprintf(os.Stderr, "[e] %v\n", err) return nil } // width, hieght, r,g,b,a (color depth bits), depth, stencil, mode if err = glfw.OpenWindow(window.width, window.height, 8, 8, 8, 0, 0, 0, glfw.Windowed); err != nil { fmt.Fprintf(os.Stderr, "[e] %v\n", err) return nil } onResize := func(w, h int) { logger.Printf("resized: %dx%d\n", w, h) } onClose := func() int { logger.Println("window closed\n") return 1 // return 0 to keep window open. } // list callback generators createBtnList := func(btnNext func() interface{}, device string) func(button, state int) { btnList := list.New() btnNext = func() interface{} { return btnList.Remove(btnList.Back()) } return func(button, state int) { btnList.PushFront(btnEvent{button: button, state: state}) logger.Printf("%s button: %d, %d\n", device, button, state) } } createPosList := func(posNext func() interface{}, device string) func(x, y int) { posList := list.New() posNext = func() interface{} { return posList.Remove(posList.Back()) } return func(x, y int) { posList.PushFront(posEvent{x: x, y: y}) logger.Printf("%s pos: %d, %d\n", device, x, y) } } createDeltaList := func(deltaNext func() interface{}, device string) func(delta int) { deltaList := list.New() deltaNext = func() interface{} { return deltaList.Remove(deltaList.Back()) } return func(delta int) { deltaList.PushFront(deltaEvent{delta: delta}) logger.Printf("%s delta: %d\n", device, delta) } } glfw.SetSwapInterval(1) glfw.SetWindowTitle(title) glfw.SetWindowSizeCallback(onResize) glfw.SetWindowCloseCallback(onClose) glfw.SetMousePosCallback(createPosList(window.MousePos, "mouse pos")) glfw.SetMouseButtonCallback(createBtnList(window.MouseBtn, "mouse")) glfw.SetMouseWheelCallback(createDeltaList(window.MouseWheel, "mouse wheel")) glfw.SetKeyCallback(createBtnList(window.KeyEvt, "keyboard")) glfw.SetCharCallback(createBtnList(window.CharEvt, "char")) window.Start = func() { defer glfw.Terminate() defer glfw.CloseWindow() running := true for running { window.Render() glfw.SwapBuffers() // Break out of loop when Escape key is pressed, or window is closed. running = glfw.Key(glfw.KeyEsc) == 0 && glfw.WindowParam(glfw.Opened) == 1 } } return window }
func main() { if err := glfw.Init(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } defer glfw.Terminate() glfw.OpenWindowHint(glfw.FsaaSamples, 4) glfw.OpenWindowHint(glfw.OpenGLVersionMajor, 3) glfw.OpenWindowHint(glfw.OpenGLVersionMinor, 3) glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) if err := glfw.OpenWindow(1024, 768, 0, 0, 0, 0, 32, 0, glfw.Windowed); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } gl.Init() gl.GetError() // Ignore error glfw.SetWindowTitle("Tutorial 04") glfw.Enable(glfw.StickyKeys) gl.ClearColor(0., 0., 0.4, 0.) gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) vertexArray := gl.GenVertexArray() defer vertexArray.Delete() vertexArray.Bind() prog := helper.MakeProgram("TransformVertexShader.vertexshader", "ColorFragmentShader.fragmentshader") defer prog.Delete() matrixID := prog.GetUniformLocation("MVP") Projection := mathgl.Perspective(45.0, 4.0/3.0, 0.1, 100.0) View := mathgl.LookAt(4.0, 3.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) Model := mathgl.Ident4f() MVP := Projection.Mul4(View).Mul4(Model) // Remember, transform multiplication order is "backwards" vBufferData := [...]float32{ -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0} colorBufferData := [...]float32{ 0.583, 0.771, 0.014, 0.609, 0.115, 0.436, 0.327, 0.483, 0.844, 0.822, 0.569, 0.201, 0.435, 0.602, 0.223, 0.310, 0.747, 0.185, 0.597, 0.770, 0.761, 0.559, 0.436, 0.730, 0.359, 0.583, 0.152, 0.483, 0.596, 0.789, 0.559, 0.861, 0.639, 0.195, 0.548, 0.859, 0.014, 0.184, 0.576, 0.771, 0.328, 0.970, 0.406, 0.615, 0.116, 0.676, 0.977, 0.133, 0.971, 0.572, 0.833, 0.140, 0.616, 0.489, 0.997, 0.513, 0.064, 0.945, 0.719, 0.592, 0.543, 0.021, 0.978, 0.279, 0.317, 0.505, 0.167, 0.620, 0.077, 0.347, 0.857, 0.137, 0.055, 0.953, 0.042, 0.714, 0.505, 0.345, 0.783, 0.290, 0.734, 0.722, 0.645, 0.174, 0.302, 0.455, 0.848, 0.225, 0.587, 0.040, 0.517, 0.713, 0.338, 0.053, 0.959, 0.120, 0.393, 0.621, 0.362, 0.673, 0.211, 0.457, 0.820, 0.883, 0.371, 0.982, 0.099, 0.879} //elBufferData := [...]uint8{0, 1, 2} // Not sure why this is here vertexBuffer := gl.GenBuffer() defer vertexBuffer.Delete() vertexBuffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, len(vBufferData)*4, &vBufferData, gl.STATIC_DRAW) colorBuffer := gl.GenBuffer() defer colorBuffer.Delete() colorBuffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, len(colorBufferData)*4, &colorBufferData, gl.STATIC_DRAW) // Equivalent to a do... while for ok := true; ok; ok = (glfw.Key(glfw.KeyEsc) != glfw.KeyPress && glfw.WindowParam(glfw.Opened) == gl.TRUE) { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) prog.Use() matrixID.UniformMatrix4fv(false, MVP) vertexAttrib := gl.AttribLocation(0) vertexAttrib.EnableArray() vertexBuffer.Bind(gl.ARRAY_BUFFER) vertexAttrib.AttribPointer(3, gl.FLOAT, false, 0, nil) colorAttrib := gl.AttribLocation(1) colorAttrib.EnableArray() colorBuffer.Bind(gl.ARRAY_BUFFER) colorAttrib.AttribPointer(3, gl.FLOAT, false, 0, nil) gl.DrawArrays(gl.TRIANGLES, 0, 12*3) vertexAttrib.DisableArray() colorAttrib.DisableArray() glfw.SwapBuffers() } }
// Returns true if the specified key is pressed. func (_ *NgUserIO) KeyPressed(key int) bool { return glfw.Key(key) == glfw.KeyPress }
func main() { if err := glfw.Init(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } defer glfw.Terminate() glfw.OpenWindowHint(glfw.FsaaSamples, 4) glfw.OpenWindowHint(glfw.OpenGLVersionMajor, 3) glfw.OpenWindowHint(glfw.OpenGLVersionMinor, 3) glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) if err := glfw.OpenWindow(1024, 768, 0, 0, 0, 0, 32, 0, glfw.Windowed); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } //gl.GlewExperimental(true) gl.Init() // Can't find gl.GLEW_OK or any variation, not sure how to check if this worked gl.GetError() // ignore error, since we're telling it to use CoreProfile above, we get "invalid enumerant" (GLError 1280) which freaks the OpenGLSentinel out // With go-gl we also apparently can't set glewExperimental glfw.SetWindowTitle("Tutorial 05") glfw.Enable(glfw.StickyKeys) gl.ClearColor(0., 0., 0.4, 0.) gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) vertexArray := gl.GenVertexArray() defer vertexArray.Delete() vertexArray.Bind() prog := helper.MakeProgram("TransformVertexShader.vertexshader", "TextureFragmentShader.fragmentshader") defer prog.Delete() matrixID := prog.GetUniformLocation("MVP") Projection := mathgl.Perspective(45.0, 4.0/3.0, 0.1, 100.0) View := mathgl.LookAt(4.0, 3.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) Model := mathgl.Ident4f() MVP := Projection.Mul4(View).Mul4(Model) // Remember, transform multiplication order is "backwards" texture := helper.MakeTextureFromTGA("uvtemplate.tga") defer texture.Delete() texSampler := prog.GetUniformLocation("myTextureSampler") vBufferData := [...]float32{ -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0} uvBufferData := [...]float32{ 0.000059, 1.0 - 0.000004, 0.000103, 1.0 - 0.336048, 0.335973, 1.0 - 0.335903, 1.000023, 1.0 - 0.000013, 0.667979, 1.0 - 0.335851, 0.999958, 1.0 - 0.336064, 0.667979, 1.0 - 0.335851, 0.336024, 1.0 - 0.671877, 0.667969, 1.0 - 0.671889, 1.000023, 1.0 - 0.000013, 0.668104, 1.0 - 0.000013, 0.667979, 1.0 - 0.335851, 0.000059, 1.0 - 0.000004, 0.335973, 1.0 - 0.335903, 0.336098, 1.0 - 0.000071, 0.667979, 1.0 - 0.335851, 0.335973, 1.0 - 0.335903, 0.336024, 1.0 - 0.671877, 1.000004, 1.0 - 0.671847, 0.999958, 1.0 - 0.336064, 0.667979, 1.0 - 0.335851, 0.668104, 1.0 - 0.000013, 0.335973, 1.0 - 0.335903, 0.667979, 1.0 - 0.335851, 0.335973, 1.0 - 0.335903, 0.668104, 1.0 - 0.000013, 0.336098, 1.0 - 0.000071, 0.000103, 1.0 - 0.336048, 0.000004, 1.0 - 0.671870, 0.336024, 1.0 - 0.671877, 0.000103, 1.0 - 0.336048, 0.336024, 1.0 - 0.671877, 0.335973, 1.0 - 0.335903, 0.667969, 1.0 - 0.671889, 1.000004, 1.0 - 0.671847, 0.667979, 1.0 - 0.335851} vertexBuffer := gl.GenBuffer() defer vertexBuffer.Delete() vertexBuffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, len(vBufferData)*4, &vBufferData, gl.STATIC_DRAW) uvBuffer := gl.GenBuffer() defer uvBuffer.Delete() uvBuffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, len(uvBufferData)*4, &uvBufferData, gl.STATIC_DRAW) // Equivalent to a do... while for ok := true; ok; ok = (glfw.Key(glfw.KeyEsc) != glfw.KeyPress && glfw.WindowParam(glfw.Opened) == gl.TRUE) { func() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) prog.Use() defer gl.ProgramUnuse() matrixID.UniformMatrix4fv(false, MVP) gl.ActiveTexture(gl.TEXTURE0) texture.Bind(gl.TEXTURE_2D) defer texture.Unbind(gl.TEXTURE_2D) texSampler.Uniform1i(0) vertexAttrib := gl.AttribLocation(0) vertexAttrib.EnableArray() defer vertexAttrib.DisableArray() vertexBuffer.Bind(gl.ARRAY_BUFFER) defer vertexBuffer.Unbind(gl.ARRAY_BUFFER) vertexAttrib.AttribPointer(3, gl.FLOAT, false, 0, nil) uvAttrib := gl.AttribLocation(1) uvAttrib.EnableArray() defer uvAttrib.DisableArray() uvBuffer.Bind(gl.ARRAY_BUFFER) defer uvBuffer.Unbind(gl.ARRAY_BUFFER) uvAttrib.AttribPointer(2, gl.FLOAT, false, 0, nil) gl.DrawArrays(gl.TRIANGLES, 0, 12*3) glfw.SwapBuffers() }() // Defers unbinds and disables to here, end of the loop } }
func (me *window) Key(key int) int { return glfw.Key(key) }
func (s *System) CheckExitMainLoop() bool { return (glfw.Key(glfw.KeyEsc) != glfw.KeyPress && glfw.WindowParam(glfw.Opened) == gl.TRUE) }
func IsKeyDown(key int) bool { return glfw.Key(key) == glfw.KeyPress }
func main() { if err := glfw.Init(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } defer glfw.Terminate() glfw.OpenWindowHint(glfw.FsaaSamples, 4) glfw.OpenWindowHint(glfw.OpenGLVersionMajor, 3) glfw.OpenWindowHint(glfw.OpenGLVersionMinor, 3) glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) if err := glfw.OpenWindow(1024, 768, 0, 0, 0, 0, 32, 0, glfw.Windowed); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } gl.Init() // Can't find gl.GLEW_OK or any variation, not sure how to check if this worked gl.GetError() // Ignore error glfw.SetWindowTitle("Tutorial 03") glfw.Enable(glfw.StickyKeys) gl.ClearColor(0., 0., 0.4, 0.) vertexArray := gl.GenVertexArray() defer vertexArray.Delete() vertexArray.Bind() prog := helper.MakeProgram("SimpleTransform.vertexshader", "SingleColor.fragmentshader") defer prog.Delete() matrixID := prog.GetUniformLocation("MVP") Projection := mathgl.Perspective(45.0, 4.0/3.0, 0.1, 100.0) //Projection := mathgl.Identity(4,mathgl.FLOAT64) //Projection := mathgl.Ortho2D(-5,5,-5,5) View := mathgl.LookAt(4.0, 3.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) //View := mathgl.Identity(4,mathgl.FLOAT64) Model := mathgl.Ident4f() //Model := mathgl.Scale3D(2.,2.,2.).Mul(mathgl.HomogRotate3DX(25.0)).Mul(mathgl.Translate3D(.5,.2,-.7)) MVP := Projection.Mul4(View).Mul4(Model) // Remember, transform multiplication order is "backwards" vBufferData := [...]float32{ -1., -1., 0., 1., -1., 0., 0., 1., 0.} //elBufferData := [...]uint8{0, 1, 2} // Not sure why this is here buffer := gl.GenBuffer() defer buffer.Delete() buffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, len(vBufferData)*4, &vBufferData, gl.STATIC_DRAW) // Equivalent to a do... while for ok := true; ok; ok = (glfw.Key(glfw.KeyEsc) != glfw.KeyPress && glfw.WindowParam(glfw.Opened) == gl.TRUE) { gl.Clear(gl.COLOR_BUFFER_BIT) prog.Use() matrixID.UniformMatrix4fv(false, MVP) attribLoc := gl.AttribLocation(0) attribLoc.EnableArray() buffer.Bind(gl.ARRAY_BUFFER) attribLoc.AttribPointer(3, gl.FLOAT, false, 0, nil) gl.DrawArrays(gl.TRIANGLES, 0, 3) attribLoc.DisableArray() glfw.SwapBuffers() } }
func (s *Sys) stepCycle() error { // TODO(nictuku): Show CPU tracer on video. draw := false // pc points to next opcode. opcode := uint16(s.mem[s.PC])<<8 | uint16(s.mem[s.PC+1]) // defer log.Printf("opcode 0x%04x", opcode) // defer log.Printf("cycle result:\n%v", s.String()) x := byte((opcode & 0x0F00) >> 8) y := byte((opcode & 0x00F0) >> 4) switch opcode & 0xF000 { case 0x0000: if opcode&0xFF00 != 0x0000 { // 0NNN Calls RCA 1802 program at address NNN. // => Only used by the original computers that implemented CHIP-8. goto NOTIMPLEMENTED } switch opcode & 0x000F { case 0x0000: // 00E0 Clears the screen. s.gfx = make([]byte, screenWidth*screenHeight) draw = true default: // 00EE Returns from a subroutine. if s.SP <= 0 { return fmt.Errorf("stack bottom") } s.PC = s.stack[s.SP] s.SP-- } case 0x1000: // 1NNN Jumps to address NNN. s.PC = opcode & 0x0FFF goto SKIPINC case 0x2000: // 2NNN Calls subroutine at NNN. if s.SP >= 15 { return fmt.Errorf("stack exhausted") } s.SP++ s.stack[s.SP] = s.PC s.PC = opcode & 0x0FFF goto SKIPINC case 0x3000: // 3XNN Skips the next instruction if VX equals NN. // Weird type mistmatch. Expected? if uint16(s.V[x]) == opcode&0xFF { s.PC += 2 } case 0x4000: // 4XNN Skips the next instruction if VX doesn't equal NN. if s.V[x] != byte(opcode&0xFF) { // Skip next. s.PC += 2 } case 0x5000: // 5XY0 Skips the next instruction if VX equals VY. if s.V[x] == s.V[y] { s.PC += 2 } case 0x6000: // 6XNN Sets VX to NN. s.V[x] = byte(opcode & 0x00FF) case 0x7000: // 7XNN Adds NN to VX. s.V[x] += byte(opcode & 0x00FF) case 0x8000: switch opcode & 0x000F { case 0x0000: // 8XY0 Sets VX to the value of VY. s.V[x] = s.V[y] case 0x0001: // 8XY1 Sets VX to VX or VY. s.V[x] = s.V[x] | s.V[y] case 0x0002: // 8XY2 Sets VX to VX and VY. s.V[x] = s.V[x] & s.V[y] case 0x0003: // 8XY3 Sets VX to VX xor VY. s.V[x] = s.V[x] ^ s.V[y] case 0x0004: // 8XY4 Adds VY to VX. VF is set to 1 when there's a carry, and to 0 when there isn't. add := s.V[x] + s.V[y] s.V[x] = add & 0xFF s.V[0xF] = (add >> 8) & 0x1 case 0x0005: // 8XY5 VY is subtracted from VX. VF is set to 0 when there's a borrow, and 1 when there isn't. sub := s.V[x] - s.V[y] if sub < 0 { sub = 0 s.V[0xF] = 0 } else { s.V[0xF] = 1 } s.V[x] = sub default: goto NOTIMPLEMENTED } // 8XY6 Shifts VX right by one. VF is set to the value of the least significant bit of VX before the shift.[2] // 8XY7 Sets VX to VY minus VX. VF is set to 0 when there's a borrow, and 1 when there isn't. // 8XYE Shifts VX left by one. VF is set to the value of the most significant bit of VX before the shift.[2] case 0x9000: // 9XY0 Skips the next instruction if VX doesn't equal VY. if s.V[x] != s.V[y] { s.PC += 2 } case 0xA000: // ANNN Sets I to the address NNN. s.I = opcode & 0x0FFF // BNNN Jumps to the address NNN plus V0. case 0xC000: // CXNN Sets VX to a random number and NN. s.V[x] = byte(uint16(rand.Int()) & opcode & 0x0FF) case 0xD000: // DXYN Draws a sprite at coordinate (VX, VY) that has a width of 8 // pixels and a height of N pixels. Each row of 8 pixels is read as // bit-coded (with the most significant bit of each byte displayed on // the left) starting from memory location I; I value doesn't change // after the execution of this instruction. // Based on the implementation from: // http://www.multigesture.net var pixel byte x := uint16(s.V[(opcode&0x0F00)>>8]) y := uint16(s.V[(opcode&0x00F0)>>4]) height := uint16(opcode & 0x000F) s.V[0xF] = 0 // yline+y < screenHeight was added later, to prevent out of range offsets. for yline := uint16(0); yline < height && yline+y < screenHeight; yline++ { pixel = s.mem[s.I+yline] for xline := uint16(0); xline < 8; xline++ { if (pixel & (0x80 >> xline)) != 0 { offset := (x + xline + ((y + yline) * screenWidth)) if s.gfx[offset] == 1 { // VF is set to 1 if any screen pixels are flipped from // set to unset when the sprite is drawn, and to 0 if // that doesn't happen. s.V[0xF] = 1 } s.gfx[offset] ^= 1 } } } draw = true case 0xE000: switch opcode & 0x00FF { case 0x00A1: // EXA1 Skips the next instruction if the key stored in VX isn't pressed. // TODO(nictuku): Implement keyboard events. if (s.key[s.V[x]]) == false { s.PC += 2 } // goto NOTIMPLEMENTED case 0x009E: // EX9E Skips the next instruction if the key stored in VX is pressed. // TODO(nictuku): Implement keyboard events. // goto NOTIMPLEMENTED // s.PC += 2 if (s.key[s.V[x]]) == true { s.PC += 2 } default: goto NOTIMPLEMENTED } case 0xF000: switch opcode & 0x00FF { case 0x000A: // FX0A A key press is awaited, and then stored in VX. // notifyKeyEvent. L: for { glfw.WaitEvents() for i, k := range keyMap { panic(fmt.Sprintf("resulting value %x", k)) if glfw.Key(int(k)) == glfw.KeyPress { s.key[i] = true s.V[x] = k break L } s.key[i] = false } } case 0x0007: // FX07 Sets VX to the value of the delay timer. s.V[x] = s.DelayTimer case 0x0015: // FX15 Sets the delay timer to VX. s.DelayTimer = s.V[x] case 0x0018: // FX18 Sets the sound timer to VX. s.SoundTimer = s.V[x] case 0x001E: // FX1E Adds VX to I. // VF is set to 1 when range overflow (I+VX>0xFFF), and 0 when // there isn't. This is undocumented feature of the Chip-8 and used // by Spacefight 2019! game. add := s.I + uint16(s.V[x]) if add > s.I { s.V[0xF] = 0x0 } else { s.V[0xF] = 0x1 } s.I = add case 0x0029: // FX29 Sets I to the location of the sprite for the character in VX. Characters 0-F (in hexadecimal) are represented by a 4x5 font. s.I = 0x50 + uint16(s.V[x])*4 // XXX assuming fontset at the beginning of memory. case 0x0033: // FX33 Stores the Binary-coded decimal representation of VX, with // the most significant of three digits at the address in I, the // middle digit at I plus 1, and the least significant digit at I // plus 2. s.mem[s.I] = byte(s.V[x] / 100 % 10) s.mem[s.I+1] = byte(s.V[x] / 10 % 10) s.mem[s.I+2] = byte(s.V[x] % 10) case 0x0055: // FX55 Stores V0 to VX in memory starting at address I. // On the original interpreter, when the operation is done, I=I+X+1 for i, reg := range s.V[0:x] { m := s.I + uint16(i) s.mem[m] = reg } s.I = +uint16(x + 1) case 0x0065: // FX65 Fills V0 to VX with values from memory starting at address I. for i := uint16(0); i <= uint16(x); i++ { s.V[i] = s.mem[s.I+i] } /* // Debugging. for i, b := range s.mem { fmt.Printf("%2x ", b) if i > 1 && i % 20 == 0 { fmt.Printf("\n%x\n", i) } } */ default: goto NOTIMPLEMENTED } default: goto NOTIMPLEMENTED } // Common case. s.PC += 2 SKIPINC: if s.DelayTimer > 0 { s.DelayTimer -= 1 } if s.SoundTimer > 0 { if s.SoundTimer == 1 { log.Println("BEEP!") } s.SoundTimer -= 1 } if draw { s.video.draw(s.gfx) } return nil NOTIMPLEMENTED: return fmt.Errorf("opcode not implemented: %x", opcode) }
// Since go has multiple return values, I just went ahead and made it return the view and perspective matrices (in that order) rather than messing with getter methods func (c *Camera) ComputeViewPerspective() (mathgl.Mat4f, mathgl.Mat4f) { if mathgl.FloatEqual(-1.0, c.time) { c.time = glfw.Time() } currTime := glfw.Time() deltaT := currTime - c.time xPos, yPos := glfw.MousePos() glfw.SetMousePos(width/2.0, height/2.0) c.hAngle += mouseSpeed * ((width / 2.0) - float64(xPos)) c.vAngle += mouseSpeed * ((height / 2.0) - float64(yPos)) dir := mathgl.Vec3f{ float32(math.Cos(c.vAngle) * math.Sin(c.hAngle)), float32(math.Sin(c.vAngle)), float32(math.Cos(c.vAngle) * math.Cos(c.hAngle))} right := mathgl.Vec3f{ float32(math.Sin(c.hAngle - math.Pi/2.0)), 0.0, float32(math.Cos(c.hAngle - math.Pi/2.0))} up := right.Cross(dir) if glfw.Key(glfw.KeyUp) == glfw.KeyPress || glfw.Key('W') == glfw.KeyPress { c.pos = c.pos.Add(dir.Mul(float32(deltaT * speed))) } if glfw.Key(glfw.KeyDown) == glfw.KeyPress || glfw.Key('S') == glfw.KeyPress { c.pos = c.pos.Sub(dir.Mul(float32(deltaT * speed))) } if glfw.Key(glfw.KeyRight) == glfw.KeyPress || glfw.Key('D') == glfw.KeyPress { c.pos = c.pos.Add(right.Mul(float32(deltaT * speed))) } if glfw.Key(glfw.KeyLeft) == glfw.KeyPress || glfw.Key('A') == glfw.KeyPress { c.pos = c.pos.Sub(right.Mul(float32(deltaT * speed))) } // Adding to the original tutorial, Space goes up if glfw.Key(glfw.KeySpace) == glfw.KeyPress { c.pos = c.pos.Add(up.Mul(float32(deltaT * speed))) } // Adding to the original tutorial, left control goes down if glfw.Key(glfw.KeyLctrl) == glfw.KeyPress { c.pos = c.pos.Sub(up.Mul(float32(deltaT * speed))) } fov := initialFOV - 5.0*float64(glfw.MouseWheel()) proj := mathgl.Perspective(fov, 4.0/3.0, 0.1, 100.0) view := mathgl.LookAtV(c.pos, c.pos.Add(dir), up) c.time = currTime return view, proj }
func main() { if err := glfw.Init(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } defer glfw.Terminate() glfw.OpenWindowHint(glfw.FsaaSamples, 4) glfw.OpenWindowHint(glfw.OpenGLVersionMajor, 3) glfw.OpenWindowHint(glfw.OpenGLVersionMinor, 3) glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) if err := glfw.OpenWindow(1024, 768, 0, 0, 0, 0, 32, 0, glfw.Windowed); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } glfw.SetSwapInterval(0) //gl.GlewExperimental(true) gl.Init() // Can't find gl.GLEW_OK or any variation, not sure how to check if this worked gl.GetError() // ignore error, since we're telling it to use CoreProfile above, we get "invalid enumerant" (GLError 1280) which freaks the OpenGLSentinel out glfw.SetWindowTitle("Tutorial 09") glfw.Enable(glfw.StickyKeys) glfw.Disable(glfw.MouseCursor) // Not in the original tutorial, but IMO it SHOULD be there glfw.SetMousePos(1024.0/2.0, 768.0/2.0) gl.ClearColor(0., 0., 0.4, 0.) gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.Enable(gl.CULL_FACE) camera := input.NewCamera() vertexArray := gl.GenVertexArray() defer vertexArray.Delete() vertexArray.Bind() prog := helper.MakeProgram("StandardShading.vertexshader", "StandardShading.fragmentshader") defer prog.Delete() matrixID := prog.GetUniformLocation("MVP") viewMatrixID := prog.GetUniformLocation("V") modelMatrixID := prog.GetUniformLocation("M") texture := helper.MakeTextureFromTGA("uvmap.tga") // Had to convert to tga, go-gl is missing the texture method for DDS right now defer texture.Delete() texSampler := prog.GetUniformLocation("myTextureSampler") meshObj := objloader.LoadObject("suzanne.obj") indices, indexedVertices, indexedUVs, indexedNormals := indexer.IndexVBO(meshObj.Vertices, meshObj.UVs, meshObj.Normals) vertexBuffer := gl.GenBuffer() defer vertexBuffer.Delete() vertexBuffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, len(indexedVertices)*3*4, indexedVertices, gl.STATIC_DRAW) uvBuffer := gl.GenBuffer() defer uvBuffer.Delete() uvBuffer.Bind(gl.ARRAY_BUFFER) // And yet, the weird length stuff doesn't seem to matter for UV or normal gl.BufferData(gl.ARRAY_BUFFER, len(indexedUVs)*2*4, indexedUVs, gl.STATIC_DRAW) normBuffer := gl.GenBuffer() defer normBuffer.Delete() normBuffer.Bind(gl.ARRAY_BUFFER) gl.BufferData(gl.ARRAY_BUFFER, len(indexedNormals)*3*4, indexedNormals, gl.STATIC_DRAW) elementBuffer := gl.GenBuffer() defer elementBuffer.Delete() elementBuffer.Bind(gl.ELEMENT_ARRAY_BUFFER) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices)*2, indices, gl.STATIC_DRAW) // NOTE: a GL_UNSIGNED_SHORT is 16-bits lightID := prog.GetUniformLocation("LightPosition_worldspace") lastTime := glfw.Time() nbFrames := 0 // Equivalent to a do... while for ok := true; ok; ok = (glfw.Key(glfw.KeyEsc) != glfw.KeyPress && glfw.WindowParam(glfw.Opened) == gl.TRUE && glfw.Key('Q') != glfw.KeyPress) { currTime := glfw.Time() nbFrames++ if currTime-lastTime >= 1.0 { fmt.Printf("%f ms/frame\n", 1000.0/float64(nbFrames)) nbFrames = 0 lastTime += 1.0 } func() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) prog.Use() defer gl.ProgramUnuse() view, proj := camera.ComputeViewPerspective() model := mathgl.Ident4f() MVP := proj.Mul4(view).Mul4(model) //mvpArray := mvp.AsCMOArray(mathgl.FLOAT32).([16]float32) //vArray := view.AsCMOArray(mathgl.FLOAT32).([16]float32) //mArray := model.AsCMOArray(mathgl.FLOAT32).([16]float32) matrixID.UniformMatrix4fv(false, MVP) viewMatrixID.UniformMatrix4fv(false, view) modelMatrixID.UniformMatrix4fv(false, model) lightID.Uniform3f(4., 4., 4.) gl.ActiveTexture(gl.TEXTURE0) texture.Bind(gl.TEXTURE_2D) defer texture.Unbind(gl.TEXTURE_2D) texSampler.Uniform1i(0) vertexAttrib := gl.AttribLocation(0) vertexAttrib.EnableArray() defer vertexAttrib.DisableArray() vertexBuffer.Bind(gl.ARRAY_BUFFER) defer vertexBuffer.Unbind(gl.ARRAY_BUFFER) vertexAttrib.AttribPointer(3, gl.FLOAT, false, 0, nil) uvAttrib := gl.AttribLocation(1) uvAttrib.EnableArray() defer uvAttrib.DisableArray() uvBuffer.Bind(gl.ARRAY_BUFFER) defer uvBuffer.Unbind(gl.ARRAY_BUFFER) uvAttrib.AttribPointer(2, gl.FLOAT, false, 0, nil) normAttrib := gl.AttribLocation(2) normAttrib.EnableArray() defer normAttrib.DisableArray() normBuffer.Bind(gl.ARRAY_BUFFER) defer normBuffer.Unbind(gl.ARRAY_BUFFER) normAttrib.AttribPointer(3, gl.FLOAT, false, 0, nil) elementBuffer.Bind(gl.ELEMENT_ARRAY_BUFFER) defer elementBuffer.Unbind(gl.ELEMENT_ARRAY_BUFFER) gl.DrawElements(gl.TRIANGLES, len(indices), gl.UNSIGNED_SHORT, nil) glfw.SwapBuffers() }() // Defers unbinds and disables to here, end of the loop } }