mirror of
https://github.com/isledecomp/isle-portable.git
synced 2025-09-23 03:55:44 -04:00
software: Add support for transparent surfaces (#201)
Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>
This commit is contained in:
parent
f6c9eaa006
commit
0ab5070b46
@ -10,15 +10,12 @@
|
|||||||
|
|
||||||
Direct3DRMSoftwareRenderer::Direct3DRMSoftwareRenderer(DWORD width, DWORD height) : m_width(width), m_height(height)
|
Direct3DRMSoftwareRenderer::Direct3DRMSoftwareRenderer(DWORD width, DWORD height) : m_width(width), m_height(height)
|
||||||
{
|
{
|
||||||
|
m_zBuffer.resize(m_width * m_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Direct3DRMSoftwareRenderer::SetBackbuffer(SDL_Surface* buf)
|
void Direct3DRMSoftwareRenderer::SetBackbuffer(SDL_Surface* buf)
|
||||||
{
|
{
|
||||||
m_backbuffer = buf;
|
m_backbuffer = buf;
|
||||||
if (m_backbuffer) {
|
|
||||||
m_zBuffer.resize(m_width * m_height);
|
|
||||||
std::fill(m_zBuffer.begin(), m_zBuffer.end(), std::numeric_limits<float>::infinity());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Direct3DRMSoftwareRenderer::PushLights(const SceneLight* vertices, size_t count)
|
void Direct3DRMSoftwareRenderer::PushLights(const SceneLight* vertices, size_t count)
|
||||||
@ -28,7 +25,11 @@ void Direct3DRMSoftwareRenderer::PushLights(const SceneLight* vertices, size_t c
|
|||||||
|
|
||||||
void Direct3DRMSoftwareRenderer::PushVertices(const PositionColorVertex* vertices, size_t count)
|
void Direct3DRMSoftwareRenderer::PushVertices(const PositionColorVertex* vertices, size_t count)
|
||||||
{
|
{
|
||||||
m_vertexBuffer.insert(m_vertexBuffer.end(), vertices, vertices + count);
|
if (!count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_vertexBuffer.resize(count);
|
||||||
|
memcpy(m_vertexBuffer.data(), vertices, count * sizeof(PositionColorVertex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Direct3DRMSoftwareRenderer::SetProjection(D3DRMMATRIX4D perspective, D3DVALUE front, D3DVALUE back)
|
void Direct3DRMSoftwareRenderer::SetProjection(D3DRMMATRIX4D perspective, D3DVALUE front, D3DVALUE back)
|
||||||
@ -121,6 +122,29 @@ void Direct3DRMSoftwareRenderer::DrawTriangleClipped(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo pre-compute a blending table when running in 256 colors since the game always uses an alpha of 152
|
||||||
|
*/
|
||||||
|
void Direct3DRMSoftwareRenderer::BlendPixel(Uint8* pixelAddr, const PositionColorVertex& srcColor)
|
||||||
|
{
|
||||||
|
Uint32 dstPixel = 0;
|
||||||
|
memcpy(&dstPixel, pixelAddr, m_bytesPerPixel);
|
||||||
|
|
||||||
|
Uint8 dstR, dstG, dstB, dstA;
|
||||||
|
SDL_GetRGBA(dstPixel, m_format, m_palette, &dstR, &dstG, &dstB, &dstA);
|
||||||
|
|
||||||
|
float alpha = srcColor.a / 255.0f;
|
||||||
|
float invAlpha = 1.0f - alpha;
|
||||||
|
|
||||||
|
Uint8 outR = static_cast<Uint8>(srcColor.r * alpha + dstR * invAlpha);
|
||||||
|
Uint8 outG = static_cast<Uint8>(srcColor.g * alpha + dstG * invAlpha);
|
||||||
|
Uint8 outB = static_cast<Uint8>(srcColor.b * alpha + dstB * invAlpha);
|
||||||
|
Uint8 outA = static_cast<Uint8>(srcColor.a + dstA * invAlpha);
|
||||||
|
|
||||||
|
Uint32 blended = SDL_MapRGBA(m_format, m_palette, outR, outG, outB, outA);
|
||||||
|
memcpy(pixelAddr, &blended, m_bytesPerPixel);
|
||||||
|
}
|
||||||
|
|
||||||
void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
|
void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
|
||||||
const PositionColorVertex& v0,
|
const PositionColorVertex& v0,
|
||||||
const PositionColorVertex& v1,
|
const PositionColorVertex& v1,
|
||||||
@ -160,10 +184,11 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
|
|||||||
}
|
}
|
||||||
float invArea = 1.0f / area;
|
float invArea = 1.0f / area;
|
||||||
|
|
||||||
const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(m_backbuffer->format);
|
Uint32 color;
|
||||||
Uint32 color = SDL_MapRGBA(format, nullptr, v0.r, v0.g, v0.b, v0.a);
|
if (v0.a == 255) {
|
||||||
|
color = SDL_MapRGBA(m_format, m_palette, v0.r, v0.g, v0.b, v0.a);
|
||||||
|
}
|
||||||
|
|
||||||
int bytesPerPixel = format->bits_per_pixel / 8;
|
|
||||||
Uint8* pixels = (Uint8*) m_backbuffer->pixels;
|
Uint8* pixels = (Uint8*) m_backbuffer->pixels;
|
||||||
int pitch = m_backbuffer->pitch;
|
int pitch = m_backbuffer->pitch;
|
||||||
|
|
||||||
@ -185,14 +210,19 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
|
|||||||
float z = w0 * z0 + w1 * z1 + w2 * z2;
|
float z = w0 * z0 + w1 * z1 + w2 * z2;
|
||||||
|
|
||||||
int zidx = y * m_width + x;
|
int zidx = y * m_width + x;
|
||||||
if (z >= m_zBuffer[zidx]) {
|
float& zref = m_zBuffer[zidx];
|
||||||
|
if (z >= zref) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_zBuffer[zidx] = z;
|
Uint8* pixelAddr = pixels + y * pitch + x * m_bytesPerPixel;
|
||||||
Uint8* pixelAddr = pixels + y * pitch + x * bytesPerPixel;
|
if (v0.a == 255) {
|
||||||
// TODO make color endian safe
|
zref = z;
|
||||||
memcpy(pixelAddr, &color, bytesPerPixel);
|
memcpy(pixelAddr, &color, m_bytesPerPixel);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BlendPixel(pixelAddr, v0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,7 +244,7 @@ void Direct3DRMSoftwareRenderer::GetDesc(D3DDEVICEDESC* halDesc, D3DDEVICEDESC*
|
|||||||
helDesc->dcmColorModel = D3DCOLORMODEL::RGB;
|
helDesc->dcmColorModel = D3DCOLORMODEL::RGB;
|
||||||
helDesc->dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH;
|
helDesc->dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH;
|
||||||
helDesc->dwDeviceZBufferBitDepth = DDBD_32;
|
helDesc->dwDeviceZBufferBitDepth = DDBD_32;
|
||||||
helDesc->dwDeviceRenderBitDepth = DDBD_16 | DDBD_24 | DDBD_32;
|
helDesc->dwDeviceRenderBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32;
|
||||||
helDesc->dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE;
|
helDesc->dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE;
|
||||||
helDesc->dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND;
|
helDesc->dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND;
|
||||||
helDesc->dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR;
|
helDesc->dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR;
|
||||||
@ -222,7 +252,7 @@ void Direct3DRMSoftwareRenderer::GetDesc(D3DDEVICEDESC* halDesc, D3DDEVICEDESC*
|
|||||||
|
|
||||||
const char* Direct3DRMSoftwareRenderer::GetName()
|
const char* Direct3DRMSoftwareRenderer::GetName()
|
||||||
{
|
{
|
||||||
return "Software Rendere";
|
return "Software Renderer";
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT Direct3DRMSoftwareRenderer::Render()
|
HRESULT Direct3DRMSoftwareRenderer::Render()
|
||||||
@ -231,6 +261,9 @@ HRESULT Direct3DRMSoftwareRenderer::Render()
|
|||||||
return DDERR_GENERIC;
|
return DDERR_GENERIC;
|
||||||
}
|
}
|
||||||
ClearZBuffer();
|
ClearZBuffer();
|
||||||
|
m_format = SDL_GetPixelFormatDetails(m_backbuffer->format);
|
||||||
|
m_palette = SDL_GetSurfacePalette(m_backbuffer);
|
||||||
|
m_bytesPerPixel = m_format->bits_per_pixel / 8;
|
||||||
for (size_t i = 0; i + 2 < m_vertexBuffer.size(); i += 3) {
|
for (size_t i = 0; i + 2 < m_vertexBuffer.size(); i += 3) {
|
||||||
DrawTriangleClipped(m_vertexBuffer[i], m_vertexBuffer[i + 1], m_vertexBuffer[i + 2]);
|
DrawTriangleClipped(m_vertexBuffer[i], m_vertexBuffer[i + 1], m_vertexBuffer[i + 2]);
|
||||||
}
|
}
|
||||||
|
@ -104,9 +104,6 @@ HRESULT DirectDrawSurfaceImpl::Blt(
|
|||||||
if (blitSource != srcSurface->m_surface) {
|
if (blitSource != srcSurface->m_surface) {
|
||||||
SDL_DestroySurface(blitSource);
|
SDL_DestroySurface(blitSource);
|
||||||
}
|
}
|
||||||
if (m_autoFlip) {
|
|
||||||
return Flip(nullptr, DDFLIP_WAIT);
|
|
||||||
}
|
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,10 +30,14 @@ private:
|
|||||||
const PositionColorVertex& v2
|
const PositionColorVertex& v2
|
||||||
);
|
);
|
||||||
void ProjectVertex(const PositionColorVertex&, float&, float&, float&) const;
|
void ProjectVertex(const PositionColorVertex&, float&, float&, float&) const;
|
||||||
|
void BlendPixel(Uint8* pixelAddr, const PositionColorVertex& srcColor);
|
||||||
|
|
||||||
DWORD m_width;
|
DWORD m_width;
|
||||||
DWORD m_height;
|
DWORD m_height;
|
||||||
SDL_Surface* m_backbuffer = nullptr;
|
SDL_Surface* m_backbuffer = nullptr;
|
||||||
|
SDL_Palette* m_palette;
|
||||||
|
const SDL_PixelFormatDetails* m_format;
|
||||||
|
int m_bytesPerPixel;
|
||||||
D3DVALUE m_front;
|
D3DVALUE m_front;
|
||||||
D3DVALUE m_back;
|
D3DVALUE m_back;
|
||||||
std::vector<PositionColorVertex> m_vertexBuffer;
|
std::vector<PositionColorVertex> m_vertexBuffer;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user