func (ctx *DrawContext) drawHud(o *orrery.Orrery, frametime time.Duration) { txt, size, err := ctx.createHudTexture(o, frametime) if err != nil { log.Fatalf(`can't create texture from text surface: %s`, err) } defer gl.DeleteTextures(1, &txt) gl.MatrixMode(gl.PROJECTION) gl.PushMatrix() gl.LoadIdentity() gl.Ortho(0.0, float64(ctx.width), float64(ctx.height), 0.0, -1.0, 1.0) gl.MatrixMode(gl.MODELVIEW) gl.LoadIdentity() gl.Clear(gl.DEPTH_BUFFER_BIT) gl.BindTexture(gl.TEXTURE_2D, txt) gl.Enable(gl.TEXTURE_2D) defer gl.Disable(gl.TEXTURE_2D) gl.Color3f(1, 1, 1) gl.Begin(gl.QUADS) gl.TexCoord2f(0, 0) gl.Vertex2f(0.0, 0.0) gl.TexCoord2f(1, 0) gl.Vertex2f(float32(size[0]), 0.0) gl.TexCoord2f(1, 1) gl.Vertex2f(float32(size[0]), float32(size[1])) gl.TexCoord2f(0, 1) gl.Vertex2f(0.0, float32(size[1])) gl.End() gl.PopMatrix() }
func drawSelection(x, y, p, w float32) { gl.LineWidth(w) gl.Begin(gl.LINE_STRIP) gl.Vertex2f(x-p, y-p) gl.Vertex2f(x+256+p, y-p) gl.Vertex2f(x+256+p, y+240+p) gl.Vertex2f(x-p, y+240+p) gl.Vertex2f(x-p, y-p) gl.End() }
func (back *glbackend) Stroke(b Bounds) { gl.Color4ub(back.current.fore.RGBA()) gl.Begin(gl.LINE_LOOP) { gl.Vertex2f(b.Min.X, b.Min.Y) gl.Vertex2f(b.Max.X, b.Min.Y) gl.Vertex2f(b.Max.X, b.Max.Y) gl.Vertex2f(b.Min.X, b.Max.Y) } gl.End() }
func (back *glbackend) Fill(b Bounds) { gl.Color4ub(back.current.back.RGBA()) gl.Begin(gl.QUADS) { gl.Vertex2f(b.Min.X, b.Min.Y) gl.Vertex2f(b.Max.X, b.Min.Y) gl.Vertex2f(b.Max.X, b.Max.Y) gl.Vertex2f(b.Min.X, b.Max.Y) } gl.End() }
func drawgl() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) gl.Begin(gl.TRIANGLES) gl.Color3f(1.0, 0.0, 0.0) gl.Vertex2f(0.5, 0.0) gl.Color3f(0.0, 1.0, 0.0) gl.Vertex2f(-0.5, -0.5) gl.Color3f(0.0, 0.0, 1.0) gl.Vertex2f(-0.5, 0.5) gl.End() }
func (stash *Stash) FlushDraw() { i := 0 texture := stash.ttTextures[i] tt := true for { if texture.nverts > 0 { gl.Enable(gl.TEXTURE_2D) gl.BindTexture(gl.TEXTURE_2D, texture.id) for k := 0; k < texture.nverts; k++ { gl.Begin(gl.QUADS) gl.Color4fv(&texture.color[0]) gl.TexCoord2f(texture.verts[k*4+2], texture.verts[k*4+3]) gl.Vertex2f(texture.verts[k*4+0], texture.verts[k*4+1]) k++ gl.Color4fv(&texture.color[0]) gl.TexCoord2f(texture.verts[k*4+2], texture.verts[k*4+3]) gl.Vertex2f(texture.verts[k*4+0], texture.verts[k*4+1]) k++ gl.Color4fv(&texture.color[0]) gl.TexCoord2f(texture.verts[k*4+2], texture.verts[k*4+3]) gl.Vertex2f(texture.verts[k*4+0], texture.verts[k*4+1]) k++ gl.Color4fv(&texture.color[0]) gl.TexCoord2f(texture.verts[k*4+2], texture.verts[k*4+3]) gl.Vertex2f(texture.verts[k*4+0], texture.verts[k*4+1]) gl.End() } gl.Disable(gl.TEXTURE_2D) texture.nverts = 0 } if tt { if i < len(stash.ttTextures)-1 { i++ texture = stash.ttTextures[i] } else { i = 0 if len(stash.bmTextures) > 0 { texture = stash.bmTextures[i] tt = false } else { break } } } else { if i < len(stash.bmTextures)-1 { i++ texture = stash.bmTextures[i] } else { break } } } }
func glRect(x, y, w, h, r, g, b, a float32) { gl.Disable(gl.TEXTURE_2D) // TODO do this once and remember the state gl.Begin(gl.QUADS) gl.Color4f(r, g, b, a) gl.Vertex2f(x, y) gl.Color4f(r, g, b, a) gl.Vertex2f(x+w, y) gl.Color4f(r, g, b, a) gl.Vertex2f(x+w, y+h) gl.Color4f(r, g, b, a) gl.Vertex2f(x, y+h) gl.End() }
func (m *menu) draw() { return // TODO gl.Disable(gl.TEXTURE_2D) gl.Begin(gl.QUADS) gl.Color4f(m.color.r, m.color.g, m.color.b, m.color.a) gl.Vertex2f(m.pos.x, m.pos.y) gl.Color4f(m.color.r, m.color.g, m.color.b, m.color.a) gl.Vertex2f(m.pos.x+m.pos.w, m.pos.y) gl.Color4f(m.color.r, m.color.g, m.color.b, m.color.a) gl.Vertex2f(m.pos.x+m.pos.w, m.pos.y+m.pos.h) gl.Color4f(m.color.r, m.color.g, m.color.b, m.color.a) gl.Vertex2f(m.pos.x, m.pos.y+m.pos.h) gl.End() }
func (atlas *FontAtlas) Draw(text string, b Bounds) { atlas.LoadGlyphs(text) gl.Enable(gl.BLEND) defer gl.Disable(gl.BLEND) gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) gl.Enable(gl.TEXTURE_2D) defer gl.Disable(gl.TEXTURE_2D) gl.BindTexture(gl.TEXTURE_2D, atlas.Texture) x := b.Min.X + atlas.drawPadding y := (b.Max.Y+b.Min.Y)/2 + (ceilPxf(atlas.maxBounds.Min.Y)+ceilPxf(atlas.maxBounds.Max.Y))/2 p := rune(0) for _, r := range text { glyph := atlas.Rendered[r] dx := float32(glyph.Loc.Dx()) dy := float32(glyph.Loc.Dy()) px := x + ceilPxf(glyph.Bounds.Min.X) - glyphPadding py := y + ceilPxf(glyph.Bounds.Min.Y) - glyphPadding // this is not the ideal way of positioning the letters // will create positioning artifacts // but it the result is more px = float32(math.Trunc(float64(px))) py = float32(math.Trunc(float64(py))) gl.Begin(gl.QUADS) { gl.TexCoord2f(glyph.RelLoc.Min.X, glyph.RelLoc.Min.Y) gl.Vertex2f(px, py) gl.TexCoord2f(glyph.RelLoc.Max.X, glyph.RelLoc.Min.Y) gl.Vertex2f(px+dx, py) gl.TexCoord2f(glyph.RelLoc.Max.X, glyph.RelLoc.Max.Y) gl.Vertex2f(px+dx, py+dy) gl.TexCoord2f(glyph.RelLoc.Min.X, glyph.RelLoc.Max.Y) gl.Vertex2f(px, py+dy) } gl.End() k := atlas.Face.Kern(p, r) p = r x += ceilPxf(glyph.Advance + k) } }
func (atlas *FontAtlas) draw(rendered *image.RGBA, b Bounds) { var texture uint32 gl.Enable(gl.TEXTURE_2D) gl.GenTextures(1, &texture) gl.BindTexture(gl.TEXTURE_2D, texture) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, int32(rendered.Bounds().Dx()), int32(rendered.Bounds().Dy()), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rendered.Pix)) gl.Enable(gl.BLEND) gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) gl.Begin(gl.QUADS) { gl.TexCoord2f(0, 0) gl.Vertex2f(b.Min.X, b.Min.Y) gl.TexCoord2f(1, 0) gl.Vertex2f(b.Max.X, b.Min.Y) gl.TexCoord2f(1, 1) gl.Vertex2f(b.Max.X, b.Max.Y) gl.TexCoord2f(0, 1) gl.Vertex2f(b.Min.X, b.Max.Y) } gl.End() gl.Disable(gl.BLEND) gl.DeleteTextures(1, &texture) gl.Disable(gl.TEXTURE_2D) }
func my_print(x, y float64, text string, ftex uint32, cdata []*truetype.BakedChar) { gl.Enable(gl.TEXTURE_2D) gl.BindTexture(gl.TEXTURE_2D, ftex) gl.Begin(gl.QUADS) for _, b := range text { if int(b) >= 32 && int(b) < 128 { var q *truetype.AlignedQuad x, q = truetype.GetBakedQuad(cdata, 512, 512, int(b)-32, x, y, true) gl.TexCoord2f(q.S0, q.T0) gl.Vertex2f(q.X0, q.Y0) gl.TexCoord2f(q.S1, q.T0) gl.Vertex2f(q.X1, q.Y0) gl.TexCoord2f(q.S1, q.T1) gl.Vertex2f(q.X1, q.Y1) gl.TexCoord2f(q.S0, q.T1) gl.Vertex2f(q.X0, q.Y1) } } gl.End() }
func piirräRuutu(x, y int, r Ruutu) { const sivu = 0.1 const tekstuuriaskel = 1.0 / KuviaTextuurissa left := float32(x)*sivu - 1 top := -float32(y)*sivu + 1 texAlku := tekstuuriaskel * float32(r) texLoppu := texAlku + tekstuuriaskel gl.TexCoord2f(texAlku, 0) gl.Vertex2f(left, top) gl.TexCoord2f(texLoppu, 0) gl.Vertex2f(left+sivu, top) gl.TexCoord2f(texLoppu, 1) gl.Vertex2f(left+sivu, top-sivu) gl.TexCoord2f(texAlku, 1) gl.Vertex2f(left, top-sivu) }
func drawBuffer(window *glfw.Window) { w, h := window.GetFramebufferSize() s1 := float32(w) / 256 s2 := float32(h) / 240 f := float32(1 - padding) var x, y float32 if s1 >= s2 { x = f * s2 / s1 y = f } else { x = f y = f * s1 / s2 } gl.Begin(gl.QUADS) gl.TexCoord2f(0, 1) gl.Vertex2f(-x, -y) gl.TexCoord2f(1, 1) gl.Vertex2f(x, -y) gl.TexCoord2f(1, 0) gl.Vertex2f(x, y) gl.TexCoord2f(0, 0) gl.Vertex2f(-x, y) gl.End() }
func drawThumbnail(x, y, tx, ty, tw, th float32) { sx := x + 4 sy := y + 4 gl.Disable(gl.TEXTURE_2D) gl.Color3f(0.2, 0.2, 0.2) gl.Begin(gl.QUADS) gl.Vertex2f(sx, sy) gl.Vertex2f(sx+256, sy) gl.Vertex2f(sx+256, sy+240) gl.Vertex2f(sx, sy+240) gl.End() gl.Enable(gl.TEXTURE_2D) gl.Color3f(1, 1, 1) gl.Begin(gl.QUADS) gl.TexCoord2f(tx, ty) gl.Vertex2f(x, y) gl.TexCoord2f(tx+tw, ty) gl.Vertex2f(x+256, y) gl.TexCoord2f(tx+tw, ty+th) gl.Vertex2f(x+256, y+240) gl.TexCoord2f(tx, ty+th) gl.Vertex2f(x, y+240) gl.End() }
func MakeRect(X, Y, Width, Height int32) Rect { rect := Rect{X, Y, Width, Height, MakeColor(255, 255, 255), NumPropertySet{0, 0, 0, 0}} x := rect.X y := rect.Y width := rect.X2 height := rect.Y2 radius := rect.BorderRadius.LEFT //TODO edit corner radius builder to use NumPropertySet for each corner if radius > 0 { gl.Color4f(1, 0, 0, 0.5) gl.Begin(gl.QUADS) gl.Vertex2i(x+radius, y+height) //4 gl.Vertex2i(x+(width-radius), y+height) //5 gl.Vertex2i(x+(width-radius), y) //10 gl.Vertex2i(x+radius, y) //11 gl.End() gl.Begin(gl.QUADS) gl.Vertex2i(x, y+radius) //1 gl.Vertex2i(x, y+(height-radius)) //2 gl.Vertex2i(x+radius, y+(height-radius)) //3 gl.Vertex2i(x+radius, y+radius) //12 gl.End() gl.Begin(gl.QUADS) gl.Vertex2i(x+(width-radius), y+(height-radius)) //6 gl.Vertex2i(x+width, y+(height-radius)) //7 gl.Vertex2i(x+width, y+radius) //8 gl.Vertex2i(x+(width-radius), y+radius) //9 gl.End() gl.Begin(gl.TRIANGLE_FAN) orginx := x orginy := y x = orginx + radius y = orginy + radius //gl.Translatef(float32(-x), float32(-y), 0) var triangleAmount = float64(48.0) //# of triangles used to draw circle //GLfloat radius = 0.8f; //radius twicePi := float64(0.5) * float64(3.14) gl.Vertex2f(float32(x), float32(y)) // center of circle for i := float64(144); i >= triangleAmount+48; i-- { gl.Vertex2f(float32(float64(x)+(float64(radius)*Cos(i*twicePi/triangleAmount))), float32(float64(y)+(float64(radius)*Sin(i*twicePi/triangleAmount)))) } gl.End() y = orginy + height - radius gl.Begin(gl.TRIANGLE_FAN) gl.Vertex2f(float32(x), float32(y)) // center of circle for i := float64(96); i >= triangleAmount; i-- { gl.Vertex2f(float32(float64(x)+(float64(radius)*Cos(i*twicePi/triangleAmount))), float32(float64(y)+(float64(radius)*Sin(i*twicePi/triangleAmount)))) } gl.End() x = orginx + width - radius gl.Begin(gl.TRIANGLE_FAN) gl.Vertex2f(float32(x), float32(y)) // center of circle for i := float64(0); i <= triangleAmount; i++ { gl.Vertex2f(float32(float64(x)+(float64(radius)*Cos(i*twicePi/triangleAmount))), float32(float64(y)+(float64(radius)*Sin(i*twicePi/triangleAmount)))) } gl.End() y = orginy + radius gl.Begin(gl.TRIANGLE_FAN) gl.Vertex2f(float32(x), float32(y)) // center of circle for i := float64(192); i >= triangleAmount+96; i-- { gl.Vertex2f(float32(float64(x)+(float64(radius)*Cos(i*twicePi/triangleAmount))), float32(float64(y)+(float64(radius)*Sin(i*twicePi/triangleAmount)))) } gl.End() } else { gl.Begin(gl.QUADS) gl.Vertex2i(x, y) gl.Vertex2i(x, y+height) gl.Vertex2i(x+width, y+height) gl.Vertex2i(x+width, y) gl.End() } // if rect.Stroke.BOTTOM.Width < 1 || rect.Stroke.LEFT.Width < 1 || rect.Stroke.RIGHT.Width < 1 || rect.Stroke.TOP.Width < 1 { // //BOTTOM // if rect.Stroke.BOTTOM.Width < 1 { // gl.Begin(gl.LINE) // gl.Color4f(float32(float32(rect.Stroke.BOTTOM.Fill.R)*0.0039), float32(float32(rect.Stroke.BOTTOM.Fill.G)*0.0039), float32(float32(rect.Stroke.BOTTOM.Fill.B)*0.0039), float32(float32(rect.Stroke.BOTTOM.Fill.A)*0.0039)) // gl.Vertex2i(x, y+height) // gl.Vertex2i(x+width, y+height) // gl.End() // } else if rect.Stroke.LEFT.Width < 1 { // gl.Begin(gl.LINE) // gl.Color4f(float32(float32(rect.Stroke.LEFT.Fill.R)*0.0039), float32(float32(rect.Stroke.LEFT.Fill.G)*0.0039), float32(float32(rect.Stroke.LEFT.Fill.B)*0.0039), float32(float32(rect.Stroke.LEFT.Fill.A)*0.0039)) // gl.Vertex2i(x, y) // gl.Vertex2i(x, y+height) // gl.End() // } else if rect.Stroke.TOP.Width < 1 { // gl.Begin(gl.LINE) // gl.Color4f(float32(float32(rect.Stroke.TOP.Fill.R)*0.0039), float32(float32(rect.Stroke.TOP.Fill.G)*0.0039), float32(float32(rect.Stroke.TOP.Fill.B)*0.0039), float32(float32(rect.Stroke.TOP.Fill.A)*0.0039)) // gl.Vertex2i(x, y) // gl.Vertex2i(x+width, y) // gl.End() // } else if rect.Stroke.RIGHT.Width < 1 { // gl.Begin(gl.LINE) // gl.Color4f(float32(float32(rect.Stroke.RIGHT.Fill.R)*0.0039), float32(float32(rect.Stroke.RIGHT.Fill.G)*0.0039), float32(float32(rect.Stroke.RIGHT.Fill.B)*0.0039), float32(float32(rect.Stroke.RIGHT.Fill.A)*0.0039)) // gl.Vertex2i(x+width, y) // gl.Vertex2i(x+width, y+height) // gl.End() // } // //LEFT // //TOP // //RIGHT // gl.Begin(gl.LINES) // gl.Vertex2i(x, y) // gl.Vertex2i(x, y+height) // gl.Vertex2i(x+width, y+height) // gl.Vertex2i(x+width, y) // } return rect }
// 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 = 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. gl.GenTextures(1, &f.texture) gl.BindTexture(gl.TEXTURE_2D, f.texture) 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, int32(ib.Dx()), int32(ib.Dy()), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(img.Pix)) // Create display lists for each glyph. f.listbase = gl.GenLists(int32(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+uint32(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 = checkGLError() return }