Add alpha blending of transparent textures
This commit is contained in:
parent
abf9e8fa7c
commit
ba68f22bee
|
@ -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);
|
||||
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),
|
||||
|
||||
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);
|
||||
(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);
|
||||
(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…
Reference in New Issue