From 15c5688a7d7090e8eb3851852a3fdb5fc77a800a Mon Sep 17 00:00:00 2001 From: Kamil Marciniak Date: Sat, 22 Sep 2018 23:20:41 +0200 Subject: [PATCH 1/2] Modifiec dx drawing code to use same queue as other dx functions --- Client/core/Graphics/CGraphics.cpp | 136 ++++++++++++------ Client/core/Graphics/CGraphics.h | 41 ++++-- Client/core/Graphics/CPrimitiveBatcher.cpp | 70 +++++---- Client/core/Graphics/CPrimitiveBatcher.h | 26 ++-- .../Graphics/CPrimitiveMaterialBatcher.cpp | 76 ++++++---- .../core/Graphics/CPrimitiveMaterialBatcher.h | 29 ++-- .../logic/luadefs/CLuaDrawingDefs.cpp | 121 ++++------------ Client/sdk/core/CGraphicsInterface.h | 14 +- 8 files changed, 272 insertions(+), 241 deletions(-) diff --git a/Client/core/Graphics/CGraphics.cpp b/Client/core/Graphics/CGraphics.cpp index 27b9d0dbb95..2a219ff3f12 100644 --- a/Client/core/Graphics/CGraphics.cpp +++ b/Client/core/Graphics/CGraphics.cpp @@ -58,10 +58,8 @@ CGraphics::CGraphics(CLocalGUI* pGUI) m_pLine3DBatcherPostGUI = new CLine3DBatcher(false); m_pMaterialLine3DBatcherPreGUI = new CMaterialLine3DBatcher(true); m_pMaterialLine3DBatcherPostGUI = new CMaterialLine3DBatcher(false); - m_pPrimitiveBatcherPreGUI = new CPrimitiveBatcher(true); - m_pPrimitiveBatcherPostGUI = new CPrimitiveBatcher(false); - m_pPrimitiveMaterialBatcherPreGUI = new CPrimitiveMaterialBatcher(true, this); - m_pPrimitiveMaterialBatcherPostGUI = new CPrimitiveMaterialBatcher(false, this); + m_pPrimitiveBatcher = new CPrimitiveBatcher(); + m_pPrimitiveMaterialBatcher = new CPrimitiveMaterialBatcher(this); m_pScreenGrabber = NewScreenGrabber(); m_pPixelsManager = NewPixelsManager(); @@ -84,10 +82,8 @@ CGraphics::~CGraphics(void) SAFE_DELETE(m_pLine3DBatcherPostGUI); SAFE_DELETE(m_pMaterialLine3DBatcherPreGUI); SAFE_DELETE(m_pMaterialLine3DBatcherPostGUI); - SAFE_DELETE(m_pPrimitiveBatcherPreGUI); - SAFE_DELETE(m_pPrimitiveBatcherPostGUI); - SAFE_DELETE(m_pPrimitiveMaterialBatcherPreGUI); - SAFE_DELETE(m_pPrimitiveMaterialBatcherPostGUI); + SAFE_DELETE(m_pPrimitiveBatcher); + SAFE_DELETE(m_pPrimitiveMaterialBatcher); SAFE_DELETE(m_pScreenGrabber); SAFE_DELETE(m_pPixelsManager); SAFE_DELETE(m_pAspectRatioConverter); @@ -508,6 +504,14 @@ void CGraphics::CheckModes(EDrawModeType newDrawMode, EBlendModeType newBlendMod { m_pTileBatcher->Flush(); } + else if (m_CurDrawMode == EDrawMode::PRIMITIVE) + { + m_pPrimitiveBatcher->Flush(); + } + else if (m_CurDrawMode == EDrawMode::PRIMITIVE_MATERIAL) + { + m_pPrimitiveMaterialBatcher->Flush(); + } // Start new if (newDrawMode == EDrawMode::DX_SPRITE) @@ -841,58 +845,92 @@ void CGraphics::DrawCircleQueued(float fX, float fY, float fRadius, float fStart AddQueueItem(Item, bPostGUI); } -void CGraphics::DrawPrimitiveQueued(const std::vector& vecVertices, D3DPRIMITIVETYPE eType, bool bPostGUI) +void CGraphics::DrawPrimitiveQueued(std::vector* pVecVertices, D3DPRIMITIVETYPE eType, bool bPostGUI) { // Prevent queuing when minimized if (g_pCore->IsWindowMinimized()) { - m_pPrimitiveBatcherPreGUI->ClearQueue(); - m_pPrimitiveBatcherPostGUI->ClearQueue(); + delete pVecVertices; + m_pPrimitiveBatcher->ClearQueue(); return; } - for (PrimitiveVertice vert : vecVertices) + for (auto& vert : *pVecVertices) { vert.fY = m_pAspectRatioConverter->ConvertPositionForAspectRatio(vert.fY); } - sDrawQueuePrimitive primitive; - primitive.vertices = vecVertices; - primitive.type = eType; - // Add it to the queue - if (bPostGUI && !CCore::GetSingleton().IsMenuVisible()) - m_pPrimitiveBatcherPostGUI->AddPrimitive(primitive); - else - m_pPrimitiveBatcherPreGUI->AddPrimitive(primitive); + // Set up a queue item + sDrawQueueItem Item; + Item.eType = QUEUE_PRIMITIVE; + Item.Primitive.eType = eType; + Item.Primitive.pVecVertices = pVecVertices; + AddQueueItem (Item, bPostGUI); } -void CGraphics::DrawMaterialPrimitiveQueued(const std::vector& vecVertices, D3DPRIMITIVETYPE eType, CMaterialItem* pMaterial, +void CGraphics::DrawMaterialPrimitiveQueued(std::vector* pVecVertices, D3DPRIMITIVETYPE eType, CMaterialItem* pMaterial, bool bPostGUI) { // Prevent queuing when minimized if (g_pCore->IsWindowMinimized()) { - m_pPrimitiveBatcherPreGUI->ClearQueue(); - m_pPrimitiveBatcherPostGUI->ClearQueue(); + delete pVecVertices; + m_pPrimitiveMaterialBatcher->ClearQueue(); return; } - for (PrimitiveMaterialVertice vert : vecVertices) + for (auto& vert : *pVecVertices) { vert.fY = m_pAspectRatioConverter->ConvertPositionForAspectRatio(vert.fY); } - sDrawQueuePrimitiveMaterial primitive; - primitive.vertices = vecVertices; - primitive.material = pMaterial; - primitive.type = eType; + // Set up a queue item + sDrawQueueItem Item; + Item.eType = QUEUE_PRIMITIVEMATERIAL; + Item.PrimitiveMaterial.eType = eType; + Item.PrimitiveMaterial.pMaterial = pMaterial; + Item.PrimitiveMaterial.pVecVertices = pVecVertices; + AddQueueItem(Item, bPostGUI); - AddQueueRef(primitive.material); - // Add it to the queue - if (bPostGUI && !CCore::GetSingleton().IsMenuVisible()) - m_pPrimitiveMaterialBatcherPostGUI->AddPrimitive(primitive); - else - m_pPrimitiveMaterialBatcherPreGUI->AddPrimitive(primitive); + AddQueueRef(pMaterial); +} + +bool CGraphics::IsValidPrimitiveSize (int iNumVertives, D3DPRIMITIVETYPE eType) +{ + if (iNumVertives < 1) + { + return false; + } + + switch (eType) + { + case D3DPT_LINESTRIP: + if (iNumVertives < 2) + { + return false; + } + break; + case D3DPT_LINELIST: + if (iNumVertives % 2 != 0) + { + return false; + } + break; + case D3DPT_TRIANGLELIST: + if (iNumVertives % 3 != 0) + { + return false; + } + case D3DPT_TRIANGLEFAN: + case D3DPT_TRIANGLESTRIP: + if (iNumVertives < 3) + { + return false; + } + break; + } + + return true; } struct stVertex @@ -1424,10 +1462,8 @@ void CGraphics::OnDeviceCreate(IDirect3DDevice9* pDevice) m_pLine3DBatcherPostGUI->OnDeviceCreate(pDevice, GetViewportWidth(), GetViewportHeight()); m_pMaterialLine3DBatcherPreGUI->OnDeviceCreate(pDevice, GetViewportWidth(), GetViewportHeight()); m_pMaterialLine3DBatcherPostGUI->OnDeviceCreate(pDevice, GetViewportWidth(), GetViewportHeight()); - m_pPrimitiveBatcherPreGUI->OnDeviceCreate(pDevice, GetViewportWidth(), GetViewportHeight()); - m_pPrimitiveBatcherPostGUI->OnDeviceCreate(pDevice, GetViewportWidth(), GetViewportHeight()); - m_pPrimitiveMaterialBatcherPreGUI->OnDeviceCreate(pDevice, GetViewportWidth(), GetViewportHeight()); - m_pPrimitiveMaterialBatcherPostGUI->OnDeviceCreate(pDevice, GetViewportWidth(), GetViewportHeight()); + m_pPrimitiveBatcher->OnDeviceCreate(pDevice, GetViewportWidth(), GetViewportHeight()); + m_pPrimitiveMaterialBatcher->OnDeviceCreate(pDevice, GetViewportWidth(), GetViewportHeight()); m_pRenderItemManager->OnDeviceCreate(pDevice, GetViewportWidth(), GetViewportHeight()); m_pScreenGrabber->OnDeviceCreate(pDevice); m_pPixelsManager->OnDeviceCreate(pDevice); @@ -1496,15 +1532,11 @@ void CGraphics::OnZBufferModified(void) void CGraphics::DrawPreGUIQueue(void) { DrawQueue(m_PreGUIQueue); - m_pPrimitiveBatcherPreGUI->Flush(); - m_pPrimitiveMaterialBatcherPreGUI->Flush(); } void CGraphics::DrawPostGUIQueue(void) { DrawQueue(m_PostGUIQueue); - m_pPrimitiveBatcherPostGUI->Flush(); - m_pPrimitiveMaterialBatcherPostGUI->Flush(); m_pLine3DBatcherPostGUI->Flush(); m_pMaterialLine3DBatcherPostGUI->Flush(); @@ -1683,6 +1715,20 @@ void CGraphics::DrawQueueItem(const sDrawQueueItem& Item) RemoveQueueRef(Item.Texture.pMaterial); break; } + case QUEUE_PRIMITIVE: + { + const sDrawQueuePrimitive primitive = Item.Primitive; + CheckModes (EDrawMode::PRIMITIVE); + m_pPrimitiveBatcher->AddPrimitive (primitive.eType, primitive.pVecVertices); + break; + } + case QUEUE_PRIMITIVEMATERIAL: + { + const sDrawQueuePrimitiveMaterial primitive = Item.PrimitiveMaterial; + CheckModes(EDrawMode::PRIMITIVE_MATERIAL); + m_pPrimitiveMaterialBatcher->AddPrimitive(primitive.eType, primitive.pMaterial, primitive.pVecVertices); + break; + } } } @@ -1758,10 +1804,8 @@ void CGraphics::OnChangingRenderTarget(uint uiNewViewportSizeX, uint uiNewViewpo DrawPreGUIQueue(); // Inform batchers m_pTileBatcher->OnChangingRenderTarget(uiNewViewportSizeX, uiNewViewportSizeY); - m_pPrimitiveBatcherPreGUI->OnChangingRenderTarget(uiNewViewportSizeX, uiNewViewportSizeY); - m_pPrimitiveBatcherPostGUI->OnChangingRenderTarget(uiNewViewportSizeX, uiNewViewportSizeY); - m_pPrimitiveMaterialBatcherPreGUI->OnChangingRenderTarget(uiNewViewportSizeX, uiNewViewportSizeY); - m_pPrimitiveMaterialBatcherPostGUI->OnChangingRenderTarget(uiNewViewportSizeX, uiNewViewportSizeY); + m_pPrimitiveBatcher->OnChangingRenderTarget(uiNewViewportSizeX, uiNewViewportSizeY); + m_pPrimitiveMaterialBatcher->OnChangingRenderTarget(uiNewViewportSizeX, uiNewViewportSizeY); } //////////////////////////////////////////////////////////////// diff --git a/Client/core/Graphics/CGraphics.h b/Client/core/Graphics/CGraphics.h index 2918b10d3a6..dc109e13311 100644 --- a/Client/core/Graphics/CGraphics.h +++ b/Client/core/Graphics/CGraphics.h @@ -40,6 +40,8 @@ namespace EDrawMode DX_LINE, DX_SPRITE, TILE_BATCHER, + PRIMITIVE, + PRIMITIVE_MATERIAL }; } using EDrawMode::EDrawModeType; @@ -145,11 +147,13 @@ class CGraphics : public CGraphicsInterface, public CSingleton unsigned long ulFormat, ID3DXFont* pDXFont = NULL, bool bPostGUI = false, bool bColorCoded = false, bool bSubPixelPositioning = false, float fRotation = 0, float fRotationCenterX = 0, float fRotationCenterY = 0); - void DrawPrimitiveQueued(const std::vector& vecVertices, D3DPRIMITIVETYPE type, bool bPostGUI = false); - void DrawMaterialPrimitiveQueued(const std::vector& vertices, D3DPRIMITIVETYPE type, CMaterialItem* pMaterial, bool bPostGUI); + void DrawPrimitiveQueued(std::vector* pVecVertices, D3DPRIMITIVETYPE eType, bool bPostGUI = false); + void DrawMaterialPrimitiveQueued(std::vector* vertices, D3DPRIMITIVETYPE type, CMaterialItem* pMaterial, bool bPostGUI); void DrawCircleQueued(float fX, float fY, float fRadius, float fStartAngle, float fStopAngle, unsigned long ulColor, unsigned long ulColorCenter, short siSegments, float fRatio, bool bPostGUI); + bool IsValidPrimitiveSize (int iNumVertives, D3DPRIMITIVETYPE eType); + void OnChangingRenderTarget(uint uiNewViewportSizeX, uint uiNewViewportSizeY); // Subsystems @@ -213,10 +217,8 @@ class CGraphics : public CGraphicsInterface, public CSingleton CLine3DBatcher* m_pLine3DBatcherPostGUI; CMaterialLine3DBatcher* m_pMaterialLine3DBatcherPreGUI; CMaterialLine3DBatcher* m_pMaterialLine3DBatcherPostGUI; - CPrimitiveBatcher* m_pPrimitiveBatcherPreGUI; - CPrimitiveBatcher* m_pPrimitiveBatcherPostGUI; - CPrimitiveMaterialBatcher* m_pPrimitiveMaterialBatcherPreGUI; - CPrimitiveMaterialBatcher* m_pPrimitiveMaterialBatcherPostGUI; + CPrimitiveBatcher* m_pPrimitiveBatcher; + CPrimitiveMaterialBatcher* m_pPrimitiveMaterialBatcher; CAspectRatioConverter* m_pAspectRatioConverter; // Fonts @@ -237,6 +239,8 @@ class CGraphics : public CGraphicsInterface, public CSingleton QUEUE_TEXTURE, QUEUE_SHADER, QUEUE_CIRCLE, + QUEUE_PRIMITIVE, + QUEUE_PRIMITIVEMATERIAL, }; struct sDrawQueueLine @@ -307,6 +311,19 @@ class CGraphics : public CGraphicsInterface, public CSingleton bool bRelativeUV; }; + struct sDrawQueuePrimitive + { + D3DPRIMITIVETYPE eType; + std::vector* pVecVertices; + }; + + struct sDrawQueuePrimitiveMaterial + { + D3DPRIMITIVETYPE eType; + CMaterialItem* pMaterial; + std::vector* pVecVertices; + }; + struct sDrawQueueItem { eDrawQueueType eType; @@ -315,11 +332,13 @@ class CGraphics : public CGraphicsInterface, public CSingleton // Queue item data based on the eType. union { - sDrawQueueLine Line; - sDrawQueueText Text; - sDrawQueueRect Rect; - sDrawQueueTexture Texture; - sDrawQueueCircle Circle; + sDrawQueueLine Line; + sDrawQueueText Text; + sDrawQueueRect Rect; + sDrawQueueTexture Texture; + sDrawQueueCircle Circle; + sDrawQueuePrimitive Primitive; + sDrawQueuePrimitiveMaterial PrimitiveMaterial; }; }; diff --git a/Client/core/Graphics/CPrimitiveBatcher.cpp b/Client/core/Graphics/CPrimitiveBatcher.cpp index 9240c73c83e..ac474de1c89 100644 --- a/Client/core/Graphics/CPrimitiveBatcher.cpp +++ b/Client/core/Graphics/CPrimitiveBatcher.cpp @@ -17,9 +17,9 @@ // // //////////////////////////////////////////////////////////////// -CPrimitiveBatcher::CPrimitiveBatcher(bool m_bZTest) +CPrimitiveBatcher::CPrimitiveBatcher() { - m_bZTest = m_bZTest; + D3DXMatrixIdentity(&m_MatWorld); } //////////////////////////////////////////////////////////////// // @@ -92,31 +92,15 @@ void CPrimitiveBatcher::UpdateMatrices(float fViewportSizeX, float fViewportSize } //////////////////////////////////////////////////////////////// // -// CPrimitiveBatcher::Flush +// CPrimitiveBatcher::SetDeviceStates +// // -// Send all buffered vertices to D3D // //////////////////////////////////////////////////////////////// -void CPrimitiveBatcher::Flush(void) +void CPrimitiveBatcher::SetDeviceStates() { - if (m_primitiveList.empty()) - return; - - // Save render states - IDirect3DStateBlock9* pSavedStateBlock = nullptr; - m_pDevice->CreateStateBlock(D3DSBT_ALL, &pSavedStateBlock); - // Set transformations - D3DXMATRIX matWorld; - D3DXMatrixIdentity(&matWorld); - m_pDevice->SetTransform(D3DTS_WORLD, &matWorld); - m_pDevice->SetTransform(D3DTS_VIEW, &m_MatView); - m_pDevice->SetTransform(D3DTS_PROJECTION, &m_MatProjection); - - // Set vertex FVF - m_pDevice->SetFVF(PrimitiveVertice::FNV); - // Set states - m_pDevice->SetRenderState(D3DRS_ZENABLE, m_bZTest ? D3DZB_TRUE : D3DZB_FALSE); + 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); @@ -134,17 +118,42 @@ void CPrimitiveBatcher::Flush(void) m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); m_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); +} +//////////////////////////////////////////////////////////////// +// +// CPrimitiveBatcher::Flush +// +// Send all buffered vertices to D3D +// +//////////////////////////////////////////////////////////////// +void CPrimitiveBatcher::Flush(void) +{ + if (m_primitiveList.empty()) + return; + + // Save render states + IDirect3DStateBlock9* pSavedStateBlock = nullptr; + m_pDevice->CreateStateBlock(D3DSBT_ALL, &pSavedStateBlock); + + // Set transformations + m_pDevice->SetTransform(D3DTS_WORLD, &m_MatWorld); + m_pDevice->SetTransform(D3DTS_VIEW, &m_MatView); + m_pDevice->SetTransform(D3DTS_PROJECTION, &m_MatProjection); + + // Set vertex FVF + m_pDevice->SetFVF(PrimitiveVertice::FNV); + + // Set device states + SetDeviceStates(); // Draw m_pDevice->SetTexture(0, nullptr); - for (int i = 0; i < m_primitiveList.size(); i++) + for (auto& primitive : m_primitiveList) { - sDrawQueuePrimitive primitive = m_primitiveList[i]; - - const void* pVertexStreamZeroData = &primitive.vertices[0]; + const void* pVertexStreamZeroData = &primitive.pVecVertices->at(0); uint uiVertexStreamZeroStride = sizeof(PrimitiveVertice); - DrawPrimitive(primitive.type, primitive.vertices.size(), pVertexStreamZeroData, uiVertexStreamZeroStride); + DrawPrimitive(primitive.eType, primitive.pVecVertices->size(), pVertexStreamZeroData, uiVertexStreamZeroStride); } // Clean up @@ -197,6 +206,9 @@ void CPrimitiveBatcher::DrawPrimitive(D3DPRIMITIVETYPE eType, size_t iCollection void CPrimitiveBatcher::ClearQueue() { // Clean up + for(auto& primitive : m_primitiveList){ + delete primitive.pVecVertices; + } size_t prevSize = m_primitiveList.size(); m_primitiveList.clear(); m_primitiveList.reserve(prevSize); @@ -208,7 +220,7 @@ void CPrimitiveBatcher::ClearQueue() // Add a new primitive to the list // //////////////////////////////////////////////////////////////// -void CPrimitiveBatcher::AddPrimitive(sDrawQueuePrimitive primitive) +void CPrimitiveBatcher::AddPrimitive(D3DPRIMITIVETYPE eType, std::vector* pVecVertices) { - m_primitiveList.push_back(primitive); + m_primitiveList.push_back({eType, pVecVertices}); } diff --git a/Client/core/Graphics/CPrimitiveBatcher.h b/Client/core/Graphics/CPrimitiveBatcher.h index da471f1aa02..de559aa515c 100644 --- a/Client/core/Graphics/CPrimitiveBatcher.h +++ b/Client/core/Graphics/CPrimitiveBatcher.h @@ -8,11 +8,12 @@ * *****************************************************************************/ // Vertex type used by the primitives batcher -struct sDrawQueuePrimitive +struct sPrimitive { - D3DPRIMITIVETYPE type; - std::vector vertices; + D3DPRIMITIVETYPE eType; + std::vector* pVecVertices; }; + // // Batches primitives drawing // @@ -20,22 +21,23 @@ class CPrimitiveBatcher { public: ZERO_ON_NEW - CPrimitiveBatcher(bool m_bZTest); + CPrimitiveBatcher(); ~CPrimitiveBatcher(void); void OnDeviceCreate(IDirect3DDevice9* pDevice, float fViewportSizeX, float fViewportSizeY); void OnChangingRenderTarget(uint uiNewViewportSizeX, uint uiNewViewportSizeY); void UpdateMatrices(float fViewportSizeX, float fViewportSizeY); + void SetDeviceStates(); void Flush(void); void DrawPrimitive(D3DPRIMITIVETYPE eType, size_t iSize, const void* pDataAddr, size_t iVertexStride); void ClearQueue(void); - void AddPrimitive(sDrawQueuePrimitive primitive); + void AddPrimitive(D3DPRIMITIVETYPE eType, std::vector* pVecVertices); protected: - bool m_bZTest; - IDirect3DDevice9* m_pDevice; - std::vector m_primitiveList; - float m_fViewportSizeX; - float m_fViewportSizeY; - D3DXMATRIX m_MatView; - D3DXMATRIX m_MatProjection; + IDirect3DDevice9* m_pDevice; + std::vector m_primitiveList; + float m_fViewportSizeX; + float m_fViewportSizeY; + D3DXMATRIX m_MatWorld; + D3DXMATRIX m_MatView; + D3DXMATRIX m_MatProjection; }; diff --git a/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp b/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp index 6fc7c9a95c9..5024660c955 100644 --- a/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp +++ b/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp @@ -17,9 +17,8 @@ // // //////////////////////////////////////////////////////////////// -CPrimitiveMaterialBatcher::CPrimitiveMaterialBatcher(bool m_bZTest, CGraphics* graphics) +CPrimitiveMaterialBatcher::CPrimitiveMaterialBatcher(CGraphics* graphics) { - m_bZTest = m_bZTest; m_pGraphics = graphics; } //////////////////////////////////////////////////////////////// @@ -93,31 +92,15 @@ void CPrimitiveMaterialBatcher::UpdateMatrices(float fViewportSizeX, float fView } //////////////////////////////////////////////////////////////// // -// CPrimitiveMaterialBatcher::Flush +// CPrimitiveMaterialBatcher::SetDeviceStates +// // -// Send all buffered vertices to D3D // //////////////////////////////////////////////////////////////// -void CPrimitiveMaterialBatcher::Flush(void) +void CPrimitiveMaterialBatcher::SetDeviceStates() { - if (m_primitiveList.empty()) - return; - - // Save render states - IDirect3DStateBlock9* pSavedStateBlock = nullptr; - m_pDevice->CreateStateBlock(D3DSBT_ALL, &pSavedStateBlock); - // Set transformations - D3DXMATRIX matWorld; - D3DXMatrixIdentity(&matWorld); - m_pDevice->SetTransform(D3DTS_WORLD, &matWorld); - m_pDevice->SetTransform(D3DTS_VIEW, &m_MatView); - m_pDevice->SetTransform(D3DTS_PROJECTION, &m_MatProjection); - - // Set vertex FVF - m_pDevice->SetFVF(PrimitiveMaterialVertice::FNV); - // Set states - m_pDevice->SetRenderState(D3DRS_ZENABLE, m_bZTest ? D3DZB_TRUE : D3DZB_FALSE); + m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); m_pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); @@ -137,20 +120,46 @@ void CPrimitiveMaterialBatcher::Flush(void) m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); m_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); +} +//////////////////////////////////////////////////////////////// +// +// CPrimitiveMaterialBatcher::Flush +// +// Send all buffered vertices to D3D +// +//////////////////////////////////////////////////////////////// +void CPrimitiveMaterialBatcher::Flush(void) +{ + if (m_primitiveList.empty()) + return; + + // Save render states + IDirect3DStateBlock9* pSavedStateBlock = nullptr; + m_pDevice->CreateStateBlock(D3DSBT_ALL, &pSavedStateBlock); + // Set transformations + D3DXMATRIX matWorld; + D3DXMatrixIdentity(&matWorld); + m_pDevice->SetTransform(D3DTS_WORLD, &matWorld); + m_pDevice->SetTransform(D3DTS_VIEW, &m_MatView); + m_pDevice->SetTransform(D3DTS_PROJECTION, &m_MatProjection); + + // Set vertex FVF + m_pDevice->SetFVF(PrimitiveMaterialVertice::FNV); + + // Set device states + SetDeviceStates(); // Draw m_pDevice->SetTexture(0, nullptr); // Cache last used material, so we don't set directx parameters needlessly CMaterialItem* pLastMaterial = nullptr; - for (uint i = 0; i < m_primitiveList.size(); i++) + for (auto& primitive : m_primitiveList) { - sDrawQueuePrimitiveMaterial primitive = m_primitiveList[i]; - // uint PrimitiveCount = m_triangleList.size () / 3; - const void* pVertexStreamZeroData = &primitive.vertices[0]; + const void* pVertexStreamZeroData = &primitive.pVecVertices->at(0); uint uiVertexStreamZeroStride = sizeof(PrimitiveMaterialVertice); - CMaterialItem* pMaterial = primitive.material; + CMaterialItem* pMaterial = primitive.pMaterial; if (pMaterial != pLastMaterial) { // Set texture addressing mode @@ -169,7 +178,7 @@ void CPrimitiveMaterialBatcher::Flush(void) m_pDevice->SetTexture(0, pTextureItem->m_pD3DTexture); } - DrawPrimitive(primitive.type, primitive.vertices.size(), pVertexStreamZeroData, uiVertexStreamZeroStride); + DrawPrimitive(primitive.eType, primitive.pVecVertices->size(), pVertexStreamZeroData, uiVertexStreamZeroStride); } else if (CShaderInstance* pShaderInstance = DynamicCast(pMaterial)) { @@ -194,7 +203,7 @@ void CPrimitiveMaterialBatcher::Flush(void) for (uint uiPass = 0; uiPass < uiNumPasses; uiPass++) { pD3DEffect->BeginPass(uiPass); - DrawPrimitive(primitive.type, primitive.vertices.size(), pVertexStreamZeroData, uiVertexStreamZeroStride); + DrawPrimitive(primitive.eType, primitive.pVecVertices->size(), pVertexStreamZeroData, uiVertexStreamZeroStride); pD3DEffect->EndPass(); } pShaderInstance->m_pEffectWrap->End(); @@ -260,6 +269,11 @@ void CPrimitiveMaterialBatcher::DrawPrimitive(D3DPRIMITIVETYPE eType, size_t iCo void CPrimitiveMaterialBatcher::ClearQueue() { // Clean up + for (auto& primitive : m_primitiveList) + { + delete primitive.pVecVertices; + } + size_t prevSize = m_primitiveList.size(); m_primitiveList.clear(); m_primitiveList.reserve(prevSize); @@ -271,7 +285,7 @@ void CPrimitiveMaterialBatcher::ClearQueue() // Add a new primitive to the list // //////////////////////////////////////////////////////////////// -void CPrimitiveMaterialBatcher::AddPrimitive(sDrawQueuePrimitiveMaterial primitive) +void CPrimitiveMaterialBatcher::AddPrimitive(D3DPRIMITIVETYPE eType, CMaterialItem* pMaterial, std::vector* pVecVertices) { - m_primitiveList.push_back(primitive); + m_primitiveList.push_back({eType, pMaterial, pVecVertices}); } diff --git a/Client/core/Graphics/CPrimitiveMaterialBatcher.h b/Client/core/Graphics/CPrimitiveMaterialBatcher.h index 3a50f48aa04..db5cf659977 100644 --- a/Client/core/Graphics/CPrimitiveMaterialBatcher.h +++ b/Client/core/Graphics/CPrimitiveMaterialBatcher.h @@ -8,11 +8,11 @@ * *****************************************************************************/ // Vertex type used by the primitives batcher -struct sDrawQueuePrimitiveMaterial +struct sPrimitiveMaterial { - D3DPRIMITIVETYPE type; - CMaterialItem* material; - std::vector vertices; + D3DPRIMITIVETYPE eType; + CMaterialItem* pMaterial; + std::vector* pVecVertices; }; // // Batches primitives drawing @@ -23,23 +23,24 @@ class CPrimitiveMaterialBatcher public: ZERO_ON_NEW - CPrimitiveMaterialBatcher(bool m_bZTest, CGraphics* graphics); + CPrimitiveMaterialBatcher(CGraphics* graphics); ~CPrimitiveMaterialBatcher(void); void OnDeviceCreate(IDirect3DDevice9* pDevice, float fViewportSizeX, float fViewportSizeY); void OnChangingRenderTarget(uint uiNewViewportSizeX, uint uiNewViewportSizeY); void UpdateMatrices(float fViewportSizeX, float fViewportSizeY); + void SetDeviceStates(); void Flush(void); void DrawPrimitive(D3DPRIMITIVETYPE eType, size_t iSize, const void* pDataAddr, size_t iVertexStride); void ClearQueue(void); - void AddPrimitive(sDrawQueuePrimitiveMaterial primitive); + void AddPrimitive(D3DPRIMITIVETYPE eType, CMaterialItem* pMaterial, std::vector* pVecVertices); protected: - bool m_bZTest; - IDirect3DDevice9* m_pDevice; - CGraphics* m_pGraphics; - std::vector m_primitiveList; - float m_fViewportSizeX; - float m_fViewportSizeY; - D3DXMATRIX m_MatView; - D3DXMATRIX m_MatProjection; + IDirect3DDevice9* m_pDevice; + CGraphics* m_pGraphics; + std::vector m_primitiveList; + float m_fViewportSizeX; + float m_fViewportSizeY; + D3DXMATRIX m_MatWorld; + D3DXMATRIX m_MatView; + D3DXMATRIX m_MatProjection; }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp index f625ac71c3e..af776d6f3fc 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp @@ -565,12 +565,12 @@ int CLuaDrawingDefs::DxDrawImageSection(lua_State* luaVM) int CLuaDrawingDefs::DxDrawPrimitive(lua_State* luaVM) { // bool dxDrawPrimitive (string primitiveType, bool postGUI, table vertice1, ...) - D3DPRIMITIVETYPE primitiveType; - std::vector vecVertices; - bool bPostGUI; + D3DPRIMITIVETYPE ePrimitiveType; + auto pVecVertices = new std::vector(); + bool bPostGUI; CScriptArgReader argStream(luaVM); - argStream.ReadEnumString(primitiveType); + argStream.ReadEnumString(ePrimitiveType); argStream.ReadBool(bPostGUI); while (argStream.NextIsTable()) @@ -579,58 +579,23 @@ int CLuaDrawingDefs::DxDrawPrimitive(lua_State* luaVM) argStream.ReadNumberTable(vecTableContent); switch (vecTableContent.size()) { - case 2: - vecVertices.push_back(PrimitiveVertice{vecTableContent[0], vecTableContent[1], 0, (DWORD)0xFFFFFFFF}); + case PrimitiveVerticeSizes::VERT_XY: + pVecVertices->push_back(PrimitiveVertice{vecTableContent[0], vecTableContent[1], 0, (DWORD)0xFFFFFFFF}); break; - case 3: - vecVertices.push_back(PrimitiveVertice{vecTableContent[0], vecTableContent[1], 0, static_cast(vecTableContent[2])}); + case PrimitiveVerticeSizes::VERT_XY_COLOR: + pVecVertices->push_back(PrimitiveVertice{vecTableContent[0], vecTableContent[1], 0, static_cast(vecTableContent[2])}); break; } } if (!argStream.HasErrors()) { - if (vecVertices.size() < 1) + if (g_pCore->GetGraphics()->IsValidPrimitiveSize(pVecVertices->size(), ePrimitiveType)) { - lua_pushboolean(luaVM, false); + g_pCore->GetGraphics()->DrawPrimitiveQueued(pVecVertices, ePrimitiveType, bPostGUI); + lua_pushboolean(luaVM, true); return 1; - } - - switch (primitiveType) - { - case D3DPT_LINESTRIP: - if (vecVertices.size() < 2) - { - lua_pushboolean(luaVM, false); - return 1; - } - break; - case D3DPT_LINELIST: - if (vecVertices.size() % 2 != 0) - { - lua_pushboolean(luaVM, false); - return 1; - } - break; - case D3DPT_TRIANGLELIST: - if (vecVertices.size() % 3 != 0) - { - lua_pushboolean(luaVM, false); - return 1; - } - case D3DPT_TRIANGLEFAN: - case D3DPT_TRIANGLESTRIP: - if (vecVertices.size() < 3) - { - lua_pushboolean(luaVM, false); - return 1; - } - break; - } - - g_pCore->GetGraphics()->DrawPrimitiveQueued(vecVertices, primitiveType, bPostGUI); - lua_pushboolean(luaVM, true); - return 1; + } } else { @@ -638,6 +603,7 @@ int CLuaDrawingDefs::DxDrawPrimitive(lua_State* luaVM) } // Failed + delete pVecVertices; lua_pushboolean(luaVM, false); return 1; } @@ -645,13 +611,13 @@ int CLuaDrawingDefs::DxDrawPrimitive(lua_State* luaVM) int CLuaDrawingDefs::DxDrawMaterialPrimitive(lua_State* luaVM) { // bool dxDrawPrimitive (string primitiveType, dxMaterial material, bool postGUI, table vertice1, ...) - D3DPRIMITIVETYPE primitiveType; - std::vector vecVertices; - CClientMaterial* pMaterialElement; - bool bPostGUI; + D3DPRIMITIVETYPE ePrimitiveType; + auto pVecVertices = new std::vector(); + CClientMaterial* pMaterialElement; + bool bPostGUI; CScriptArgReader argStream(luaVM); - argStream.ReadEnumString(primitiveType); + argStream.ReadEnumString(ePrimitiveType); MixedReadMaterialString(argStream, pMaterialElement); argStream.ReadBool(bPostGUI); @@ -661,12 +627,12 @@ int CLuaDrawingDefs::DxDrawMaterialPrimitive(lua_State* luaVM) argStream.ReadNumberTable(vecTableContent); switch (vecTableContent.size()) { - case 4: - vecVertices.push_back( + case PrimitiveVerticeSizes::VERT_XY_UV: + pVecVertices->push_back( PrimitiveMaterialVertice{vecTableContent[0], vecTableContent[1], 0, (DWORD)0xFFFFFFFF, vecTableContent[2], vecTableContent[3]}); break; - case 5: - vecVertices.push_back(PrimitiveMaterialVertice{vecTableContent[0], vecTableContent[1], 0, static_cast(vecTableContent[2]), + case PrimitiveVerticeSizes::VERT_XY_COLOR_UV: + pVecVertices->push_back(PrimitiveMaterialVertice{vecTableContent[0], vecTableContent[1], 0, static_cast(vecTableContent[2]), vecTableContent[3], vecTableContent[4]}); break; } @@ -674,47 +640,9 @@ int CLuaDrawingDefs::DxDrawMaterialPrimitive(lua_State* luaVM) if (!argStream.HasErrors()) { - if (pMaterialElement) + if (pMaterialElement && g_pCore->GetGraphics()->IsValidPrimitiveSize(pVecVertices->size(), ePrimitiveType)) { - if (vecVertices.size() < 1) - { - lua_pushboolean(luaVM, false); - return 1; - } - - switch (primitiveType) - { - case D3DPT_LINESTRIP: - if (vecVertices.size() < 2) - { - lua_pushboolean(luaVM, false); - return 1; - } - break; - case D3DPT_LINELIST: - if (vecVertices.size() % 2 != 0) - { - lua_pushboolean(luaVM, false); - return 1; - } - break; - case D3DPT_TRIANGLELIST: - if (vecVertices.size() % 3 != 0) - { - lua_pushboolean(luaVM, false); - return 1; - } - case D3DPT_TRIANGLEFAN: - case D3DPT_TRIANGLESTRIP: - if (vecVertices.size() < 3) - { - lua_pushboolean(luaVM, false); - return 1; - } - break; - } - - g_pCore->GetGraphics()->DrawMaterialPrimitiveQueued(vecVertices, primitiveType, pMaterialElement->GetMaterialItem(), bPostGUI); + g_pCore->GetGraphics()->DrawMaterialPrimitiveQueued(pVecVertices, ePrimitiveType, pMaterialElement->GetMaterialItem(), bPostGUI); lua_pushboolean(luaVM, true); return 1; } @@ -725,6 +653,7 @@ int CLuaDrawingDefs::DxDrawMaterialPrimitive(lua_State* luaVM) } // Failed + delete pVecVertices; lua_pushboolean(luaVM, false); return 1; } diff --git a/Client/sdk/core/CGraphicsInterface.h b/Client/sdk/core/CGraphicsInterface.h index b82e345621c..687b33c7423 100644 --- a/Client/sdk/core/CGraphicsInterface.h +++ b/Client/sdk/core/CGraphicsInterface.h @@ -29,6 +29,14 @@ struct PrimitiveMaterialVertice float u, v; }; +enum PrimitiveVerticeSizes +{ + VERT_XY = 2, + VERT_XY_COLOR = 3, + VERT_XY_UV = 4, + VERT_XY_COLOR_UV = 5 +}; + struct ID3DXFont; struct IDirect3DDevice9; struct IDirect3DTexture9; @@ -142,12 +150,14 @@ class CGraphicsInterface float fScaleY, unsigned long ulFormat, ID3DXFont* pDXFont, bool bPostGUI, bool bColorCoded = false, bool bSubPixelPositioning = false, float fRotation = 0, float fRotationCenterX = 0, float fRotationCenterY = 0) = 0; - virtual void DrawPrimitiveQueued(const std::vector& vertices, D3DPRIMITIVETYPE type, bool bPostGUI) = 0; - virtual void DrawMaterialPrimitiveQueued(const std::vector& vertices, D3DPRIMITIVETYPE type, CMaterialItem* pMaterial, + virtual void DrawPrimitiveQueued(std::vector* pVecVertices, D3DPRIMITIVETYPE eType, bool bPostGUI) = 0; + virtual void DrawMaterialPrimitiveQueued(std::vector* pVecVertices, D3DPRIMITIVETYPE eType, CMaterialItem* pMaterial, bool bPostGUI) = 0; virtual void DrawCircleQueued(float fX, float fY, float fRadius, float fStartAngle, float fStopAngle, unsigned long ulColor, unsigned long ulColorCenter, short siSegments, float fRatio, bool bPostGUI) = 0; + virtual bool IsValidPrimitiveSize (int iNumVertives, D3DPRIMITIVETYPE eType) = 0; + // Subsystems virtual CRenderItemManagerInterface* GetRenderItemManager(void) = 0; virtual CScreenGrabberInterface* GetScreenGrabber(void) = 0; From 2eeb229d74d27f2724f6d6bd60b06efffb5e5ea3 Mon Sep 17 00:00:00 2001 From: Kamil Marciniak Date: Wed, 26 Sep 2018 19:00:16 +0200 Subject: [PATCH 2/2] Disable depth buffering for material primitives drawing --- Client/core/Graphics/CPrimitiveMaterialBatcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp b/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp index 5024660c955..ba935e8a717 100644 --- a/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp +++ b/Client/core/Graphics/CPrimitiveMaterialBatcher.cpp @@ -100,7 +100,7 @@ void CPrimitiveMaterialBatcher::UpdateMatrices(float fViewportSizeX, float fView void CPrimitiveMaterialBatcher::SetDeviceStates() { // Set states - m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); + 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);