From ab44da27336241ee67c3c1c71368afbd90df3cfc Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 1 Jul 2022 20:02:51 -0700 Subject: [PATCH] Move Push/Pop Layer stuff to pl3DPipeline This is what calls `Eval()` to make layer animations work, so that's now hooked up for plGLPipeline. I don't love this approach because it feels weird doing it in the shader class, and I suspect we need to know about layer overrides when the shader is being generated, but... for now it sorta works. --- .../FeatureLib/pfDXPipeline/plDXPipeline.cpp | 82 -------------- .../FeatureLib/pfDXPipeline/plDXPipeline.h | 5 - .../pfGLPipeline/plGLMaterialShaderRef.cpp | 22 +++- .../pfGLPipeline/plGLMaterialShaderRef.h | 6 +- .../FeatureLib/pfGLPipeline/plGLPipeline.h | 1 + .../PubUtilLib/plPipeline/pl3DPipeline.h | 106 +++++++++++++++++- 6 files changed, 125 insertions(+), 97 deletions(-) diff --git a/Sources/Plasma/FeatureLib/pfDXPipeline/plDXPipeline.cpp b/Sources/Plasma/FeatureLib/pfDXPipeline/plDXPipeline.cpp index 4b9b97cac5..838bef2605 100644 --- a/Sources/Plasma/FeatureLib/pfDXPipeline/plDXPipeline.cpp +++ b/Sources/Plasma/FeatureLib/pfDXPipeline/plDXPipeline.cpp @@ -5280,88 +5280,6 @@ void plDXPipeline::IBottomLayer() // Special effects ///////////////////////////////////////////////////////////// -// IPushOverBaseLayer ///////////////////////////////////////////////////////// -// Sets fOverBaseLayer (if any) as a wrapper on top of input layer. -// This allows the OverBaseLayer to intercept and modify queries of -// the real current layer's properties (e.g. color or state). -// fOverBaseLayer is set to only get applied to the base layer during -// multitexturing. -// Must be matched with call to IPopOverBaseLayer. -plLayerInterface* plDXPipeline::IPushOverBaseLayer(plLayerInterface* li) -{ - if( !li ) - return nullptr; - - fOverLayerStack.push_back(li); - - if( !fOverBaseLayer ) - return fOverBaseLayer = li; - - fForceMatHandle = true; - fOverBaseLayer = fOverBaseLayer->Attach(li); - fOverBaseLayer->Eval(fTime, fFrame, 0); - return fOverBaseLayer; -} - -// IPopOverBaseLayer ///////////////////////////////////////////////////////// -// Removes fOverBaseLayer as wrapper on top of input layer. -// Should match calls to IPushOverBaseLayer. -plLayerInterface* plDXPipeline::IPopOverBaseLayer(plLayerInterface* li) -{ - if( !li ) - return nullptr; - - fForceMatHandle = true; - - plLayerInterface* pop = fOverLayerStack.back(); - fOverLayerStack.pop_back(); - fOverBaseLayer = fOverBaseLayer->Detach(pop); - - return pop; -} - -// IPushOverAllLayer /////////////////////////////////////////////////// -// Push fOverAllLayer (if any) as wrapper around the input layer. -// fOverAllLayer is set to be applied to each layer during multitexturing. -// Must be matched by call to IPopOverAllLayer -plLayerInterface* plDXPipeline::IPushOverAllLayer(plLayerInterface* li) -{ - if( !li ) - return nullptr; - - fOverLayerStack.push_back(li); - - if( !fOverAllLayer ) - { - fOverAllLayer = li; - fOverAllLayer->Eval(fTime, fFrame, 0); - return fOverAllLayer; - } - - fForceMatHandle = true; - fOverAllLayer = fOverAllLayer->Attach(li); - fOverAllLayer->Eval(fTime, fFrame, 0); - - return fOverAllLayer; -} - -// IPopOverAllLayer ////////////////////////////////////////////////// -// Remove fOverAllLayer as wrapper on top of input layer. -// Should match calls to IPushOverAllLayer. -plLayerInterface* plDXPipeline::IPopOverAllLayer(plLayerInterface* li) -{ - if( !li ) - return nullptr; - - fForceMatHandle = true; - - plLayerInterface* pop = fOverLayerStack.back(); - fOverLayerStack.pop_back(); - fOverAllLayer = fOverAllLayer->Detach(pop); - - return pop; -} - // PiggyBacks - used in techniques like projective lighting. // PiggyBacks are layers appended to each drawprimitive pass. // For example, if a material has 3 layers which will be drawn diff --git a/Sources/Plasma/FeatureLib/pfDXPipeline/plDXPipeline.h b/Sources/Plasma/FeatureLib/pfDXPipeline/plDXPipeline.h index 221fc7b78b..396eb92d96 100644 --- a/Sources/Plasma/FeatureLib/pfDXPipeline/plDXPipeline.h +++ b/Sources/Plasma/FeatureLib/pfDXPipeline/plDXPipeline.h @@ -341,11 +341,6 @@ class plDXPipeline : public pl3DPipeline void IBottomLayer(); // Push special effects - plLayerInterface* IPushOverBaseLayer(plLayerInterface* li); - plLayerInterface* IPopOverBaseLayer(plLayerInterface* li); - plLayerInterface* IPushOverAllLayer(plLayerInterface* li); - plLayerInterface* IPopOverAllLayer(plLayerInterface* li); - int ISetNumActivePiggyBacks(); void IPushPiggyBacks(hsGMaterial* mat); void IPopPiggyBacks(); diff --git a/Sources/Plasma/FeatureLib/pfGLPipeline/plGLMaterialShaderRef.cpp b/Sources/Plasma/FeatureLib/pfGLPipeline/plGLMaterialShaderRef.cpp index 78ba5de0db..70946fed21 100644 --- a/Sources/Plasma/FeatureLib/pfGLPipeline/plGLMaterialShaderRef.cpp +++ b/Sources/Plasma/FeatureLib/pfGLPipeline/plGLMaterialShaderRef.cpp @@ -42,6 +42,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plGLMaterialShaderRef.h" #include "plGLDevice.h" +#include "plGLPipeline.h" #include @@ -49,7 +50,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "hsBitVector.h" #include "hsGMatState.inl" -#include "plPipeline.h" #include "plPipeDebugFlags.h" #include "plDrawable/plGBufferGroup.h" @@ -230,7 +230,7 @@ void main() { fragColor = vec4(currColor, currAlpha); })"; -plGLMaterialShaderRef::plGLMaterialShaderRef(hsGMaterial* mat, plPipeline* pipe) +plGLMaterialShaderRef::plGLMaterialShaderRef(hsGMaterial* mat, plGLPipeline* pipe) : plGLDeviceRef(), fMaterial(mat), fPipeline(pipe), fVertShaderRef(0), fFragShaderRef(0) { ISetupShaderContexts(); @@ -274,16 +274,22 @@ void plGLMaterialShaderRef::SetupTextureRefs() if (!layer) continue; + layer = fPipeline->IPushOverAllLayer(layer); + // Load the image plBitmap* img = plBitmap::ConvertNoRef(layer->GetTexture()); - if (!img) + if (!img) { + layer = fPipeline->IPopOverAllLayer(layer); continue; + } plGLTextureRef* texRef = static_cast(img->GetDeviceRef()); - if (!texRef->fRef) + if (!texRef->fRef) { + layer = fPipeline->IPopOverAllLayer(layer); continue; + } fPipeline->CheckTextureRef(layer); @@ -325,6 +331,7 @@ void plGLMaterialShaderRef::SetupTextureRefs() glUniform1i(this->uTexture[i], numTextures); LOG_GL_ERROR_CHECK("Uniform Texture failed") + layer = fPipeline->IPopOverAllLayer(layer); numTextures++; } } @@ -580,12 +587,12 @@ uint32_t plGLMaterialShaderRef::IHandleMaterial(uint32_t layer, std::shared_ptr< // Ignoring the bit about self-rendering cube maps - plLayerInterface* currLay = /*IPushOverBaseLayer*/ fMaterial->GetLayer(layer); + plLayerInterface* currLay = fPipeline->IPushOverBaseLayer(fMaterial->GetLayer(layer)); if (fPipeline->IsDebugFlagSet(plPipeDbg::kFlagBumpW) && (currLay->GetMiscFlags() & hsGMatState::kMiscBumpDu)) currLay = fMaterial->GetLayer(++layer); - //currLay = IPushOverAllLayer(currLay); + currLay = fPipeline->IPushOverAllLayer(currLay); hsGMatState state = ICompositeLayerState(currLay); @@ -627,6 +634,9 @@ uint32_t plGLMaterialShaderRef::IHandleMaterial(uint32_t layer, std::shared_ptr< //ISetBumpMatrices(currLay); } + currLay = fPipeline->IPopOverAllLayer(currLay); + currLay = fPipeline->IPopOverBaseLayer(currLay); + std::shared_ptr vVtxColor = IFindVariable("vVtxColor", "vec4"); std::shared_ptr fBaseAlpha = std::make_shared("baseAlpha", "float"); diff --git a/Sources/Plasma/FeatureLib/pfGLPipeline/plGLMaterialShaderRef.h b/Sources/Plasma/FeatureLib/pfGLPipeline/plGLMaterialShaderRef.h index 21e640bce1..03674e3d69 100644 --- a/Sources/Plasma/FeatureLib/pfGLPipeline/plGLMaterialShaderRef.h +++ b/Sources/Plasma/FeatureLib/pfGLPipeline/plGLMaterialShaderRef.h @@ -52,7 +52,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "hsGMatState.h" class hsGMaterial; -class plPipeline; +class plGLPipeline; class plLayerInterface; enum plGLShaderConstants : GLuint { @@ -100,7 +100,7 @@ class plGLMaterialShaderRef : public plGLDeviceRef protected: hsGMaterial* fMaterial; - plPipeline* fPipeline; + plGLPipeline* fPipeline; GLuint fVertShaderRef; GLuint fFragShaderRef; @@ -142,7 +142,7 @@ class plGLMaterialShaderRef : public plGLDeviceRef void Link(plGLMaterialShaderRef** back) { plGLDeviceRef::Link((plGLDeviceRef**)back); } plGLMaterialShaderRef* GetNext() { return (plGLMaterialShaderRef*)fNext; } - plGLMaterialShaderRef(hsGMaterial* mat, plPipeline* pipe); + plGLMaterialShaderRef(hsGMaterial* mat, plGLPipeline* pipe); virtual ~plGLMaterialShaderRef(); void Release(); diff --git a/Sources/Plasma/FeatureLib/pfGLPipeline/plGLPipeline.h b/Sources/Plasma/FeatureLib/pfGLPipeline/plGLPipeline.h index aca1b59b82..f1b79f4d50 100644 --- a/Sources/Plasma/FeatureLib/pfGLPipeline/plGLPipeline.h +++ b/Sources/Plasma/FeatureLib/pfGLPipeline/plGLPipeline.h @@ -66,6 +66,7 @@ class plGLPipeline : public pl3DPipeline { friend class plGLPlateManager; friend class plGLDevice; + friend class plGLMaterialShaderRef; protected: typedef void(*blend_vert_buffer_ptr)(plSpan*, hsMatrix44*, int, const uint8_t*, uint8_t , uint32_t, uint8_t*, uint32_t, uint32_t, uint16_t); diff --git a/Sources/Plasma/PubUtilLib/plPipeline/pl3DPipeline.h b/Sources/Plasma/PubUtilLib/plPipeline/pl3DPipeline.h index ed4f3ead3c..1bedda7ebf 100644 --- a/Sources/Plasma/PubUtilLib/plPipeline/pl3DPipeline.h +++ b/Sources/Plasma/PubUtilLib/plPipeline/pl3DPipeline.h @@ -680,7 +680,6 @@ class pl3DPipeline : public plPipeline /** Removes a layer wrapper installed by AppendLayerInterface. */ plLayerInterface* RemoveLayerInterface(plLayerInterface* li, bool onAllLayers = false) override; - /** * Return the current bits set to be always on for the given category * (e.g. ZFlags). @@ -851,6 +850,39 @@ class pl3DPipeline : public plPipeline plRenderTarget* IGetNextAvRT(); void IFreeAvRT(plRenderTarget* tex); + /** + * Sets fOverBaseLayer (if any) as a wrapper on top of input layer. + * This allows the OverBaseLayer to intercept and modify queries of + * the real current layer's properties (e.g. color or state). + * fOverBaseLayer is set to only get applied to the base layer during + * multitexturing. + * + * Must be matched with call to IPopOverBaseLayer. + */ + plLayerInterface* IPushOverBaseLayer(plLayerInterface* li); + + /** + * Removes fOverBaseLayer as wrapper on top of input layer. + * + * Should match calls to IPushOverBaseLayer. + */ + plLayerInterface* IPopOverBaseLayer(plLayerInterface* li); + + /** + * Push fOverAllLayer (if any) as wrapper around the input layer. + * + * fOverAllLayer is set to be applied to each layer during multitexturing. + * + * Must be matched by call to IPopOverAllLayer + */ + plLayerInterface* IPushOverAllLayer(plLayerInterface* li); + + /** + * Remove fOverAllLayer as wrapper on top of input layer. + * + * Should match calls to IPushOverAllLayer. + */ + plLayerInterface* IPopOverAllLayer(plLayerInterface* li); /** * For every span in the list of visible span indices, find the list of @@ -1745,6 +1777,78 @@ void pl3DPipeline::IFreeAvRT(plRenderTarget* tex) } +template +plLayerInterface* pl3DPipeline::IPushOverBaseLayer(plLayerInterface* li) +{ + if (!li) + return nullptr; + + fOverLayerStack.push_back(li); + + if (!fOverBaseLayer) + return fOverBaseLayer = li; + + fForceMatHandle = true; + fOverBaseLayer = fOverBaseLayer->Attach(li); + fOverBaseLayer->Eval(fTime, fFrame, 0); + return fOverBaseLayer; +} + + +template +plLayerInterface* pl3DPipeline::IPopOverBaseLayer(plLayerInterface* li) +{ + if (!li) + return nullptr; + + fForceMatHandle = true; + + plLayerInterface* pop = fOverLayerStack.back(); + fOverLayerStack.pop_back(); + fOverBaseLayer = fOverBaseLayer->Detach(pop); + + return pop; +} + + +template +plLayerInterface* pl3DPipeline::IPushOverAllLayer(plLayerInterface* li) +{ + if (!li) + return nullptr; + + fOverLayerStack.push_back(li); + + if (!fOverAllLayer) { + fOverAllLayer = li; + fOverAllLayer->Eval(fTime, fFrame, 0); + return fOverAllLayer; + } + + fForceMatHandle = true; + fOverAllLayer = fOverAllLayer->Attach(li); + fOverAllLayer->Eval(fTime, fFrame, 0); + + return fOverAllLayer; +} + + +template +plLayerInterface* pl3DPipeline::IPopOverAllLayer(plLayerInterface* li) +{ + if (!li) + return nullptr; + + fForceMatHandle = true; + + plLayerInterface* pop = fOverLayerStack.back(); + fOverLayerStack.pop_back(); + fOverAllLayer = fOverAllLayer->Detach(pop); + + return pop; +} + + template void pl3DPipeline::ICheckLighting(plDrawableSpans* drawable, std::vector& visList, plVisMgr* visMgr) {