mirror of
https://github.com/SleepingInsomniac/pixelfaucet
synced 2025-01-23 07:27:17 +01:00
Add depth buffer
This commit is contained in:
parent
cf6409250f
commit
329f57af0e
3 changed files with 43 additions and 14 deletions
24
src/3d/depth_buffer.cr
Normal file
24
src/3d/depth_buffer.cr
Normal file
|
@ -0,0 +1,24 @@
|
|||
module PF
|
||||
# A buffer of depth values for rending 3d scenes
|
||||
class DepthBuffer
|
||||
@values : Slice(Float64)
|
||||
@width : Int32
|
||||
@height : Int32
|
||||
|
||||
def initialize(@width, @height)
|
||||
@values = Slice(Float64).new(@width * @height, 0.0)
|
||||
end
|
||||
|
||||
def clear
|
||||
@values.fill(0.0)
|
||||
end
|
||||
|
||||
def [](x : Int, y : Int)
|
||||
@values[y * @width + x]
|
||||
end
|
||||
|
||||
def []=(x : Int, y : Int, value : Float64)
|
||||
@values[y * @width + x] = value
|
||||
end
|
||||
end
|
||||
end
|
|
@ -55,7 +55,7 @@ module PF
|
|||
end
|
||||
|
||||
# Project an array of Triangles into screen space
|
||||
def project(tris : Array(Tri), camera = @camera)
|
||||
def project(tris : Array(Tri), camera = @camera, sort : Bool = false)
|
||||
mat_view = camera.view_matrix
|
||||
|
||||
# only draw triangles facing the camera
|
||||
|
@ -96,9 +96,8 @@ module PF
|
|||
end
|
||||
end
|
||||
|
||||
# sort triangles
|
||||
# TODO: Z-buffer
|
||||
tris.sort! { |a, b| b.z <=> a.z }
|
||||
# sort triangles, no need to do this if using a depth buffer
|
||||
tris.sort! { |a, b| b.z <=> a.z } if sort
|
||||
|
||||
# Clip against the edges of the screen
|
||||
{
|
||||
|
|
|
@ -61,7 +61,7 @@ module PF
|
|||
end
|
||||
|
||||
# Draw a textured triangle
|
||||
def fill_triangle(p1 : Vector2, p2 : Vector2, p3 : Vector2, t1 : Vector3, t2 : Vector3, t3 : Vector3, sprite : Sprite, color : Pixel = Pixel.white)
|
||||
def fill_triangle(p1 : Vector2, p2 : Vector2, p3 : Vector2, t1 : Vector3, t2 : Vector3, t3 : Vector3, sprite : Sprite, buffer : DepthBuffer, color : Pixel = Pixel.white)
|
||||
# Sort points from top to bottom
|
||||
p1, p2, t1, t2 = p2, p1, t2, t1 if p2.y < p1.y
|
||||
p1, p3, t1, t3 = p3, p1, t3, t1 if p3.y < p1.y
|
||||
|
@ -151,10 +151,15 @@ module PF
|
|||
t = scan_size == 0 ? 0.0 : (x - x_left) / scan_size
|
||||
texture_point = texture_line.lerp(t)
|
||||
|
||||
if texture_point.z >= buffer[x, y + c]
|
||||
buffer[x, y + c] = texture_point.z
|
||||
# Get the x and y of the texture coords, divide by z for perspective, then
|
||||
# multiply the point by the size of the sprite to get the final texture point
|
||||
sample_point = Vector[texture_point.x / texture_point.z, texture_point.y / texture_point.z] * sprite.size
|
||||
pixel = sprite.sample(sample_point.to_i)
|
||||
sample_point = ((Vector[texture_point.x, texture_point.y] / texture_point.z) * sprite.size)
|
||||
# Invert the y axis for the sprite
|
||||
sample_point.y = sprite.height - sample_point.y
|
||||
# sample_point = sample_point / texture_point.z if texture_point.z != 0
|
||||
pixel = sprite.sample((sample_point + 0.5).to_i)
|
||||
|
||||
# Blend the pixel sample with the provided color
|
||||
pixel.r = (pixel.r * (color.r / 255)).to_u8
|
||||
|
@ -163,6 +168,7 @@ module PF
|
|||
|
||||
draw_point(x, y + c, pixel)
|
||||
end
|
||||
end
|
||||
|
||||
# Once we hit the point where a line changes, we need a new slope for that line
|
||||
if y == mid
|
||||
|
|
Loading…
Add table
Reference in a new issue