Check depth buffer before texture mapping
This commit is contained in:
parent
ba68f22bee
commit
bedc30038b
171
src/render.cpp
171
src/render.cpp
|
@ -84,85 +84,6 @@ void Render(EngineBuffer &buffer, EngineMemory &memory)
|
||||||
&& (barycenter[1] >= 0.0f)
|
&& (barycenter[1] >= 0.0f)
|
||||||
&& (barycenter[2] >= 0.0f))
|
&& (barycenter[2] >= 0.0f))
|
||||||
{
|
{
|
||||||
// Interpolate U and V of the texture for this point
|
|
||||||
Texture &texture = textures.data[faces.data[f].materialIndex];
|
|
||||||
UV &uv0 = uvs.data[face.uvIndex[0]];
|
|
||||||
UV &uv1 = uvs.data[face.uvIndex[1]];
|
|
||||||
UV &uv2 = uvs.data[face.uvIndex[2]];
|
|
||||||
|
|
||||||
float a = barycenter[0] * p1.w * p2.w;
|
|
||||||
float b = barycenter[1] * p0.w * p2.w;
|
|
||||||
float c = barycenter[2] * p0.w * p1.w;
|
|
||||||
float abc = 1.0f / (a + b + c);
|
|
||||||
|
|
||||||
float uInterp =
|
|
||||||
((a * uv0.u) + (b * uv1.u) + (c * uv2.u))
|
|
||||||
* abc
|
|
||||||
* texture.width;
|
|
||||||
|
|
||||||
float vInterp =
|
|
||||||
((a * uv0.v) + (b * uv1.v) + (c * uv2.v))
|
|
||||||
* abc
|
|
||||||
* texture.height;
|
|
||||||
|
|
||||||
|
|
||||||
// Bilinear filtering
|
|
||||||
unsigned int u = (unsigned int)uInterp;
|
|
||||||
unsigned int v = (unsigned int)vInterp;
|
|
||||||
float du = uInterp - u;
|
|
||||||
float dv = vInterp - v;
|
|
||||||
float duDiff = 1 - du;
|
|
||||||
float dvDiff = 1 - dv;
|
|
||||||
|
|
||||||
ColorU32 color =
|
|
||||||
{
|
|
||||||
(uint8_t)
|
|
||||||
(duDiff * dvDiff * texture.texels[v][u].b
|
|
||||||
+ du * dvDiff * texture.texels[v][u+1].b
|
|
||||||
+ du * dv * texture.texels[v+1][u+1].b
|
|
||||||
+ duDiff * dv * texture.texels[v+1][u].b),
|
|
||||||
|
|
||||||
(uint8_t)
|
|
||||||
(duDiff * dvDiff * texture.texels[v][u].g
|
|
||||||
+ du * dvDiff * texture.texels[v][u+1].g
|
|
||||||
+ du * dv * texture.texels[v+1][u+1].g
|
|
||||||
+ duDiff * dv * texture.texels[v+1][u].g),
|
|
||||||
|
|
||||||
(uint8_t)
|
|
||||||
(duDiff * dvDiff * texture.texels[v][u].r
|
|
||||||
+ du * dvDiff * texture.texels[v][u+1].r
|
|
||||||
+ du * dv * texture.texels[v+1][u+1].r
|
|
||||||
+ duDiff * dv * texture.texels[v+1][u].r),
|
|
||||||
|
|
||||||
(uint8_t)
|
|
||||||
(duDiff * dvDiff * texture.texels[v][u].a
|
|
||||||
+ du * dvDiff * texture.texels[v][u+1].a
|
|
||||||
+ du * dv * texture.texels[v+1][u+1].a
|
|
||||||
+ duDiff * dv * texture.texels[v+1][u].a)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Perform Gouraud shading on the texture
|
|
||||||
ColorF32 &c0 = verts.data[face.vertIndex[0]].color;
|
|
||||||
ColorF32 &c1 = verts.data[face.vertIndex[1]].color;
|
|
||||||
ColorF32 &c2 = verts.data[face.vertIndex[2]].color;
|
|
||||||
|
|
||||||
ColorF32 shading =
|
|
||||||
(barycenter[0] * c0)
|
|
||||||
+ (barycenter[1] * c1)
|
|
||||||
+ (barycenter[2] * c2);
|
|
||||||
|
|
||||||
|
|
||||||
// Ensure no color channel exceeds max
|
|
||||||
ScaleColor(shading);
|
|
||||||
|
|
||||||
|
|
||||||
// Light the texture
|
|
||||||
color.b *= shading.b;
|
|
||||||
color.g *= shading.g;
|
|
||||||
color.r *= shading.r;
|
|
||||||
|
|
||||||
|
|
||||||
// Interpolate 1/z for the z-buffer
|
// Interpolate 1/z for the z-buffer
|
||||||
float zInv =
|
float zInv =
|
||||||
1.0f /
|
1.0f /
|
||||||
|
@ -171,15 +92,97 @@ void Render(EngineBuffer &buffer, EngineMemory &memory)
|
||||||
+ (barycenter[2] * p2.w));
|
+ (barycenter[2] * p2.w));
|
||||||
|
|
||||||
|
|
||||||
// Draw the pixel if it's closer than what's in the z-buffer
|
// Compute pixel color if it's closer than what's in the z-buffer
|
||||||
if (zInv > memory.zbuffer[y][x])
|
if (zInv > memory.zbuffer[y][x])
|
||||||
{
|
{
|
||||||
ColorU32 *pixel = (ColorU32*)&buffer.buffer[y*buffer.width+x];
|
// Update the depth buffer
|
||||||
|
memory.zbuffer[y][x] = zInv;
|
||||||
|
|
||||||
|
|
||||||
|
// Interpolate U and V of the texture for this point
|
||||||
|
Texture &texture = textures.data[faces.data[f].materialIndex];
|
||||||
|
UV &uv0 = uvs.data[face.uvIndex[0]];
|
||||||
|
UV &uv1 = uvs.data[face.uvIndex[1]];
|
||||||
|
UV &uv2 = uvs.data[face.uvIndex[2]];
|
||||||
|
|
||||||
|
float a = barycenter[0] * p1.w * p2.w;
|
||||||
|
float b = barycenter[1] * p0.w * p2.w;
|
||||||
|
float c = barycenter[2] * p0.w * p1.w;
|
||||||
|
float abc = 1.0f / (a + b + c);
|
||||||
|
|
||||||
|
float uInterp =
|
||||||
|
((a * uv0.u) + (b * uv1.u) + (c * uv2.u))
|
||||||
|
* abc
|
||||||
|
* texture.width;
|
||||||
|
|
||||||
|
float vInterp =
|
||||||
|
((a * uv0.v) + (b * uv1.v) + (c * uv2.v))
|
||||||
|
* abc
|
||||||
|
* texture.height;
|
||||||
|
|
||||||
|
|
||||||
|
// Bilinear filtering
|
||||||
|
unsigned int u = (unsigned int)uInterp;
|
||||||
|
unsigned int v = (unsigned int)vInterp;
|
||||||
|
float du = uInterp - u;
|
||||||
|
float dv = vInterp - v;
|
||||||
|
float duDiff = 1 - du;
|
||||||
|
float dvDiff = 1 - dv;
|
||||||
|
|
||||||
|
ColorU32 color =
|
||||||
|
{
|
||||||
|
(uint8_t)
|
||||||
|
(duDiff * dvDiff * texture.texels[v][u].b
|
||||||
|
+ du * dvDiff * texture.texels[v][u+1].b
|
||||||
|
+ du * dv * texture.texels[v+1][u+1].b
|
||||||
|
+ duDiff * dv * texture.texels[v+1][u].b),
|
||||||
|
|
||||||
|
(uint8_t)
|
||||||
|
(duDiff * dvDiff * texture.texels[v][u].g
|
||||||
|
+ du * dvDiff * texture.texels[v][u+1].g
|
||||||
|
+ du * dv * texture.texels[v+1][u+1].g
|
||||||
|
+ duDiff * dv * texture.texels[v+1][u].g),
|
||||||
|
|
||||||
|
(uint8_t)
|
||||||
|
(duDiff * dvDiff * texture.texels[v][u].r
|
||||||
|
+ du * dvDiff * texture.texels[v][u+1].r
|
||||||
|
+ du * dv * texture.texels[v+1][u+1].r
|
||||||
|
+ duDiff * dv * texture.texels[v+1][u].r),
|
||||||
|
|
||||||
|
(uint8_t)
|
||||||
|
(duDiff * dvDiff * texture.texels[v][u].a
|
||||||
|
+ du * dvDiff * texture.texels[v][u+1].a
|
||||||
|
+ du * dv * texture.texels[v+1][u+1].a
|
||||||
|
+ duDiff * dv * texture.texels[v+1][u].a)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Perform Gouraud shading on the texture
|
||||||
|
ColorF32 &c0 = verts.data[face.vertIndex[0]].color;
|
||||||
|
ColorF32 &c1 = verts.data[face.vertIndex[1]].color;
|
||||||
|
ColorF32 &c2 = verts.data[face.vertIndex[2]].color;
|
||||||
|
|
||||||
|
ColorF32 shading =
|
||||||
|
(barycenter[0] * c0)
|
||||||
|
+ (barycenter[1] * c1)
|
||||||
|
+ (barycenter[2] * c2);
|
||||||
|
|
||||||
|
|
||||||
|
// Ensure no color channel exceeds max
|
||||||
|
ScaleColor(shading);
|
||||||
|
|
||||||
|
|
||||||
|
// Light the texture
|
||||||
|
color.b *= shading.b;
|
||||||
|
color.g *= shading.g;
|
||||||
|
color.r *= shading.r;
|
||||||
|
|
||||||
|
|
||||||
|
// Alpha blend the pixel
|
||||||
|
ColorU32 *pixel = (ColorU32*)&buffer.buffer[y*buffer.width+x];
|
||||||
float alpha = color.a / 255.0f;
|
float alpha = color.a / 255.0f;
|
||||||
float alphaDiff = 1.0f - alpha;
|
float alphaDiff = 1.0f - alpha;
|
||||||
|
|
||||||
// Blend new color with the existing color
|
|
||||||
ColorU32 blended =
|
ColorU32 blended =
|
||||||
{
|
{
|
||||||
(uint8_t)((alpha * color.b) + (alphaDiff * pixel->b)),
|
(uint8_t)((alpha * color.b) + (alphaDiff * pixel->b)),
|
||||||
|
@ -188,9 +191,9 @@ void Render(EngineBuffer &buffer, EngineMemory &memory)
|
||||||
(uint8_t)((alpha * color.a) + (alphaDiff * pixel->a))
|
(uint8_t)((alpha * color.a) + (alphaDiff * pixel->a))
|
||||||
};
|
};
|
||||||
|
|
||||||
DrawPixel(buffer.buffer, buffer.width, blended.u32, x, y);
|
|
||||||
|
|
||||||
memory.zbuffer[y][x] = zInv;
|
// Draw
|
||||||
|
DrawPixel(buffer.buffer, buffer.width, blended.u32, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue