Skip to content

Commit

Permalink
Fix texture blending (#1098)
Browse files Browse the repository at this point in the history
* Fix TileBatcher blending

* Set blend mode before drawing

* Fix primitive blending

* Fix material primitive blending

* Fix texture blending

* Restore render states after drawing a tile

* Remove unnecessary texture stages from TileBatcher
  • Loading branch information
StrixG authored and ccw808 committed Oct 26, 2019
1 parent cee5627 commit d112011
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 61 deletions.
18 changes: 8 additions & 10 deletions Client/core/Graphics/CGraphics.cpp
Expand Up @@ -488,6 +488,7 @@ void CGraphics::CheckModes(EDrawModeType newDrawMode, EBlendModeType newBlendMod
// Draw mode changing? // Draw mode changing?
if (bDrawModeChanging || bBlendModeChanging) if (bDrawModeChanging || bBlendModeChanging)
{ {

// Flush old // Flush old
if (m_CurDrawMode == EDrawMode::DX_SPRITE) if (m_CurDrawMode == EDrawMode::DX_SPRITE)
{ {
Expand Down Expand Up @@ -521,16 +522,11 @@ void CGraphics::CheckModes(EDrawModeType newDrawMode, EBlendModeType newBlendMod
{ {
m_pLineInterface->Begin(); m_pLineInterface->Begin();
} }
}


// Blend mode changing?
if (bDrawModeChanging || bBlendModeChanging)
{
SetBlendModeRenderStates(newBlendMode); SetBlendModeRenderStates(newBlendMode);
m_CurBlendMode = newBlendMode;
m_CurDrawMode = newDrawMode;
} }

m_CurDrawMode = newDrawMode;
m_CurBlendMode = newBlendMode;
} }


void CGraphics::CalcWorldCoors(CVector* vecScreen, CVector* vecWorld) void CGraphics::CalcWorldCoors(CVector* vecScreen, CVector* vecWorld)
Expand Down Expand Up @@ -900,6 +896,7 @@ void CGraphics::DrawPrimitiveQueued(std::vector<PrimitiveVertice>* pVecVertices,
// Set up a queue item // Set up a queue item
sDrawQueueItem Item; sDrawQueueItem Item;
Item.eType = QUEUE_PRIMITIVE; Item.eType = QUEUE_PRIMITIVE;
Item.blendMode = m_ActiveBlendMode;
Item.Primitive.eType = eType; Item.Primitive.eType = eType;
Item.Primitive.pVecVertices = pVecVertices; Item.Primitive.pVecVertices = pVecVertices;
AddQueueItem(Item, bPostGUI); AddQueueItem(Item, bPostGUI);
Expand Down Expand Up @@ -968,6 +965,7 @@ void CGraphics::DrawMaterialPrimitiveQueued(std::vector<PrimitiveMaterialVertice
// Set up a queue item // Set up a queue item
sDrawQueueItem Item; sDrawQueueItem Item;
Item.eType = QUEUE_PRIMITIVEMATERIAL; Item.eType = QUEUE_PRIMITIVEMATERIAL;
Item.blendMode = m_ActiveBlendMode;
Item.PrimitiveMaterial.eType = eType; Item.PrimitiveMaterial.eType = eType;
Item.PrimitiveMaterial.pMaterial = pMaterial; Item.PrimitiveMaterial.pMaterial = pMaterial;
Item.PrimitiveMaterial.pVecVertices = pVecVertices; Item.PrimitiveMaterial.pVecVertices = pVecVertices;
Expand Down Expand Up @@ -1737,7 +1735,7 @@ void CGraphics::DrawQueueItem(const sDrawQueueItem& Item)
fU2 *= fUScale; fU2 *= fUScale;
fV2 *= fVScale; fV2 *= fVScale;
} }
CheckModes(EDrawMode::TILE_BATCHER); CheckModes(EDrawMode::TILE_BATCHER, Item.blendMode);
m_pTileBatcher->AddTile(t.fX, t.fY, t.fX + t.fWidth, t.fY + t.fHeight, fU1, fV1, fU2, fV2, t.pMaterial, t.fRotation, t.fRotCenOffX, t.fRotCenOffY, m_pTileBatcher->AddTile(t.fX, t.fY, t.fX + t.fWidth, t.fY + t.fHeight, fU1, fV1, fU2, fV2, t.pMaterial, t.fRotation, t.fRotCenOffX, t.fRotCenOffY,
t.ulColor); t.ulColor);
RemoveQueueRef(Item.Texture.pMaterial); RemoveQueueRef(Item.Texture.pMaterial);
Expand All @@ -1746,14 +1744,14 @@ void CGraphics::DrawQueueItem(const sDrawQueueItem& Item)
case QUEUE_PRIMITIVE: case QUEUE_PRIMITIVE:
{ {
const sDrawQueuePrimitive primitive = Item.Primitive; const sDrawQueuePrimitive primitive = Item.Primitive;
CheckModes(EDrawMode::PRIMITIVE); CheckModes(EDrawMode::PRIMITIVE, Item.blendMode);
m_pPrimitiveBatcher->AddPrimitive(primitive.eType, primitive.pVecVertices); m_pPrimitiveBatcher->AddPrimitive(primitive.eType, primitive.pVecVertices);
break; break;
} }
case QUEUE_PRIMITIVEMATERIAL: case QUEUE_PRIMITIVEMATERIAL:
{ {
const sDrawQueuePrimitiveMaterial primitive = Item.PrimitiveMaterial; const sDrawQueuePrimitiveMaterial primitive = Item.PrimitiveMaterial;
CheckModes(EDrawMode::PRIMITIVE_MATERIAL); CheckModes(EDrawMode::PRIMITIVE_MATERIAL, Item.blendMode);
m_pPrimitiveMaterialBatcher->AddPrimitive(primitive.eType, primitive.pMaterial, primitive.pVecVertices); m_pPrimitiveMaterialBatcher->AddPrimitive(primitive.eType, primitive.pMaterial, primitive.pVecVertices);
break; break;
} }
Expand Down
14 changes: 0 additions & 14 deletions Client/core/Graphics/CPrimitiveBatcher.cpp
Expand Up @@ -100,24 +100,10 @@ void CPrimitiveBatcher::UpdateMatrices(float fViewportSizeX, float fViewportSize
void CPrimitiveBatcher::SetDeviceStates() void CPrimitiveBatcher::SetDeviceStates()
{ {
// Set states // Set states
m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
m_pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_ALPHAREF, 0x01);
m_pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// //
Expand Down
14 changes: 0 additions & 14 deletions Client/core/Graphics/CPrimitiveMaterialBatcher.cpp
Expand Up @@ -100,26 +100,12 @@ void CPrimitiveMaterialBatcher::UpdateMatrices(float fViewportSizeX, float fView
void CPrimitiveMaterialBatcher::SetDeviceStates() void CPrimitiveMaterialBatcher::SetDeviceStates()
{ {
// Set states // Set states
m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
m_pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_ALPHAREF, 0x01);
m_pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// //
Expand Down
37 changes: 14 additions & 23 deletions Client/core/Graphics/CTileBatcher.cpp
Expand Up @@ -130,34 +130,21 @@ void CTileBatcher::Flush()
// TODO - Optimize all this // TODO - Optimize all this
// //


// Save render states
IDirect3DStateBlock9* pSavedStateBlock = nullptr;
m_pDevice->CreateStateBlock(D3DSBT_ALL, &pSavedStateBlock);

if (m_bUseCustomMatrices && m_bZBufferDirty) if (m_bUseCustomMatrices && m_bZBufferDirty)
{ {
// Shaders with transforms will probably need a clear zbuffer // Shaders with transforms will probably need a clear zbuffer
m_pDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0); m_pDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1, 0);
m_bZBufferDirty = false; m_bZBufferDirty = false;
} }


// Set states // Set states
if (g_pDeviceState->AdapterState.bRequiresClipping) if (g_pDeviceState->AdapterState.bRequiresClipping)
m_pDevice->SetRenderState(D3DRS_CLIPPING, TRUE); m_pDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
m_pDevice->SetRenderState(D3DRS_ZENABLE, m_bUseCustomMatrices ? D3DZB_TRUE : D3DZB_FALSE); m_pDevice->SetRenderState(D3DRS_ZENABLE, m_bUseCustomMatrices ? D3DZB_TRUE : D3DZB_FALSE);
m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_ALPHAREF, 0x01);
m_pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);


if (m_bUseCustomMatrices) if (m_bUseCustomMatrices)
{ {
Expand Down Expand Up @@ -243,22 +230,26 @@ void CTileBatcher::Flush()
// If we didn't get the effect to save the shader state, clear some things here // If we didn't get the effect to save the shader state, clear some things here
if (dwFlags & D3DXFX_DONOTSAVESHADERSTATE) if (dwFlags & D3DXFX_DONOTSAVESHADERSTATE)
{ {
m_pDevice->SetVertexShader(NULL); m_pDevice->SetVertexShader(nullptr);
m_pDevice->SetPixelShader(NULL); m_pDevice->SetPixelShader(nullptr);
} }
} }


// Clean up // Clean up
ListClearAndReserve(m_Indices); ListClearAndReserve(m_Indices);
ListClearAndReserve(m_Vertices); ListClearAndReserve(m_Vertices);


SetCurrentMaterial(NULL); SetCurrentMaterial(nullptr);
m_fCurrentRotation = 0; m_fCurrentRotation = 0;
m_fCurrentRotCenX = 0; m_fCurrentRotCenX = 0;
m_fCurrentRotCenY = 0; m_fCurrentRotCenY = 0;


if (g_pDeviceState->AdapterState.bRequiresClipping) // Restore render states
m_pDevice->SetRenderState(D3DRS_CLIPPING, FALSE); if (pSavedStateBlock)
{
pSavedStateBlock->Apply();
SAFE_RELEASE(pSavedStateBlock);
}
} }
} }


Expand Down

0 comments on commit d112011

Please sign in to comment.