Add bilinear filtering
This commit is contained in:
parent
20402784f7
commit
21fb0058ad
|
@ -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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
if (smooth)
|
|
||||||
{
|
|
||||||
shading =
|
|
||||||
(barycenter[0] * v0.color)
|
(barycenter[0] * v0.color)
|
||||||
+ (barycenter[1] * v1.color)
|
+ (barycenter[1] * v1.color)
|
||||||
+ (barycenter[2] * v2.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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue