From f1733b42a54e580f58c00b20eb78b2d084634f6c Mon Sep 17 00:00:00 2001 From: Austin Morlan Date: Tue, 18 Sep 2018 19:59:16 -0700 Subject: [PATCH] Clean up main render loop --- src/geometry.cpp | 55 ++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/src/geometry.cpp b/src/geometry.cpp index e635196..a1fbc64 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -110,15 +110,12 @@ void RenderMesh( { for (int x = xMin; x <= xMax; ++x) { - // Constant terms used for barycentric calculation + // Calculate the barycentric coordinate of this point Point p(x, y, 1.0f); Vector v0P = p - p0; float dot0P01 = Vector::Dot(v0P, v01); float dot0P02 = Vector::Dot(v0P, v02); float denomInv = 1.0f / ((dot0101 * dot0202) - (dot0102 * dot0102)); - - - // Calculate the barycentric coordinate of this point float barycenter[3]; barycenter[1] = (dot0202 * dot0P01 - dot0102 * dot0P02) * denomInv; barycenter[2] = (dot0101 * dot0P02 - dot0102 * dot0P01) * denomInv; @@ -130,47 +127,36 @@ void RenderMesh( && (barycenter[1] >= 0.0f) && (barycenter[2] >= 0.0f)) { - ColorF32 &c0 = verts.data[face.vertIndex[0]].color; - ColorF32 &c1 = verts.data[face.vertIndex[1]].color; - ColorF32 &c2 = verts.data[face.vertIndex[2]].color; + // 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]]; - // Gouraud shading - ColorF32 shading = - (barycenter[0] * c0) - + (barycenter[1] * c1) - + (barycenter[2] * c2); - - - // Constant terms used in the U and V interpolation 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); - UV &uv0 = uvs.data[face.uvIndex[0]]; - UV &uv1 = uvs.data[face.uvIndex[1]]; - UV &uv2 = uvs.data[face.uvIndex[2]]; + float uInterp = + ((a * uv0.u) + (b * uv1.u) + (c * uv2.u)) + * abc + * texture.width; - // Interpolate U and V - float uInterp = ((a * uv0.u) + (b * uv1.u) + (c * uv2.u)) * abc; - float vInterp = ((a * uv0.v) + (b * uv1.v) + (c * uv2.v)) * abc; + float vInterp = + ((a * uv0.v) + (b * uv1.v) + (c * uv2.v)) + * abc + * texture.height; - // Convert U and V to pixels in the texture image - Texture &texture = textures.data[faces.data[f].materialIndex]; - uInterp *= texture.width; - vInterp *= texture.height; + // Bilinear filtering unsigned int u = (unsigned int)uInterp; unsigned int v = (unsigned int)vInterp; - - // Constant terms for bilinear filtering float du = uInterp - u; float dv = vInterp - v; float duDiff = 1 - du; float dvDiff = 1 - dv; - - // Bilinear filtering ColorU32 color; color.b = (uint8_t) (duDiff * dvDiff * texture.texels[v][u].b @@ -191,7 +177,16 @@ void RenderMesh( + duDiff * dv * texture.texels[v+1][u].r); - // Shade the texture with the light calculations + // 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); + color.b *= shading.b; color.g *= shading.g; color.r *= shading.r;