func (t *Text) Draw() { if t.IsDebug { t.BoundingBox.Draw() } gl.UseProgram(t.font.program) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, t.font.textureID) // uniforms gl.Uniform1i(t.font.fragmentTextureUniform, 0) gl.Uniform4fv(t.font.colorUniform, 1, &t.color[0]) gl.Uniform2fv(t.font.finalPositionUniform, 1, &t.finalPosition[0]) gl.UniformMatrix4fv(t.font.orthographicMatrixUniform, 1, false, &t.font.OrthographicMatrix[0]) gl.UniformMatrix4fv(t.font.scaleMatrixUniform, 1, false, &t.scaleMatrix[0]) // draw drawCount := int32(t.RuneCount * 6) if drawCount > int32(t.eboIndexCount) { drawCount = int32(t.eboIndexCount) } if drawCount < 0 { drawCount = 0 } gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.BindVertexArray(t.vao) gl.DrawElements(gl.TRIANGLES, drawCount, gl.UNSIGNED_INT, nil) gl.BindVertexArray(0) gl.Disable(gl.BLEND) }
func (tr *TextRenderer) Bind() error { gl.UseProgram(tr.Program) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } gl.Uniform1i(tr.TextureUnitLoc, 0) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } gl.BindBuffer(gl.ARRAY_BUFFER, tr.VBO) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } gl.EnableVertexAttribArray(tr.PositionLoc) gl.VertexAttribPointer(tr.PositionLoc, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0)) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } gl.EnableVertexAttribArray(tr.TextureLoc) gl.VertexAttribPointer(tr.TextureLoc, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4)) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } gl.UniformMatrix4fv(tr.ProjectionLoc, 1, false, &tr.Renderer.Camera.Projection[0]) if e := gl.GetError(); e != 0 { return fmt.Errorf("ERROR: %X", e) } return nil }
func (lr *LinesRenderer) Draw(line *LineGeometry, mv mgl32.Mat4, style *LineStyle) (err error) { var ( dataBytes int = len(line.Vertices) * int(lr.stride) indexBytes int = len(line.Indices) * int(lr.stride) elementCount int32 = int32(len(line.Indices)) r, g, b, a = style.Color.RGBA() ) gl.Uniform1f(lr.thicknessLoc, style.Thickness) gl.Uniform1f(lr.innerLoc, style.Inner) gl.Uniform4f(lr.colorLoc, float32(r)/255.0, float32(g)/255.0, float32(b)/255.0, float32(a)/255.0) gl.UniformMatrix4fv(lr.modelviewLoc, 1, false, &mv[0]) if dataBytes > lr.bufferBytes { lr.bufferBytes = dataBytes gl.BufferData(gl.ARRAY_BUFFER, dataBytes, gl.Ptr(line.Vertices), gl.STREAM_DRAW) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, indexBytes, gl.Ptr(line.Indices), gl.STREAM_DRAW) } else { gl.BufferSubData(gl.ARRAY_BUFFER, 0, dataBytes, gl.Ptr(line.Vertices)) gl.BufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, indexBytes, gl.Ptr(line.Indices)) } gl.DrawElements(gl.TRIANGLES, elementCount, gl.UNSIGNED_INT, gl.PtrOffset(0)) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR: OpenGL error %X", e) } return }
func (rt *renderableText) render(x, y float32) { m := newScaleMatrix(rt.width, rt.height, 1) m = m.mult(newTranslationMatrix(x, y, 0)) gl.UniformMatrix4fv(modelMatrixUniform, 1, false, &m[0]) gl.Uniform1i(textureUniform, int32(rt.texture)-1) textLineMesh.drawElements() }
func (r *BatchRenderer) Bind() error { gl.UseProgram(r.Program) gl.ActiveTexture(gl.TEXTURE0) gl.Uniform1i(r.TextureUnitLoc, 0) gl.UniformMatrix4fv(r.ProjectionLoc, 1, false, &r.Camera.Projection[0]) return nil }
func renderCellBlock(metrics *metrics, c *game.Cell, x, y int) { bv := float32(0) if c.Block.State == game.BlockFlashing { bv = pulse(metrics.g.GlobalPulse+metrics.fudge, 0, 0.5, 1.5) } gl.Uniform1f(brightnessUniform, bv) m := metrics.blockMatrix(c.Block, x, y) gl.UniformMatrix4fv(modelMatrixUniform, 1, false, &m[0]) blockMeshes[c.Block.Color].drawElements() }
func (b *BoundingBox) Draw() { gl.UseProgram(b.program) // uniforms gl.Uniform2fv(b.finalPositionUniform, 1, &b.finalPosition[0]) gl.UniformMatrix4fv(b.orthographicMatrixUniform, 1, false, &b.font.OrthographicMatrix[0]) // draw gl.BindVertexArray(b.vao) gl.DrawElements(gl.TRIANGLES, int32(b.eboIndexCount), gl.UNSIGNED_INT, nil) gl.BindVertexArray(0) }
func Draw() { // if len(layers) == 0 { // fmt.Println("layers empty!!!") // return // } // for _, layer := range layers { // vertexData := textureHash[layer] vertexData := &vertexDataTest // check to see if there are any vertices at all to draw if len(vertexData.vertexData) == 0 { return } // vertexData.Print() // vertexData := vertexDataTest //vertexData.Print() // BindBuffers(vertexData) // vertexData.Print() //gl.BufferSubData(gl.ARRAY_BUFFER, 0, len(vertexData.VertexData)*4, gl.Ptr(vertexData.VertexData)) // gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(vertexData.vertexData)*4, gl.Ptr(vertexData.vertexData), gl.DYNAMIC_DRAW) // gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementvbo) // gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertexData.Elements)*4, gl.Ptr(vertexData.Elements), gl.DYNAMIC_DRAW) MVP := projectionM.Mul4(viewM) //.Mul4(Model) gl.UniformMatrix4fv(MVPid, 1, false, &MVP[0]) lightPos := mathgl.Vec3{0, 3, 10} lightintensities := mathgl.Vec3{1, .4, .2} gl.Uniform3f(lightpositionID, lightPos[0], lightPos[1], lightPos[2]) gl.Uniform3f(lightintensitiesID, lightintensities[0], lightintensities[1], lightintensities[2]) gl.Uniform3f(cameraPositionID, 0.0, 1.0, -1.0) // vertexData.Print() // gl.DrawElements(gl.TRIANGLES, int32(len(vertexData.Elements)), gl.UNSIGNED_INT, nil) // } numTriVerts := int32((len(vertexData.vertexData) / (int(NUM_ATTRIBUTES) * 2)) * 3) gl.DrawArrays(gl.TRIANGLES, 0, numTriVerts) ClearVertexData() }
func (r *Framerate) Render(camera *core.Camera) (err error) { r.data.Sample() var ( modelView = mgl32.Ident4() dataBytes int = int(r.data.Count) * int(r.stride) ) gl.Uniform4f(r.locColor, 255.0/255.0, 0, 0, 255.0/255.0) gl.UniformMatrix4fv(r.locModelView, 1, false, &modelView[0]) gl.UniformMatrix4fv(r.locProjection, 1, false, &camera.Projection[0]) if dataBytes > r.vboBytes { r.vboBytes = dataBytes gl.BufferData(gl.ARRAY_BUFFER, dataBytes, gl.Ptr(r.data.Points), gl.STREAM_DRAW) } else { gl.BufferSubData(gl.ARRAY_BUFFER, 0, dataBytes, gl.Ptr(r.data.Points)) } gl.DrawArrays(gl.POINTS, 0, r.data.Count) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR: OpenGL error %X", e) } return }
func (r *BatchRenderer) Draw(batch *Batch, x, y, rot float32) error { batch.Texture.Bind() gl.BindBuffer(gl.ARRAY_BUFFER, batch.Buffer) gl.EnableVertexAttribArray(r.PositionLoc) gl.VertexAttribPointer(r.PositionLoc, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(r.TextureLoc) gl.VertexAttribPointer(r.TextureLoc, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4)) m := mgl32.Translate3D(x, y, 0.0).Mul4(mgl32.HomogRotate3DZ(rot)) gl.UniformMatrix4fv(r.ModelViewLoc, 1, false, &m[0]) gl.Uniform2f(r.TexOffsetLoc, batch.textureOffset.X(), batch.textureOffset.Y()) gl.DrawArrays(gl.TRIANGLES, 0, int32(batch.Count)) gl.BindBuffer(gl.ARRAY_BUFFER, 0) return nil }
func (c Context) DrawRectangle(x, y, w, h float32, color Color) { gl.UseProgram(c.program) model := mgl32.Translate3D(x, y, 0).Mul4(mgl32.Scale3D(w, h, 0)) modelUniform := gl.GetUniformLocation(c.program, gl.Str("model\x00")) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) colorArray := []float32{color.B, color.G, color.R} colorUniform := gl.GetUniformLocation(c.program, gl.Str("color\x00")) gl.Uniform4fv(colorUniform, 1, &colorArray[0]) gl.DrawArrays(gl.TRIANGLES, 0, 6) }
func (lr *LinesRenderer) Bind() (err error) { gl.UseProgram(lr.program) gl.BindBuffer(gl.ARRAY_BUFFER, lr.buffer) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, lr.indexBuffer) gl.EnableVertexAttribArray(lr.positionLoc) gl.EnableVertexAttribArray(lr.normalLoc) gl.EnableVertexAttribArray(lr.miterLoc) gl.VertexAttribPointer(lr.positionLoc, 2, gl.FLOAT, false, lr.stride, lr.offPosition) gl.VertexAttribPointer(lr.normalLoc, 2, gl.FLOAT, false, lr.stride, lr.offNormal) gl.VertexAttribPointer(lr.miterLoc, 1, gl.FLOAT, false, lr.stride, lr.offMiter) gl.UniformMatrix4fv(lr.projectionLoc, 1, false, &lr.Renderer.Camera.Projection[0]) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR: OpenGL error %X", e) } return }
func renderMarker(metrics *metrics, m *game.Marker, x, y int) { switch m.State { case game.MarkerShowing: var val string switch { case m.ChainLevel > 0: val = "x" + strconv.Itoa(m.ChainLevel+1) case m.ComboLevel > 3: val = strconv.Itoa(m.ComboLevel) default: return } sc := float32(0.5) tx := -float32(len(val)-1) * sc ty := metrics.globalTranslationY + cellTranslationY*-float32(y) + easeOutCubic(m.StateProgress(metrics.fudge), 0, 0.5) tz := metrics.globalTranslationZ + cellTranslationZ/2 + 0.1 ry := metrics.globalRotationY + metrics.cellRotationY*-float32(x) yq := newAxisAngleQuaternion(yAxis, ry) qm := newQuaternionMatrix(yq.normalize()) gl.Uniform1f(brightnessUniform, 0) gl.Uniform1f(alphaUniform, easeOutCubic(m.StateProgress(metrics.fudge), 1, -1)) for _, rune := range val { text := markerRuneText[rune] m := newScaleMatrix(sc, sc, sc) m = m.mult(newTranslationMatrix(tx, ty, tz)) m = m.mult(qm) gl.UniformMatrix4fv(modelMatrixUniform, 1, false, &m[0]) gl.Uniform1i(textureUniform, int32(text.texture)-1) squareMesh.drawElements() tx++ } gl.Uniform1i(textureUniform, int32(boardTexture)-1) } }
func renderHUD(g *game.Game, fudge float32) { gl.UniformMatrix4fv(projectionViewMatrixUniform, 1, false, &orthoProjectionViewMatrix[0]) gl.Uniform1f(grayscaleUniform, 0) gl.Uniform1f(brightnessUniform, 0) gl.Uniform1f(alphaUniform, 1) i := 1 renderText := func(item game.HUDItem, val string) { text := hudItemText[item] x := float32(winWidth)/4*float32(i) - text.width/2 y := float32(winHeight) - text.height*2 text.render(x, y) var valWidth, valHeight float32 for _, rune := range val { text := hudRuneText[rune] valWidth += text.width if text.height > valHeight { valHeight = text.height } } x = float32(winWidth)/4*float32(i) - valWidth/2 y -= valHeight * 1.5 for _, rune := range val { text := hudRuneText[rune] text.render(x, y) x += text.width } i++ } renderText(game.HUDItemSpeed, formattedSpeed(g)) renderText(game.HUDItemTime, formattedTime(g)) renderText(game.HUDItemScore, formattedScore(g)) }
func renderMenu(g *game.Game, fudge float32) { ease := func(start, change float32) float32 { return easeOutCubic(g.StateProgress(fudge), start, change) } alpha := float32(1) switch g.State { case game.GameInitial, game.GamePaused: alpha = ease(0, 1) case game.GamePlaying, game.GameExiting: alpha = ease(1, -1) } // Don't render the menu if it is invisible. if alpha == 0 { return } gl.UniformMatrix4fv(projectionViewMatrixUniform, 1, false, &orthoProjectionViewMatrix[0]) gl.Uniform1f(grayscaleUniform, 0) gl.Uniform1f(brightnessUniform, 0) gl.Uniform1f(alphaUniform, alpha) gl.Uniform1f(mixAmountUniform, 0) menu := g.Menu titleText := menuTitleText[menu.ID] totalHeight := titleText.height * 2 for _, item := range menu.Items { totalHeight += float32(menuItemFontSize) * 2 if !item.SingleChoice() { totalHeight += float32(menuItemFontSize) * 2 } } currentY := (float32(winHeight) + totalHeight) / 2 centerX := func(txt *renderableText) float32 { return (float32(winWidth) - txt.width) / 2 } renderText := func(text *renderableText) { currentY -= text.height text.render(centerX(text), currentY) currentY -= text.height // add spacing for next item } // TODO(btmura): split these out into separate functions renderSlider := func(item *game.MenuItem) { val := strconv.Itoa(item.Slider.Value) var valWidth, valHeight float32 for _, rune := range val { text := menuRuneText[rune] valWidth += text.width if text.height > valHeight { valHeight = text.height } } currentY -= valHeight x := (float32(winWidth) - valWidth) / 2 for _, rune := range val { text := menuRuneText[rune] text.render(x, currentY) x += text.width } currentY -= valHeight } renderMenuItem := func(index int, item *game.MenuItem) { var brightness float32 if menu.FocusedIndex == index { switch { case menu.Selected: brightness = pulse(g.GlobalPulse+fudge, 1, 1, 1) case item.SingleChoice(): brightness = pulse(g.GlobalPulse+fudge, 1, 0.3, 0.06) default: brightness = 1 } } gl.Uniform1f(brightnessUniform, brightness) renderText(menuItemText[item.ID]) switch { case item.Selector != nil: renderText(menuChoiceText[item.Selector.Value()]) case item.Slider != nil: renderSlider(item) } } renderText(titleText) for i, item := range menu.Items { renderMenuItem(i, item) } }
func CreateContext(width, height int) Context { vertexShader := ` #version 330 uniform mat4 projection; uniform mat4 camera; uniform mat4 model; in vec3 vert; void main() { gl_Position = projection * camera * model * vec4(vert, 1); } ` + "\x00" fragmentShader := ` #version 330 uniform vec4 color; out vec4 outputColor; void main() { outputColor = color; } ` + "\x00" vertices := []float32{ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, } 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, 3) glfw.WindowHint(glfw.ContextVersionMinor, 3) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(width, height, "OpenGL", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() if err := gl.Init(); err != nil { panic(err) } program, err := newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) projection := mgl32.Ortho2D(0, 800, 0, 600) projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00")) gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0]) camera := mgl32.LookAtV(mgl32.Vec3{0, 0, 0.5}, 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]) 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(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) return Context{Window: window, program: program} }
func main() { vertices, normals := obj.Parse(os.Args[1]) // initialize GLFW if err := glfw.Init(); err != nil { panic(err) } defer glfw.Terminate() // set opengl core profile 3.3 glfw.WindowHint(glfw.ContextVersionMajor, 3) glfw.WindowHint(glfw.ContextVersionMinor, 3) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(640, 480, "GOpenGL", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // initialise OpenGL library if err := gl.Init(); err != nil { panic(err) } // link program from shaders program, err := newProgram("vertex.glsl", "fragment.glsl") if err != nil { panic(err) } gl.UseProgram(program) // vertex attribute object holds links between attributes and vbo var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) // vertex buffer with per-vertex data var vbo [2]uint32 gl.GenBuffers(2, &vbo[0]) // position data gl.BindBuffer(gl.ARRAY_BUFFER, vbo[0]) gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) // set up position attribute with layout of vertices posAttrib := uint32(gl.GetAttribLocation(program, gl.Str("position\x00"))) gl.VertexAttribPointer(posAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(posAttrib) // normal data gl.BindBuffer(gl.ARRAY_BUFFER, vbo[1]) gl.BufferData(gl.ARRAY_BUFFER, len(normals)*4, gl.Ptr(normals), gl.STATIC_DRAW) normAttrib := uint32(gl.GetAttribLocation(program, gl.Str("normal\x00"))) gl.VertexAttribPointer(normAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(normAttrib) uniModel := gl.GetUniformLocation(program, gl.Str("model\x00")) uniView := gl.GetUniformLocation(program, gl.Str("view\x00")) uniProj := gl.GetUniformLocation(program, gl.Str("proj\x00")) matView := mgl32.LookAt(2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0) gl.UniformMatrix4fv(uniView, 1, false, &matView[0]) matProj := mgl32.Perspective(mgl32.DegToRad(45.0), 640.0/480.0, 1.0, 10.0) gl.UniformMatrix4fv(uniProj, 1, false, &matProj[0]) uniLightDir := gl.GetUniformLocation(program, gl.Str("lightDir\x00")) uniLightCol := gl.GetUniformLocation(program, gl.Str("lightCol\x00")) gl.Uniform3f(uniLightDir, -0.5, 0.0, -1.0) gl.Uniform3f(uniLightCol, 0.0, 0.5, 0.5) startTime := glfw.GetTime() gl.Enable(gl.DEPTH_TEST) gl.ClearColor(1.0, 1.0, 1.0, 1.0) for !window.ShouldClose() { // clear buffer gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) matRot := mgl32.HomogRotate3DZ(float32(glfw.GetTime() - startTime)) gl.UniformMatrix4fv(uniModel, 1, false, &matRot[0]) gl.DrawArrays(gl.TRIANGLES, 0, int32(len(vertices))) window.SwapBuffers() glfw.PollEvents() } }
func (shader *MVCShader) SetMVC(mat mgl32.Mat4) { gl.UniformMatrix4fv(shader.mVCHandle, 1, false, &mat[0]) }
func (r *Renderable) Draw(perspective mgl.Mat4, view mgl.Mat4) { gl.UseProgram(r.Shader) gl.BindVertexArray(r.Vao) model := r.GetTransformMat4() var mvp mgl.Mat4 shaderMvp := getUniformLocation(r.Shader, "MVP_MATRIX") if shaderMvp >= 0 { mvp = perspective.Mul4(view).Mul4(model) gl.UniformMatrix4fv(shaderMvp, 1, false, &mvp[0]) } shaderMv := getUniformLocation(r.Shader, "MV_MATRIX") if shaderMv >= 0 { mv := view.Mul4(model) gl.UniformMatrix4fv(shaderMv, 1, false, &mv[0]) } shaderTex0 := getUniformLocation(r.Shader, "DIFFUSE_TEX") if shaderTex0 >= 0 { gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, r.Tex0) gl.Uniform1i(shaderTex0, 0) } shaderColor := getUniformLocation(r.Shader, "MATERIAL_DIFFUSE") if shaderColor >= 0 { gl.Uniform4f(shaderColor, r.Color[0], r.Color[1], r.Color[2], r.Color[3]) } shaderTex1 := getUniformLocation(r.Shader, "MATERIAL_TEX_0") if shaderTex1 >= 0 { gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, r.Tex0) gl.Uniform1i(shaderTex1, 0) } shaderCameraWorldPos := getUniformLocation(r.Shader, "CAMERA_WORLD_POSITION") if shaderCameraWorldPos >= 0 { gl.Uniform3f(shaderCameraWorldPos, -view[12], -view[13], -view[14]) } shaderPosition := getAttribLocation(r.Shader, "VERTEX_POSITION") if shaderPosition >= 0 { gl.BindBuffer(gl.ARRAY_BUFFER, r.VertVBO) gl.EnableVertexAttribArray(uint32(shaderPosition)) gl.VertexAttribPointer(uint32(shaderPosition), 3, gl.FLOAT, false, 0, gl.PtrOffset(0)) } shaderNormal := getAttribLocation(r.Shader, "VERTEX_NORMAL") if shaderNormal >= 0 { gl.BindBuffer(gl.ARRAY_BUFFER, r.NormsVBO) gl.EnableVertexAttribArray(uint32(shaderNormal)) gl.VertexAttribPointer(uint32(shaderNormal), 3, gl.FLOAT, false, 0, gl.PtrOffset(0)) } shaderVertUv := getAttribLocation(r.Shader, "VERTEX_UV_0") if shaderVertUv >= 0 { gl.BindBuffer(gl.ARRAY_BUFFER, r.UvVBO) gl.EnableVertexAttribArray(uint32(shaderVertUv)) gl.VertexAttribPointer(uint32(shaderVertUv), 2, gl.FLOAT, false, 0, gl.PtrOffset(0)) } gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.ElementsVBO) gl.DrawElements(gl.TRIANGLES, int32(r.FaceCount*3), gl.UNSIGNED_INT, gl.PtrOffset(0)) gl.BindVertexArray(0) }
func (tr *SpriteRenderer) Draw(instances []SpriteConfig) error { var ( bytesNeeded int byteoffset int count int32 data unsafe.Pointer float float32 = 0 floatSize uint32 i uint32 offset unsafe.Pointer sprite SpriteConfig stride int32 ) floatSize = uint32(unsafe.Sizeof(float)) stride = int32(unsafe.Sizeof(sprite)) gl.UseProgram(tr.program) gl.Uniform1i(tr.textureUnitLoc, 0) // Instance data binding gl.BindBuffer(gl.ARRAY_BUFFER, tr.instanceVBO) count = int32(len(instances)) bytesNeeded = int(stride * count) data = gl.Ptr(instances) if bytesNeeded > tr.instanceBytes { gl.BufferData(gl.ARRAY_BUFFER, bytesNeeded, data, gl.STREAM_DRAW) tr.instanceBytes = bytesNeeded } else { gl.BufferSubData(gl.ARRAY_BUFFER, 0, bytesNeeded, data) } gl.EnableVertexAttribArray(tr.translationLoc) gl.VertexAttribPointer(tr.translationLoc, 3, gl.FLOAT, false, stride, tr.offAttrX) gl.VertexAttribDivisor(tr.translationLoc, 1) gl.EnableVertexAttribArray(tr.rotationLoc) gl.VertexAttribPointer(tr.rotationLoc, 3, gl.FLOAT, false, stride, tr.offAttrRotationX) gl.VertexAttribDivisor(tr.rotationLoc, 1) gl.EnableVertexAttribArray(tr.scaleLoc) gl.VertexAttribPointer(tr.scaleLoc, 3, gl.FLOAT, false, stride, tr.offAttrScaleX) gl.VertexAttribDivisor(tr.scaleLoc, 1) gl.EnableVertexAttribArray(tr.colorLoc) gl.VertexAttribPointer(tr.colorLoc, 4, gl.FLOAT, false, stride, tr.offAttrColor) gl.VertexAttribDivisor(tr.colorLoc, 1) for i = 0; i < 4; i++ { byteoffset = int(i * 4 * floatSize) offset = gl.PtrOffset(tr.offAttrPointAdj + byteoffset) gl.EnableVertexAttribArray(tr.pointAdjLoc + i) gl.VertexAttribPointer(tr.pointAdjLoc+i, 4, gl.FLOAT, false, stride, offset) gl.VertexAttribDivisor(tr.pointAdjLoc+i, 1) offset = gl.PtrOffset(tr.offAttrTextureAdj + byteoffset) gl.EnableVertexAttribArray(tr.textureAdjLoc + i) gl.VertexAttribPointer(tr.textureAdjLoc+i, 4, gl.FLOAT, false, stride, offset) gl.VertexAttribDivisor(tr.textureAdjLoc+i, 1) } // Projection gl.UniformMatrix4fv(tr.projectionLoc, 1, false, &tr.Renderer.Camera.Projection[0]) // Actually draw. gl.DrawArraysInstanced(gl.TRIANGLES, 0, 6, int32(len(instances))) // Undo instance attr repetition. gl.VertexAttribDivisor(tr.translationLoc, 0) gl.VertexAttribDivisor(tr.rotationLoc, 0) gl.VertexAttribDivisor(tr.scaleLoc, 0) gl.VertexAttribDivisor(tr.colorLoc, 0) for i = 0; i < 4; i++ { gl.VertexAttribDivisor(tr.pointAdjLoc+i, 0) gl.VertexAttribDivisor(tr.textureAdjLoc+i, 0) } gl.BindBuffer(gl.ARRAY_BUFFER, 0) return nil }
func (vertexArray VertexArray) SetMVCData(mat mgl32.Mat4) { gl.UniformMatrix4fv(vertexArray.handleMVC, 1, false, &mat[0]) }
func renderBoard(g *game.Game, fudge float32) bool { if g.Board == nil { return false } b := g.Board metrics := newMetrics(g, fudge) gl.UniformMatrix4fv(projectionViewMatrixUniform, 1, false, &perspectiveProjectionViewMatrix[0]) gl.Uniform3fv(mixColorUniform, 1, &blackColor[0]) globalGrayscale := float32(1) globalDarkness := float32(0.8) var boardDarkness float32 gameEase := func(start, change float32) float32 { return easeOutCubic(g.StateProgress(fudge), start, change) } boardEase := func(start, change float32) float32 { return easeOutCubic(b.StateProgress(fudge), start, change) } switch g.State { case game.GamePlaying: globalGrayscale = gameEase(1, -1) globalDarkness = gameEase(0.8, -0.8) case game.GamePaused: globalGrayscale = gameEase(0, 1) globalDarkness = gameEase(0, 0.8) case game.GameExiting: globalGrayscale = 1 globalDarkness = gameEase(0.8, 1) } switch b.State { case game.BoardEntering: boardDarkness = boardEase(1, -1) case game.BoardExiting: boardDarkness = boardEase(0, 1) } finalDarkness := globalDarkness if finalDarkness < boardDarkness { finalDarkness = boardDarkness } gl.Uniform1f(mixAmountUniform, finalDarkness) gl.Uniform1i(textureUniform, int32(boardTexture)-1) for i := 0; i <= 2; i++ { gl.Uniform1f(grayscaleUniform, globalGrayscale) gl.Uniform1f(brightnessUniform, 0) gl.Uniform1f(alphaUniform, 1) if i == 0 { renderSelector(metrics) } for y, r := range b.Rings { for x, c := range r.Cells { switch i { case 0: // draw opaque objects switch c.Block.State { case game.BlockStatic, game.BlockSwappingFromLeft, game.BlockSwappingFromRight, game.BlockDroppingFromAbove, game.BlockFlashing: renderCellBlock(metrics, c, x, y) case game.BlockCracking, game.BlockCracked: renderCellFragments(metrics, c, x, y) } case 1: // draw transparent objects switch c.Block.State { case game.BlockExploding: renderCellFragments(metrics, c, x, y) } renderMarker(metrics, c.Marker, x, y) } } } } // Render the spare rings. // Set brightness to zero for all spare rings. gl.Uniform1f(brightnessUniform, 0) for y, r := range b.SpareRings { // Set grayscale value. First spare rings becomes colored. Rest are gray. grayscale := float32(1) if y == 0 { grayscale = easeInExpo(b.RiseProgress(fudge), 1, -1) } if grayscale < globalGrayscale { grayscale = globalGrayscale } gl.Uniform1f(grayscaleUniform, grayscale) // Set alpha value. Last spare ring fades in. Rest are opaque. alpha := float32(1) if y == len(b.SpareRings)-1 { alpha = easeInExpo(b.RiseProgress(fudge), 0, 1) } gl.Uniform1f(alphaUniform, alpha) // Render the spare rings below the normal rings. for x, c := range r.Cells { renderCellBlock(metrics, c, x, y+b.RingCount) } } return true }
func Init() error { if err := gl.Init(); err != nil { return err } log.Printf("OpenGL version: %s", gl.GoStr(gl.GetString(gl.VERSION))) vs, err := asset.String("shader.vert") if err != nil { return err } fs, err := asset.String("shader.frag") if err != nil { return err } program, err := createProgram(vs, fs) if err != nil { return err } gl.UseProgram(program) var shaderErr error uniform := func(name string) int32 { var loc int32 loc, shaderErr = getUniformLocation(program, name) return loc } projectionViewMatrixUniform = uniform("u_projectionViewMatrix") modelMatrixUniform = uniform("u_modelMatrix") normalMatrixUniform = uniform("u_normalMatrix") ambientLightColorUniform = uniform("u_ambientLightColor") directionalLightColorUniform = uniform("u_directionalLightColor") directionalVectorUniform = uniform("u_directionalVector") textureUniform = uniform("u_texture") grayscaleUniform = uniform("u_grayscale") brightnessUniform = uniform("u_brightness") alphaUniform = uniform("u_alpha") mixColorUniform = uniform("u_mixColor") mixAmountUniform = uniform("u_mixAmount") if shaderErr != nil { return shaderErr } vm := newViewMatrix(cameraPosition, targetPosition, up) nm := vm.inverse().transpose() gl.UniformMatrix4fv(normalMatrixUniform, 1, false, &nm[0]) gl.Uniform3fv(ambientLightColorUniform, 1, &ambientLightColor[0]) gl.Uniform3fv(directionalLightColorUniform, 1, &directionalLightColor[0]) gl.Uniform3fv(directionalVectorUniform, 1, &directionalVector[0]) SizeCallback = func(width, height int) { if winWidth == width && winHeight == height { return } log.Printf("window size changed (%dx%d -> %dx%d)", int(winWidth), int(winHeight), width, height) gl.Viewport(0, 0, int32(width), int32(height)) // Calculate new perspective projection view matrix. winWidth, winHeight = width, height fw, fh := float32(width), float32(height) aspect := fw / fh fovRadians := float32(math.Pi) / 3 perspectiveProjectionViewMatrix = vm.mult(newPerspectiveMatrix(fovRadians, aspect, 1, 2000)) // Calculate new ortho projection view matrix. orthoProjectionViewMatrix = newOrthoMatrix(fw, fh, fw /* use width as depth */) } if err := initMeshes(); err != nil { return err } if err := initTextures(); err != nil { return err } gl.Enable(gl.CULL_FACE) gl.CullFace(gl.BACK) gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.ClearColor(0, 0, 0, 0) return nil }
func (u *Uniform) Mat4(m mgl32.Mat4) { gl.UniformMatrix4fv(u.location, 1, false, &m[0]) }
func main() { // init glfw if err := glfw.Init(); err != nil { panic(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) // make an application window window, err := glfw.CreateWindow(windowWidth, windowHeight, "Transform", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // init gl if err := gl.Init(); err != nil { panic(err) } fmt.Println("OpenGL version", gl.GoStr(gl.GetString(gl.VERSION))) // create vertex & fragment shader 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]) gl.BindFragDataLocation(program, 0, gl.Str("vert\x00")) points := []float32{ -0.9, -0.9, -0.9, 0.9, -0.9, -0.9, 0.9, -0.9, 0.9, -0.9, -0.9, 0.9, -0.9, 0.9, -0.9, 0.9, 0.9, -0.9, 0.9, 0.9, 0.9, -0.9, 0.9, 0.9, } vertices := []uint32{ 0, 1, 1, 2, 2, 3, 3, 0, 0, 4, 1, 5, 2, 6, 3, 7, 4, 5, 5, 6, 6, 7, 7, 4, } // configure the vertex data var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) defer gl.BindVertexArray(0) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(points)*4, gl.Ptr(points), gl.STATIC_DRAW) var ibo uint32 gl.GenBuffers(1, &ibo) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) // global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(0.0, 0.0, 0.0, 1.0) angleX := 0.0 angleY := 0.0 angleZ := 0.0 previousTime := glfw.GetTime() for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) time := glfw.GetTime() elapsed := time - previousTime previousTime = time angleX += math.Sin((elapsed / period) * math.Pi * 2.0) angleY += math.Sin((elapsed / period) / 6.0 * math.Pi * 2.0) angleZ += math.Sin((elapsed / period) / 3.0 * math.Pi * 2.0) model = mgl32.HomogRotate3DY(float32(angleY)).Mul4(mgl32.HomogRotate3DX(float32(angleX))).Mul4(mgl32.HomogRotate3DZ(float32(angleZ))) gl.UseProgram(program) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindVertexArray(vao) gl.DrawElements(gl.LINES, int32(len(vertices)), gl.UNSIGNED_INT, gl.PtrOffset(0)) window.SwapBuffers() glfw.PollEvents() } }
func renderSelector(metrics *metrics) { gl.UniformMatrix4fv(modelMatrixUniform, 1, false, &metrics.selectorMatrix[0]) selectorMesh.drawElements() }
func renderCellFragments(metrics *metrics, c *game.Cell, x, y int) { const ( nw = iota ne se sw ) render := func(sc, rx, ry, rz float32, dir int) { m := newScaleMatrix(sc, sc, sc) m = m.mult(newTranslationMatrix(rx, ry, rz)) m = m.mult(metrics.blockMatrix(c.Block, x, y)) gl.UniformMatrix4fv(modelMatrixUniform, 1, false, &m[0]) fragmentMeshes[c.Block.Color][dir].drawElements() } ease := func(start, change float32) float32 { return easeOutCubic(c.Block.StateProgress(metrics.fudge), start, change) } var bv float32 var av float32 switch c.Block.State { case game.BlockCracking, game.BlockCracked: av = 1 case game.BlockExploding: bv = ease(0, 1) av = ease(1, -1) } gl.Uniform1f(brightnessUniform, bv) gl.Uniform1f(alphaUniform, av) const ( maxCrack = 0.03 maxExpand = 0.02 ) var rs float32 var rt float32 var j float32 switch c.Block.State { case game.BlockCracking: rs = ease(1, 1+maxExpand) rt = ease(0, maxCrack) j = pulse(c.Block.StateProgress(metrics.fudge), 0, 0.5, 1.5) case game.BlockCracked: rs = 1 rt = maxCrack case game.BlockExploding: rs = ease(1, -1) rt = ease(maxCrack, math.Pi*0.75) } const szt = 0.5 // starting z translation since model is 0.5 in depth wx, ex := -rt, rt fz, bz := rt+szt, -rt-szt const amp = 1 ny := rt + amp*float32(math.Sin(float64(rt))) sy := -rt + amp*(float32(math.Cos(float64(-rt)))-1) render(rs, wx+j, ny+j, fz, nw) // front north west render(rs, ex+j, ny+j, fz, ne) // front north east render(rs, wx+j, ny+j, bz, nw) // back north west render(rs, ex+j, ny+j, bz, ne) // back north east render(rs, wx+j, sy+j, fz, sw) // front south west render(rs, ex+j, sy+j, fz, se) // front south east render(rs, wx+j, sy+j, bz, sw) // back south west render(rs, ex+j, sy+j, bz, se) // back south east }