diff --git a/src/render.cpp b/src/render.cpp index dadeaef..1b4fa70 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -84,85 +84,6 @@ void Render(EngineBuffer &buffer, EngineMemory &memory) && (barycenter[1] >= 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 float zInv = 1.0f / @@ -171,15 +92,97 @@ void Render(EngineBuffer &buffer, EngineMemory &memory) + (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]) { - 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 alphaDiff = 1.0f - alpha; - // Blend new color with the existing color ColorU32 blended = { (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)) }; - DrawPixel(buffer.buffer, buffer.width, blended.u32, x, y); - memory.zbuffer[y][x] = zInv; + // Draw + DrawPixel(buffer.buffer, buffer.width, blended.u32, x, y); } } }