mirror of
https://github.com/SleepingInsomniac/pixelfaucet
synced 2025-02-02 20:45:54 +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
|
end
|
||||||
|
|
||||||
# Project an array of Triangles into screen space
|
# 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
|
mat_view = camera.view_matrix
|
||||||
|
|
||||||
# only draw triangles facing the camera
|
# only draw triangles facing the camera
|
||||||
|
@ -96,9 +96,8 @@ module PF
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# sort triangles
|
# sort triangles, no need to do this if using a depth buffer
|
||||||
# TODO: Z-buffer
|
tris.sort! { |a, b| b.z <=> a.z } if sort
|
||||||
tris.sort! { |a, b| b.z <=> a.z }
|
|
||||||
|
|
||||||
# Clip against the edges of the screen
|
# Clip against the edges of the screen
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,7 +61,7 @@ module PF
|
||||||
end
|
end
|
||||||
|
|
||||||
# Draw a textured triangle
|
# 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
|
# Sort points from top to bottom
|
||||||
p1, p2, t1, t2 = p2, p1, t2, t1 if p2.y < p1.y
|
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
|
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
|
t = scan_size == 0 ? 0.0 : (x - x_left) / scan_size
|
||||||
texture_point = texture_line.lerp(t)
|
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
|
# 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
|
# 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
|
sample_point = ((Vector[texture_point.x, texture_point.y] / texture_point.z) * sprite.size)
|
||||||
pixel = sprite.sample(sample_point.to_i)
|
# 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
|
# Blend the pixel sample with the provided color
|
||||||
pixel.r = (pixel.r * (color.r / 255)).to_u8
|
pixel.r = (pixel.r * (color.r / 255)).to_u8
|
||||||
|
@ -163,6 +168,7 @@ module PF
|
||||||
|
|
||||||
draw_point(x, y + c, pixel)
|
draw_point(x, y + c, pixel)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Once we hit the point where a line changes, we need a new slope for that line
|
# Once we hit the point where a line changes, we need a new slope for that line
|
||||||
if y == mid
|
if y == mid
|
||||||
|
|
Loading…
Add table
Reference in a new issue