1
0
Fork 0

Add bilinear filtering

This commit is contained in:
Austin Morlan 2018-09-13 19:19:59 -07:00
parent 20402784f7
commit 21fb0058ad
Signed by: austin
GPG Key ID: FD6B27654AF5E348
5 changed files with 54 additions and 54 deletions

View File

@ -19,8 +19,7 @@ enum Engine_Input
ROTATE_Z_POS, ROTATE_Z_POS,
ROTATE_Z_NEG, ROTATE_Z_NEG,
SCALE_UP, SCALE_UP,
SCALE_DOWN, SCALE_DOWN
SHADING_TOGGLE
}; };

View File

@ -10,6 +10,7 @@
// STRUCTURES // STRUCTURES
struct Material struct Material
{ {
bool smooth;
ColorF32 kAmbient; ColorF32 kAmbient;
ColorF32 kDiffuse; ColorF32 kDiffuse;
}; };
@ -75,7 +76,6 @@ struct Mesh
float scale; float scale;
Material material; Material material;
bool smooth;
Mesh_LocalData local; Mesh_LocalData local;
Mesh_TransformedData transformed; Mesh_TransformedData transformed;
@ -88,8 +88,8 @@ void CullBackfaces(
Point &camPosition); Point &camPosition);
void RenderMesh( void RenderMesh(
Engine_Buffer &buffer, Mesh_TransformedData &mesh, bool smooth, Texture &texture, Engine_Buffer &buffer, Mesh_TransformedData &mesh,
std::vector<TextureCoord> &uvs); Texture &texture, std::vector<TextureCoord> &uvs);
#define GEOMETRY_H #define GEOMETRY_H

View File

@ -35,6 +35,7 @@ int Engine_Init(Engine_Buffer &buffer, char *filename)
mesh.position.z = 250; mesh.position.z = 250;
mesh.material.kDiffuse = {1.0,1.0,1.0,1.0}; mesh.material.kDiffuse = {1.0,1.0,1.0,1.0};
mesh.material.kAmbient = {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); 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 // Clear the z-buffer
unsigned long bufferSize = (unsigned long)(buffer.width * buffer.height); memset(buffer.zbuffer, 0, sizeof(float) * (size_t)(buffer.width * buffer.height));
memset(buffer.zbuffer, 0, bufferSize * sizeof(float));
// Local space to world space // Local space to world space
@ -78,7 +78,7 @@ void Engine_Render(Engine_Buffer &buffer, uint32_t input)
// Color the vertices for Gouraud shading // Color the vertices for Gouraud shading
if (mesh.smooth) if (mesh.material.smooth)
{ {
for (size_t f = 0; f < mesh.transformed.faces.size(); ++f) 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; 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) void Engine_Shutdown(void)
@ -208,13 +208,4 @@ static void CheckInputs(uint32_t input)
{ {
mesh.scale -= 0.1f; mesh.scale -= 0.1f;
} }
if (CHECK_BIT(input, SHADING_TOGGLE))
{
mesh.smooth = true;
}
else
{
mesh.smooth = false;
}
} }

View File

@ -66,8 +66,9 @@ void CullBackfaces(
} }
void RenderMesh(Engine_Buffer &buffer, Mesh_TransformedData &mesh, bool smooth, Texture &texture, void RenderMesh(
std::vector<TextureCoord> &uvs) Engine_Buffer &buffer, Mesh_TransformedData &mesh,
Texture &texture, std::vector<TextureCoord> &uvs)
{ {
for(size_t f = 0; f < mesh.faces.size(); ++f) 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 // Interpolate U and V
float u = ((a * t0.u) + (b * t1.u) + (c * t2.u)) * abc; float uInterp = ((a * t0.u) + (b * t1.u) + (c * t2.u)) * abc;
float v = ((a * t0.v) + (b * t1.v) + (c * t2.v)) * abc; float vInterp = ((a * t0.v) + (b * t1.v) + (c * t2.v)) * abc;
// Convert U and V to pixels in the texture image // Convert U and V to pixels in the texture image
unsigned int uPixel = (unsigned int)(u * texture.width); uInterp *= texture.width;
unsigned int vPixel = (unsigned int)(v * texture.height); vInterp *= texture.height;
unsigned int u = (unsigned int)uInterp;
unsigned int v = (unsigned int)vInterp;
ColorF32 shading; // Gouraud shading
ColorF32 shading =
// Gouraud shading - interpolate color based on vertices (barycenter[0] * v0.color)
if (smooth) + (barycenter[1] * v1.color)
{ + (barycenter[2] * v2.color);
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;
}
// Shade the texel with lighting calculations // Bilinear filtering
ColorU32 texel = texture.texels[vPixel][uPixel]; float du = uInterp - u;
texel.r *= shading.r; float dv = vInterp - v;
texel.g *= shading.g; float duDiff = 1-du;
texel.b *= shading.b; 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 // 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)); + (barycenter[2] * v2.point.w));
// Draw the pixel if it's closer than what's in the z-buffer // Draw the pixel if it's closer than what's in the z-buffer
int pixel = (y * buffer.width + x); int pixel = (y * buffer.width + x);
if (zInv > buffer.zbuffer[pixel]) 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; buffer.zbuffer[pixel] = zInv;
} }

View File

@ -169,10 +169,6 @@ static void HandleEvent(
{ {
SET_BIT(platform.input, ROTATE_Y_NEG); SET_BIT(platform.input, ROTATE_Y_NEG);
} break; } break;
case SDLK_g:
{
SET_BIT(platform.input, SHADING_TOGGLE);
} break;
case SDLK_UP: case SDLK_UP:
{ {
SET_BIT(platform.input, SCALE_UP); SET_BIT(platform.input, SCALE_UP);
@ -235,10 +231,6 @@ static void HandleEvent(
{ {
CLEAR_BIT(platform.input, ROTATE_Y_NEG); CLEAR_BIT(platform.input, ROTATE_Y_NEG);
} break; } break;
case SDLK_g:
{
CLEAR_BIT(platform.input, SHADING_TOGGLE);
} break;
case SDLK_UP: case SDLK_UP:
{ {
CLEAR_BIT(platform.input, SCALE_UP); CLEAR_BIT(platform.input, SCALE_UP);