diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp index 1f913d2af82..f040941a6a5 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp @@ -1880,7 +1880,10 @@ void W3DView::draw() /// @todo we might want to consider wiping this iterate out if there is nothing to post draw // TheGameClient->resetRenderedObjectCount(); + + TheDisplay->beginBatch(); TheGameClient->iterateDrawablesInRegion( &axisAlignedRegion, drawablePostDraw, this ); + TheDisplay->endBatch(); TheGameClient->flushTextBearingDrawables(); diff --git a/Generals/Code/GameEngine/Include/GameClient/Display.h b/Generals/Code/GameEngine/Include/GameClient/Display.h index dab09f09c1a..37cdad97b0e 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Display.h +++ b/Generals/Code/GameEngine/Include/GameClient/Display.h @@ -113,6 +113,11 @@ class Display : public SubsystemInterface virtual Bool isClippingEnabled() = 0; virtual void enableClipping( Bool onoff ) = 0; + virtual void beginBatch(); + virtual void endBatch(); + virtual void flush(); + virtual Bool isBatching() { return m_isBatching; } + virtual void step() {}; ///< Do one fixed time step virtual void draw() override; ///< Redraw the entire display virtual void setTimeOfDay( TimeOfDay tod ) = 0; ///< Set the time of day for this display @@ -182,11 +187,15 @@ class Display : public SubsystemInterface virtual Int getLastFrameDrawCalls() = 0; ///< returns the number of draw calls issued in the previous frame protected: + virtual void onBeginBatch() { } + virtual void onEndBatch() { } + virtual void onFlush() { } virtual void deleteViews(); ///< delete all views UnsignedInt m_width, m_height; ///< Dimensions of the display UnsignedInt m_bitDepth; ///< bit depth of the display Bool m_windowed; ///< TRUE when windowed, FALSE when fullscreen + Bool m_isBatching; View *m_viewList; ///< All of the views into the world // Cinematic text data diff --git a/Generals/Code/GameEngine/Source/GameClient/Display.cpp b/Generals/Code/GameEngine/Source/GameClient/Display.cpp index 770900814e1..c75fcaa0399 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Display.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Display.cpp @@ -66,6 +66,7 @@ Display::Display() m_currentlyPlayingMovie.clear(); m_letterBoxFadeStartTime = 0; + m_isBatching = FALSE; } /** @@ -387,3 +388,31 @@ Display::DebugDisplayCallback *Display::getDebugDisplayCallback() { return m_debugDisplayCallback; } + +void Display::beginBatch() +{ + if (m_isBatching) + { + return; + } + m_isBatching = TRUE; + onBeginBatch(); +} + +void Display::endBatch() +{ + if (!m_isBatching) + { + return; + } + m_isBatching = FALSE; + onEndBatch(); +} + +void Display::flush() +{ + if (m_isBatching) + { + onFlush(); + } +} diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h index 5f079d4324d..937e2d756ba 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h @@ -45,6 +45,7 @@ class Render2DClass; class RTS3DScene; class RTS2DScene; class RTS3DInterfaceScene; +class TextureClass; //============================================================================= @@ -160,6 +161,10 @@ class W3DDisplay : public Display void calculateTerrainLOD(); ///< Calculate terrain LOD. void renderLetterBox(UnsignedInt time); ///< draw letter box border void updateAverageFPS(); ///< calculate the average fps over the last 30 frames. + void setup2DRenderState(TextureClass *tex, DrawImageMode mode, Bool grayscale); + virtual void onBeginBatch() override; + virtual void onEndBatch() override; + virtual void onFlush() override; Byte m_initialized; ///< TRUE when system is initialized LightClass *m_myLight[LightEnvironmentClass::MAX_LIGHTS]; ///< light hack for now @@ -168,6 +173,12 @@ class W3DDisplay : public Display Bool m_isClippedEnabled; ///Reset(); + } +} + +void W3DDisplay::onEndBatch() +{ + onFlush(); + if (m_batchTexture) + { + m_batchTexture->Release_Ref(); + m_batchTexture = nullptr; + } +} + +void W3DDisplay::onFlush() +{ + if (m_2DRender && !m_batchNeedsInit) + { + m_2DRender->Render(); + m_2DRender->Reset(); + m_batchNeedsInit = TRUE; + } +} + +void W3DDisplay::setup2DRenderState(TextureClass *tex, DrawImageMode mode, Bool grayscale) +{ + if (m_isBatching) + { + if (!m_batchNeedsInit && m_batchTexture == tex && m_batchMode == mode && m_batchGrayscale == grayscale) + { + return; + } + + onFlush(); + + if (tex != m_batchTexture) + { + if (tex) + { + tex->Add_Ref(); + } + if (m_batchTexture) + { + m_batchTexture->Release_Ref(); + } + + m_batchTexture = tex; + } + + m_batchMode = mode; + m_batchGrayscale = grayscale; + m_batchNeedsInit = FALSE; + } + else if (m_2DRender) + { + m_2DRender->Reset(); + } + + if (m_2DRender) + { + if (tex) + { + m_2DRender->Enable_Texturing(TRUE); + m_2DRender->Set_Texture(tex); + } + else + { + m_2DRender->Enable_Texturing(FALSE); + } + + switch (mode) + { + case DRAW_IMAGE_ALPHA: + m_2DRender->Enable_Additive(FALSE); + m_2DRender->Enable_Alpha(TRUE); + m_2DRender->Enable_Grayscale(grayscale); + break; + case DRAW_IMAGE_GRAYSCALE: + m_2DRender->Enable_Additive(FALSE); + m_2DRender->Enable_Alpha(TRUE); + m_2DRender->Enable_Grayscale(TRUE); + break; + case DRAW_IMAGE_ADDITIVE: + m_2DRender->Enable_Additive(TRUE); + m_2DRender->Enable_Alpha(FALSE); + m_2DRender->Enable_Grayscale(grayscale); + break; + case DRAW_IMAGE_SOLID: + m_2DRender->Enable_Additive(FALSE); + m_2DRender->Enable_Alpha(FALSE); + m_2DRender->Enable_Grayscale(grayscale); + break; + } + } +} + // W3DDisplay::initAssets ===================================================== /** */ //============================================================================= @@ -2039,13 +2148,14 @@ void W3DDisplay::drawLine( Int startX, Int startY, Real lineWidth, UnsignedInt lineColor ) { + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - /// @todo we need to consider the efficiency of the 2D renderer - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); m_2DRender->Add_Line( Vector2( startX, startY ), Vector2( endX, endY ), lineWidth, lineColor ); - m_2DRender->Render(); + if (!m_isBatching) + { + m_2DRender->Render(); + } } @@ -2057,13 +2167,15 @@ void W3DDisplay::drawLine( Int startX, Int startY, Real lineWidth, UnsignedInt lineColor1,UnsignedInt lineColor2 ) { + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - /// @todo we need to consider the efficiency of the 2D renderer - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); m_2DRender->Add_Line( Vector2( startX, startY ), Vector2( endX, endY ), lineWidth, lineColor1, lineColor2 ); - m_2DRender->Render(); + + if (!m_isBatching) + { + m_2DRender->Render(); + } } @@ -2106,16 +2218,17 @@ void W3DDisplay::drawOpenRect( Int startX, Int startY, Int width, Int height, } else { - /// @todo we need to consider the efficiency of the 2D renderer - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); m_2DRender->Add_Outline( RectClass( startX, startY, startX + width, startY + height ), lineWidth, lineColor ); // render it now! - m_2DRender->Render(); + if (!m_isBatching) + { + m_2DRender->Render(); + } } } @@ -2125,17 +2238,17 @@ void W3DDisplay::drawOpenRect( Int startX, Int startY, Int width, Int height, void W3DDisplay::drawFillRect( Int startX, Int startY, Int width, Int height, UnsignedInt color ) { + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - /// @todo we need to consider the efficiency of the 2D renderer - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); m_2DRender->Add_Rect( RectClass( startX, startY, startX + width, startY + height ), 0, 0, color ); // render it now! - m_2DRender->Render(); - + if (!m_isBatching) + { + m_2DRender->Render(); + } } void W3DDisplay::drawRectClock(Int startX, Int startY, Int width, Int height, Int percent, UnsignedInt color) @@ -2144,8 +2257,7 @@ void W3DDisplay::drawRectClock(Int startX, Int startY, Int width, Int height, In if(percent < 1 || percent > 100) return; - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); // The rectanges are numberd as follows //(x,y) |---------| @@ -2291,8 +2403,10 @@ void W3DDisplay::drawRectClock(Int startX, Int startY, Int width, Int height, In } // render it now! - m_2DRender->Render(); - + if (!m_isBatching) + { + m_2DRender->Render(); + } } @@ -2308,8 +2422,7 @@ void W3DDisplay::drawRemainingRectClock(Int startX, Int startY, Int width, Int h if( percent < 0 || percent > 99 ) return; - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); // The rectanges are numbered as follows //(x,y) |---------| @@ -2470,7 +2583,10 @@ void W3DDisplay::drawRemainingRectClock(Int startX, Int startY, Int width, Int h } // render it now! - m_2DRender->Render(); + if (!m_isBatching) + { + m_2DRender->Render(); + } } @@ -2486,6 +2602,17 @@ void W3DDisplay::drawImage( const Image *image, Int startX, Int startY, if( image == nullptr ) return; + if (m_isClippedEnabled) + { + if ( endX <= m_clipRegion.lo.x || + endY <= m_clipRegion.lo.y || + startX >= m_clipRegion.hi.x || + startY >= m_clipRegion.hi.y) + { + return; //nothing to render + } + } + // !! // Remember to update the GUIEditDisplay::drawImage when you make // changes to this, it technically uses W3D code to render itself, @@ -2494,52 +2621,22 @@ void W3DDisplay::drawImage( const Image *image, Int startX, Int startY, const Region2D *uv = image->getUV(); - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( TRUE ); - - Bool doAlphaReset=FALSE; - - ///@todo: Why are we alpha blending all images? Reduces our fillrate. -MW - switch (mode) - { - case DRAW_IMAGE_ALPHA: //nothing to do since alpha is the default state - break; - case DRAW_IMAGE_GRAYSCALE: - m_2DRender->Enable_Grayscale(true); - break; - case DRAW_IMAGE_ADDITIVE: - m_2DRender->Enable_Additive(true); - doAlphaReset = TRUE; - break; - case DRAW_IMAGE_SOLID: - m_2DRender->Enable_Additive(false); - m_2DRender->Enable_Alpha(false); - doAlphaReset = TRUE; - break; - default: - break; - } - - // if we have raw texture data we will use it, otherwise we are referencing filenames - if( BitIsSet( image->getStatus(), IMAGE_STATUS_RAW_TEXTURE ) ) - m_2DRender->Set_Texture( (TextureClass *)(image->getRawTextureData()) ); + TextureClass *tex = nullptr; + if (BitIsSet(image->getStatus(), IMAGE_STATUS_RAW_TEXTURE)) + tex = (TextureClass *)(image->getRawTextureData()); else - m_2DRender->Set_Texture( image->getFilename().str() ); + tex = WW3DAssetManager::Get_Instance()->Get_Texture(image->getFilename().str(), MIP_LEVELS_1); + + Bool grayscale = (mode == DRAW_IMAGE_GRAYSCALE); + setup2DRenderState(tex, mode, grayscale); RectClass screen_rect(startX,startY,endX,endY); RectClass uv_rect(uv->lo.x,uv->lo.y,uv->hi.x,uv->hi.y); if (m_isClippedEnabled) { //need to clip this quad to clip rectangle - - // - // Check for completely clipped - // - if ( endX <= m_clipRegion.lo.x || - endY <= m_clipRegion.lo.y) + if (screen_rect.Left < m_clipRegion.lo.x || screen_rect.Right > m_clipRegion.hi.x || screen_rect.Top < m_clipRegion.lo.y || screen_rect.Bottom > m_clipRegion.hi.y) { - return; //nothing to render - } else { RectClass clipped_rect; RectClass clipped_uv_rect; @@ -2639,12 +2736,20 @@ void W3DDisplay::drawImage( const Image *image, Int startX, Int startY, } - m_2DRender->Render(); + if (!m_isBatching) + { + m_2DRender->Render(); + m_2DRender->Enable_Grayscale(false); + if (mode == DRAW_IMAGE_ADDITIVE || mode == DRAW_IMAGE_SOLID) + { + m_2DRender->Enable_Alpha(true); + } + } - //reset to default states for next time this method is called. - m_2DRender->Enable_Grayscale(false); //never leave it in this mode - if (doAlphaReset) - m_2DRender->Enable_Alpha(true); + if (tex != nullptr && !BitIsSet(image->getStatus(), IMAGE_STATUS_RAW_TEXTURE)) + { + tex->Release_Ref(); + } } @@ -2746,12 +2851,15 @@ void W3DDisplay::drawVideoBuffer( VideoBuffer *buffer, Int startX, Int startY, I { W3DVideoBuffer *vbuffer = (W3DVideoBuffer*) buffer; - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( TRUE ); - m_2DRender->Set_Texture( vbuffer->texture() ); + setup2DRenderState(vbuffer->texture(), DRAW_IMAGE_ALPHA, FALSE); + m_2DRender->Add_Quad( RectClass( startX, startY, endX, endY ), vbuffer->Rect( 0, 0, 1, 1) ); - m_2DRender->Render(); + + if (!m_isBatching) + { + m_2DRender->Render(); + } } diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp index 8b046b02ffd..b2dd25e12ff 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp @@ -49,6 +49,7 @@ #include // USER INCLUDES ////////////////////////////////////////////////////////////// +#include "GameClient/Display.h" #include "GameClient/GameClient.h" #include "W3DDevice/GameClient/W3DDisplayString.h" #include "GameClient/HotKey.h" @@ -216,17 +217,22 @@ void W3DDisplayString::draw( Int x, Int y, Color color, Color dropColor, Int xDr m_textRenderer.Set_Location( Vector2( m_textPos.x, m_textPos.y ) ); m_textRenderer.Draw_Sentence( m_currTextColor ); - if(m_useHotKey) + if (m_useHotKey) { m_textRendererHotKey.Reset_Polys(); m_textRendererHotKey.Set_Location( Vector2( m_textPos.x + m_hotKeyPos.x , m_textPos.y +m_hotKeyPos.y) ); m_textRendererHotKey.Draw_Sentence( m_hotKeyColor ); - m_textRendererHotKey.Render(); } } - // render the text + TheDisplay->flush(); + + if(m_useHotKey) + { + m_textRendererHotKey.Render(); + } + m_textRenderer.Render(); // we are for sure using display resources now diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp index dec0b3a473d..c85dd43ab0b 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp @@ -387,6 +387,7 @@ void W3DInGameUI::reset() //------------------------------------------------------------------------------------------------- void W3DInGameUI::draw() { + TheDisplay->beginBatch(); preDraw(); // draw selection region if drag selecting @@ -439,6 +440,8 @@ void W3DInGameUI::draw() } #endif + TheDisplay->endBatch(); + } //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Display.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Display.h index 319b15dc651..6b035fc112e 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Display.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Display.h @@ -113,6 +113,11 @@ class Display : public SubsystemInterface virtual Bool isClippingEnabled() = 0; virtual void enableClipping( Bool onoff ) = 0; + virtual void beginBatch(); + virtual void endBatch(); + virtual void flush(); + virtual Bool isBatching() { return m_isBatching; } + virtual void step() {}; ///< Do one fixed time step virtual void draw() override; ///< Redraw the entire display virtual void setTimeOfDay( TimeOfDay tod ) = 0; ///< Set the time of day for this display @@ -182,11 +187,15 @@ class Display : public SubsystemInterface virtual Int getLastFrameDrawCalls() = 0; ///< returns the number of draw calls issued in the previous frame protected: + virtual void onBeginBatch() { } + virtual void onEndBatch() { } + virtual void onFlush() { } virtual void deleteViews(); ///< delete all views UnsignedInt m_width, m_height; ///< Dimensions of the display UnsignedInt m_bitDepth; ///< bit depth of the display Bool m_windowed; ///< TRUE when windowed, FALSE when fullscreen + Bool m_isBatching; View *m_viewList; ///< All of the views into the world // Cinematic text data diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp index 9b7bbeaadd8..65422dcb50a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Display.cpp @@ -66,6 +66,7 @@ Display::Display() m_currentlyPlayingMovie.clear(); m_letterBoxFadeStartTime = 0; + m_isBatching = FALSE; } /** @@ -387,3 +388,31 @@ Display::DebugDisplayCallback *Display::getDebugDisplayCallback() { return m_debugDisplayCallback; } + +void Display::beginBatch() +{ + if (m_isBatching) + { + return; + } + m_isBatching = TRUE; + onBeginBatch(); +} + +void Display::endBatch() +{ + if (!m_isBatching) + { + return; + } + m_isBatching = FALSE; + onEndBatch(); +} + +void Display::flush() +{ + if (m_isBatching) + { + onFlush(); + } +} diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h index 9372d69136f..476fc14342c 100644 --- a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h +++ b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h @@ -45,6 +45,7 @@ class Render2DClass; class RTS3DScene; class RTS2DScene; class RTS3DInterfaceScene; +class TextureClass; //============================================================================= @@ -160,6 +161,10 @@ class W3DDisplay : public Display void calculateTerrainLOD(); ///< Calculate terrain LOD. void renderLetterBox(UnsignedInt time); ///< draw letter box border void updateAverageFPS(); ///< calculate the average fps over the last 30 frames. + void setup2DRenderState(TextureClass *tex, DrawImageMode mode, Bool grayscale); + virtual void onBeginBatch() override; + virtual void onEndBatch() override; + virtual void onFlush() override; Byte m_initialized; ///< TRUE when system is initialized LightClass *m_myLight[LightEnvironmentClass::MAX_LIGHTS]; ///< light hack for now @@ -168,6 +173,12 @@ class W3DDisplay : public Display Bool m_isClippedEnabled; ///Reset(); + } +} + +void W3DDisplay::onEndBatch() +{ + onFlush(); + if (m_batchTexture) + { + m_batchTexture->Release_Ref(); + m_batchTexture = nullptr; + } +} + +void W3DDisplay::onFlush() +{ + if (m_2DRender && !m_batchNeedsInit) + { + m_2DRender->Render(); + m_2DRender->Reset(); + m_batchNeedsInit = TRUE; + } +} + +void W3DDisplay::setup2DRenderState(TextureClass *tex, DrawImageMode mode, Bool grayscale) +{ + if (m_isBatching) + { + if (!m_batchNeedsInit && m_batchTexture == tex && m_batchMode == mode && m_batchGrayscale == grayscale) + { + return; + } + + onFlush(); + + if (tex != m_batchTexture) + { + if (tex) + { + tex->Add_Ref(); + } + if (m_batchTexture) + { + m_batchTexture->Release_Ref(); + } + + m_batchTexture = tex; + } + + m_batchMode = mode; + m_batchGrayscale = grayscale; + m_batchNeedsInit = FALSE; + } + else if (m_2DRender) + { + m_2DRender->Reset(); + } + + if (m_2DRender) + { + if (tex) + { + m_2DRender->Enable_Texturing(TRUE); + m_2DRender->Set_Texture(tex); + } + else + { + m_2DRender->Enable_Texturing(FALSE); + } + + switch (mode) + { + case DRAW_IMAGE_ALPHA: + m_2DRender->Enable_Additive(FALSE); + m_2DRender->Enable_Alpha(TRUE); + m_2DRender->Enable_Grayscale(grayscale); + break; + case DRAW_IMAGE_GRAYSCALE: + m_2DRender->Enable_Additive(FALSE); + m_2DRender->Enable_Alpha(TRUE); + m_2DRender->Enable_Grayscale(TRUE); + break; + case DRAW_IMAGE_ADDITIVE: + m_2DRender->Enable_Additive(TRUE); + m_2DRender->Enable_Alpha(FALSE); + m_2DRender->Enable_Grayscale(grayscale); + break; + case DRAW_IMAGE_SOLID: + m_2DRender->Enable_Additive(FALSE); + m_2DRender->Enable_Alpha(FALSE); + m_2DRender->Enable_Grayscale(grayscale); + break; + } + } +} + // W3DDisplay::initAssets ===================================================== /** */ //============================================================================= @@ -2148,14 +2257,15 @@ void W3DDisplay::drawLine( Int startX, Int startY, Real lineWidth, UnsignedInt lineColor ) { + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - /// @todo we need to consider the efficiency of the 2D renderer - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); m_2DRender->Add_Line( Vector2( startX, startY ), Vector2( endX, endY ), lineWidth, lineColor ); - m_2DRender->Render(); + if (!m_isBatching) + { + m_2DRender->Render(); + } } // W3DDisplay::drawLine ======================================================= @@ -2166,13 +2276,15 @@ void W3DDisplay::drawLine( Int startX, Int startY, Real lineWidth, UnsignedInt lineColor1,UnsignedInt lineColor2 ) { + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - /// @todo we need to consider the efficiency of the 2D renderer - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); m_2DRender->Add_Line( Vector2( startX, startY ), Vector2( endX, endY ), lineWidth, lineColor1, lineColor2 ); - m_2DRender->Render(); + + if (!m_isBatching) + { + m_2DRender->Render(); + } } @@ -2215,16 +2327,17 @@ void W3DDisplay::drawOpenRect( Int startX, Int startY, Int width, Int height, } else { - /// @todo we need to consider the efficiency of the 2D renderer - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); m_2DRender->Add_Outline( RectClass( startX, startY, startX + width, startY + height ), lineWidth, lineColor ); // render it now! - m_2DRender->Render(); + if (!m_isBatching) + { + m_2DRender->Render(); + } } } @@ -2234,17 +2347,17 @@ void W3DDisplay::drawOpenRect( Int startX, Int startY, Int width, Int height, void W3DDisplay::drawFillRect( Int startX, Int startY, Int width, Int height, UnsignedInt color ) { + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); - /// @todo we need to consider the efficiency of the 2D renderer - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); m_2DRender->Add_Rect( RectClass( startX, startY, startX + width, startY + height ), 0, 0, color ); // render it now! - m_2DRender->Render(); - + if (!m_isBatching) + { + m_2DRender->Render(); + } } void W3DDisplay::drawRectClock(Int startX, Int startY, Int width, Int height, Int percent, UnsignedInt color) @@ -2253,8 +2366,7 @@ void W3DDisplay::drawRectClock(Int startX, Int startY, Int width, Int height, In if(percent < 1 || percent > 100) return; - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); // The rectangles are numberd as follows //(x,y) |---------| @@ -2400,8 +2512,10 @@ void W3DDisplay::drawRectClock(Int startX, Int startY, Int width, Int height, In } // render it now! - m_2DRender->Render(); - + if (!m_isBatching) + { + m_2DRender->Render(); + } } @@ -2417,8 +2531,7 @@ void W3DDisplay::drawRemainingRectClock(Int startX, Int startY, Int width, Int h if( percent < 0 || percent > 99 ) return; - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( FALSE ); + setup2DRenderState(nullptr, DRAW_IMAGE_ALPHA, FALSE); // The rectangles are numbered as follows //(x,y) |---------| @@ -2579,7 +2692,10 @@ void W3DDisplay::drawRemainingRectClock(Int startX, Int startY, Int width, Int h } // render it now! - m_2DRender->Render(); + if (!m_isBatching) + { + m_2DRender->Render(); + } } @@ -2595,6 +2711,17 @@ void W3DDisplay::drawImage( const Image *image, Int startX, Int startY, if( image == nullptr ) return; + if (m_isClippedEnabled) + { + if ( endX <= m_clipRegion.lo.x || + endY <= m_clipRegion.lo.y || + startX >= m_clipRegion.hi.x || + startY >= m_clipRegion.hi.y) + { + return; //nothing to render + } + } + // !! // Remember to update the GUIEditDisplay::drawImage when you make // changes to this, it technically uses W3D code to render itself, @@ -2603,52 +2730,22 @@ void W3DDisplay::drawImage( const Image *image, Int startX, Int startY, const Region2D *uv = image->getUV(); - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( TRUE ); - - Bool doAlphaReset=FALSE; - - ///@todo: Why are we alpha blending all images? Reduces our fillrate. -MW - switch (mode) - { - case DRAW_IMAGE_ALPHA: //nothing to do since alpha is the default state - break; - case DRAW_IMAGE_GRAYSCALE: - m_2DRender->Enable_Grayscale(true); - break; - case DRAW_IMAGE_ADDITIVE: - m_2DRender->Enable_Additive(true); - doAlphaReset = TRUE; - break; - case DRAW_IMAGE_SOLID: - m_2DRender->Enable_Additive(false); - m_2DRender->Enable_Alpha(false); - doAlphaReset = TRUE; - break; - default: - break; - } - - // if we have raw texture data we will use it, otherwise we are referencing filenames - if( BitIsSet( image->getStatus(), IMAGE_STATUS_RAW_TEXTURE ) ) - m_2DRender->Set_Texture( (TextureClass *)(image->getRawTextureData()) ); + TextureClass *tex = nullptr; + if (BitIsSet(image->getStatus(), IMAGE_STATUS_RAW_TEXTURE)) + tex = (TextureClass *)(image->getRawTextureData()); else - m_2DRender->Set_Texture( image->getFilename().str() ); + tex = WW3DAssetManager::Get_Instance()->Get_Texture(image->getFilename().str(), MIP_LEVELS_1); + + Bool grayscale = (mode == DRAW_IMAGE_GRAYSCALE); + setup2DRenderState(tex, mode, grayscale); RectClass screen_rect(startX,startY,endX,endY); RectClass uv_rect(uv->lo.x,uv->lo.y,uv->hi.x,uv->hi.y); if (m_isClippedEnabled) { //need to clip this quad to clip rectangle - - // - // Check for completely clipped - // - if ( endX <= m_clipRegion.lo.x || - endY <= m_clipRegion.lo.y) + if (screen_rect.Left < m_clipRegion.lo.x || screen_rect.Right > m_clipRegion.hi.x || screen_rect.Top < m_clipRegion.lo.y || screen_rect.Bottom > m_clipRegion.hi.y) { - return; //nothing to render - } else { RectClass clipped_rect; RectClass clipped_uv_rect; @@ -2748,12 +2845,20 @@ void W3DDisplay::drawImage( const Image *image, Int startX, Int startY, } - m_2DRender->Render(); + if (!m_isBatching) + { + m_2DRender->Render(); + m_2DRender->Enable_Grayscale(false); + if (mode == DRAW_IMAGE_ADDITIVE || mode == DRAW_IMAGE_SOLID) + { + m_2DRender->Enable_Alpha(true); + } + } - //reset to default states for next time this method is called. - m_2DRender->Enable_Grayscale(false); //never leave it in this mode - if (doAlphaReset) - m_2DRender->Enable_Alpha(true); + if (tex != nullptr && !BitIsSet(image->getStatus(), IMAGE_STATUS_RAW_TEXTURE)) + { + tex->Release_Ref(); + } } @@ -2855,12 +2960,15 @@ void W3DDisplay::drawVideoBuffer( VideoBuffer *buffer, Int startX, Int startY, I { W3DVideoBuffer *vbuffer = (W3DVideoBuffer*) buffer; - m_2DRender->Reset(); - m_2DRender->Enable_Texturing( TRUE ); - m_2DRender->Set_Texture( vbuffer->texture() ); + setup2DRenderState(vbuffer->texture(), DRAW_IMAGE_ALPHA, FALSE); + m_2DRender->Add_Quad( RectClass( startX, startY, endX, endY ), vbuffer->Rect( 0, 0, 1, 1) ); - m_2DRender->Render(); + + if (!m_isBatching) + { + m_2DRender->Render(); + } } diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp index 12c7c8dbeeb..55071200656 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayString.cpp @@ -49,6 +49,7 @@ #include // USER INCLUDES ////////////////////////////////////////////////////////////// +#include "GameClient/Display.h" #include "GameClient/GameClient.h" #include "W3DDevice/GameClient/W3DDisplayString.h" #include "GameClient/HotKey.h" @@ -216,17 +217,22 @@ void W3DDisplayString::draw( Int x, Int y, Color color, Color dropColor, Int xDr m_textRenderer.Set_Location( Vector2( m_textPos.x, m_textPos.y ) ); m_textRenderer.Draw_Sentence( m_currTextColor ); - if(m_useHotKey) + if (m_useHotKey) { m_textRendererHotKey.Reset_Polys(); m_textRendererHotKey.Set_Location( Vector2( m_textPos.x + m_hotKeyPos.x , m_textPos.y +m_hotKeyPos.y) ); m_textRendererHotKey.Draw_Sentence( m_hotKeyColor ); - m_textRendererHotKey.Render(); } } - // render the text + TheDisplay->flush(); + + if(m_useHotKey) + { + m_textRendererHotKey.Render(); + } + m_textRenderer.Render(); // we are for sure using display resources now diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp index 8fd63a0c3fd..d1fb63d2af4 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DInGameUI.cpp @@ -387,6 +387,7 @@ void W3DInGameUI::reset() //------------------------------------------------------------------------------------------------- void W3DInGameUI::draw() { + TheDisplay->beginBatch(); preDraw(); // draw selection region if drag selecting @@ -439,6 +440,8 @@ void W3DInGameUI::draw() } #endif + TheDisplay->endBatch(); + } //-------------------------------------------------------------------------------------------------