func (w *TextEditLine) Draw(region Region) { region.PushClipPlanes() defer region.PopClipPlanes() gl.Disable(gl.TEXTURE_2D) gl.Color4d(0.3, 0.3, 0.3, 0.9) gl.Begin(gl.QUADS) gl.Vertex2i(region.X+1, region.Y+1) gl.Vertex2i(region.X+1, region.Y-1+region.Dy) gl.Vertex2i(region.X-1+region.Dx, region.Y-1+region.Dy) gl.Vertex2i(region.X-1+region.Dx, region.Y+1) gl.End() w.TextLine.preDraw(region) w.TextLine.coreDraw(region) gl.Disable(gl.TEXTURE_2D) if w.cursor.on { gl.Color3d(1, 0.3, 0) } else { gl.Color3d(0.5, 0.3, 0) } gl.Begin(gl.LINES) gl.Vertex2i(region.X+int(w.cursor.pos), region.Y) gl.Vertex2i(region.X+int(w.cursor.pos), region.Y+region.Dy) gl.End() w.TextLine.postDraw(region) }
func (te *TextEntry) RenderAt(x, y int) { te.Button.RenderAt(x, y) d := base.GetDictionary(te.Button.Text.Size) x += te.Entry.X y += te.Button.Y x2 := x + te.Entry.Dx y2 := y + int(d.MaxHeight()) te.Entry.bounds.x = x te.Entry.bounds.y = y te.Entry.bounds.dx = x2 - x te.Entry.bounds.dy = y2 - y gl.Disable(gl.TEXTURE_2D) if te.Entry.entering { gl.Color4ub(255, 255, 255, 255) } else { gl.Color4ub(255, 255, 255, 128) } gl.Begin(gl.QUADS) gl.Vertex2i(x-3, y-3) gl.Vertex2i(x-3, y2+3) gl.Vertex2i(x2+3, y2+3) gl.Vertex2i(x2+3, y-3) gl.End() gl.Color4ub(0, 0, 0, 255) gl.Begin(gl.QUADS) gl.Vertex2i(x, y) gl.Vertex2i(x, y2) gl.Vertex2i(x2, y2) gl.Vertex2i(x2, y) gl.End() gl.Color4ub(255, 255, 255, 255) d.RenderString(te.Entry.text, float64(x), float64(y), 0, d.MaxHeight(), gui.Left) if te.Entry.ghost.offset >= 0 { gl.Disable(gl.TEXTURE_2D) gl.Color4ub(255, 100, 100, 127) gl.Begin(gl.LINES) gl.Vertex2i(te.Entry.bounds.x+te.Entry.ghost.offset, te.Entry.bounds.y) gl.Vertex2i(te.Entry.bounds.x+te.Entry.ghost.offset, te.Entry.bounds.y+te.Entry.bounds.dy) gl.End() } if te.Entry.entering { gl.Disable(gl.TEXTURE_2D) gl.Color4ub(255, 100, 100, 255) gl.Begin(gl.LINES) gl.Vertex2i(te.Entry.bounds.x+te.Entry.cursor.offset, te.Entry.bounds.y) gl.Vertex2i(te.Entry.bounds.x+te.Entry.cursor.offset, te.Entry.bounds.y+te.Entry.bounds.dy) gl.End() } }
func (rv *RoomViewer) drawFloor() { gl.MatrixMode(gl.MODELVIEW) gl.PushMatrix() gl.LoadIdentity() gl.MultMatrixf(&rv.mat[0]) defer gl.PopMatrix() gl.Disable(gl.TEXTURE_2D) gl.Color4f(1, 0, 1, 0.9) if rv.edit_mode == editCells { gl.LineWidth(0.02 * rv.zoom) } else { gl.LineWidth(0.05 * rv.zoom) } gl.Begin(gl.LINES) for i := float32(0); i < float32(rv.room.Size.Dx); i += 1.0 { gl.Vertex2f(i, 0) gl.Vertex2f(i, float32(rv.room.Size.Dy)) } for j := float32(0); j < float32(rv.room.Size.Dy); j += 1.0 { gl.Vertex2f(0, j) gl.Vertex2f(float32(rv.room.Size.Dx), j) } gl.End() if rv.edit_mode == editCells { gl.Disable(gl.TEXTURE_2D) gl.Color4d(1, 0, 0, 1) gl.LineWidth(0.05 * rv.zoom) gl.Begin(gl.LINES) for _, f := range rv.room.Furniture { x, y := f.Pos() dx, dy := f.Dims() gl.Vertex2i(x, y) gl.Vertex2i(x, y+dy) gl.Vertex2i(x, y+dy) gl.Vertex2i(x+dx, y+dy) gl.Vertex2i(x+dx, y+dy) gl.Vertex2i(x+dx, y) gl.Vertex2i(x+dx, y) gl.Vertex2i(x, y) } gl.End() } gl.Disable(gl.STENCIL_TEST) }
func (cb *checkBox) Draw(region Region) { cb.Render_region = region if cb.disabled { gl.Color3d(0.6, 0.6, 0.6) } else { gl.Color3d(1, 1, 1) } gl.Begin(gl.QUADS) gl.Vertex2i(region.X, region.Y) gl.Vertex2i(region.X, region.Y+region.Dy) gl.Vertex2i(region.X+region.Dx, region.Y+region.Dy) gl.Vertex2i(region.X+region.Dx, region.Y) if cb.selected == checkBoxUnknown || cb.selected == checkBoxUnselected { if cb.selected == checkBoxUnknown { gl.Color3d(0.4, 0.4, 0.4) } else { gl.Color3d(0, 0, 0) } if region.Dx >= 4 && region.Dy >= 4 { gl.Vertex2i(region.X+2, region.Y+2) gl.Vertex2i(region.X+2, region.Y+region.Dy-2) gl.Vertex2i(region.X+region.Dx-2, region.Y+region.Dy-2) gl.Vertex2i(region.X+region.Dx-2, region.Y+2) } } gl.End() }
func (w *ImageBox) Draw(region Region) { w.Render_region = region // We check texture == 0 and not active because active only indicates if we // have a texture that we need to free later. It's possible for us to have // a texture that someone else owns. if w.texture == 0 { return } gl.Enable(gl.TEXTURE_2D) w.texture.Bind(gl.TEXTURE_2D) gl.Enable(gl.BLEND) gl.Color4d(w.r, w.g, w.b, w.a) gl.Begin(gl.QUADS) gl.TexCoord2f(0, 0) gl.Vertex2i(region.X, region.Y) gl.TexCoord2f(0, -1) gl.Vertex2i(region.X, region.Y+region.Dy) gl.TexCoord2f(1, -1) gl.Vertex2i(region.X+region.Dx, region.Y+region.Dy) gl.TexCoord2f(1, 0) gl.Vertex2i(region.X+region.Dx, region.Y) gl.End() gl.Disable(gl.TEXTURE_2D) }
func (w *TextLine) preDraw(region Region) { if !w.initted { w.initted = true w.texture = gl.GenTexture() w.text = w.next_text w.figureDims() } if w.text != w.next_text { w.text = w.next_text w.figureDims() } gl.PushMatrix() gl.Color3d(0, 0, 0) gl.Begin(gl.QUADS) gl.Vertex2i(region.X, region.Y) gl.Vertex2i(region.X, region.Y+region.Dy) gl.Vertex2i(region.X+region.Dx, region.Y+region.Dy) gl.Vertex2i(region.X+region.Dx, region.Y) gl.End() gl.PushAttrib(gl.TEXTURE_BIT) gl.Enable(gl.TEXTURE_2D) w.texture.Bind(gl.TEXTURE_2D) gl.PushAttrib(gl.COLOR_BUFFER_BIT) gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) }
func (a *BasicAttack) RenderOnFloor() { gl.Disable(gl.TEXTURE_2D) gl.Begin(gl.QUADS) gl.Color4d(1.0, 0.2, 0.2, 0.8) for _, ent := range a.targets { ix, iy := ent.Pos() x := float64(ix) y := float64(iy) gl.Vertex2d(x+0, y+0) gl.Vertex2d(x+0, y+1) gl.Vertex2d(x+1, y+1) gl.Vertex2d(x+1, y+0) } gl.End() }
func (c *Console) DrawFocused(region gui.Region) { gl.Color4d(0.2, 0, 0.3, 0.8) gl.Disable(gl.TEXTURE_2D) gl.Begin(gl.QUADS) gl.Vertex2i(region.X, region.Y) gl.Vertex2i(region.X, region.Y+region.Dy) gl.Vertex2i(region.X+region.Dx, region.Y+region.Dy) gl.Vertex2i(region.X+region.Dx, region.Y) gl.End() gl.Color4d(1, 1, 1, 1) y := float64(region.Y) + float64(len(c.lines))*c.dict.MaxHeight() do_color := func(line string) { if strings.HasPrefix(line, "LOG") { gl.Color4d(1, 1, 1, 1) } if strings.HasPrefix(line, "WARN") { gl.Color4d(1, 1, 0, 1) } if strings.HasPrefix(line, "ERROR") { gl.Color4d(1, 0, 0, 1) } } if c.start > c.end { for i := c.start; i < len(c.lines); i++ { do_color(c.lines[i]) c.dict.RenderString(c.lines[i], c.xscroll, y, 0, c.dict.MaxHeight(), gui.Left) y -= c.dict.MaxHeight() } for i := 0; i < c.end; i++ { do_color(c.lines[i]) c.dict.RenderString(c.lines[i], c.xscroll, y, 0, c.dict.MaxHeight(), gui.Left) y -= c.dict.MaxHeight() } } else { for i := c.start; i < c.end && i < len(c.lines); i++ { do_color(c.lines[i]) c.dict.RenderString(c.lines[i], c.xscroll, y, 0, c.dict.MaxHeight(), gui.Left) y -= c.dict.MaxHeight() } } c.dict.RenderString(string(c.cmd), c.xscroll, y, 0, c.dict.MaxHeight(), gui.Left) }
func setupTextureList() { textureListSync.Do(func() { render.Queue(func() { textureList = gl.GenLists(1) gl.NewList(textureList, gl.COMPILE) gl.Begin(gl.QUADS) gl.TexCoord2d(0, 0) gl.Vertex2i(0, 0) gl.TexCoord2d(0, -1) gl.Vertex2i(0, 1) gl.TexCoord2d(1, -1) gl.Vertex2i(1, 1) gl.TexCoord2d(1, 0) gl.Vertex2i(1, 0) gl.End() gl.EndList() }) }) }
func (w *TextLine) coreDraw(region Region) { if region.Size() == 0 { return } gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) gl.Color4d(1.0, 1.0, 1.0, 1.0) req := w.Request_dims if req.Dx > region.Dx { req.Dx = region.Dx } if req.Dy > region.Dy { req.Dy = region.Dy } if req.Dx*region.Dy < req.Dy*region.Dx { req.Dy = (region.Dy * req.Dx) / region.Dx } else { req.Dx = (region.Dx * req.Dy) / region.Dy } w.Render_region.Dims = req w.Render_region.Point = region.Point tx := float64(w.rdims.Dx) / float64(w.rgba.Bounds().Dx()) ty := float64(w.rdims.Dy) / float64(w.rgba.Bounds().Dy()) // w.scale = float64(w.Render_region.Dx) / float64(w.rdims.Dx) { r, g, b, a := w.color.RGBA() gl.Color4d(float64(r)/65535, float64(g)/65535, float64(b)/65535, float64(a)/65535) } gl.Begin(gl.QUADS) gl.TexCoord2d(0, 0) gl.Vertex2i(region.X, region.Y) gl.TexCoord2d(0, -ty) gl.Vertex2i(region.X, region.Y+w.rdims.Dy) gl.TexCoord2d(tx, -ty) gl.Vertex2i(region.X+w.rdims.Dx, region.Y+w.rdims.Dy) gl.TexCoord2d(tx, 0) gl.Vertex2i(region.X+w.rdims.Dx, region.Y) gl.End() }
func (w *VerticalTable) Draw(region Region) { gl.Enable(gl.BLEND) gl.Disable(gl.TEXTURE_2D) dx := region.Dx if dx > w.Request_dims.Dx && !w.Ex { dx = w.Request_dims.Dx } dy := region.Dy if dy > w.Request_dims.Dy && !w.Ex { dy = w.Request_dims.Dy } gl.Color4d( w.params.Background.R, w.params.Background.G, w.params.Background.B, w.params.Background.A) gl.Begin(gl.QUADS) gl.Vertex2i(region.X, region.Y+region.Dy-dy) gl.Vertex2i(region.X, region.Y+region.Dy) gl.Vertex2i(region.X+dx, region.Y+region.Dy) gl.Vertex2i(region.X+dx, region.Y+region.Dy-dy) gl.End() gl.Color4d( w.params.Border.R, w.params.Border.G, w.params.Border.B, w.params.Border.A) gl.Begin(gl.LINES) gl.Vertex2i(region.X, region.Y+region.Dy-dy) gl.Vertex2i(region.X, region.Y+region.Dy) gl.Vertex2i(region.X, region.Y+region.Dy) gl.Vertex2i(region.X+dx, region.Y+region.Dy) gl.Vertex2i(region.X+dx, region.Y+region.Dy) gl.Vertex2i(region.X+dx, region.Y+region.Dy-dy) gl.Vertex2i(region.X+dx, region.Y+region.Dy-dy) gl.Vertex2i(region.X, region.Y+region.Dy-dy) gl.End() fill_available := region.Dy - w.Request_dims.Dy if fill_available < 0 { fill_available = 0 } fill_request := 0 for _, child := range w.Children { if _, ey := child.Expandable(); ey { fill_request += child.Requested().Dy } } var child_region Region child_region.Y = region.Y + region.Dy for _, child := range w.Children { child_region.Dims = child.Requested() if _, ey := child.Expandable(); ey && fill_request > 0 { child_region.Dy += (child_region.Dy * fill_available) / fill_request } if region.Dy < w.Request_dims.Dy { child_region.Dims.Dy *= region.Dy child_region.Dims.Dy /= w.Request_dims.Dy } if child_region.Dx > region.Dx { child_region.Dx = region.Dx } if ex, _ := child.Expandable(); child_region.Dx < region.Dx && ex { child_region.Dx = region.Dx } child_region.X = region.X child_region.Y -= child_region.Dy child_region.Y -= w.params.Spacing child.Draw(child_region) } w.Render_region = region }
func (m *MainBar) Draw(region gui.Region) { m.region = region gl.Enable(gl.TEXTURE_2D) m.layout.Background.Data().Bind() gl.Color4d(1, 1, 1, 1) gl.Begin(gl.QUADS) gl.TexCoord2d(0, 0) gl.Vertex2i(region.X, region.Y) gl.TexCoord2d(0, -1) gl.Vertex2i(region.X, region.Y+region.Dy) gl.TexCoord2d(1, -1) gl.Vertex2i(region.X+region.Dx, region.Y+region.Dy) gl.TexCoord2d(1, 0) gl.Vertex2i(region.X+region.Dx, region.Y) gl.End() buttons := m.no_actions_buttons if m.ent != nil && len(m.ent.Actions) > m.layout.Actions.Count { buttons = m.all_buttons } for _, button := range buttons { button.RenderAt(region.X, region.Y) } ent := m.game.HoveredEnt() if ent == nil { ent = m.ent } if ent != nil && ent.Stats != nil { gl.Color4d(1, 1, 1, 1) ent.Still.Data().Bind() tdx := ent.Still.Data().Dx() tdy := ent.Still.Data().Dy() cx := region.X + m.layout.CenterStillFrame.X cy := region.Y + m.layout.CenterStillFrame.Y gl.Begin(gl.QUADS) gl.TexCoord2d(0, 0) gl.Vertex2i(cx-tdx/2, cy-tdy/2) gl.TexCoord2d(0, -1) gl.Vertex2i(cx-tdx/2, cy+tdy/2) gl.TexCoord2d(1, -1) gl.Vertex2i(cx+tdx/2, cy+tdy/2) gl.TexCoord2d(1, 0) gl.Vertex2i(cx+tdx/2, cy-tdy/2) gl.End() m.layout.Name.RenderString(ent.Name) m.layout.Ap.RenderString(fmt.Sprintf("Ap:%d", ent.Stats.ApCur())) m.layout.Hp.RenderString(fmt.Sprintf("Hp:%d", ent.Stats.HpCur())) m.layout.Corpus.RenderString(fmt.Sprintf("Corpus:%d", ent.Stats.Corpus())) m.layout.Ego.RenderString(fmt.Sprintf("Ego:%d", ent.Stats.Ego())) gl.Color4d(1, 1, 1, 1) m.layout.Divider.Data().Bind() tdx = m.layout.Divider.Data().Dx() tdy = m.layout.Divider.Data().Dy() cx = region.X + m.layout.Name.X cy = region.Y + m.layout.Name.Y - 5 gl.Begin(gl.QUADS) gl.TexCoord2d(0, 0) gl.Vertex2i(cx-tdx/2, cy-tdy/2) gl.TexCoord2d(0, -1) gl.Vertex2i(cx-tdx/2, cy+(tdy+1)/2) gl.TexCoord2d(1, -1) gl.Vertex2i(cx+(tdx+1)/2, cy+(tdy+1)/2) gl.TexCoord2d(1, 0) gl.Vertex2i(cx+(tdx+1)/2, cy-tdy/2) gl.End() } if m.ent != nil && m.ent.Stats != nil { // Actions { spacing := m.layout.Actions.Icon_size * float64(m.layout.Actions.Count) spacing = m.layout.Actions.Width - spacing spacing /= float64(m.layout.Actions.Count - 1) m.state.Actions.space = spacing s := m.layout.Actions.Icon_size num_actions := len(m.ent.Actions) xpos := m.layout.Actions.X if num_actions > m.layout.Actions.Count { xpos -= m.state.Actions.scroll_pos * (s + spacing) } d := base.GetDictionary(10) var r gui.Region r.X = int(m.layout.Actions.X) r.Y = int(m.layout.Actions.Y - d.MaxHeight()) r.Dx = int(m.layout.Actions.Width) r.Dy = int(m.layout.Actions.Icon_size + d.MaxHeight()) r.PushClipPlanes() gl.Color4d(1, 1, 1, 1) for i, action := range m.ent.Actions { // Highlight the selected action if action == m.game.current_action { gl.Disable(gl.TEXTURE_2D) gl.Color4d(1, 0, 0, 1) gl.Begin(gl.QUADS) gl.Vertex3d(xpos-2, m.layout.Actions.Y-2, 0) gl.Vertex3d(xpos-2, m.layout.Actions.Y+s+2, 0) gl.Vertex3d(xpos+s+2, m.layout.Actions.Y+s+2, 0) gl.Vertex3d(xpos+s+2, m.layout.Actions.Y-2, 0) gl.End() } gl.Enable(gl.TEXTURE_2D) action.Icon().Data().Bind() if action.Preppable(m.ent, m.game) { gl.Color4d(1, 1, 1, 1) } else { gl.Color4d(0.5, 0.5, 0.5, 1) } gl.Begin(gl.QUADS) gl.TexCoord2d(0, 0) gl.Vertex3d(xpos, m.layout.Actions.Y, 0) gl.TexCoord2d(0, -1) gl.Vertex3d(xpos, m.layout.Actions.Y+s, 0) gl.TexCoord2d(1, -1) gl.Vertex3d(xpos+s, m.layout.Actions.Y+s, 0) gl.TexCoord2d(1, 0) gl.Vertex3d(xpos+s, m.layout.Actions.Y, 0) gl.End() gl.Disable(gl.TEXTURE_2D) ypos := m.layout.Actions.Y - d.MaxHeight() - 2 d.RenderString(fmt.Sprintf("%d", i+1), xpos+s/2, ypos, 0, d.MaxHeight(), gui.Center) xpos += spacing + m.layout.Actions.Icon_size } r.PopClipPlanes() // Now, if there is a selected action, position it between the arrows if m.state.Actions.selected != nil { // a := m.state.Actions.selected d := base.GetDictionary(15) x := m.layout.Actions.X + m.layout.Actions.Width/2 y := float64(m.layout.ActionLeft.Y) str := fmt.Sprintf("%s:%dAP", m.state.Actions.selected.String(), m.state.Actions.selected.AP()) gl.Color4d(1, 1, 1, 1) d.RenderString(str, x, y, 0, d.MaxHeight(), gui.Center) } } // Conditions { gl.Color4d(1, 1, 1, 1) c := m.layout.Conditions d := base.GetDictionary(int(c.Size)) ypos := c.Y + c.Height - d.MaxHeight() + m.state.Conditions.scroll_pos var r gui.Region r.X = int(c.X) r.Y = int(c.Y) r.Dx = int(c.Width) r.Dy = int(c.Height) r.PushClipPlanes() for _, s := range m.ent.Stats.ConditionNames() { d.RenderString(s, c.X+c.Width/2, ypos, 0, d.MaxHeight(), gui.Center) ypos -= float64(d.MaxHeight()) } r.PopClipPlanes() } // Gear if m.ent.ExplorerEnt != nil && m.ent.ExplorerEnt.Gear != nil { gear := m.ent.ExplorerEnt.Gear layout := m.layout.Gear icon := gear.Small_icon.Data() icon.RenderNatural(int(layout.X), int(layout.Y)) d := base.GetDictionary(10) d.RenderString("Gear", layout.X+float64(icon.Dx())/2, layout.Y-d.MaxHeight(), 0, d.MaxHeight(), gui.Center) } } // Mouseover text if m.state.MouseOver.active { var x int switch m.state.MouseOver.location { case mouseOverActions: x = int(m.layout.Actions.X + m.layout.Actions.Width/2) case mouseOverConditions: x = int(m.layout.Conditions.X + m.layout.Conditions.Width/2) case mouseOverGear: default: base.Warn().Printf("Got an unknown mouseover location: %d", m.state.MouseOver.location) m.state.MouseOver.active = false } y := m.layout.Background.Data().Dy() - 40 d := base.GetDictionary(15) d.RenderString(m.state.MouseOver.text, float64(x), float64(y), 0, d.MaxHeight(), gui.Center) } }
func drawFloor(room *Room, floor mathgl.Mat4, temp *WallTexture, cstack base.ColorStack, los_tex *LosTexture, los_alpha float64, floor_drawer []FloorDrawer) { gl.MatrixMode(gl.MODELVIEW) gl.PushMatrix() gl.LoadIdentity() gl.MultMatrixf(&floor[0]) defer gl.PopMatrix() gl.Enable(gl.STENCIL_TEST) defer gl.Disable(gl.STENCIL_TEST) gl.StencilFunc(gl.ALWAYS, 4, 4) gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE) gl.Disable(gl.TEXTURE_2D) gl.Begin(gl.QUADS) gl.Vertex2i(0, 0) gl.Vertex2i(0, room.Size.Dy) gl.Vertex2i(room.Size.Dx, room.Size.Dy) gl.Vertex2i(room.Size.Dx, 0) gl.End() gl.StencilFunc(gl.EQUAL, 4, 15) gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) // Draw the floor gl.Enable(gl.TEXTURE_2D) cstack.ApplyWithAlpha(los_alpha) room.Floor.Data().Render(0, 0, float64(room.Size.Dx), float64(room.Size.Dy)) if los_tex != nil { los_tex.Bind() gl.BlendFunc(gl.SRC_ALPHA_SATURATE, gl.SRC_ALPHA) gl.Color4d(0, 0, 0, 1) gl.Begin(gl.QUADS) gl.TexCoord2i(0, 0) gl.Vertex2i(-room.X, -room.Y) gl.TexCoord2i(1, 0) gl.Vertex2i(-room.X, los_tex.Size()-room.Y) gl.TexCoord2i(1, 1) gl.Vertex2i(los_tex.Size()-room.X, los_tex.Size()-room.Y) gl.TexCoord2i(0, 1) gl.Vertex2i(los_tex.Size()-room.X, -room.Y) gl.End() gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) } cstack.ApplyWithAlpha(los_alpha) { g_texs = g_texs[0:0] if temp != nil { g_texs = append(g_texs, *temp) } for _, tex := range room.WallTextures { g_texs = append(g_texs, *tex) } for i, tex := range g_texs { if tex.X >= float32(room.Size.Dx) { tex.Rot -= 3.1415926535 / 2 } if temp != nil && i == 0 { cstack.Push(1, 0.7, 0.7, 0.7) } cstack.ApplyWithAlpha(los_alpha) tex.Render() if temp != nil && i == 0 { cstack.Pop() } } } gl.PushMatrix() gl.Translated(-float64(room.X), -float64(room.Y), 0) for _, fd := range floor_drawer { fd.RenderOnFloor() } gl.PopMatrix() // Re-enable textures because floor_drawer.RenderOnFloor() might have // disabled them gl.Enable(gl.TEXTURE_2D) gl.StencilFunc(gl.ALWAYS, 5, 5) gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE) gl.Disable(gl.TEXTURE_2D) gl.Color4d(0, 0, 0, 0) gl.Begin(gl.QUADS) gl.Vertex2i(0, 0) gl.Vertex2i(0, room.Size.Dy) gl.Vertex2i(room.Size.Dx, room.Size.Dy) gl.Vertex2i(room.Size.Dx, 0) gl.End() }
// room: the wall to draw // wall: the texture to render on the wall // temp: an additional texture to render along with the other detail textures // specified in room // left,right: the xy planes of the left and right walls func drawWall(room *Room, floor, left, right mathgl.Mat4, temp_tex *WallTexture, temp_door doorInfo, cstack base.ColorStack, los_tex *LosTexture, los_alpha float64) { gl.Enable(gl.STENCIL_TEST) defer gl.Disable(gl.STENCIL_TEST) gl.MatrixMode(gl.MODELVIEW) gl.PushMatrix() defer gl.PopMatrix() var dz int if room.Wall.Data().Dx() > 0 { dz = room.Wall.Data().Dy() * (room.Size.Dx + room.Size.Dy) / room.Wall.Data().Dx() } corner := float32(room.Size.Dx) / float32(room.Size.Dx+room.Size.Dy) gl.LoadIdentity() gl.MultMatrixf(&floor[0]) g_texs = g_texs[0:0] if temp_tex != nil { g_texs = append(g_texs, *temp_tex) } for _, tex := range room.WallTextures { g_texs = append(g_texs, *tex) } do_right_wall := func() { gl.Begin(gl.QUADS) gl.TexCoord2f(1, 0) gl.Vertex3i(room.Size.Dx, 0, 0) gl.TexCoord2f(1, -1) gl.Vertex3i(room.Size.Dx, 0, -dz) gl.TexCoord2f(corner, -1) gl.Vertex3i(room.Size.Dx, room.Size.Dy, -dz) gl.TexCoord2f(corner, 0) gl.Vertex3i(room.Size.Dx, room.Size.Dy, 0) gl.End() } g_doors = g_doors[0:0] for _, door := range room.Doors { g_doors = append(g_doors, door) } if temp_door.Door != nil { g_doors = append(g_doors, temp_door.Door) } alpha := 0.2 do_right_doors := func(opened bool) { for _, door := range g_doors { if door.Facing != FarRight { continue } if door.IsOpened() != opened { continue } door.TextureData().Bind() if door == temp_door.Door { if temp_door.Valid { cstack.Push(0, 0, 1, alpha) } else { cstack.Push(1, 0, 0, alpha) } } cstack.ApplyWithAlpha(alpha * los_alpha) gl.Begin(gl.QUADS) height := float64(door.Width*door.TextureData().Dy()) / float64(door.TextureData().Dx()) gl.TexCoord2f(1, 0) gl.Vertex3d(float64(room.Size.Dx), float64(door.Pos), 0) gl.TexCoord2f(1, -1) gl.Vertex3d(float64(room.Size.Dx), float64(door.Pos), -height) gl.TexCoord2f(0, -1) gl.Vertex3d(float64(room.Size.Dx), float64(door.Pos+door.Width), -height) gl.TexCoord2f(0, 0) gl.Vertex3d(float64(room.Size.Dx), float64(door.Pos+door.Width), 0) gl.End() if door == temp_door.Door { cstack.Pop() } } } // Right wall gl.StencilFunc(gl.NOTEQUAL, 8, 7) gl.StencilOp(gl.DECR_WRAP, gl.REPLACE, gl.REPLACE) gl.Color4d(0, 0, 0, 0) do_right_wall() gl.Enable(gl.TEXTURE_2D) cstack.ApplyWithAlpha(alpha * los_alpha) gl.StencilFunc(gl.EQUAL, 8, 15) gl.StencilOp(gl.KEEP, gl.ZERO, gl.ZERO) do_right_doors(true) cstack.ApplyWithAlpha(1.0 * los_alpha) gl.StencilFunc(gl.EQUAL, 15, 15) gl.StencilOp(gl.KEEP, gl.ZERO, gl.ZERO) do_right_doors(true) for _, alpha := range []float64{alpha, 1.0} { cstack.ApplyWithAlpha(alpha * los_alpha) if alpha == 1.0 { gl.StencilFunc(gl.EQUAL, 15, 15) gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) } else { gl.StencilFunc(gl.EQUAL, 8, 15) gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) } room.Wall.Data().Bind() do_right_wall() gl.PushMatrix() gl.LoadIdentity() gl.MultMatrixf(&right[0]) for i, tex := range g_texs { dx, dy := float32(room.Size.Dx), float32(room.Size.Dy) if tex.Y > dy { tex.X, tex.Y = dx+tex.Y-dy, dy+dx-tex.X } if tex.X > dx { tex.Rot -= 3.1415926535 / 2 } tex.X -= dx if temp_tex != nil && i == 0 { cstack.Push(1, 0.7, 0.7, 0.7) } cstack.ApplyWithAlpha(alpha * los_alpha) tex.Render() if temp_tex != nil && i == 0 { cstack.Pop() } } gl.PopMatrix() } cstack.ApplyWithAlpha(alpha * los_alpha) gl.StencilFunc(gl.EQUAL, 8, 15) do_right_doors(false) cstack.ApplyWithAlpha(1.0 * los_alpha) gl.StencilFunc(gl.EQUAL, 15, 15) do_right_doors(false) // Go back over the area we just drew on and replace it with all b0001 gl.StencilFunc(gl.ALWAYS, 1, 1) gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE) gl.Color4d(0, 0, 0, 0) do_right_wall() // Now that the entire wall has been draw we can cast shadows on it if we've // got a los texture if los_tex != nil { los_tex.Bind() gl.BlendFunc(gl.SRC_ALPHA_SATURATE, gl.SRC_ALPHA) gl.Color4d(0, 0, 0, 1) tx := (float64(room.X+room.Size.Dx) - 0.5) / float64(los_tex.Size()) ty := (float64(room.Y) + 0.5) / float64(los_tex.Size()) ty2 := (float64(room.Y+room.Size.Dy) - 0.5) / float64(los_tex.Size()) gl.Begin(gl.QUADS) gl.TexCoord2d(ty, tx) gl.Vertex3i(room.Size.Dx, 0, 0) gl.TexCoord2d(ty, tx) gl.Vertex3i(room.Size.Dx, 0, -dz) gl.TexCoord2d(ty2, tx) gl.Vertex3i(room.Size.Dx, room.Size.Dy, -dz) gl.TexCoord2d(ty2, tx) gl.Vertex3i(room.Size.Dx, room.Size.Dy, 0) gl.End() gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) } do_left_wall := func() { gl.Begin(gl.QUADS) gl.TexCoord2f(corner, 0) gl.Vertex3i(room.Size.Dx, room.Size.Dy, 0) gl.TexCoord2f(corner, -1) gl.Vertex3i(room.Size.Dx, room.Size.Dy, -dz) gl.TexCoord2f(0, -1) gl.Vertex3i(0, room.Size.Dy, -dz) gl.TexCoord2f(0, 0) gl.Vertex3i(0, room.Size.Dy, 0) gl.End() } do_left_doors := func(opened bool) { for _, door := range g_doors { if door.Facing != FarLeft { continue } if door.IsOpened() != opened { continue } door.TextureData().Bind() if door == temp_door.Door { if temp_door.Valid { cstack.Push(0, 0, 1, alpha) } else { cstack.Push(1, 0, 0, alpha) } } cstack.ApplyWithAlpha(alpha * los_alpha) gl.Begin(gl.QUADS) height := float64(door.Width*door.TextureData().Dy()) / float64(door.TextureData().Dx()) gl.TexCoord2f(0, 0) gl.Vertex3d(float64(door.Pos), float64(room.Size.Dy), 0) gl.TexCoord2f(0, -1) gl.Vertex3d(float64(door.Pos), float64(room.Size.Dy), -height) gl.TexCoord2f(1, -1) gl.Vertex3d(float64(door.Pos+door.Width), float64(room.Size.Dy), -height) gl.TexCoord2f(1, 0) gl.Vertex3d(float64(door.Pos+door.Width), float64(room.Size.Dy), 0) gl.End() if door == temp_door.Door { cstack.Pop() } } } gl.StencilFunc(gl.NOTEQUAL, 8, 7) gl.StencilOp(gl.DECR_WRAP, gl.REPLACE, gl.REPLACE) gl.Color4d(0, 0, 0, 0) do_left_wall() gl.Enable(gl.TEXTURE_2D) cstack.ApplyWithAlpha(alpha * los_alpha) gl.StencilFunc(gl.EQUAL, 8, 15) gl.StencilOp(gl.KEEP, gl.ZERO, gl.ZERO) do_left_doors(true) cstack.ApplyWithAlpha(1.0 * los_alpha) gl.StencilFunc(gl.EQUAL, 15, 15) gl.StencilOp(gl.KEEP, gl.ZERO, gl.ZERO) do_left_doors(true) for _, alpha := range []float64{alpha, 1.0} { if alpha == 1.0 { gl.StencilFunc(gl.EQUAL, 15, 15) gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) } else { gl.StencilFunc(gl.EQUAL, 8, 15) gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) } room.Wall.Data().Bind() cstack.ApplyWithAlpha(alpha * los_alpha) do_left_wall() gl.PushMatrix() gl.LoadIdentity() gl.MultMatrixf(&left[0]) for i, tex := range g_texs { dx, dy := float32(room.Size.Dx), float32(room.Size.Dy) if tex.X > dx { tex.X, tex.Y = dx+dy-tex.Y, dy+tex.X-dx } tex.Y -= dy if temp_tex != nil && i == 0 { cstack.Push(1, 0.7, 0.7, 0.7) } cstack.ApplyWithAlpha(alpha * los_alpha) tex.Render() if temp_tex != nil && i == 0 { cstack.Pop() } } gl.PopMatrix() } cstack.ApplyWithAlpha(alpha * los_alpha) gl.StencilFunc(gl.EQUAL, 8, 15) do_left_doors(false) cstack.ApplyWithAlpha(1.0 * los_alpha) gl.StencilFunc(gl.EQUAL, 15, 15) do_left_doors(false) // Go back over the area we just drew on and replace it with all b0010 gl.StencilFunc(gl.ALWAYS, 2, 2) gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE) gl.Color4d(0, 0, 0, 0) do_left_wall() // Now that the entire wall has been draw we can cast shadows on it if we've // got a los texture if los_tex != nil { los_tex.Bind() gl.BlendFunc(gl.SRC_ALPHA_SATURATE, gl.SRC_ALPHA) gl.Color4d(0, 0, 0, 1) ty := (float64(room.Y+room.Size.Dy) - 0.5) / float64(los_tex.Size()) tx := (float64(room.X) + 0.5) / float64(los_tex.Size()) tx2 := (float64(room.X+room.Size.Dx) - 0.5) / float64(los_tex.Size()) gl.Begin(gl.QUADS) gl.TexCoord2d(ty, tx) gl.Vertex3i(0, room.Size.Dy, 0) gl.TexCoord2d(ty, tx) gl.Vertex3i(0, room.Size.Dy, -dz) gl.TexCoord2d(ty, tx2) gl.Vertex3i(room.Size.Dx, room.Size.Dy, -dz) gl.TexCoord2d(ty, tx2) gl.Vertex3i(room.Size.Dx, room.Size.Dy, 0) gl.End() gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) } }