Exemplo n.º 1
0
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)
}
Exemplo n.º 2
0
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)
}
Exemplo n.º 3
0
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()
}
Exemplo n.º 4
0
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)
}
Exemplo n.º 5
0
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)
}
Exemplo n.º 6
0
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)
}
Exemplo n.º 7
0
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()
		})
	})
}
Exemplo n.º 8
0
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()
}
Exemplo n.º 9
0
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
}
Exemplo n.º 10
0
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)
	}
}
Exemplo n.º 11
0
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()
	}
}
Exemplo n.º 12
0
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()
}