diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 1f7739c01..9d4a0e828 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1198,6 +1198,9 @@ public: // Set builtin parameters virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform) = 0; virtual void setUniformFog(TProgram program, uint index) = 0; + // Set feature parameters + virtual bool setUniformDriver(TProgram program) = 0; // set all driver-specific features params (based on program->features->DriverFlags) (called automatically when rendering with cmaterial and using a user program) + virtual void setUniformParams(TProgram program, const CGPUProgramParams ¶ms) = 0; // set all user-provided params from the storage // @} diff --git a/code/nel/include/nel/3d/material.h b/code/nel/include/nel/3d/material.h index 6d9589ca5..671f3339a 100644 --- a/code/nel/include/nel/3d/material.h +++ b/code/nel/include/nel/3d/material.h @@ -172,10 +172,6 @@ public: * - RGB still unchanged * Water : * - Water - * PostProcessing : - * - For internal use only when a pixel program is set manually through activePixelProgram. - * - Only textures are set by CMaterial (does not work with ps_3_0 for some reason), the rest must be set manually. - * - May be replaced in the future by some generic shader system. */ enum TShader { Normal=0, Bump, @@ -187,8 +183,8 @@ public: PerPixelLightingNoSpec, Cloud, Water, - PostProcessing, - shaderCount}; + shaderCount, + Program /* internally used when a pixel program is active */ }; /// \name Texture Env Modes. // @{ diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index a17ae32c3..d360fb915 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -1207,6 +1207,10 @@ public: // Set builtin parameters virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform); virtual void setUniformFog(TProgram program, uint index); + // Set feature parameters + virtual bool setUniformDriver(TProgram program); // set all driver-specific features params (based on program->features->DriverFlags) + virtual bool setUniformMaterial(TProgram program, CMaterial &material); // set all material-specific feature params (based on program->features->MaterialFlags) + virtual void setUniformParams(TProgram program, const CGPUProgramParams ¶ms); // set all user-provided params from the storage // @} @@ -2537,6 +2541,9 @@ private: // The last vertex buffer needs vertex color bool _FogEnabled; + bool _VertexProgramUser; + bool _PixelProgramUser; + // *** Internal resources // Current render pass diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_pixel_program.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_pixel_program.cpp index 0d97925b3..ea636b348 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_pixel_program.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_pixel_program.cpp @@ -129,11 +129,13 @@ bool CDriverD3D::activePixelProgram(CPixelProgram *program) if (!CDriverD3D::compilePixelProgram(program)) return false; CPixelProgramDrvInfosD3D *info = static_cast((IGPUProgramDrvInfos*)program->m_DrvInfo); + _PixelProgramUser = true; setPixelShader(info->Shader); } else { setPixelShader(NULL); + _PixelProgramUser = false; } return true; diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp index 27e76bfd4..2ade8cfb4 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp @@ -215,4 +215,23 @@ void CDriverD3D::setUniformFog(NL3D::IDriver::TProgram program, uint index) 1 - (_D3DModelView._43 - _FogStart) / delta); } +bool CDriverD3D::setUniformDriver(TProgram program) +{ + // todo + + return true; +} + +bool CDriverD3D::setUniformMaterial(TProgram program, const CMaterial &material) +{ + // todo + + return true; +} + +void CDriverD3D::setUniformParams(TProgram program, const CGPUProgramParams ¶ms) +{ + // todo +} + } // NL3D diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex_program.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex_program.cpp index a409f20cf..74ddf9011 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex_program.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex_program.cpp @@ -379,6 +379,7 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) if (!CDriverD3D::compileVertexProgram(program)) return false; CVertexProgamDrvInfosD3D *info = NLMISC::safe_cast((IGPUProgramDrvInfos*)program->m_DrvInfo); + _VertexProgramUser = true; setVertexProgram (info->Shader, program); /* D3DRS_FOGSTART and D3DRS_FOGEND must be set with [1, 0] else the fog doesn't work properly on VertexShader and non-VertexShader objects @@ -394,6 +395,7 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) else { setVertexProgram (NULL, NULL); + _VertexProgramUser = false; // Set the old fog range setRenderState (D3DRS_FOGSTART, *((DWORD*) (&_FogStart))); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index e76563fb3..48e50ab8e 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1413,6 +1413,11 @@ private: // Set builtin parameters virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform); virtual void setUniformFog(TProgram program, uint index); + // Set feature parameters + virtual bool setUniformDriver(TProgram program); // set all driver-specific features params (based on program->features->DriverFlags) + virtual bool setUniformMaterial(TProgram program, CMaterial &material); // set all material-specific feature params (based on program->features->MaterialFlags) + bool setUniformMaterialInternal(TProgram program, CMaterial &material); // set all material-specific feature params (based on program->features->MaterialFlags) + virtual void setUniformParams(TProgram program, const CGPUProgramParams ¶ms); // set all user-provided params from the storage // @} diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp index 6d9dbb247..67afe7868 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp @@ -283,14 +283,15 @@ void CDriverGL::setTextureShaders(const uint8 *addressingModes, const CSmartPtr< bool CDriverGL::setupMaterial(CMaterial& mat) { H_AUTO_OGL(CDriverGL_setupMaterial) - CShaderGL* pShader; - GLenum glenum = GL_ZERO; - uint32 touched = mat.getTouched(); - uint stage; // profile. _NbSetupMaterialCall++; + CMaterial::TShader matShader; + + CShaderGL* pShader; + GLenum glenum = GL_ZERO; + uint32 touched = mat.getTouched(); // 0. Retrieve/Create driver shader. //================================== @@ -359,9 +360,29 @@ bool CDriverGL::setupMaterial(CMaterial& mat) mat.clearTouched(0xFFFFFFFF); } - // Now we can get the supported shader from the cache. - CMaterial::TShader matShader = pShader->SupportedShader; + // 2b. User supplied pixel shader overrides material + //================================== + if (_VertexProgramEnabled) + { + if (!setUniformDriver(VertexProgram)) return false; + if (!setUniformMaterialInternal(VertexProgram, mat)) return false; + } + if (_PixelProgramEnabled) + { + matShader = CMaterial::Program; + + if (!setUniformDriver(PixelProgram)) return false; + if (!setUniformMaterialInternal(PixelProgram, mat)) return false; + if (!_LastSetuppedPP) return false; + } + else + { + // Now we can get the supported shader from the cache. + matShader = pShader->SupportedShader; + } + // 2b. Update more shader state + //================================== // if the shader has changed since last time if(matShader != _CurrentMaterialSupportedShader) { @@ -382,9 +403,11 @@ bool CDriverGL::setupMaterial(CMaterial& mat) // Must setup textures each frame. (need to test if touched). // Must separate texture setup and texture activation in 2 "for"... // because setupTexture() may disable all stage. - if (matShader != CMaterial::Water) + if (matShader != CMaterial::Water + && ((matShader != CMaterial::Program) || (_LastSetuppedPP->features().MaterialFlags & CGPUProgramFeatures::TextureStages)) + ) { - for(stage=0 ; stagefeatures().MaterialFlags & CGPUProgramFeatures::TextureStages)) ) { - for(stage=0 ; stagefeatures().MaterialFlags & CGPUProgramFeatures::TextureMatrices)) + ) { setupUserTextureMatrix(inlGetNumTextStages(), mat); } - else // deactivate texture matrix + else { disableUserTextureMatrix(); } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp index 6b429e706..3ba97efd3 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -291,6 +291,107 @@ void CDriverGL::setUniformFog(NL3D::IDriver::TProgram program, uint index) CDriverGL::setUniform4f(program, index, -values[2], -values[6], -values[10], -values[14]); } +bool CDriverGL::setUniformDriver(TProgram program) +{ + IGPUProgram *prog = NULL; + switch (program) + { + case VertexProgram: + prog = _LastSetuppedVP; + break; + case PixelProgram: + prog = _LastSetuppedPP; + break; + } + if (!prog) return false; + + const CGPUProgramFeatures &features = prog->features(); + + if (features.DriverFlags) + { + // todo + } + + return true; +} + +bool CDriverGL::setUniformMaterial(TProgram program, CMaterial &material) +{ + IGPUProgram *prog = NULL; + switch (program) + { + case VertexProgram: + prog = _LastSetuppedVP; + break; + case PixelProgram: + prog = _LastSetuppedPP; + break; + } + if (!prog) return false; + + const CGPUProgramFeatures &features = prog->features(); + + // These are also already set by setupMaterial, so setupMaterial uses setUniformMaterialInternal instead + if (features.MaterialFlags & (CGPUProgramFeatures::TextureStages | CGPUProgramFeatures::TextureMatrices)) + { + if (features.MaterialFlags & CGPUProgramFeatures::TextureStages) + { + for (uint stage = 0; stage < inlGetNumTextStages(); ++stage) + { + ITexture *text= material.getTexture(uint8(stage)); + + // Must setup textures each frame. (need to test if touched). + if (text != NULL && !setupTexture(*text)) + return false; + + // activate the texture, or disable texturing if NULL. + activateTexture(stage, text); + + // If texture not NULL, Change texture env function. + setTextureEnvFunction(stage, material); + } + + + } + if (features.MaterialFlags & CGPUProgramFeatures::TextureMatrices) + { + // Textures user matrix + setupUserTextureMatrix(inlGetNumTextStages(), material); + } + } + + return true; +} + +bool CDriverGL::setUniformMaterialInternal(TProgram program, CMaterial &material) +{ + IGPUProgram *prog = NULL; + switch (program) + { + case VertexProgram: + prog = _LastSetuppedVP; + break; + case PixelProgram: + prog = _LastSetuppedPP; + break; + } + if (!prog) return false; + + const CGPUProgramFeatures &features = prog->features(); + + if (features.MaterialFlags & ~(CGPUProgramFeatures::TextureStages | CGPUProgramFeatures::TextureMatrices)) + { + // todo + } + + return true; +} + +void CDriverGL::setUniformParams(TProgram program, const CGPUProgramParams ¶ms) +{ + // todo +} + #ifdef NL_STATIC } // NLDRIVERGL/ES #endif diff --git a/code/nel/src/3d/flare_model.cpp b/code/nel/src/3d/flare_model.cpp index ba5cc8098..6c422aac9 100644 --- a/code/nel/src/3d/flare_model.cpp +++ b/code/nel/src/3d/flare_model.cpp @@ -364,6 +364,7 @@ void CFlareModel::traverseRender() // setup driver drv->activeVertexProgram(NULL); drv->activePixelProgram(NULL); + drv->activeGeometryProgram(NULL); drv->setupModelMatrix(fs->getLookAtMode() ? CMatrix::Identity : getWorldMatrix()); // we don't change the fustrum to draw 2d shapes : it is costly, and we need to restore it after the drawing has been done // we setup Z to be (near + far) / 2, and setup x and y to get the screen coordinates we want @@ -567,6 +568,7 @@ void CFlareModel::updateOcclusionQueryBegin(IDriver *drv) nlassert(drv); drv->activeVertexProgram(NULL); drv->activePixelProgram(NULL); + drv->activeGeometryProgram(NULL); drv->setupModelMatrix(CMatrix::Identity); initStatics(); drv->setColorMask(false, false, false, false); // don't write any pixel during the test @@ -664,6 +666,7 @@ void CFlareModel::occlusionTest(CMesh &mesh, IDriver &drv) drv.setColorMask(false, false, false, false); // don't write any pixel during the test drv.activeVertexProgram(NULL); drv.activePixelProgram(NULL); + drv.activeGeometryProgram(NULL); setupOcclusionMeshMatrix(drv, *_Scene); drv.activeVertexBuffer(const_cast(mesh.getVertexBuffer())); // query drawn count diff --git a/code/nel/src/3d/scene.cpp b/code/nel/src/3d/scene.cpp index 76761bc71..fb2d476ac 100644 --- a/code/nel/src/3d/scene.cpp +++ b/code/nel/src/3d/scene.cpp @@ -382,6 +382,7 @@ void CScene::endPartRender() IDriver *drv = getDriver(); drv->activeVertexProgram(NULL); drv->activePixelProgram(NULL); + drv->activeGeometryProgram(NULL); // Ensure nothing animates on subsequent renders _EllapsedTime = 0.f; @@ -1577,6 +1578,7 @@ void CScene::renderOcclusionTestMeshs() RenderTrav.getDriver()->setupViewport(RenderTrav.getViewport()); RenderTrav.getDriver()->activeVertexProgram(NULL); RenderTrav.getDriver()->activePixelProgram(NULL); + RenderTrav.getDriver()->activeGeometryProgram(NULL); IDriver::TPolygonMode oldPolygonMode = RenderTrav.getDriver()->getPolygonMode(); CMaterial m; m.initUnlit(); diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 588e36fcb..4dc9a39bb 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -150,7 +150,7 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) m_Mat.setBlend (false); m_Mat.setAlphaTest (false); NL3D::CMaterial *mat = m_Mat.getObjectPtr(); - mat->setShader(NL3D::CMaterial::PostProcessing); + mat->setShader(NL3D::CMaterial::Normal); mat->setBlendFunc(CMaterial::one, CMaterial::zero); mat->setZWrite(false); mat->setZFunc(CMaterial::always); diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index cedfe3434..b3eb2f235 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -356,7 +356,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) m_BarrelMat.setBlend (false); m_BarrelMat.setAlphaTest (false); NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); - barrelMat->setShader(NL3D::CMaterial::PostProcessing); + barrelMat->setShader(NL3D::CMaterial::Normal); barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero); barrelMat->setZWrite(false); barrelMat->setZFunc(CMaterial::always);