mirror of
https://github.com/isledecomp/isle-portable.git
synced 2025-09-22 11:31:57 -04:00
Use dedicated path for flat shading (#248)
This commit is contained in:
parent
cd4a24ec9e
commit
de82e8477a
@ -146,15 +146,15 @@ void Direct3DRMSoftwareRenderer::BlendPixel(Uint8* pixelAddr, Uint8 r, Uint8 g,
|
|||||||
memcpy(pixelAddr, &blended, m_bytesPerPixel);
|
memcpy(pixelAddr, &blended, m_bytesPerPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Color Direct3DRMSoftwareRenderer::ApplyLighting(const D3DRMVERTEX& vertex, const Appearance& appearance)
|
SDL_Color Direct3DRMSoftwareRenderer::ApplyLighting(
|
||||||
|
const D3DVECTOR& position,
|
||||||
|
const D3DVECTOR& normal,
|
||||||
|
const Appearance& appearance
|
||||||
|
)
|
||||||
{
|
{
|
||||||
FColor specular = {0, 0, 0, 0};
|
FColor specular = {0, 0, 0, 0};
|
||||||
FColor diffuse = {0, 0, 0, 0};
|
FColor diffuse = {0, 0, 0, 0};
|
||||||
|
|
||||||
// Position and normal
|
|
||||||
D3DVECTOR position = vertex.position;
|
|
||||||
D3DVECTOR normal = Normalize(vertex.normal);
|
|
||||||
|
|
||||||
for (const auto& light : m_lights) {
|
for (const auto& light : m_lights) {
|
||||||
FColor lightColor = light.color;
|
FColor lightColor = light.color;
|
||||||
|
|
||||||
@ -201,6 +201,16 @@ SDL_Color Direct3DRMSoftwareRenderer::ApplyLighting(const D3DRMVERTEX& vertex, c
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float EdgeFloat(float x0, float y0, float x1, float y1, float x, float y)
|
||||||
|
{
|
||||||
|
return (x - x0) * (y1 - y0) - (y - y0) * (x1 - x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float EdgeDouble(double x0, double y0, double x1, double y1, double x, double y)
|
||||||
|
{
|
||||||
|
return (x - x0) * (y1 - y0) - (y - y0) * (x1 - x0);
|
||||||
|
}
|
||||||
|
|
||||||
void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
|
void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
|
||||||
const D3DRMVERTEX& v0,
|
const D3DRMVERTEX& v0,
|
||||||
const D3DRMVERTEX& v1,
|
const D3DRMVERTEX& v1,
|
||||||
@ -235,19 +245,20 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto edge = [](double x0, double y0, double x1, double y1, double x, double y) {
|
// Cull backfaces
|
||||||
return (x - x0) * (y1 - y0) - (y - y0) * (x1 - x0);
|
float area = EdgeFloat(p0.x, p0.y, p1.x, p1.y, p2.x, p2.y);
|
||||||
};
|
|
||||||
float area = edge(p0.x, p0.y, p1.x, p1.y, p2.x, p2.y);
|
|
||||||
if (area >= 0) {
|
if (area >= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float invArea = 1.0f / area;
|
float invArea = 1.0f / area;
|
||||||
|
|
||||||
// Per-vertex lighting using vertex normals
|
Uint8 r, g, b;
|
||||||
SDL_Color c0 = ApplyLighting(v0, appearance);
|
SDL_Color c0 = ApplyLighting(v0.position, v0.normal, appearance);
|
||||||
SDL_Color c1 = ApplyLighting(v1, appearance);
|
SDL_Color c1, c2;
|
||||||
SDL_Color c2 = ApplyLighting(v2, appearance);
|
if (!appearance.flat) {
|
||||||
|
c1 = ApplyLighting(v1.position, v1.normal, appearance);
|
||||||
|
c2 = ApplyLighting(v2.position, v2.normal, appearance);
|
||||||
|
}
|
||||||
|
|
||||||
Uint32 textureId = appearance.textureId;
|
Uint32 textureId = appearance.textureId;
|
||||||
int texturePitch;
|
int texturePitch;
|
||||||
@ -271,12 +282,12 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
|
|||||||
for (int x = minX; x <= maxX; ++x) {
|
for (int x = minX; x <= maxX; ++x) {
|
||||||
float px = x + 0.5f;
|
float px = x + 0.5f;
|
||||||
float py = y + 0.5f;
|
float py = y + 0.5f;
|
||||||
float w0 = edge(p1.x, p1.y, p2.x, p2.y, px, py) * invArea;
|
float w0 = EdgeDouble(p1.x, p1.y, p2.x, p2.y, px, py) * invArea;
|
||||||
if (w0 < 0.0f || w0 > 1.0f) {
|
if (w0 < 0.0f || w0 > 1.0f) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float w1 = edge(p2.x, p2.y, p0.x, p0.y, px, py) * invArea;
|
float w1 = EdgeDouble(p2.x, p2.y, p0.x, p0.y, px, py) * invArea;
|
||||||
if (w1 < 0.0f || w1 > 1.0f - w0) {
|
if (w1 < 0.0f || w1 > 1.0f - w0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -290,10 +301,16 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interpolate color
|
if (appearance.flat) {
|
||||||
Uint8 r = static_cast<Uint8>(w0 * c0.r + w1 * c1.r + w2 * c2.r);
|
r = c0.r;
|
||||||
Uint8 g = static_cast<Uint8>(w0 * c0.g + w1 * c1.g + w2 * c2.g);
|
g = c0.g;
|
||||||
Uint8 b = static_cast<Uint8>(w0 * c0.b + w1 * c1.b + w2 * c2.b);
|
b = c0.b;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = static_cast<Uint8>(w0 * c0.r + w1 * c1.r + w2 * c2.r);
|
||||||
|
g = static_cast<Uint8>(w0 * c0.g + w1 * c1.g + w2 * c2.g);
|
||||||
|
b = static_cast<Uint8>(w0 * c0.b + w1 * c1.b + w2 * c2.b);
|
||||||
|
}
|
||||||
Uint8* pixelAddr = pixels + y * pitch + x * m_bytesPerPixel;
|
Uint8* pixelAddr = pixels + y * pitch + x * m_bytesPerPixel;
|
||||||
|
|
||||||
if (appearance.color.a == 255) {
|
if (appearance.color.a == 255) {
|
||||||
@ -322,8 +339,22 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
|
|||||||
|
|
||||||
Uint8* texelAddr = texels + texY * texturePitch + texX * m_bytesPerPixel;
|
Uint8* texelAddr = texels + texY * texturePitch + texX * m_bytesPerPixel;
|
||||||
|
|
||||||
Uint32 texelColor = 0;
|
Uint32 texelColor;
|
||||||
memcpy(&texelColor, texelAddr, m_bytesPerPixel);
|
switch (m_bytesPerPixel) {
|
||||||
|
case 1:
|
||||||
|
texelColor = *texelAddr;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
texelColor = *(Uint16*) texelAddr;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// Manually build the 24-bit color (assuming byte order)
|
||||||
|
texelColor = texelAddr[0] | (texelAddr[1] << 8) | (texelAddr[2] << 16);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
texelColor = *(Uint32*) texelAddr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Uint8 tr, tg, tb, ta;
|
Uint8 tr, tg, tb, ta;
|
||||||
SDL_GetRGBA(texelColor, m_format, m_palette, &tr, &tg, &tb, &ta);
|
SDL_GetRGBA(texelColor, m_format, m_palette, &tr, &tg, &tb, &ta);
|
||||||
|
@ -49,7 +49,7 @@ private:
|
|||||||
void DrawTriangleClipped(const D3DRMVERTEX (&v)[3], const Appearance& appearance);
|
void DrawTriangleClipped(const D3DRMVERTEX (&v)[3], const Appearance& appearance);
|
||||||
void ProjectVertex(const D3DRMVERTEX& v, D3DRMVECTOR4D& p) const;
|
void ProjectVertex(const D3DRMVERTEX& v, D3DRMVECTOR4D& p) const;
|
||||||
void BlendPixel(Uint8* pixelAddr, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
void BlendPixel(Uint8* pixelAddr, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||||
SDL_Color ApplyLighting(const D3DRMVERTEX& vertex, const Appearance& appearance);
|
SDL_Color ApplyLighting(const D3DVECTOR& position, const D3DVECTOR& normal, const Appearance& appearance);
|
||||||
void AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture);
|
void AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture);
|
||||||
|
|
||||||
DWORD m_width;
|
DWORD m_width;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user