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 configuration
|
||||||
mesh.position.z = 175;
|
mesh.position.z = 50;
|
||||||
mesh.position.y = -175;
|
mesh.position.y = -175;
|
||||||
mesh.scale = 1.0f;
|
mesh.scale = 1.0f;
|
||||||
|
|
||||||
|
@ -152,29 +152,29 @@ static void CheckInputs(uint32_t input)
|
||||||
|
|
||||||
if (CHECK_BIT(input, ROTATE_X_POS))
|
if (CHECK_BIT(input, ROTATE_X_POS))
|
||||||
{
|
{
|
||||||
mesh.position.x += 10;
|
mesh.rotation.x += 0.10f;
|
||||||
}
|
}
|
||||||
else if (CHECK_BIT(input, ROTATE_X_NEG))
|
else if (CHECK_BIT(input, ROTATE_X_NEG))
|
||||||
{
|
{
|
||||||
mesh.position.x -= 10;
|
mesh.rotation.x -= 0.10f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_BIT(input, ROTATE_Y_POS))
|
if (CHECK_BIT(input, ROTATE_Y_POS))
|
||||||
{
|
{
|
||||||
mesh.position.y += 10;
|
mesh.rotation.y += 0.10f;
|
||||||
}
|
}
|
||||||
else if (CHECK_BIT(input, ROTATE_Y_NEG))
|
else if (CHECK_BIT(input, ROTATE_Y_NEG))
|
||||||
{
|
{
|
||||||
mesh.position.y -= 10;
|
mesh.rotation.y -= 0.10f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_BIT(input, ROTATE_Z_POS))
|
if (CHECK_BIT(input, ROTATE_Z_POS))
|
||||||
{
|
{
|
||||||
mesh.position.z += 10;
|
mesh.rotation.z += 0.10f;
|
||||||
}
|
}
|
||||||
else if (CHECK_BIT(input, ROTATE_Z_NEG))
|
else if (CHECK_BIT(input, ROTATE_Z_NEG))
|
||||||
{
|
{
|
||||||
mesh.position.z -= 10;
|
mesh.rotation.z -= 0.10f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_BIT(input, SCALE_UP))
|
if (CHECK_BIT(input, SCALE_UP))
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
|
|
||||||
// STATIC PROTOTYPES
|
// STATIC PROTOTYPES
|
||||||
static int LoadTexture(char *filename, Texture &texture);
|
static int LoadTexture(char *filename, Texture &texture, float opacity);
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
@ -194,7 +194,9 @@ int ParseMTL(char *filename, EngineMemory &memory)
|
||||||
{
|
{
|
||||||
char *textureFilename = data;
|
char *textureFilename = data;
|
||||||
textureFilename[strcspn(textureFilename, "\r\n")] = 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int LoadTexture(char *filename, Texture &texture)
|
static int LoadTexture(char *filename, Texture &texture, float opacity)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(filename, "r");
|
FILE *fp = fopen(filename, "r");
|
||||||
if (fp == NULL)
|
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].b, 1, 1, fp);
|
||||||
fread(&texture.texels[y][x].g, 1, 1, fp);
|
fread(&texture.texels[y][x].g, 1, 1, fp);
|
||||||
fread(&texture.texels[y][x].r, 1, 1, fp);
|
fread(&texture.texels[y][x].r, 1, 1, fp);
|
||||||
|
texture.texels[y][x].a = (uint8_t)(255 * opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discard padding byte
|
// Discard padding byte
|
||||||
|
|
|
@ -114,24 +114,32 @@ void Render(EngineBuffer &buffer, EngineMemory &memory)
|
||||||
float duDiff = 1 - du;
|
float duDiff = 1 - du;
|
||||||
float dvDiff = 1 - dv;
|
float dvDiff = 1 - dv;
|
||||||
|
|
||||||
ColorU32 color;
|
ColorU32 color =
|
||||||
color.b = (uint8_t)
|
{
|
||||||
|
(uint8_t)
|
||||||
(duDiff * dvDiff * texture.texels[v][u].b
|
(duDiff * dvDiff * texture.texels[v][u].b
|
||||||
+ du * dvDiff * texture.texels[v][u+1].b
|
+ du * dvDiff * texture.texels[v][u+1].b
|
||||||
+ du * dv * texture.texels[v+1][u+1].b
|
+ du * dv * texture.texels[v+1][u+1].b
|
||||||
+ duDiff * dv * texture.texels[v+1][u].b);
|
+ duDiff * dv * texture.texels[v+1][u].b),
|
||||||
|
|
||||||
color.g = (uint8_t)
|
(uint8_t)
|
||||||
(duDiff * dvDiff * texture.texels[v][u].g
|
(duDiff * dvDiff * texture.texels[v][u].g
|
||||||
+ du * dvDiff * texture.texels[v][u+1].g
|
+ du * dvDiff * texture.texels[v][u+1].g
|
||||||
+ du * dv * texture.texels[v+1][u+1].g
|
+ du * dv * texture.texels[v+1][u+1].g
|
||||||
+ duDiff * dv * texture.texels[v+1][u].g);
|
+ duDiff * dv * texture.texels[v+1][u].g),
|
||||||
|
|
||||||
color.r = (uint8_t)
|
(uint8_t)
|
||||||
(duDiff * dvDiff * texture.texels[v][u].r
|
(duDiff * dvDiff * texture.texels[v][u].r
|
||||||
+ du * dvDiff * texture.texels[v][u+1].r
|
+ du * dvDiff * texture.texels[v][u+1].r
|
||||||
+ du * dv * texture.texels[v+1][u+1].r
|
+ du * dv * texture.texels[v+1][u+1].r
|
||||||
+ duDiff * dv * texture.texels[v+1][u].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
|
// Perform Gouraud shading on the texture
|
||||||
|
@ -145,7 +153,7 @@ void Render(EngineBuffer &buffer, EngineMemory &memory)
|
||||||
+ (barycenter[2] * c2);
|
+ (barycenter[2] * c2);
|
||||||
|
|
||||||
|
|
||||||
// Ensure no color channel exceeds 1.0
|
// Ensure no color channel exceeds max
|
||||||
ScaleColor(shading);
|
ScaleColor(shading);
|
||||||
|
|
||||||
|
|
||||||
|
@ -154,6 +162,7 @@ void Render(EngineBuffer &buffer, EngineMemory &memory)
|
||||||
color.g *= shading.g;
|
color.g *= shading.g;
|
||||||
color.r *= shading.r;
|
color.r *= shading.r;
|
||||||
|
|
||||||
|
|
||||||
// Interpolate 1/z for the z-buffer
|
// Interpolate 1/z for the z-buffer
|
||||||
float zInv =
|
float zInv =
|
||||||
1.0f /
|
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
|
// Draw the pixel if it's closer than what's in the z-buffer
|
||||||
if (zInv > memory.zbuffer[y][x])
|
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;
|
memory.zbuffer[y][x] = zInv;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue