func render() { modelMatrix = trig.MatrixMult(trig.RotateY(math.Pi/360), modelMatrix) gl.Viewport(0, 0, 768, 768) gl.ClearColor(0.0, 0.0, 0, 0) gl.Enable(gl.DEPTH_TEST) raytraceProgram.Use() mInput.UniformMatrix4f(false, (*[16]float32)(modelMatrix)) vInput.UniformMatrix4f(false, (*[16]float32)(viewMatrix)) pInput.UniformMatrix4f(false, (*[16]float32)(projMatrix)) glh.With(framebuffer, func() { framebuffer.UpdateTextures() gl.DrawBuffer(gl.COLOR_ATTACHMENT0) gl.Clear(gl.COLOR_BUFFER_BIT) gl.DepthFunc(gl.GREATER) gl.CullFace(gl.BACK) cube.Render(gl.TRIANGLES, raytraceProgram) gl.DrawBuffer(gl.COLOR_ATTACHMENT1) gl.Clear(gl.COLOR_BUFFER_BIT) gl.DepthFunc(gl.LESS) gl.CullFace(gl.FRONT) cube.Render(gl.TRIANGLES, raytraceProgram) }) }
// Initialize the window. Returns an error if glfw or glew throws one. func InitWindow(width, height int) error { Width, Height = width, height err := glfw.Init() if err != nil { return err } err = glfw.OpenWindow(Width, Height, 0, 0, 0, 32, 32, 32, glfw.Windowed) if err != nil { return err } WindowOpened = true glfw.SetWindowTitle("Goliath") glfw.Enable(glfw.KeyRepeat) if ret := gl.Init(); ret != 0 { return fmt.Errorf("failed to initialize GLEW: %d", ret) } // Set GL states gl.ClearColor(0.0, 0.0, 0.0, 1.0) gl.Enable(gl.CULL_FACE) gl.CullFace(gl.BACK) gl.FrontFace(gl.CCW) err = InitShaders() if err != nil { return err } InitCamera(Width, Height) return nil }
func compose() { //w, h := window.GetSize() //gl.Viewport(0, 0, w, h) gl.ClearColor(0, 0, 0, 1) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) gl.CullFace(gl.BACK) composeProgram.Use() mInputC.UniformMatrix4f(false, (*[16]float32)(modelMatrix)) vInputC.UniformMatrix4f(false, (*[16]float32)(viewMatrix)) pInputC.UniformMatrix4f(false, (*[16]float32)(projMatrix)) cube.Render(gl.TRIANGLES, composeProgram) }
func main() { var programState programState var err error glfw.SetErrorCallback(errorCallback) if !glfw.Init() { panic("GLFW initialization failed.") } defer glfw.Terminate() glfw.WindowHint(glfw.ContextVersionMajor, 3) glfw.WindowHint(glfw.ContextVersionMinor, 3) glfw.WindowHint(glfw.SrgbCapable, glfw.True) glfw.WindowHint(glfw.Resizable, glfw.False) programState.Gl.Window, err = glfw.CreateWindow(640, 480, "Daggor", nil, nil) if err != nil { panic(err) } defer programState.Gl.Window.Destroy() programState.Gl.glfwKeyEventList = makeGlfwKeyEventList() programState.Gl.Window.SetKeyCallback(programState.Gl.glfwKeyEventList.Callback) programState.Gl.Window.MakeContextCurrent() if ec := gl.Init(); ec != 0 { panic(fmt.Sprintf("OpenGL initialization failed with code %v.", ec)) } // For some reason, here, the OpenGL error flag for me contains "Invalid enum". // This is weird since I have not done anything yet. I imagine that something // goes wrong in gl.Init. Reading the error flag clears it, so I do it. // Here's the reason: // https://github.com/go-gl/glfw3/issues/50 // Maybe I should not even ask for a core profile anyway. // What are the advantages are asking for a core profile? if err := glw.CheckGlError(); err != nil { err.Description = "OpenGL has this error right after init for some reason." //fmt.Println(err) } { // Assert OpenGL >= 3.3. major := programState.Gl.Window.GetAttribute(glfw.ContextVersionMajor) minor := programState.Gl.Window.GetAttribute(glfw.ContextVersionMinor) fmt.Printf("OpenGL version %v.%v.\n", major, minor) if (major < 3) || (major == 3 && minor < 3) { panic("OpenGL version 3.3 required, your video card/driver does not seem to support it.") } } programState.Gl.context = glw.NewGlContext() programState.Gl.Shapes[floorID] = sculpt.FloorInstNorm(programState.Gl.context.Programs) programState.Gl.Shapes[ceilingID] = sculpt.CeilingInstNorm(programState.Gl.context.Programs) programState.Gl.Shapes[wallID] = sculpt.WallInstNorm(programState.Gl.context.Programs) { // I do not like the default reference frame of OpenGl. // By default, we look in the direction -z, and y points up. // I want z to point up, and I want to look in the direction +x // by default. That way, I move on an xy plane where z is the // altitude, instead of having the altitude stuffed between // the two things I use the most. And my reason for pointing // toward +x is that I use the convention for trigonometry: // an angle of 0 points to the right (east) of the trigonometric // circle. Bonus point: this matches Blender's reference frame. myFrame := glm.ZUP.Mult(glm.RotZ(90)) eye_to_clip := glm.PerspectiveProj(110, 640./480., .1, 100).Mult(myFrame) programState.Gl.context.SetEyeToClp(eye_to_clip) } gl.Enable(gl.FRAMEBUFFER_SRGB) gl.Enable(gl.DEPTH_TEST) gl.Enable(gl.CULL_FACE) gl.CullFace(gl.BACK) gl.FrontFace(gl.CCW) gl.Enable(gl.TEXTURE_CUBE_MAP_SEAMLESS) // This needs a texture server attached to the context, like for programs. glw.LoadSkybox() programState.World = world.MakeWorld() mainLoop(programState) }