예제 #1
0
func (g *Gui) Draw() {
	gl.MatrixMode(gl.PROJECTION)
	gl.LoadIdentity()
	region := g.root.Render_region
	gl.Ortho(float64(region.X), float64(region.X+region.Dx), float64(region.Y), float64(region.Y+region.Dy), 1000, -1000)
	gl.ClearColor(0, 0, 0, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	gl.MatrixMode(gl.MODELVIEW)
	gl.LoadIdentity()
	g.root.Draw(region)
	if g.FocusWidget() != nil {
		g.FocusWidget().DrawFocused(region)
	}
}
예제 #2
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)
}
예제 #3
0
func (rv *RoomViewer) Draw(region gui.Region) {
	region.PushClipPlanes()
	defer region.PopClipPlanes()

	if rv.Render_region.X != region.X || rv.Render_region.Y != region.Y || rv.Render_region.Dx != region.Dx || rv.Render_region.Dy != region.Dy {
		rv.Render_region = region
		rv.makeMat()
	}

	gl.MatrixMode(gl.MODELVIEW)
	gl.PushMatrix()
	defer gl.PopMatrix()
	gl.LoadIdentity()
	gl.MultMatrixf(&rv.mat[0])

	// rv.room.render(rv.mat, rv.left_wall_mat, rv.right_wall_mat)
	rv.room.setupGlStuff()
	rv.room.far_left.wall_alpha = 255
	rv.room.far_right.wall_alpha = 255
	rv.room.render(rv.mat, rv.left_wall_mat, rv.right_wall_mat, rv.zoom, 255, nil, nil, nil)
	return

	rv.cstack.Push(1, 1, 1, 1)
	defer rv.cstack.Pop()
	drawPrep()
	drawWall(rv.room, rv.mat, rv.left_wall_mat, rv.right_wall_mat, rv.Temp.WallTexture, doorInfo{}, rv.cstack, nil, 1.0)
	drawFloor(rv.room, rv.mat, rv.Temp.WallTexture, rv.cstack, nil, 1.0, nil)
	rv.drawFloor()
	if rv.edit_mode == editCells {
		rv.cstack.Pop()
		rv.cstack.Push(1, 1, 1, 0.1)
	} else {
		rv.cstack.Push(1, 1, 1, 1)
		defer rv.cstack.Pop()
	}
	drawFurniture(0, 0, rv.mat, rv.zoom, rv.room.Furniture, rv.Temp.Furniture, nil, rv.cstack, nil, 1.0)
}
예제 #4
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()
}
예제 #5
0
// 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)
	}
}