Add bilinear filtering
This commit is contained in:
parent
20402784f7
commit
21fb0058ad
|
@ -19,8 +19,7 @@ enum Engine_Input
|
|||
ROTATE_Z_POS,
|
||||
ROTATE_Z_NEG,
|
||||
SCALE_UP,
|
||||
SCALE_DOWN,
|
||||
SHADING_TOGGLE
|
||||
SCALE_DOWN
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
// STRUCTURES
|
||||
struct Material
|
||||
{
|
||||
bool smooth;
|
||||
ColorF32 kAmbient;
|
||||
ColorF32 kDiffuse;
|
||||
};
|
||||
|
@ -75,7 +76,6 @@ struct Mesh
|
|||
float scale;
|
||||
|
||||
Material material;
|
||||
bool smooth;
|
||||
|
||||
Mesh_LocalData local;
|
||||
Mesh_TransformedData transformed;
|
||||
|
@ -88,8 +88,8 @@ void CullBackfaces(
|
|||
Point &camPosition);
|
||||
|
||||
void RenderMesh(
|
||||
Engine_Buffer &buffer, Mesh_TransformedData &mesh, bool smooth, Texture &texture,
|
||||
std::vector<TextureCoord> &uvs);
|
||||
Engine_Buffer &buffer, Mesh_TransformedData &mesh,
|
||||
Texture &texture, std::vector<TextureCoord> &uvs);
|
||||
|
||||
|
||||
#define GEOMETRY_H
|
||||
|
|
|
@ -35,6 +35,7 @@ int Engine_Init(Engine_Buffer &buffer, char *filename)
|
|||
mesh.position.z = 250;
|
||||
mesh.material.kDiffuse = {1.0,1.0,1.0,1.0};
|
||||
mesh.material.kAmbient = {1.0,1.0,1.0,1.0};
|
||||
mesh.material.smooth = true;
|
||||
|
||||
camera.SetFOV(90.0f, buffer.width, buffer.height);
|
||||
|
||||
|
@ -53,8 +54,7 @@ void Engine_Render(Engine_Buffer &buffer, uint32_t input)
|
|||
|
||||
|
||||
// Clear the z-buffer
|
||||
unsigned long bufferSize = (unsigned long)(buffer.width * buffer.height);
|
||||
memset(buffer.zbuffer, 0, bufferSize * sizeof(float));
|
||||
memset(buffer.zbuffer, 0, sizeof(float) * (size_t)(buffer.width * buffer.height));
|
||||
|
||||
|
||||
// Local space to world space
|
||||
|
@ -78,7 +78,7 @@ void Engine_Render(Engine_Buffer &buffer, uint32_t input)
|
|||
|
||||
|
||||
// Color the vertices for Gouraud shading
|
||||
if (mesh.smooth)
|
||||
if (mesh.material.smooth)
|
||||
{
|
||||
for (size_t f = 0; f < mesh.transformed.faces.size(); ++f)
|
||||
{
|
||||
|
@ -135,7 +135,7 @@ void Engine_Render(Engine_Buffer &buffer, uint32_t input)
|
|||
mesh.transformed.verts[v].point.z /= mesh.transformed.verts[v].point.w;
|
||||
}
|
||||
|
||||
RenderMesh(buffer, mesh.transformed, mesh.smooth, texture, mesh.local.uvs);
|
||||
RenderMesh(buffer, mesh.transformed, texture, mesh.local.uvs);
|
||||
}
|
||||
|
||||
void Engine_Shutdown(void)
|
||||
|
@ -208,13 +208,4 @@ static void CheckInputs(uint32_t input)
|
|||
{
|
||||
mesh.scale -= 0.1f;
|
||||
}
|
||||
|
||||
if (CHECK_BIT(input, SHADING_TOGGLE))
|
||||
{
|
||||
mesh.smooth = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.smooth = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,8 +66,9 @@ void CullBackfaces(
|
|||
|
||||
}
|
||||
|
||||
void RenderMesh(Engine_Buffer &buffer, Mesh_TransformedData &mesh, bool smooth, Texture &texture,
|
||||
std::vector<TextureCoord> &uvs)
|
||||
void RenderMesh(
|
||||
Engine_Buffer &buffer, Mesh_TransformedData &mesh,
|
||||
Texture &texture, std::vector<TextureCoord> &uvs)
|
||||
{
|
||||
for(size_t f = 0; f < mesh.faces.size(); ++f)
|
||||
{
|
||||
|
@ -138,37 +139,55 @@ void RenderMesh(Engine_Buffer &buffer, Mesh_TransformedData &mesh, bool smooth,
|
|||
|
||||
|
||||
// Interpolate U and V
|
||||
float u = ((a * t0.u) + (b * t1.u) + (c * t2.u)) * abc;
|
||||
float v = ((a * t0.v) + (b * t1.v) + (c * t2.v)) * abc;
|
||||
float uInterp = ((a * t0.u) + (b * t1.u) + (c * t2.u)) * abc;
|
||||
float vInterp = ((a * t0.v) + (b * t1.v) + (c * t2.v)) * abc;
|
||||
|
||||
|
||||
// Convert U and V to pixels in the texture image
|
||||
unsigned int uPixel = (unsigned int)(u * texture.width);
|
||||
unsigned int vPixel = (unsigned int)(v * texture.height);
|
||||
uInterp *= texture.width;
|
||||
vInterp *= texture.height;
|
||||
unsigned int u = (unsigned int)uInterp;
|
||||
unsigned int v = (unsigned int)vInterp;
|
||||
|
||||
|
||||
ColorF32 shading;
|
||||
|
||||
// Gouraud shading - interpolate color based on vertices
|
||||
if (smooth)
|
||||
{
|
||||
shading =
|
||||
(barycenter[0] * v0.color)
|
||||
+ (barycenter[1] * v1.color)
|
||||
+ (barycenter[2] * v2.color);
|
||||
}
|
||||
// Flat shading - base color on single face color
|
||||
else
|
||||
{
|
||||
shading = mesh.faces[f].color;
|
||||
}
|
||||
// Gouraud shading
|
||||
ColorF32 shading =
|
||||
(barycenter[0] * v0.color)
|
||||
+ (barycenter[1] * v1.color)
|
||||
+ (barycenter[2] * v2.color);
|
||||
|
||||
|
||||
// Shade the texel with lighting calculations
|
||||
ColorU32 texel = texture.texels[vPixel][uPixel];
|
||||
texel.r *= shading.r;
|
||||
texel.g *= shading.g;
|
||||
texel.b *= shading.b;
|
||||
// Bilinear filtering
|
||||
float du = uInterp - u;
|
||||
float dv = vInterp - v;
|
||||
float duDiff = 1-du;
|
||||
float dvDiff = 1-dv;
|
||||
|
||||
ColorU32 color;
|
||||
|
||||
color.b = (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);
|
||||
|
||||
color.g = (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);
|
||||
|
||||
color.r = (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);
|
||||
|
||||
|
||||
// Shade the texture with the light calculations
|
||||
color.b *= shading.b;
|
||||
color.g *= shading.g;
|
||||
color.r *= shading.r;
|
||||
|
||||
|
||||
// Interpolate 1/z for the z-buffer
|
||||
|
@ -179,12 +198,11 @@ void RenderMesh(Engine_Buffer &buffer, Mesh_TransformedData &mesh, bool smooth,
|
|||
+ (barycenter[2] * v2.point.w));
|
||||
|
||||
|
||||
|
||||
// Draw the pixel if it's closer than what's in the z-buffer
|
||||
int pixel = (y * buffer.width + x);
|
||||
if (zInv > buffer.zbuffer[pixel])
|
||||
{
|
||||
DrawPixel(buffer.buffer, buffer.width, texel.u32, x, y);
|
||||
DrawPixel(buffer.buffer, buffer.width, color.u32, x, y);
|
||||
|
||||
buffer.zbuffer[pixel] = zInv;
|
||||
}
|
||||
|
|
|
@ -169,10 +169,6 @@ static void HandleEvent(
|
|||
{
|
||||
SET_BIT(platform.input, ROTATE_Y_NEG);
|
||||
} break;
|
||||
case SDLK_g:
|
||||
{
|
||||
SET_BIT(platform.input, SHADING_TOGGLE);
|
||||
} break;
|
||||
case SDLK_UP:
|
||||
{
|
||||
SET_BIT(platform.input, SCALE_UP);
|
||||
|
@ -235,10 +231,6 @@ static void HandleEvent(
|
|||
{
|
||||
CLEAR_BIT(platform.input, ROTATE_Y_NEG);
|
||||
} break;
|
||||
case SDLK_g:
|
||||
{
|
||||
CLEAR_BIT(platform.input, SHADING_TOGGLE);
|
||||
} break;
|
||||
case SDLK_UP:
|
||||
{
|
||||
CLEAR_BIT(platform.input, SCALE_UP);
|
||||
|
|
Loading…
Reference in New Issue