1
0
Fork 0

Add alpha blending of transparent textures

master
Austin Morlan 4 years ago
parent abf9e8fa7c
commit ba68f22bee
Signed by: austin
GPG Key ID: FD6B27654AF5E348
  1. 14
      src/engine.cpp
  2. 9
      src/loader.cpp
  3. 63
      src/render.cpp

@ -64,7 +64,7 @@ int EngineInit(char *objFilename, char *mtlFilename)
// Mesh configuration
mesh.position.z = 175;
mesh.position.z = 50;
mesh.position.y = -175;
mesh.scale = 1.0f;
@ -152,29 +152,29 @@ static void CheckInputs(uint32_t input)
if (CHECK_BIT(input, ROTATE_X_POS))
{
mesh.position.x += 10;
mesh.rotation.x += 0.10f;
}
else if (CHECK_BIT(input, ROTATE_X_NEG))
{
mesh.position.x -= 10;
mesh.rotation.x -= 0.10f;
}
if (CHECK_BIT(input, ROTATE_Y_POS))
{
mesh.position.y += 10;
mesh.rotation.y += 0.10f;
}
else if (CHECK_BIT(input, ROTATE_Y_NEG))
{
mesh.position.y -= 10;
mesh.rotation.y -= 0.10f;
}
if (CHECK_BIT(input, ROTATE_Z_POS))
{
mesh.position.z += 10;
mesh.rotation.z += 0.10f;
}
else if (CHECK_BIT(input, ROTATE_Z_NEG))
{
mesh.position.z -= 10;
mesh.rotation.z -= 0.10f;
}
if (CHECK_BIT(input, SCALE_UP))

@ -8,7 +8,7 @@
// STATIC PROTOTYPES
static int LoadTexture(char *filename, Texture &texture);
static int LoadTexture(char *filename, Texture &texture, float opacity);
#pragma pack(push, 1)
@ -194,7 +194,9 @@ int ParseMTL(char *filename, EngineMemory &memory)
{
char *textureFilename = data;
textureFilename[strcspn(textureFilename, "\r\n")] = 0;
LoadTexture(textureFilename, textures.data[materialIndex]);
LoadTexture(
textureFilename, textures.data[materialIndex],
materials.data[materialIndex].opacity);
}
}
}
@ -204,7 +206,7 @@ int ParseMTL(char *filename, EngineMemory &memory)
return 0;
}
static int LoadTexture(char *filename, Texture &texture)
static int LoadTexture(char *filename, Texture &texture, float opacity)
{
FILE *fp = fopen(filename, "r");
if (fp == NULL)
@ -227,6 +229,7 @@ static int LoadTexture(char *filename, Texture &texture)
fread(&texture.texels[y][x].b, 1, 1, fp);
fread(&texture.texels[y][x].g, 1, 1, fp);
fread(&texture.texels[y][x].r, 1, 1, fp);
texture.texels[y][x].a = (uint8_t)(255 * opacity);
}
// Discard padding byte

@ -114,24 +114,32 @@ void Render(EngineBuffer &buffer, EngineMemory &memory)
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);
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
@ -145,7 +153,7 @@ void Render(EngineBuffer &buffer, EngineMemory &memory)
+ (barycenter[2] * c2);
// Ensure no color channel exceeds 1.0
// Ensure no color channel exceeds max
ScaleColor(shading);
@ -154,6 +162,7 @@ void Render(EngineBuffer &buffer, EngineMemory &memory)
color.g *= shading.g;
color.r *= shading.r;
// Interpolate 1/z for the z-buffer
float zInv =
1.0f /
@ -165,7 +174,21 @@ void Render(EngineBuffer &buffer, EngineMemory &memory)
// Draw the pixel if it's closer than what's in the z-buffer
if (zInv > memory.zbuffer[y][x])
{
DrawPixel(buffer.buffer, buffer.width, color.u32, x, y);
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)),
(uint8_t)((alpha * color.g) + (alphaDiff * pixel->g)),
(uint8_t)((alpha * color.r) + (alphaDiff * pixel->r)),
(uint8_t)((alpha * color.a) + (alphaDiff * pixel->a))
};
DrawPixel(buffer.buffer, buffer.width, blended.u32, x, y);
memory.zbuffer[y][x] = zInv;
}

Loading…
Cancel
Save