// SetActive will set current camera as the render camera func (cam *Camera) SetActive() { state.activeCam = cam if shader := shader.GetActive(); shader != nil { gl.UniformMatrix4fv(shader.Projection, 1, false, &cam.projection[0]) gl.UniformMatrix4fv(shader.Camera, 1, false, &cam.loc[0]) } }
// Load loads and sets up the model func (m *Model) Load(fileName string) { m.loadFile(fileName) shader := sm.Shader{VertSrcFile: m.data.VertShaderFile, FragSrcFile: m.data.FragShaderFile, Name: fmt.Sprintf("%s:%s", m.data.VertShaderFile, m.data.FragShaderFile)} program, err := m.shaders.LoadProgram(shader, false) if err != nil { return } m.currentProgram = program gl.UseProgram(m.currentProgram) m.projection = mgl32.Perspective(mgl32.DegToRad(45.0), float32(windowWidth)/windowHeight, 0.1, 10.0) m.projectionUniform = gl.GetUniformLocation(m.currentProgram, gl.Str("projection\x00")) gl.UniformMatrix4fv(m.projectionUniform, 1, false, &m.projection[0]) m.camera = mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}) m.cameraUniform = gl.GetUniformLocation(m.currentProgram, gl.Str("camera\x00")) gl.UniformMatrix4fv(m.cameraUniform, 1, false, &m.camera[0]) m.modelUniform = gl.GetUniformLocation(m.currentProgram, gl.Str("model\x00")) gl.UniformMatrix4fv(m.modelUniform, 1, false, &m.model[0]) m.textureUniform = gl.GetUniformLocation(m.currentProgram, gl.Str("tex\x00")) gl.Uniform1i(m.textureUniform, 0) gl.BindFragDataLocation(m.currentProgram, 0, gl.Str("outputColor\x00")) // Load the texture m.textures.LoadTexture(m.data.TextureFile, m.data.TextureFile) // Configure the vertex data gl.GenVertexArrays(1, &m.vao) gl.BindVertexArray(m.vao) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(m.data.Verts)*4, gl.Ptr(m.data.Verts), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(m.currentProgram, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, m.data.VertSize*4, gl.PtrOffset(0)) // 4:number of bytes in a float32 texCoordAttrib := uint32(gl.GetAttribLocation(m.currentProgram, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texCoordAttrib) gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, true, m.data.VertSize*4, gl.PtrOffset(3*4)) // 4:number of bytes in a float32 if m.data.Indexed { var indices uint32 gl.GenBuffers(1, &indices) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, indices) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(m.data.Indices)*4, gl.Ptr(m.data.Indices), gl.STATIC_DRAW) } gl.BindVertexArray(0) }
// Render renders the model func (m *Model) Render() { gl.UseProgram(m.currentProgram) gl.UniformMatrix4fv(m.modelUniform, 1, false, &m.model[0]) gl.BindVertexArray(m.vao) gl.ActiveTexture(gl.TEXTURE0) texture, isLoaded := m.textures.GetTexture(m.data.TextureFile) if isLoaded { gl.BindTexture(gl.TEXTURE_2D, texture) } else { if m.data.TextureFile != "" { go fmt.Printf("Unable to load texture %s", m.data.TextureFile) } } if m.data.Indexed { gl.DrawElements(gl.TRIANGLE_FAN, int32(len(m.data.Indices)), gl.UNSIGNED_INT, gl.PtrOffset(0)) } else { gl.DrawArrays(gl.TRIANGLES, 0, int32(len(m.data.Verts))/m.data.VertSize) } gl.BindVertexArray(0) }
func setupUniforms(shader *renderer.Shader) { for name, uniform := range shader.Uniforms { uniformLocation := gl.GetUniformLocation(shader.Program, gl.Str(name+"\x00")) switch t := uniform.(type) { case bool: if t { gl.Uniform1i(uniformLocation, 1) } else { gl.Uniform1i(uniformLocation, 0) } case float32: gl.Uniform1f(uniformLocation, t) case float64: gl.Uniform1f(uniformLocation, float32(t)) case int32: gl.Uniform1i(uniformLocation, t) case int: gl.Uniform1i(uniformLocation, int32(t)) case mgl32.Vec2: gl.Uniform2f(uniformLocation, t[0], t[1]) case mgl32.Vec3: gl.Uniform3f(uniformLocation, t[0], t[1], t[2]) case mgl32.Vec4: gl.Uniform4f(uniformLocation, t[0], t[1], t[2], t[3]) case mgl32.Mat4: gl.UniformMatrix4fv(uniformLocation, 1, false, &t[0]) case []float32: gl.Uniform4fv(uniformLocation, (int32)(len(t)), &t[0]) case []int32: gl.Uniform4iv(uniformLocation, (int32)(len(t)), &t[0]) default: fmt.Printf("unexpected type for shader uniform: %T\n", t) } } }
func (c *Camera) Draw(program uint32) { //c.UpdateCamera() camera := mgl32.LookAtV(c.position, c.position.Add(c.direction), c.up) cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00")) gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0]) }
func (me *test) Display(c *Core) { me.o1.Draw(c) me.o2.Draw(c) projection := mgl32.Perspective(mgl32.DegToRad(Fov), float32(WindowWidth)/WindowHeight, Near, Far) view := mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}) model := mgl32.Ident4() MVP := projection.Mul4(view).Mul4(model) gl.UniformMatrix4fv(mvpLoc, 1, false, &MVP[0]) gl.Uniform1i(TexLoc, 0) }
// Draw will draw the billvboard in the x,y and z func (billboard *Billboard) Draw(x float32, y float32, z float32) { model := mgl32.Translate3D(x, y, z) if shader := shader.GetActive(); shader != nil { gl.UniformMatrix4fv(shader.Model, 1, false, &model[0]) } gl.BindVertexArray(billboard.vao) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, billboard.image) gl.DrawArrays(gl.TRIANGLES, 0, 1*2*3) }
// DrawFrame will draw the sprite in the x,y and z with the specified frame from a spritesheet func (sprite *Sprite) DrawFrame(x float32, y float32, z float32, scale float32, frame int) { model := mgl32.Translate3D(x, y, z) model = model.Mul4(mgl32.Scale3D(scale, scale, 1)) // remember this is in radians! // model = model.Mul4(mgl32.HomogRotate3D(mgl32.DegToRad(90), mgl32.Vec3{0, 0, 1})) if shader := shader.GetActive(); shader != nil { gl.UniformMatrix4fv(shader.Model, 1, false, &model[0]) } gl.BindVertexArray(sprite.vao) sprite.image.Bind() gl.DrawArrays(gl.TRIANGLES, int32(frame*6), 6) }
func programLoop(window *win.Window) error { // the linked shader program determines how the data will be rendered vertShader, err := gfx.NewShaderFromFile("shaders/phong.vert", gl.VERTEX_SHADER) if err != nil { return err } fragShader, err := gfx.NewShaderFromFile("shaders/phong.frag", gl.FRAGMENT_SHADER) if err != nil { return err } program, err := gfx.NewProgram(vertShader, fragShader) if err != nil { return err } defer program.Delete() lightFragShader, err := gfx.NewShaderFromFile("shaders/light.frag", gl.FRAGMENT_SHADER) if err != nil { return err } // special shader program so that lights themselves are not affected by lighting lightProgram, err := gfx.NewProgram(vertShader, lightFragShader) if err != nil { return err } VAO := createVAO(cubeVertices, nil) lightVAO := createVAO(cubeVertices, nil) // ensure that triangles that are "behind" others do not draw over top of them gl.Enable(gl.DEPTH_TEST) camera := cam.NewFpsCamera(mgl32.Vec3{0, 0, 3}, mgl32.Vec3{0, 1, 0}, -90, 0, window.InputManager()) for !window.ShouldClose() { // swaps in last buffer, polls for window events, and generally sets up for a new render frame window.StartFrame() // update camera position and direction from input evevnts camera.Update(window.SinceLastFrame()) // background color gl.ClearColor(0, 0, 0, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // depth buffer needed for DEPTH_TEST // cube rotation matrices rotateX := (mgl32.Rotate3DX(mgl32.DegToRad(-45 * float32(glfw.GetTime())))) rotateY := (mgl32.Rotate3DY(mgl32.DegToRad(-45 * float32(glfw.GetTime())))) rotateZ := (mgl32.Rotate3DZ(mgl32.DegToRad(-45 * float32(glfw.GetTime())))) // creates perspective fov := float32(60.0) projectTransform := mgl32.Perspective(mgl32.DegToRad(fov), float32(window.Width())/float32(window.Height()), 0.1, 100.0) camTransform := camera.GetTransform() lightPos := mgl32.Vec3{0.6, 1, 0.1} lightTransform := mgl32.Translate3D(lightPos.X(), lightPos.Y(), lightPos.Z()).Mul4( mgl32.Scale3D(0.2, 0.2, 0.2)) program.Use() gl.UniformMatrix4fv(program.GetUniformLocation("view"), 1, false, &camTransform[0]) gl.UniformMatrix4fv(program.GetUniformLocation("project"), 1, false, &projectTransform[0]) gl.BindVertexArray(VAO) // draw each cube after all coordinate system transforms are bound // obj is colored, light is white gl.Uniform3f(program.GetUniformLocation("material.ambient"), 1.0, 0.5, 0.31) gl.Uniform3f(program.GetUniformLocation("material.diffuse"), 1.0, 0.5, 0.31) gl.Uniform3f(program.GetUniformLocation("material.specular"), 0.5, 0.5, 0.5) gl.Uniform1f(program.GetUniformLocation("material.shininess"), 32.0) lightColor := mgl32.Vec3{ float32(math.Sin(glfw.GetTime() * 1)), float32(math.Sin(glfw.GetTime() * 0.35)), float32(math.Sin(glfw.GetTime() * 0.65)), } diffuseColor := mgl32.Vec3{ 0.5 * lightColor[0], 0.5 * lightColor[1], 0.5 * lightColor[2], } ambientColor := mgl32.Vec3{ 0.2 * lightColor[0], 0.2 * lightColor[1], 0.2 * lightColor[2], } gl.Uniform3f(program.GetUniformLocation("light.ambient"), ambientColor[0], ambientColor[1], ambientColor[2]) gl.Uniform3f(program.GetUniformLocation("light.diffuse"), diffuseColor[0], diffuseColor[1], diffuseColor[2]) gl.Uniform3f(program.GetUniformLocation("light.specular"), 1.0, 1.0, 1.0) gl.Uniform3f(program.GetUniformLocation("light.position"), lightPos.X(), lightPos.Y(), lightPos.Z()) for _, pos := range cubePositions { // turn the cubes into rectangular prisms for more fun worldTranslate := mgl32.Translate3D(pos[0], pos[1], pos[2]) worldTransform := worldTranslate.Mul4( rotateX.Mul3(rotateY).Mul3(rotateZ).Mat4(), ) gl.UniformMatrix4fv(program.GetUniformLocation("model"), 1, false, &worldTransform[0]) gl.DrawArrays(gl.TRIANGLES, 0, 36) } gl.BindVertexArray(0) // Draw the light obj after the other boxes using its separate shader program // this means that we must re-bind any uniforms lightProgram.Use() gl.BindVertexArray(lightVAO) gl.UniformMatrix4fv(lightProgram.GetUniformLocation("model"), 1, false, &lightTransform[0]) gl.UniformMatrix4fv(lightProgram.GetUniformLocation("view"), 1, false, &camTransform[0]) gl.UniformMatrix4fv(lightProgram.GetUniformLocation("project"), 1, false, &projectTransform[0]) gl.DrawArrays(gl.TRIANGLES, 0, 36) gl.BindVertexArray(0) // end of draw loop } return nil }
func programLoop(window *glfw.Window) error { // the linked shader program determines how the data will be rendered vertShader, err := gfx.NewShaderFromFile("shaders/basic.vert", gl.VERTEX_SHADER) if err != nil { return err } fragShader, err := gfx.NewShaderFromFile("shaders/basic.frag", gl.FRAGMENT_SHADER) if err != nil { return err } program, err := gfx.NewProgram(vertShader, fragShader) if err != nil { return err } defer program.Delete() vertices := []float32{ // position // texture position -0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 1.0, -0.5, 0.5, 0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, -0.5, 1.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, 0.5, 0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 1.0, 1.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, 0.5, 0.0, 0.0, -0.5, 0.5, -0.5, 0.0, 1.0, } indices := []uint32{} VAO := createVAO(vertices, indices) texture0, err := gfx.NewTextureFromFile("../images/RTS_Crate.png", gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE) if err != nil { panic(err.Error()) } texture1, err := gfx.NewTextureFromFile("../images/trollface-transparent.png", gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE) if err != nil { panic(err.Error()) } cubePositions := [][]float32{ []float32{0.0, 0.0, -3.0}, []float32{2.0, 5.0, -15.0}, []float32{-1.5, -2.2, -2.5}, []float32{-3.8, -2.0, -12.3}, []float32{2.4, -0.4, -3.5}, []float32{-1.7, 3.0, -7.5}, []float32{1.3, -2.0, -2.5}, []float32{1.5, 2.0, -2.5}, []float32{1.5, 0.2, -1.5}, []float32{-1.3, 1.0, -1.5}, } gl.Enable(gl.DEPTH_TEST) for !window.ShouldClose() { // poll events and call their registered callbacks glfw.PollEvents() // background color gl.ClearColor(0.2, 0.5, 0.5, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // draw vertices program.Use() // set texture0 to uniform0 in the fragment shader texture0.Bind(gl.TEXTURE0) texture0.SetUniform(program.GetUniformLocation("ourTexture0")) // set texture1 to uniform1 in the fragment shader texture1.Bind(gl.TEXTURE1) texture1.SetUniform(program.GetUniformLocation("ourTexture1")) // update shader transform matrices // Create transformation matrices rotateX := (mgl32.Rotate3DX(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) rotateY := (mgl32.Rotate3DY(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) rotateZ := (mgl32.Rotate3DZ(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) viewTransform := mgl32.Translate3D(0, 0, -3) projectTransform := mgl32.Perspective(mgl32.DegToRad(60), windowWidth/windowHeight, 0.1, 100.0) gl.UniformMatrix4fv(program.GetUniformLocation("view"), 1, false, &viewTransform[0]) gl.UniformMatrix4fv(program.GetUniformLocation("project"), 1, false, &projectTransform[0]) gl.UniformMatrix4fv(program.GetUniformLocation("worldRotateX"), 1, false, &rotateX[0]) gl.UniformMatrix4fv(program.GetUniformLocation("worldRotateY"), 1, false, &rotateY[0]) gl.UniformMatrix4fv(program.GetUniformLocation("worldRotateZ"), 1, false, &rotateZ[0]) gl.BindVertexArray(VAO) for _, pos := range cubePositions { worldTranslate := mgl32.Translate3D(pos[0], pos[1], pos[2]) worldTransform := (worldTranslate.Mul4(rotateX.Mul3(rotateY).Mul3(rotateZ).Mat4())) gl.UniformMatrix4fv(program.GetUniformLocation("world"), 1, false, &worldTransform[0]) gl.DrawArrays(gl.TRIANGLES, 0, 36) } // gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_INT, unsafe.Pointer(nil)) gl.BindVertexArray(0) texture0.UnBind() texture1.UnBind() // end of draw loop // swap in the rendered buffer window.SwapBuffers() } return nil }
func main() { if err := glfw.Init(); err != nil { log.Fatalln("failed to initialize glfw:", err) } defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 4) glfw.WindowHint(glfw.ContextVersionMinor, 1) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(windowWidth, windowHeight, "Cube", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // Initialize Glow if err := gl.Init(); err != nil { panic(err) } version := gl.GoStr(gl.GetString(gl.VERSION)) fmt.Println("OpenGL version", version) // Configure the vertex and fragment shaders program, err := newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) projection := mgl32.Perspective(mgl32.DegToRad(45.0), float32(windowWidth)/windowHeight, 0.1, 10.0) projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00")) gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0]) camera := mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}) cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00")) gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0]) model := mgl32.Ident4() modelUniform := gl.GetUniformLocation(program, gl.Str("model\x00")) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) textureUniform := gl.GetUniformLocation(program, gl.Str("tex\x00")) gl.Uniform1i(textureUniform, 0) gl.BindFragDataLocation(program, 0, gl.Str("outputColor\x00")) // Load the texture texture, err := newTexture("square.png") if err != nil { panic(err) } // Configure the vertex data var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(cubeVertices)*4, gl.Ptr(cubeVertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0)) texCoordAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texCoordAttrib) gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4)) // Configure global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(1.0, 1.0, 1.0, 1.0) angle := 0.0 previousTime := glfw.GetTime() for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // Update time := glfw.GetTime() elapsed := time - previousTime previousTime = time angle += elapsed model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0}) // Render gl.UseProgram(program) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindVertexArray(vao) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) gl.DrawArrays(gl.TRIANGLES, 0, 6*2*3) // Maintenance window.SwapBuffers() glfw.PollEvents() } }
func Main() { err := glfw.Init() if err != nil { panic(err) } defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 3) glfw.WindowHint(glfw.ContextVersionMinor, 2) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(WindowWidth, WindowHeight, "Cube", nil, nil) Window = window if err != nil { panic(err) } window.MakeContextCurrent() // Initialize Glow if err := gl.Init(); err != nil { panic(err) } version := gl.GoStr(gl.GetString(gl.VERSION)) fmt.Println("OpenGL version", version) // Configure the vertex and fragment shaders program, err := newProgram("SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader") if err != nil { panic(err) } gl.UseProgram(program) projection := mgl32.Perspective(mgl32.DegToRad(45.0), float32(WindowWidth)/WindowHeight, 0.1, 10.0) projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00")) gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0]) camera := mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}) cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00")) gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0]) model := mgl32.Ident4() modelUniform := gl.GetUniformLocation(program, gl.Str("model\x00")) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) textureUniform := gl.GetUniformLocation(program, gl.Str("tex\x00")) gl.Uniform1i(textureUniform, 0) gl.BindFragDataLocation(program, 0, gl.Str("outputColor\x00")) // Configure global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(1.0, 1.0, 1.0, 1.0) angle := 0.0 previousTime := glfw.GetTime() width, height := window.GetSize() window.SetCursorPos(float64(width/2), float64(height/2)) window.SetKeyCallback(input.OnKey) window.SetCursorPosCallback(input.OnCursor) window.SetMouseButtonCallback(input.OnMouse) meshes.LoadColladaCube("cube.dae") for !player.ShouldClose { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // Update time := glfw.GetTime() elapsed := time - previousTime previousTime = time angle += elapsed model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0}) // Render gl.UseProgram(program) // gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) player.MainPlayer.Draw(program) for _, element := range game.Universe { (element).Draw(program) } // Maintenance window.SwapBuffers() glfw.PollEvents() } }
func programLoop(window *win.Window) error { // the linked shader program determines how the data will be rendered vertShader, err := gfx.NewShaderFromFile("shaders/basic.vert", gl.VERTEX_SHADER) if err != nil { return err } fragShader, err := gfx.NewShaderFromFile("shaders/basic.frag", gl.FRAGMENT_SHADER) if err != nil { return err } program, err := gfx.NewProgram(vertShader, fragShader) if err != nil { return err } defer program.Delete() VAO := createVAO(cubeVertices, nil) texture0, err := gfx.NewTextureFromFile("../images/RTS_Crate.png", gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE) if err != nil { panic(err.Error()) } texture1, err := gfx.NewTextureFromFile("../images/trollface-transparent.png", gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE) if err != nil { panic(err.Error()) } // ensure that triangles that are "behind" others do not draw over top of them gl.Enable(gl.DEPTH_TEST) camera := cam.NewFpsCamera(mgl32.Vec3{0, 0, 3}, mgl32.Vec3{0, 1, 0}, -90, 0, window.InputManager()) for !window.ShouldClose() { // swaps in last buffer, polls for window events, and generally sets up for a new render frame window.StartFrame() // update camera position and direction from input evevnts camera.Update(window.SinceLastFrame()) // background color gl.ClearColor(0.2, 0.5, 0.5, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // depth buffer needed for DEPTH_TEST program.Use() // bind textures texture0.Bind(gl.TEXTURE0) texture0.SetUniform(program.GetUniformLocation("ourTexture0")) texture1.Bind(gl.TEXTURE1) texture1.SetUniform(program.GetUniformLocation("ourTexture1")) // cube rotation matrices rotateX := (mgl32.Rotate3DX(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) rotateY := (mgl32.Rotate3DY(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) rotateZ := (mgl32.Rotate3DZ(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) // creates perspective fov := float32(60.0) projectTransform := mgl32.Perspective(mgl32.DegToRad(fov), float32(window.Width())/float32(window.Height()), 0.1, 100.0) camTransform := camera.GetTransform() gl.UniformMatrix4fv(program.GetUniformLocation("camera"), 1, false, &camTransform[0]) gl.UniformMatrix4fv(program.GetUniformLocation("project"), 1, false, &projectTransform[0]) gl.BindVertexArray(VAO) // draw each cube after all coordinate system transforms are bound for _, pos := range cubePositions { worldTranslate := mgl32.Translate3D(pos[0], pos[1], pos[2]) worldTransform := (worldTranslate.Mul4(rotateX.Mul3(rotateY).Mul3(rotateZ).Mat4())) gl.UniformMatrix4fv(program.GetUniformLocation("world"), 1, false, &worldTransform[0]) gl.DrawArrays(gl.TRIANGLES, 0, 36) } gl.BindVertexArray(0) texture0.UnBind() texture1.UnBind() // end of draw loop } return nil }