示例#1
0
// Distance to Plane(Point?)?  WTF IS THIS!?
func d2p(tmat mathgl.Mat4, point, ray mathgl.Vec3) float32 {
	var mat mathgl.Mat4
	mat.Assign(&tmat)
	var sub mathgl.Vec3
	sub.X = mat[12]
	sub.Y = mat[13]
	sub.Z = mat[14]
	mat[12], mat[13], mat[14] = 0, 0, 0
	point.Subtract(&sub)
	point.Scale(-1)
	ray.Normalize()
	dist := point.Dot(mat.GetForwardVec3())

	var forward mathgl.Vec3
	forward.Assign(mat.GetForwardVec3())
	cos := float64(forward.Dot(&ray))
	return dist / float32(cos)
}
示例#2
0
文件: room.go 项目: RickDakan/haunts
// Need floor, right wall, and left wall matrices to draw the details
func (room *Room) render(floor, left, right mathgl.Mat4, zoom float32, base_alpha byte, drawables []Drawable, los_tex *LosTexture, floor_drawers []FloorDrawer) {
	do_color := func(r, g, b, a byte) {
		R, G, B, A := room.Color()
		A = alphaMult(A, base_alpha)
		gl.Color4ub(alphaMult(R, r), alphaMult(G, g), alphaMult(B, b), alphaMult(A, a))
	}
	gl.Enable(gl.TEXTURE_2D)
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	gl.Enable(gl.STENCIL_TEST)
	gl.ClearStencil(0)
	gl.Clear(gl.STENCIL_BUFFER_BIT)

	gl.EnableClientState(gl.VERTEX_ARRAY)
	gl.EnableClientState(gl.TEXTURE_COORD_ARRAY)
	defer gl.DisableClientState(gl.VERTEX_ARRAY)
	defer gl.DisableClientState(gl.TEXTURE_COORD_ARRAY)

	var vert roomVertex

	planes := []plane{
		{room.left_buffer, room.Wall, &left},
		{room.right_buffer, room.Wall, &right},
		{room.floor_buffer, room.Floor, &floor},
	}

	gl.PushMatrix()
	defer gl.PopMatrix()

	if los_tex != nil {
		gl.LoadMatrixf(&floor[0])
		gl.ClientActiveTexture(gl.TEXTURE1)
		gl.ActiveTexture(gl.TEXTURE1)
		gl.Enable(gl.TEXTURE_2D)
		gl.EnableClientState(gl.TEXTURE_COORD_ARRAY)
		los_tex.Bind()
		gl.BindBuffer(gl.ARRAY_BUFFER, room.vbuffer)
		gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u)))
		gl.ClientActiveTexture(gl.TEXTURE0)
		gl.ActiveTexture(gl.TEXTURE0)
		base.EnableShader("los")
		base.SetUniformI("los", "tex2", 1)
	}

	var mul, run mathgl.Mat4
	for _, plane := range planes {
		gl.LoadMatrixf(&floor[0])
		run.Assign(&floor)

		// Render the doors and cut out the stencil buffer so we leave them empty
		// if they're open
		switch plane.mat {
		case &left:
			gl.StencilFunc(gl.ALWAYS, 1, 1)
			gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE)
			for _, door := range room.Doors {
				if door.Facing != FarLeft {
					continue
				}
				door.TextureData().Bind()
				R, G, B, A := door.Color()
				do_color(R, G, B, alphaMult(A, room.far_left.wall_alpha))
				gl.ClientActiveTexture(gl.TEXTURE0)
				door.TextureData().Bind()
				if door.door_glids.floor_buffer != 0 {
					gl.BindBuffer(gl.ARRAY_BUFFER, door.threshold_glids.vbuffer)
					gl.VertexPointer(3, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.x)))
					gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, door.door_glids.floor_buffer)
					gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.u)))
					gl.ClientActiveTexture(gl.TEXTURE1)
					gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u)))
					gl.DrawElements(gl.TRIANGLES, door.door_glids.floor_count, gl.UNSIGNED_SHORT, nil)
				}
			}
			gl.StencilFunc(gl.NOTEQUAL, 1, 1)
			gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)
			do_color(255, 255, 255, room.far_left.wall_alpha)

		case &right:
			gl.StencilFunc(gl.ALWAYS, 1, 1)
			gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE)
			for _, door := range room.Doors {
				if door.Facing != FarRight {
					continue
				}
				door.TextureData().Bind()
				R, G, B, A := door.Color()
				do_color(R, G, B, alphaMult(A, room.far_right.wall_alpha))
				gl.ClientActiveTexture(gl.TEXTURE0)
				door.TextureData().Bind()
				if door.door_glids.floor_buffer != 0 {
					gl.BindBuffer(gl.ARRAY_BUFFER, door.threshold_glids.vbuffer)
					gl.VertexPointer(3, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.x)))
					gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, door.door_glids.floor_buffer)
					gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.u)))
					gl.ClientActiveTexture(gl.TEXTURE1)
					gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u)))
					gl.DrawElements(gl.TRIANGLES, door.door_glids.floor_count, gl.UNSIGNED_SHORT, nil)
				}
			}
			gl.StencilFunc(gl.NOTEQUAL, 1, 1)
			gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)
			do_color(255, 255, 255, room.far_right.wall_alpha)

		case &floor:
			gl.StencilFunc(gl.ALWAYS, 2, 2)
			gl.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE)
			do_color(255, 255, 255, 255)
		}

		gl.ClientActiveTexture(gl.TEXTURE0)
		gl.BindBuffer(gl.ARRAY_BUFFER, room.vbuffer)
		gl.VertexPointer(3, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.x)))
		gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.u)))
		gl.ClientActiveTexture(gl.TEXTURE1)
		if los_tex != nil {
			los_tex.Bind()
		}
		gl.BindBuffer(gl.ARRAY_BUFFER, room.vbuffer)
		gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u)))
		// Now draw the walls
		gl.LoadMatrixf(&floor[0])
		plane.texture.Data().Bind()
		gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, plane.index_buffer)
		if (plane.mat == &left || plane.mat == &right) && strings.Contains(string(room.Wall.Path), "gradient.png") {
			base.EnableShader("gorey")
			base.SetUniformI("gorey", "tex", 0)
			base.SetUniformI("gorey", "foo", Foo)
			base.SetUniformF("gorey", "num_rows", Num_rows)
			base.SetUniformF("gorey", "noise_rate", Noise_rate)
			base.SetUniformF("gorey", "num_steps", Num_steps)
		}
		if plane.mat == &floor && strings.Contains(string(room.Floor.Path), "gradient.png") {
			base.EnableShader("gorey")
			base.SetUniformI("gorey", "tex", 0)
			base.SetUniformI("gorey", "foo", Foo)
			base.SetUniformF("gorey", "num_rows", Num_rows)
			base.SetUniformF("gorey", "noise_rate", Noise_rate)
			base.SetUniformF("gorey", "num_steps", Num_steps)
			zexp := math.Log(float64(zoom))
			frac := 1 - 1/zexp
			frac = (frac - 0.6) * 5.0
			switch {
			case frac > 0.7:
				base.SetUniformI("gorey", "range", 1)
			case frac > 0.3:
				base.SetUniformI("gorey", "range", 2)
			default:
				base.SetUniformI("gorey", "range", 3)
			}
		}
		if plane.mat == &floor {
			R, G, B, _ := room.Color()
			gl.Color4ub(R, G, B, 255)
		}
		gl.DrawElements(gl.TRIANGLES, gl.Sizei(room.floor_count), gl.UNSIGNED_SHORT, nil)
		if los_tex != nil {
			base.EnableShader("los")
		} else {
			base.EnableShader("")
		}
	}

	for _, wt := range room.WallTextures {
		if room.wall_texture_gl_map == nil {
			room.wall_texture_gl_map = make(map[*WallTexture]wallTextureGlIds)
			room.wall_texture_state_map = make(map[*WallTexture]wallTextureState)
		}
		ids := room.wall_texture_gl_map[wt]
		state := room.wall_texture_state_map[wt]
		var new_state wallTextureState
		new_state.flip = wt.Flip
		new_state.rot = wt.Rot
		new_state.x = wt.X
		new_state.y = wt.Y
		new_state.room.x = room.X
		new_state.room.y = room.Y
		new_state.room.dx = room.Size.Dx
		new_state.room.dy = room.Size.Dy
		if new_state != state {
			wt.setupGlStuff(room.X, room.Y, room.Size.Dx, room.Size.Dy, &ids)
			room.wall_texture_gl_map[wt] = ids
			room.wall_texture_state_map[wt] = new_state
		}
		gl.LoadMatrixf(&floor[0])
		if ids.vbuffer != 0 {
			wt.Texture.Data().Bind()
			R, G, B, A := wt.Color()

			gl.ClientActiveTexture(gl.TEXTURE0)
			gl.BindBuffer(gl.ARRAY_BUFFER, ids.vbuffer)
			gl.VertexPointer(3, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.x)))
			gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.u)))
			gl.ClientActiveTexture(gl.TEXTURE1)
			gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u)))
			gl.ClientActiveTexture(gl.TEXTURE0)
			if ids.floor_buffer != 0 {
				gl.StencilFunc(gl.ALWAYS, 2, 2)
				gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ids.floor_buffer)
				gl.Color4ub(R, G, B, A)
				gl.DrawElements(gl.TRIANGLES, ids.floor_count, gl.UNSIGNED_SHORT, nil)
			}
			if ids.left_buffer != 0 {
				gl.StencilFunc(gl.ALWAYS, 1, 1)
				gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ids.left_buffer)
				do_color(R, G, B, alphaMult(A, room.far_left.wall_alpha))
				gl.DrawElements(gl.TRIANGLES, ids.left_count, gl.UNSIGNED_SHORT, nil)
			}
			if ids.right_buffer != 0 {
				gl.StencilFunc(gl.ALWAYS, 1, 1)
				gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ids.right_buffer)
				do_color(R, G, B, alphaMult(A, room.far_right.wall_alpha))
				gl.DrawElements(gl.TRIANGLES, ids.right_count, gl.UNSIGNED_SHORT, nil)
			}
		}
	}
	base.EnableShader("marble")
	base.SetUniformI("marble", "tex2", 1)
	base.SetUniformF("marble", "room_x", float32(room.X))
	base.SetUniformF("marble", "room_y", float32(room.Y))
	for _, door := range room.Doors {
		door.setupGlStuff(room)
		if door.threshold_glids.vbuffer == 0 {
			continue
		}
		if door.AlwaysOpen() {
			continue
		}
		if door.highlight_threshold {
			gl.Color4ub(255, 255, 255, 255)
		} else {
			gl.Color4ub(128, 128, 128, 255)
		}
		gl.BindBuffer(gl.ARRAY_BUFFER, door.threshold_glids.vbuffer)
		gl.VertexPointer(3, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.x)))
		gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.u)))
		gl.ClientActiveTexture(gl.TEXTURE1)
		gl.TexCoordPointer(2, gl.FLOAT, gl.Sizei(unsafe.Sizeof(vert)), gl.Pointer(unsafe.Offsetof(vert.los_u)))
		gl.ClientActiveTexture(gl.TEXTURE0)
		gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, door.threshold_glids.floor_buffer)
		gl.DrawElements(gl.TRIANGLES, door.threshold_glids.floor_count, gl.UNSIGNED_SHORT, nil)
	}
	base.EnableShader("")
	if los_tex != nil {
		base.EnableShader("")
		gl.ActiveTexture(gl.TEXTURE1)
		gl.Disable(gl.TEXTURE_2D)
		gl.ActiveTexture(gl.TEXTURE0)
		gl.ClientActiveTexture(gl.TEXTURE1)
		gl.DisableClientState(gl.TEXTURE_COORD_ARRAY)
		gl.ClientActiveTexture(gl.TEXTURE0)
	}

	run.Assign(&floor)
	mul.Translation(float32(-room.X), float32(-room.Y), 0)
	run.Multiply(&mul)
	gl.LoadMatrixf(&run[0])
	gl.StencilFunc(gl.EQUAL, 2, 3)
	gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)
	room_rect := image.Rect(room.X, room.Y, room.X+room.Size.Dx, room.Y+room.Size.Dy)
	for _, fd := range floor_drawers {
		x, y := fd.Pos()
		dx, dy := fd.Dims()
		if room_rect.Overlaps(image.Rect(x, y, x+dx, y+dy)) {
			fd.RenderOnFloor()
		}
	}

	do_color(255, 255, 255, 255)
	gl.LoadIdentity()
	gl.Disable(gl.STENCIL_TEST)
	room.renderFurniture(floor, 255, drawables, los_tex)

	gl.ClientActiveTexture(gl.TEXTURE1)
	gl.Disable(gl.TEXTURE_2D)
	gl.ClientActiveTexture(gl.TEXTURE0)
	base.EnableShader("")
}