//Draws all the sprites in the supplied slice func (sheet SpriteSheet) Draw(sprites []*Sprite) { gl.Enable(gl.TEXTURE_2D) sheet.texture.Bind(gl.TEXTURE_2D) for _, sprite := range sprites { gl.Begin(gl.TRIANGLE_STRIP) { gl.TexCoord2f(sprite.left, sprite.bottom) gl.Vertex2f(sprite.X, sprite.Y) gl.TexCoord2f(sprite.left, sprite.top) gl.Vertex2f(sprite.X, sprite.Y+sprite.H) gl.TexCoord2f(sprite.right, sprite.bottom) gl.Vertex2f(sprite.X+sprite.W, sprite.Y) gl.TexCoord2f(sprite.right, sprite.top) gl.Vertex2f(sprite.X+sprite.W, sprite.Y+sprite.H) } gl.End() } sheet.texture.Unbind(gl.TEXTURE_2D) gl.Disable(gl.TEXTURE_2D) }
func drawPaddle(x float32, y float32) { gl.PushMatrix() gl.Translatef(float32(x), float32(y), 0) gl.Color3f(1.0, 1.0, 1.0) gl.Begin(gl.LINE_STRIP) gl.Vertex2f(0, -5) gl.Vertex2f(0, 5) gl.End() gl.PopMatrix() }
func drawQuad(srcwidth, destwidth, srcheight, destheight float32) { gl.Begin(gl.QUADS) gl.TexCoord2i(0, 0) gl.Vertex2f(-1, -1) gl.TexCoord2i(int(srcwidth), 0) gl.Vertex2f(-1+destwidth, -1) gl.TexCoord2i(int(srcwidth), int(srcheight)) gl.Vertex2f(-1+destwidth, -1+destheight) gl.TexCoord2i(0, int(srcheight)) gl.Vertex2f(-1, -1+destheight) gl.End() }
func drawBall(angle float32, ball_x float32, ball_y float32) { gl.PushMatrix() gl.Color3f(1, 1, 1) gl.Translatef(ball_x, ball_y, 0.0) gl.Begin(gl.LINE_LOOP) for rad := 0.0; rad < 1.0; rad += 0.01 { gl.Vertex2f( float32(2.0*math.Cos(2.0*math.Pi*rad)), float32(2.0*math.Sin(2.0*math.Pi*rad)+0.2)) } gl.End() gl.Rotatef(angle, 0.0, 0.0, 1.0) gl.Begin(gl.LINE_STRIP) gl.Vertex2f(0, 0) gl.Vertex2f(2, 0) gl.End() gl.PopMatrix() }
func display() { gl.Clear(gl.COLOR_BUFFER_BIT) gl.Begin(gl.TRIANGLES) l := t.units for e := l.Front(); e != nil; e = e.Next() { b := e.Value.(*Entity) //r := b.rot_matrix p := b.pos gl.Color3f(0.0, 0.0, 1.0) /* blue */ gl.Vertex2f(p[0], p[1]) gl.Color3f(0.0, 1.0, 0.0) /* green */ gl.Vertex2f(20+p[0], 20+p[1]) gl.Color3f(1.0, 0.0, 0.0) /* red */ gl.Vertex2f(p[0], 20+p[1]) } gl.End() gl.Flush() /* Single buffered, so needs a flush. */ glut.SwapBuffers() }
func main() { err := initGL() if err != nil { log.Printf("InitGL: %v", err) return } defer glfw.Terminate() // Create our texture atlas. atlas := glh.NewTextureAtlas(AtlasSize, AtlasSize, 4) defer atlas.Release() // Fill the altas with image data. fillAtlas(atlas) // Display the atlas texture on a quad, so we can see // what it looks like. for glfw.WindowParam(glfw.Opened) > 0 { gl.Clear(gl.COLOR_BUFFER_BIT) // Bind the atlas texture and render a quad with it. atlas.Bind(gl.TEXTURE_2D) gl.Begin(gl.QUADS) gl.TexCoord2f(0, 0) gl.Vertex2f(0, 0) gl.TexCoord2f(1, 0) gl.Vertex2f(AtlasSize, 0) gl.TexCoord2f(1, 1) gl.Vertex2f(AtlasSize, AtlasSize) gl.TexCoord2f(0, 1) gl.Vertex2f(0, AtlasSize) gl.End() atlas.Unbind(gl.TEXTURE_2D) glfw.SwapBuffers() } }
// vertex draws vertices. // Used in classic render mode. func (a *Attr) vertex(i int) { i *= a.size switch a.size { case 2: switch v := a.data.(type) { case []int16: gl.Vertex2s(v[i], v[i+1]) case []int32: gl.Vertex2i(int(v[i]), int(v[i+1])) case []float32: gl.Vertex2f(v[i], v[i+1]) case []float64: gl.Vertex2d(v[i], v[i+1]) } case 3: switch v := a.data.(type) { case []int16: gl.Vertex3s(v[i], v[i+1], v[i+2]) case []int32: gl.Vertex3i(int(v[i]), int(v[i+1]), int(v[i+2])) case []float32: gl.Vertex3f(v[i], v[i+1], v[i+2]) case []float64: gl.Vertex3d(v[i], v[i+1], v[i+2]) } case 4: switch v := a.data.(type) { case []int16: gl.Vertex4s(v[i], v[i+1], v[i+2], v[i+3]) case []int32: gl.Vertex4i(int(v[i]), int(v[i+1]), int(v[i+2]), int(v[i+3])) case []float32: gl.Vertex4f(v[i], v[i+1], v[i+2], v[i+3]) case []float64: gl.Vertex4d(v[i], v[i+1], v[i+2], v[i+3]) } } }
func (r *RenderTarget) Render(verts []Vertex, primType PrimitiveType, states RenderStates) { // Nothing to draw? if len(verts) == 0 { return } // First set the persistent OpenGL states if it's the very first call if !r.glStatesSet { r.resetGlStates() } // Check if the vertex count is low enough so that we can pre-transform them // TODO: Fix vertex cache useVertexCache := /*len(verts) <= vertexCacheSize*/ false if useVertexCache { // Pre-transform the vertices and store them into the vertex cache for i := 0; i < len(verts); i++ { r.vertexCache[i].Pos = states.Transform.TransformPoint(verts[i].Pos) r.vertexCache[i].Color = verts[i].Color r.vertexCache[i].TexCoords = verts[i].TexCoords } // Since vertices are transformed, we must use an identity transform to render them if !r.useVertexCache { r.applyTransform(IdentityTransform()) } } else { r.applyTransform(states.Transform) } // Apply the view if r.viewChanged { r.applyCurrentView() } // Apply the blend mode if states.BlendMode != r.lastBlendMode { //r.applyBlendMode(states.BlendMode) } // Apply the texture var textureId uint64 if states.Texture != nil { textureId = states.Texture.cacheId } if textureId != r.lastTextureId { r.applyTexture(states.Texture) } // Apply the shader // TODO /*if states.shader { applyShader(states.shader); }*/ // If we pre-transform the vertices, we must use our internal vertex cache if useVertexCache { // ... and if we already used it previously, we don't need to set the pointers again if !r.useVertexCache { verts = r.vertexCache[:] } else { verts = nil } } // ######################################### if len(verts) > 0 { // Find the OpenGL primitive type modes := [...]gl.GLenum{gl.POINTS, gl.LINES, gl.LINE_STRIP, gl.TRIANGLES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, gl.QUADS} mode := modes[primType] gl.Begin(mode) for i, _ := range verts { gl.TexCoord2f(verts[i].TexCoords.X, verts[i].TexCoords.Y) gl.Color4f(verts[i].Color.R/255, verts[i].Color.G/255, verts[i].Color.B/255, verts[i].Color.A/255) gl.Vertex2f(verts[i].Pos.X, verts[i].Pos.Y) } gl.End() } // ######################################### // Setup the pointers to the vertices' components /*if len(verts) > 0 { vData := make([]Vector2, len(verts)) //cData := make([]byte, len(verts)) tData := make([]Vector2, len(verts)) for i, _ := range verts { vData[i] = verts[i].Pos //cData[i] = verts[i].Color tData[i] = verts[i].TexCoords } //const char* data = reinterpret_cast<const char*>(vertices); gl.VertexPointer(2, gl.FLOAT, 0, vData) //gl.ColorPointer(4, gl.UNSIGNED_BYTE, unsafe.Sizeof(Vertex), cData)) gl.TexCoordPointer(2, gl.FLOAT, 0, tData) } // Find the OpenGL primitive type modes := [...]gl.GLenum{gl.POINTS, gl.LINES, gl.LINE_STRIP, gl.TRIANGLES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, gl.QUADS} mode := modes[primType] // Draw the primitives gl.DrawArrays(mode, 0, len(verts))*/ // Unbind the shader, if any // TODO /*if (states.shader) { r.applyShader(nil) }*/ // Update the cache r.useVertexCache = useVertexCache }
// loadFont loads the given font data. This does not deal with font scaling. // Scaling should be handled by the independent Bitmap/Truetype loaders. // We therefore expect the supplied image and charset to already be adjusted // to the correct font scale. // // The image should hold a sprite sheet, defining the graphical layout for // every glyph. The config describes font metadata. func loadFont(img *image.RGBA, config *FontConfig) (f *Font, err error) { f = new(Font) f.config = config // Resize image to next power-of-two. img = glh.Pow2Image(img).(*image.RGBA) ib := img.Bounds() // Create the texture itself. It will contain all glyphs. // Individual glyph-quads display a subset of this texture. f.texture = gl.GenTexture() f.texture.Bind(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, ib.Dx(), ib.Dy(), 0, gl.RGBA, gl.UNSIGNED_BYTE, img.Pix) // Create display lists for each glyph. f.listbase = gl.GenLists(len(config.Glyphs)) texWidth := float32(ib.Dx()) texHeight := float32(ib.Dy()) for index, glyph := range config.Glyphs { // Update max glyph bounds. if glyph.Width > f.maxGlyphWidth { f.maxGlyphWidth = glyph.Width } if glyph.Height > f.maxGlyphHeight { f.maxGlyphHeight = glyph.Height } // Quad width/height vw := float32(glyph.Width) vh := float32(glyph.Height) // Texture coordinate offsets. tx1 := float32(glyph.X) / texWidth ty1 := float32(glyph.Y) / texHeight tx2 := (float32(glyph.X) + vw) / texWidth ty2 := (float32(glyph.Y) + vh) / texHeight // Advance width (or height if we render top-to-bottom) adv := float32(glyph.Advance) gl.NewList(f.listbase+uint(index), gl.COMPILE) { gl.Begin(gl.QUADS) { gl.TexCoord2f(tx1, ty2) gl.Vertex2f(0, 0) gl.TexCoord2f(tx2, ty2) gl.Vertex2f(vw, 0) gl.TexCoord2f(tx2, ty1) gl.Vertex2f(vw, vh) gl.TexCoord2f(tx1, ty1) gl.Vertex2f(0, vh) } gl.End() switch config.Dir { case LeftToRight: gl.Translatef(adv, 0, 0) case RightToLeft: gl.Translatef(-adv, 0, 0) case TopToBottom: gl.Translatef(0, -adv, 0) } } gl.EndList() } err = glh.CheckGLError() return }
func (r *RenderTarget) Render(verts []Vertex, primType PrimitiveType, states RenderStates) { // Nothing to draw? if len(verts) == 0 { return } // First set the persistent OpenGL states if it's the very first call if !r.glStatesSet { r.resetGlStates() } // Check if the vertex count is low enough so that we can pre-transform them useVertexCache := len(verts) <= vertexCacheSize if useVertexCache { // Pre-transform the vertices and store them into the vertex cache for i := 0; i < len(verts); i++ { r.vpCache[i] = states.Transform.TransformPoint(verts[i].Pos) r.vcCache[i] = verts[i].Color r.vtCache[i] = verts[i].TexCoords } // Since vertices are transformed, we must use an identity transform to render them if !r.useVertexCache { r.applyTransform(IdentityTransform()) } } else { r.applyTransform(states.Transform) } // Apply the view if r.viewChanged { r.applyCurrentView() } // Apply the blend mode if states.BlendMode != r.lastBlendMode { r.applyBlendMode(states.BlendMode) } // Apply the texture var textureId uint64 if states.Texture != nil { textureId = states.Texture.cacheId } if textureId != r.lastTextureId { r.applyTexture(states.Texture) } // Apply the shader // TODO /*if states.shader { applyShader(states.shader); }*/ // ######################################### if !useVertexCache { // Find the OpenGL primitive type modes := [...]gl.GLenum{gl.POINTS, gl.LINES, gl.LINE_STRIP, gl.TRIANGLES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, gl.QUADS} mode := modes[primType] gl.Begin(mode) for i, _ := range verts { gl.TexCoord2f(verts[i].TexCoords.X, verts[i].TexCoords.Y) gl.Color4f(float32(verts[i].Color.R)/255, float32(verts[i].Color.G)/255, float32(verts[i].Color.B)/255, float32(verts[i].Color.A)/255) gl.Vertex2f(verts[i].Pos.X, verts[i].Pos.Y) } gl.End() } // ######################################### // Setup the pointers to the vertices' components // ... and if we already used it previously, we don't need to set the pointers again if useVertexCache { if !r.useVertexCache { gl.VertexPointer(2, gl.FLOAT, 0, r.vpCache[:]) gl.ColorPointer(4, gl.UNSIGNED_BYTE, 0, r.vcCache[:]) gl.TexCoordPointer(2, gl.FLOAT, 0, r.vtCache[:]) } // Find the OpenGL primitive type modes := [...]gl.GLenum{gl.POINTS, gl.LINES, gl.LINE_STRIP, gl.TRIANGLES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, gl.QUADS} mode := modes[primType] // Draw the primitives gl.DrawArrays(mode, 0, len(verts)) } // Unbind the shader, if any // TODO /*if (states.shader) { r.applyShader(nil) }*/ // Update the cache r.useVertexCache = useVertexCache }
func renderBlock_(color ColorDef, w, h, radius, lineWidth float32) { setColor(color) gl.Begin(gl.QUADS) // Render inner square gl.Vertex2f(radius, radius) gl.Vertex2f(radius, h-radius) gl.Vertex2f(w-radius, h-radius) gl.Vertex2f(w-radius, radius) // Render top square gl.Vertex2f(radius, h-radius) gl.Vertex2f(radius, h) gl.Vertex2f(w-radius, h) gl.Vertex2f(w-radius, h-radius) // Render bottom square gl.Vertex2f(radius, radius) gl.Vertex2f(radius, 0) gl.Vertex2f(w-radius, 0) gl.Vertex2f(w-radius, radius) // Render left square gl.Vertex2f(w-radius, radius) gl.Vertex2f(w, radius) gl.Vertex2f(w, h-radius) gl.Vertex2f(w-radius, h-radius) // Render right square gl.Vertex2f(radius, radius) gl.Vertex2f(0, radius) gl.Vertex2f(0, h-radius) gl.Vertex2f(radius, h-radius) gl.End() // Render bottom right corner ww, hh := float64(w-radius), float64(h-radius) renderCorner(color, ww, hh, 0, radius, lineWidth) // Render bottom left corner ww, hh = float64(radius), float64(h-radius) renderCorner(color, ww, hh, 1, radius, lineWidth) // Render top left corner ww, hh = float64(radius), float64(radius) renderCorner(color, ww, hh, 2, radius, lineWidth) // Render top right corner ww, hh = float64(w-radius), float64(radius) renderCorner(color, ww, hh, 3, radius, lineWidth) if lineWidth != 0 { // Render the shape gl.LineWidth(lineWidth) gl.Color3i(0, 0, 0) gl.Begin(gl.LINES) gl.Vertex2f(radius, 0) gl.Vertex2f(w-radius, 0) gl.Vertex2f(0, radius) gl.Vertex2f(0, h-radius) gl.Vertex2f(w, radius) gl.Vertex2f(w, h-radius) gl.Vertex2f(radius, h) gl.Vertex2f(w-radius, h) gl.End() } gl.PopMatrix() }