From abdeee4b81d16344407ff88f0cf783fa71b8d315 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 16 Jun 2013 20:48:17 +0200 Subject: [PATCH 001/137] Add info structure for multipass camera rendering effects #43 --- code/nel/include/nel/3d/driver.h | 13 +++ .../nel/3d/multipass_camera_effect_info.h | 89 +++++++++++++++++++ .../3d/driver/direct3d/driver_direct3d.cpp | 20 +++++ .../src/3d/driver/direct3d/driver_direct3d.h | 4 + .../src/3d/driver/opengl/driver_opengl.cpp | 29 ++++++ code/nel/src/3d/driver/opengl/driver_opengl.h | 7 ++ .../src/3d/multipass_camera_effect_info.cpp | 65 ++++++++++++++ 7 files changed, 227 insertions(+) create mode 100644 code/nel/include/nel/3d/multipass_camera_effect_info.h create mode 100644 code/nel/src/3d/multipass_camera_effect_info.cpp diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index d090d77da..6630be4ca 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -66,6 +66,9 @@ class CScissor; class CViewport; struct CMonitorColorProperties; struct IOcclusionQuery; +class CMultipassCameraEffectInfo; +class IMultipassCameraEffectInfoPriv; +class IMultipassCameraEffect; @@ -807,6 +810,16 @@ public: // return true if driver support non-power of two textures virtual bool supportNonPowerOfTwoTextures() const =0; + /// \name Multipass Camera Effects. Prefer to use CMultipassCameraEffectManager instead of calling these directly. + // @{ + /// Return the number of installed multipass camera effects. + virtual int getMultipassCameraEffectNb() =0; + /// Return information about a specified multipass camera effect. + virtual const CMultipassCameraEffectInfo *getMultipassCameraEffectInfo(int idx) const =0; + /// Create a multipass camera effect with specified id. + virtual IMultipassCameraEffect *createMultipassCameraEffect(int idx) const =0; + // @} + /** get a part of the ZBuffer (back buffer). * NB: 0,0 is the bottom left corner of the screen. * diff --git a/code/nel/include/nel/3d/multipass_camera_effect_info.h b/code/nel/include/nel/3d/multipass_camera_effect_info.h new file mode 100644 index 000000000..bdc8a2bc7 --- /dev/null +++ b/code/nel/include/nel/3d/multipass_camera_effect_info.h @@ -0,0 +1,89 @@ +/** + * \file multipass_camera_effect_info.h + * \brief CMultipassCameraEffectInfo + * \date 2013-06-16 17:27GMT + * \author Jan Boon (Kaetemi) + * CMultipassCameraEffectInfo + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NEVRAX NEL. + * NEVRAX NEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NEVRAX NEL is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NEVRAX NEL. If not, see + * . + */ + +#ifndef NL3D_MULTIPASS_CAMERA_EFFECT_INFO_H +#define NL3D_MULTIPASS_CAMERA_EFFECT_INFO_H +#include + +// STL includes + +// NeL includes + +// Project includes + +namespace NL3D { + class IMultipassCameraEffect; + +enum TMultipassCameraType +{ + MULTIPASS_CAMERA_UNKNOWN, + /// A multi pass effect used to support stereo displays. + MULTIPASS_CAMERA_STEREO, + /// A multi pass effect which renders at different animation deltas to create a motion blur (experimental). + MULTIPASS_CAMERA_MOTION_BLUR, + /// A multi pass effect which renders with modified camera settings to create depth of field (experimental). + MULTIPASS_CAMERA_DEPTH_OF_FIELD, + // etc. +}; + +/** + * \brief CMultipassCameraEffectInfo + * \date 2013-06-16 17:27GMT + * \author Jan Boon (Kaetemi) + * Information on a multi pass camera effect. + */ +struct CMultipassCameraEffectInfo +{ +public: + CMultipassCameraEffectInfo(); + virtual ~CMultipassCameraEffectInfo(); + + /// Name used in configs etc. Use i18n for storing display name and descriptions. + std::string Name; + + /// Type of multipass. Useful for filtering which ones the user can pick. + TMultipassCameraType Type; + +}; /* class CMultipassCameraEffectInfo */ + +/// Inherit from this class with a class which fills the public +/// information fields and that overrides the create() method. +/// Driver has list of installed IMultipassCameraEffectInfoPriv. +struct IMultipassCameraEffectInfoPriv : public CMultipassCameraEffectInfo +{ +public: + IMultipassCameraEffectInfoPriv(); + virtual ~IMultipassCameraEffectInfoPriv(); + + virtual IMultipassCameraEffect *create() const = 0; +}; + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_MULTIPASS_CAMERA_EFFECT_INFO_H */ + +/* end of file */ diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index 412cb52da..d92cd1ffd 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -2999,6 +2999,26 @@ bool CDriverD3D::supportNonPowerOfTwoTextures() const // *************************************************************************** +int CDriverD3D::getMultipassCameraEffectNb() +{ + // Screw D3D. + return 0; +} + +const NL3D::CMultipassCameraEffectInfo *CDriverD3D::getMultipassCameraEffectInfo(int idx) const +{ + // Screw D3D. + return NULL; +} + +NL3D::IMultipassCameraEffect *CDriverD3D::createMultipassCameraEffect(int idx) const +{ + // Screw D3D. + return NULL; +} + +// *************************************************************************** + bool CDriverD3D::fillBuffer (NLMISC::CBitmap &bitmap) { H_AUTO_D3D(CDriverD3D_fillBuffer); diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index cff7cb804..992a0efdd 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -832,6 +832,10 @@ public: // return true if driver support non-power of two textures virtual bool supportNonPowerOfTwoTextures() const; + virtual int getMultipassCameraEffectNb(); + virtual const CMultipassCameraEffectInfo *getMultipassCameraEffectInfo(int idx) const; + virtual IMultipassCameraEffect *createMultipassCameraEffect(int idx) const; + // copy the first texture in a second one of different dimensions virtual bool stretchRect (ITexture * srcText, NLMISC::CRect &srcRect, ITexture * destText, NLMISC::CRect &destRect); // Only 32 bits back buffer supported virtual bool isTextureRectangle(ITexture * /* tex */) const {return false;} diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 29e14a1a0..a8a59aae0 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -27,6 +27,7 @@ #include "nel/3d/vertex_buffer.h" #include "nel/3d/light.h" #include "nel/3d/index_buffer.h" +#include "nel/3d/multipass_camera_effect_info.h" #include "nel/misc/rect.h" #include "nel/misc/di_event_emitter.h" #include "nel/misc/mouse_device.h" @@ -699,6 +700,34 @@ bool CDriverGL::supportNonPowerOfTwoTextures() const return _Extensions.ARBTextureNonPowerOfTwo; } +// *************************************************************************** + +void CDriverGL::initMultipassCameraEffectInfos() +{ + if (m_MultipassCameraEffectInfos.size() == 0) + { + // Add pointers to static class instances to the list. + } +} + +int CDriverGL::getMultipassCameraEffectNb() +{ + initMultipassCameraEffectInfos(); + return m_MultipassCameraEffectInfos.size(); +} + +const NL3D::CMultipassCameraEffectInfo *CDriverGL::getMultipassCameraEffectInfo(int idx) const +{ + nlassert(idx < m_MultipassCameraEffectInfos.size()); + return static_cast(m_MultipassCameraEffectInfos[idx]); +} + +NL3D::IMultipassCameraEffect *CDriverGL::createMultipassCameraEffect(int idx) const +{ + nlassert(idx < m_MultipassCameraEffectInfos.size()); + return m_MultipassCameraEffectInfos[idx]->create(); +} + // *************************************************************************** bool CDriverGL::isTextureRectangle(ITexture * tex) const { diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index bfe73492d..24c9b6688 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -556,6 +556,10 @@ public: // return true if driver support non-power of two textures virtual bool supportNonPowerOfTwoTextures() const; + virtual int getMultipassCameraEffectNb(); + virtual const CMultipassCameraEffectInfo *getMultipassCameraEffectInfo(int idx) const; + virtual IMultipassCameraEffect *createMultipassCameraEffect(int idx) const; + virtual bool activeFrameBufferObject(ITexture * tex); virtual void getZBufferPart (std::vector &zbuffer, NLMISC::CRect &rect); @@ -1491,6 +1495,9 @@ private: */ inline void setupTextureBasicParameters(ITexture &tex); + /// Multipass Camera Effects + void initMultipassCameraEffectInfos(); + std::vector m_MultipassCameraEffectInfos; }; // *************************************************************************** diff --git a/code/nel/src/3d/multipass_camera_effect_info.cpp b/code/nel/src/3d/multipass_camera_effect_info.cpp new file mode 100644 index 000000000..971dca52b --- /dev/null +++ b/code/nel/src/3d/multipass_camera_effect_info.cpp @@ -0,0 +1,65 @@ +/** + * \file multipass_camera_effect_info.cpp + * \brief CMultipassCameraEffectInfo + * \date 2013-06-16 17:27GMT + * \author Jan Boon (Kaetemi) + * CMultipassCameraEffectInfo + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NEVRAX NEL. + * NEVRAX NEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NEVRAX NEL is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NEVRAX NEL. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +CMultipassCameraEffectInfo::CMultipassCameraEffectInfo() +{ + +} + +CMultipassCameraEffectInfo::~CMultipassCameraEffectInfo() +{ + +} + +IMultipassCameraEffectInfoPriv::IMultipassCameraEffectInfoPriv() +{ + +} + +IMultipassCameraEffectInfoPriv::~IMultipassCameraEffectInfoPriv() +{ + +} + +} /* namespace NL3D */ + +/* end of file */ From f1f06da75f026308ae1f6bb11da43d4d8fc76baf Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 16 Jun 2013 23:48:40 +0200 Subject: [PATCH 002/137] Allow configuration of bloom settings from config files in snowballs --- code/snowballs2/client/src/snowballs_client.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index c5cb73072..76338cfa5 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -179,6 +179,8 @@ void releaseIngame(); void releaseOnline(); void releaseOffline(); void cbGraphicsDriver(CConfigFile::CVar &var); +void cbSquareBloom(CConfigFile::CVar &var); +void cbDensityBloom(CConfigFile::CVar &var); // // Functions @@ -362,6 +364,8 @@ void initIngame() CBloomEffect::instance().setDriver(Driver); CBloomEffect::instance().setScene(Scene); CBloomEffect::instance().init(ConfigFile->getVar("OpenGL").asInt() == 1); + CConfiguration::setAndCallback("SquareBloom", cbSquareBloom); + CConfiguration::setAndCallback("DensityBloom", cbDensityBloom); // Init the landscape using the previously created UScene displayLoadingState("Initialize Landscape"); @@ -562,6 +566,8 @@ void releaseIngame() MouseListener = NULL; // release bloom effect + CConfiguration::dropCallback("SquareBloom"); + CConfiguration::dropCallback("DensityBloom"); CBloomEffect::instance().releaseInstance(); Driver->deleteScene(Scene); @@ -884,6 +890,16 @@ void cbGraphicsDriver(CConfigFile::CVar &var) NextGameState = GameStateReset; } +void cbSquareBloom(CConfigFile::CVar &var) +{ + CBloomEffect::instance().setSquareBloom(var.asBool()); +} + +void cbDensityBloom(CConfigFile::CVar &var) +{ + CBloomEffect::instance().setDensityBloom((uint8)(var.asInt() & 0xFF)); +} + // // Loading state procedure // From 09df2d8befd10503aa84b87ba0d399294c8a234d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 16 Jun 2013 23:49:45 +0200 Subject: [PATCH 003/137] Remove silly heap allocation of a null pointer --- code/nel/src/3d/bloom_effect.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 7cbb48310..f3a13946a 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -475,9 +475,8 @@ void CBloomEffect::endInterfacesDisplayBloom() // clientcfg return; NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); - CTextureUser *txt = new CTextureUser(); - ((CDriverUser *)_Driver)->setRenderTarget(*txt, 0, 0, 0, 0); - delete txt; + CTextureUser txtNull; + ((CDriverUser *)_Driver)->setRenderTarget(txtNull, 0, 0, 0, 0); // initialize texture coordinates float newU = drvInternal->isTextureRectangle(_InitText) ? (float)_WndWidth : 1.f; From 968e0579feca299507f7a25c1ebcf1d5f81cad2f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 16 Jun 2013 23:51:33 +0200 Subject: [PATCH 004/137] Allow stepping through the time delta in multiple passes in snowballs --- code/snowballs2/client/src/game_time.cpp | 31 ++++++++++++++----- code/snowballs2/client/src/game_time.h | 3 ++ .../client/src/snowballs_client.cpp | 1 + 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/code/snowballs2/client/src/game_time.cpp b/code/snowballs2/client/src/game_time.cpp index 62bfc2b2b..c6b1ff62c 100644 --- a/code/snowballs2/client/src/game_time.cpp +++ b/code/snowballs2/client/src/game_time.cpp @@ -42,6 +42,14 @@ static bool _SkipAnimationOnce; static NLMISC::TTime _TimeMs; static CValueSmootherTemplate _FpsSmoother; +namespace +{ + +NLMISC::TLocalTime a_LocalTimeDelta; +NL3D::TGlobalAnimationTime a_AnimationTimeDelta; + +} /* anonymous namespace */ + static void cbFpsSmoothing(CConfigFile::CVar &var) { _FpsSmoother.init((uint)var.asInt()); @@ -53,8 +61,10 @@ void CGameTime::init() _TimeMs = NLMISC::CTime::getLocalTime(); LocalTime = ((TLocalTime)_TimeMs) / 1000.0; LocalTimeDelta = 0.0; + a_LocalTimeDelta = 0.0; AnimationTime = 0.0; AnimationTimeDelta = 0.f; + a_AnimationTimeDelta = 0.0; FramesPerSecond = 0.f; FramesPerSecondSmooth = 0.f; CConfiguration::setAndCallback("FpsSmoothing", cbFpsSmoothing); @@ -78,26 +88,24 @@ void CGameTime::updateTime() // average of previous fps and this fps should be ok FramesPerSecond *= 3; - LocalTimeDelta = 0.f; - AnimationTimeDelta = 0.f; + a_LocalTimeDelta = 0.f; + a_AnimationTimeDelta = 0.f; } else { FramesPerSecond = 1000.0f / (float)deltams; TLocalTime localTime = ((TLocalTime)timems) / 1000.0; - LocalTimeDelta = localTime - LocalTime; - LocalTime = localTime; + a_LocalTimeDelta = localTime - LocalTime; if (_SkipAnimationOnce) { - AnimationTimeDelta = 0.f; + a_AnimationTimeDelta = 0.f; _SkipAnimationOnce = false; } else { - AnimationTimeDelta = (TAnimationTime)LocalTimeDelta; - AnimationTime += (TGlobalAnimationTime)LocalTimeDelta; + a_AnimationTimeDelta = (TGlobalAnimationTime)a_LocalTimeDelta; } } @@ -105,6 +113,15 @@ void CGameTime::updateTime() FramesPerSecondSmooth = _FpsSmoother.getSmoothValue(); } +void CGameTime::advanceTime(double f) +{ + LocalTimeDelta = a_LocalTimeDelta * f; + LocalTime += LocalTimeDelta; + TGlobalAnimationTime atd = a_AnimationTimeDelta * f; + AnimationTimeDelta = (NL3D::TAnimationTime)atd; + AnimationTime += atd; +} + void CGameTime::skipAnimationOnce() { _SkipAnimationOnce = true; diff --git a/code/snowballs2/client/src/game_time.h b/code/snowballs2/client/src/game_time.h index 72a671d43..7cf4ec827 100644 --- a/code/snowballs2/client/src/game_time.h +++ b/code/snowballs2/client/src/game_time.h @@ -40,6 +40,9 @@ public: static void updateTime(); + /// Advance time to target time by factor f. + static void advanceTime(double f); + /// Used when loading, this will skip changing animation time on the next update /// (updates aren't called during loading) static void skipAnimationOnce(); diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 76338cfa5..1d7fefd60 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -679,6 +679,7 @@ void loopIngame() // 02. Update Time (deltas) CGameTime::updateTime(); + CGameTime::advanceTime(1.0); // 03. Update Input (keyboard controls, etc) Driver->EventServer.pump(); // Pump user input messages From 23e3393d2ef34431bc91739577db8836f823a621 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 17 Jun 2013 00:45:17 +0200 Subject: [PATCH 005/137] Allow rendering with bloom to a user provided render target (untested) (#43) --- code/nel/include/nel/3d/bloom_effect.h | 5 +- code/nel/src/3d/bloom_effect.cpp | 71 +++++++++++++++++--------- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/code/nel/include/nel/3d/bloom_effect.h b/code/nel/include/nel/3d/bloom_effect.h index 77673741c..f5da7a4dd 100644 --- a/code/nel/include/nel/3d/bloom_effect.h +++ b/code/nel/include/nel/3d/bloom_effect.h @@ -83,6 +83,7 @@ public: // If window size exceeds 256*256 the textures used to apply blur are reinitialized with // 256*256 size. If a dimension is less than 256, the texture is initialized with the nearer // power of 2, lower than this window dimension. + void initBloom(UTexture &renderTarget); void initBloom(); // Called at the end of renderAll method in the main loop, recover stretched texture, apply @@ -131,13 +132,15 @@ private: uint8 _DensityBloom; // render target textures - // used to display scene + // used to display scene (FIXME: redundant when user render target provided...) NLMISC::CSmartPtr _InitText; // used as stretched texture from _InitText, as displayed texture in first blur pass, // and as render target in second blur pass. NLMISC::CSmartPtr _BlurFinalTex; // used as render target in first blur pass, and as displayed texture on second blur pass. NLMISC::CSmartPtr _BlurHorizontalTex; + /// User provided render target. + NLMISC::CSmartPtr m_UserRenderTarget; // materials diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index f3a13946a..0bc9c1e41 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -271,11 +271,19 @@ void CBloomEffect::initTexture(CSmartPtr & tex, bool isMode2D, uint32 //----------------------------------------------------------------------------------------------------------- -void CBloomEffect::initBloom() // clientcfg +void CBloomEffect::initBloom() +{ + CTextureUser cu; + initBloom(cu); +} + +void CBloomEffect::initBloom(UTexture &renderTarget) // clientcfg { if(!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) return; + m_UserRenderTarget = dynamic_cast(renderTarget).getITexture(); + // don't activate bloom when PolygonMode is different from Filled if (_Driver->getPolygonMode() != UDriver::Filled) return; @@ -348,14 +356,25 @@ void CBloomEffect::initBloom() // clientcfg _DisplaySquareBlurMat.getObjectPtr()->setTexture(1, _BlurFinalTex); } } + + // For now the user target must be the window size + // to be compatible with the existing code. + // TODO: Instead, if user render target is provided, + // assume the size of the user render target as + // the screen size to be used. + if (m_UserRenderTarget.getPtr()) + { + nlassert(_WndWidth == m_UserRenderTarget->getWidth()); + nlassert(_WndHeight == m_UserRenderTarget->getHeight()); + _DisplayInitMat.getObjectPtr()->setTexture(0, m_UserRenderTarget); + } - NL3D::CTextureUser *txt = (_InitBloomEffect) ? (new CTextureUser(_InitText)) : (new CTextureUser()); - if(!((CDriverUser *) _Driver)->setRenderTarget(*txt, 0, 0, _WndWidth, _WndHeight)) + NL3D::CTextureUser txt = (_InitBloomEffect) ? (CTextureUser(m_UserRenderTarget.getPtr() ? m_UserRenderTarget : _InitText)) : (CTextureUser()); + if(!((CDriverUser *) _Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)) { nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); return; } - delete txt; } //----------------------------------------------------------------------------------------------------------- @@ -371,13 +390,13 @@ void CBloomEffect::endBloom() // clientcfg if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0) return; - CTextureUser *txt1 = (_InitBloomEffect) ? (new CTextureUser(_InitText)) : (new CTextureUser()); - CTextureUser *txt2 = new CTextureUser(_BlurFinalTex); - CRect *rect1 = new CRect(0, 0, _WndWidth, _WndHeight); - CRect *rect2 = new CRect(0, 0, _BlurWidth, _BlurHeight); + CTextureUser txt1 = (_InitBloomEffect) ? (CTextureUser(m_UserRenderTarget.getPtr() ? m_UserRenderTarget : _InitText)) : (CTextureUser()); + CTextureUser txt2(_BlurFinalTex); + CRect rect1(0, 0, _WndWidth, _WndHeight); + CRect rect2(0, 0, _BlurWidth, _BlurHeight); // stretch rect - ((CDriverUser *) _Driver)->stretchRect(_Scene, *txt1 , *rect1, - *txt2, *rect2); + ((CDriverUser *) _Driver)->stretchRect(_Scene, txt1 , rect1, + txt2, rect2); // horizontal blur pass doBlur(true); @@ -387,10 +406,6 @@ void CBloomEffect::endBloom() // clientcfg // apply blur with a blend operation applyBlur(); - delete txt1; - delete txt2; - delete rect1; - delete rect2; } //----------------------------------------------------------------------------------------------------------- @@ -402,13 +417,12 @@ void CBloomEffect::applyBlur() // in opengl, display in init texture if(_InitBloomEffect) { - CTextureUser *txt = new CTextureUser(_InitText); - if(!((CDriverUser *) _Driver)->setRenderTarget(*txt, 0, 0, _WndWidth, _WndHeight)) + CTextureUser txt(m_UserRenderTarget.getPtr() ? m_UserRenderTarget : _InitText); + if(!((CDriverUser *) _Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)) { nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); return; } - delete txt; } // display blur texture @@ -463,7 +477,9 @@ void CBloomEffect::applyBlur() void CBloomEffect::endInterfacesDisplayBloom() // clientcfg { - if(_InitBloomEffect) + // Render from render target to screen if necessary. + // Don't do this when the blend was done to the screen or when rendering to a user provided rendertarget. + if (_InitBloomEffect && m_UserRenderTarget.isNull()) { if(!_Driver->supportBloomEffect() || !_Init) return; @@ -496,6 +512,15 @@ void CBloomEffect::endInterfacesDisplayBloom() // clientcfg _Driver->drawQuad(_DisplayQuad, _DisplayInitMat); _Driver->setMatrixMode3D(pCam); } + + if (m_UserRenderTarget.getPtr()) + { + if (_InitBloomEffect) + { + _DisplayInitMat.getObjectPtr()->setTexture(0, _InitText); + } + m_UserRenderTarget = NULL; + } } @@ -522,14 +547,13 @@ void CBloomEffect::doBlur(bool horizontalBlur) } NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); - CTextureUser *txt = new CTextureUser(endTexture); + CTextureUser txt(endTexture); // initialize render target - if(!((CDriverUser *) _Driver)->setRenderTarget(*txt, 0, 0, _BlurWidth, _BlurHeight)) + if(!((CDriverUser *) _Driver)->setRenderTarget(txt, 0, 0, _BlurWidth, _BlurHeight)) { nlwarning("setRenderTarget return false with blur texture for bloom effect\n"); return; } - delete txt; // initialize vertex program drvInternal->activeVertexProgram(&TextureOffsetVertexProgram); @@ -578,10 +602,9 @@ void CBloomEffect::doBlur(bool horizontalBlur) // disable render target and vertex program drvInternal->activeVertexProgram(NULL); - txt = new CTextureUser(); - ((CDriverUser *)_Driver)->setRenderTarget(*txt, 0, 0, 0, 0); + CTextureUser cu; + ((CDriverUser *)_Driver)->setRenderTarget(cu, 0, 0, 0, 0); _Driver->setMatrixMode3D(pCam); - delete txt; } }; // NL3D From ad6cc747b96b1810414adba36085c6a27e8bbb66 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 01:03:20 +0200 Subject: [PATCH 006/137] Backed out changeset ea4b76b7213a, bad approach --- code/nel/include/nel/3d/driver.h | 13 --- .../nel/3d/multipass_camera_effect_info.h | 89 ------------------- .../3d/driver/direct3d/driver_direct3d.cpp | 20 ----- .../src/3d/driver/direct3d/driver_direct3d.h | 4 - .../src/3d/driver/opengl/driver_opengl.cpp | 29 ------ code/nel/src/3d/driver/opengl/driver_opengl.h | 7 -- .../src/3d/multipass_camera_effect_info.cpp | 65 -------------- 7 files changed, 227 deletions(-) delete mode 100644 code/nel/include/nel/3d/multipass_camera_effect_info.h delete mode 100644 code/nel/src/3d/multipass_camera_effect_info.cpp diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 6630be4ca..d090d77da 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -66,9 +66,6 @@ class CScissor; class CViewport; struct CMonitorColorProperties; struct IOcclusionQuery; -class CMultipassCameraEffectInfo; -class IMultipassCameraEffectInfoPriv; -class IMultipassCameraEffect; @@ -810,16 +807,6 @@ public: // return true if driver support non-power of two textures virtual bool supportNonPowerOfTwoTextures() const =0; - /// \name Multipass Camera Effects. Prefer to use CMultipassCameraEffectManager instead of calling these directly. - // @{ - /// Return the number of installed multipass camera effects. - virtual int getMultipassCameraEffectNb() =0; - /// Return information about a specified multipass camera effect. - virtual const CMultipassCameraEffectInfo *getMultipassCameraEffectInfo(int idx) const =0; - /// Create a multipass camera effect with specified id. - virtual IMultipassCameraEffect *createMultipassCameraEffect(int idx) const =0; - // @} - /** get a part of the ZBuffer (back buffer). * NB: 0,0 is the bottom left corner of the screen. * diff --git a/code/nel/include/nel/3d/multipass_camera_effect_info.h b/code/nel/include/nel/3d/multipass_camera_effect_info.h deleted file mode 100644 index bdc8a2bc7..000000000 --- a/code/nel/include/nel/3d/multipass_camera_effect_info.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * \file multipass_camera_effect_info.h - * \brief CMultipassCameraEffectInfo - * \date 2013-06-16 17:27GMT - * \author Jan Boon (Kaetemi) - * CMultipassCameraEffectInfo - */ - -/* - * Copyright (C) 2013 by authors - * - * This file is part of NEVRAX NEL. - * NEVRAX NEL is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * NEVRAX NEL is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with NEVRAX NEL. If not, see - * . - */ - -#ifndef NL3D_MULTIPASS_CAMERA_EFFECT_INFO_H -#define NL3D_MULTIPASS_CAMERA_EFFECT_INFO_H -#include - -// STL includes - -// NeL includes - -// Project includes - -namespace NL3D { - class IMultipassCameraEffect; - -enum TMultipassCameraType -{ - MULTIPASS_CAMERA_UNKNOWN, - /// A multi pass effect used to support stereo displays. - MULTIPASS_CAMERA_STEREO, - /// A multi pass effect which renders at different animation deltas to create a motion blur (experimental). - MULTIPASS_CAMERA_MOTION_BLUR, - /// A multi pass effect which renders with modified camera settings to create depth of field (experimental). - MULTIPASS_CAMERA_DEPTH_OF_FIELD, - // etc. -}; - -/** - * \brief CMultipassCameraEffectInfo - * \date 2013-06-16 17:27GMT - * \author Jan Boon (Kaetemi) - * Information on a multi pass camera effect. - */ -struct CMultipassCameraEffectInfo -{ -public: - CMultipassCameraEffectInfo(); - virtual ~CMultipassCameraEffectInfo(); - - /// Name used in configs etc. Use i18n for storing display name and descriptions. - std::string Name; - - /// Type of multipass. Useful for filtering which ones the user can pick. - TMultipassCameraType Type; - -}; /* class CMultipassCameraEffectInfo */ - -/// Inherit from this class with a class which fills the public -/// information fields and that overrides the create() method. -/// Driver has list of installed IMultipassCameraEffectInfoPriv. -struct IMultipassCameraEffectInfoPriv : public CMultipassCameraEffectInfo -{ -public: - IMultipassCameraEffectInfoPriv(); - virtual ~IMultipassCameraEffectInfoPriv(); - - virtual IMultipassCameraEffect *create() const = 0; -}; - -} /* namespace NL3D */ - -#endif /* #ifndef NL3D_MULTIPASS_CAMERA_EFFECT_INFO_H */ - -/* end of file */ diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index d92cd1ffd..412cb52da 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -2999,26 +2999,6 @@ bool CDriverD3D::supportNonPowerOfTwoTextures() const // *************************************************************************** -int CDriverD3D::getMultipassCameraEffectNb() -{ - // Screw D3D. - return 0; -} - -const NL3D::CMultipassCameraEffectInfo *CDriverD3D::getMultipassCameraEffectInfo(int idx) const -{ - // Screw D3D. - return NULL; -} - -NL3D::IMultipassCameraEffect *CDriverD3D::createMultipassCameraEffect(int idx) const -{ - // Screw D3D. - return NULL; -} - -// *************************************************************************** - bool CDriverD3D::fillBuffer (NLMISC::CBitmap &bitmap) { H_AUTO_D3D(CDriverD3D_fillBuffer); diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 992a0efdd..cff7cb804 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -832,10 +832,6 @@ public: // return true if driver support non-power of two textures virtual bool supportNonPowerOfTwoTextures() const; - virtual int getMultipassCameraEffectNb(); - virtual const CMultipassCameraEffectInfo *getMultipassCameraEffectInfo(int idx) const; - virtual IMultipassCameraEffect *createMultipassCameraEffect(int idx) const; - // copy the first texture in a second one of different dimensions virtual bool stretchRect (ITexture * srcText, NLMISC::CRect &srcRect, ITexture * destText, NLMISC::CRect &destRect); // Only 32 bits back buffer supported virtual bool isTextureRectangle(ITexture * /* tex */) const {return false;} diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index a8a59aae0..29e14a1a0 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -27,7 +27,6 @@ #include "nel/3d/vertex_buffer.h" #include "nel/3d/light.h" #include "nel/3d/index_buffer.h" -#include "nel/3d/multipass_camera_effect_info.h" #include "nel/misc/rect.h" #include "nel/misc/di_event_emitter.h" #include "nel/misc/mouse_device.h" @@ -700,34 +699,6 @@ bool CDriverGL::supportNonPowerOfTwoTextures() const return _Extensions.ARBTextureNonPowerOfTwo; } -// *************************************************************************** - -void CDriverGL::initMultipassCameraEffectInfos() -{ - if (m_MultipassCameraEffectInfos.size() == 0) - { - // Add pointers to static class instances to the list. - } -} - -int CDriverGL::getMultipassCameraEffectNb() -{ - initMultipassCameraEffectInfos(); - return m_MultipassCameraEffectInfos.size(); -} - -const NL3D::CMultipassCameraEffectInfo *CDriverGL::getMultipassCameraEffectInfo(int idx) const -{ - nlassert(idx < m_MultipassCameraEffectInfos.size()); - return static_cast(m_MultipassCameraEffectInfos[idx]); -} - -NL3D::IMultipassCameraEffect *CDriverGL::createMultipassCameraEffect(int idx) const -{ - nlassert(idx < m_MultipassCameraEffectInfos.size()); - return m_MultipassCameraEffectInfos[idx]->create(); -} - // *************************************************************************** bool CDriverGL::isTextureRectangle(ITexture * tex) const { diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 24c9b6688..bfe73492d 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -556,10 +556,6 @@ public: // return true if driver support non-power of two textures virtual bool supportNonPowerOfTwoTextures() const; - virtual int getMultipassCameraEffectNb(); - virtual const CMultipassCameraEffectInfo *getMultipassCameraEffectInfo(int idx) const; - virtual IMultipassCameraEffect *createMultipassCameraEffect(int idx) const; - virtual bool activeFrameBufferObject(ITexture * tex); virtual void getZBufferPart (std::vector &zbuffer, NLMISC::CRect &rect); @@ -1495,9 +1491,6 @@ private: */ inline void setupTextureBasicParameters(ITexture &tex); - /// Multipass Camera Effects - void initMultipassCameraEffectInfos(); - std::vector m_MultipassCameraEffectInfos; }; // *************************************************************************** diff --git a/code/nel/src/3d/multipass_camera_effect_info.cpp b/code/nel/src/3d/multipass_camera_effect_info.cpp deleted file mode 100644 index 971dca52b..000000000 --- a/code/nel/src/3d/multipass_camera_effect_info.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/** - * \file multipass_camera_effect_info.cpp - * \brief CMultipassCameraEffectInfo - * \date 2013-06-16 17:27GMT - * \author Jan Boon (Kaetemi) - * CMultipassCameraEffectInfo - */ - -/* - * Copyright (C) 2013 by authors - * - * This file is part of NEVRAX NEL. - * NEVRAX NEL is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * NEVRAX NEL is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with NEVRAX NEL. If not, see - * . - */ - -#include -#include - -// STL includes - -// NeL includes -// #include - -// Project includes - -using namespace std; -// using namespace NLMISC; - -namespace NL3D { - -CMultipassCameraEffectInfo::CMultipassCameraEffectInfo() -{ - -} - -CMultipassCameraEffectInfo::~CMultipassCameraEffectInfo() -{ - -} - -IMultipassCameraEffectInfoPriv::IMultipassCameraEffectInfoPriv() -{ - -} - -IMultipassCameraEffectInfoPriv::~IMultipassCameraEffectInfoPriv() -{ - -} - -} /* namespace NL3D */ - -/* end of file */ From fd42d61af990e01b3f28b2ec769f96d436be7f69 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 01:14:30 +0200 Subject: [PATCH 007/137] Add some files from old nevrax shader code for exposing pixel programs in the drivers --- code/nel/include/nel/3d/pixel_program.h | 86 +++ .../driver_direct3d_pixel_program.cpp | 305 ++++++++++ .../opengl/driver_opengl_pixel_program.cpp | 553 ++++++++++++++++++ code/nel/src/3d/pixel_program.cpp | 62 ++ 4 files changed, 1006 insertions(+) create mode 100644 code/nel/include/nel/3d/pixel_program.h create mode 100644 code/nel/src/3d/driver/direct3d/driver_direct3d_pixel_program.cpp create mode 100644 code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp create mode 100644 code/nel/src/3d/pixel_program.cpp diff --git a/code/nel/include/nel/3d/pixel_program.h b/code/nel/include/nel/3d/pixel_program.h new file mode 100644 index 000000000..35731ca6d --- /dev/null +++ b/code/nel/include/nel/3d/pixel_program.h @@ -0,0 +1,86 @@ +/** \file pixel_program.h + * Pixel program definition + * + * $Id: pixel_program.h,v 1.1.2.3 2007/07/06 15:58:45 legallo Exp $ + */ + +/* Copyright, 2000, 2001 Nevrax Ltd. + * + * This file is part of NEVRAX NEL. + * NEVRAX NEL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + + * NEVRAX NEL is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with NEVRAX NEL; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef NL_PIXEL_PROGRAM_H +#define NL_PIXEL_PROGRAM_H + +#include "program.h" + +#include "nel/misc/types_nl.h" +#include "nel/misc/smart_ptr.h" + +#include + +#define PIXEL_SHADER_PROFILE "ps_2_0" + +namespace NL3D { + +// List typedef. +class IDriver; +class IPixelProgramDrvInfos; +typedef std::list TPixelPrgDrvInfoPtrList; +typedef TPixelPrgDrvInfoPtrList::iterator ItPixelPrgDrvInfoPtrList; + +// Class for interaction of pixel program with Driver. +// IPixelProgramDrvInfos represent the real data of the pixel program, stored into the driver. +class IPixelProgramDrvInfos : public NLMISC::CRefCount +{ +private: + IDriver *_Driver; + ItPixelPrgDrvInfoPtrList _DriverIterator; + +public: + IPixelProgramDrvInfos (IDriver *drv, ItPixelPrgDrvInfoPtrList it); + // The virtual dtor is important. + virtual ~IPixelProgramDrvInfos(void); +}; + + +//------------------------------------------------------------------------------- +class CPixelProgram : public IProgram +{ +public: + + /// Constructor + CPixelProgram (const char* program, bool isEffectPrg=false); + + /// Destructor + virtual ~CPixelProgram (); + + /// The driver informations. For the driver implementation only. + NLMISC::CRefPtr _DrvInfo; + + const char * getASMProfile() { return PIXEL_SHADER_PROFILE; } ; + + static const char * getPixelASMProfile() { return PIXEL_SHADER_PROFILE; } ; +}; + + +} // NL3D + + +#endif // NL_PIXEL_PROGRAM_H + +/* End of vertex_program.h */ 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 new file mode 100644 index 000000000..755592043 --- /dev/null +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_pixel_program.cpp @@ -0,0 +1,305 @@ +/** \file driver_direct3d_pixel_program.cpp + * Direct 3d driver implementation + * + * $Id: driver_direct3d_pixel_program.cpp,v 1.1.2.4 2007/07/09 15:26:35 legallo Exp $ + * + * \todo manage better the init/release system (if a throw occurs in the init, we must release correctly the driver) + */ + +/* Copyright, 2000 Nevrax Ltd. + * + * This file is part of NEVRAX NEL. + * NEVRAX NEL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + + * NEVRAX NEL is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with NEVRAX NEL; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "stddirect3d.h" + +#include "driver_direct3d.h" + +using namespace std; +using namespace NLMISC; + +namespace NL3D +{ + +// *************************************************************************** + +CPixelProgramDrvInfosD3D::CPixelProgramDrvInfosD3D(IDriver *drv, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it) +{ + H_AUTO_D3D(CPixelProgramDrvInfosD3D_CPixelProgamDrvInfosD3D) + Shader = NULL; +} + +// *************************************************************************** + +CPixelProgramDrvInfosD3D::~CPixelProgramDrvInfosD3D() +{ + H_AUTO_D3D(CPixelProgramDrvInfosD3D_CPixelProgramDrvInfosD3DDtor) + if (Shader) + Shader->Release(); +} + +// *************************************************************************** + +bool CDriverD3D::isPixelProgramSupported () const +{ + H_AUTO_D3D(CDriverD3D_isPixelProgramSupported ) + return _PixelProgram; +} + +// *************************************************************************** + +bool CDriverD3D::activePixelProgram(CPixelProgram *program) +{ + H_AUTO_D3D(CDriverD3D_activePixelProgram ) + if (_DisableHardwarePixelProgram) + return false; + + // Setup or unsetup ? + if (program) + { + // Program setuped ? + if (program->_DrvInfo==NULL) + { + _PixelPrgDrvInfos.push_front (NULL); + ItPixelPrgDrvInfoPtrList itPix = _PixelPrgDrvInfos.begin(); + *itPix = new CPixelProgramDrvInfosD3D(this, itPix); + + // Create a driver info structure + program->_DrvInfo = *itPix; + + std::string dest; + if(program->isEffectProgram()) + { + dest = program->getProgram(); + } + + LPD3DXBUFFER pShader; + LPD3DXBUFFER pErrorMsgs; + if (D3DXAssembleShader (dest.c_str(), dest.size(), NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK) + { + if (_DeviceInterface->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), &(getPixelProgramD3D(*program)->Shader)) != D3D_OK) + return false; + } + else + { + nlwarning ("Can't assemble pixel program:"); + nlwarning ((const char*)pErrorMsgs->GetBufferPointer()); + return false; + } + } + } + + // Set the pixel program + if (program) + { + CPixelProgramDrvInfosD3D *info = static_cast((IPixelProgramDrvInfos*)program->_DrvInfo); + setPixelShader (info->Shader); + + float z = 0; + float o = 1; + setRenderState (D3DRS_FOGSTART, *((DWORD*) (&o))); + setRenderState (D3DRS_FOGEND, *((DWORD*) (&z))); + } + else + { + setPixelShader (NULL); + + // Set the old fog range + setRenderState (D3DRS_FOGSTART, *((DWORD*) (&_FogStart))); + setRenderState (D3DRS_FOGEND, *((DWORD*) (&_FogEnd))); + } + + return true; +} + +// *************************************************************************** + +void CDriverD3D::setPixelProgramConstant (uint index, float f0, float f1, float f2, float f3) +{ + H_AUTO_D3D(CDriverD3D_setPixelProgramConstant) + if (!_PixelProgram) + { + #ifdef NL_DEBUG + nlwarning("No pixel programs available!!"); + #endif + return; + } + const float tabl[4] = {f0, f1, f2, f3}; + setPixelShaderConstant (index, tabl); +} + +// *************************************************************************** + +void CDriverD3D::setPixelProgramConstant (uint index, double d0, double d1, double d2, double d3) +{ + H_AUTO_D3D(CDriverD3D_setPixelProgramConstant ) + if (!_PixelProgram) + { + #ifdef NL_DEBUG + nlwarning("No pixel programs available!!"); + #endif + return; + } + const float tabl[4] = {(float)d0, (float)d1, (float)d2, (float)d3}; + setPixelShaderConstant (index, tabl); +} + +// *************************************************************************** + +void CDriverD3D::setPixelProgramConstant (uint index, const NLMISC::CVector& value) +{ + H_AUTO_D3D(CDriverD3D_setPixelProgramConstant ) + if (!_PixelProgram) + { + #ifdef NL_DEBUG + nlwarning("No pixel programs available!!"); + #endif + return; + } + const float tabl[4] = {value.x, value.y, value.z, 0}; + setPixelShaderConstant (index, tabl); +} + +// *************************************************************************** + +void CDriverD3D::setPixelProgramConstant (uint index, const NLMISC::CVectorD& value) +{ + H_AUTO_D3D(CDriverD3D_setPixelProgramConstant ) + if (!_PixelProgram) + { + #ifdef NL_DEBUG + nlwarning("No pixel programs available!!"); + #endif + return; + } + const float tabl[4] = {(float)value.x, (float)value.y, (float)value.z, 0}; + setPixelShaderConstant (index, tabl); +} + +// *************************************************************************** + +void CDriverD3D::setPixelProgramConstant (uint index, uint num, const float *src) +{ + H_AUTO_D3D(CDriverD3D_setPixelProgramConstant ) + if (!_PixelProgram) + { + #ifdef NL_DEBUG + nlwarning("No pixel programs available!!"); + #endif + return; + } + uint i; + for (i=0; i_11, matPtr->_21, matPtr->_31, matPtr->_41); + setPixelProgramConstant (index+1, matPtr->_12, matPtr->_22, matPtr->_32, matPtr->_42); + setPixelProgramConstant (index+2, matPtr->_13, matPtr->_23, matPtr->_33, matPtr->_43); + setPixelProgramConstant (index+3, matPtr->_14, matPtr->_24, matPtr->_34, matPtr->_44); +} + +// *************************************************************************** + +void CDriverD3D::disableHardwarePixelProgram() +{ + H_AUTO_D3D(CDriverD3D_disableHardwarePixelProgram) + _DisableHardwarePixelProgram = true; + _PixelProgram = false; +} + +// *************************************************************************** + +uint CDriverD3D::getMaxTexturesForEffects() const +{ + H_AUTO_D3D(CDriverD3D_getMaxTexturesForEffects) + + // we use ps_2_0 profile for direct3D ASM pixel program, then 16 texture samplers are available + if(!strcmp(CPixelProgram::getPixelASMProfile(), "ps_2_0")) + return 16; + + return 0; +} + +} // NL3D diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp new file mode 100644 index 000000000..7677e6151 --- /dev/null +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -0,0 +1,553 @@ +/** \file driver_opengl_pixel_program.cpp + * OpenGL driver implementation for pixel program manipulation. + * + * $Id: driver_opengl_pixel_program.cpp,v 1.1.2.4 2007/07/09 15:29:00 legallo Exp $ + * + * \todo manage better the init/release system (if a throw occurs in the init, we must release correctly the driver) + */ + +/* Copyright, 2000 Nevrax Ltd. + * + * This file is part of NEVRAX NEL. + * NEVRAX NEL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + + * NEVRAX NEL is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with NEVRAX NEL; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "stdopengl.h" + +#include "driver_opengl.h" +#include "../../index_buffer.h" +#include "../../vertex_program.h" +//#include "../../vertex_program_parse.h" +#include "../../program_parse_D3D.h" +#include + +// tmp +#include "nel/misc/file.h" + +using namespace std; +using namespace NLMISC; + +//#define DEBUG_SETUP_EXT_VERTEX_SHADER + +namespace NL3D +{ + +// *************************************************************************** +CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it) +{ + H_AUTO_OGL(CPixelProgamDrvInfosGL_CPixelProgamDrvInfosGL) + // Extension must exist + nlassert(drv->_Extensions.ARBFragmentProgram); + + if (drv->_Extensions.ARBFragmentProgram) // ARB implementation + { + nglGenProgramsARB(1, &ID); + } +} + +// *************************************************************************** +bool CDriverGL::isPixelProgramSupported () const +{ + H_AUTO_OGL(CPixelProgamDrvInfosGL_isPixelProgramSupported) + return _Extensions.ARBFragmentProgram; +} + +// *************************************************************************** +bool CDriverGL::activePixelProgram(CPixelProgram *program) +{ + H_AUTO_OGL(CDriverGL_activePixelProgram) + + if (_Extensions.ARBFragmentProgram) + { + return activeARBPixelProgram(program); + } + + return false; +} + +// *************************************************************************** +bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) +{ + H_AUTO_OGL(CDriverGL_activeARBPixelProgram) + + // Setup or unsetup ? + if (program) + { + // Driver info + CPixelProgamDrvInfosGL *drvInfo; + + // Program setuped ? + if (program->_DrvInfo==NULL) + { + // Insert into driver list. (so it is deleted when driver is deleted). + ItPixelPrgDrvInfoPtrList it= _PixelPrgDrvInfos.insert(_PixelPrgDrvInfos.end()); + + // Create a driver info + *it = drvInfo = new CPixelProgamDrvInfosGL (this, it); + // Set the pointer + program->_DrvInfo=drvInfo; + + std::string asmProgram; + CPixelProgramParser::CPProgram parsedProgram; + if(program->isEffectProgram()) + { + asmProgram = program->getProgram(); + + CPPParserD3D parser; + // try to parse the program + std::string errorOutput; + bool result = parser.parse(asmProgram.c_str(), parsedProgram, errorOutput); + if (!result) + { + nlwarning("Unable to parse a pixel program."); + #ifdef NL_DEBUG + nlerror(errorOutput.c_str()); + #endif + return false; + } + } + + if(!setupARBPixelProgram(parsedProgram, drvInfo->ID)) + { + delete drvInfo; + program->_DrvInfo = NULL; + _PixelPrgDrvInfos.erase(it); + return false; + } + } + else + { + // Cast the driver info pointer + drvInfo=safe_cast((IPixelProgramDrvInfos*)program->_DrvInfo); + } + glEnable( GL_FRAGMENT_PROGRAM_ARB ); + _PixelProgramEnabled = true; + nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, drvInfo->ID ); + + glDisable( GL_COLOR_SUM_ARB ); // no specular written + + _LastSetuppedPP = program; + } + else + { + glDisable( GL_FRAGMENT_PROGRAM_ARB ); + glDisable( GL_COLOR_SUM_ARB ); + _PixelProgramEnabled = false; + } + + return true; +} + +// *************************************************************************** +bool CDriverGL::setupARBPixelProgram (const CPixelProgramParser::CPProgram &inParsedProgram, GLuint id/*, bool &specularWritten*/) +{ + H_AUTO_OGL(CDriverGL_setupARBPixelProgram) + + // convert from proprietary format to ARB_pixel_program code + CPixelProgramConversionARB vpConvertARB; + std::string code; + if(!vpConvertARB.convert(inParsedProgram, code)) return false; + + // + nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, id); + glGetError(); + nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, code.size(), code.c_str() ); + GLenum err = glGetError(); + if (err != GL_NO_ERROR) + { + if (err == GL_INVALID_OPERATION) + { + GLint position; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &position); + nlassert(position != -1) // there was an error.. + nlassert(position < (GLint) code.size()); + uint line = 0; + const char *lineStart = code.c_str(); + for(uint k = 0; k < (uint) position; ++k) + { + if (code[k] == '\n') + { + lineStart = code.c_str() + k; + ++line; + } + } + nlwarning("ARB fragment program parse error at line %d.", (int) line); + // search end of line + const char *lineEnd = code.c_str() + code.size(); + for(uint k = position; k < code.size(); ++k) + { + if (code[k] == '\n') + { + lineEnd = code.c_str() + k; + break; + } + } + nlwarning(std::string(lineStart, lineEnd).c_str()); + // display the gl error msg + const GLubyte *errorMsg = glGetString(GL_PROGRAM_ERROR_STRING_ARB); + nlassert((const char *) errorMsg); + nlwarning((const char *) errorMsg); + } + nlassert(0); + return false; + } + return true; +} + +// *************************************************************************** + +void CDriverGL::setPixelProgramConstant (uint index, float f0, float f1, float f2, float f3) +{ + H_AUTO_OGL(CDriverGL_setPixelProgramConstant) + + if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + { + if (_Extensions.ARBFragmentProgram) + nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3); + } +} + + +// *************************************************************************** + +void CDriverGL::setPixelProgramConstant (uint index, double d0, double d1, double d2, double d3) +{ + H_AUTO_OGL(CDriverGL_setPixelProgramConstant) + + if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + { + if (_Extensions.ARBFragmentProgram) + nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, d0, d1, d2, d3); + } +} + + +// *************************************************************************** + +void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVector& value) +{ + H_AUTO_OGL(CDriverGL_setPixelProgramConstant) + + if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + { + if (_Extensions.ARBFragmentProgram) + nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0); + } +} + + +// *************************************************************************** + +void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVectorD& value) +{ + H_AUTO_OGL(CDriverGL_setPixelProgramConstant) + + if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + { + if (_Extensions.ARBFragmentProgram) + nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0); + } +} + + +// *************************************************************************** +void CDriverGL::setPixelProgramConstant (uint index, uint num, const float *src) +{ + H_AUTO_OGL(CDriverGL_setPixelProgramConstant) + + if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + { + if (_Extensions.ARBFragmentProgram) + { + for(uint k = 0; k < num; ++k) + { + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k); + } + } + } +} + +// *************************************************************************** +void CDriverGL::setPixelProgramConstant (uint index, uint num, const double *src) +{ + H_AUTO_OGL(CDriverGL_setPixelProgramConstant) + + if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + { + if (_Extensions.ARBFragmentProgram) + { + for(uint k = 0; k < num; ++k) + { + nglProgramEnvParameter4dvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k); + } + } + } +} + +// *************************************************************************** + +void CDriverGL::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform) +{ + H_AUTO_OGL(CDriverGL_setPixelProgramConstantMatrix) + + if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + { + if (_Extensions.ARBFragmentProgram) + { + + // First, ensure that the render setup is correctly setuped. + refreshRenderSetup(); + CMatrix mat; + switch (matrix) + { + case IDriver::ModelView: + mat = _ModelViewMatrix; + break; + case IDriver::Projection: + { + refreshProjMatrixFromGL(); + mat = _GLProjMat; + } + break; + case IDriver::ModelViewProjection: + refreshProjMatrixFromGL(); + mat = _GLProjMat * _ModelViewMatrix; + break; + default: + break; + } + + switch(transform) + { + case IDriver::Identity: break; + case IDriver::Inverse: + mat.invert(); + break; + case IDriver::Transpose: + mat.transpose(); + break; + case IDriver::InverseTranspose: + mat.invert(); + mat.transpose(); + break; + default: + break; + } + mat.transpose(); + float matDatas[16]; + mat.get(matDatas); + + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index, matDatas); + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 1, matDatas + 4); + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 2, matDatas + 8); + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 3, matDatas + 12); + } + } +} + +// *************************************************************************** +uint CDriverGL::getMaxTexturesForEffects() const +{ + H_AUTO_OGL(CDriverGL_getMaxTexturesForEffects) + + uint texSamplerNb = 0; + if (_Extensions.ARBFragmentProgram) // ARB implementation + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, (int*)(&texSamplerNb)); + + return texSamplerNb; +} + +// *************************************************************************** +// ***************** CPixelProgramConversionARB ***************************** +// *************************************************************************** + +const char * CPixelProgramConversionARB::ARBPixelProgramInputRegisterToName[CPPOperand::InputRegisterCount] = +{ + "color.primary", + "color.secondary", + "texcoord[0]", + "texcoord[1]", + "texcoord[2]", + "texcoord[3]", + "texcoord[4]", + "texcoord[5]", + "texcoord[6]", + "texcoord[7]", +}; + +// *************************************************************************** +const char * CPixelProgramConversionARB::ARBPixelProgramOutputRegisterToName[CPPOperand::OutputRegisterCount] = +{ + "color", + "depth" +}; + +// *************************************************************************** +bool CPixelProgramConversionARB::convert(const CPixelProgramParser::CPProgram &inParsedProgram, std::string & code) +{ + CPixelProgramParser::TPProgram parsedProgram = inParsedProgram._Program; + // + code = "!!ARBfp1.0\n"; + // declare temporary registers + GLint glMaxTempVar; + nglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &glMaxTempVar); + uint usedTempVar = inParsedProgram.getUsedVariablesNb(); + if(usedTempVar>glMaxTempVar) + { + nlwarning(" Used temporary registers number is superior to maximum ARB_FRAGMENT_PROGRAM temporaries registers."); + return false; + } + ARBProgramTemporaryRegisters(code, usedTempVar); + // declare constant register + if(!CProgramConversionARB::constantRegisters(inParsedProgram._Constants, code)) return false; + + for(uint k = 0; k < parsedProgram.size(); ++k) + { + std::string instr; + ARBPixelProgramDumpInstr(parsedProgram[k], instr); + code += instr + "\r\n"; + } + code += "END\n"; + + return true; +} + +// *************************************************************************** +// Dump an instruction in a string +void CPixelProgramConversionARB::ARBPixelProgramDumpInstr(const CPPInstruction &instr, std::string &out) +{ + nlassert(instr.Opcode.PPOp < CPPInstruction::OpcodeCount); + // Special case for EXP with a scalar output argument (y component) -> translate to FRC + + out = std::string(); + switch(instr.Opcode.PPOp) + { + case CPPInstruction::ADD: + out = "ADD"; + break; + case CPPInstruction::DP3: + out = "DP3"; + break; + case CPPInstruction::DP4: + out = "DP4"; + break; + case CPPInstruction::EXP: + out = "EXP"; + break; + case CPPInstruction::FRC: + out = "FRC"; + break; + case CPPInstruction::LOG: + out = "LOG"; + break; + case CPPInstruction::MAD: + out = "MAD"; + break; + case CPPInstruction::MAX: + out = "MAX"; + break; + case CPPInstruction::MIN: + out = "MIN"; + break; + case CPPInstruction::MOV: + out = "MOV"; + break; + case CPPInstruction::MUL: + out = "MUL"; + break; + case CPPInstruction::RCP: + out = "RCP"; + break; + case CPPInstruction::RSQ: + out = "RSQ"; + break; + case CPPInstruction::SUB: + out = "SUB"; + break; + case CPPInstruction::ABS: + out = "ABS"; + break; + case CPPInstruction::CMP: + out = "CMP"; + break; + case CPPInstruction::CRS: + out = "XPD"; + break; + case CPPInstruction::LRP: + out = "LRP"; + break; + case CPPInstruction::POW: + out = "POW"; + break; + case CPPInstruction::TEX: + out = "TEX"; + break; + case CPPInstruction::TEXB: + out = "TXB"; + break; + case CPPInstruction::TEXP: + out = "TXP"; + break; + default: + nlwarning("no match with a ARB Pixel Program Operator"); + break; + } + + if(instr.Sat) out += "_SAT"; + out += " "; + uint nbOp = instr.getNumUsedSrc(); + std::string destOperand; + ARBPixelProgramDumpOperand(instr.Dest, true, destOperand); + out += destOperand; + for(uint k = 0; k < nbOp; ++k) + { + out += ", "; + std::string srcOperand; + ARBPixelProgramDumpOperand(instr.getSrc(k), false, srcOperand); + out += srcOperand; + } + out +="; \n"; +} + +// *************************************************************************** +void CPixelProgramConversionARB::ARBPixelProgramDumpOperand(const CPPOperand &op, bool destOperand, std::string &out) +{ + out = op.Negate ? " -" : " "; + switch(op.Type) + { + case CPPOperand::Variable: out += "R" + NLMISC::toString(op.Value.VariableValue); break; + case CPPOperand::Constant: + out += "c["; + out += NLMISC::toString(op.Value.ConstantValue) + "]"; + break; + case CPPOperand::InputRegister: out += string("fragment.") + ARBPixelProgramInputRegisterToName[(uint) op.Value.InputRegisterValue]; break; + case CPPOperand::OutputRegister: + nlassert(op.Value.OutputRegisterValue < CVPOperand::OutputRegisterCount); + out += "result." + std::string(ARBPixelProgramOutputRegisterToName[op.Value.OutputRegisterValue]); + break; + case CPPOperand::Sampler2DRegister: + out += string("texture[") + op.Value.SamplerValue + "], 2D"; + break; + case CPPOperand::Sampler3DRegister: + out += string("texture[") + op.Value.SamplerValue + "], 3D"; + break; + default: + break; + } + ARBProgramSuffix(op, destOperand, out); +} + +} // NL3D diff --git a/code/nel/src/3d/pixel_program.cpp b/code/nel/src/3d/pixel_program.cpp new file mode 100644 index 000000000..bd0e4d709 --- /dev/null +++ b/code/nel/src/3d/pixel_program.cpp @@ -0,0 +1,62 @@ +/** \file pixel_program.cpp + * Pixel program definition + * + * $Id: pixel_program.cpp,v 1.1.2.1 2007/04/27 17:35:07 legallo Exp $ + */ + +/* Copyright, 2000, 2001 Nevrax Ltd. + * + * This file is part of NEVRAX NEL. + * NEVRAX NEL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + + * NEVRAX NEL is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with NEVRAX NEL; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "std3d.h" + +#include "pixel_program.h" + +#include "driver.h" + +namespace NL3D +{ + +// *************************************************************************** +IPixelProgramDrvInfos::IPixelProgramDrvInfos (IDriver *drv, ItPixelPrgDrvInfoPtrList it) +{ + _Driver= drv; + _DriverIterator= it; +} + + +// *************************************************************************** +IPixelProgramDrvInfos::~IPixelProgramDrvInfos () +{ + _Driver->removePixelPrgDrvInfoPtr (_DriverIterator); +} + + +// *************************************************************************** +CPixelProgram::CPixelProgram(const char* program, bool isEffectPrg) +:IProgram(program, isEffectPrg) +{ +} + + +// *************************************************************************** +CPixelProgram::~CPixelProgram() +{ +} + +} // NL3D From b5dfdbdd55951a61953895a7d846b408fe27b1fc Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 01:19:45 +0200 Subject: [PATCH 008/137] Simplify CPixelProgram --- code/nel/include/nel/3d/pixel_program.h | 16 ++++------------ code/nel/src/3d/pixel_program.cpp | 9 +++++---- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/code/nel/include/nel/3d/pixel_program.h b/code/nel/include/nel/3d/pixel_program.h index 35731ca6d..fd39a76bc 100644 --- a/code/nel/include/nel/3d/pixel_program.h +++ b/code/nel/include/nel/3d/pixel_program.h @@ -26,15 +26,11 @@ #ifndef NL_PIXEL_PROGRAM_H #define NL_PIXEL_PROGRAM_H -#include "program.h" - -#include "nel/misc/types_nl.h" -#include "nel/misc/smart_ptr.h" +#include +#include #include -#define PIXEL_SHADER_PROFILE "ps_2_0" - namespace NL3D { // List typedef. @@ -59,22 +55,18 @@ public: //------------------------------------------------------------------------------- -class CPixelProgram : public IProgram +class CPixelProgram : public NLMISC::CRefCount { public: /// Constructor - CPixelProgram (const char* program, bool isEffectPrg=false); + CPixelProgram (const char* program); /// Destructor virtual ~CPixelProgram (); /// The driver informations. For the driver implementation only. NLMISC::CRefPtr _DrvInfo; - - const char * getASMProfile() { return PIXEL_SHADER_PROFILE; } ; - - static const char * getPixelASMProfile() { return PIXEL_SHADER_PROFILE; } ; }; diff --git a/code/nel/src/3d/pixel_program.cpp b/code/nel/src/3d/pixel_program.cpp index bd0e4d709..b7cba51d0 100644 --- a/code/nel/src/3d/pixel_program.cpp +++ b/code/nel/src/3d/pixel_program.cpp @@ -25,9 +25,9 @@ #include "std3d.h" -#include "pixel_program.h" +#include -#include "driver.h" +#include namespace NL3D { @@ -48,15 +48,16 @@ IPixelProgramDrvInfos::~IPixelProgramDrvInfos () // *************************************************************************** -CPixelProgram::CPixelProgram(const char* program, bool isEffectPrg) -:IProgram(program, isEffectPrg) +CPixelProgram::CPixelProgram(const char* program) { + } // *************************************************************************** CPixelProgram::~CPixelProgram() { + } } // NL3D From 9f6b60a920d5f062b653277b925d9f05c8dd19a5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 01:20:51 +0200 Subject: [PATCH 009/137] Add diff from old nevrax pixel program code to IDriver, CEffect related code not included --- code/nel/include/nel/3d/driver.h | 50 +++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index d090d77da..b3b8a250f 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -30,6 +30,7 @@ #include "nel/3d/vertex_buffer.h" #include "nel/3d/index_buffer.h" #include "nel/3d/vertex_program.h" +#include "nel/3d/pixel_program.h" #include "nel/3d/material.h" #include "nel/misc/mutex.h" #include "nel/3d/primitive_profile.h" @@ -145,6 +146,7 @@ public: protected: CSynchronized _SyncTexDrvInfos; + CSynchronized _SyncEffectDrvInfos; TTexDrvSharePtrList _TexDrvShares; TMatDrvInfoPtrList _MatDrvInfos; @@ -152,6 +154,7 @@ protected: TIBDrvInfoPtrList _IBDrvInfos; TPolygonMode _PolygonMode; TVtxPrgDrvInfoPtrList _VtxPrgDrvInfos; + TPixelPrgDrvInfoPtrList _PixelPrgDrvInfos; TShaderDrvInfoPtrList _ShaderDrvInfos; uint _ResetCounter; @@ -172,6 +175,7 @@ public: */ // @{ virtual void disableHardwareVertexProgram()=0; + virtual void disableHardwarePixelProgram()=0; virtual void disableHardwareVertexArrayAGP()=0; virtual void disableHardwareTextureShader()=0; // @} @@ -1009,6 +1013,11 @@ public: */ virtual bool isVertexProgramEmulated () const =0; + /** + * Does the driver supports pixel programs ? + */ + virtual bool isPixelProgramSupported () const =0; + /** @@ -1021,7 +1030,16 @@ public: virtual bool activeVertexProgram (CVertexProgram *program) =0; /** - * Setup constant values. + * Activate / disactivate a pixel program + * + * \param program is a pointer on a pixel program. Can be NULL to disable the current pixel program. + * + * \return true if setup/unsetup successed, false else. + */ + virtual bool activePixelProgram (CPixelProgram *program) =0; + + /** + * Setup vertex program constant values. */ virtual void setConstant (uint index, float, float, float, float) =0; virtual void setConstant (uint index, double, double, double, double) =0; @@ -1031,7 +1049,32 @@ public: virtual void setConstant (uint index, uint num, const float *src) =0; /// setup several 4 double csts taken from the given tab virtual void setConstant (uint index, uint num, const double *src) =0; + + /** + * Setup pixel program constant values. + */ + virtual void setPixelProgramConstant (uint index, float, float, float, float) =0; + virtual void setPixelProgramConstant (uint index, double, double, double, double) =0; + virtual void setPixelProgramConstant (uint index, const NLMISC::CVector& value) =0; + virtual void setPixelProgramConstant (uint index, const NLMISC::CVectorD& value) =0; + /// setup several 4 float csts taken from the given tab + virtual void setPixelProgramConstant (uint index, uint num, const float *src) =0; + /// setup several 4 double csts taken from the given tab + virtual void setPixelProgramConstant (uint index, uint num, const double *src) =0; + /** + * Setup constants with a current matrix. + * + * This call must be done after setFrustum(), setupViewMatrix() or setupModelMatrix() to get correct + * results. + * + * \param index is the base constant index where to store the matrix. This index must be a multiple of 4. + * \param matrix is the matrix id to store in the constants + * \param transform is the transformation to apply to the matrix before store it in the constants. + * + */ + virtual void setPixelProgramConstantMatrix (uint index, TMatrix matrix, TTransform transform) =0; + /** * Setup constants with a current matrix. * @@ -1251,6 +1294,9 @@ public: virtual void stencilOp(TStencilOp fail, TStencilOp zfail, TStencilOp zpass) = 0; virtual void stencilMask(uint mask) = 0; + // get the number of texture samplers available for pû•el programs + virtual uint getMaxTexturesForEffects() const = 0; + protected: friend class IVBDrvInfos; friend class IIBDrvInfos; @@ -1258,6 +1304,7 @@ protected: friend class ITextureDrvInfos; friend class IMaterialDrvInfos; friend class IVertexProgramDrvInfos; + friend class IPixelProgramDrvInfos; friend class IShaderDrvInfos; /// remove ptr from the lists in the driver. @@ -1268,6 +1315,7 @@ protected: void removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt); void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt); void removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt); + void removePixelPrgDrvInfoPtr(ItPixelPrgDrvInfoPtrList pixelPrgDrvInfoIt); private: bool _StaticMemoryToVRAM; From 7da48d8866b8d4cbc9e75d57095f79bf9600017d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 01:22:26 +0200 Subject: [PATCH 010/137] Removed some CEffect related bit that slipped in --- code/nel/include/nel/3d/driver.h | 1 - 1 file changed, 1 deletion(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index b3b8a250f..f9667cca9 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -146,7 +146,6 @@ public: protected: CSynchronized _SyncTexDrvInfos; - CSynchronized _SyncEffectDrvInfos; TTexDrvSharePtrList _TexDrvShares; TMatDrvInfoPtrList _MatDrvInfos; From cb966505ccf7bf492130e7c867a4efff175a73c1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 01:38:23 +0200 Subject: [PATCH 011/137] Add rest of the diff from the old nevrax code for pixel programs to NL3D --- code/nel/include/nel/3d/driver_user.h | 1 + code/nel/include/nel/3d/u_driver.h | 1 + code/nel/src/3d/driver.cpp | 5 +++++ code/nel/src/3d/driver_user.cpp | 6 ++++++ code/nel/src/3d/flare_model.cpp | 3 +++ code/nel/src/3d/scene.cpp | 4 ++++ 6 files changed, 20 insertions(+) diff --git a/code/nel/include/nel/3d/driver_user.h b/code/nel/include/nel/3d/driver_user.h index bfe4c1755..fff83d6d5 100644 --- a/code/nel/include/nel/3d/driver_user.h +++ b/code/nel/include/nel/3d/driver_user.h @@ -133,6 +133,7 @@ public: // @{ virtual void disableHardwareVertexProgram(); + virtual void disableHardwarePixelProgram(); virtual void disableHardwareVertexArrayAGP(); virtual void disableHardwareTextureShader(); diff --git a/code/nel/include/nel/3d/u_driver.h b/code/nel/include/nel/3d/u_driver.h index d66a72e47..1397c9c6e 100644 --- a/code/nel/include/nel/3d/u_driver.h +++ b/code/nel/include/nel/3d/u_driver.h @@ -168,6 +168,7 @@ public: */ // @{ virtual void disableHardwareVertexProgram()=0; + virtual void disableHardwarePixelProgram()=0; virtual void disableHardwareVertexArrayAGP()=0; virtual void disableHardwareTextureShader()=0; // @} diff --git a/code/nel/src/3d/driver.cpp b/code/nel/src/3d/driver.cpp index fa48649ae..d44079749 100644 --- a/code/nel/src/3d/driver.cpp +++ b/code/nel/src/3d/driver.cpp @@ -258,6 +258,11 @@ void IDriver::removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt) { _VtxPrgDrvInfos.erase(vtxPrgDrvInfoIt); } +// *************************************************************************** +void IDriver::removePixelPrgDrvInfoPtr(ItPixelPrgDrvInfoPtrList pixelPrgDrvInfoIt) +{ + _PixelPrgDrvInfos.erase(pixelPrgDrvInfoIt); +} // *************************************************************************** bool IDriver::invalidateShareTexture (ITexture &texture) diff --git a/code/nel/src/3d/driver_user.cpp b/code/nel/src/3d/driver_user.cpp index b45ebbd37..83c7343ec 100644 --- a/code/nel/src/3d/driver_user.cpp +++ b/code/nel/src/3d/driver_user.cpp @@ -213,6 +213,12 @@ void CDriverUser::disableHardwareVertexProgram() _Driver->disableHardwareVertexProgram(); } +void CDriverUser::disableHardwarePixelProgram() +{ + NL3D_HAUTO_UI_DRIVER; + + _Driver->disableHardwarePixelProgram(); +} void CDriverUser::disableHardwareVertexArrayAGP() { NL3D_HAUTO_UI_DRIVER; diff --git a/code/nel/src/3d/flare_model.cpp b/code/nel/src/3d/flare_model.cpp index 47d9fdb43..ba5cc8098 100644 --- a/code/nel/src/3d/flare_model.cpp +++ b/code/nel/src/3d/flare_model.cpp @@ -363,6 +363,7 @@ void CFlareModel::traverseRender() } // setup driver drv->activeVertexProgram(NULL); + drv->activePixelProgram(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 @@ -565,6 +566,7 @@ void CFlareModel::updateOcclusionQueryBegin(IDriver *drv) { nlassert(drv); drv->activeVertexProgram(NULL); + drv->activePixelProgram(NULL); drv->setupModelMatrix(CMatrix::Identity); initStatics(); drv->setColorMask(false, false, false, false); // don't write any pixel during the test @@ -661,6 +663,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); 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 df5297e2f..f257c7206 100644 --- a/code/nel/src/3d/scene.cpp +++ b/code/nel/src/3d/scene.cpp @@ -377,6 +377,9 @@ void CScene::endPartRender() // Reset profiling _NextRenderProfile= false; + IDriver *drv = getDriver(); + drv->activeVertexProgram(NULL); + drv->activePixelProgram(NULL); /* uint64 total = PSStatsRegisterPSModelObserver + @@ -1561,6 +1564,7 @@ void CScene::renderOcclusionTestMeshs() nlassert(RenderTrav.getDriver()); RenderTrav.getDriver()->setupViewport(RenderTrav.getViewport()); RenderTrav.getDriver()->activeVertexProgram(NULL); + RenderTrav.getDriver()->activePixelProgram(NULL); IDriver::TPolygonMode oldPolygonMode = RenderTrav.getDriver()->getPolygonMode(); CMaterial m; m.initUnlit(); From acf8ec653c94ab7473ac13eba50019ddbae5d140 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 02:01:12 +0200 Subject: [PATCH 012/137] Added diff to opengl driver for old nevrax pixel program code, marked todos in comments --- code/nel/include/nel/3d/driver.h | 3 -- .../src/3d/driver/opengl/driver_opengl.cpp | 8 +++ code/nel/src/3d/driver/opengl/driver_opengl.h | 42 ++++++++++++++++ .../driver/opengl/driver_opengl_extension.cpp | 11 ++++ .../driver/opengl/driver_opengl_extension.h | 2 + .../opengl/driver_opengl_pixel_program.cpp | 50 ++++++++++--------- 6 files changed, 90 insertions(+), 26 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index f9667cca9..9a079d95d 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1293,9 +1293,6 @@ public: virtual void stencilOp(TStencilOp fail, TStencilOp zfail, TStencilOp zpass) = 0; virtual void stencilMask(uint mask) = 0; - // get the number of texture samplers available for pû•el programs - virtual uint getMaxTexturesForEffects() const = 0; - protected: friend class IVBDrvInfos; friend class IIBDrvInfos; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 29e14a1a0..b3567ed90 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -482,6 +482,7 @@ bool CDriverGL::setupDisplay() } _VertexProgramEnabled= false; + _PixelProgramEnabled= false; _LastSetupGLArrayVertexProgram= false; // Init VertexArrayRange according to supported extenstion. @@ -737,6 +738,12 @@ void CDriverGL::disableHardwareVertexProgram() _Extensions.DisableHardwareVertexProgram= true; } +void CDriverGL::disableHardwarePixelProgram() +{ + H_AUTO_OGL(CDriverGL_disableHardwarePixelProgram) + _Extensions.DisableHardwarePixelProgram= true; +} + // *************************************************************************** void CDriverGL::disableHardwareVertexArrayAGP() { @@ -854,6 +861,7 @@ bool CDriverGL::swapBuffers() // Reset texture shaders //resetTextureShaders(); activeVertexProgram(NULL); + activePixelProgram(NULL); #ifndef USE_OPENGLES /* Yoyo: must do this (GeForce bug ??) else weird results if end render with a VBHard. diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index bfe73492d..25503d9c6 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -306,6 +306,7 @@ public: virtual bool init (uint windowIcon = 0, emptyProc exitFunc = 0); virtual void disableHardwareVertexProgram(); + virtual void disableHardwarePixelProgram(); virtual void disableHardwareVertexArrayAGP(); virtual void disableHardwareTextureShader(); @@ -692,6 +693,7 @@ private: virtual class IVertexBufferHardGL *createVertexBufferHard(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb); friend class CTextureDrvInfosGL; friend class CVertexProgamDrvInfosGL; + friend class CPixelProgamDrvInfosGL; private: // Version of the driver. Not the interface version!! Increment when implementation of the driver change. @@ -1302,8 +1304,10 @@ private: // @{ bool isVertexProgramSupported () const; + bool isPixelProgramSupported () const; bool isVertexProgramEmulated () const; bool activeVertexProgram (CVertexProgram *program); + bool activePixelProgram (CPixelProgram *program); void setConstant (uint index, float, float, float, float); void setConstant (uint index, double, double, double, double); void setConstant (uint indexStart, const NLMISC::CVector& value); @@ -1314,6 +1318,15 @@ private: void setConstantFog (uint index); void enableVertexProgramDoubleSidedColor(bool doubleSided); bool supportVertexProgramDoubleSidedColor() const; + + // Pixel program + virtual void setPixelProgramConstant (uint index, float, float, float, float); + virtual void setPixelProgramConstant (uint index, double, double, double, double); + virtual void setPixelProgramConstant (uint index, const NLMISC::CVector& value); + virtual void setPixelProgramConstant (uint index, const NLMISC::CVectorD& value); + virtual void setPixelProgramConstant (uint index, uint num, const float *src); + virtual void setPixelProgramConstant (uint index, uint num, const double *src); + virtual void setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform); virtual bool supportMADOperator() const ; @@ -1328,6 +1341,12 @@ private: //@} + /// \name Pixel program implementation + // @{ + bool activeARBPixelProgram (CPixelProgram *program); + // TODO_REMOVE_PARSER bool setupARBPixelProgram (const CPixelProgramParser::CPProgram &parsedProgram, GLuint id/*, bool &specularWritten*/); + //@} + /// \fallback for material shaders // @{ @@ -1340,15 +1359,27 @@ private: // Don't use glIsEnabled, too slow. return _VertexProgramEnabled; } + + bool isPixelProgramEnabled () const + { + // Don't use glIsEnabled, too slow. + return _PixelProgramEnabled; + } // Track state of activeVertexProgram() bool _VertexProgramEnabled; + // Track state of activePixelProgram() + bool _PixelProgramEnabled; + // Say if last setupGlArrays() was a VertexProgram setup. bool _LastSetupGLArrayVertexProgram; // The last vertex program that was setupped NLMISC::CRefPtr _LastSetuppedVP; + // The last pixel program that was setupped + NLMISC::CRefPtr _LastSetuppedPP; + bool _ForceDXTCCompression; /// Divisor for textureResize (power). uint _ForceTextureResizePower; @@ -1518,6 +1549,17 @@ public: CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it); }; +// *************************************************************************** +class CPixelProgamDrvInfosGL : public IPixelProgramDrvInfos +{ +public: + // The GL Id. + GLuint ID; + + // The gl id is auto created here. + CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it); +}; + #ifdef NL_STATIC } // NLDRIVERGL/ES #endif diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp index d38ff8f51..e777d2696 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp @@ -1560,6 +1560,17 @@ void registerGlExtensions(CGlExtensions &ext) ext.EXTVertexShader = false; ext.ARBVertexProgram = false; } + + // Check pixel program + // Disable feature ??? + if(!ext.DisableHardwarePixelProgram) + { + ext.ARBFragmentProgram= setupARBFragmentProgram(glext); + } + else + { + ext.ARBFragmentProgram = false; + } ext.OESDrawTexture = setupOESDrawTexture(glext); ext.OESMapBuffer = setupOESMapBuffer(glext); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h index 9d28a15ab..d6d4974a6 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h @@ -111,6 +111,7 @@ public: /// \name Disable Hardware feature. False by default. setuped by IDriver // @{ bool DisableHardwareVertexProgram; + bool DisableHardwarePixelProgram; bool DisableHardwareVertexArrayAGP; bool DisableHardwareTextureShader; // @} @@ -174,6 +175,7 @@ public: /// \name Disable Hardware feature. False by default. setuped by IDriver DisableHardwareVertexProgram= false; + DisableHardwarePixelProgram= false; DisableHardwareVertexArrayAGP= false; DisableHardwareTextureShader= false; } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index 7677e6151..a0439f3b3 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -28,10 +28,8 @@ #include "stdopengl.h" #include "driver_opengl.h" -#include "../../index_buffer.h" -#include "../../vertex_program.h" -//#include "../../vertex_program_parse.h" -#include "../../program_parse_D3D.h" +#include +#include #include // tmp @@ -92,6 +90,8 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) // Program setuped ? if (program->_DrvInfo==NULL) { + /* TODO_REMOVE_PARSER + // Insert into driver list. (so it is deleted when driver is deleted). ItPixelPrgDrvInfoPtrList it= _PixelPrgDrvInfos.insert(_PixelPrgDrvInfos.end()); @@ -127,6 +127,8 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) _PixelPrgDrvInfos.erase(it); return false; } + + */ } else { @@ -150,7 +152,8 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) return true; } - +// TODO_REMOVE_PARSER +#if 0 // *************************************************************************** bool CDriverGL::setupARBPixelProgram (const CPixelProgramParser::CPProgram &inParsedProgram, GLuint id/*, bool &specularWritten*/) { @@ -206,6 +209,7 @@ bool CDriverGL::setupARBPixelProgram (const CPixelProgramParser::CPProgram &inPa } return true; } +#endif // *************************************************************************** @@ -213,7 +217,8 @@ void CDriverGL::setPixelProgramConstant (uint index, float f0, float f1, float f { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + //if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS { if (_Extensions.ARBFragmentProgram) nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3); @@ -227,7 +232,8 @@ void CDriverGL::setPixelProgramConstant (uint index, double d0, double d1, doubl { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS { if (_Extensions.ARBFragmentProgram) nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, d0, d1, d2, d3); @@ -241,7 +247,8 @@ void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVector& valu { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS { if (_Extensions.ARBFragmentProgram) nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0); @@ -255,7 +262,8 @@ void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVectorD& val { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS { if (_Extensions.ARBFragmentProgram) nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0); @@ -268,7 +276,8 @@ void CDriverGL::setPixelProgramConstant (uint index, uint num, const float *src) { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS { if (_Extensions.ARBFragmentProgram) { @@ -285,7 +294,8 @@ void CDriverGL::setPixelProgramConstant (uint index, uint num, const double *src { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS { if (_Extensions.ARBFragmentProgram) { @@ -303,7 +313,8 @@ void CDriverGL::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matr { H_AUTO_OGL(CDriverGL_setPixelProgramConstantMatrix) - if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) + if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS { if (_Extensions.ARBFragmentProgram) { @@ -358,17 +369,8 @@ void CDriverGL::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matr } } -// *************************************************************************** -uint CDriverGL::getMaxTexturesForEffects() const -{ - H_AUTO_OGL(CDriverGL_getMaxTexturesForEffects) - - uint texSamplerNb = 0; - if (_Extensions.ARBFragmentProgram) // ARB implementation - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, (int*)(&texSamplerNb)); - - return texSamplerNb; -} +// TODO_REMOVE_PARSER +#if 0 // *************************************************************************** // ***************** CPixelProgramConversionARB ***************************** @@ -550,4 +552,6 @@ void CPixelProgramConversionARB::ARBPixelProgramDumpOperand(const CPPOperand &op ARBProgramSuffix(op, destOperand, out); } +#endif + } // NL3D From 7dcc86c717ce566efd1cf1dd7f3dd442b6179d4d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 02:10:38 +0200 Subject: [PATCH 013/137] Add direct3d diff for old nevrax pixel program code, marked a todo in the comments --- .../3d/driver/direct3d/driver_direct3d.cpp | 8 +++++ .../src/3d/driver/direct3d/driver_direct3d.h | 36 +++++++++++++++++++ .../driver_direct3d_pixel_program.cpp | 16 ++------- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index 412cb52da..26cf628e0 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -193,6 +193,11 @@ CDriverD3D::CDriverD3D() #else // NL_DISABLE_HARDWARE_VERTEX_PROGAM _DisableHardwareVertexProgram = false; #endif // NL_DISABLE_HARDWARE_VERTEX_PROGAM +#ifdef NL_DISABLE_HARDWARE_PIXEL_PROGAM + _DisableHardwarePixelProgram = true; +#else // NL_DISABLE_HARDWARE_PIXEL_PROGAM + _DisableHardwarePixelProgram = false; +#endif // NL_DISABLE_HARDWARE_PIXEL_PROGAM #ifdef NL_DISABLE_HARDWARE_VERTEX_ARRAY_AGP _DisableHardwareVertexArrayAGP = true; #else // NL_DISABLE_HARDWARE_VERTEX_ARRAY_AGP @@ -1546,6 +1551,7 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r #endif // NL_FORCE_TEXTURE_STAGE_COUNT _VertexProgram = !_DisableHardwareVertexProgram && ((caps.VertexShaderVersion&0xffff) >= 0x0100); + _PixelProgram = !_DisableHardwarePixelProgram && (caps.PixelShaderVersion&0xffff) >= 0x0101; _PixelShader = !_DisableHardwarePixelShader && (caps.PixelShaderVersion&0xffff) >= 0x0101; _MaxVerticesByVertexBufferHard = caps.MaxVertexIndex; _MaxLight = caps.MaxActiveLights; @@ -2016,6 +2022,8 @@ bool CDriverD3D::swapBuffers() // Reset vertex program setVertexProgram (NULL, NULL); + // Reset pixel program + setPixelShader (NULL); if (_VBHardProfiling) { diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index cff7cb804..7668bd63c 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -240,6 +240,19 @@ public: CVertexProgamDrvInfosD3D(IDriver *drv, ItVtxPrgDrvInfoPtrList it); ~CVertexProgamDrvInfosD3D(); }; + + +// *************************************************************************** +class CPixelProgramDrvInfosD3D : public IPixelProgramDrvInfos +{ +public: + + // The shader + IDirect3DPixelShader9 *Shader; + + CPixelProgramDrvInfosD3D(IDriver *drv, ItPixelPrgDrvInfoPtrList it); + ~CPixelProgramDrvInfosD3D(); +}; // *************************************************************************** @@ -773,6 +786,7 @@ public: // Driver parameters virtual void disableHardwareVertexProgram(); + virtual void disableHardwarePixelProgram(); virtual void disableHardwareIndexArrayAGP(); virtual void disableHardwareVertexArrayAGP(); virtual void disableHardwareTextureShader(); @@ -993,8 +1007,10 @@ public: // Vertex program virtual bool isVertexProgramSupported () const; + virtual bool isPixelProgramSupported () const; virtual bool isVertexProgramEmulated () const; virtual bool activeVertexProgram (CVertexProgram *program); + virtual bool activePixelProgram (CPixelProgram *program); virtual void setConstant (uint index, float, float, float, float); virtual void setConstant (uint index, double, double, double, double); virtual void setConstant (uint index, const NLMISC::CVector& value); @@ -1006,6 +1022,15 @@ public: virtual void enableVertexProgramDoubleSidedColor(bool doubleSided); virtual bool supportVertexProgramDoubleSidedColor() const; + // Pixel program + virtual void setPixelProgramConstant (uint index, float, float, float, float); + virtual void setPixelProgramConstant (uint index, double, double, double, double); + virtual void setPixelProgramConstant (uint index, const NLMISC::CVector& value); + virtual void setPixelProgramConstant (uint index, const NLMISC::CVectorD& value); + virtual void setPixelProgramConstant (uint index, uint num, const float *src); + virtual void setPixelProgramConstant (uint index, uint num, const double *src); + virtual void setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform); + // Occlusion query virtual bool supportOcclusionQuery() const; virtual IOcclusionQuery *createOcclusionQuery(); @@ -1892,6 +1917,15 @@ public: return d3dtex; } + // Get the d3dtext mirror of an existing setuped pixel program. + static inline CPixelProgramDrvInfosD3D* getPixelProgramD3D(CPixelProgram& pixelProgram) + { + H_AUTO_D3D(CDriverD3D_getPixelProgramD3D); + CPixelProgramDrvInfosD3D* d3dPixelProgram; + d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IPixelProgramDrvInfos*)(pixelProgram._DrvInfo); + return d3dPixelProgram; + } + // Get the d3dtext mirror of an existing setuped vertex program. static inline CVertexProgamDrvInfosD3D* getVertexProgramD3D(CVertexProgram& vertexProgram) { @@ -2197,8 +2231,10 @@ private: bool _ForceDXTCCompression:1; bool _TextureCubeSupported; bool _VertexProgram; + bool _PixelProgram; bool _PixelShader; bool _DisableHardwareVertexProgram; + bool _DisableHardwarePixelProgram; bool _DisableHardwareVertexArrayAGP; bool _DisableHardwareIndexArrayAGP; bool _DisableHardwarePixelShader; 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 755592043..f2255f88b 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 @@ -82,10 +82,11 @@ bool CDriverD3D::activePixelProgram(CPixelProgram *program) program->_DrvInfo = *itPix; std::string dest; + /* TODO_REMOVE if(program->isEffectProgram()) { dest = program->getProgram(); - } + }*/ LPD3DXBUFFER pShader; LPD3DXBUFFER pErrorMsgs; @@ -289,17 +290,4 @@ void CDriverD3D::disableHardwarePixelProgram() _PixelProgram = false; } -// *************************************************************************** - -uint CDriverD3D::getMaxTexturesForEffects() const -{ - H_AUTO_D3D(CDriverD3D_getMaxTexturesForEffects) - - // we use ps_2_0 profile for direct3D ASM pixel program, then 16 texture samplers are available - if(!strcmp(CPixelProgram::getPixelASMProfile(), "ps_2_0")) - return 16; - - return 0; -} - } // NL3D From 72035e936afa62d9af9651b84f7867a2216826ef Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 02:33:19 +0200 Subject: [PATCH 014/137] Removed unneeded parser related code from the opengl pixel program implementation --- code/nel/include/nel/3d/pixel_program.h | 8 + code/nel/src/3d/driver/opengl/driver_opengl.h | 2 +- .../opengl/driver_opengl_pixel_program.cpp | 194 ++++++------------ code/nel/src/3d/pixel_program.cpp | 2 +- 4 files changed, 78 insertions(+), 128 deletions(-) diff --git a/code/nel/include/nel/3d/pixel_program.h b/code/nel/include/nel/3d/pixel_program.h index fd39a76bc..811dbe0e1 100644 --- a/code/nel/include/nel/3d/pixel_program.h +++ b/code/nel/include/nel/3d/pixel_program.h @@ -65,8 +65,16 @@ public: /// Destructor virtual ~CPixelProgram (); + /// Get the program + inline const std::string& getProgram() const { return _Program; }; + /// The driver informations. For the driver implementation only. NLMISC::CRefPtr _DrvInfo; + +protected: + + /// The progam + std::string _Program; }; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 25503d9c6..f53f6f535 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1344,7 +1344,7 @@ private: /// \name Pixel program implementation // @{ bool activeARBPixelProgram (CPixelProgram *program); - // TODO_REMOVE_PARSER bool setupARBPixelProgram (const CPixelProgramParser::CPProgram &parsedProgram, GLuint id/*, bool &specularWritten*/); + bool setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, bool &specularWritten*/); //@} diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index a0439f3b3..eff54736f 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -90,45 +90,21 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) // Program setuped ? if (program->_DrvInfo==NULL) { - /* TODO_REMOVE_PARSER - // Insert into driver list. (so it is deleted when driver is deleted). - ItPixelPrgDrvInfoPtrList it= _PixelPrgDrvInfos.insert(_PixelPrgDrvInfos.end()); + ItPixelPrgDrvInfoPtrList it= _PixelPrgDrvInfos.insert(_PixelPrgDrvInfos.end(), (NL3D::IPixelProgramDrvInfos*)NULL); // Create a driver info *it = drvInfo = new CPixelProgamDrvInfosGL (this, it); // Set the pointer program->_DrvInfo=drvInfo; - - std::string asmProgram; - CPixelProgramParser::CPProgram parsedProgram; - if(program->isEffectProgram()) - { - asmProgram = program->getProgram(); - - CPPParserD3D parser; - // try to parse the program - std::string errorOutput; - bool result = parser.parse(asmProgram.c_str(), parsedProgram, errorOutput); - if (!result) - { - nlwarning("Unable to parse a pixel program."); - #ifdef NL_DEBUG - nlerror(errorOutput.c_str()); - #endif - return false; - } - } - if(!setupARBPixelProgram(parsedProgram, drvInfo->ID)) + if(!setupARBPixelProgram(program, drvInfo->ID)) { delete drvInfo; program->_DrvInfo = NULL; _PixelPrgDrvInfos.erase(it); return false; } - - */ } else { @@ -152,19 +128,14 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) return true; } -// TODO_REMOVE_PARSER -#if 0 + // *************************************************************************** -bool CDriverGL::setupARBPixelProgram (const CPixelProgramParser::CPProgram &inParsedProgram, GLuint id/*, bool &specularWritten*/) +bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, bool &specularWritten*/) { H_AUTO_OGL(CDriverGL_setupARBPixelProgram) - // convert from proprietary format to ARB_pixel_program code - CPixelProgramConversionARB vpConvertARB; - std::string code; - if(!vpConvertARB.convert(inParsedProgram, code)) return false; + const std::string &code = program->getProgram(); - // nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, id); glGetError(); nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, code.size(), code.c_str() ); @@ -175,10 +146,10 @@ bool CDriverGL::setupARBPixelProgram (const CPixelProgramParser::CPProgram &inPa { GLint position; glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &position); - nlassert(position != -1) // there was an error.. + nlassert(position != -1); // there was an error.. nlassert(position < (GLint) code.size()); uint line = 0; - const char *lineStart = code.c_str(); + const char *lineStart = program->getProgram().c_str(); for(uint k = 0; k < (uint) position; ++k) { if (code[k] == '\n') @@ -209,7 +180,6 @@ bool CDriverGL::setupARBPixelProgram (const CPixelProgramParser::CPProgram &inPa } return true; } -#endif // *************************************************************************** @@ -217,12 +187,8 @@ void CDriverGL::setPixelProgramConstant (uint index, float f0, float f1, float f { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - //if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) - if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS - { - if (_Extensions.ARBFragmentProgram) - nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3); - } + if (_Extensions.ARBFragmentProgram) + nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3); } @@ -232,12 +198,8 @@ void CDriverGL::setPixelProgramConstant (uint index, double d0, double d1, doubl { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) - if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS - { - if (_Extensions.ARBFragmentProgram) - nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, d0, d1, d2, d3); - } + if (_Extensions.ARBFragmentProgram) + nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, d0, d1, d2, d3); } @@ -247,12 +209,8 @@ void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVector& valu { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) - if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS - { - if (_Extensions.ARBFragmentProgram) - nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0); - } + if (_Extensions.ARBFragmentProgram) + nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0); } @@ -262,12 +220,8 @@ void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVectorD& val { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) - if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS - { - if (_Extensions.ARBFragmentProgram) - nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0); - } + if (_Extensions.ARBFragmentProgram) + nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0); } @@ -276,15 +230,11 @@ void CDriverGL::setPixelProgramConstant (uint index, uint num, const float *src) { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) - if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS + if (_Extensions.ARBFragmentProgram) { - if (_Extensions.ARBFragmentProgram) - { - for(uint k = 0; k < num; ++k) - { - nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k); - } + for(uint k = 0; k < num; ++k) + { + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k); } } } @@ -294,15 +244,11 @@ void CDriverGL::setPixelProgramConstant (uint index, uint num, const double *src { H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) - if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS + if (_Extensions.ARBFragmentProgram) { - if (_Extensions.ARBFragmentProgram) - { - for(uint k = 0; k < num; ++k) - { - nglProgramEnvParameter4dvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k); - } + for(uint k = 0; k < num; ++k) + { + nglProgramEnvParameter4dvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k); } } } @@ -313,59 +259,55 @@ void CDriverGL::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matr { H_AUTO_OGL(CDriverGL_setPixelProgramConstantMatrix) - // if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram()) - if (_LastSetuppedPP) // TODO_REMOVE_EFFECTS + if (_Extensions.ARBFragmentProgram) { - if (_Extensions.ARBFragmentProgram) + + // First, ensure that the render setup is correctly setuped. + refreshRenderSetup(); + CMatrix mat; + switch (matrix) { - - // First, ensure that the render setup is correctly setuped. - refreshRenderSetup(); - CMatrix mat; - switch (matrix) - { - case IDriver::ModelView: - mat = _ModelViewMatrix; + case IDriver::ModelView: + mat = _ModelViewMatrix; + break; + case IDriver::Projection: + { + refreshProjMatrixFromGL(); + mat = _GLProjMat; + } + break; + case IDriver::ModelViewProjection: + refreshProjMatrixFromGL(); + mat = _GLProjMat * _ModelViewMatrix; + break; + default: break; - case IDriver::Projection: - { - refreshProjMatrixFromGL(); - mat = _GLProjMat; - } - break; - case IDriver::ModelViewProjection: - refreshProjMatrixFromGL(); - mat = _GLProjMat * _ModelViewMatrix; - break; - default: - break; - } - - switch(transform) - { - case IDriver::Identity: break; - case IDriver::Inverse: - mat.invert(); - break; - case IDriver::Transpose: - mat.transpose(); - break; - case IDriver::InverseTranspose: - mat.invert(); - mat.transpose(); - break; - default: - break; - } - mat.transpose(); - float matDatas[16]; - mat.get(matDatas); - - nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index, matDatas); - nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 1, matDatas + 4); - nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 2, matDatas + 8); - nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 3, matDatas + 12); } + + switch(transform) + { + case IDriver::Identity: break; + case IDriver::Inverse: + mat.invert(); + break; + case IDriver::Transpose: + mat.transpose(); + break; + case IDriver::InverseTranspose: + mat.invert(); + mat.transpose(); + break; + default: + break; + } + mat.transpose(); + float matDatas[16]; + mat.get(matDatas); + + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index, matDatas); + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 1, matDatas + 4); + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 2, matDatas + 8); + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 3, matDatas + 12); } } diff --git a/code/nel/src/3d/pixel_program.cpp b/code/nel/src/3d/pixel_program.cpp index b7cba51d0..320bfa541 100644 --- a/code/nel/src/3d/pixel_program.cpp +++ b/code/nel/src/3d/pixel_program.cpp @@ -48,7 +48,7 @@ IPixelProgramDrvInfos::~IPixelProgramDrvInfos () // *************************************************************************** -CPixelProgram::CPixelProgram(const char* program) +CPixelProgram::CPixelProgram(const char* program) : _Program(program) { } From 0c1bfe0f638e85006ac4f0f2cfb4188d5d5d41b3 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 02:36:57 +0200 Subject: [PATCH 015/137] Cleanup more unneeded code --- .../driver_direct3d_pixel_program.cpp | 7 +- .../opengl/driver_opengl_pixel_program.cpp | 185 ------------------ 2 files changed, 1 insertion(+), 191 deletions(-) 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 f2255f88b..08ac5d74b 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 @@ -81,12 +81,7 @@ bool CDriverD3D::activePixelProgram(CPixelProgram *program) // Create a driver info structure program->_DrvInfo = *itPix; - std::string dest; - /* TODO_REMOVE - if(program->isEffectProgram()) - { - dest = program->getProgram(); - }*/ + const std::string &dest = program->getProgram(); LPD3DXBUFFER pShader; LPD3DXBUFFER pErrorMsgs; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index eff54736f..18ce82846 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -311,189 +311,4 @@ void CDriverGL::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matr } } -// TODO_REMOVE_PARSER -#if 0 - -// *************************************************************************** -// ***************** CPixelProgramConversionARB ***************************** -// *************************************************************************** - -const char * CPixelProgramConversionARB::ARBPixelProgramInputRegisterToName[CPPOperand::InputRegisterCount] = -{ - "color.primary", - "color.secondary", - "texcoord[0]", - "texcoord[1]", - "texcoord[2]", - "texcoord[3]", - "texcoord[4]", - "texcoord[5]", - "texcoord[6]", - "texcoord[7]", -}; - -// *************************************************************************** -const char * CPixelProgramConversionARB::ARBPixelProgramOutputRegisterToName[CPPOperand::OutputRegisterCount] = -{ - "color", - "depth" -}; - -// *************************************************************************** -bool CPixelProgramConversionARB::convert(const CPixelProgramParser::CPProgram &inParsedProgram, std::string & code) -{ - CPixelProgramParser::TPProgram parsedProgram = inParsedProgram._Program; - // - code = "!!ARBfp1.0\n"; - // declare temporary registers - GLint glMaxTempVar; - nglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &glMaxTempVar); - uint usedTempVar = inParsedProgram.getUsedVariablesNb(); - if(usedTempVar>glMaxTempVar) - { - nlwarning(" Used temporary registers number is superior to maximum ARB_FRAGMENT_PROGRAM temporaries registers."); - return false; - } - ARBProgramTemporaryRegisters(code, usedTempVar); - // declare constant register - if(!CProgramConversionARB::constantRegisters(inParsedProgram._Constants, code)) return false; - - for(uint k = 0; k < parsedProgram.size(); ++k) - { - std::string instr; - ARBPixelProgramDumpInstr(parsedProgram[k], instr); - code += instr + "\r\n"; - } - code += "END\n"; - - return true; -} - -// *************************************************************************** -// Dump an instruction in a string -void CPixelProgramConversionARB::ARBPixelProgramDumpInstr(const CPPInstruction &instr, std::string &out) -{ - nlassert(instr.Opcode.PPOp < CPPInstruction::OpcodeCount); - // Special case for EXP with a scalar output argument (y component) -> translate to FRC - - out = std::string(); - switch(instr.Opcode.PPOp) - { - case CPPInstruction::ADD: - out = "ADD"; - break; - case CPPInstruction::DP3: - out = "DP3"; - break; - case CPPInstruction::DP4: - out = "DP4"; - break; - case CPPInstruction::EXP: - out = "EXP"; - break; - case CPPInstruction::FRC: - out = "FRC"; - break; - case CPPInstruction::LOG: - out = "LOG"; - break; - case CPPInstruction::MAD: - out = "MAD"; - break; - case CPPInstruction::MAX: - out = "MAX"; - break; - case CPPInstruction::MIN: - out = "MIN"; - break; - case CPPInstruction::MOV: - out = "MOV"; - break; - case CPPInstruction::MUL: - out = "MUL"; - break; - case CPPInstruction::RCP: - out = "RCP"; - break; - case CPPInstruction::RSQ: - out = "RSQ"; - break; - case CPPInstruction::SUB: - out = "SUB"; - break; - case CPPInstruction::ABS: - out = "ABS"; - break; - case CPPInstruction::CMP: - out = "CMP"; - break; - case CPPInstruction::CRS: - out = "XPD"; - break; - case CPPInstruction::LRP: - out = "LRP"; - break; - case CPPInstruction::POW: - out = "POW"; - break; - case CPPInstruction::TEX: - out = "TEX"; - break; - case CPPInstruction::TEXB: - out = "TXB"; - break; - case CPPInstruction::TEXP: - out = "TXP"; - break; - default: - nlwarning("no match with a ARB Pixel Program Operator"); - break; - } - - if(instr.Sat) out += "_SAT"; - out += " "; - uint nbOp = instr.getNumUsedSrc(); - std::string destOperand; - ARBPixelProgramDumpOperand(instr.Dest, true, destOperand); - out += destOperand; - for(uint k = 0; k < nbOp; ++k) - { - out += ", "; - std::string srcOperand; - ARBPixelProgramDumpOperand(instr.getSrc(k), false, srcOperand); - out += srcOperand; - } - out +="; \n"; -} - -// *************************************************************************** -void CPixelProgramConversionARB::ARBPixelProgramDumpOperand(const CPPOperand &op, bool destOperand, std::string &out) -{ - out = op.Negate ? " -" : " "; - switch(op.Type) - { - case CPPOperand::Variable: out += "R" + NLMISC::toString(op.Value.VariableValue); break; - case CPPOperand::Constant: - out += "c["; - out += NLMISC::toString(op.Value.ConstantValue) + "]"; - break; - case CPPOperand::InputRegister: out += string("fragment.") + ARBPixelProgramInputRegisterToName[(uint) op.Value.InputRegisterValue]; break; - case CPPOperand::OutputRegister: - nlassert(op.Value.OutputRegisterValue < CVPOperand::OutputRegisterCount); - out += "result." + std::string(ARBPixelProgramOutputRegisterToName[op.Value.OutputRegisterValue]); - break; - case CPPOperand::Sampler2DRegister: - out += string("texture[") + op.Value.SamplerValue + "], 2D"; - break; - case CPPOperand::Sampler3DRegister: - out += string("texture[") + op.Value.SamplerValue + "], 3D"; - break; - default: - break; - } - ARBProgramSuffix(op, destOperand, out); -} - -#endif - } // NL3D From f534bac6e1547567085482859657057740120a93 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 02:59:32 +0200 Subject: [PATCH 016/137] Add test for ARBfp1.0 fragment program in snowballs (it works) --- code/snowballs2/client/src/commands.cpp | 35 +++++++++++++++++++ code/snowballs2/client/src/snowballs_config.h | 7 +++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index 70dd3b247..f5acf0b80 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -40,6 +40,12 @@ #include "snowballs_client.h" #include "interface.h" +#if SBCLIENT_DEV_PIXEL_PROGRAM +#include +#include +#include +#endif + // // Namespaces // @@ -237,6 +243,12 @@ void cbUpdateCommands (CConfigFile::CVar &var) else nlwarning ("Unknown variable update %s", var.Name.c_str()); } +#if SBCLIENT_DEV_PIXEL_PROGRAM +namespace { +CPixelProgram *a_DevPixelProgram; +} +#endif + void initCommands() { // Add the keyboard listener in the event server @@ -278,6 +290,15 @@ void initCommands() CommandsMaterial.initUnlit(); CommandsMaterial.setBlendFunc(UMaterial::srcalpha, UMaterial::invsrcalpha); CommandsMaterial.setBlend(true); + +#if SBCLIENT_DEV_PIXEL_PROGRAM + static const char *program = + "!!ARBfp1.0\n" + "PARAM red = {1.0, 0.0, 0.0, 1.0};\n" + "MOV result.color, red;\n" + "END\n"; + a_DevPixelProgram = new CPixelProgram(program); +#endif } void updateCommands() @@ -301,8 +322,18 @@ void updateCommands() float y0 = CommandsBoxY - CommandsBoxBorderY; float x1 = CommandsBoxX + CommandsBoxWidth + CommandsBoxBorderX; float y1 = CommandsBoxY + CommandsBoxHeight + CommandsBoxBorderY; + +#if SBCLIENT_DEV_PIXEL_PROGRAM + NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); + d->activePixelProgram(a_DevPixelProgram); +#endif + Driver->drawQuad(CQuad(CVector(x0, y0, 0), CVector(x1, y0, 0), CVector(x1, y1, 0), CVector(x0, y1, 0)), CommandsMaterial); +#if SBCLIENT_DEV_PIXEL_PROGRAM + d->activePixelProgram(NULL); +#endif + // Set the text context TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setColor (CommandsFrontColor); @@ -334,6 +365,10 @@ void clearCommands () void releaseCommands() { +#if SBCLIENT_DEV_PIXEL_PROGRAM + delete a_DevPixelProgram; + a_DevPixelProgram = NULL; +#endif // Remove the displayers CommandsLog.removeDisplayer(&CommandsDisplayer); #ifndef NL_RELEASE diff --git a/code/snowballs2/client/src/snowballs_config.h b/code/snowballs2/client/src/snowballs_config.h index edd282718..9565fe4cf 100644 --- a/code/snowballs2/client/src/snowballs_config.h +++ b/code/snowballs2/client/src/snowballs_config.h @@ -37,7 +37,11 @@ #define SBCLIENT_ERASE_LOG true // version number -#define SBCLIENT_VERSION "2.1.551" +// 2.1 +// - Bloom +// 2.2 +// - OculusVR support +#define SBCLIENT_VERSION "2.2" @@ -45,6 +49,7 @@ #define SBCLIENT_DEV_SOUND 0 #define SBCLIENT_DEV_STEREO 0 #define SBCLIENT_DEV_MEMLEAK 0 +#define SBCLIENT_DEV_PIXEL_PROGRAM 1 From 9c5fabf615313a9bf2afbf0a86c106a0bc631c9c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 04:03:32 +0200 Subject: [PATCH 017/137] Add test for ps.1.1 pixel program in snowballs (it works too now) --- code/nel/include/nel/3d/material.h | 8 +++++++- code/snowballs2/client/src/commands.cpp | 13 +++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/code/nel/include/nel/3d/material.h b/code/nel/include/nel/3d/material.h index a7ca18bff..b9f063af1 100644 --- a/code/nel/include/nel/3d/material.h +++ b/code/nel/include/nel/3d/material.h @@ -171,7 +171,12 @@ public: * - Alpha of texture in stage 0 is blended with alpha of texture in stage 1. Blend done with the alpha color of each * stage and the whole is multiplied by the alpha in color vertex [AT0*ADiffuseCol+AT1*(1-ADiffuseCol)]*AStage * - 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 (probably does not work yet), the rest must be set manually. + * - May be replaced in the future by some generic shader system. */ enum TShader { Normal=0, Bump, @@ -183,6 +188,7 @@ public: PerPixelLightingNoSpec, Cloud, Water, + PostProcessing, shaderCount}; /// \name Texture Env Modes. diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index f5acf0b80..fe33e566a 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #endif // @@ -292,12 +293,17 @@ void initCommands() CommandsMaterial.setBlend(true); #if SBCLIENT_DEV_PIXEL_PROGRAM - static const char *program = + CommandsMaterial.getObjectPtr()->setShader(NL3D::CMaterial::PostProcessing); + static const char *program_arbfp10 = "!!ARBfp1.0\n" "PARAM red = {1.0, 0.0, 0.0, 1.0};\n" "MOV result.color, red;\n" "END\n"; - a_DevPixelProgram = new CPixelProgram(program); + static const char *program_ps10 = + "ps.1.1\n" + "def c0, 1.0, 0.0, 0.0, 1.0\n" + "mov r0, c0\n"; + a_DevPixelProgram = new CPixelProgram(program_ps10); #endif } @@ -326,11 +332,14 @@ void updateCommands() #if SBCLIENT_DEV_PIXEL_PROGRAM NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); d->activePixelProgram(a_DevPixelProgram); + bool fogEnabled = d->fogEnabled(); + d->enableFog(false); #endif Driver->drawQuad(CQuad(CVector(x0, y0, 0), CVector(x1, y0, 0), CVector(x1, y1, 0), CVector(x0, y1, 0)), CommandsMaterial); #if SBCLIENT_DEV_PIXEL_PROGRAM + d->enableFog(fogEnabled); d->activePixelProgram(NULL); #endif From 3865e6e56f52cc1074972317affe43e616f9cc90 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 05:03:47 +0200 Subject: [PATCH 018/137] Add function to check which pixel program profiles are available on a driver --- code/nel/include/nel/3d/driver.h | 20 ++++++++++++++++++- code/nel/src/3d/driver.cpp | 2 +- .../3d/driver/direct3d/driver_direct3d.cpp | 9 +++++---- .../src/3d/driver/direct3d/driver_direct3d.h | 5 ++--- .../direct3d/driver_direct3d_material.cpp | 6 +++--- .../driver_direct3d_pixel_program.cpp | 9 ++++++++- code/nel/src/3d/driver/opengl/driver_opengl.h | 1 + .../opengl/driver_opengl_pixel_program.cpp | 7 ++++++- code/snowballs2/client/src/commands.cpp | 12 +++++++---- 9 files changed, 53 insertions(+), 18 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 9a079d95d..9e77e31d6 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -142,6 +142,23 @@ public: */ enum TMatrixCount { MaxModelMatrix= 16 }; + enum TPixelProgramProfile + { + // direct3d + ps_1_1 = 0xD3D00101, + ps_1_2 = 0xD3D00102, + ps_1_3 = 0xD3D00103, + ps_1_4 = 0xD3D00104, + ps_2_0 = 0xD3D00200, + ps_2_x = 0xD3D00201, // not sure... + ps_3_0 = 0xD3D00300, + + // opengl + arbfp1 = 0x061A0100, // made up values + fp20 = 0x06100200, + fp30 = 0x06100300, + fp40 = 0x06100400, + }; protected: @@ -1015,7 +1032,8 @@ public: /** * Does the driver supports pixel programs ? */ - virtual bool isPixelProgramSupported () const =0; + virtual bool isPixelProgramSupported() const =0; + virtual bool isPixelProgramSupported(TPixelProgramProfile profile) const =0; diff --git a/code/nel/src/3d/driver.cpp b/code/nel/src/3d/driver.cpp index d44079749..5a08da982 100644 --- a/code/nel/src/3d/driver.cpp +++ b/code/nel/src/3d/driver.cpp @@ -33,7 +33,7 @@ namespace NL3D { // *************************************************************************** -const uint32 IDriver::InterfaceVersion = 0x6b; // added anisotropic filter +const uint32 IDriver::InterfaceVersion = 0x6c; // pixel program interface // *************************************************************************** IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" ) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index 26cf628e0..e33075b60 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -1551,14 +1551,15 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r #endif // NL_FORCE_TEXTURE_STAGE_COUNT _VertexProgram = !_DisableHardwareVertexProgram && ((caps.VertexShaderVersion&0xffff) >= 0x0100); - _PixelProgram = !_DisableHardwarePixelProgram && (caps.PixelShaderVersion&0xffff) >= 0x0101; - _PixelShader = !_DisableHardwarePixelShader && (caps.PixelShaderVersion&0xffff) >= 0x0101; + _PixelProgramVersion = _DisableHardwareVertexProgram ? 0x0000 : caps.PixelShaderVersion & 0xffff; + nldebug("Pixel Program Version: %i.%i", (uint32)((_PixelProgramVersion & 0xFF00) >> 8), (uint32)(_PixelProgramVersion & 0xFF)); + _PixelProgram = _PixelProgramVersion >= 0x0101; _MaxVerticesByVertexBufferHard = caps.MaxVertexIndex; _MaxLight = caps.MaxActiveLights; if(_MaxLight > 0xFF) _MaxLight = 3; - if (_PixelShader) + if (_PixelProgram) { _MaxNumPerStageConstantLighted = _NbNeLTextureStages; _MaxNumPerStageConstantUnlighted = _NbNeLTextureStages; @@ -3626,7 +3627,7 @@ void CDriverD3D::CVertexProgramPtrState::apply(CDriverD3D *driver) void CDriverD3D::CPixelShaderPtrState::apply(CDriverD3D *driver) { H_AUTO_D3D(CDriverD3D_CPixelShaderPtrState); - if (!driver->supportPixelShaders()) return; + if (!driver->isPixelProgramSupported()) return; driver->_DeviceInterface->SetPixelShader(PixelShader); } diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 7668bd63c..465689838 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -1008,6 +1008,7 @@ public: // Vertex program virtual bool isVertexProgramSupported () const; virtual bool isPixelProgramSupported () const; + virtual bool isPixelProgramSupported (TPixelProgramProfile profile) const; virtual bool isVertexProgramEmulated () const; virtual bool activeVertexProgram (CVertexProgram *program); virtual bool activePixelProgram (CPixelProgram *program); @@ -1065,8 +1066,6 @@ public: uint32 getMaxVertexIndex() const { return _MaxVertexIndex; } - bool supportPixelShaders() const { return _PixelShader; } - // *** Inline info uint inlGetNumTextStages() const { return _NbNeLTextureStages; } @@ -2232,7 +2231,7 @@ private: bool _TextureCubeSupported; bool _VertexProgram; bool _PixelProgram; - bool _PixelShader; + uint16 _PixelProgramVersion; bool _DisableHardwareVertexProgram; bool _DisableHardwarePixelProgram; bool _DisableHardwareVertexArrayAGP; diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp index a7d218e79..eb550c2cc 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp @@ -567,7 +567,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) normalShaderDesc.TexEnvMode[stage] = mat.getTexEnvMode(uint8(stage)); } - if (_PixelShader) + if (_PixelProgram) { #ifdef NL_DEBUG_D3D // Check, should not occured @@ -933,7 +933,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) activeShader (NULL); /* If unlighted trick is needed, set the shader later */ - if (!pShader->NeedsConstantForDiffuse && _PixelShader) + if (!pShader->NeedsConstantForDiffuse && _PixelProgram) setPixelShader (pShader->PixelShader); } break; @@ -2019,7 +2019,7 @@ void CDriverD3D::endMaterialMultiPass() bool CDriverD3D::supportCloudRenderSinglePass () const { H_AUTO_D3D(CDriver3D_supportCloudRenderSinglePass); - return _PixelShader; + return _PixelProgram; } // *************************************************************************** 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 08ac5d74b..2d7303589 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 @@ -56,10 +56,17 @@ CPixelProgramDrvInfosD3D::~CPixelProgramDrvInfosD3D() bool CDriverD3D::isPixelProgramSupported () const { - H_AUTO_D3D(CDriverD3D_isPixelProgramSupported ) + H_AUTO_D3D(CDriverD3D_isPixelProgramSupported) return _PixelProgram; } +bool CDriverD3D::isPixelProgramSupported (TPixelProgramProfile profile) const +{ + H_AUTO_D3D(CDriverD3D_isPixelProgramSupported_profile) + return ((profile & 0xFFFF0000) == 0xD3D00000) + && (_PixelProgramVersion >= (uint16)(profile & 0x0000FFFF)); +} + // *************************************************************************** bool CDriverD3D::activePixelProgram(CPixelProgram *program) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index f53f6f535..3f7487937 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1305,6 +1305,7 @@ private: bool isVertexProgramSupported () const; bool isPixelProgramSupported () const; + bool isPixelProgramSupported (TPixelProgramProfile profile) const; bool isVertexProgramEmulated () const; bool activeVertexProgram (CVertexProgram *program); bool activePixelProgram (CPixelProgram *program); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index 18ce82846..5cc3316c1 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -57,11 +57,16 @@ CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInf } // *************************************************************************** -bool CDriverGL::isPixelProgramSupported () const +bool CDriverGL::isPixelProgramSupported() const { H_AUTO_OGL(CPixelProgamDrvInfosGL_isPixelProgramSupported) return _Extensions.ARBFragmentProgram; } +bool CDriverGL::isPixelProgramSupported(TPixelProgramProfile profile) const +{ + H_AUTO_OGL(CPixelProgamDrvInfosGL_isPixelProgramSupported_profile) + return profile == arbfp1 && _Extensions.ARBFragmentProgram; +} // *************************************************************************** bool CDriverGL::activePixelProgram(CPixelProgram *program) diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index fe33e566a..a92f296c8 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -246,7 +246,7 @@ void cbUpdateCommands (CConfigFile::CVar &var) #if SBCLIENT_DEV_PIXEL_PROGRAM namespace { -CPixelProgram *a_DevPixelProgram; +CPixelProgram *a_DevPixelProgram = NULL; } #endif @@ -294,16 +294,20 @@ void initCommands() #if SBCLIENT_DEV_PIXEL_PROGRAM CommandsMaterial.getObjectPtr()->setShader(NL3D::CMaterial::PostProcessing); - static const char *program_arbfp10 = + static const char *program_arbfp1 = "!!ARBfp1.0\n" "PARAM red = {1.0, 0.0, 0.0, 1.0};\n" "MOV result.color, red;\n" "END\n"; - static const char *program_ps10 = + static const char *program_ps_1_1 = "ps.1.1\n" "def c0, 1.0, 0.0, 0.0, 1.0\n" "mov r0, c0\n"; - a_DevPixelProgram = new CPixelProgram(program_ps10); + NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); + if (d->isPixelProgramSupported(IDriver::arbfp1)) + a_DevPixelProgram = new CPixelProgram(program_arbfp1); + if (d->isPixelProgramSupported(IDriver::ps_1_1)) + a_DevPixelProgram = new CPixelProgram(program_ps_1_1); #endif } From 4cc4a84578e88cd664b8464100fcb94bf191cf49 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 16:18:09 +0200 Subject: [PATCH 019/137] Fix linux compile --- .../opengl/driver_opengl_pixel_program.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index 5cc3316c1..a70fbb42d 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -28,8 +28,8 @@ #include "stdopengl.h" #include "driver_opengl.h" -#include -#include +#include "nel/3d/index_buffer.h" +#include "nel/3d/pixel_program.h" #include // tmp @@ -37,11 +37,17 @@ using namespace std; using namespace NLMISC; - -//#define DEBUG_SETUP_EXT_VERTEX_SHADER namespace NL3D { + +#ifdef NL_STATIC +#ifdef USE_OPENGLES +namespace NLDRIVERGLES { +#else +namespace NLDRIVERGL { +#endif +#endif // *************************************************************************** CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it) @@ -316,4 +322,8 @@ void CDriverGL::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matr } } +#ifdef NL_STATIC +} // NLDRIVERGL/ES +#endif + } // NL3D From 1224d570372652b5e3a4542118438e263404142d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 16:22:48 +0200 Subject: [PATCH 020/137] Updated snowballs default config --- code/snowballs2/bin/snowballs_client_default.cfg | 8 ++++++++ 1 file changed, 8 insertions(+) mode change 100644 => 100755 code/snowballs2/bin/snowballs_client_default.cfg diff --git a/code/snowballs2/bin/snowballs_client_default.cfg b/code/snowballs2/bin/snowballs_client_default.cfg old mode 100644 new mode 100755 index 37b958820..ba9178e19 --- a/code/snowballs2/bin/snowballs_client_default.cfg +++ b/code/snowballs2/bin/snowballs_client_default.cfg @@ -256,6 +256,14 @@ RetrieverBankName = "snowballs.rbank"; GlobalRetrieverName = "snowballs.gr"; +////////////////////////////////////////////////////////////////////////////// +// Bloom Variables /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +SquareBloom = 1; +DensityBloom = 128; + + ////////////////////////////////////////////////////////////////////////////// // Compass interface Variables /////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// From cfb9827b2c1fbc9be2d884cb1dd3a110d5eaea22 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 20:47:23 +0200 Subject: [PATCH 021/137] Test texture with postprocessing material, seems to work with opengl --- code/nel/include/nel/3d/driver.h | 14 +++--- code/snowballs2/bin/pp_test.cg | 13 +++++ code/snowballs2/client/src/commands.cpp | 65 ++++++++++++++++++++----- 3 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 code/snowballs2/bin/pp_test.cg diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 9e77e31d6..58db119c0 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -144,7 +144,7 @@ public: enum TPixelProgramProfile { - // direct3d + // direct3d - 0xD3D0,major,minor ps_1_1 = 0xD3D00101, ps_1_2 = 0xD3D00102, ps_1_3 = 0xD3D00103, @@ -153,11 +153,13 @@ public: ps_2_x = 0xD3D00201, // not sure... ps_3_0 = 0xD3D00300, - // opengl - arbfp1 = 0x061A0100, // made up values - fp20 = 0x06100200, - fp30 = 0x06100300, - fp40 = 0x06100400, + // opengl - 0x0610,bitfield + arbfp1 = 0x06100001, // ARB_fragment_program + // fp20 = 0x061B0002, + fp30 = 0x06100004, // NV_fragment_program + fp40 = 0x06100008, // NV_fragment_program2 + gp4fp = 0x06100010, // NV_gpu_program4 + gp5fp = 0x06100020, // NV_gpu_program5 }; protected: diff --git a/code/snowballs2/bin/pp_test.cg b/code/snowballs2/bin/pp_test.cg new file mode 100644 index 000000000..f44c2d424 --- /dev/null +++ b/code/snowballs2/bin/pp_test.cg @@ -0,0 +1,13 @@ +void pp_test( + // Per fragment parameters + float2 texCoord : TEXCOORD0, + + // Fragment program constants + uniform sampler2D cTex0 : TEX0, + + // Output color + out float4 oCol : COLOR) +{ + oCol.rba = float3(1.0, 0.0, 1.0); + oCol.g = tex2D(cTex0, texCoord).g; +} \ No newline at end of file diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index a92f296c8..09f7b354c 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #endif // @@ -247,6 +248,7 @@ void cbUpdateCommands (CConfigFile::CVar &var) #if SBCLIENT_DEV_PIXEL_PROGRAM namespace { CPixelProgram *a_DevPixelProgram = NULL; +UTextureFile *a_NelLogo; } #endif @@ -294,20 +296,44 @@ void initCommands() #if SBCLIENT_DEV_PIXEL_PROGRAM CommandsMaterial.getObjectPtr()->setShader(NL3D::CMaterial::PostProcessing); - static const char *program_arbfp1 = + /*static const char *program_arbfp1 = "!!ARBfp1.0\n" - "PARAM red = {1.0, 0.0, 0.0, 1.0};\n" - "MOV result.color, red;\n" + "PARAM c[1] = { { 0, 1 } };\n" + "MOV result.color, c[0].xyxy;\n" "END\n"; - static const char *program_ps_1_1 = + static const char *program_ps_2_0 = "ps.1.1\n" "def c0, 1.0, 0.0, 0.0, 1.0\n" - "mov r0, c0\n"; + "mov r0, c0\n";*/ + a_NelLogo = Driver->createTextureFile("nel128.tga"); + CommandsMaterial.setTexture(dynamic_cast(a_NelLogo)); + /*CommandsMaterial.setBlend (false); + CommandsMaterial.setAlphaTest (false); + CommandsMaterial.setBlendFunc (UMaterial::one, UMaterial::zero); + CommandsMaterial.setZWrite(false); + CommandsMaterial.setZFunc(UMaterial::always); + CommandsMaterial.setDoubleSided(true);*/ + //CommandsMaterial.set + static const char *program_arbfp1 = + "!!ARBfp1.0\n" + "PARAM c[1] = { { 1, 0 } };\n" + "MOV result.color.xzw, c[0].xyyx;\n" + "TEX result.color.y, fragment.texcoord[0], texture[0], 2D;\n" + "END\n"; + static const char *program_ps_2_0 = + "ps_2_0\n" + "dcl_2d s0\n" + "def c0, 1.00000000, 0.00000000, 0, 0\n" + "dcl t0.xy\n" + "texld r0, t0, s0\n" + "mov r0.z, c0.y\n" + "mov r0.xw, c0.x\n" + "mov oC0, r0\n"; NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); if (d->isPixelProgramSupported(IDriver::arbfp1)) a_DevPixelProgram = new CPixelProgram(program_arbfp1); - if (d->isPixelProgramSupported(IDriver::ps_1_1)) - a_DevPixelProgram = new CPixelProgram(program_ps_1_1); + if (d->isPixelProgramSupported(IDriver::ps_2_0)) + a_DevPixelProgram = new CPixelProgram(program_ps_2_0); #endif } @@ -327,7 +353,11 @@ void updateCommands() // Display the background Driver->setMatrixMode2D11 (); +#if SBCLIENT_DEV_PIXEL_PROGRAM + CommandsMaterial.setColor(CRGBA::Blue); // Test to check which shader is displaying. +#else CommandsMaterial.setColor(CommandsBackColor); +#endif float x0 = CommandsBoxX - CommandsBoxBorderX; float y0 = CommandsBoxY - CommandsBoxBorderY; float x1 = CommandsBoxX + CommandsBoxWidth + CommandsBoxBorderX; @@ -338,13 +368,26 @@ void updateCommands() d->activePixelProgram(a_DevPixelProgram); bool fogEnabled = d->fogEnabled(); d->enableFog(false); -#endif + + // Driver->drawQuad(CQuad(CVector(x0, y0, 0), CVector(x1, y0, 0), CVector(x1, y1, 0), CVector(x0, y1, 0)), CommandsMaterial); + CQuadUV quadUV; + quadUV.V0 = CVector(x0, y0, 0); + quadUV.V1 = CVector(x1, y0, 0); + quadUV.V2 = CVector(x1, y1, 0); + quadUV.V3 = CVector(x0, y1, 0); + quadUV.Uv0 = CUV(0, 1); + quadUV.Uv1 = CUV(1, 1); + quadUV.Uv2 = CUV(1, 0); + quadUV.Uv3 = CUV(0, 0); + Driver->drawQuad(quadUV, CommandsMaterial); + //Driver->drawBitmap(x0, y0, x1 - x0, y1 - y0, *a_NelLogo); + + d->enableFog(fogEnabled); + d->activePixelProgram(NULL); +#else Driver->drawQuad(CQuad(CVector(x0, y0, 0), CVector(x1, y0, 0), CVector(x1, y1, 0), CVector(x0, y1, 0)), CommandsMaterial); -#if SBCLIENT_DEV_PIXEL_PROGRAM - d->enableFog(fogEnabled); - d->activePixelProgram(NULL); #endif // Set the text context From 0d1e405d3ea18bd83d6501e4fa1fbe0d725eadb5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 21:16:13 +0200 Subject: [PATCH 022/137] Activate textures for postprocessing material under direct3d --- code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp index eb550c2cc..07ec5187b 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp @@ -648,7 +648,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) // Must separate texture setup and texture activation in 2 "for"... // because setupTexture() may disable all stage. - if (matShader == CMaterial::Normal) + if (matShader == CMaterial::Normal || matShader == CMaterial::PostProcessing) { uint stage; for(stage=0 ; stage Date: Wed, 19 Jun 2013 21:31:29 +0200 Subject: [PATCH 023/137] Additional test, textures does not seem to work in ps_3_0 --- code/snowballs2/client/src/commands.cpp | 50 ++++++++++++++++--------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index 09f7b354c..e1039a1ea 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -296,30 +296,22 @@ void initCommands() #if SBCLIENT_DEV_PIXEL_PROGRAM CommandsMaterial.getObjectPtr()->setShader(NL3D::CMaterial::PostProcessing); - /*static const char *program_arbfp1 = - "!!ARBfp1.0\n" - "PARAM c[1] = { { 0, 1 } };\n" - "MOV result.color, c[0].xyxy;\n" - "END\n"; - static const char *program_ps_2_0 = - "ps.1.1\n" - "def c0, 1.0, 0.0, 0.0, 1.0\n" - "mov r0, c0\n";*/ a_NelLogo = Driver->createTextureFile("nel128.tga"); CommandsMaterial.setTexture(dynamic_cast(a_NelLogo)); - /*CommandsMaterial.setBlend (false); - CommandsMaterial.setAlphaTest (false); - CommandsMaterial.setBlendFunc (UMaterial::one, UMaterial::zero); - CommandsMaterial.setZWrite(false); - CommandsMaterial.setZFunc(UMaterial::always); - CommandsMaterial.setDoubleSided(true);*/ - //CommandsMaterial.set static const char *program_arbfp1 = "!!ARBfp1.0\n" "PARAM c[1] = { { 1, 0 } };\n" "MOV result.color.xzw, c[0].xyyx;\n" "TEX result.color.y, fragment.texcoord[0], texture[0], 2D;\n" "END\n"; + static const char *program_ps_1_1 = + "ps.1.1\n" + "def c0, 0.000000, 0.000000, 1.000000, 0.000000\n" + "def c1, 1.000000, 0.000000, 0.000000, 0.000000\n" + "def c2, 0.000000, 1.000000, 0.000000, 0.000000\n" + "tex t0\n" + "mad r0.rgb, c2, t0, c1\n" + "mov r0.a, c0.b\n"; static const char *program_ps_2_0 = "ps_2_0\n" "dcl_2d s0\n" @@ -329,11 +321,35 @@ void initCommands() "mov r0.z, c0.y\n" "mov r0.xw, c0.x\n" "mov oC0, r0\n"; + static const char *program_ps_3_0 = + "ps_3_0\n" + "dcl_2d s0\n" + "def c0, 1.00000000, 0.00000000, 0, 0\n" + "dcl_texcoord0 v0.xy\n" + "mov oC0.xzw, c0.xyyx\n" + "texld oC0.y, v0, s0\n"; NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); if (d->isPixelProgramSupported(IDriver::arbfp1)) + { + nldebug("arbfp1"); a_DevPixelProgram = new CPixelProgram(program_arbfp1); - if (d->isPixelProgramSupported(IDriver::ps_2_0)) + } + /*else if (d->isPixelProgramSupported(IDriver::ps_3_0)) + { + nldebug("ps_3_0"); + a_DevPixelProgram = new CPixelProgram(program_ps_3_0); + // Textures do not seem to work with ps_3_0... + }*/ + else if (d->isPixelProgramSupported(IDriver::ps_2_0)) + { + nldebug("ps_2_0"); a_DevPixelProgram = new CPixelProgram(program_ps_2_0); + } + else if (d->isPixelProgramSupported(IDriver::ps_1_1)) + { + nldebug("ps_1_1"); + a_DevPixelProgram = new CPixelProgram(program_ps_1_1); + } #endif } From aa3462b7bc2c244950534055590f7ea19ea9b632 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 22:41:03 +0200 Subject: [PATCH 024/137] Add support for fp40 with opengl --- code/nel/include/nel/3d/driver.h | 6 +++--- .../driver/opengl/driver_opengl_extension.cpp | 17 +++++++++++++---- .../3d/driver/opengl/driver_opengl_extension.h | 4 ++++ .../opengl/driver_opengl_pixel_program.cpp | 8 +++++++- code/snowballs2/client/src/commands.cpp | 17 ++++++++++++++++- 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 58db119c0..ee040df78 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -155,9 +155,9 @@ public: // opengl - 0x0610,bitfield arbfp1 = 0x06100001, // ARB_fragment_program - // fp20 = 0x061B0002, - fp30 = 0x06100004, // NV_fragment_program - fp40 = 0x06100008, // NV_fragment_program2 + // fp20 = 0x061B0002, // very limited and outdated, unnecessary + // fp30 = 0x06100004, // NV_fragment_program, now arbfp1, redundant + fp40 = 0x06100008, // NV_fragment_program2, arbfp1 with "OPTION NV_fragment_program2;\n" gp4fp = 0x06100010, // NV_gpu_program4 gp5fp = 0x06100020, // NV_gpu_program5 }; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp index e777d2696..3b771e1c1 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp @@ -1225,6 +1225,15 @@ static bool setupARBFragmentProgram(const char *glext) return true; } +// ********************************* +static bool setupNVFragmentProgram2(const char *glext) +{ + H_AUTO_OGL(setupNVFragmentProgram2); + CHECK_EXT("GL_NV_fragment_program2"); + + return true; +} + // *************************************************************************** static bool setupARBVertexBufferObject(const char *glext) { @@ -1563,13 +1572,15 @@ void registerGlExtensions(CGlExtensions &ext) // Check pixel program // Disable feature ??? - if(!ext.DisableHardwarePixelProgram) + if (!ext.DisableHardwarePixelProgram) { - ext.ARBFragmentProgram= setupARBFragmentProgram(glext); + ext.ARBFragmentProgram = setupARBFragmentProgram(glext); + ext.NVFragmentProgram2 = setupNVFragmentProgram2(glext); } else { ext.ARBFragmentProgram = false; + ext.NVFragmentProgram2 = false; } ext.OESDrawTexture = setupOESDrawTexture(glext); @@ -1582,14 +1593,12 @@ void registerGlExtensions(CGlExtensions &ext) ext.NVTextureShader = setupNVTextureShader(glext); ext.ATIEnvMapBumpMap = setupATIEnvMapBumpMap(glext); ext.ATIFragmentShader = setupATIFragmentShader(glext); - ext.ARBFragmentProgram = setupARBFragmentProgram(glext); } else { ext.ATIEnvMapBumpMap = false; ext.NVTextureShader = false; ext.ATIFragmentShader = false; - ext.ARBFragmentProgram = false; } // For now, the only way to know if emulation, is to test some extension which exist only on GeForce3. diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h index d6d4974a6..fe7738fd8 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h @@ -103,6 +103,9 @@ struct CGlExtensions bool ARBTextureNonPowerOfTwo; bool ARBMultisample; + // NV Pixel Programs + bool NVFragmentProgram2; + bool OESDrawTexture; bool OESMapBuffer; @@ -208,6 +211,7 @@ public: result += NVTextureShader ? "NVTextureShader " : ""; result += ATIFragmentShader ? "ATIFragmentShader " : ""; result += ARBFragmentProgram ? "ARBFragmentProgram " : ""; + result += NVFragmentProgram2 ? "NVFragmentProgram2 " : ""; result += ARBVertexProgram ? "ARBVertexProgram " : ""; result += NVVertexProgram ? "NVVertexProgram " : ""; result += EXTVertexShader ? "EXTVertexShader " : ""; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index a70fbb42d..4131c76b1 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -71,7 +71,13 @@ bool CDriverGL::isPixelProgramSupported() const bool CDriverGL::isPixelProgramSupported(TPixelProgramProfile profile) const { H_AUTO_OGL(CPixelProgamDrvInfosGL_isPixelProgramSupported_profile) - return profile == arbfp1 && _Extensions.ARBFragmentProgram; + switch (profile) + { + case arbfp1: + return _Extensions.ARBFragmentProgram; + case fp40: + return _Extensions.NVFragmentProgram2; + } } // *************************************************************************** diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index e1039a1ea..5c1274472 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -304,6 +304,16 @@ void initCommands() "MOV result.color.xzw, c[0].xyyx;\n" "TEX result.color.y, fragment.texcoord[0], texture[0], 2D;\n" "END\n"; + static const char *program_fp40 = + "!!ARBfp1.0\n" + "OPTION NV_fragment_program2;\n" + "PARAM c[1] = { { 1, 0 } };\n" + "TEMP RC;\n" + "TEMP HC;\n" + "OUTPUT oCol = result.color;\n" + "MOVR oCol.xzw, c[0].xyyx;\n" + "TEX oCol.y, fragment.texcoord[0], texture[0], 2D;\n" + "END\n"; static const char *program_ps_1_1 = "ps.1.1\n" "def c0, 0.000000, 0.000000, 1.000000, 0.000000\n" @@ -329,7 +339,12 @@ void initCommands() "mov oC0.xzw, c0.xyyx\n" "texld oC0.y, v0, s0\n"; NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); - if (d->isPixelProgramSupported(IDriver::arbfp1)) + if (d->isPixelProgramSupported(IDriver::fp40)) + { + nldebug("fp40"); + a_DevPixelProgram = new CPixelProgram(program_fp40); + } + else if (d->isPixelProgramSupported(IDriver::arbfp1)) { nldebug("arbfp1"); a_DevPixelProgram = new CPixelProgram(program_arbfp1); From 1ed0d46026dbb208c7c32f87e4ab4411686d8b4c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 23:34:40 +0200 Subject: [PATCH 025/137] Cleanup --- code/nel/include/nel/3d/driver.h | 22 +------------------ code/nel/include/nel/3d/material.h | 2 +- code/nel/include/nel/3d/pixel_program.h | 20 +++++++++++++++++ .../src/3d/driver/direct3d/driver_direct3d.h | 2 +- .../driver_direct3d_pixel_program.cpp | 2 +- code/nel/src/3d/driver/opengl/driver_opengl.h | 2 +- .../opengl/driver_opengl_pixel_program.cpp | 6 ++--- code/snowballs2/client/src/commands.cpp | 10 ++++----- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index ee040df78..3644fefca 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -142,26 +142,6 @@ public: */ enum TMatrixCount { MaxModelMatrix= 16 }; - enum TPixelProgramProfile - { - // direct3d - 0xD3D0,major,minor - ps_1_1 = 0xD3D00101, - ps_1_2 = 0xD3D00102, - ps_1_3 = 0xD3D00103, - ps_1_4 = 0xD3D00104, - ps_2_0 = 0xD3D00200, - ps_2_x = 0xD3D00201, // not sure... - ps_3_0 = 0xD3D00300, - - // opengl - 0x0610,bitfield - arbfp1 = 0x06100001, // ARB_fragment_program - // fp20 = 0x061B0002, // very limited and outdated, unnecessary - // fp30 = 0x06100004, // NV_fragment_program, now arbfp1, redundant - fp40 = 0x06100008, // NV_fragment_program2, arbfp1 with "OPTION NV_fragment_program2;\n" - gp4fp = 0x06100010, // NV_gpu_program4 - gp5fp = 0x06100020, // NV_gpu_program5 - }; - protected: CSynchronized _SyncTexDrvInfos; @@ -1035,7 +1015,7 @@ public: * Does the driver supports pixel programs ? */ virtual bool isPixelProgramSupported() const =0; - virtual bool isPixelProgramSupported(TPixelProgramProfile profile) const =0; + virtual bool isPixelProgramSupported(CPixelProgram::TProfile profile) const =0; diff --git a/code/nel/include/nel/3d/material.h b/code/nel/include/nel/3d/material.h index b9f063af1..bf00f9741 100644 --- a/code/nel/include/nel/3d/material.h +++ b/code/nel/include/nel/3d/material.h @@ -175,7 +175,7 @@ public: * - Water * PostProcessing : * - For internal use only when a pixel program is set manually through activePixelProgram. - * - Only textures are set by CMaterial (probably does not work yet), the rest must be set manually. + * - 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, diff --git a/code/nel/include/nel/3d/pixel_program.h b/code/nel/include/nel/3d/pixel_program.h index 811dbe0e1..6e14f0f04 100644 --- a/code/nel/include/nel/3d/pixel_program.h +++ b/code/nel/include/nel/3d/pixel_program.h @@ -59,6 +59,26 @@ class CPixelProgram : public NLMISC::CRefCount { public: + enum TProfile + { + // direct3d - 0xD3D0,major,minor + ps_1_1 = 0xD3D00101, + ps_1_2 = 0xD3D00102, + ps_1_3 = 0xD3D00103, + ps_1_4 = 0xD3D00104, + ps_2_0 = 0xD3D00200, + ps_2_x = 0xD3D00201, // not sure... + ps_3_0 = 0xD3D00300, + + // opengl - 0x0610,bitfield + // fp20 = 0x061B0001, // very limited and outdated, unnecessary + // fp30 = 0x06100002, // NV_fragment_program, now arbfp1, redundant + arbfp1 = 0x06100004, // ARB_fragment_program + fp40 = 0x06100008, // NV_fragment_program2, arbfp1 with "OPTION NV_fragment_program2;\n" + gp4fp = 0x06100010, // NV_gpu_program4 + gp5fp = 0x06100020, // NV_gpu_program5 + }; + /// Constructor CPixelProgram (const char* program); diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 465689838..cb6975725 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -1008,7 +1008,7 @@ public: // Vertex program virtual bool isVertexProgramSupported () const; virtual bool isPixelProgramSupported () const; - virtual bool isPixelProgramSupported (TPixelProgramProfile profile) const; + virtual bool isPixelProgramSupported (CPixelProgram::TProfile profile) const; virtual bool isVertexProgramEmulated () const; virtual bool activeVertexProgram (CVertexProgram *program); virtual bool activePixelProgram (CPixelProgram *program); 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 2d7303589..d27019fff 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 @@ -60,7 +60,7 @@ bool CDriverD3D::isPixelProgramSupported () const return _PixelProgram; } -bool CDriverD3D::isPixelProgramSupported (TPixelProgramProfile profile) const +bool CDriverD3D::isPixelProgramSupported (CPixelProgram::TProfile profile) const { H_AUTO_D3D(CDriverD3D_isPixelProgramSupported_profile) return ((profile & 0xFFFF0000) == 0xD3D00000) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 3f7487937..a46d8c704 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1305,7 +1305,7 @@ private: bool isVertexProgramSupported () const; bool isPixelProgramSupported () const; - bool isPixelProgramSupported (TPixelProgramProfile profile) const; + bool isPixelProgramSupported (CPixelProgram::TProfile profile) const; bool isVertexProgramEmulated () const; bool activeVertexProgram (CVertexProgram *program); bool activePixelProgram (CPixelProgram *program); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index 4131c76b1..74a1127c6 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -68,14 +68,14 @@ bool CDriverGL::isPixelProgramSupported() const H_AUTO_OGL(CPixelProgamDrvInfosGL_isPixelProgramSupported) return _Extensions.ARBFragmentProgram; } -bool CDriverGL::isPixelProgramSupported(TPixelProgramProfile profile) const +bool CDriverGL::isPixelProgramSupported(CPixelProgram::TProfile profile) const { H_AUTO_OGL(CPixelProgamDrvInfosGL_isPixelProgramSupported_profile) switch (profile) { - case arbfp1: + case CPixelProgram::arbfp1: return _Extensions.ARBFragmentProgram; - case fp40: + case CPixelProgram::fp40: return _Extensions.NVFragmentProgram2; } } diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index 5c1274472..46c655a5b 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -339,28 +339,28 @@ void initCommands() "mov oC0.xzw, c0.xyyx\n" "texld oC0.y, v0, s0\n"; NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); - if (d->isPixelProgramSupported(IDriver::fp40)) + if (d->isPixelProgramSupported(CPixelProgram::fp40)) { nldebug("fp40"); a_DevPixelProgram = new CPixelProgram(program_fp40); } - else if (d->isPixelProgramSupported(IDriver::arbfp1)) + else if (d->isPixelProgramSupported(CPixelProgram::arbfp1)) { nldebug("arbfp1"); a_DevPixelProgram = new CPixelProgram(program_arbfp1); } - /*else if (d->isPixelProgramSupported(IDriver::ps_3_0)) + /*else if (d->isPixelProgramSupported(CPixelProgram::ps_3_0)) { nldebug("ps_3_0"); a_DevPixelProgram = new CPixelProgram(program_ps_3_0); // Textures do not seem to work with ps_3_0... }*/ - else if (d->isPixelProgramSupported(IDriver::ps_2_0)) + else if (d->isPixelProgramSupported(CPixelProgram::ps_2_0)) { nldebug("ps_2_0"); a_DevPixelProgram = new CPixelProgram(program_ps_2_0); } - else if (d->isPixelProgramSupported(IDriver::ps_1_1)) + else if (d->isPixelProgramSupported(CPixelProgram::ps_1_1)) { nldebug("ps_1_1"); a_DevPixelProgram = new CPixelProgram(program_ps_1_1); From 1f680259312b652fdaad14b8b7d88138797e03dd Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 19 Jun 2013 23:49:39 +0200 Subject: [PATCH 026/137] Rename some functions to follow the same naming convention of others --- code/nel/include/nel/3d/driver.h | 10 +++++----- code/nel/src/3d/driver/direct3d/driver_direct3d.cpp | 8 ++++---- code/nel/src/3d/driver/direct3d/driver_direct3d.h | 10 +++++----- .../driver/direct3d/driver_direct3d_pixel_program.cpp | 8 ++++---- .../driver/direct3d/driver_direct3d_vertex_program.cpp | 4 ++-- code/nel/src/3d/driver/opengl/driver_opengl.cpp | 10 +++++----- code/nel/src/3d/driver/opengl/driver_opengl.h | 10 +++++----- .../3d/driver/opengl/driver_opengl_pixel_program.cpp | 9 +++++---- .../3d/driver/opengl/driver_opengl_vertex_program.cpp | 4 ++-- code/nel/src/3d/landscape.cpp | 2 +- code/nel/src/3d/landscapevb_allocator.cpp | 2 +- code/nel/src/3d/meshvp_per_pixel_light.cpp | 2 +- code/nel/src/3d/meshvp_wind_tree.cpp | 4 ++-- code/nel/src/3d/ps_particle_basic.cpp | 10 +++++----- code/nel/src/3d/vegetablevb_allocator.cpp | 2 +- code/nel/src/3d/water_model.cpp | 8 ++++---- code/nel/src/3d/water_shape.cpp | 2 +- code/ryzom/client/src/decal.cpp | 2 +- code/snowballs2/client/src/commands.cpp | 10 +++++----- 19 files changed, 59 insertions(+), 58 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 3644fefca..32953e58b 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1004,7 +1004,7 @@ public: /** * Does the driver supports vertex programs ? */ - virtual bool isVertexProgramSupported () const =0; + virtual bool supportVertexProgram () const =0; /** * Does the driver supports vertex program, but emulated by CPU ? @@ -1014,8 +1014,8 @@ public: /** * Does the driver supports pixel programs ? */ - virtual bool isPixelProgramSupported() const =0; - virtual bool isPixelProgramSupported(CPixelProgram::TProfile profile) const =0; + virtual bool supportPixelProgram() const =0; + virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const =0; @@ -1122,10 +1122,10 @@ public: /// test whether the device supports some form of texture shader. (could be limited to DX6 EMBM for example) virtual bool supportTextureShaders() const = 0; // Is the shader water supported ? If not, the driver caller should implement its own version - virtual bool isWaterShaderSupported() const = 0; + virtual bool supportWaterShader() const = 0; // /// test whether a texture addressing mode is supported - virtual bool isTextureAddrModeSupported(CMaterial::TTexAddressingMode mode) const = 0; + virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode mode) const = 0; /** setup the 2D matrix for the OffsetTexture, OffsetTextureScale and OffsetTexture addressing mode * It should be stored as the following * [a0 a1] diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index e33075b60..8f8901f5c 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -2996,7 +2996,7 @@ bool CDriverD3D::stretchRect(ITexture * srcText, NLMISC::CRect &srcRect, ITextur bool CDriverD3D::supportBloomEffect() const { - return isVertexProgramSupported(); + return supportVertexProgram(); } // *************************************************************************** @@ -3339,9 +3339,9 @@ uint COcclusionQueryD3D::getVisibleCount() } // *************************************************************************** -bool CDriverD3D::isWaterShaderSupported() const +bool CDriverD3D::supportWaterShader() const { - H_AUTO_D3D(CDriverD3D_isWaterShaderSupported); + H_AUTO_D3D(CDriverD3D_supportWaterShader); return _PixelShaderVersion >= D3DPS_VERSION(1, 1); } @@ -3627,7 +3627,7 @@ void CDriverD3D::CVertexProgramPtrState::apply(CDriverD3D *driver) void CDriverD3D::CPixelShaderPtrState::apply(CDriverD3D *driver) { H_AUTO_D3D(CDriverD3D_CPixelShaderPtrState); - if (!driver->isPixelProgramSupported()) return; + if (!driver->supportPixelProgram()) return; driver->_DeviceInterface->SetPixelShader(PixelShader); } diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index cb6975725..779a62a5c 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -973,9 +973,9 @@ public: virtual bool supportTextureShaders() const {return false;}; virtual bool supportMADOperator() const; // todo hulud d3d adressing mode - virtual bool isWaterShaderSupported() const; + virtual bool supportWaterShader() const; // todo hulud d3d adressing mode - virtual bool isTextureAddrModeSupported(CMaterial::TTexAddressingMode /* mode */) const {return false;}; + virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode /* mode */) const {return false;}; // todo hulud d3d adressing mode virtual void setMatrix2DForTextureOffsetAddrMode(const uint /* stage */, const float /* mat */[4]) {} @@ -1006,9 +1006,9 @@ public: virtual void endMaterialMultiPass(); // Vertex program - virtual bool isVertexProgramSupported () const; - virtual bool isPixelProgramSupported () const; - virtual bool isPixelProgramSupported (CPixelProgram::TProfile profile) const; + virtual bool supportVertexProgram () const; + virtual bool supportPixelProgram () const; + virtual bool supportPixelProgram (CPixelProgram::TProfile profile) const; virtual bool isVertexProgramEmulated () const; virtual bool activeVertexProgram (CVertexProgram *program); virtual bool activePixelProgram (CPixelProgram *program); 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 d27019fff..8234fc31d 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 @@ -54,15 +54,15 @@ CPixelProgramDrvInfosD3D::~CPixelProgramDrvInfosD3D() // *************************************************************************** -bool CDriverD3D::isPixelProgramSupported () const +bool CDriverD3D::supportPixelProgram () const { - H_AUTO_D3D(CDriverD3D_isPixelProgramSupported) + H_AUTO_D3D(CDriverD3D_supportPixelProgram) return _PixelProgram; } -bool CDriverD3D::isPixelProgramSupported (CPixelProgram::TProfile profile) const +bool CDriverD3D::supportPixelProgram (CPixelProgram::TProfile profile) const { - H_AUTO_D3D(CDriverD3D_isPixelProgramSupported_profile) + H_AUTO_D3D(CDriverD3D_supportPixelProgram_profile) return ((profile & 0xFFFF0000) == 0xD3D00000) && (_PixelProgramVersion >= (uint16)(profile & 0x0000FFFF)); } 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 ce6bda220..a758aa7b3 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 @@ -43,9 +43,9 @@ CVertexProgamDrvInfosD3D::~CVertexProgamDrvInfosD3D() // *************************************************************************** -bool CDriverD3D::isVertexProgramSupported () const +bool CDriverD3D::supportVertexProgram () const { - H_AUTO_D3D(CDriverD3D_isVertexProgramSupported ) + H_AUTO_D3D(CDriverD3D_supportVertexProgram ) return _VertexProgram; } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index b3567ed90..42d8b4834 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -691,7 +691,7 @@ bool CDriverGL::stretchRect(ITexture * /* srcText */, NLMISC::CRect &/* srcRect // *************************************************************************** bool CDriverGL::supportBloomEffect() const { - return (isVertexProgramSupported() && supportFrameBufferObject() && supportPackedDepthStencil() && supportTextureRectangle()); + return (supportVertexProgram() && supportFrameBufferObject() && supportPackedDepthStencil() && supportTextureRectangle()); } // *************************************************************************** @@ -1539,9 +1539,9 @@ bool CDriverGL::supportTextureShaders() const } // *************************************************************************** -bool CDriverGL::isWaterShaderSupported() const +bool CDriverGL::supportWaterShader() const { - H_AUTO_OGL(CDriverGL_isWaterShaderSupported); + H_AUTO_OGL(CDriverGL_supportWaterShader); if(_Extensions.ARBFragmentProgram && ARBWaterShader[0] != 0) return true; @@ -1551,9 +1551,9 @@ bool CDriverGL::isWaterShaderSupported() const } // *************************************************************************** -bool CDriverGL::isTextureAddrModeSupported(CMaterial::TTexAddressingMode /* mode */) const +bool CDriverGL::supportTextureAddrMode(CMaterial::TTexAddressingMode /* mode */) const { - H_AUTO_OGL(CDriverGL_isTextureAddrModeSupported) + H_AUTO_OGL(CDriverGL_supportTextureAddrMode) if (_Extensions.NVTextureShader) { diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index a46d8c704..f88936a8a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -601,9 +601,9 @@ public: // @{ virtual bool supportTextureShaders() const; - virtual bool isWaterShaderSupported() const; + virtual bool supportWaterShader() const; - virtual bool isTextureAddrModeSupported(CMaterial::TTexAddressingMode mode) const; + virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode mode) const; virtual void setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4]); // @} @@ -1303,9 +1303,9 @@ private: /// \name Vertex program interface // @{ - bool isVertexProgramSupported () const; - bool isPixelProgramSupported () const; - bool isPixelProgramSupported (CPixelProgram::TProfile profile) const; + bool supportVertexProgram () const; + bool supportPixelProgram () const; + bool supportPixelProgram (CPixelProgram::TProfile profile) const; bool isVertexProgramEmulated () const; bool activeVertexProgram (CVertexProgram *program); bool activePixelProgram (CPixelProgram *program); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index 74a1127c6..2bcfc185d 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -63,14 +63,14 @@ CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInf } // *************************************************************************** -bool CDriverGL::isPixelProgramSupported() const +bool CDriverGL::supportPixelProgram() const { - H_AUTO_OGL(CPixelProgamDrvInfosGL_isPixelProgramSupported) + H_AUTO_OGL(CPixelProgamDrvInfosGL_supportPixelProgram) return _Extensions.ARBFragmentProgram; } -bool CDriverGL::isPixelProgramSupported(CPixelProgram::TProfile profile) const +bool CDriverGL::supportPixelProgram(CPixelProgram::TProfile profile) const { - H_AUTO_OGL(CPixelProgamDrvInfosGL_isPixelProgramSupported_profile) + H_AUTO_OGL(CPixelProgamDrvInfosGL_supportPixelProgram_profile) switch (profile) { case CPixelProgram::arbfp1: @@ -78,6 +78,7 @@ bool CDriverGL::isPixelProgramSupported(CPixelProgram::TProfile profile) const case CPixelProgram::fp40: return _Extensions.NVFragmentProgram2; } + return false; } // *************************************************************************** diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp index 5392bcbdd..1ddb42a7d 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp @@ -70,9 +70,9 @@ CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInf // *************************************************************************** -bool CDriverGL::isVertexProgramSupported () const +bool CDriverGL::supportVertexProgram () const { - H_AUTO_OGL(CVertexProgamDrvInfosGL_isVertexProgramSupported) + H_AUTO_OGL(CVertexProgamDrvInfosGL_supportVertexProgram) return _Extensions.NVVertexProgram || _Extensions.EXTVertexShader || _Extensions.ARBVertexProgram; } diff --git a/code/nel/src/3d/landscape.cpp b/code/nel/src/3d/landscape.cpp index 31f1bb051..e842ae369 100644 --- a/code/nel/src/3d/landscape.cpp +++ b/code/nel/src/3d/landscape.cpp @@ -574,7 +574,7 @@ void CLandscape::setDriver(IDriver *drv) // Does the driver support VertexShader??? // only if VP supported by GPU. - _VertexShaderOk= (_Driver->isVertexProgramSupported() && !_Driver->isVertexProgramEmulated()); + _VertexShaderOk= (_Driver->supportVertexProgram() && !_Driver->isVertexProgramEmulated()); // Does the driver has sufficient requirements for Vegetable??? diff --git a/code/nel/src/3d/landscapevb_allocator.cpp b/code/nel/src/3d/landscapevb_allocator.cpp index 00cf78f1f..f57d6ef8d 100644 --- a/code/nel/src/3d/landscapevb_allocator.cpp +++ b/code/nel/src/3d/landscapevb_allocator.cpp @@ -82,7 +82,7 @@ void CLandscapeVBAllocator::updateDriver(IDriver *driver) deleteVertexProgram(); // Then rebuild VB format, and VertexProgram, if needed. // Do it only if VP supported by GPU. - setupVBFormatAndVertexProgram(_Driver->isVertexProgramSupported() && !_Driver->isVertexProgramEmulated()); + setupVBFormatAndVertexProgram(_Driver->supportVertexProgram() && !_Driver->isVertexProgramEmulated()); // must reallocate the VertexBuffer. if( _NumVerticesAllocated>0 ) diff --git a/code/nel/src/3d/meshvp_per_pixel_light.cpp b/code/nel/src/3d/meshvp_per_pixel_light.cpp index ab84492c4..dd06e951c 100644 --- a/code/nel/src/3d/meshvp_per_pixel_light.cpp +++ b/code/nel/src/3d/meshvp_per_pixel_light.cpp @@ -428,7 +428,7 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, { // test if supported by driver if (! - (drv->isVertexProgramSupported() + (drv->supportVertexProgram() && !drv->isVertexProgramEmulated() && drv->supportPerPixelLighting(SpecularLighting) ) diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index bf04c6096..579557012 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -287,7 +287,7 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene // *************************************************************************** bool CMeshVPWindTree::begin(IDriver *driver, CScene *scene, CMeshBaseInstance *mbi, const NLMISC::CMatrix &invertedModelMat, const NLMISC::CVector & /*viewerPos*/) { - if (!(driver->isVertexProgramSupported() && !driver->isVertexProgramEmulated())) return false; + if (!(driver->supportVertexProgram() && !driver->isVertexProgramEmulated())) return false; // precompute mesh @@ -367,7 +367,7 @@ bool CMeshVPWindTree::supportMeshBlockRendering() const // *************************************************************************** bool CMeshVPWindTree::isMBRVpOk(IDriver *driver) const { - return driver->isVertexProgramSupported() && !driver->isVertexProgramEmulated(); + return driver->supportVertexProgram() && !driver->isVertexProgramEmulated(); } // *************************************************************************** diff --git a/code/nel/src/3d/ps_particle_basic.cpp b/code/nel/src/3d/ps_particle_basic.cpp index 1cb57d2bc..c2d6b6357 100644 --- a/code/nel/src/3d/ps_particle_basic.cpp +++ b/code/nel/src/3d/ps_particle_basic.cpp @@ -786,7 +786,7 @@ void CPSMultiTexturedParticle::setupMaterial(ITexture *primary, IDriver *driver, /// if bump is used, the matrix must be setupped each time (not a material field) if (!_ForceBasicCaps && isMultiTextureEnabled() && _MainOp == EnvBumpMap) { - if (driver->isTextureAddrModeSupported(CMaterial::OffsetTexture)) + if (driver->supportTextureAddrMode(CMaterial::OffsetTexture)) { CTextureBump *tb = dynamic_cast((ITexture *) _Texture2); if (tb != NULL) @@ -858,7 +858,7 @@ void CPSMultiTexturedParticle::setupMaterial(ITexture *primary, IDriver *driver, } else { - if (!_ForceBasicCaps && (driver->isTextureAddrModeSupported(CMaterial::OffsetTexture) || driver->supportEMBM())) // envbumpmap supported ? + if (!_ForceBasicCaps && (driver->supportTextureAddrMode(CMaterial::OffsetTexture) || driver->supportEMBM())) // envbumpmap supported ? { CTextureBump *tb = dynamic_cast((ITexture *) _Texture2); if (tb != NULL) @@ -917,7 +917,7 @@ void CPSMultiTexturedParticle::setupMultiTexEnv(TOperator op, ITexture *tex1, IT mat.enableTexAddrMode(false); break; case EnvBumpMap: - if (drv.isTextureAddrModeSupported(CMaterial::OffsetTexture)) + if (drv.supportTextureAddrMode(CMaterial::OffsetTexture)) { mat.setTexture(0, tex2); mat.setTexture(1, tex1); @@ -1113,7 +1113,7 @@ void CPSMultiTexturedParticle::enumTexs(std::vector NL_PS_FUNC(CPSMultiTexturedParticle_enumTexs) if (_MainOp == EnvBumpMap && !_ForceBasicCaps) { - if (drv.isTextureAddrModeSupported(CMaterial::OffsetTexture) || drv.supportEMBM()) + if (drv.supportTextureAddrMode(CMaterial::OffsetTexture) || drv.supportEMBM()) { if (_Texture2) dest.push_back(_Texture2); } @@ -1132,7 +1132,7 @@ bool CPSMultiTexturedParticle::isAlternateTextureUsed(IDriver &driver) const NL_PS_FUNC(CPSMultiTexturedParticle_isAlternateTextureUsed) if (!isTouched() && areBasicCapsForcedLocal() == areBasicCapsForced()) return (_MultiTexState & AlternateTextureUsed) != 0; if (_MainOp != EnvBumpMap) return false; - return _ForceBasicCaps || (!driver.isTextureAddrModeSupported(CMaterial::OffsetTexture) && !driver.supportEMBM()); + return _ForceBasicCaps || (!driver.supportTextureAddrMode(CMaterial::OffsetTexture) && !driver.supportEMBM()); } } // NL3D diff --git a/code/nel/src/3d/vegetablevb_allocator.cpp b/code/nel/src/3d/vegetablevb_allocator.cpp index 9c801b179..efbd1f5a3 100644 --- a/code/nel/src/3d/vegetablevb_allocator.cpp +++ b/code/nel/src/3d/vegetablevb_allocator.cpp @@ -98,7 +98,7 @@ void CVegetableVBAllocator::updateDriver(IDriver *driver) _VBHardOk= false; // Driver must support VP. - nlassert(_Driver->isVertexProgramSupported()); + nlassert(_Driver->supportVertexProgram()); // must reallocate the VertexBuffer. if( _NumVerticesAllocated>0 ) diff --git a/code/nel/src/3d/water_model.cpp b/code/nel/src/3d/water_model.cpp index ddf3d35b2..e72d7bab9 100644 --- a/code/nel/src/3d/water_model.cpp +++ b/code/nel/src/3d/water_model.cpp @@ -61,7 +61,7 @@ void CWaterModel::setupVertexBuffer(CVertexBuffer &vb, uint numWantedVertices, I vb.setNumVertices(0); vb.setName("Water"); vb.setPreferredMemory(CVertexBuffer::AGPPreferred, false); - if (drv->isWaterShaderSupported()) + if (drv->supportWaterShader()) { vb.setVertexFormat(CVertexBuffer::PositionFlag); } @@ -377,7 +377,7 @@ void CWaterModel::traverseRender() #ifndef FORCE_SIMPLE_WATER_RENDER - if (!drv->isWaterShaderSupported()) + if (!drv->supportWaterShader()) #endif { doSimpleRender(drv); @@ -1363,7 +1363,7 @@ uint CWaterModel::getNumWantedVertices() uint CWaterModel::fillVB(void *datas, uint startTri, IDriver &drv) { H_AUTO( NL3D_Water_Render ); - if (drv.isWaterShaderSupported()) + if (drv.supportWaterShader()) { return fillVBHard(datas, startTri); } @@ -1657,7 +1657,7 @@ void CWaterModel::traverseRender() drv->setupModelMatrix(modelMat); bool isAbove = obsPos.z > getWorldMatrix().getPos().z; CVertexBuffer &vb = renderTrav.Scene->getWaterVB(); - if (drv->isWaterShaderSupported()) + if (drv->supportWaterShader()) { setupMaterialNVertexShader(drv, shape, obsPos, isAbove, zHeight); nlassert(vb.getNumVertices() > 0); diff --git a/code/nel/src/3d/water_shape.cpp b/code/nel/src/3d/water_shape.cpp index 0196294c3..227b85254 100644 --- a/code/nel/src/3d/water_shape.cpp +++ b/code/nel/src/3d/water_shape.cpp @@ -372,7 +372,7 @@ void CWaterShape::flushTextures (IDriver &driver, uint selectedTexture) /* if ( - (driver.supportTextureShaders() && driver.isTextureAddrModeSupported(CMaterial::OffsetTexture)) + (driver.supportTextureShaders() && driver.supportTextureAddrMode(CMaterial::OffsetTexture)) || driver.supportEMBM() ) { diff --git a/code/ryzom/client/src/decal.cpp b/code/ryzom/client/src/decal.cpp index 45c5311ac..7aa4b3c3a 100644 --- a/code/ryzom/client/src/decal.cpp +++ b/code/ryzom/client/src/decal.cpp @@ -560,7 +560,7 @@ void CDecalRenderList::renderAllDecals() NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver(); // static volatile bool forceNoVertexProgram = false; - if (drvInternal->isVertexProgramSupported() && !forceNoVertexProgram) + if (drvInternal->supportVertexProgram() && !forceNoVertexProgram) { //drvInternal->setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); drvInternal->setConstant(7, _DistScale, _DistBias, 0.f, 1.f); diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index 46c655a5b..ed8a1dc7d 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -339,28 +339,28 @@ void initCommands() "mov oC0.xzw, c0.xyyx\n" "texld oC0.y, v0, s0\n"; NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); - if (d->isPixelProgramSupported(CPixelProgram::fp40)) + if (d->supportPixelProgram(CPixelProgram::fp40)) { nldebug("fp40"); a_DevPixelProgram = new CPixelProgram(program_fp40); } - else if (d->isPixelProgramSupported(CPixelProgram::arbfp1)) + else if (d->supportPixelProgram(CPixelProgram::arbfp1)) { nldebug("arbfp1"); a_DevPixelProgram = new CPixelProgram(program_arbfp1); } - /*else if (d->isPixelProgramSupported(CPixelProgram::ps_3_0)) + /*else if (d->supportPixelProgram(CPixelProgram::ps_3_0)) { nldebug("ps_3_0"); a_DevPixelProgram = new CPixelProgram(program_ps_3_0); // Textures do not seem to work with ps_3_0... }*/ - else if (d->isPixelProgramSupported(CPixelProgram::ps_2_0)) + else if (d->supportPixelProgram(CPixelProgram::ps_2_0)) { nldebug("ps_2_0"); a_DevPixelProgram = new CPixelProgram(program_ps_2_0); } - else if (d->isPixelProgramSupported(CPixelProgram::ps_1_1)) + else if (d->supportPixelProgram(CPixelProgram::ps_1_1)) { nldebug("ps_1_1"); a_DevPixelProgram = new CPixelProgram(program_ps_1_1); From 982bf804de601e7883d9f9a8304d718296dd9f83 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 20 Jun 2013 00:25:52 +0200 Subject: [PATCH 027/137] Added some notes --- code/nel/include/nel/3d/driver.h | 6 ++++-- code/nel/include/nel/3d/pixel_program.h | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 32953e58b..14595e05c 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1038,7 +1038,7 @@ public: virtual bool activePixelProgram (CPixelProgram *program) =0; /** - * Setup vertex program constant values. + * Setup vertex program constant (uniform) values. */ virtual void setConstant (uint index, float, float, float, float) =0; virtual void setConstant (uint index, double, double, double, double) =0; @@ -1048,9 +1048,10 @@ public: virtual void setConstant (uint index, uint num, const float *src) =0; /// setup several 4 double csts taken from the given tab virtual void setConstant (uint index, uint num, const double *src) =0; + // TODO: rename to setVertexProgramConstant /** - * Setup pixel program constant values. + * Setup pixel program constant (uniform) values. */ virtual void setPixelProgramConstant (uint index, float, float, float, float) =0; virtual void setPixelProgramConstant (uint index, double, double, double, double) =0; @@ -1060,6 +1061,7 @@ public: virtual void setPixelProgramConstant (uint index, uint num, const float *src) =0; /// setup several 4 double csts taken from the given tab virtual void setPixelProgramConstant (uint index, uint num, const double *src) =0; + // TODO: uint32 and sint32 uniform types supported in opengl from gp4fp and gp5fp and sint32 in d3d /** * Setup constants with a current matrix. diff --git a/code/nel/include/nel/3d/pixel_program.h b/code/nel/include/nel/3d/pixel_program.h index 6e14f0f04..183ad2d83 100644 --- a/code/nel/include/nel/3d/pixel_program.h +++ b/code/nel/include/nel/3d/pixel_program.h @@ -61,6 +61,11 @@ public: enum TProfile { + // TODO: + // If it's more useful, change this to a flags bitfield and + // change the d3d (and gl) code to generate the bitfield of + // supported modes instead of doing a >= version check. + // direct3d - 0xD3D0,major,minor ps_1_1 = 0xD3D00101, ps_1_2 = 0xD3D00102, From b45bdb88e6c84078d31cf622a0d3e25664229ccf Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 02:45:49 +0200 Subject: [PATCH 028/137] List stereo devices, see #43 --- code/nel/include/nel/3d/stereo_ovr.h | 96 ++++++++ code/nel/src/3d/stereo_ovr.cpp | 209 ++++++++++++++++++ .../bin/snowballs_client_default.cfg | 13 +- code/snowballs2/client/src/camera.cpp | 40 ++++ .../client/src/snowballs_client.cpp | 32 ++- code/snowballs2/client/src/snowballs_config.h | 2 +- 6 files changed, 377 insertions(+), 15 deletions(-) create mode 100644 code/nel/include/nel/3d/stereo_ovr.h create mode 100644 code/nel/src/3d/stereo_ovr.cpp diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h new file mode 100644 index 000000000..ce61c1c2e --- /dev/null +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -0,0 +1,96 @@ +/** + * \file stereo_ovr.h + * \brief CStereoOVR + * \date 2013-06-25 22:22GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + * + * Linking this library statically or dynamically with other modules + * is making a combined work based on this library. Thus, the terms + * and conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give + * you permission to link this library with the Oculus SDK to produce + * an executable, regardless of the license terms of the Oculus SDK, + * and distribute linked combinations including the two, provided that + * you also meet the terms and conditions of the license of the Oculus + * SDK. You must obey the GNU General Public License in all respects + * for all of the code used other than the Oculus SDK. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. + */ + +#ifndef NL3D_STEREO_OVR_H +#define NL3D_STEREO_OVR_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes + +namespace NL3D { + +struct CStereoDeviceInfo +{ +public: + uint8 Class; + uint8 Identifier; + NLMISC::CSmartPtr Factory; + + std::string Manufacturer; + std::string ProductName; +}; + +class CStereoOVRDevicePtr; + +/** + * \brief CStereoOVR + * \date 2013-06-25 22:22GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ +class CStereoOVR +{ +public: + CStereoOVR(const CStereoDeviceInfo &deviceInfo); + virtual ~CStereoOVR(); + + static void listDevices(std::vector &devicesOut); + static CStereoOVR *createDevice(const CStereoDeviceInfo &deviceInfo); + static bool isLibraryInUse(); + static void releaseLibrary(); + +private: + CStereoOVRDevicePtr *m_DevicePtr; + +}; /* class CStereoOVR */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_STEREO_OVR_H */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp new file mode 100644 index 000000000..c11d38774 --- /dev/null +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -0,0 +1,209 @@ +/** + * \file stereo_ovr.cpp + * \brief CStereoOVR + * \date 2013-06-25 22:22GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + * + * Linking this library statically or dynamically with other modules + * is making a combined work based on this library. Thus, the terms + * and conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give + * you permission to link this library with the Oculus SDK to produce + * an executable, regardless of the license terms of the Oculus SDK, + * and distribute linked combinations including the two, provided that + * you also meet the terms and conditions of the license of the Oculus + * SDK. You must obey the GNU General Public License in all respects + * for all of the code used other than the Oculus SDK. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. + */ + +#include +#include + +// STL includes + +// External includes +#include + +// NeL includes +// #include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +namespace { + +class CStereoOVRLog : public OVR::Log +{ +public: + CStereoOVRLog(unsigned logMask = OVR::LogMask_All) : OVR::Log(logMask) + { + + } + + virtual void LogMessageVarg(OVR::LogMessageType messageType, const char* fmt, va_list argList) + { + if (NLMISC::INelContext::isContextInitialised()) + { + char buffer[MaxLogBufferMessageSize]; + FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList); + if (IsDebugMessage(messageType)) + NLMISC::INelContext::getInstance().getDebugLog()->displayNL("OVR: %s", buffer); + else + NLMISC::INelContext::getInstance().getInfoLog()->displayNL("OVR: %s", buffer); + } + } +}; + +CStereoOVRLog *s_StereoOVRLog = NULL; +OVR::Ptr s_DeviceManager; + +class CStereoOVRSystem +{ +public: + ~CStereoOVRSystem() + { + Release(); + } + + void Init() + { + if (!s_StereoOVRLog) + { + nldebug("Initialize OVR"); + s_StereoOVRLog = new CStereoOVRLog(); + } + if (!OVR::System::IsInitialized()) + OVR::System::Init(s_StereoOVRLog); + if (!s_DeviceManager) + s_DeviceManager = OVR::DeviceManager::Create(); + } + + void Release() + { + if (s_DeviceManager) + { + nldebug("Release OVR"); + s_DeviceManager->Release(); + } + s_DeviceManager.Clear(); + if (OVR::System::IsInitialized()) + OVR::System::Destroy(); + if (s_StereoOVRLog) + nldebug("Release OVR Ok"); + delete s_StereoOVRLog; + s_StereoOVRLog = NULL; + } +}; + +CStereoOVRSystem s_StereoOVRSystem; + +class CStereoOVRDeviceHandle : public NLMISC::CRefCount +{ +public: + OVR::DeviceHandle DeviceHandle; +}; + +sint s_DeviceCounter = 0; + +} + +class CStereoOVRDevicePtr +{ +public: + OVR::Ptr HMDDevice; +}; + +CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) +{ + ++s_DeviceCounter; + m_DevicePtr = new CStereoOVRDevicePtr(); + + // CStereoOVRDeviceHandle *handle = static_cast(deviceInfo.Factory.getPtr()); + // OVR::DeviceHandle dh = handle->DeviceHandle; + // dh.CreateDevice(); +} + +CStereoOVR::~CStereoOVR() +{ + // ... + + delete m_DevicePtr; + m_DevicePtr = NULL; + --s_DeviceCounter; +} + +void CStereoOVR::listDevices(std::vector &devicesOut) +{ + s_StereoOVRSystem.Init(); + OVR::DeviceEnumerator devices = s_DeviceManager->EnumerateDevices(); + uint8 id = 1; + do + { + CStereoDeviceInfo deviceInfoOut; + OVR::DeviceInfo deviceInfo; + if (devices.IsAvailable()) + { + devices.GetDeviceInfo(&deviceInfo); + CStereoOVRDeviceHandle *handle = new CStereoOVRDeviceHandle(); + deviceInfoOut.Factory = static_cast(handle); + handle->DeviceHandle = devices; + deviceInfoOut.Class = 1; // OVR::HMDDevice + deviceInfoOut.Identifier = id; + deviceInfoOut.Manufacturer = deviceInfo.Manufacturer; + deviceInfoOut.ProductName = deviceInfo.ProductName; + devicesOut.push_back(deviceInfoOut); + ++id; + } + + } while (devices.Next()); +} + +CStereoOVR *CStereoOVR::createDevice(const CStereoDeviceInfo &deviceInfo) +{ + return NULL; +} + +bool CStereoOVR::isLibraryInUse() +{ + nlassert(s_DeviceCounter >= 0); + return s_DeviceCounter > 0; +} + +void CStereoOVR::releaseLibrary() +{ + nlassert(s_DeviceCounter == 0); + s_StereoOVRSystem.Release(); +} + +} /* namespace NL3D */ + +/* end of file */ diff --git a/code/snowballs2/bin/snowballs_client_default.cfg b/code/snowballs2/bin/snowballs_client_default.cfg index ba9178e19..758bd8483 100755 --- a/code/snowballs2/bin/snowballs_client_default.cfg +++ b/code/snowballs2/bin/snowballs_client_default.cfg @@ -47,8 +47,8 @@ FpsSmoothing = 64; OpenGL = 1; // Resolution of the screen -ScreenWidth = 800; -ScreenHeight = 600; +ScreenWidth = 1280; +ScreenHeight = 800; ScreenDepth = 32; // If 1, run in fullscreen mode, 0 for windowed @@ -58,6 +58,15 @@ ScreenFull = 0; StartPoint = { 1840.0, -970.0, 0.0 }; +////////////////////////////////////////////////////////////////////////////// +// HMD Variables ///////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +HMDEnable = 1; +HMDDeviceId = 0; +HMDDevice = "Auto"; + + ////////////////////////////////////////////////////////////////////////////// // Sound Variables /////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index b202fba63..d71ebc134 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -33,6 +34,8 @@ #include #include +#include + #include "snowballs_client.h" #include "entities.h" #include "mouse_listener.h" @@ -67,12 +70,47 @@ static UInstance Sky = NULL; static UCloudScape *Clouds = NULL; +static CStereoOVR *s_StereoHMD = NULL; + // // Functions // void initCamera() { + if (ConfigFile->getVar("HMDEnable").asBool()) + { + std::vector devices; + CStereoOVR::listDevices(devices); + for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) + { + std::stringstream name; + name << std::string("[") << (uint32)it->Identifier << "] [" << it->Manufacturer << " - " << it->ProductName << "]"; + nlinfo("Stereo Device: %s", name.str().c_str()); + } + CStereoDeviceInfo *deviceInfo = NULL; + std::string hmdDeviceCfg = ConfigFile->getVar("HMDDevice").asString(); + if (hmdDeviceCfg == std::string("Auto") + && devices.begin() != devices.end()) + { + deviceInfo = &devices[0]; + } + else + { + uint8 hmdDeviceId = (ConfigFile->getVar("HMDDeviceId").asInt() & 0xFF); + for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) + { + std::stringstream name; + name << it->Manufacturer << " - " << it->ProductName; + if (name.str() == hmdDeviceCfg) + deviceInfo = &(*it); + if (hmdDeviceId == it->Identifier) + break; + } + } + //s_StereoHMD->createDevice( + } + // Set up directly the camera Camera = Scene->getCam(); Camera.setTransformMode (UTransformable::DirectMatrix); @@ -114,6 +152,8 @@ void releaseCamera() Driver->deleteScene(SkyScene); Scene->deleteInstance(Snow); VisualCollisionManager->deleteEntity(CamCollisionEntity); + + CStereoOVR::releaseLibrary(); } void updateCamera() diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 1d7fefd60..e0f044174 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -356,6 +356,7 @@ void initIngame() //#ifdef NL_OS_WINDOWS // playMusic(SBCLIENT_MUSIC_WAIT); //#endif + displayLoadingState("Initialize"); // Create a scene Scene = Driver->createScene(false); @@ -366,7 +367,6 @@ void initIngame() CBloomEffect::instance().init(ConfigFile->getVar("OpenGL").asInt() == 1); CConfiguration::setAndCallback("SquareBloom", cbSquareBloom); CConfiguration::setAndCallback("DensityBloom", cbDensityBloom); - // Init the landscape using the previously created UScene displayLoadingState("Initialize Landscape"); initLandscape(); @@ -1141,21 +1141,29 @@ sint main(int argc, char **argv) FILE *f = _tfopen(_T(SBCLIENT_CONFIG_FILE_DEFAULT), _T("r")); if (!f) { - OutputDebugString(" ******************************** \n"); - OutputDebugString(" * CHANGING WORKING DIRECTORY * \n"); - OutputDebugString(" ******************************** \n\n"); - char cwd[256]; - _tgetcwd(cwd, 256); - tstring workdir(cwd); - workdir += "\\..\\bin\\"; - _tchdir(workdir.c_str()); - f = _tfopen(_T(SBCLIENT_CONFIG_FILE_DEFAULT), _T("r")); + f = _tfopen(_T(SBCLIENT_CONFIG_FILE), _T("r")); if (!f) { OutputDebugString(" ******************************** \n"); - OutputDebugString(" * DEFAULT CONFIG MISSING * \n"); + OutputDebugString(" * CHANGING WORKING DIRECTORY * \n"); OutputDebugString(" ******************************** \n\n"); - return EXIT_FAILURE; + char cwd[256]; + _tgetcwd(cwd, 256); + tstring workdir(cwd); + workdir = "R:\\build\\devw_x86\\bin\\Debug\\"; + _tchdir(workdir.c_str()); + f = _tfopen(_T(SBCLIENT_CONFIG_FILE_DEFAULT), _T("r")); + if (!f) + { + f = _tfopen(_T(SBCLIENT_CONFIG_FILE), _T("r")); + if (!f) + { + OutputDebugString(" ******************************** \n"); + OutputDebugString(" * DEFAULT CONFIG MISSING * \n"); + OutputDebugString(" ******************************** \n\n"); + return EXIT_FAILURE; + } + } } } fclose(f); diff --git a/code/snowballs2/client/src/snowballs_config.h b/code/snowballs2/client/src/snowballs_config.h index 9565fe4cf..fb304ba68 100644 --- a/code/snowballs2/client/src/snowballs_config.h +++ b/code/snowballs2/client/src/snowballs_config.h @@ -75,7 +75,7 @@ # ifndef SNOWBALLS_CONFIG # define SBCLIENT_CONFIG_FILE "snowballs_client.cfg" # else -# define SBCLIENT_CONFIG_FILE SNOWBALLS_CONFIG "client.cfg" +# define SBCLIENT_CONFIG_FILE SNOWBALLS_CONFIG "snowballs_client.cfg" # endif #endif From dc813a060e9f178a69d1496e7dd8f222e730d741 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 02:55:15 +0200 Subject: [PATCH 029/137] Add library name to device name, re #43 --- code/nel/include/nel/3d/stereo_ovr.h | 1 + code/nel/src/3d/stereo_ovr.cpp | 1 + code/snowballs2/client/src/camera.cpp | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index ce61c1c2e..5f61c0595 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -61,6 +61,7 @@ public: uint8 Identifier; NLMISC::CSmartPtr Factory; + std::string Library; std::string Manufacturer; std::string ProductName; }; diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index c11d38774..40d94f901 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -177,6 +177,7 @@ void CStereoOVR::listDevices(std::vector &devicesOut) deviceInfoOut.Factory = static_cast(handle); handle->DeviceHandle = devices; deviceInfoOut.Class = 1; // OVR::HMDDevice + deviceInfoOut.Library = "Oculus SDK"; deviceInfoOut.Identifier = id; deviceInfoOut.Manufacturer = deviceInfo.Manufacturer; deviceInfoOut.ProductName = deviceInfo.ProductName; diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index d71ebc134..38db2d599 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -85,7 +85,7 @@ void initCamera() for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) { std::stringstream name; - name << std::string("[") << (uint32)it->Identifier << "] [" << it->Manufacturer << " - " << it->ProductName << "]"; + name << std::string("[") << (uint32)it->Identifier << "] [" << it->Library << " - " << it->Manufacturer << " - " << it->ProductName << "]"; nlinfo("Stereo Device: %s", name.str().c_str()); } CStereoDeviceInfo *deviceInfo = NULL; @@ -101,7 +101,7 @@ void initCamera() for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) { std::stringstream name; - name << it->Manufacturer << " - " << it->ProductName; + name << it->Library << " - " << it->Manufacturer << " - " << it->ProductName; if (name.str() == hmdDeviceCfg) deviceInfo = &(*it); if (hmdDeviceId == it->Identifier) From a7cf55c58e28acc0d6be6f9a4349a9120b55af1a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 04:57:58 +0200 Subject: [PATCH 030/137] Read sensor data and set camera in snowballs, ref #43 --- code/nel/include/nel/3d/stereo_ovr.h | 4 ++ code/nel/src/3d/stereo_ovr.cpp | 52 ++++++++++++++++--- code/snowballs2/client/src/camera.cpp | 20 ++++++- code/snowballs2/client/src/snowballs_config.h | 2 +- 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 5f61c0595..3858b046e 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -80,11 +80,15 @@ public: CStereoOVR(const CStereoDeviceInfo &deviceInfo); virtual ~CStereoOVR(); + virtual NLMISC::CQuat getOrientation(); + static void listDevices(std::vector &devicesOut); static CStereoOVR *createDevice(const CStereoDeviceInfo &deviceInfo); static bool isLibraryInUse(); static void releaseLibrary(); + bool isDeviceCreated(); + private: CStereoOVRDevicePtr *m_DevicePtr; diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 40d94f901..44daae9ef 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -129,7 +129,7 @@ CStereoOVRSystem s_StereoOVRSystem; class CStereoOVRDeviceHandle : public NLMISC::CRefCount { public: - OVR::DeviceHandle DeviceHandle; + OVR::DeviceEnumerator DeviceHandle; }; sint s_DeviceCounter = 0; @@ -140,6 +140,8 @@ class CStereoOVRDevicePtr { public: OVR::Ptr HMDDevice; + OVR::Ptr SensorDevice; + OVR::SensorFusion SensorFusion; }; CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) @@ -147,20 +149,53 @@ CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); - // CStereoOVRDeviceHandle *handle = static_cast(deviceInfo.Factory.getPtr()); - // OVR::DeviceHandle dh = handle->DeviceHandle; - // dh.CreateDevice(); + CStereoOVRDeviceHandle *handle = static_cast(deviceInfo.Factory.getPtr()); + OVR::DeviceEnumerator dh = handle->DeviceHandle; + m_DevicePtr->HMDDevice = dh.CreateDevice(); + + if (m_DevicePtr->HMDDevice) + { + m_DevicePtr->SensorDevice = m_DevicePtr->HMDDevice->GetSensor(); + m_DevicePtr->SensorFusion.AttachToSensor(m_DevicePtr->SensorDevice); + m_DevicePtr->SensorFusion.SetGravityEnabled(true); + m_DevicePtr->SensorFusion.SetPredictionEnabled(true); + m_DevicePtr->SensorFusion.SetYawCorrectionEnabled(true); + } } CStereoOVR::~CStereoOVR() { - // ... + if (m_DevicePtr->SensorDevice) + m_DevicePtr->SensorDevice->Release(); + m_DevicePtr->SensorDevice.Clear(); + if (m_DevicePtr->HMDDevice) + m_DevicePtr->HMDDevice->Release(); + m_DevicePtr->HMDDevice.Clear(); delete m_DevicePtr; m_DevicePtr = NULL; --s_DeviceCounter; } +NLMISC::CQuat CStereoOVR::getOrientation() +{ + OVR::Quatf quatovr = m_DevicePtr->SensorFusion.GetPredictedOrientation(); + NLMISC::CMatrix coordsys; + float csys[] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + coordsys.set(csys); + NLMISC::CMatrix matovr; + matovr.setRot(NLMISC::CQuat(quatovr.x, quatovr.y, quatovr.z, quatovr.w)); + NLMISC::CMatrix matr; + matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) + NLMISC::CMatrix matnel = matr * matovr * coordsys; + return matnel.getRot(); +} + void CStereoOVR::listDevices(std::vector &devicesOut) { s_StereoOVRSystem.Init(); @@ -190,7 +225,7 @@ void CStereoOVR::listDevices(std::vector &devicesOut) CStereoOVR *CStereoOVR::createDevice(const CStereoDeviceInfo &deviceInfo) { - return NULL; + return new CStereoOVR(deviceInfo); } bool CStereoOVR::isLibraryInUse() @@ -205,6 +240,11 @@ void CStereoOVR::releaseLibrary() s_StereoOVRSystem.Release(); } +bool CStereoOVR::isDeviceCreated() +{ + return m_DevicePtr->HMDDevice != NULL; +} + } /* namespace NL3D */ /* end of file */ diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index 38db2d599..f1a76e552 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -108,13 +108,19 @@ void initCamera() break; } } - //s_StereoHMD->createDevice( + if (deviceInfo) + { + nlinfo("Create HMD device!"); + s_StereoHMD = CStereoOVR::createDevice(*deviceInfo); + } } // Set up directly the camera Camera = Scene->getCam(); Camera.setTransformMode (UTransformable::DirectMatrix); - Camera.setPerspective ((float)Pi/2.f, 1.33f, 0.1f, 1000); + Camera.setPerspective((float)Pi/2.f, + ConfigFile->getVar("ScreenWidth").asFloat() / ConfigFile->getVar("ScreenHeight").asFloat(), + 0.1f, 1000.f); Camera.lookAt (CVector(ConfigFile->getVar("StartPoint").asFloat(0), ConfigFile->getVar("StartPoint").asFloat(1), ConfigFile->getVar("StartPoint").asFloat(2)), @@ -153,11 +159,21 @@ void releaseCamera() Scene->deleteInstance(Snow); VisualCollisionManager->deleteEntity(CamCollisionEntity); + delete s_StereoHMD; + s_StereoHMD = NULL; CStereoOVR::releaseLibrary(); } void updateCamera() { + if (s_StereoHMD) + { + NLMISC::CQuat hmdOrient = s_StereoHMD->getOrientation(); + NLMISC::CMatrix camMatrix = Camera.getMatrix(); + NLMISC::CMatrix hmdMatrix; + hmdMatrix.setRot(hmdOrient); + Camera.setMatrix(camMatrix * hmdMatrix); + } // Set the new position of the snow emitter CMatrix mat = CMatrix::Identity; mat.setPos (Camera.getMatrix().getPos()/*+CVector (0.0f, 0.0f, -10.0f)*/); diff --git a/code/snowballs2/client/src/snowballs_config.h b/code/snowballs2/client/src/snowballs_config.h index fb304ba68..2e6b848fb 100644 --- a/code/snowballs2/client/src/snowballs_config.h +++ b/code/snowballs2/client/src/snowballs_config.h @@ -49,7 +49,7 @@ #define SBCLIENT_DEV_SOUND 0 #define SBCLIENT_DEV_STEREO 0 #define SBCLIENT_DEV_MEMLEAK 0 -#define SBCLIENT_DEV_PIXEL_PROGRAM 1 +#define SBCLIENT_DEV_PIXEL_PROGRAM 0 From e51d9e15d907496d8be6693524fbfc1c6d79653a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 08:00:19 +0200 Subject: [PATCH 031/137] Render from multiple cameras, see #43 --- code/nel/include/nel/3d/stereo_ovr.h | 27 ++++++ code/nel/src/3d/stereo_ovr.cpp | 97 ++++++++++++++++++- .../bin/snowballs_client_default.cfg | 2 +- code/snowballs2/client/src/camera.cpp | 26 +++-- code/snowballs2/client/src/camera.h | 4 + .../client/src/snowballs_client.cpp | 52 ++++++---- 6 files changed, 177 insertions(+), 31 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 3858b046e..89e6759d7 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -49,11 +49,15 @@ // NeL includes #include +#include +#include // Project includes namespace NL3D { +class UCamera; + struct CStereoDeviceInfo { public: @@ -80,6 +84,20 @@ public: CStereoOVR(const CStereoDeviceInfo &deviceInfo); virtual ~CStereoOVR(); + /// Gets the required screen resolution for this device + virtual void getScreenResolution(uint &width, uint &height); + /// Set latest camera position etcetera + virtual void updateCamera(const NL3D::UCamera *camera); + + /// Is there a next pass + virtual bool nextPass(); + /// Gets the current viewport + virtual const NL3D::CViewport &getCurrentViewport(); + /// Gets the current camera frustum + virtual void getCurrentFrustum(NL3D::UCamera *camera); + /// Gets the current camera matrix + virtual void getCurrentMatrix(NL3D::UCamera *camera); + virtual NLMISC::CQuat getOrientation(); static void listDevices(std::vector &devicesOut); @@ -87,10 +105,19 @@ public: static bool isLibraryInUse(); static void releaseLibrary(); + /// Calculates internal camera information based on the reference camera + void initCamera(const NL3D::UCamera *camera); + bool isDeviceCreated(); private: CStereoOVRDevicePtr *m_DevicePtr; + int m_Stage; + CViewport m_LeftViewport; + CViewport m_RightViewport; + CFrustum m_LeftFrustum; + CFrustum m_RightFrustum; + CMatrix m_CameraMatrix; }; /* class CStereoOVR */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 44daae9ef..32d5bffb7 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -51,6 +51,7 @@ // NeL includes // #include +#include // Project includes @@ -142,9 +143,10 @@ public: OVR::Ptr HMDDevice; OVR::Ptr SensorDevice; OVR::SensorFusion SensorFusion; + OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) +CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) : m_Stage(2) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -155,11 +157,30 @@ CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) if (m_DevicePtr->HMDDevice) { + m_DevicePtr->HMDDevice->GetDeviceInfo(&m_DevicePtr->HMDInfo); + nldebug("OVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.HScreenSize, m_DevicePtr->HMDInfo.VScreenSize); + nldebug("OVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.VScreenCenter); + nldebug("OVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.EyeToScreenDistance); + nldebug("OVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.LensSeparationDistance); + nldebug("OVR: InterpupillaryDistance: %f", m_DevicePtr->HMDInfo.InterpupillaryDistance); + nldebug("OVR: HResolution: %i, VResolution: %i", m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); + nldebug("OVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.DistortionK[0], m_DevicePtr->HMDInfo.DistortionK[1]); + nldebug("OVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.DistortionK[2], m_DevicePtr->HMDInfo.DistortionK[3]); + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 160 NL3D::CStereoOVR::CStereoOVR : OVR: HScreenSize: 0.149760, VScreenSize: 0.093600 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 161 NL3D::CStereoOVR::CStereoOVR : OVR: VScreenCenter: 0.046800 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 162 NL3D::CStereoOVR::CStereoOVR : OVR: EyeToScreenDistance: 0.041000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 163 NL3D::CStereoOVR::CStereoOVR : OVR: LensSeparationDistance: 0.063500 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 164 NL3D::CStereoOVR::CStereoOVR : OVR: InterpupillaryDistance: 0.064000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 165 NL3D::CStereoOVR::CStereoOVR : OVR: HResolution: 1280, VResolution: 800 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 166 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[0]: 1.000000, DistortionK[1]: 0.220000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 167 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[2]: 0.240000, DistortionK[3]: 0.000000 m_DevicePtr->SensorDevice = m_DevicePtr->HMDDevice->GetSensor(); m_DevicePtr->SensorFusion.AttachToSensor(m_DevicePtr->SensorDevice); m_DevicePtr->SensorFusion.SetGravityEnabled(true); m_DevicePtr->SensorFusion.SetPredictionEnabled(true); m_DevicePtr->SensorFusion.SetYawCorrectionEnabled(true); + m_LeftViewport.init(0.f, 0.f, 0.5f, 1.0f); + m_RightViewport.init(0.5f, 0.f, 0.5f, 1.0f); } } @@ -177,6 +198,74 @@ CStereoOVR::~CStereoOVR() --s_DeviceCounter; } +void CStereoOVR::getScreenResolution(uint &width, uint &height) +{ + width = m_DevicePtr->HMDInfo.HResolution; + height = m_DevicePtr->HMDInfo.VResolution; +} + +void CStereoOVR::initCamera(const NL3D::UCamera *camera) +{ + float ar = (float)m_DevicePtr->HMDInfo.HResolution / ((float)m_DevicePtr->HMDInfo.VResolution * 2.0f); + float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.VScreenSize / 2.0f) / m_DevicePtr->HMDInfo.EyeToScreenDistance); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); + m_LeftFrustum.initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); + m_RightFrustum = m_LeftFrustum; + float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; + float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; + float projectionCenterOffset = 4.0f * eyeProjectionShift / m_DevicePtr->HMDInfo.HScreenSize; + nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset); + projectionCenterOffset *= (m_LeftFrustum.Left - m_LeftFrustum.Right) * 0.5f; // made this up ... + m_LeftFrustum.Left += projectionCenterOffset; + m_LeftFrustum.Right += projectionCenterOffset; + m_RightFrustum.Left -= projectionCenterOffset; + m_RightFrustum.Right -= projectionCenterOffset; +} + +void CStereoOVR::updateCamera(const NL3D::UCamera *camera) +{ + if (camera->getFrustum().Near != m_LeftFrustum.Near + || camera->getFrustum().Far != m_LeftFrustum.Far) + CStereoOVR::initCamera(camera); + m_CameraMatrix = camera->getMatrix(); +} + +bool CStereoOVR::nextPass() +{ + switch (m_Stage) + { + case 0: + ++m_Stage; + return true; + case 1: + ++m_Stage; + return false; + case 2: + m_Stage = 0; + return true; + } +} + +const NL3D::CViewport &CStereoOVR::getCurrentViewport() +{ + if (m_Stage) return m_RightViewport; + else return m_LeftViewport; +} + +void CStereoOVR::getCurrentFrustum(NL3D::UCamera *camera) +{ + if (m_Stage) camera->setFrustum(m_RightFrustum); + else camera->setFrustum(m_LeftFrustum); +} + +void CStereoOVR::getCurrentMatrix(NL3D::UCamera *camera) +{ + CMatrix translate; + if (m_Stage) translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); + else translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); + camera->setTransformMode(NL3D::UTransformable::DirectMatrix); + camera->setMatrix(m_CameraMatrix * translate); // or switch? +} + NLMISC::CQuat CStereoOVR::getOrientation() { OVR::Quatf quatovr = m_DevicePtr->SensorFusion.GetPredictedOrientation(); @@ -225,7 +314,11 @@ void CStereoOVR::listDevices(std::vector &devicesOut) CStereoOVR *CStereoOVR::createDevice(const CStereoDeviceInfo &deviceInfo) { - return new CStereoOVR(deviceInfo); + CStereoOVR *stereo = new CStereoOVR(deviceInfo); + if (stereo->isDeviceCreated()) + return stereo; + delete stereo; + return NULL; } bool CStereoOVR::isLibraryInUse() diff --git a/code/snowballs2/bin/snowballs_client_default.cfg b/code/snowballs2/bin/snowballs_client_default.cfg index 758bd8483..9d1429f83 100755 --- a/code/snowballs2/bin/snowballs_client_default.cfg +++ b/code/snowballs2/bin/snowballs_client_default.cfg @@ -52,7 +52,7 @@ ScreenHeight = 800; ScreenDepth = 32; // If 1, run in fullscreen mode, 0 for windowed -ScreenFull = 0; +ScreenFull = 1; // Start position of the player (the z is always 0) StartPoint = { 1840.0, -970.0, 0.0 }; diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index f1a76e552..1911f9694 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -64,13 +64,13 @@ UVisualCollisionEntity *CamCollisionEntity = NULL; static UInstance Snow = NULL; // The sky 3D objects -static UScene *SkyScene = NULL; -static UCamera SkyCamera = NULL; +UScene *SkyScene = NULL; +UCamera SkyCamera = NULL; static UInstance Sky = NULL; static UCloudScape *Clouds = NULL; -static CStereoOVR *s_StereoHMD = NULL; +CStereoOVR *StereoHMD = NULL; // // Functions @@ -111,7 +111,7 @@ void initCamera() if (deviceInfo) { nlinfo("Create HMD device!"); - s_StereoHMD = CStereoOVR::createDevice(*deviceInfo); + StereoHMD = CStereoOVR::createDevice(*deviceInfo); } } @@ -129,6 +129,13 @@ void initCamera() CamCollisionEntity = VisualCollisionManager->createEntity(); CamCollisionEntity->setCeilMode(true); + if (StereoHMD) + { + StereoHMD->nextPass(); // test + + StereoHMD->initCamera(&Camera); + } + // Create the snowing particle system Snow = Scene->createInstance("snow.ps"); // And setup it @@ -159,16 +166,16 @@ void releaseCamera() Scene->deleteInstance(Snow); VisualCollisionManager->deleteEntity(CamCollisionEntity); - delete s_StereoHMD; - s_StereoHMD = NULL; + delete StereoHMD; + StereoHMD = NULL; CStereoOVR::releaseLibrary(); } void updateCamera() { - if (s_StereoHMD) + if (StereoHMD) { - NLMISC::CQuat hmdOrient = s_StereoHMD->getOrientation(); + NLMISC::CQuat hmdOrient = StereoHMD->getOrientation(); NLMISC::CMatrix camMatrix = Camera.getMatrix(); NLMISC::CMatrix hmdMatrix; hmdMatrix.setRot(hmdOrient); @@ -217,7 +224,8 @@ void updateSky() // Must clear ZBuffer For incoming rendering. Driver->clearZBuffer(); - Clouds->render(); + if (!StereoHMD) // Cloudscape not supported (fix Viewport please) + Clouds->render(); } } /* namespace SBCLIENT */ diff --git a/code/snowballs2/client/src/camera.h b/code/snowballs2/client/src/camera.h index c7718c653..5eae47c53 100644 --- a/code/snowballs2/client/src/camera.h +++ b/code/snowballs2/client/src/camera.h @@ -30,6 +30,7 @@ namespace NL3D { class UVisualCollisionEntity; + class CStereoOVR; }; namespace SBCLIENT { @@ -39,7 +40,10 @@ namespace SBCLIENT { // extern NL3D::UCamera Camera; +extern NL3D::UCamera SkyCamera; extern NL3D::UVisualCollisionEntity *CamCollisionEntity; +extern NL3D::CStereoOVR *StereoHMD; +extern NL3D::UScene *SkyScene; // // External functions diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index e0f044174..5ed15b9d7 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -51,6 +51,7 @@ #if SBCLIENT_DEV_STEREO # include #endif /* #if SBCLIENT_DEV_STEREO */ +#include // Project includes #include "pacs.h" @@ -709,6 +710,7 @@ void loopIngame() // 09. Update Camera (depends on entities) updateCamera(); + StereoHMD->updateCamera(&Camera); // 10. Update Interface (login, ui, etc) // ... @@ -729,17 +731,28 @@ void loopIngame() else { // call all 3d render thingies - Driver->clearBuffers(CRGBA(127, 0, 0)); // if you see red, there's a problem with bloom or stereo render + // Driver->clearBuffers(CRGBA(127, 0, 0)); // if you see red, there's a problem with bloom or stereo render + + // 01. Render Driver (background color) + // BLOOM CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) + Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering + #if SBCLIENT_DEV_STEREO _StereoRender->calculateCameras(Camera.getObjectPtr()); // calculate modified matrices for the current camera for (uint cameraId = 0; cameraId < _StereoRender->getCameraCount(); ++cameraId) { _StereoRender->getCamera(cameraId, Camera.getObjectPtr()); // get the matrix details for this camera -#endif /* #if SBCLIENT_DEV_STEREO */ - // 01. Render Driver (background color) - CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) - Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering +#endif /* #if SBCLIENT_DEV_STEREO */ + while (StereoHMD->nextPass()) + { + const CViewport &vp = StereoHMD->getCurrentViewport(); + Driver->setViewport(vp); + Scene->setViewport(vp); + SkyScene->setViewport(vp); + StereoHMD->getCurrentFrustum(&Camera); + StereoHMD->getCurrentFrustum(&SkyCamera); + StereoHMD->getCurrentMatrix(&Camera); // 02. Render Sky (sky scene) updateSky(); // Render the sky scene before the main scene @@ -749,10 +762,10 @@ void loopIngame() // 05. Render Effects (flare) updateLensFlare(); // Render the lens flare - CBloomEffect::instance().endBloom(); // end the actual bloom effect visible in the scene + // BLOOM CBloomEffect::instance().endBloom(); // end the actual bloom effect visible in the scene // 06. Render Interface 3D (player names) - CBloomEffect::instance().endInterfacesDisplayBloom(); // end bloom effect system after drawing the 3d interface (z buffer related) + // BLOOM CBloomEffect::instance().endInterfacesDisplayBloom(); // end bloom effect system after drawing the 3d interface (z buffer related) #if SBCLIENT_DEV_STEREO _StereoRender->copyBufferToTexture(cameraId); // copy current buffer to the active stereorender texture @@ -761,19 +774,20 @@ void loopIngame() _StereoRender->render(); // render everything together in the current mode #endif /* #if SBCLIENT_DEV_STEREO */ - // 07. Render Interface 2D (chatboxes etc, optionally does have 3d) - updateCompass(); // Update the compass - updateRadar(); // Update the radar - updateGraph(); // Update the radar - if (ShowCommands) updateCommands(); // Update the commands panel - updateAnimation(); - renderEntitiesNames(); // Render the name on top of the other players - updateInterface(); // Update interface - renderInformation(); - update3dLogo(); + // 07. Render Interface 2D (chatboxes etc, optionally does have 3d) + updateCompass(); // Update the compass + updateRadar(); // Update the radar + updateGraph(); // Update the radar + if (ShowCommands) updateCommands(); // Update the commands panel + updateAnimation(); + renderEntitiesNames(); // Render the name on top of the other players + updateInterface(); // Update interface + renderInformation(); + update3dLogo(); - // 08. Render Debug (stuff for dev) - // ... + // 08. Render Debug (stuff for dev) + // ... + } // 09. Render Buffer Driver->swapBuffers(); From 7672ab28127afe1a92e5ed0ec2fdba43044a8e87 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 15:49:31 +0200 Subject: [PATCH 032/137] Cleanup and make bloom work with stereo rendering, re #43 --- code/nel/include/nel/3d/stereo_ovr.h | 23 +++- code/nel/src/3d/stereo_ovr.cpp | 120 +++++++++++++++-- .../bin/snowballs_client_default.cfg | 2 +- code/snowballs2/client/src/camera.cpp | 2 - code/snowballs2/client/src/mouse_listener.cpp | 5 + .../client/src/snowballs_client.cpp | 127 +++++++++++------- 6 files changed, 209 insertions(+), 70 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 89e6759d7..68cb8fd1c 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -84,6 +84,7 @@ public: CStereoOVR(const CStereoDeviceInfo &deviceInfo); virtual ~CStereoOVR(); + /// Gets the required screen resolution for this device virtual void getScreenResolution(uint &width, uint &height); /// Set latest camera position etcetera @@ -92,19 +93,33 @@ public: /// Is there a next pass virtual bool nextPass(); /// Gets the current viewport - virtual const NL3D::CViewport &getCurrentViewport(); + virtual const NL3D::CViewport &getCurrentViewport() const; /// Gets the current camera frustum - virtual void getCurrentFrustum(NL3D::UCamera *camera); + virtual void getCurrentFrustum(NL3D::UCamera *camera) const; /// Gets the current camera matrix - virtual void getCurrentMatrix(NL3D::UCamera *camera); + virtual void getCurrentMatrix(NL3D::UCamera *camera) const; + + virtual bool beginClear(); + virtual void endClear(); + + virtual bool beginScene(); + virtual void endScene(); + + virtual bool beginInterface3D(); + virtual void endInterface3D(); + + virtual bool beginInterface2D(); + virtual void endInterface2D(); + + virtual NLMISC::CQuat getOrientation() const; - virtual NLMISC::CQuat getOrientation(); static void listDevices(std::vector &devicesOut); static CStereoOVR *createDevice(const CStereoDeviceInfo &deviceInfo); static bool isLibraryInUse(); static void releaseLibrary(); + /// Calculates internal camera information based on the reference camera void initCamera(const NL3D::UCamera *camera); diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 32d5bffb7..b9c829d5b 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -146,7 +146,7 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) : m_Stage(2) +CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) : m_Stage(0) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -235,38 +235,130 @@ bool CStereoOVR::nextPass() { case 0: ++m_Stage; + // stage 1: + // (initBloom) + // clear buffer + // draw scene left return true; case 1: ++m_Stage; - return false; - case 2: - m_Stage = 0; + // stage 2: + // draw scene right return true; + case 2: + ++m_Stage; + // stage 3: + // (endBloom) + // draw interface 3d left + return true; + case 3: + ++m_Stage; + // stage 4: + // draw interface 3d right + return true; + case 4: + ++m_Stage; + // stage 5: + // (endInterfacesDisplayBloom) + // draw interface 2d left + return true; + case 5: + ++m_Stage; + // stage 6: + // draw interface 2d right + return true; + case 6: + m_Stage = 0; + // present + return false; } } -const NL3D::CViewport &CStereoOVR::getCurrentViewport() +const NL3D::CViewport &CStereoOVR::getCurrentViewport() const { - if (m_Stage) return m_RightViewport; - else return m_LeftViewport; + if (m_Stage % 2) return m_LeftViewport; + else return m_RightViewport; } -void CStereoOVR::getCurrentFrustum(NL3D::UCamera *camera) +void CStereoOVR::getCurrentFrustum(NL3D::UCamera *camera) const { - if (m_Stage) camera->setFrustum(m_RightFrustum); - else camera->setFrustum(m_LeftFrustum); + if (m_Stage % 2) camera->setFrustum(m_LeftFrustum); + else camera->setFrustum(m_RightFrustum); } -void CStereoOVR::getCurrentMatrix(NL3D::UCamera *camera) +void CStereoOVR::getCurrentMatrix(NL3D::UCamera *camera) const { CMatrix translate; - if (m_Stage) translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); + if (m_Stage % 2) translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); else translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); camera->setTransformMode(NL3D::UTransformable::DirectMatrix); - camera->setMatrix(m_CameraMatrix * translate); // or switch? + camera->setMatrix(m_CameraMatrix * translate); } -NLMISC::CQuat CStereoOVR::getOrientation() +bool CStereoOVR::beginClear() +{ + switch (m_Stage) + { + case 1: + return true; + } + return false; +} + +void CStereoOVR::endClear() +{ + +} + +bool CStereoOVR::beginScene() +{ + switch (m_Stage) + { + case 1: + case 2: + return true; + } + return false; +} + +void CStereoOVR::endScene() +{ + +} + +bool CStereoOVR::beginInterface3D() +{ + switch (m_Stage) + { + case 3: + case 4: + return true; + } + return false; +} + +void CStereoOVR::endInterface3D() +{ + +} + +bool CStereoOVR::beginInterface2D() +{ + switch (m_Stage) + { + case 5: + case 6: + return true; + } + return false; +} + +void CStereoOVR::endInterface2D() +{ + +} + +NLMISC::CQuat CStereoOVR::getOrientation() const { OVR::Quatf quatovr = m_DevicePtr->SensorFusion.GetPredictedOrientation(); NLMISC::CMatrix coordsys; diff --git a/code/snowballs2/bin/snowballs_client_default.cfg b/code/snowballs2/bin/snowballs_client_default.cfg index 9d1429f83..758bd8483 100755 --- a/code/snowballs2/bin/snowballs_client_default.cfg +++ b/code/snowballs2/bin/snowballs_client_default.cfg @@ -52,7 +52,7 @@ ScreenHeight = 800; ScreenDepth = 32; // If 1, run in fullscreen mode, 0 for windowed -ScreenFull = 1; +ScreenFull = 0; // Start position of the player (the z is always 0) StartPoint = { 1840.0, -970.0, 0.0 }; diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index 1911f9694..030ebe0d9 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -131,8 +131,6 @@ void initCamera() if (StereoHMD) { - StereoHMD->nextPass(); // test - StereoHMD->initCamera(&Camera); } diff --git a/code/snowballs2/client/src/mouse_listener.cpp b/code/snowballs2/client/src/mouse_listener.cpp index c459f6bd2..67508e281 100644 --- a/code/snowballs2/client/src/mouse_listener.cpp +++ b/code/snowballs2/client/src/mouse_listener.cpp @@ -427,6 +427,11 @@ void C3dMouseListener::updateCamera() cpos = snapped+CVector(0.0f, 0.0f, GroundCamLimit); _ViewHeight = cpos.z - getPosition().z; } + if (StereoHMD) + { + // look at straight forward + tpos.z = cpos.z; + } _Camera.lookAt(cpos, tpos); } diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 5ed15b9d7..9563ad774 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -710,7 +710,7 @@ void loopIngame() // 09. Update Camera (depends on entities) updateCamera(); - StereoHMD->updateCamera(&Camera); + if (StereoHMD) StereoHMD->updateCamera(&Camera); // 10. Update Interface (login, ui, etc) // ... @@ -730,63 +730,92 @@ void loopIngame() if (Driver->isLost()) nlSleep(10); else { - // call all 3d render thingies - // Driver->clearBuffers(CRGBA(127, 0, 0)); // if you see red, there's a problem with bloom or stereo render - - // 01. Render Driver (background color) - // BLOOM CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) - Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering - -#if SBCLIENT_DEV_STEREO - _StereoRender->calculateCameras(Camera.getObjectPtr()); // calculate modified matrices for the current camera - for (uint cameraId = 0; cameraId < _StereoRender->getCameraCount(); ++cameraId) + uint i = 0; + uint bloomStage = 0; + while ((!StereoHMD && i == 0) || (StereoHMD && StereoHMD->nextPass())) { - _StereoRender->getCamera(cameraId, Camera.getObjectPtr()); // get the matrix details for this camera + ++i; + if (StereoHMD) + { + const CViewport &vp = StereoHMD->getCurrentViewport(); + Driver->setViewport(vp); + Scene->setViewport(vp); + SkyScene->setViewport(vp); + StereoHMD->getCurrentFrustum(&Camera); + StereoHMD->getCurrentFrustum(&SkyCamera); + StereoHMD->getCurrentMatrix(&Camera); + } + + if (!StereoHMD || StereoHMD->beginClear()) + { + nlassert(bloomStage == 0); + CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) + bloomStage = 1; -#endif /* #if SBCLIENT_DEV_STEREO */ - while (StereoHMD->nextPass()) - { - const CViewport &vp = StereoHMD->getCurrentViewport(); - Driver->setViewport(vp); - Scene->setViewport(vp); - SkyScene->setViewport(vp); - StereoHMD->getCurrentFrustum(&Camera); - StereoHMD->getCurrentFrustum(&SkyCamera); - StereoHMD->getCurrentMatrix(&Camera); + // 01. Render Driver (background color) + Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering + + if (StereoHMD) StereoHMD->endClear(); + } - // 02. Render Sky (sky scene) - updateSky(); // Render the sky scene before the main scene + if (!StereoHMD || StereoHMD->beginScene()) + { + // 02. Render Sky (sky scene) + updateSky(); // Render the sky scene before the main scene - // 04. Render Scene (entity scene) - Scene->render(); // Render + // 04. Render Scene (entity scene) + Scene->render(); // Render - // 05. Render Effects (flare) - updateLensFlare(); // Render the lens flare - // BLOOM CBloomEffect::instance().endBloom(); // end the actual bloom effect visible in the scene + // 05. Render Effects (flare) + if (!StereoHMD) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...) - // 06. Render Interface 3D (player names) - // BLOOM CBloomEffect::instance().endInterfacesDisplayBloom(); // end bloom effect system after drawing the 3d interface (z buffer related) + if (StereoHMD) StereoHMD->endScene(); + } -#if SBCLIENT_DEV_STEREO - _StereoRender->copyBufferToTexture(cameraId); // copy current buffer to the active stereorender texture - } - _StereoRender->restoreCamera(Camera.getObjectPtr()); // restore the camera - _StereoRender->render(); // render everything together in the current mode -#endif /* #if SBCLIENT_DEV_STEREO */ + if (!StereoHMD || StereoHMD->beginInterface3D()) + { + if (bloomStage == 1) + { + // End the actual bloom effect visible in the scene. + if (StereoHMD) Driver->setViewport(NL3D::CViewport()); + CBloomEffect::instance().endBloom(); + if (StereoHMD) Driver->setViewport(StereoHMD->getCurrentViewport()); + bloomStage = 2; + } - // 07. Render Interface 2D (chatboxes etc, optionally does have 3d) - updateCompass(); // Update the compass - updateRadar(); // Update the radar - updateGraph(); // Update the radar - if (ShowCommands) updateCommands(); // Update the commands panel - updateAnimation(); - renderEntitiesNames(); // Render the name on top of the other players - updateInterface(); // Update interface - renderInformation(); - update3dLogo(); + // 06. Render Interface 3D (player names) + // ... + + if (StereoHMD) StereoHMD->endInterface3D(); + } - // 08. Render Debug (stuff for dev) - // ... + if (!StereoHMD || StereoHMD->beginInterface2D()) + { + if (bloomStage == 2) + { + // End bloom effect system after drawing the 3d interface (z buffer related). + if (StereoHMD) Driver->setViewport(NL3D::CViewport()); + CBloomEffect::instance().endInterfacesDisplayBloom(); + if (StereoHMD) Driver->setViewport(StereoHMD->getCurrentViewport()); + bloomStage = 0; + } + + // 07. Render Interface 2D (chatboxes etc, optionally does have 3d) + updateCompass(); // Update the compass + updateRadar(); // Update the radar + updateGraph(); // Update the radar + if (ShowCommands) updateCommands(); // Update the commands panel + updateAnimation(); + renderEntitiesNames(); // Render the name on top of the other players + updateInterface(); // Update interface + renderInformation(); + if (!StereoHMD) update3dLogo(); // broken with stereo + + // 08. Render Debug (stuff for dev) + // ... + + if (StereoHMD) StereoHMD->endInterface2D(); + } } // 09. Render Buffer From cbd72f73ffc307d2b49afd51b21b6506cb312c77 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 15:55:39 +0200 Subject: [PATCH 033/137] Add some comments, see #43 --- code/nel/include/nel/3d/stereo_ovr.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 68cb8fd1c..9a91e0bd0 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -99,18 +99,25 @@ public: /// Gets the current camera matrix virtual void getCurrentMatrix(NL3D::UCamera *camera) const; + /// At the start of a new render target virtual bool beginClear(); + // virtual void *getRenderTarget() const; virtual void endClear(); + /// The 3D scene virtual bool beginScene(); virtual void endScene(); + /// Interface within the 3D scene virtual bool beginInterface3D(); virtual void endInterface3D(); + /// 2D Interface virtual bool beginInterface2D(); virtual void endInterface2D(); + + /// Get the HMD orientation virtual NLMISC::CQuat getOrientation() const; From 78ae99731d3a89db4b65a4439c9d9404d3209aa1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 16:08:48 +0200 Subject: [PATCH 034/137] Correctly adjust text to viewport, re #43 --- code/nel/src/3d/computed_string.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/nel/src/3d/computed_string.cpp b/code/nel/src/3d/computed_string.cpp index 0c2cd48de..71ea58948 100644 --- a/code/nel/src/3d/computed_string.cpp +++ b/code/nel/src/3d/computed_string.cpp @@ -21,6 +21,7 @@ #include "nel/3d/index_buffer.h" #include "nel/3d/material.h" #include "nel/3d/frustum.h" +#include "nel/3d/viewport.h" #include "nel/misc/smart_ptr.h" #include "nel/misc/debug.h" @@ -85,6 +86,10 @@ void CComputedString::render2D (IDriver& driver, // get window size uint32 wndWidth, wndHeight; driver.getWindowSize(wndWidth, wndHeight); + CViewport vp; + driver.getViewport(vp); + wndWidth = (uint32)((float)wndWidth * vp.getWidth()); + wndHeight = (uint32)((float)wndHeight * vp.getHeight()); // scale to window size. x*= wndWidth; z*= wndHeight; From 1b8ddaa87b325484e7c9575a1ab1d034ea5a7d97 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 16:59:08 +0200 Subject: [PATCH 035/137] Add 2D interface shifting calculations, see #43 --- code/nel/include/nel/3d/stereo_ovr.h | 6 ++++ code/nel/src/3d/stereo_ovr.cpp | 31 +++++++++++++++++-- code/snowballs2/client/src/camera.h | 1 - code/snowballs2/client/src/commands.cpp | 15 +++++++++ code/snowballs2/client/src/snowballs_client.h | 2 ++ 5 files changed, 52 insertions(+), 3 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 9a91e0bd0..cd466a7aa 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -95,6 +95,8 @@ public: /// Gets the current viewport virtual const NL3D::CViewport &getCurrentViewport() const; /// Gets the current camera frustum + virtual const NL3D::CFrustum &getCurrentFrustum() const; + /// Gets the current camera frustum virtual void getCurrentFrustum(NL3D::UCamera *camera) const; /// Gets the current camera matrix virtual void getCurrentMatrix(NL3D::UCamera *camera) const; @@ -119,6 +121,8 @@ public: /// Get the HMD orientation virtual NLMISC::CQuat getOrientation() const; + /// Get GUI center (1 = width, 1 = height, 0 = center) (todo: move to CStereoHMD) + void getInterface2DShift(float &x, float &y, float distance); static void listDevices(std::vector &devicesOut); @@ -140,6 +144,8 @@ private: CFrustum m_LeftFrustum; CFrustum m_RightFrustum; CMatrix m_CameraMatrix; + mutable bool m_OrientationCached; + mutable NLMISC::CQuat m_OrientationCache; }; /* class CStereoOVR */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index b9c829d5b..09e079f81 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -146,7 +146,7 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) : m_Stage(0) +CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) : m_Stage(0), m_OrientationCached(false) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -270,6 +270,7 @@ bool CStereoOVR::nextPass() case 6: m_Stage = 0; // present + m_OrientationCached = false; return false; } } @@ -280,6 +281,12 @@ const NL3D::CViewport &CStereoOVR::getCurrentViewport() const else return m_RightViewport; } +const NL3D::CFrustum &CStereoOVR::getCurrentFrustum() const +{ + if (m_Stage % 2) return m_LeftFrustum; + else return m_RightFrustum; +} + void CStereoOVR::getCurrentFrustum(NL3D::UCamera *camera) const { if (m_Stage % 2) camera->setFrustum(m_LeftFrustum); @@ -360,6 +367,9 @@ void CStereoOVR::endInterface2D() NLMISC::CQuat CStereoOVR::getOrientation() const { + if (m_OrientationCached) + return m_OrientationCache; + OVR::Quatf quatovr = m_DevicePtr->SensorFusion.GetPredictedOrientation(); NLMISC::CMatrix coordsys; float csys[] = { @@ -374,7 +384,24 @@ NLMISC::CQuat CStereoOVR::getOrientation() const NLMISC::CMatrix matr; matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) NLMISC::CMatrix matnel = matr * matovr * coordsys; - return matnel.getRot(); + NLMISC::CQuat finalquat = matnel.getRot(); + m_OrientationCache = finalquat; + m_OrientationCached = true; + return finalquat; +} + +/// Get GUI shift (todo: move to CStereoHMD) +void CStereoOVR::getInterface2DShift(float &x, float &y, float distance) +{ + NLMISC::CVector vector = CVector(0.f, -distance, 0.f); + NLMISC::CQuat rot = getOrientation(); + rot.invert(); + NLMISC::CMatrix mat; + mat.rotate(rot); + mat.translate(vector); + CVector proj = getCurrentFrustum().project(mat.getPos()); + x = proj.x - 0.5f; + y = proj.y - 0.5f; } void CStereoOVR::listDevices(std::vector &devicesOut) diff --git a/code/snowballs2/client/src/camera.h b/code/snowballs2/client/src/camera.h index 5eae47c53..c2d61d866 100644 --- a/code/snowballs2/client/src/camera.h +++ b/code/snowballs2/client/src/camera.h @@ -42,7 +42,6 @@ namespace SBCLIENT { extern NL3D::UCamera Camera; extern NL3D::UCamera SkyCamera; extern NL3D::UVisualCollisionEntity *CamCollisionEntity; -extern NL3D::CStereoOVR *StereoHMD; extern NL3D::UScene *SkyScene; // diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index ed8a1dc7d..795371cb6 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "network.h" #include "snowballs_client.h" @@ -374,6 +375,9 @@ void updateCommands() uint32 _width, _height; Driver->getWindowSize(_width, _height); float width = (float)_width, height = (float)_height; + NL3D::CViewport vp = Driver->getViewport(); + width *= vp.getWidth(); + height *= vp.getHeight(); float CommandsLineHeight = CommandsFontSize / height; float CommandsBoxX = ((float)(sint32)(SBCLIENT::CommandsBoxX * width)) / width; float CommandsBoxWidth = ((float)(sint32)(SBCLIENT::CommandsBoxWidth * width)) / width; @@ -381,6 +385,17 @@ void updateCommands() float CommandsBoxHeight = ((float)(sint32)((CommandsNbLines + 1) * CommandsLineHeight * width)) / width; float CommandsBoxBorderX = ((float)(sint32)(SBCLIENT::CommandsBoxBorder * width)) / width; float CommandsBoxBorderY = ((float)(sint32)(SBCLIENT::CommandsBoxBorder * height)) / height; + if (StereoHMD) + { + float xshift, yshift; + StereoHMD->getInterface2DShift(xshift, yshift, 1.0f); + // snap to pixels + xshift = ((float)(sint32)(xshift * width)) / width; + yshift = ((float)(sint32)(yshift * height)) / height; + // adjust + CommandsBoxX += xshift; + CommandsBoxY += yshift; + } // Display the background Driver->setMatrixMode2D11 (); diff --git a/code/snowballs2/client/src/snowballs_client.h b/code/snowballs2/client/src/snowballs_client.h index 67116f7e6..bc955d317 100644 --- a/code/snowballs2/client/src/snowballs_client.h +++ b/code/snowballs2/client/src/snowballs_client.h @@ -42,6 +42,7 @@ namespace NL3D { class UScene; class UTextContext; class ULandscape; + class CStereoOVR; } namespace SBCLIENT { @@ -58,6 +59,7 @@ public: }; extern NL3D::UDriver *Driver; +extern NL3D::CStereoOVR *StereoHMD; extern NL3D::UScene *Scene; extern NL3D::UTextContext *TextContext; extern NLMISC::CConfigFile *ConfigFile; From 8230238b5f16db76ac616625df528210cdf73b52 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 17:24:23 +0200 Subject: [PATCH 036/137] Add eye distance in 2D interface shift, re #43 --- code/nel/include/nel/3d/stereo_ovr.h | 4 ++-- code/nel/src/3d/stereo_ovr.cpp | 6 ++++-- code/snowballs2/client/src/commands.cpp | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index cd466a7aa..bb85438ad 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -121,8 +121,8 @@ public: /// Get the HMD orientation virtual NLMISC::CQuat getOrientation() const; - /// Get GUI center (1 = width, 1 = height, 0 = center) (todo: move to CStereoHMD) - void getInterface2DShift(float &x, float &y, float distance); + /// Get GUI center (1 = width, 1 = height, 0 = center) + virtual void getInterface2DShift(float &x, float &y, float distance); static void listDevices(std::vector &devicesOut); diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 09e079f81..cba1c004f 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -390,7 +390,7 @@ NLMISC::CQuat CStereoOVR::getOrientation() const return finalquat; } -/// Get GUI shift (todo: move to CStereoHMD) +/// Get GUI shift void CStereoOVR::getInterface2DShift(float &x, float &y, float distance) { NLMISC::CVector vector = CVector(0.f, -distance, 0.f); @@ -398,8 +398,10 @@ void CStereoOVR::getInterface2DShift(float &x, float &y, float distance) rot.invert(); NLMISC::CMatrix mat; mat.rotate(rot); + if (m_Stage % 2) mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); + else mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); mat.translate(vector); - CVector proj = getCurrentFrustum().project(mat.getPos()); + CVector proj = CStereoOVR::getCurrentFrustum().project(mat.getPos()); x = proj.x - 0.5f; y = proj.y - 0.5f; } diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index 795371cb6..4a36db8bb 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -388,7 +388,7 @@ void updateCommands() if (StereoHMD) { float xshift, yshift; - StereoHMD->getInterface2DShift(xshift, yshift, 1.0f); + StereoHMD->getInterface2DShift(xshift, yshift, 4.0f); // snap to pixels xshift = ((float)(sint32)(xshift * width)) / width; yshift = ((float)(sint32)(yshift * height)) / height; From 06e96929afe825d91928c51fc72beebd9f02cc0b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 17:38:20 +0200 Subject: [PATCH 037/137] Move snowballs compass, see #43 --- code/snowballs2/client/src/compass.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/code/snowballs2/client/src/compass.cpp b/code/snowballs2/client/src/compass.cpp index 11d7ddefa..b915cdb52 100644 --- a/code/snowballs2/client/src/compass.cpp +++ b/code/snowballs2/client/src/compass.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "mouse_listener.h" #include "camera.h" @@ -94,6 +95,13 @@ void updateCompass () { float x = CompassPosX; float y = CompassPosY; + if (StereoHMD) + { + float xshift, yshift; + StereoHMD->getInterface2DShift(xshift, yshift, 4.0f); + x += xshift; + y += yshift; + } float radius = CompassRadius; // tri @@ -109,7 +117,8 @@ void updateCompass () quad.V2.set ( radius, radius, 0); quad.V3.set (-radius, radius, 0); - Driver->setMatrixMode2D43 (); + if (StereoHMD) Driver->setMatrixMode2D11(); + else Driver->setMatrixMode2D43(); CMatrix mtx; @@ -152,7 +161,7 @@ void updateCompass () Driver->setModelMatrix (mtx); Driver->drawQuad (quad, CompassMaterial); - x *= 3.0/4.0f; + if (!StereoHMD) x *= 3.0/4.0f; // Print position TextContext->setHotSpot(UTextContext::MiddleTop); From eb196fd99ae06c81b5769992411f899d74318da7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 19:58:27 +0200 Subject: [PATCH 038/137] Adjust 2D interface shift, re #43 --- code/nel/src/3d/stereo_ovr.cpp | 43 +++++++++++++++++-- .../bin/snowballs_client_default.cfg | 2 +- code/snowballs2/client/src/commands.cpp | 2 +- code/snowballs2/client/src/compass.cpp | 2 +- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index cba1c004f..1f62213eb 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -393,17 +393,52 @@ NLMISC::CQuat CStereoOVR::getOrientation() const /// Get GUI shift void CStereoOVR::getInterface2DShift(float &x, float &y, float distance) { +#if 0 + NLMISC::CVector vector = CVector(0.f, -distance, 0.f); NLMISC::CQuat rot = getOrientation(); rot.invert(); NLMISC::CMatrix mat; mat.rotate(rot); - if (m_Stage % 2) mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); - else mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); + //if (m_Stage % 2) mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); + //else mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); mat.translate(vector); CVector proj = CStereoOVR::getCurrentFrustum().project(mat.getPos()); - x = proj.x - 0.5f; - y = proj.y - 0.5f; + + NLMISC::CVector ipd; + if (m_Stage % 2) ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f); + else ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f); + CVector projipd = CStereoOVR::getCurrentFrustum().project(vector + ipd); + CVector projvec = CStereoOVR::getCurrentFrustum().project(vector); + + x = (proj.x + projipd.x - projvec.x - 0.5f); + y = (proj.y + projipd.y - projvec.y - 0.5f); + +#elif 1 + + // Alternative method + + NLMISC::CVector vec = CVector(0.f, -distance, 0.f); + NLMISC::CVector ipd; + if (m_Stage % 2) ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f); + else ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f); + + + NLMISC::CQuat rot = getOrientation(); + NLMISC::CQuat modrot = NLMISC::CQuat(CVector(0.f, 1.f, 0.f), NLMISC::Pi); + rot = rot * modrot; + float p = NLMISC::Pi + atan2f(2.0f * ((rot.x * rot.y) + (rot.z * rot.w)), 1.0f - 2.0f * ((rot.y * rot.y) + (rot.w * rot.w))); + if (p > NLMISC::Pi) p -= NLMISC::Pi * 2.0f; + float t = -atan2f(2.0f * ((rot.x * rot.w) + (rot.y * rot.z)), 1.0f - 2.0f * ((rot.z * rot.z) + (rot.w * rot.w)));// // asinf(2.0f * ((rot.x * rot.z) - (rot.w * rot.y))); + + CVector rotshift = CVector(p, 0.f, t) * -distance; + + CVector proj = CStereoOVR::getCurrentFrustum().project(vec + ipd + rotshift); + + x = (proj.x - 0.5f); + y = (proj.y - 0.5f); + +#endif } void CStereoOVR::listDevices(std::vector &devicesOut) diff --git a/code/snowballs2/bin/snowballs_client_default.cfg b/code/snowballs2/bin/snowballs_client_default.cfg index 758bd8483..9d1429f83 100755 --- a/code/snowballs2/bin/snowballs_client_default.cfg +++ b/code/snowballs2/bin/snowballs_client_default.cfg @@ -52,7 +52,7 @@ ScreenHeight = 800; ScreenDepth = 32; // If 1, run in fullscreen mode, 0 for windowed -ScreenFull = 0; +ScreenFull = 1; // Start position of the player (the z is always 0) StartPoint = { 1840.0, -970.0, 0.0 }; diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index 4a36db8bb..bd44411e1 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -388,7 +388,7 @@ void updateCommands() if (StereoHMD) { float xshift, yshift; - StereoHMD->getInterface2DShift(xshift, yshift, 4.0f); + StereoHMD->getInterface2DShift(xshift, yshift, 1.f); // snap to pixels xshift = ((float)(sint32)(xshift * width)) / width; yshift = ((float)(sint32)(yshift * height)) / height; diff --git a/code/snowballs2/client/src/compass.cpp b/code/snowballs2/client/src/compass.cpp index b915cdb52..285ba3bdc 100644 --- a/code/snowballs2/client/src/compass.cpp +++ b/code/snowballs2/client/src/compass.cpp @@ -98,7 +98,7 @@ void updateCompass () if (StereoHMD) { float xshift, yshift; - StereoHMD->getInterface2DShift(xshift, yshift, 4.0f); + StereoHMD->getInterface2DShift(xshift, yshift, 1.f); x += xshift; y += yshift; } From 4a579d0af236f2696ec0858115da38e4e5fcf9bb Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 20:10:30 +0200 Subject: [PATCH 039/137] Fix warning --- code/nel/src/3d/stereo_ovr.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 1f62213eb..5ef7f9933 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -273,6 +273,10 @@ bool CStereoOVR::nextPass() m_OrientationCached = false; return false; } + nlassert(false); + m_Stage = 0; + m_OrientationCached = false; + return false; } const NL3D::CViewport &CStereoOVR::getCurrentViewport() const From 2f4867ab781b2b0c1e2125bc31c10a2ef194af9d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 20:57:37 +0200 Subject: [PATCH 040/137] Allow multiple user cameras to be calculated separately, useful for sky etc, re #43 --- code/nel/include/nel/3d/stereo_ovr.h | 20 ++++---- code/nel/src/3d/stereo_ovr.cpp | 46 +++++++++---------- code/snowballs2/client/src/camera.cpp | 2 +- code/snowballs2/client/src/commands.cpp | 2 +- code/snowballs2/client/src/compass.cpp | 2 +- .../client/src/snowballs_client.cpp | 8 ++-- 6 files changed, 41 insertions(+), 39 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index bb85438ad..552995457 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -72,6 +72,8 @@ public: class CStereoOVRDevicePtr; +#define NL_STEREO_MAX_USER_CAMERAS 8 + /** * \brief CStereoOVR * \date 2013-06-25 22:22GMT @@ -88,18 +90,18 @@ public: /// Gets the required screen resolution for this device virtual void getScreenResolution(uint &width, uint &height); /// Set latest camera position etcetera - virtual void updateCamera(const NL3D::UCamera *camera); + virtual void updateCamera(uint cid, const NL3D::UCamera *camera); /// Is there a next pass virtual bool nextPass(); /// Gets the current viewport virtual const NL3D::CViewport &getCurrentViewport() const; /// Gets the current camera frustum - virtual const NL3D::CFrustum &getCurrentFrustum() const; + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const; /// Gets the current camera frustum - virtual void getCurrentFrustum(NL3D::UCamera *camera) const; + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const; /// Gets the current camera matrix - virtual void getCurrentMatrix(NL3D::UCamera *camera) const; + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; /// At the start of a new render target virtual bool beginClear(); @@ -122,7 +124,7 @@ public: /// Get the HMD orientation virtual NLMISC::CQuat getOrientation() const; /// Get GUI center (1 = width, 1 = height, 0 = center) - virtual void getInterface2DShift(float &x, float &y, float distance); + virtual void getInterface2DShift(uint cid, float &x, float &y, float distance); static void listDevices(std::vector &devicesOut); @@ -132,7 +134,7 @@ public: /// Calculates internal camera information based on the reference camera - void initCamera(const NL3D::UCamera *camera); + void initCamera(uint cid, const NL3D::UCamera *camera); bool isDeviceCreated(); @@ -141,9 +143,9 @@ private: int m_Stage; CViewport m_LeftViewport; CViewport m_RightViewport; - CFrustum m_LeftFrustum; - CFrustum m_RightFrustum; - CMatrix m_CameraMatrix; + CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; mutable bool m_OrientationCached; mutable NLMISC::CQuat m_OrientationCache; diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 5ef7f9933..4b2417571 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -204,29 +204,29 @@ void CStereoOVR::getScreenResolution(uint &width, uint &height) height = m_DevicePtr->HMDInfo.VResolution; } -void CStereoOVR::initCamera(const NL3D::UCamera *camera) +void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) { float ar = (float)m_DevicePtr->HMDInfo.HResolution / ((float)m_DevicePtr->HMDInfo.VResolution * 2.0f); float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.VScreenSize / 2.0f) / m_DevicePtr->HMDInfo.EyeToScreenDistance); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); - m_LeftFrustum.initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); - m_RightFrustum = m_LeftFrustum; + m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); + m_RightFrustum[cid] = m_LeftFrustum[cid]; float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; float projectionCenterOffset = 4.0f * eyeProjectionShift / m_DevicePtr->HMDInfo.HScreenSize; nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset); - projectionCenterOffset *= (m_LeftFrustum.Left - m_LeftFrustum.Right) * 0.5f; // made this up ... - m_LeftFrustum.Left += projectionCenterOffset; - m_LeftFrustum.Right += projectionCenterOffset; - m_RightFrustum.Left -= projectionCenterOffset; - m_RightFrustum.Right -= projectionCenterOffset; + projectionCenterOffset *= (m_LeftFrustum[cid].Left - m_LeftFrustum[cid].Right) * 0.5f; // made this up ... + m_LeftFrustum[cid].Left += projectionCenterOffset; + m_LeftFrustum[cid].Right += projectionCenterOffset; + m_RightFrustum[cid].Left -= projectionCenterOffset; + m_RightFrustum[cid].Right -= projectionCenterOffset; } -void CStereoOVR::updateCamera(const NL3D::UCamera *camera) +void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera) { - if (camera->getFrustum().Near != m_LeftFrustum.Near - || camera->getFrustum().Far != m_LeftFrustum.Far) - CStereoOVR::initCamera(camera); - m_CameraMatrix = camera->getMatrix(); + if (camera->getFrustum().Near != m_LeftFrustum[cid].Near + || camera->getFrustum().Far != m_LeftFrustum[cid].Far) + CStereoOVR::initCamera(cid, camera); + m_CameraMatrix[cid] = camera->getMatrix(); } bool CStereoOVR::nextPass() @@ -285,25 +285,25 @@ const NL3D::CViewport &CStereoOVR::getCurrentViewport() const else return m_RightViewport; } -const NL3D::CFrustum &CStereoOVR::getCurrentFrustum() const +const NL3D::CFrustum &CStereoOVR::getCurrentFrustum(uint cid) const { - if (m_Stage % 2) return m_LeftFrustum; - else return m_RightFrustum; + if (m_Stage % 2) return m_LeftFrustum[cid]; + else return m_RightFrustum[cid]; } -void CStereoOVR::getCurrentFrustum(NL3D::UCamera *camera) const +void CStereoOVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const { - if (m_Stage % 2) camera->setFrustum(m_LeftFrustum); - else camera->setFrustum(m_RightFrustum); + if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]); + else camera->setFrustum(m_RightFrustum[cid]); } -void CStereoOVR::getCurrentMatrix(NL3D::UCamera *camera) const +void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const { CMatrix translate; if (m_Stage % 2) translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); else translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); camera->setTransformMode(NL3D::UTransformable::DirectMatrix); - camera->setMatrix(m_CameraMatrix * translate); + camera->setMatrix(m_CameraMatrix[cid] * translate); } bool CStereoOVR::beginClear() @@ -395,7 +395,7 @@ NLMISC::CQuat CStereoOVR::getOrientation() const } /// Get GUI shift -void CStereoOVR::getInterface2DShift(float &x, float &y, float distance) +void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distance) { #if 0 @@ -437,7 +437,7 @@ void CStereoOVR::getInterface2DShift(float &x, float &y, float distance) CVector rotshift = CVector(p, 0.f, t) * -distance; - CVector proj = CStereoOVR::getCurrentFrustum().project(vec + ipd + rotshift); + CVector proj = CStereoOVR::getCurrentFrustum(cid).project(vec + ipd + rotshift); x = (proj.x - 0.5f); y = (proj.y - 0.5f); diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index 030ebe0d9..ef65a7a9f 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -131,7 +131,7 @@ void initCamera() if (StereoHMD) { - StereoHMD->initCamera(&Camera); + StereoHMD->initCamera(0, &Camera); } // Create the snowing particle system diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index bd44411e1..e6e7a0086 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -388,7 +388,7 @@ void updateCommands() if (StereoHMD) { float xshift, yshift; - StereoHMD->getInterface2DShift(xshift, yshift, 1.f); + StereoHMD->getInterface2DShift(0, xshift, yshift, 1.f); // snap to pixels xshift = ((float)(sint32)(xshift * width)) / width; yshift = ((float)(sint32)(yshift * height)) / height; diff --git a/code/snowballs2/client/src/compass.cpp b/code/snowballs2/client/src/compass.cpp index 285ba3bdc..e01173f66 100644 --- a/code/snowballs2/client/src/compass.cpp +++ b/code/snowballs2/client/src/compass.cpp @@ -98,7 +98,7 @@ void updateCompass () if (StereoHMD) { float xshift, yshift; - StereoHMD->getInterface2DShift(xshift, yshift, 1.f); + StereoHMD->getInterface2DShift(0, xshift, yshift, 1.f); x += xshift; y += yshift; } diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 9563ad774..292465266 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -710,7 +710,7 @@ void loopIngame() // 09. Update Camera (depends on entities) updateCamera(); - if (StereoHMD) StereoHMD->updateCamera(&Camera); + if (StereoHMD) StereoHMD->updateCamera(0, &Camera); // 10. Update Interface (login, ui, etc) // ... @@ -741,9 +741,9 @@ void loopIngame() Driver->setViewport(vp); Scene->setViewport(vp); SkyScene->setViewport(vp); - StereoHMD->getCurrentFrustum(&Camera); - StereoHMD->getCurrentFrustum(&SkyCamera); - StereoHMD->getCurrentMatrix(&Camera); + StereoHMD->getCurrentFrustum(0, &Camera); + StereoHMD->getCurrentFrustum(0, &SkyCamera); + StereoHMD->getCurrentMatrix(0, &Camera); } if (!StereoHMD || StereoHMD->beginClear()) From d404c1228cc497e6f4f3950a12b49ecc8af58bb8 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 21:35:36 +0200 Subject: [PATCH 041/137] Create a clipping frustum, ref #43 --- code/nel/include/nel/3d/stereo_ovr.h | 3 +++ code/nel/src/3d/stereo_ovr.cpp | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 552995457..ba8d6eac6 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -91,6 +91,8 @@ public: virtual void getScreenResolution(uint &width, uint &height); /// Set latest camera position etcetera virtual void updateCamera(uint cid, const NL3D::UCamera *camera); + /// Get the frustum to use for clipping + virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const; /// Is there a next pass virtual bool nextPass(); @@ -143,6 +145,7 @@ private: int m_Stage; CViewport m_LeftViewport; CViewport m_RightViewport; + CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 4b2417571..f6c063de4 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -219,6 +219,17 @@ void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) m_LeftFrustum[cid].Right += projectionCenterOffset; m_RightFrustum[cid].Left -= projectionCenterOffset; m_RightFrustum[cid].Right -= projectionCenterOffset; + + // TODO: Clipping frustum should also take into account the IPD + m_ClippingFrustum[cid] = m_LeftFrustum[cid]; + m_ClippingFrustum[cid].Left = min(m_LeftFrustum[cid].Left, m_RightFrustum[cid].Left); + m_ClippingFrustum[cid].Right = max(m_LeftFrustum[cid].Right, m_RightFrustum[cid].Right); +} + +/// Get the frustum to use for clipping +void CStereoOVR::getClippingFrustum(uint cid, NL3D::UCamera *camera) const +{ + camera->setFrustum(m_ClippingFrustum[cid]); } void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera) From 9526910d4ba7017b2947606742502787f9d5eb53 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 26 Jun 2013 21:36:21 +0200 Subject: [PATCH 042/137] Return view as CQuat, see #43 --- code/ryzom/client/src/global.cpp | 2 ++ code/ryzom/client/src/global.h | 3 +++ code/ryzom/client/src/main_loop.cpp | 12 ++++++++---- code/ryzom/client/src/view.cpp | 9 ++++++++- code/ryzom/client/src/view.h | 2 ++ 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/code/ryzom/client/src/global.cpp b/code/ryzom/client/src/global.cpp index 8bd6f10fa..bb60f5c04 100644 --- a/code/ryzom/client/src/global.cpp +++ b/code/ryzom/client/src/global.cpp @@ -26,6 +26,8 @@ using namespace NLMISC; // *************************************************************************** // Main System NL3D::UDriver *Driver = 0; // The main 3D Driver +NL3D::CStereoOVR *StereoDisplay = NULL; // Stereo display +NL3D::CStereoOVR *StereoHMD = NULL; // Head mount display CSoundManager *SoundMngr = 0; // the sound manager NL3D::UMaterial GenericMat; // Generic Material NL3D::UTextContext *TextContext = 0; // Context for all the text in the client. diff --git a/code/ryzom/client/src/global.h b/code/ryzom/client/src/global.h index a6b7a03c6..6ec3db7ec 100644 --- a/code/ryzom/client/src/global.h +++ b/code/ryzom/client/src/global.h @@ -40,6 +40,7 @@ namespace NL3D class UMaterial; class UTextContext; class UWaterEnvMap; + class CStereoOVR; } class CEntityAnimationManager; @@ -77,6 +78,8 @@ const float ExtraZoneLoadingVision = 100.f; // *************************************************************************** // Main System extern NL3D::UDriver *Driver; // The main 3D Driver +extern NL3D::CStereoOVR *StereoDisplay; // Stereo display +extern NL3D::CStereoOVR *StereoHMD; extern CSoundManager *SoundMngr; // the sound manager extern NL3D::UMaterial GenericMat; // Generic Material extern NL3D::UTextContext *TextContext; // Context for all the text in the client. diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 2c362aceb..c034eaa83 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -42,6 +42,7 @@ #include "nel/3d/u_material.h" #include "nel/3d/u_instance_material.h" #include "nel/3d/u_cloud_scape.h" +#include "nel/3d/stereo_ovr.h" // game share #include "game_share/brick_types.h" #include "game_share/light_cycle.h" @@ -136,6 +137,7 @@ #include "nel/3d/driver_user.h" + #ifdef USE_WATER_ENV_MAP #include "water_env_map_rdr.h" #endif @@ -452,6 +454,8 @@ void validateDialogs(const CGameContextMenu &gcm); void buildCameraClippingPyramid (vector &planes) { + if (StereoDisplay) StereoDisplay->getClippingFrustum(0, &MainCam); + // Compute pyramid in view basis. CVector pfoc(0,0,0); const CFrustum &frustum = MainCam.getFrustum(); @@ -1006,7 +1010,7 @@ static void renderCanopyPart(UScene::TRenderPart renderPart) { // Update Camera Position/Rotation. camRoot.setPos(View.currentViewPos()); - camRoot.setRotQuat(View.currentView()); + camRoot.setRotQuat(View.currentViewQuat()); } // Render the root scene SceneRoot->renderPart(renderPart); @@ -1859,9 +1863,9 @@ bool mainLoop() // Update Camera Position/Orientation. CVector currViewPos = View.currentViewPos(); - MainCam.setPos(currViewPos);; - MainCam.setRotQuat(View.currentView()); - + MainCam.setPos(currViewPos); + MainCam.setRotQuat(View.currentViewQuat()); + if (StereoDisplay) StereoDisplay->updateCamera(0, &MainCam); // see if camera is below water (useful for sort order) if (ContinentMngr.cur()) diff --git a/code/ryzom/client/src/view.cpp b/code/ryzom/client/src/view.cpp index ded81013d..4bc52af08 100644 --- a/code/ryzom/client/src/view.cpp +++ b/code/ryzom/client/src/view.cpp @@ -183,7 +183,6 @@ CVector CView::currentViewPos() const //----------------------------------------------- // currentView : -// Set the user position. //----------------------------------------------- CVector CView::currentView() const { @@ -200,6 +199,14 @@ CVector CView::currentView() const return _View; }// currentView // +NLMISC::CQuat CView::currentViewQuat() const +{ + CMatrix mat; + mat.setRot(CVector::I, currentView(), CVector::K); + mat.normalize(CMatrix::YZX); + return mat.getRot(); +} + //----------------------------------------------- // currentCameraTarget : //----------------------------------------------- diff --git a/code/ryzom/client/src/view.h b/code/ryzom/client/src/view.h index 69fcea994..e1c57d4ca 100644 --- a/code/ryzom/client/src/view.h +++ b/code/ryzom/client/src/view.h @@ -115,6 +115,8 @@ public: CVector currentViewPos() const; // Return the current view (rear or normal) CVector currentView() const; + // Return the current view as a quaternion + NLMISC::CQuat currentViewQuat() const; // Return the current Camera Target (for 3rd person only. 1st person: return currentViewPos()) CVector currentCameraTarget() const; From b9334e372228e18938c74ad1c47569a9c692cbd2 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 27 Jun 2013 01:23:53 +0200 Subject: [PATCH 043/137] Pull CPing out of main_loop.cpp, refs #43 --- code/ryzom/client/src/main_loop.cpp | 80 +---------------------------- code/ryzom/client/src/ping.cpp | 73 ++++++++++++++++++++++++++ code/ryzom/client/src/ping.h | 62 ++++++++++++++++++++++ 3 files changed, 137 insertions(+), 78 deletions(-) create mode 100644 code/ryzom/client/src/ping.cpp create mode 100644 code/ryzom/client/src/ping.h diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index c034eaa83..8cccb99f2 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -150,6 +150,8 @@ #include "nel/gui/lua_manager.h" #include "nel/gui/group_table.h" +#include "ping.h" + /////////// // USING // @@ -218,84 +220,6 @@ uint64 SimulatedServerTick = 0; -/////////// -// CLASS // -/////////// -/** - * Class to manage the ping computed with the database. - * \author Guillaume PUZIN - * \author Nevrax France - * \date 2003 - */ -class CPing : public ICDBNode::IPropertyObserver -{ -private: - uint32 _Ping; - bool _RdyToPing; - -public: - // Constructor. - CPing() {_Ping = 0; _RdyToPing = true;} - // Destructor. - ~CPing() {;} - - // Add an observer on the database for the ping. - void init() - { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - if(pIM) - { - CCDBNodeLeaf *pNodeLeaf = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:DEBUG_INFO:Ping", false); - if(pNodeLeaf) - { - ICDBNode::CTextId textId; - pNodeLeaf->addObserver(this, textId); - // nlwarning("CPing: cannot add the observer"); - } - else - nlwarning("CPing: 'SERVER:DEBUG_INFO:Ping' does not exist."); - } - } - - // Release the observer on the database for the ping. - void release() - { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - if(pIM) - { - CCDBNodeLeaf *pNodeLeaf = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:DEBUG_INFO:Ping", false); - if(pNodeLeaf) - { - ICDBNode::CTextId textId; - pNodeLeaf->removeObserver(this, textId); - } - else - nlwarning("CPing: 'SERVER:DEBUG_INFO:Ping' does not exist."); - } - } - - // Method called when the ping message is back. - virtual void update(ICDBNode* node) - { - CCDBNodeLeaf *leaf = safe_cast(node); - uint32 before = (uint32)leaf->getValue32(); - uint32 current = (uint32)(0xFFFFFFFF & ryzomGetLocalTime()); - if(before > current) - { - //nlwarning("DB PING Pb before '%u' after '%u'.", before, current); - if(ClientCfg.Check) - nlstop; - } - _Ping = current - before; - _RdyToPing = true; - } - - // return the ping in ms. - uint32 getValue() {return _Ping;} - - void rdyToPing(bool rdy) {_RdyToPing = rdy;} - bool rdyToPing() const {return _RdyToPing;} -}; ///////////// // GLOBALS // diff --git a/code/ryzom/client/src/ping.cpp b/code/ryzom/client/src/ping.cpp new file mode 100644 index 000000000..a6d5c2e2c --- /dev/null +++ b/code/ryzom/client/src/ping.cpp @@ -0,0 +1,73 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "ping.h" + +#include "interface_v3/interface_manager.h" +#include "time_client.h" + +using namespace NLMISC; +using namespace NLGUI; + +void CPing::init() +{ + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + if(pIM) + { + CCDBNodeLeaf *pNodeLeaf = CDBManager::getInstance()->getDbProp("SERVER:DEBUG_INFO:Ping", false); + if(pNodeLeaf) + { + ICDBNode::CTextId textId; + pNodeLeaf->addObserver(this, textId); + // nlwarning("CPing: cannot add the observer"); + } + else + nlwarning("CPing: 'SERVER:DEBUG_INFO:Ping' does not exist."); + } +} + +void CPing::release() +{ + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + if(pIM) + { + CCDBNodeLeaf *pNodeLeaf = CDBManager::getInstance()->getDbProp("SERVER:DEBUG_INFO:Ping", false); + if(pNodeLeaf) + { + ICDBNode::CTextId textId; + pNodeLeaf->removeObserver(this, textId); + } + else + nlwarning("CPing: 'SERVER:DEBUG_INFO:Ping' does not exist."); + } +} + +void CPing::update(NLMISC::ICDBNode* node) +{ + CCDBNodeLeaf *leaf = safe_cast(node); + uint32 before = (uint32)leaf->getValue32(); + uint32 current = (uint32)(0xFFFFFFFF & ryzomGetLocalTime()); + if(before > current) + { + //nlwarning("DB PING Pb before '%u' after '%u'.", before, current); + if(ClientCfg.Check) + nlstop; + } + _Ping = current - before; + _RdyToPing = true; +} + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/ping.h b/code/ryzom/client/src/ping.h new file mode 100644 index 000000000..46a7e2c13 --- /dev/null +++ b/code/ryzom/client/src/ping.h @@ -0,0 +1,62 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CL_PING_H +#define CL_PING_H + +#include +#include + +/////////// +// CLASS // +/////////// +/** + * Class to manage the ping computed with the database. + * \author Guillaume PUZIN + * \author Nevrax France + * \date 2003 + */ +class CPing : public NLMISC::ICDBNode::IPropertyObserver +{ +private: + uint32 _Ping; + bool _RdyToPing; + +public: + // Constructor. + CPing() {_Ping = 0; _RdyToPing = true;} + // Destructor. + ~CPing() {;} + + // Add an observer on the database for the ping. + void init(); + + // Release the observer on the database for the ping. + void release(); + + // Method called when the ping message is back. + virtual void update(NLMISC::ICDBNode* node); + + // return the ping in ms. + uint32 getValue() {return _Ping;} + + void rdyToPing(bool rdy) {_RdyToPing = rdy;} + bool rdyToPing() const {return _RdyToPing;} +}; + +#endif // CL_PING_H + +/* end of file */ \ No newline at end of file From 825ebb3335e5f2509b657467ff9df0d7bf562a7e Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 27 Jun 2013 01:43:04 +0200 Subject: [PATCH 044/137] Separate some profiling code from main_loop.cpp, see #43 --- code/ryzom/client/src/main_loop.cpp | 119 +-------------------- code/ryzom/client/src/profiling.cpp | 159 ++++++++++++++++++++++++++++ code/ryzom/client/src/profiling.h | 36 +++++++ 3 files changed, 197 insertions(+), 117 deletions(-) create mode 100644 code/ryzom/client/src/profiling.cpp create mode 100644 code/ryzom/client/src/profiling.h diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 8cccb99f2..bd79d3490 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -150,7 +150,9 @@ #include "nel/gui/lua_manager.h" #include "nel/gui/group_table.h" +// pulled from main_loop.cpp #include "ping.h" +#include "profiling.h" /////////// @@ -253,12 +255,6 @@ uint8 ShowInfos = 0; // 0=no info 1=text info 2=graph info bool bZeroCpu = false; // For no Cpu use if application is minimize TODO: intercept minimize message, called by CTRL + Z at this -bool Profiling = false; // Are we in Profile mode? -uint ProfileNumFrame = 0; -bool WantProfiling = false; -bool ProfilingVBLock = false; -bool WantProfilingVBLock = false; - bool MovieShooterSaving= false; // Are we in Shooting mode? @@ -415,119 +411,8 @@ void buildCameraClippingPyramid (vector &planes) } -//--------------------------------------------------- -// Test Profiling and run? -//--------------------------------------------------- -void testLaunchProfile() -{ - if(!WantProfiling) - return; - - // comes from ActionHandler - WantProfiling= false; - -#ifdef _PROFILE_ON_ - if( !Profiling ) - { - // start the bench. - NLMISC::CHTimer::startBench(); - ProfileNumFrame = 0; - Driver->startBench(); - if (SoundMngr) - SoundMngr->getMixer()->startDriverBench(); - // state - Profiling= true; - } - else - { - // end the bench. - if (SoundMngr) - SoundMngr->getMixer()->endDriverBench(); - NLMISC::CHTimer::endBench(); - Driver->endBench(); - // Display and save profile to a File. - CLog log; - CFileDisplayer fileDisplayer(NLMISC::CFile::findNewFile(getLogDirectory() + "profile.log")); - CStdDisplayer stdDisplayer; - log.addDisplayer(&fileDisplayer); - log.addDisplayer(&stdDisplayer); - // diplay - NLMISC::CHTimer::displayHierarchicalByExecutionPathSorted(&log, CHTimer::TotalTime, true, 48, 2); - NLMISC::CHTimer::displayHierarchical(&log, true, 48, 2); - NLMISC::CHTimer::displayByExecutionPath(&log, CHTimer::TotalTime); - NLMISC::CHTimer::display(&log, CHTimer::TotalTime); - NLMISC::CHTimer::display(&log, CHTimer::TotalTimeWithoutSons); - Driver->displayBench(&log); - - if (SoundMngr) - SoundMngr->getMixer()->displayDriverBench(&log); - - // state - Profiling= false; - } -#endif // #ifdef _PROFILE_ON_ -} - - -//--------------------------------------------------- -// Test ProfilingVBLock and run? -//--------------------------------------------------- -void testLaunchProfileVBLock() -{ - // If running, must stop for this frame. - if(ProfilingVBLock) - { - vector strs; - Driver->endProfileVBHardLock(strs); - nlinfo("Profile VBLock"); - nlinfo("**************"); - for(uint i=0;iprofileVBHardAllocation(strs); - for(uint i=0;iendProfileIBLock(strs); - nlinfo("Profile Index Buffer Lock"); - nlinfo("**************"); - for(uint i=0;iprofileIBAllocation(strs); - for(uint i=0;istartProfileVBHardLock(); - Driver->startProfileIBLock(); - } -} //--------------------------------------------------- diff --git a/code/ryzom/client/src/profiling.cpp b/code/ryzom/client/src/profiling.cpp new file mode 100644 index 000000000..54f830211 --- /dev/null +++ b/code/ryzom/client/src/profiling.cpp @@ -0,0 +1,159 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "profiling.h" + +// NeL includes +#include + +// Project includes +#include "misc.h" +#include "sound_manager.h" + +/////////// +// USING // +/////////// +using namespace NLMISC; +using namespace NL3D; + +//////////// +// EXTERN // +//////////// +extern UDriver *Driver; + +///////////// +// GLOBALS // +///////////// +bool Profiling = false; // Are we in Profile mode? +uint ProfileNumFrame = 0; +bool WantProfiling = false; +bool ProfilingVBLock = false; +bool WantProfilingVBLock = false; + +// ******************************************************************** + +/// Test Profiling and run? +void testLaunchProfile() +{ + if(!WantProfiling) + return; + + // comes from ActionHandler + WantProfiling= false; + +#ifdef _PROFILE_ON_ + if( !Profiling ) + { + // start the bench. + NLMISC::CHTimer::startBench(); + ProfileNumFrame = 0; + Driver->startBench(); + if (SoundMngr) + SoundMngr->getMixer()->startDriverBench(); + // state + Profiling= true; + } + else + { + // end the bench. + if (SoundMngr) + SoundMngr->getMixer()->endDriverBench(); + NLMISC::CHTimer::endBench(); + Driver->endBench(); + + + // Display and save profile to a File. + CLog log; + CFileDisplayer fileDisplayer(NLMISC::CFile::findNewFile(getLogDirectory() + "profile.log")); + CStdDisplayer stdDisplayer; + log.addDisplayer(&fileDisplayer); + log.addDisplayer(&stdDisplayer); + // diplay + NLMISC::CHTimer::displayHierarchicalByExecutionPathSorted(&log, CHTimer::TotalTime, true, 48, 2); + NLMISC::CHTimer::displayHierarchical(&log, true, 48, 2); + NLMISC::CHTimer::displayByExecutionPath(&log, CHTimer::TotalTime); + NLMISC::CHTimer::display(&log, CHTimer::TotalTime); + NLMISC::CHTimer::display(&log, CHTimer::TotalTimeWithoutSons); + Driver->displayBench(&log); + + if (SoundMngr) + SoundMngr->getMixer()->displayDriverBench(&log); + + // state + Profiling= false; + } +#endif // #ifdef _PROFILE_ON_ +} + +// ******************************************************************** + +/// Test ProfilingVBLock and run? +void testLaunchProfileVBLock() +{ + // If running, must stop for this frame. + if(ProfilingVBLock) + { + std::vector strs; + Driver->endProfileVBHardLock(strs); + nlinfo("Profile VBLock"); + nlinfo("**************"); + for(uint i=0;iprofileVBHardAllocation(strs); + for(uint i=0;iendProfileIBLock(strs); + nlinfo("Profile Index Buffer Lock"); + nlinfo("**************"); + for(uint i=0;iprofileIBAllocation(strs); + for(uint i=0;istartProfileVBHardLock(); + Driver->startProfileIBLock(); + } +} + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/profiling.h b/code/ryzom/client/src/profiling.h new file mode 100644 index 000000000..cb7a55495 --- /dev/null +++ b/code/ryzom/client/src/profiling.h @@ -0,0 +1,36 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CL_MAIN_LOOP_PROFILING_H +#define CL_MAIN_LOOP_PROFILING_H + +#include + +extern bool Profiling; // Are we in Profile mode? +extern uint ProfileNumFrame; +extern bool WantProfiling; +extern bool ProfilingVBLock; +extern bool WantProfilingVBLock; + +/// Test Profiling and run? +void testLaunchProfile(); + +/// Test ProfilingVBLock and run? +void testLaunchProfileVBLock(); + +#endif // CL_MAIN_LOOP_PROFILING_H + +/* end of file */ \ No newline at end of file From a046b1c494614ca66599bbf71e9a65c866cd9a79 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 27 Jun 2013 02:13:48 +0200 Subject: [PATCH 045/137] Take some debug render code out of main_loop.cpp, see #43 --- code/ryzom/client/src/main_loop.cpp | 497 +------------------ code/ryzom/client/src/main_loop_debug.cpp | 560 ++++++++++++++++++++++ code/ryzom/client/src/main_loop_debug.h | 31 ++ code/ryzom/client/src/ping.cpp | 1 + code/ryzom/client/src/profiling.cpp | 1 + code/ryzom/client/src/profiling.h | 6 +- 6 files changed, 601 insertions(+), 495 deletions(-) create mode 100644 code/ryzom/client/src/main_loop_debug.cpp create mode 100644 code/ryzom/client/src/main_loop_debug.h diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index bd79d3490..4ed395d29 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -153,6 +153,7 @@ // pulled from main_loop.cpp #include "ping.h" #include "profiling.h" +#include "main_loop_debug.h" /////////// @@ -178,7 +179,6 @@ static void viewportToScissor(const CViewport &vp, CScissor &scissor) //////////// // EXTERN // //////////// -extern std::set LodCharactersNotFound; extern UDriver *Driver; extern IMouseDevice *MouseDevice; extern UScene *Scene; @@ -193,13 +193,16 @@ extern TTime UniversalTime; extern UMaterial GenericMat; extern UCamera MainCam; extern CEventsListener EventsListener; -extern uint32 NbDatabaseChanges; extern CMatrix MainSceneViewMatrix; extern CMatrix InvMainSceneViewMatrix; extern std::vector LogoBitmaps; extern bool IsInRingSession; extern std::string UsedFSAddr; +// temp +extern NLMISC::CValueSmoother smoothFPS; +extern NLMISC::CValueSmoother moreSmoothFPS; + void loadBackgroundBitmap (TBackground background); void destroyLoadingBitmap (); void drawLoadingBitmap (float progress); @@ -301,8 +304,6 @@ CGameContextMenu GameContextMenu; -NLMISC::CValueSmoother smoothFPS; -NLMISC::CValueSmoother moreSmoothFPS(64); // Profile @@ -344,12 +345,6 @@ H_AUTO_DECL ( RZ_Client_Main_Loop_Net ) /////////////// // FUNCTIONS // /////////////// -// Display some debug infos. -void displayDebug(); -void displayDebugFps(); -void displayDebugUIUnderMouse(); -// Display an Help. -void displayHelp(); //update the sound manager (listener pos, user walk/run sound...) void updateSound(); @@ -3056,488 +3051,6 @@ class CHandlerDebugUiDumpElementUnderMouse : public IActionHandler REGISTER_ACTION_HANDLER( CHandlerDebugUiDumpElementUnderMouse, "debug_ui_inspect_element_under_mouse"); -//--------------------------------------------------- -// displayDebug : -// Display some debug infos. -//--------------------------------------------------- -void displayDebug() -{ - float lineStep = ClientCfg.DebugLineStep; - float line; - - // Initialize Pen // - //----------------// - // Create a shadow when displaying a text. - TextContext->setShaded(true); - // Set the font size. - TextContext->setFontSize(ClientCfg.DebugFontSize); - // Set the text color - TextContext->setColor(ClientCfg.DebugFontColor); - - // TOP LEFT // - //----------// - TextContext->setHotSpot(UTextContext::TopLeft); - line = 0.9f; - // FPS and Ms per frame - { - // smooth across frames. - double deltaTime = smoothFPS.getSmoothValue (); - // FPS and Ms per frame - if(deltaTime != 0.f) - TextContext->printfAt(0.f, line,"%.1f fps", 1.f/deltaTime); - else - TextContext->printfAt(0.f, line,"%.1f fps", 0.f); - TextContext->printfAt(0.1f, line, "%d ms", (uint)(deltaTime*1000)); - } - line -= lineStep; - line -= lineStep; - - // USER - // Front - TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) front", atan2(UserEntity->front().y, UserEntity->front().x), UserEntity->front().x, UserEntity->front().y, UserEntity->front().z); - line -= lineStep; - // Dir - TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) dir", atan2(UserEntity->dir().y, UserEntity->dir().x), UserEntity->dir().x, UserEntity->dir().y, UserEntity->dir().z); - line -= lineStep; - // NB Stage - TextContext->printfAt(0.0f, line, " NB Stage: %d", UserEntity->nbStage()); - line -= lineStep; - // NB Animation FXs still remaining in the remove list. - TextContext->printfAt(0.0f, line, " NB FXs to remove: %d", UserEntity->nbAnimFXToRemove()); - line -= lineStep; - // Mode. - TextContext->printfAt(0.0f, line, " Mode: %d (%s)", (sint)UserEntity->mode(), MBEHAV::modeToString(UserEntity->mode()).c_str()); - line -= lineStep; - // Behaviour. - TextContext->printfAt(0.0f, line, " Behaviour: %d (%s)", (sint)UserEntity->behaviour(), MBEHAV::behaviourToString(UserEntity->behaviour()).c_str()); - line -= lineStep; - // Display the target mount. - TextContext->printfAt(0.0f, line, " Mount: %d", UserEntity->mount()); - line -= lineStep; - // Display the target rider. - TextContext->printfAt(0.0f, line, " Rider: %d", UserEntity->rider()); - line -= lineStep; - // Display the current animation name. - TextContext->printfAt(0.0f, line, " Current Animation Name: %s", UserEntity->currentAnimationName().c_str()); - line -= lineStep; - // Display the current move animation set name. - TextContext->printfAt(0.0f, line, " Current AnimationSet Name (MOVE): %s", UserEntity->currentAnimationSetName(MOVE).c_str()); - line -= lineStep; - // Display Missing Animations - if(::CAnimation::MissingAnim.empty() == false) - { - TextContext->printfAt(0.0f, line, " '%u' Missing Animations, 1st: '%s'", ::CAnimation::MissingAnim.size(), (*(::CAnimation::MissingAnim.begin())).c_str()); - line -= lineStep; - } - // Display Missing LoD - if(LodCharactersNotFound.empty() == false) - { - TextContext->printfAt(0.0f, line, " '%u' Missing LoD, 1st: '%s'", LodCharactersNotFound.size(), (*(LodCharactersNotFound.begin())).c_str()); - line -= lineStep; - } - - // Watched Entity - line -= lineStep; - // Now Displaying the selection. - TextContext->printfAt(0.0f, line, "--*** Watched entity ***--"); - line -= lineStep; - // Display information about the debug entity slot. - if(WatchedEntitySlot != CLFECOMMON::INVALID_SLOT) - { - // Get a pointer on the target. - CEntityCL *watchedEntity = EntitiesMngr.entity(WatchedEntitySlot); - if(watchedEntity) - { - // Display Debug Information about the Selection. - watchedEntity->displayDebug(0.0f, line, -lineStep); - - // Distance of the target - CVectorD diffvector = UserEntity->pos() - watchedEntity->pos(); - TextContext->printfAt(0.0f, line, " Distance: %10.2f (Manhattan: %.2f)", diffvector.norm(), fabs(diffvector.x) + fabs(diffvector.y) ); - line -= lineStep; - } - // Target not allocated - else - { - TextContext->printfAt(0.0f, line, "Not allocated (%d)", WatchedEntitySlot); - line -= lineStep; - } - } - // No Target - else - { - TextContext->printfAt(0.0f, line, "None"); - line -= lineStep; - } - - /* Ca rame grave ! - - uint nMem = NLMEMORY::GetAllocatedMemory(); - line -= lineStep; - TextContext->printfAt(0.0f, line, "Mem Used: %d",nMem);*/ - - // 3D Filters information: -#ifdef _PROFILE_ON_ - line-= lineStep; - TextContext->printfAt(0.0f, line, "3D Filters:"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "MeshNoVP: %s", Filter3D[FilterMeshNoVP]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "MeshVP: %s", Filter3D[FilterMeshVP]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "FXs: %s", Filter3D[FilterFXs]?"Ok":"NOT RENDERED!"); - line-= lineStep; - if (Landscape) - { - TextContext->printfAt(0.0f, line, "Landscape: %s", Filter3D[FilterLandscape]?"Ok":"NOT RENDERED!"); - line-= lineStep; - } - else - { - TextContext->printfAt(0.0f, line, "Landscape not enabled"); - } - TextContext->printfAt(0.0f, line, "Vegetable: %s", Filter3D[FilterVegetable]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "Skeleton: %s", Filter3D[FilterSkeleton]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "Water: %s", Filter3D[FilterWater]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "Cloud: %s", Filter3D[FilterCloud]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "CoarseMesh: %s", Filter3D[FilterCoarseMesh]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "Sky: %s", Filter3D[FilterSky]?"Ok":"NOT RENDERED!"); - line-= lineStep; - // Materials Infos - TextContext->printfAt(0.0f, line, "SetupedMatrix: %d", Driver->profileSetupedModelMatrix() ); - line-= lineStep; - TextContext->printfAt(0.0f, line, "SetupedMaterials: %d", Driver->profileSetupedMaterials() ); - line-= lineStep; - // Display camera cluster system - TextContext->printfAt(0.0f, line, "ClusterSystem: %p", MainCam.getClusterSystem() ); - line-= 2 * lineStep; - // Lua stuffs - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - TextContext->printfAt(0.0f, line, "Lua mem (kb) : %d / %d", CLuaManager::getInstance().getLuaState()->getGCCount(), CLuaManager::getInstance().getLuaState()->getGCThreshold()); - line-= lineStep; - TextContext->printfAt(0.0f, line, "Lua stack size = %d", CLuaManager::getInstance().getLuaState()->getTop()); - line-= lineStep; - -#endif - - // TOP LEFT // - //-----------// - TextContext->setHotSpot(UTextContext::TopLeft); - line = 1.f; - string str; -#if FINAL_VERSION - str = "FV"; -#else - str = "DEV"; -#endif - if(ClientCfg.ExtendedCommands) - str += "_E"; - str += " "RYZOM_VERSION; - TextContext->printfAt(0.f, line, "Version %s", str.c_str()); - - // TOP MIDDLE // - //------------// - TextContext->setHotSpot(UTextContext::MiddleTop); - line = 1.f; - // Motion Mode - TextContext->printfAt(0.5f, line, "%s", UserControls.modeStr().c_str()); - line -= lineStep; - - // TOP RIGHT // - //-----------// - TextContext->setHotSpot(UTextContext::TopRight); - line = 1.f; - //// 3D Infos - // Video mem allocated. - TextContext->printfAt(1.f, line, "Video mem. : %f", Driver->profileAllocatedTextureMemory()/(1024.f*1024.f)); - line -= lineStep; - // Video mem used since last swapBuffers(). - TextContext->printfAt(1.f, line, "Video mem. since last swap buffer: %f", Driver->getUsedTextureMemory()/(1024.f*1024.f)); - line -= lineStep; - // Get the last face count asked from the main scene before reduction. - TextContext->printfAt(1.f, line, "Nb Skin Face Asked: %f", Scene->getGroupNbFaceAsked("Skin")); - line -= lineStep; - TextContext->printfAt(1.f, line, "Nb Fx Face Asked: %f", Scene->getGroupNbFaceAsked("Fx")); - line -= lineStep; - // All Triangles In - CPrimitiveProfile pIn; - CPrimitiveProfile pOut; - Driver->profileRenderedPrimitives(pIn, pOut); - TextContext->printfAt(1.f, line, "Tri In : %d", pIn.NTriangles+2*pIn.NQuads); - line -= lineStep; - // All Triangles Out - TextContext->printfAt(1.f, line, "Tri Out : %d", pOut.NTriangles+2*pIn.NQuads); - line -= lineStep; - // Current Cluster - string strPos; - // Check there is a PACS Primitive before using it. - if(UserEntity->getPrimitive() && GR) - { - UGlobalPosition gPos; - UserEntity->getPrimitive()->getGlobalPosition(gPos, dynamicWI); - string strPos = GR->getIdentifier(gPos); - } - else - strPos = "No Primitive"; - TextContext->printfAt(1.f, line, "Cluster : %s", strPos.c_str()); - line -= lineStep; - //// SOUND Infos - line -= lineStep; - if(SoundMngr) - { - TextContext->printfAt(1.f, line, "Sound source instance: %u", SoundMngr->getSourcesInstanceCount()); - line -= lineStep; - TextContext->printfAt(1.f, line, "Logical playing SoundSource: %u", SoundMngr->getMixer()->getPlayingSourcesCount ()); - line -= lineStep; - TextContext->printfAt(1.f, line, "Audio tracks: %u/%u", SoundMngr->getMixer()->getUsedTracksCount(), SoundMngr->getMixer()->getPolyphony()); - line -= lineStep; - if (SoundMngr->getMixer()->getMutedPlayingSourcesCount() > 0) - { - TextContext->printfAt(1.f, line, "Source muted: %u !", SoundMngr->getMixer()->getMutedPlayingSourcesCount()); - line -= lineStep; - } - TextContext->printfAt(1.f, line, "Samples in memory: %g MB", SoundMngr->getLoadingSamplesSize() / (1024.0f*1024.0f)); - line -= lineStep; - - } - - // BOTTOM RIGHT // - //--------------// - TextContext->setHotSpot(UTextContext::BottomRight); - line = 0.f; - //// POSITION - CVector postmp = View.viewPos(); - // Pos - TextContext->printfAt(1.f, line, "Position : %d %d %d",(int)postmp.x,(int)postmp.y,(int)postmp.z); - line += lineStep; - // Body Heading - TextContext->printfAt(1.f, line, "Front : %.2f %.2f %.2f", UserEntity->front().x, UserEntity->front().y, UserEntity->front().z); - line += lineStep; - // Speed - TextContext->printfAt(1.f, line, "Speed : %.2f", (float) UserEntity->speed()); - line += lineStep; - // Zone - if (!ClientCfg.Light) - { - if (Landscape) - { - TextContext->printfAt(1.f, line, "Zone: %s", Landscape->getZoneName(postmp).c_str()); - line += lineStep; - } - } - // Prim File - string primFile = PrimFiles.getCurrentPrimitive (); - if (!primFile.empty ()) - { - TextContext->printfAt(1.f, line, "Prim File: %s", primFile.c_str ()); - line += lineStep; - } - - //// CONNECTION - line += lineStep; - // Ryzom Day. - TextContext->printfAt(1.f, line, "Ryzom Day : %d", RT.getRyzomDay()); - line += lineStep; - // hour in the game - float dayNightCycleHour = (float)RT.getRyzomTime(); - TextContext->printfAt(1.f, line, "Ryzom Time : %2u:%02u", int(dayNightCycleHour), int((dayNightCycleHour-int(dayNightCycleHour))*60.0f)); - line += lineStep; - // light hour in the game, used to display te day/night - TextContext->printfAt(1.f, line, "Ryzom Light Time : %2u:%02u (%s)", int(DayNightCycleHour), int((DayNightCycleHour-int(DayNightCycleHour))*60.0f), LightCycleManager.getStateString().c_str()); - line += lineStep; - // Server GameCycle - TextContext->printfAt(1.f, line, "Server GameCycle : %u", (uint)NetMngr.getCurrentServerTick()); - line += lineStep; - // Current GameCycle - TextContext->printfAt(1.f, line, "Current GameCycle : %u", (uint)NetMngr.getCurrentClientTick()); - line += lineStep; - // Current GameCycle - TextContext->printfAt(1.f, line, "Ms per Cycle : %d", NetMngr.getMsPerTick()); - line += lineStep; - // Packet Loss - TextContext->printfAt(1.f, line, "Packet Loss : %.1f %%", NetMngr.getMeanPacketLoss()*100.0f); - line += lineStep; - // Packet Loss - TextContext->printfAt(1.f, line, "Packets Lost : %u", NetMngr.getTotalLostPackets()); - line += lineStep; - // Mean Upload - TextContext->printfAt(1.f, line, "Mean Upld : %.3f kbps", NetMngr.getMeanUpload()); - line += lineStep; - // Mean Download - TextContext->printfAt(1.f, line, "Mean Dnld : %.3f kbps", NetMngr.getMeanDownload()); - line += lineStep; - - // Mean Download - TextContext->printfAt(1.f, line, "Nb in Vision : %d(%d,%d,%d)", - EntitiesMngr.nbEntitiesAllocated(), - EntitiesMngr.nbUser(), - EntitiesMngr.nbPlayer(), - EntitiesMngr.nbChar()); - line += lineStep; - - // Number of database changes - TextContext->printfAt(1.f, line, "DB Changes : %u", NbDatabaseChanges ); - line += lineStep; - - // Ping - TextContext->printfAt(1.f, line, "DB Ping : %u ms", Ping.getValue()); - line += lineStep; - - - - - - // Manual weather setup - { - if(ContinentMngr.cur()) // Only usable if there is a continent loaded. - { - if (!ForceTrueWeatherValue) - { - const CWeatherFunction &wf = ContinentMngr.cur()->WeatherFunction[CurrSeason]; - float wv; - if (ClientCfg.ManualWeatherSetup) - { - wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ManualWeatherValue; - } - else - { - wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ::getBlendedWeather(RT.getRyzomDay(), RT.getRyzomTime(), *WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); - } - const CWeatherSetup *ws = wf.getWeatherSetup((uint) floorf(wv)); - std::string name0 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???"; - ws = wf.getWeatherSetup(std::min((uint) (floorf(wv) + 1), wf.getNumWeatherSetups() - 1)); - std::string name1 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???"; - TextContext->printfAt(1.f, line, "Weather value : %.02f : %s -> %s", ws ? wv : 0.f, name0.c_str(), name1.c_str()); - line += lineStep; - } - else - { - TextContext->printfAt(1.f, line, "Weather value : %.02f", WeatherManager.getWeatherValue() * std::max(ContinentMngr.cur()->WeatherFunction[CurrSeason].getNumWeatherSetups() - 1, 0u)); - line += lineStep; - TextContext->printfAt(1.f, line, "TEST WEATHER FUNCTION"); - line += lineStep; - } - // season - TextContext->printfAt(1.f, line, "Season : %s", EGSPD::CSeason::toString(CurrSeason).c_str()); - line += lineStep; - } - } - - // fog dist - if (ContinentMngr.cur()) - { - TextContext->printfAt(1.f, line, "Continent fog min near = %.1f, max far = %.1f", ContinentMngr.cur()->FogStart, ContinentMngr.cur()->FogEnd); - line += lineStep; - CFogState tmpFog; - ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), tmpFog); - TextContext->printfAt(1.f, line, "Continent fog curr near = %.1f, curr far = %.1f", tmpFog.FogStartDist, tmpFog.FogEndDist); - line += lineStep; - } - const CWeatherState &ws = WeatherManager.getCurrWeatherState(); - TextContext->printfAt(1.f, line, "Weather fog near = %.1f, far = %.1f", ws.FogNear[MainFog], ws.FogFar[MainFog]); - line += lineStep; - TextContext->printfAt(1.f, line, "Final fog near = %.1f, far = %.1f", MainFogState.FogStartDist, MainFogState.FogEndDist); - line += lineStep; - float left, right, bottom, top, znear, zfar; - Scene->getCam().getFrustum(left, right, bottom, top, znear, zfar); - TextContext->printfAt(1.f, line, "Clip near = %.1f, far = %.1f", znear, zfar); - line += lineStep; - - // Connection states - TextContext->printfAt(1.f, line, "State : %s", NetMngr.getConnectionStateCStr() ); - line += lineStep; - -// UGlobalPosition globalPos; -// UserEntity->getPrimitive()->getGlobalPosition(globalPos, dynamicWI); -// uint32 material = GR->getMaterial( globalPos ); -// TextContext->printfAt(0.5f,0.5f,"Material : %d Gpos=(inst=%d,surf=%d,x=%.2f,y=%.2f",material, globalPos.InstanceId, globalPos.LocalPosition.Surface, globalPos.LocalPosition.Estimation.x, globalPos.LocalPosition.Estimation.y); - - // No more shadow when displaying a text. - TextContext->setShaded(false); -}// displayDebug // - -//----------------------------------------------- -// Macro to Display a Text -//----------------------------------------------- -#define DISP_TEXT(x, text) \ - /* Display the text at the right place */ \ - TextContext->printfAt(x, line, text); \ - /* Change the line */ \ - line += lineStep; \ - -//--------------------------------------------------- -// displayHelp : -// Display an Help. -//--------------------------------------------------- -void displayHelp() -{ - float line = 1.f; - float lineStep = -ClientCfg.HelpLineStep; - - // Create a shadow when displaying a text. - TextContext->setShaded(true); - // Set the font size. - TextContext->setFontSize(ClientCfg.HelpFontSize); - // Set the text color - TextContext->setColor(ClientCfg.HelpFontColor); - - - line = 1.f; - TextContext->setHotSpot(UTextContext::TopLeft); - DISP_TEXT(0.0f, "SHIFT + F1 : This Menu") - DISP_TEXT(0.0f, "SHIFT + F2 : Display Debug Infos") - DISP_TEXT(0.0f, "SHIFT + F3 : Wire mode"); - DISP_TEXT(0.0f, "SHIFT + F4 : Do not Render the Scene"); - DISP_TEXT(0.0f, "SHIFT + F5 : Toogle Display OSD interfaces"); -// DISP_TEXT(0.0f, "SHIFT + F6 : Not used"); - DISP_TEXT(0.0f, "SHIFT + F7 : Compass Mode (User/Camera)"); - DISP_TEXT(0.0f, "SHIFT + F8 : Camera Mode (INSERT to change your position)"); - DISP_TEXT(0.0f, "SHIFT + F9 : Free Mouse"); - DISP_TEXT(0.0f, "SHIFT + F10 : Take a Screen Shot (+CTRL) for jpg"); -// DISP_TEXT(0.0f, "SHIFT + F11 : Test"); - DISP_TEXT(0.0f, "SHIFT + ESCAPE : Quit"); - DISP_TEXT(0.0f, "SHIFT + C : First/Third Person View"); - - line = 1.f; - TextContext->setHotSpot(UTextContext::TopRight); - DISP_TEXT(1.0f, "UP : FORWARD"); - DISP_TEXT(1.0f, "DOWN : BACKWARD"); - DISP_TEXT(1.0f, "LEFT : ROTATE LEFT"); - DISP_TEXT(1.0f, "RIGHT : ROTATE RIGHT"); - DISP_TEXT(1.0f, "CTRL + LEFT : STRAFE LEFT"); - DISP_TEXT(1.0f, "CTRL + RIGHT : STRAFE RIGHT"); - DISP_TEXT(1.0f, "END : Auto Walk"); - DISP_TEXT(1.0f, "DELETE : Walk/Run"); - DISP_TEXT(1.0f, "PG UP : Look Up"); - DISP_TEXT(1.0f, "PG DOWN : Look Down"); -// DISP_TEXT(1.0f, "CTRL + I : Inventory"); -// DISP_TEXT(1.0f, "CTRL + C : Spells composition interface"); -// DISP_TEXT(1.0f, "CTRL + S : Memorized Spells interface"); - DISP_TEXT(1.0f, "CTRL + B : Show/Hide PACS Borders"); - DISP_TEXT(1.0f, "CTRL + P : Player target himself"); - DISP_TEXT(1.0f, "CTRL + D : Unselect target"); - DISP_TEXT(1.0f, "CTRL + TAB : Next Chat Mode (say/shout"); - DISP_TEXT(1.0f, "CTRL + R : Reload Client.cfg File"); -// DISP_TEXT(1.0f, "CTRL + N : Toggle Night / Day lighting"); - DISP_TEXT(1.0f, "CTRL + F2 : Profile on / off"); - DISP_TEXT(1.0f, "CTRL + F3 : Movie Shooter record / stop"); - DISP_TEXT(1.0f, "CTRL + F4 : Movie Shooter replay"); - DISP_TEXT(1.0f, "CTRL + F5 : Movie Shooter save"); -#ifndef NL_USE_DEFAULT_MEMORY_MANAGER - DISP_TEXT(1.0f, "CTRL + F6 : Save memory stat report"); -#endif // NL_USE_DEFAULT_MEMORY_MANAGER - DISP_TEXT(1.0f, "CTRL + F7 : Show / hide prim file"); - DISP_TEXT(1.0f, "CTRL + F8 : Change prim file UP"); - DISP_TEXT(1.0f, "CTRL + F9 : Change prim file DOWN"); - - // No more shadow when displaying a text. - TextContext->setShaded(false); -}// displayHelp // //--------------------------------------------------- diff --git a/code/ryzom/client/src/main_loop_debug.cpp b/code/ryzom/client/src/main_loop_debug.cpp new file mode 100644 index 000000000..fc0e7801c --- /dev/null +++ b/code/ryzom/client/src/main_loop_debug.cpp @@ -0,0 +1,560 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include "main_loop_debug.h" + +#include + +#include "game_share/ryzom_version.h" + +#include "global.h" +#include "client_cfg.h" +#include "user_entity.h" +#include "debug_client.h" +#include "entities.h" +#include "motion/user_controls.h" +#include "pacs_client.h" +#include "sound_manager.h" +#include "view.h" +#include "prim_file.h" +#include "weather.h" +#include "light_cycle_manager.h" +#include "net_manager.h" +#include "ping.h" +#include "world_database_manager.h" +#include "continent_manager.h" +#include "client_sheets/weather_function_params_sheet.h" +#include "weather_manager_client.h" +#include "fog_map.h" + +using namespace NLMISC; +using namespace NL3D; + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +extern std::set LodCharactersNotFound; +extern uint32 NbDatabaseChanges; +extern CFogState MainFogState; +extern CPing Ping; + +//namespace /* anonymous */ { + +NLMISC::CValueSmoother smoothFPS; +NLMISC::CValueSmoother moreSmoothFPS(64); + +//} /* anonymous namespace */ + +//--------------------------------------------------- +// displayDebug : +// Display some debug infos. +//--------------------------------------------------- +void displayDebug() +{ + float lineStep = ClientCfg.DebugLineStep; + float line; + + // Initialize Pen // + //----------------// + // Create a shadow when displaying a text. + TextContext->setShaded(true); + // Set the font size. + TextContext->setFontSize(ClientCfg.DebugFontSize); + // Set the text color + TextContext->setColor(ClientCfg.DebugFontColor); + + // TOP LEFT // + //----------// + TextContext->setHotSpot(UTextContext::TopLeft); + line = 0.9f; + // FPS and Ms per frame + { + // smooth across frames. + double deltaTime = smoothFPS.getSmoothValue (); + // FPS and Ms per frame + if(deltaTime != 0.f) + TextContext->printfAt(0.f, line,"%.1f fps", 1.f/deltaTime); + else + TextContext->printfAt(0.f, line,"%.1f fps", 0.f); + TextContext->printfAt(0.1f, line, "%d ms", (uint)(deltaTime*1000)); + } + line -= lineStep; + line -= lineStep; + + // USER + // Front + TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) front", atan2(UserEntity->front().y, UserEntity->front().x), UserEntity->front().x, UserEntity->front().y, UserEntity->front().z); + line -= lineStep; + // Dir + TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) dir", atan2(UserEntity->dir().y, UserEntity->dir().x), UserEntity->dir().x, UserEntity->dir().y, UserEntity->dir().z); + line -= lineStep; + // NB Stage + TextContext->printfAt(0.0f, line, " NB Stage: %d", UserEntity->nbStage()); + line -= lineStep; + // NB Animation FXs still remaining in the remove list. + TextContext->printfAt(0.0f, line, " NB FXs to remove: %d", UserEntity->nbAnimFXToRemove()); + line -= lineStep; + // Mode. + TextContext->printfAt(0.0f, line, " Mode: %d (%s)", (sint)UserEntity->mode(), MBEHAV::modeToString(UserEntity->mode()).c_str()); + line -= lineStep; + // Behaviour. + TextContext->printfAt(0.0f, line, " Behaviour: %d (%s)", (sint)UserEntity->behaviour(), MBEHAV::behaviourToString(UserEntity->behaviour()).c_str()); + line -= lineStep; + // Display the target mount. + TextContext->printfAt(0.0f, line, " Mount: %d", UserEntity->mount()); + line -= lineStep; + // Display the target rider. + TextContext->printfAt(0.0f, line, " Rider: %d", UserEntity->rider()); + line -= lineStep; + // Display the current animation name. + TextContext->printfAt(0.0f, line, " Current Animation Name: %s", UserEntity->currentAnimationName().c_str()); + line -= lineStep; + // Display the current move animation set name. + TextContext->printfAt(0.0f, line, " Current AnimationSet Name (MOVE): %s", UserEntity->currentAnimationSetName(MOVE).c_str()); + line -= lineStep; + // Display Missing Animations + if(::CAnimation::MissingAnim.empty() == false) + { + TextContext->printfAt(0.0f, line, " '%u' Missing Animations, 1st: '%s'", ::CAnimation::MissingAnim.size(), (*(::CAnimation::MissingAnim.begin())).c_str()); + line -= lineStep; + } + // Display Missing LoD + if(LodCharactersNotFound.empty() == false) + { + TextContext->printfAt(0.0f, line, " '%u' Missing LoD, 1st: '%s'", LodCharactersNotFound.size(), (*(LodCharactersNotFound.begin())).c_str()); + line -= lineStep; + } + + // Watched Entity + line -= lineStep; + // Now Displaying the selection. + TextContext->printfAt(0.0f, line, "--*** Watched entity ***--"); + line -= lineStep; + // Display information about the debug entity slot. + if(WatchedEntitySlot != CLFECOMMON::INVALID_SLOT) + { + // Get a pointer on the target. + CEntityCL *watchedEntity = EntitiesMngr.entity(WatchedEntitySlot); + if(watchedEntity) + { + // Display Debug Information about the Selection. + watchedEntity->displayDebug(0.0f, line, -lineStep); + + // Distance of the target + CVectorD diffvector = UserEntity->pos() - watchedEntity->pos(); + TextContext->printfAt(0.0f, line, " Distance: %10.2f (Manhattan: %.2f)", diffvector.norm(), fabs(diffvector.x) + fabs(diffvector.y) ); + line -= lineStep; + } + // Target not allocated + else + { + TextContext->printfAt(0.0f, line, "Not allocated (%d)", WatchedEntitySlot); + line -= lineStep; + } + } + // No Target + else + { + TextContext->printfAt(0.0f, line, "None"); + line -= lineStep; + } + + /* Ca rame grave ! + + uint nMem = NLMEMORY::GetAllocatedMemory(); + line -= lineStep; + TextContext->printfAt(0.0f, line, "Mem Used: %d",nMem);*/ + + // 3D Filters information: +#ifdef _PROFILE_ON_ + line-= lineStep; + TextContext->printfAt(0.0f, line, "3D Filters:"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "MeshNoVP: %s", Filter3D[FilterMeshNoVP]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "MeshVP: %s", Filter3D[FilterMeshVP]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "FXs: %s", Filter3D[FilterFXs]?"Ok":"NOT RENDERED!"); + line-= lineStep; + if (Landscape) + { + TextContext->printfAt(0.0f, line, "Landscape: %s", Filter3D[FilterLandscape]?"Ok":"NOT RENDERED!"); + line-= lineStep; + } + else + { + TextContext->printfAt(0.0f, line, "Landscape not enabled"); + } + TextContext->printfAt(0.0f, line, "Vegetable: %s", Filter3D[FilterVegetable]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "Skeleton: %s", Filter3D[FilterSkeleton]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "Water: %s", Filter3D[FilterWater]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "Cloud: %s", Filter3D[FilterCloud]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "CoarseMesh: %s", Filter3D[FilterCoarseMesh]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "Sky: %s", Filter3D[FilterSky]?"Ok":"NOT RENDERED!"); + line-= lineStep; + // Materials Infos + TextContext->printfAt(0.0f, line, "SetupedMatrix: %d", Driver->profileSetupedModelMatrix() ); + line-= lineStep; + TextContext->printfAt(0.0f, line, "SetupedMaterials: %d", Driver->profileSetupedMaterials() ); + line-= lineStep; + // Display camera cluster system + TextContext->printfAt(0.0f, line, "ClusterSystem: %p", MainCam.getClusterSystem() ); + line-= 2 * lineStep; + // Lua stuffs + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + TextContext->printfAt(0.0f, line, "Lua mem (kb) : %d / %d", CLuaManager::getInstance().getLuaState()->getGCCount(), CLuaManager::getInstance().getLuaState()->getGCThreshold()); + line-= lineStep; + TextContext->printfAt(0.0f, line, "Lua stack size = %d", CLuaManager::getInstance().getLuaState()->getTop()); + line-= lineStep; + +#endif + + // TOP LEFT // + //-----------// + TextContext->setHotSpot(UTextContext::TopLeft); + line = 1.f; + string str; +#if FINAL_VERSION + str = "FV"; +#else + str = "DEV"; +#endif + if(ClientCfg.ExtendedCommands) + str += "_E"; + str += " "RYZOM_VERSION; + TextContext->printfAt(0.f, line, "Version %s", str.c_str()); + + // TOP MIDDLE // + //------------// + TextContext->setHotSpot(UTextContext::MiddleTop); + line = 1.f; + // Motion Mode + TextContext->printfAt(0.5f, line, "%s", UserControls.modeStr().c_str()); + line -= lineStep; + + // TOP RIGHT // + //-----------// + TextContext->setHotSpot(UTextContext::TopRight); + line = 1.f; + //// 3D Infos + // Video mem allocated. + TextContext->printfAt(1.f, line, "Video mem. : %f", Driver->profileAllocatedTextureMemory()/(1024.f*1024.f)); + line -= lineStep; + // Video mem used since last swapBuffers(). + TextContext->printfAt(1.f, line, "Video mem. since last swap buffer: %f", Driver->getUsedTextureMemory()/(1024.f*1024.f)); + line -= lineStep; + // Get the last face count asked from the main scene before reduction. + TextContext->printfAt(1.f, line, "Nb Skin Face Asked: %f", Scene->getGroupNbFaceAsked("Skin")); + line -= lineStep; + TextContext->printfAt(1.f, line, "Nb Fx Face Asked: %f", Scene->getGroupNbFaceAsked("Fx")); + line -= lineStep; + // All Triangles In + CPrimitiveProfile pIn; + CPrimitiveProfile pOut; + Driver->profileRenderedPrimitives(pIn, pOut); + TextContext->printfAt(1.f, line, "Tri In : %d", pIn.NTriangles+2*pIn.NQuads); + line -= lineStep; + // All Triangles Out + TextContext->printfAt(1.f, line, "Tri Out : %d", pOut.NTriangles+2*pIn.NQuads); + line -= lineStep; + // Current Cluster + string strPos; + // Check there is a PACS Primitive before using it. + if(UserEntity->getPrimitive() && GR) + { + UGlobalPosition gPos; + UserEntity->getPrimitive()->getGlobalPosition(gPos, dynamicWI); + string strPos = GR->getIdentifier(gPos); + } + else + strPos = "No Primitive"; + TextContext->printfAt(1.f, line, "Cluster : %s", strPos.c_str()); + line -= lineStep; + //// SOUND Infos + line -= lineStep; + if(SoundMngr) + { + TextContext->printfAt(1.f, line, "Sound source instance: %u", SoundMngr->getSourcesInstanceCount()); + line -= lineStep; + TextContext->printfAt(1.f, line, "Logical playing SoundSource: %u", SoundMngr->getMixer()->getPlayingSourcesCount ()); + line -= lineStep; + TextContext->printfAt(1.f, line, "Audio tracks: %u/%u", SoundMngr->getMixer()->getUsedTracksCount(), SoundMngr->getMixer()->getPolyphony()); + line -= lineStep; + if (SoundMngr->getMixer()->getMutedPlayingSourcesCount() > 0) + { + TextContext->printfAt(1.f, line, "Source muted: %u !", SoundMngr->getMixer()->getMutedPlayingSourcesCount()); + line -= lineStep; + } + TextContext->printfAt(1.f, line, "Samples in memory: %g MB", SoundMngr->getLoadingSamplesSize() / (1024.0f*1024.0f)); + line -= lineStep; + + } + + // BOTTOM RIGHT // + //--------------// + TextContext->setHotSpot(UTextContext::BottomRight); + line = 0.f; + //// POSITION + CVector postmp = View.viewPos(); + // Pos + TextContext->printfAt(1.f, line, "Position : %d %d %d",(int)postmp.x,(int)postmp.y,(int)postmp.z); + line += lineStep; + // Body Heading + TextContext->printfAt(1.f, line, "Front : %.2f %.2f %.2f", UserEntity->front().x, UserEntity->front().y, UserEntity->front().z); + line += lineStep; + // Speed + TextContext->printfAt(1.f, line, "Speed : %.2f", (float) UserEntity->speed()); + line += lineStep; + // Zone + if (!ClientCfg.Light) + { + if (Landscape) + { + TextContext->printfAt(1.f, line, "Zone: %s", Landscape->getZoneName(postmp).c_str()); + line += lineStep; + } + } + // Prim File + string primFile = PrimFiles.getCurrentPrimitive (); + if (!primFile.empty ()) + { + TextContext->printfAt(1.f, line, "Prim File: %s", primFile.c_str ()); + line += lineStep; + } + + //// CONNECTION + line += lineStep; + // Ryzom Day. + TextContext->printfAt(1.f, line, "Ryzom Day : %d", RT.getRyzomDay()); + line += lineStep; + // hour in the game + float dayNightCycleHour = (float)RT.getRyzomTime(); + TextContext->printfAt(1.f, line, "Ryzom Time : %2u:%02u", int(dayNightCycleHour), int((dayNightCycleHour-int(dayNightCycleHour))*60.0f)); + line += lineStep; + // light hour in the game, used to display te day/night + TextContext->printfAt(1.f, line, "Ryzom Light Time : %2u:%02u (%s)", int(DayNightCycleHour), int((DayNightCycleHour-int(DayNightCycleHour))*60.0f), LightCycleManager.getStateString().c_str()); + line += lineStep; + // Server GameCycle + TextContext->printfAt(1.f, line, "Server GameCycle : %u", (uint)NetMngr.getCurrentServerTick()); + line += lineStep; + // Current GameCycle + TextContext->printfAt(1.f, line, "Current GameCycle : %u", (uint)NetMngr.getCurrentClientTick()); + line += lineStep; + // Current GameCycle + TextContext->printfAt(1.f, line, "Ms per Cycle : %d", NetMngr.getMsPerTick()); + line += lineStep; + // Packet Loss + TextContext->printfAt(1.f, line, "Packet Loss : %.1f %%", NetMngr.getMeanPacketLoss()*100.0f); + line += lineStep; + // Packet Loss + TextContext->printfAt(1.f, line, "Packets Lost : %u", NetMngr.getTotalLostPackets()); + line += lineStep; + // Mean Upload + TextContext->printfAt(1.f, line, "Mean Upld : %.3f kbps", NetMngr.getMeanUpload()); + line += lineStep; + // Mean Download + TextContext->printfAt(1.f, line, "Mean Dnld : %.3f kbps", NetMngr.getMeanDownload()); + line += lineStep; + + // Mean Download + TextContext->printfAt(1.f, line, "Nb in Vision : %d(%d,%d,%d)", + EntitiesMngr.nbEntitiesAllocated(), + EntitiesMngr.nbUser(), + EntitiesMngr.nbPlayer(), + EntitiesMngr.nbChar()); + line += lineStep; + + // Number of database changes + TextContext->printfAt(1.f, line, "DB Changes : %u", NbDatabaseChanges ); + line += lineStep; + + // Ping + TextContext->printfAt(1.f, line, "DB Ping : %u ms", Ping.getValue()); + line += lineStep; + + + + + + // Manual weather setup + { + if(ContinentMngr.cur()) // Only usable if there is a continent loaded. + { + if (!ForceTrueWeatherValue) + { + const CWeatherFunction &wf = ContinentMngr.cur()->WeatherFunction[CurrSeason]; + float wv; + if (ClientCfg.ManualWeatherSetup) + { + wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ManualWeatherValue; + } + else + { + wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ::getBlendedWeather(RT.getRyzomDay(), RT.getRyzomTime(), *WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); + } + const CWeatherSetup *ws = wf.getWeatherSetup((uint) floorf(wv)); + std::string name0 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???"; + ws = wf.getWeatherSetup(std::min((uint) (floorf(wv) + 1), wf.getNumWeatherSetups() - 1)); + std::string name1 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???"; + TextContext->printfAt(1.f, line, "Weather value : %.02f : %s -> %s", ws ? wv : 0.f, name0.c_str(), name1.c_str()); + line += lineStep; + } + else + { + TextContext->printfAt(1.f, line, "Weather value : %.02f", WeatherManager.getWeatherValue() * std::max(ContinentMngr.cur()->WeatherFunction[CurrSeason].getNumWeatherSetups() - 1, 0u)); + line += lineStep; + TextContext->printfAt(1.f, line, "TEST WEATHER FUNCTION"); + line += lineStep; + } + // season + TextContext->printfAt(1.f, line, "Season : %s", EGSPD::CSeason::toString(CurrSeason).c_str()); + line += lineStep; + } + } + + // fog dist + if (ContinentMngr.cur()) + { + TextContext->printfAt(1.f, line, "Continent fog min near = %.1f, max far = %.1f", ContinentMngr.cur()->FogStart, ContinentMngr.cur()->FogEnd); + line += lineStep; + CFogState tmpFog; + ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), tmpFog); + TextContext->printfAt(1.f, line, "Continent fog curr near = %.1f, curr far = %.1f", tmpFog.FogStartDist, tmpFog.FogEndDist); + line += lineStep; + } + const CWeatherState &ws = WeatherManager.getCurrWeatherState(); + TextContext->printfAt(1.f, line, "Weather fog near = %.1f, far = %.1f", ws.FogNear[MainFog], ws.FogFar[MainFog]); + line += lineStep; + TextContext->printfAt(1.f, line, "Final fog near = %.1f, far = %.1f", MainFogState.FogStartDist, MainFogState.FogEndDist); + line += lineStep; + float left, right, bottom, top, znear, zfar; + Scene->getCam().getFrustum(left, right, bottom, top, znear, zfar); + TextContext->printfAt(1.f, line, "Clip near = %.1f, far = %.1f", znear, zfar); + line += lineStep; + + // Connection states + TextContext->printfAt(1.f, line, "State : %s", NetMngr.getConnectionStateCStr() ); + line += lineStep; + +// UGlobalPosition globalPos; +// UserEntity->getPrimitive()->getGlobalPosition(globalPos, dynamicWI); +// uint32 material = GR->getMaterial( globalPos ); +// TextContext->printfAt(0.5f,0.5f,"Material : %d Gpos=(inst=%d,surf=%d,x=%.2f,y=%.2f",material, globalPos.InstanceId, globalPos.LocalPosition.Surface, globalPos.LocalPosition.Estimation.x, globalPos.LocalPosition.Estimation.y); + + // No more shadow when displaying a text. + TextContext->setShaded(false); +}// displayDebug // + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +//----------------------------------------------- +// Macro to Display a Text +//----------------------------------------------- +#define DISP_TEXT(x, text) \ + /* Display the text at the right place */ \ + TextContext->printfAt(x, line, text); \ + /* Change the line */ \ + line += lineStep; \ + +//--------------------------------------------------- +// displayHelp : +// Display an Help. +//--------------------------------------------------- +void displayHelp() +{ + float line = 1.f; + float lineStep = -ClientCfg.HelpLineStep; + + // Create a shadow when displaying a text. + TextContext->setShaded(true); + // Set the font size. + TextContext->setFontSize(ClientCfg.HelpFontSize); + // Set the text color + TextContext->setColor(ClientCfg.HelpFontColor); + + + line = 1.f; + TextContext->setHotSpot(UTextContext::TopLeft); + DISP_TEXT(0.0f, "SHIFT + F1 : This Menu") + DISP_TEXT(0.0f, "SHIFT + F2 : Display Debug Infos") + DISP_TEXT(0.0f, "SHIFT + F3 : Wire mode"); + DISP_TEXT(0.0f, "SHIFT + F4 : Do not Render the Scene"); + DISP_TEXT(0.0f, "SHIFT + F5 : Toogle Display OSD interfaces"); +// DISP_TEXT(0.0f, "SHIFT + F6 : Not used"); + DISP_TEXT(0.0f, "SHIFT + F7 : Compass Mode (User/Camera)"); + DISP_TEXT(0.0f, "SHIFT + F8 : Camera Mode (INSERT to change your position)"); + DISP_TEXT(0.0f, "SHIFT + F9 : Free Mouse"); + DISP_TEXT(0.0f, "SHIFT + F10 : Take a Screen Shot (+CTRL) for jpg"); +// DISP_TEXT(0.0f, "SHIFT + F11 : Test"); + DISP_TEXT(0.0f, "SHIFT + ESCAPE : Quit"); + DISP_TEXT(0.0f, "SHIFT + C : First/Third Person View"); + + line = 1.f; + TextContext->setHotSpot(UTextContext::TopRight); + DISP_TEXT(1.0f, "UP : FORWARD"); + DISP_TEXT(1.0f, "DOWN : BACKWARD"); + DISP_TEXT(1.0f, "LEFT : ROTATE LEFT"); + DISP_TEXT(1.0f, "RIGHT : ROTATE RIGHT"); + DISP_TEXT(1.0f, "CTRL + LEFT : STRAFE LEFT"); + DISP_TEXT(1.0f, "CTRL + RIGHT : STRAFE RIGHT"); + DISP_TEXT(1.0f, "END : Auto Walk"); + DISP_TEXT(1.0f, "DELETE : Walk/Run"); + DISP_TEXT(1.0f, "PG UP : Look Up"); + DISP_TEXT(1.0f, "PG DOWN : Look Down"); +// DISP_TEXT(1.0f, "CTRL + I : Inventory"); +// DISP_TEXT(1.0f, "CTRL + C : Spells composition interface"); +// DISP_TEXT(1.0f, "CTRL + S : Memorized Spells interface"); + DISP_TEXT(1.0f, "CTRL + B : Show/Hide PACS Borders"); + DISP_TEXT(1.0f, "CTRL + P : Player target himself"); + DISP_TEXT(1.0f, "CTRL + D : Unselect target"); + DISP_TEXT(1.0f, "CTRL + TAB : Next Chat Mode (say/shout"); + DISP_TEXT(1.0f, "CTRL + R : Reload Client.cfg File"); +// DISP_TEXT(1.0f, "CTRL + N : Toggle Night / Day lighting"); + DISP_TEXT(1.0f, "CTRL + F2 : Profile on / off"); + DISP_TEXT(1.0f, "CTRL + F3 : Movie Shooter record / stop"); + DISP_TEXT(1.0f, "CTRL + F4 : Movie Shooter replay"); + DISP_TEXT(1.0f, "CTRL + F5 : Movie Shooter save"); +#ifndef NL_USE_DEFAULT_MEMORY_MANAGER + DISP_TEXT(1.0f, "CTRL + F6 : Save memory stat report"); +#endif // NL_USE_DEFAULT_MEMORY_MANAGER + DISP_TEXT(1.0f, "CTRL + F7 : Show / hide prim file"); + DISP_TEXT(1.0f, "CTRL + F8 : Change prim file UP"); + DISP_TEXT(1.0f, "CTRL + F9 : Change prim file DOWN"); + + // No more shadow when displaying a text. + TextContext->setShaded(false); +}// displayHelp // + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/main_loop_debug.h b/code/ryzom/client/src/main_loop_debug.h new file mode 100644 index 000000000..70139290e --- /dev/null +++ b/code/ryzom/client/src/main_loop_debug.h @@ -0,0 +1,31 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CL_MAIN_LOOP_DEBUG_H +#define CL_MAIN_LOOP_DEBUG_H + +#include + +// Display some debug infos. +void displayDebug(); +void displayDebugFps(); +void displayDebugUIUnderMouse(); +// Display an Help. +void displayHelp(); + +#endif // CL_MAIN_LOOP_DEBUG_H + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/ping.cpp b/code/ryzom/client/src/ping.cpp index a6d5c2e2c..5a07a2b9d 100644 --- a/code/ryzom/client/src/ping.cpp +++ b/code/ryzom/client/src/ping.cpp @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include #include "ping.h" #include "interface_v3/interface_manager.h" diff --git a/code/ryzom/client/src/profiling.cpp b/code/ryzom/client/src/profiling.cpp index 54f830211..a5a0f770f 100644 --- a/code/ryzom/client/src/profiling.cpp +++ b/code/ryzom/client/src/profiling.cpp @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include #include "profiling.h" // NeL includes diff --git a/code/ryzom/client/src/profiling.h b/code/ryzom/client/src/profiling.h index cb7a55495..2499fa20b 100644 --- a/code/ryzom/client/src/profiling.h +++ b/code/ryzom/client/src/profiling.h @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#ifndef CL_MAIN_LOOP_PROFILING_H -#define CL_MAIN_LOOP_PROFILING_H +#ifndef CL_PROFILING_H +#define CL_PROFILING_H #include @@ -31,6 +31,6 @@ void testLaunchProfile(); /// Test ProfilingVBLock and run? void testLaunchProfileVBLock(); -#endif // CL_MAIN_LOOP_PROFILING_H +#endif // CL_PROFILING_H /* end of file */ \ No newline at end of file From d91959109339b826e9420446e76f3abe0986ff84 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 27 Jun 2013 02:43:51 +0200 Subject: [PATCH 046/137] Moved some temp code out of main_loop.cpp, ref #43 --- code/ryzom/client/src/main_loop.cpp | 174 +---------------- code/ryzom/client/src/main_loop_temp.cpp | 226 +++++++++++++++++++++++ code/ryzom/client/src/main_loop_temp.h | 30 +++ 3 files changed, 261 insertions(+), 169 deletions(-) create mode 100644 code/ryzom/client/src/main_loop_temp.cpp create mode 100644 code/ryzom/client/src/main_loop_temp.h diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 4ed395d29..3e91ffda7 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -78,7 +78,7 @@ #include "world_database_manager.h" #include "continent_manager.h" #include "ig_callback.h" -#include "fog_map.h" +//#include "fog_map.h" #include "movie_shooter.h" #include "sound_manager.h" #include "graph.h" @@ -154,6 +154,7 @@ #include "ping.h" #include "profiling.h" #include "main_loop_debug.h" +#include "main_loop_temp.h" /////////// @@ -166,14 +167,7 @@ using namespace NLNET; using namespace std; -// TMP TMP -static void viewportToScissor(const CViewport &vp, CScissor &scissor) -{ - scissor.X = vp.getX(); - scissor.Y = vp.getY(); - scissor.Width = vp.getWidth(); - scissor.Height = vp.getHeight(); -} + //////////// @@ -2385,169 +2379,11 @@ bool mainLoop() // TMP TMP static volatile bool dumpValidPolys = false; - if (dumpValidPolys) - { - struct CPolyDisp : public CInterfaceElementVisitor - { - virtual void visitCtrl(CCtrlBase *ctrl) - { - CCtrlPolygon *cp = dynamic_cast(ctrl); - if (cp) - { - sint32 cornerX, cornerY; - cp->getParent()->getCorner(cornerX, cornerY, cp->getParentPosRef()); - for(sint32 y = 0; y < (sint32) Screen.getHeight(); ++y) - { - for(sint32 x = 0; x < (sint32) Screen.getWidth(); ++x) - { - if (cp->contains(CVector2f((float) (x - cornerX), (float) (y - cornerY)))) - { - ((CRGBA *) &Screen.getPixels()[0])[x + (Screen.getHeight() - 1 - y) * Screen.getWidth()] = CRGBA::Magenta; - } - } - } - } - } - CBitmap Screen; - } polyDisp; - Driver->getBuffer(polyDisp.Screen); - CInterfaceManager::getInstance()->visit(&polyDisp); - COFile output("poly.tga"); - polyDisp.Screen.writeTGA(output); - dumpValidPolys = false; - }; + if (dumpValidPolys) { tempDumpValidPolys(); dumpValidPolys = false; } // TMP TMP static volatile bool dumpColPolys = false; - if (dumpColPolys) - { - CPackedWorld *pw = R2::getEditor().getIslandCollision().getPackedIsland(); - if (pw) - { - static CMaterial material; - static CMaterial wiredMaterial; - static CMaterial texturedMaterial; - static CVertexBuffer vb; - static bool initDone = false; - if (!initDone) - { - vb.setVertexFormat(CVertexBuffer::PositionFlag); - vb.setPreferredMemory(CVertexBuffer::AGPVolatile, false); - material.initUnlit(); - material.setDoubleSided(true); - material.setZFunc(CMaterial::lessequal); - wiredMaterial.initUnlit(); - wiredMaterial.setDoubleSided(true); - wiredMaterial.setZFunc(CMaterial::lessequal); - wiredMaterial.setColor(CRGBA(255, 255, 255, 250)); - wiredMaterial.texEnvOpAlpha(0, CMaterial::Replace); - wiredMaterial.texEnvArg0Alpha(0, CMaterial::Diffuse, CMaterial::SrcAlpha); - wiredMaterial.setBlend(true); - wiredMaterial.setBlendFunc(CMaterial::srcalpha, CMaterial::invsrcalpha); - texturedMaterial.initUnlit(); - texturedMaterial.setDoubleSided(true); - texturedMaterial.setZFunc(CMaterial::lessequal); - initDone = true; - } - // just add a projected texture - R2::getEditor().getIslandCollision().loadEntryPoints(); - R2::CScenarioEntryPoints &sep = R2::CScenarioEntryPoints::getInstance(); - CVectorD playerPos = UserEntity->pos(); - R2::CScenarioEntryPoints::CCompleteIsland *island = sep.getCompleteIslandFromCoords(CVector2f((float) playerPos.x, (float) playerPos.y)); - static CSString currIsland; - if (island && island->Island != currIsland) - { - currIsland = island->Island; - CTextureFile *newTex = new CTextureFile(currIsland + "_sp.tga"); - newTex->setWrapS(ITexture::Clamp); - newTex->setWrapT(ITexture::Clamp); - texturedMaterial.setTexture(0, newTex); - texturedMaterial.texEnvOpRGB(0, CMaterial::Replace); - texturedMaterial.texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor); - texturedMaterial.setTexCoordGen(0, true); - texturedMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace); - CMatrix mat; - CVector scale((float) (island->XMax - island->XMin), - (float) (island->YMax - island->YMin), 0.f); - scale.x = 1.f / favoid0(scale.x); - scale.y = 1.f / favoid0(scale.y); - scale.z = 0.f; - mat.setScale(scale); - mat.setPos(CVector(- island->XMin * scale.x, - island->YMin * scale.y, 0.f)); - // - CMatrix uvScaleMat; - // - uint texWidth = (uint) (island->XMax - island->XMin); - uint texHeight = (uint) (island->YMax - island->YMin); - float UScale = (float) texWidth / raiseToNextPowerOf2(texWidth); - float VScale = (float) texHeight / raiseToNextPowerOf2(texHeight); - // - uvScaleMat.setScale(CVector(UScale, - VScale, 0.f)); - uvScaleMat.setPos(CVector(0.f, VScale, 0.f)); - // - texturedMaterial.enableUserTexMat(0, true); - texturedMaterial.setUserTexMat(0, uvScaleMat * mat); - } - const CFrustum &frust = MainCam.getFrustum(); - - // - IDriver *driver = ((CDriverUser *) Driver)->getDriver(); - - driver->enableFog(true); - const CRGBA clearColor = CRGBA(0, 0, 127, 0); - driver->setupFog(frust.Far * 0.8f, frust.Far, clearColor); - CViewport vp; - vp.init(0.f, 0.f, 1.f, 1.f); - driver->setupViewport(vp); - CScissor scissor; - viewportToScissor(vp, scissor); - driver->setupScissor(scissor); - // - driver->setFrustum(frust.Left, frust.Right, frust.Bottom, frust.Top, frust.Near, frust.Far, frust.Perspective); - driver->setupViewMatrix(MainCam.getMatrix().inverted()); - driver->setupModelMatrix(CMatrix::Identity); - // - // - const CVector localFrustCorners[8] = - { - CVector(frust.Left, frust.Near, frust.Top), - CVector(frust.Right, frust.Near, frust.Top), - CVector(frust.Right, frust.Near, frust.Bottom), - CVector(frust.Left, frust.Near, frust.Bottom), - CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near), - CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near), - CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near), - CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near) - }; - // roughly compute covered zones - // - /* - sint frustZoneMinX = INT_MAX; - sint frustZoneMaxX = INT_MIN; - sint frustZoneMinY = INT_MAX; - sint frustZoneMaxY = INT_MIN; - for(uint k = 0; k < sizeofarray(localFrustCorners); ++k) - { - CVector corner = camMat * localFrustCorners[k]; - sint zoneX = (sint) (corner.x / 160.f) - zoneMinX; - sint zoneY = (sint) floorf(corner.y / 160.f) - zoneMinY; - frustZoneMinX = std::min(frustZoneMinX, zoneX); - frustZoneMinY = std::min(frustZoneMinY, zoneY); - frustZoneMaxX = std::max(frustZoneMaxX, zoneX); - frustZoneMaxY = std::max(frustZoneMaxY, zoneY); - } - */ - - const uint TRI_BATCH_SIZE = 10000; // batch size for rendering - static std::vector zones; - zones.clear(); - pw->getZones(zones); - for(uint k = 0; k < zones.size(); ++k) - { - zones[k]->render(vb, *driver, texturedMaterial, wiredMaterial, MainCam.getMatrix(), TRI_BATCH_SIZE, localFrustCorners); - } - } - } + if (dumpColPolys) { tempDumpColPolys(); } if (ClientCfg.R2EDEnabled) { diff --git a/code/ryzom/client/src/main_loop_temp.cpp b/code/ryzom/client/src/main_loop_temp.cpp new file mode 100644 index 000000000..0b3f24fa3 --- /dev/null +++ b/code/ryzom/client/src/main_loop_temp.cpp @@ -0,0 +1,226 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include "main_loop_temp.h" + +#include "global.h" + +// tempDumpValidPolys +#include +#include +#include "interface_v3/interface_manager.h" + +// tempDumpColPolys +#include +#include "r2/editor.h" +#include "user_entity.h" +#include + +using namespace NLMISC; +using namespace NL3D; + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +// TMP TMP +void tempDumpValidPolys() +{ + struct CPolyDisp : public CInterfaceElementVisitor + { + virtual void visitCtrl(CCtrlBase *ctrl) + { + CCtrlPolygon *cp = dynamic_cast(ctrl); + if (cp) + { + sint32 cornerX, cornerY; + cp->getParent()->getCorner(cornerX, cornerY, cp->getParentPosRef()); + for(sint32 y = 0; y < (sint32) Screen.getHeight(); ++y) + { + for(sint32 x = 0; x < (sint32) Screen.getWidth(); ++x) + { + if (cp->contains(CVector2f((float) (x - cornerX), (float) (y - cornerY)))) + { + ((CRGBA *) &Screen.getPixels()[0])[x + (Screen.getHeight() - 1 - y) * Screen.getWidth()] = CRGBA::Magenta; + } + } + } + } + } + CBitmap Screen; + } polyDisp; + Driver->getBuffer(polyDisp.Screen); + CInterfaceManager::getInstance()->visit(&polyDisp); + COFile output("poly.tga"); + polyDisp.Screen.writeTGA(output); +} + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +// TMP TMP +static void viewportToScissor(const CViewport &vp, CScissor &scissor) +{ + scissor.X = vp.getX(); + scissor.Y = vp.getY(); + scissor.Width = vp.getWidth(); + scissor.Height = vp.getHeight(); +} + +// TMP TMP +void tempDumpColPolys() +{ + CPackedWorld *pw = R2::getEditor().getIslandCollision().getPackedIsland(); + if (pw) + { + static CMaterial material; + static CMaterial wiredMaterial; + static CMaterial texturedMaterial; + static CVertexBuffer vb; + static bool initDone = false; + if (!initDone) + { + vb.setVertexFormat(CVertexBuffer::PositionFlag); + vb.setPreferredMemory(CVertexBuffer::AGPVolatile, false); + material.initUnlit(); + material.setDoubleSided(true); + material.setZFunc(CMaterial::lessequal); + wiredMaterial.initUnlit(); + wiredMaterial.setDoubleSided(true); + wiredMaterial.setZFunc(CMaterial::lessequal); + wiredMaterial.setColor(CRGBA(255, 255, 255, 250)); + wiredMaterial.texEnvOpAlpha(0, CMaterial::Replace); + wiredMaterial.texEnvArg0Alpha(0, CMaterial::Diffuse, CMaterial::SrcAlpha); + wiredMaterial.setBlend(true); + wiredMaterial.setBlendFunc(CMaterial::srcalpha, CMaterial::invsrcalpha); + texturedMaterial.initUnlit(); + texturedMaterial.setDoubleSided(true); + texturedMaterial.setZFunc(CMaterial::lessequal); + initDone = true; + } + // just add a projected texture + R2::getEditor().getIslandCollision().loadEntryPoints(); + R2::CScenarioEntryPoints &sep = R2::CScenarioEntryPoints::getInstance(); + CVectorD playerPos = UserEntity->pos(); + R2::CScenarioEntryPoints::CCompleteIsland *island = sep.getCompleteIslandFromCoords(CVector2f((float) playerPos.x, (float) playerPos.y)); + static CSString currIsland; + if (island && island->Island != currIsland) + { + currIsland = island->Island; + CTextureFile *newTex = new CTextureFile(currIsland + "_sp.tga"); + newTex->setWrapS(ITexture::Clamp); + newTex->setWrapT(ITexture::Clamp); + texturedMaterial.setTexture(0, newTex); + texturedMaterial.texEnvOpRGB(0, CMaterial::Replace); + texturedMaterial.texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor); + texturedMaterial.setTexCoordGen(0, true); + texturedMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace); + CMatrix mat; + CVector scale((float) (island->XMax - island->XMin), + (float) (island->YMax - island->YMin), 0.f); + scale.x = 1.f / favoid0(scale.x); + scale.y = 1.f / favoid0(scale.y); + scale.z = 0.f; + mat.setScale(scale); + mat.setPos(CVector(- island->XMin * scale.x, - island->YMin * scale.y, 0.f)); + // + CMatrix uvScaleMat; + // + uint texWidth = (uint) (island->XMax - island->XMin); + uint texHeight = (uint) (island->YMax - island->YMin); + float UScale = (float) texWidth / raiseToNextPowerOf2(texWidth); + float VScale = (float) texHeight / raiseToNextPowerOf2(texHeight); + // + uvScaleMat.setScale(CVector(UScale, - VScale, 0.f)); + uvScaleMat.setPos(CVector(0.f, VScale, 0.f)); + // + texturedMaterial.enableUserTexMat(0, true); + texturedMaterial.setUserTexMat(0, uvScaleMat * mat); + } + const CFrustum &frust = MainCam.getFrustum(); + + // + IDriver *driver = ((CDriverUser *) Driver)->getDriver(); + + driver->enableFog(true); + const CRGBA clearColor = CRGBA(0, 0, 127, 0); + driver->setupFog(frust.Far * 0.8f, frust.Far, clearColor); + CViewport vp; + vp.init(0.f, 0.f, 1.f, 1.f); + driver->setupViewport(vp); + CScissor scissor; + viewportToScissor(vp, scissor); + driver->setupScissor(scissor); + // + driver->setFrustum(frust.Left, frust.Right, frust.Bottom, frust.Top, frust.Near, frust.Far, frust.Perspective); + driver->setupViewMatrix(MainCam.getMatrix().inverted()); + driver->setupModelMatrix(CMatrix::Identity); + // + // + const CVector localFrustCorners[8] = + { + CVector(frust.Left, frust.Near, frust.Top), + CVector(frust.Right, frust.Near, frust.Top), + CVector(frust.Right, frust.Near, frust.Bottom), + CVector(frust.Left, frust.Near, frust.Bottom), + CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near), + CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near), + CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near), + CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near) + }; + // roughly compute covered zones + // + /* + sint frustZoneMinX = INT_MAX; + sint frustZoneMaxX = INT_MIN; + sint frustZoneMinY = INT_MAX; + sint frustZoneMaxY = INT_MIN; + for(uint k = 0; k < sizeofarray(localFrustCorners); ++k) + { + CVector corner = camMat * localFrustCorners[k]; + sint zoneX = (sint) (corner.x / 160.f) - zoneMinX; + sint zoneY = (sint) floorf(corner.y / 160.f) - zoneMinY; + frustZoneMinX = std::min(frustZoneMinX, zoneX); + frustZoneMinY = std::min(frustZoneMinY, zoneY); + frustZoneMaxX = std::max(frustZoneMaxX, zoneX); + frustZoneMaxY = std::max(frustZoneMaxY, zoneY); + } + */ + + const uint TRI_BATCH_SIZE = 10000; // batch size for rendering + static std::vector zones; + zones.clear(); + pw->getZones(zones); + for(uint k = 0; k < zones.size(); ++k) + { + zones[k]->render(vb, *driver, texturedMaterial, wiredMaterial, MainCam.getMatrix(), TRI_BATCH_SIZE, localFrustCorners); + } + } +} + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/main_loop_temp.h b/code/ryzom/client/src/main_loop_temp.h new file mode 100644 index 000000000..4f24972f7 --- /dev/null +++ b/code/ryzom/client/src/main_loop_temp.h @@ -0,0 +1,30 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CL_MAIN_LOOP_TEMP_H +#define CL_MAIN_LOOP_TEMP_H + +#include + +// TMP TMP +void tempDumpValidPolys(); + +// TMP TMP +void tempDumpColPolys(); + +#endif // CL_MAIN_LOOP_TEMP_H + +/* end of file */ \ No newline at end of file From 1e461ec4f3c8835666f4a113d9145d85e6ec9cb0 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 27 Jun 2013 03:04:40 +0200 Subject: [PATCH 047/137] Some more debug functions moved, see #43 --- code/ryzom/client/src/main_loop.cpp | 210 +-------------------- code/ryzom/client/src/main_loop_debug.cpp | 214 ++++++++++++++++++++++ 2 files changed, 221 insertions(+), 203 deletions(-) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 3e91ffda7..4191e22b7 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -2536,6 +2536,9 @@ bool mainLoop() frameToSkip--; } + /////////////// + // FAR_TP -> // + /////////////// // Enter a network loop during the FarTP process, without doing the whole real main loop. // This code must remain at the very end of the main loop. if(LoginSM.getCurrentState() == CLoginStateMachine::st_enter_far_tp_main_loop) @@ -2619,7 +2622,10 @@ bool mainLoop() connectionState = NetMngr.getConnectionState(); CLuaManager::getInstance().executeLuaScript("game:onFarTpEnd()"); - } + } + /////////////// + // <- FAR_TP // + /////////////// } // end of main loop @@ -2687,208 +2693,6 @@ bool mainLoop() return ryzom_exit || (Driver == NULL) || (!Driver->isActive ()); }// mainLoop // -//--------------------------------------------------- -// displayDebug : -// Display some debug infos. -//--------------------------------------------------- -void displayDebugFps() -{ - float lineStep = ClientCfg.DebugLineStep; - float line; - - // Initialize Pen // - //----------------// - // Create a shadow when displaying a text. - TextContext->setShaded(true); - // Set the font size. - TextContext->setFontSize(ClientCfg.DebugFontSize); - // Set the text color - TextContext->setColor(ClientCfg.DebugFontColor); - - // TOP LEFT // - //----------// - TextContext->setHotSpot(UTextContext::TopLeft); - line = 0.9f; - // Ms per frame - { - float spf = smoothFPS.getSmoothValue (); - // Ms per frame - TextContext->printfAt(0.1f, line, "FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf); - line-= lineStep; - // More Smoothed Ms per frame - spf = moreSmoothFPS.getSmoothValue (); - TextContext->printfAt(0.1f, line, "Smoothed FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf); - line-= lineStep; - } -} - -static NLMISC::CRefPtr HighlightedDebugUI; - -// displayDebug : -// Display information about ui elements that are under the mouse -//--------------------------------------------------- -void displayDebugUIUnderMouse() -{ - float lineStep = ClientCfg.DebugLineStep; - float line; - - // Initialize Pen // - //----------------// - // Create a shadow when displaying a text. - TextContext->setShaded(true); - // Set the font size. - TextContext->setFontSize(ClientCfg.DebugFontSize); - - - - // TOP LEFT // - //----------// - TextContext->setHotSpot(UTextContext::TopLeft); - line = 0.9f; - - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - // for now only accessible with R2ED - if (ClientCfg.R2EDEnabled) - { - TextContext->setColor(CRGBA::Cyan); - TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+A) to cycle prev"); - line-= lineStep; - TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+Q) to cycle next"); - line-= lineStep; - TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+W) to inspect element"); - line-= 2 * lineStep; - } - // - const vector &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer (); - const vector &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer (); - // If previous highlighted element is found in the list, then keep it, else reset to first element - if (std::find(rICL.begin(), rICL.end(), HighlightedDebugUI) == rICL.end() && - std::find(rIGL.begin(), rIGL.end(), HighlightedDebugUI) == rIGL.end()) - { - if (!rICL.empty()) - { - HighlightedDebugUI = rICL[0]; - } - else - if (!rIGL.empty()) - { - HighlightedDebugUI = rIGL[0]; - } - else - { - HighlightedDebugUI = NULL; - } - } - // - TextContext->setColor(CRGBA::Green); - TextContext->printfAt(0.1f, line, "Controls under cursor "); - line -= lineStep * 1.4f; - TextContext->printfAt(0.1f, line, "----------------------"); - line -= lineStep; - for(uint k = 0; k < rICL.size(); ++k) - { - if (rICL[k]) - { - TextContext->setColor(rICL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red); - TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rICL[k]->getId().c_str(), rICL[k], rICL[k]->getParent()); - } - else - { - TextContext->setColor(CRGBA::Blue); - TextContext->printfAt(0.1f, line, " control found !!!"); - } - line-= lineStep; - } - // - TextContext->setColor(CRGBA::Green); - TextContext->printfAt(0.1f, line, "Groups under cursor "); - line -= lineStep * 1.4f; - TextContext->printfAt(0.1f, line, "----------------------"); - line-= lineStep; - for(uint k = 0; k < rIGL.size(); ++k) - { - if (rIGL[k]) - { - TextContext->setColor(rIGL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red); - TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rIGL[k]->getId().c_str(), rIGL[k], rIGL[k]->getParent()); - } - else - { - TextContext->setColor(CRGBA::Blue); - TextContext->printfAt(0.1f, line, " group found !!!"); - } - line-= lineStep; - } -} - - - -// get all element under the mouse in a single vector -static void getElementsUnderMouse(vector &ielem) -{ - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - const vector &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer(); - const vector &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer(); - ielem.clear(); - ielem.insert(ielem.end(), rICL.begin(), rICL.end()); - ielem.insert(ielem.end(), rIGL.begin(), rIGL.end()); -} - -class CHandlerDebugUiPrevElementUnderMouse : public IActionHandler -{ - virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) - { - vector ielem; - getElementsUnderMouse(ielem); - for(uint k = 0; k < ielem.size(); ++k) - { - if (HighlightedDebugUI == ielem[k]) - { - HighlightedDebugUI = ielem[k == 0 ? ielem.size() - 1 : k - 1]; - return; - } - } - } -}; -REGISTER_ACTION_HANDLER( CHandlerDebugUiPrevElementUnderMouse, "debug_ui_prev_element_under_mouse"); - -class CHandlerDebugUiNextElementUnderMouse : public IActionHandler -{ - virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) - { - vector ielem; - getElementsUnderMouse(ielem); - for(uint k = 0; k < ielem.size(); ++k) - { - if (HighlightedDebugUI == ielem[k]) - { - HighlightedDebugUI = ielem[(k + 1) % ielem.size()]; - return; - } - } - } -}; -REGISTER_ACTION_HANDLER( CHandlerDebugUiNextElementUnderMouse, "debug_ui_next_element_under_mouse"); - -class CHandlerDebugUiDumpElementUnderMouse : public IActionHandler -{ - virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) - { - if (HighlightedDebugUI == NULL) return; - CLuaState *lua = CLuaManager::getInstance().getLuaState(); - if (!lua) return; - CLuaStackRestorer lsr(lua, 0); - CLuaIHM::pushUIOnStack(*lua, HighlightedDebugUI); - lua->pushGlobalTable(); - CLuaObject env(*lua); - env["inspect"].callNoThrow(1, 0); - } -}; -REGISTER_ACTION_HANDLER( CHandlerDebugUiDumpElementUnderMouse, "debug_ui_inspect_element_under_mouse"); - - - - //--------------------------------------------------- // Just Display some text with ... anim at some place. //--------------------------------------------------- diff --git a/code/ryzom/client/src/main_loop_debug.cpp b/code/ryzom/client/src/main_loop_debug.cpp index fc0e7801c..dbcb47b96 100644 --- a/code/ryzom/client/src/main_loop_debug.cpp +++ b/code/ryzom/client/src/main_loop_debug.cpp @@ -18,6 +18,7 @@ #include "main_loop_debug.h" #include +#include #include "game_share/ryzom_version.h" @@ -40,9 +41,12 @@ #include "client_sheets/weather_function_params_sheet.h" #include "weather_manager_client.h" #include "fog_map.h" +#include "misc.h" +#include "interface_v3/interface_manager.h" using namespace NLMISC; using namespace NL3D; +using namespace NLGUI; // ******************************************************************** // ******************************************************************** @@ -54,6 +58,7 @@ extern std::set LodCharactersNotFound; extern uint32 NbDatabaseChanges; extern CFogState MainFogState; extern CPing Ping; +extern bool Filter3D[RYZOM_MAX_FILTER_3D]; //namespace /* anonymous */ { @@ -473,6 +478,215 @@ void displayDebug() // ******************************************************************** // ******************************************************************** +//--------------------------------------------------- +// displayDebug : +// Display some debug infos. +//--------------------------------------------------- +void displayDebugFps() +{ + float lineStep = ClientCfg.DebugLineStep; + float line; + + // Initialize Pen // + //----------------// + // Create a shadow when displaying a text. + TextContext->setShaded(true); + // Set the font size. + TextContext->setFontSize(ClientCfg.DebugFontSize); + // Set the text color + TextContext->setColor(ClientCfg.DebugFontColor); + + // TOP LEFT // + //----------// + TextContext->setHotSpot(UTextContext::TopLeft); + line = 0.9f; + // Ms per frame + { + float spf = smoothFPS.getSmoothValue (); + // Ms per frame + TextContext->printfAt(0.1f, line, "FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf); + line-= lineStep; + // More Smoothed Ms per frame + spf = moreSmoothFPS.getSmoothValue (); + TextContext->printfAt(0.1f, line, "Smoothed FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf); + line-= lineStep; + } +} + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +static NLMISC::CRefPtr HighlightedDebugUI; + +// displayDebug : +// Display information about ui elements that are under the mouse +//--------------------------------------------------- +void displayDebugUIUnderMouse() +{ + float lineStep = ClientCfg.DebugLineStep; + float line; + + // Initialize Pen // + //----------------// + // Create a shadow when displaying a text. + TextContext->setShaded(true); + // Set the font size. + TextContext->setFontSize(ClientCfg.DebugFontSize); + + + + // TOP LEFT // + //----------// + TextContext->setHotSpot(UTextContext::TopLeft); + line = 0.9f; + + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + // for now only accessible with R2ED + if (ClientCfg.R2EDEnabled) + { + TextContext->setColor(CRGBA::Cyan); + TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+A) to cycle prev"); + line-= lineStep; + TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+Q) to cycle next"); + line-= lineStep; + TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+W) to inspect element"); + line-= 2 * lineStep; + } + // + const std::vector &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer (); + const std::vector &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer (); + // If previous highlighted element is found in the list, then keep it, else reset to first element + if (std::find(rICL.begin(), rICL.end(), HighlightedDebugUI) == rICL.end() && + std::find(rIGL.begin(), rIGL.end(), HighlightedDebugUI) == rIGL.end()) + { + if (!rICL.empty()) + { + HighlightedDebugUI = rICL[0]; + } + else + if (!rIGL.empty()) + { + HighlightedDebugUI = rIGL[0]; + } + else + { + HighlightedDebugUI = NULL; + } + } + // + TextContext->setColor(CRGBA::Green); + TextContext->printfAt(0.1f, line, "Controls under cursor "); + line -= lineStep * 1.4f; + TextContext->printfAt(0.1f, line, "----------------------"); + line -= lineStep; + for(uint k = 0; k < rICL.size(); ++k) + { + if (rICL[k]) + { + TextContext->setColor(rICL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red); + TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rICL[k]->getId().c_str(), rICL[k], rICL[k]->getParent()); + } + else + { + TextContext->setColor(CRGBA::Blue); + TextContext->printfAt(0.1f, line, " control found !!!"); + } + line-= lineStep; + } + // + TextContext->setColor(CRGBA::Green); + TextContext->printfAt(0.1f, line, "Groups under cursor "); + line -= lineStep * 1.4f; + TextContext->printfAt(0.1f, line, "----------------------"); + line-= lineStep; + for(uint k = 0; k < rIGL.size(); ++k) + { + if (rIGL[k]) + { + TextContext->setColor(rIGL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red); + TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rIGL[k]->getId().c_str(), rIGL[k], rIGL[k]->getParent()); + } + else + { + TextContext->setColor(CRGBA::Blue); + TextContext->printfAt(0.1f, line, " group found !!!"); + } + line-= lineStep; + } +} + +// get all element under the mouse in a single vector +static void getElementsUnderMouse(std::vector &ielem) +{ + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + const std::vector &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer(); + const std::vector &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer(); + ielem.clear(); + ielem.insert(ielem.end(), rICL.begin(), rICL.end()); + ielem.insert(ielem.end(), rIGL.begin(), rIGL.end()); +} + +class CHandlerDebugUiPrevElementUnderMouse : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) + { + std::vector ielem; + getElementsUnderMouse(ielem); + for(uint k = 0; k < ielem.size(); ++k) + { + if (HighlightedDebugUI == ielem[k]) + { + HighlightedDebugUI = ielem[k == 0 ? ielem.size() - 1 : k - 1]; + return; + } + } + } +}; +REGISTER_ACTION_HANDLER( CHandlerDebugUiPrevElementUnderMouse, "debug_ui_prev_element_under_mouse"); + +class CHandlerDebugUiNextElementUnderMouse : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) + { + std::vector ielem; + getElementsUnderMouse(ielem); + for(uint k = 0; k < ielem.size(); ++k) + { + if (HighlightedDebugUI == ielem[k]) + { + HighlightedDebugUI = ielem[(k + 1) % ielem.size()]; + return; + } + } + } +}; +REGISTER_ACTION_HANDLER( CHandlerDebugUiNextElementUnderMouse, "debug_ui_next_element_under_mouse"); + +class CHandlerDebugUiDumpElementUnderMouse : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) + { + if (HighlightedDebugUI == NULL) return; + CLuaState *lua = CLuaManager::getInstance().getLuaState(); + if (!lua) return; + CLuaStackRestorer lsr(lua, 0); + CLuaIHM::pushUIOnStack(*lua, HighlightedDebugUI); + lua->pushGlobalTable(); + CLuaObject env(*lua); + env["inspect"].callNoThrow(1, 0); + } +}; +REGISTER_ACTION_HANDLER( CHandlerDebugUiDumpElementUnderMouse, "debug_ui_inspect_element_under_mouse"); + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + //----------------------------------------------- // Macro to Display a Text //----------------------------------------------- From 1928c9c6793fedb3d43112783e8ad2250591c5b7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 27 Jun 2013 03:16:53 +0200 Subject: [PATCH 048/137] Remove some unused includes, re #43 --- code/ryzom/client/src/main_loop.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 4191e22b7..36be09144 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -125,17 +125,6 @@ #include "nel/misc/check_fpu.h" -// TMP TMP -#include "nel/gui/ctrl_polygon.h" -// TMP TMP -#include "game_share/scenario_entry_points.h" -#include "nel/3d/driver.h" -#include "nel/3d/texture_file.h" - -#include "nel/3d/packed_world.h" -#include "nel/3d/packed_zone.h" -#include "nel/3d/driver_user.h" - #ifdef USE_WATER_ENV_MAP @@ -399,11 +388,6 @@ void buildCameraClippingPyramid (vector &planes) } } - - - - - //--------------------------------------------------- // update the camera perspective setup //--------------------------------------------------- From f84f5807c14535c0ef99a949fcdbd283536620ea Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 27 Jun 2013 03:49:30 +0200 Subject: [PATCH 049/137] Move some config stuff out of main_loop.cpp, see #43 --- code/ryzom/client/src/main_loop.cpp | 320 +--------------- code/ryzom/client/src/main_loop_utilities.cpp | 359 ++++++++++++++++++ code/ryzom/client/src/main_loop_utilities.h | 35 ++ 3 files changed, 395 insertions(+), 319 deletions(-) create mode 100644 code/ryzom/client/src/main_loop_utilities.cpp create mode 100644 code/ryzom/client/src/main_loop_utilities.h diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 36be09144..64379b7c2 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -144,6 +144,7 @@ #include "profiling.h" #include "main_loop_debug.h" #include "main_loop_temp.h" +#include "main_loop_utilities.h" /////////// @@ -388,325 +389,6 @@ void buildCameraClippingPyramid (vector &planes) } } -//--------------------------------------------------- -// update the camera perspective setup -//--------------------------------------------------- -void updateCameraPerspective() -{ - float fov, aspectRatio; - computeCurrentFovAspectRatio(fov, aspectRatio); - - // change the perspective of the scene - if(!MainCam.empty()) - MainCam.setPerspective(fov, aspectRatio, CameraSetupZNear, ClientCfg.Vision); - // change the perspective of the root scene - if(SceneRoot) - { - UCamera cam= SceneRoot->getCam(); - cam.setPerspective(fov, aspectRatio, SceneRootCameraZNear, SceneRootCameraZFar); - } -} - -//--------------------------------------------------- -// Compare ClientCfg and LastClientCfg to know what we must update -//--------------------------------------------------- -void updateFromClientCfg() -{ - CClientConfig::setValues(); - ClientCfg.IsInvalidated = false; - - // GRAPHICS - GENERAL - //--------------------------------------------------- - if ((ClientCfg.Windowed != LastClientCfg.Windowed) || - (ClientCfg.Width != LastClientCfg.Width) || - (ClientCfg.Height != LastClientCfg.Height) || - (ClientCfg.Depth != LastClientCfg.Depth) || - (ClientCfg.Frequency != LastClientCfg.Frequency)) - { - setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, - ClientCfg.Windowed, ClientCfg.Frequency)); - } - - if (ClientCfg.DivideTextureSizeBy2 != LastClientCfg.DivideTextureSizeBy2) - { - if (ClientCfg.DivideTextureSizeBy2) - Driver->forceTextureResize(2); - else - Driver->forceTextureResize(1); - } - - //--------------------------------------------------- - if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL) - { - if(ClientCfg.WaitVBL) - Driver->setSwapVBLInterval(1); - else - Driver->setSwapVBLInterval(0); - } - - // GRAPHICS - LANDSCAPE - //--------------------------------------------------- - if (ClientCfg.LandscapeThreshold != LastClientCfg.LandscapeThreshold) - { - if (Landscape) Landscape->setThreshold(ClientCfg.getActualLandscapeThreshold()); - } - - //--------------------------------------------------- - if (ClientCfg.LandscapeTileNear != LastClientCfg.LandscapeTileNear) - { - if (Landscape) Landscape->setTileNear(ClientCfg.LandscapeTileNear); - } - - //--------------------------------------------------- - if (Landscape) - { - if (ClientCfg.Vision != LastClientCfg.Vision) - { - if (!ClientCfg.Light) - { - // Not in an indoor ? - if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor) - { - // Refresh All Zone in streaming according to the refine position - vector zonesAdded; - vector zonesRemoved; - const R2::CScenarioEntryPoints::CCompleteIsland *ci = R2::CScenarioEntryPoints::getInstance().getCompleteIslandFromCoords(CVector2f((float) UserEntity->pos().x, (float) UserEntity->pos().y)); - Landscape->refreshAllZonesAround(View.refinePos(), ClientCfg.Vision + ExtraZoneLoadingVision, zonesAdded, zonesRemoved, ProgressBar, ci ? &(ci->ZoneIDs) : NULL); - LandscapeIGManager.unloadArrayZoneIG(zonesRemoved); - LandscapeIGManager.loadArrayZoneIG(zonesAdded); - } - } - } - } - - //--------------------------------------------------- - if (ClientCfg.Vision != LastClientCfg.Vision || ClientCfg.FoV!=LastClientCfg.FoV || - ClientCfg.Windowed != LastClientCfg.Windowed || ClientCfg.ScreenAspectRatio != LastClientCfg.ScreenAspectRatio ) - { - updateCameraPerspective(); - } - - //--------------------------------------------------- - if (Landscape) - { - if (ClientCfg.MicroVeget != LastClientCfg.MicroVeget) - { - if(ClientCfg.MicroVeget) - { - // if configured, enable the vegetable and load the texture. - Landscape->enableVegetable(true); - // Default setup. TODO later by gameDev. - Landscape->setVegetableWind(CVector(0.5, 0.5, 0).normed(), 0.5, 1, 0); - // Default setup. should work well for night/day transition in 30 minutes. - // Because all vegetables will be updated every 20 seconds => 90 steps. - Landscape->setVegetableUpdateLightingFrequency(1/20.f); - // Density (percentage to ratio) - Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f); - } - else - { - Landscape->enableVegetable(false); - } - } - } - - //--------------------------------------------------- - if (ClientCfg.MicroVegetDensity != LastClientCfg.MicroVegetDensity) - { - // Density (percentage to ratio) - if (Landscape) Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f); - } - - // GRAPHICS - SPECIAL EFFECTS - //--------------------------------------------------- - if (ClientCfg.FxNbMaxPoly != LastClientCfg.FxNbMaxPoly) - { - if (Scene->getGroupLoadMaxPolygon("Fx") != ClientCfg.FxNbMaxPoly) - Scene->setGroupLoadMaxPolygon("Fx", ClientCfg.FxNbMaxPoly); - } - - //--------------------------------------------------- - if (ClientCfg.Cloud != LastClientCfg.Cloud) - { - if (ClientCfg.Cloud) - { - InitCloudScape = true; - CloudScape = Scene->createCloudScape(); - } - else - { - if (CloudScape != NULL) - Scene->deleteCloudScape(CloudScape); - CloudScape = NULL; - } - } - - //--------------------------------------------------- - if (ClientCfg.CloudQuality != LastClientCfg.CloudQuality) - { - if (CloudScape != NULL) - CloudScape->setQuality(ClientCfg.CloudQuality); - } - - //--------------------------------------------------- - if (ClientCfg.CloudUpdate != LastClientCfg.CloudUpdate) - { - if (CloudScape != NULL) - CloudScape->setNbCloudToUpdateIn80ms(ClientCfg.CloudUpdate); - } - - //--------------------------------------------------- - if (ClientCfg.Shadows != LastClientCfg.Shadows) - { - // Enable/Disable Receive on Landscape - if(Landscape) - { - Landscape->enableReceiveShadowMap(ClientCfg.Shadows); - } - // Enable/Disable Cast for all entities - for(uint i=0;iupdateCastShadowMap(); - } - } - - // GRAPHICS - CHARACTERS - //--------------------------------------------------- - if (ClientCfg.SkinNbMaxPoly != LastClientCfg.SkinNbMaxPoly) - { - if (Scene->getGroupLoadMaxPolygon("Skin") != ClientCfg.SkinNbMaxPoly) - Scene->setGroupLoadMaxPolygon("Skin", ClientCfg.SkinNbMaxPoly); - } - - //--------------------------------------------------- - if (ClientCfg.NbMaxSkeletonNotCLod != LastClientCfg.NbMaxSkeletonNotCLod ) - { - Scene->setMaxSkeletonsInNotCLodForm(ClientCfg.NbMaxSkeletonNotCLod); - } - - //--------------------------------------------------- - if (ClientCfg.CharacterFarClip != LastClientCfg.CharacterFarClip) - { - // Nothing to do - } - - //--------------------------------------------------- - if (ClientCfg.HDEntityTexture != LastClientCfg.HDEntityTexture) - { - // Don't reload Texture, will be done at next Game Start - } - - // INTERFACE works - - - // INPUTS - //--------------------------------------------------- - if (ClientCfg.CursorSpeed != LastClientCfg.CursorSpeed) - SetMouseSpeed (ClientCfg.CursorSpeed); - - if (ClientCfg.CursorAcceleration != LastClientCfg.CursorAcceleration) - SetMouseAcceleration (ClientCfg.CursorAcceleration); - - if (ClientCfg.HardwareCursor != LastClientCfg.HardwareCursor) - { - if (ClientCfg.HardwareCursor != IsMouseCursorHardware()) - { - InitMouseWithCursor (ClientCfg.HardwareCursor); - } - } - - - // SOUND - //--------------------------------------------------- - bool mustReloadSoundMngrContinent= false; - - // disable/enable sound? - if (ClientCfg.SoundOn != LastClientCfg.SoundOn) - { - if (SoundMngr && !ClientCfg.SoundOn) - { - nlwarning("Deleting sound manager..."); - delete SoundMngr; - SoundMngr = NULL; - } - else if (SoundMngr == NULL && ClientCfg.SoundOn) - { - nlwarning("Creating sound manager..."); - SoundMngr = new CSoundManager(); - try - { - SoundMngr->init(NULL); - } - catch(const Exception &e) - { - nlwarning("init : Error when creating 'SoundMngr' : %s", e.what()); - SoundMngr = 0; - } - - // re-init with good SFX/Music Volume - if(SoundMngr) - { - SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); - SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); - } - } - else - { - nlwarning("Sound config error !"); - } - - mustReloadSoundMngrContinent= true; - } - - // change EAX? - if ( SoundMngr && LastClientCfg.SoundOn && - (ClientCfg.UseEax != LastClientCfg.UseEax) ) - { - SoundMngr->reset(); - - mustReloadSoundMngrContinent= true; - } - - // change SoundForceSoftwareBuffer? - if ( SoundMngr && LastClientCfg.SoundOn && - (ClientCfg.SoundForceSoftwareBuffer != LastClientCfg.SoundForceSoftwareBuffer) ) - { - SoundMngr->reset(); - - mustReloadSoundMngrContinent= true; - } - - // change MaxTrack? don't reset - if ( SoundMngr && LastClientCfg.SoundOn && - (ClientCfg.MaxTrack != LastClientCfg.MaxTrack)) - { - SoundMngr->getMixer()->changeMaxTrack(ClientCfg.MaxTrack); - } - - // change SoundFX Volume? don't reset - if (SoundMngr && ClientCfg.SoundSFXVolume != LastClientCfg.SoundSFXVolume) - { - SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); - } - - // change Game Music Volume? don't reset - if (SoundMngr && ClientCfg.SoundGameMusicVolume != LastClientCfg.SoundGameMusicVolume) - { - SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); - } - - // reload only if active and reseted - if (mustReloadSoundMngrContinent && SoundMngr && ContinentMngr.cur() && !ContinentMngr.cur()->Indoor && UserEntity) - { - SoundMngr->loadContinent(ContinentMngr.getCurrentContinentSelectName(), UserEntity->pos()); - } - - // Ok backup the new clientcfg - LastClientCfg = ClientCfg; -} - void preRenderNewSky () { CSky &sky = ContinentMngr.cur()->CurrentSky; diff --git a/code/ryzom/client/src/main_loop_utilities.cpp b/code/ryzom/client/src/main_loop_utilities.cpp new file mode 100644 index 000000000..26be0ab0d --- /dev/null +++ b/code/ryzom/client/src/main_loop_utilities.cpp @@ -0,0 +1,359 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include "main_loop_utilities.h" + +#include +#include + +#include "game_share/scenario_entry_points.h" + +#include "client_cfg.h" +#include "misc.h" +#include "global.h" +#include "world_database_manager.h" +#include "continent_manager.h" +#include "user_entity.h" +#include "view.h" +#include "ig_client.h" +#include "entities.h" +#include "input.h" +#include "sound_manager.h" + +using namespace NLMISC; +using namespace NL3D; + +//--------------------------------------------------- +// update the camera perspective setup +//--------------------------------------------------- +void updateCameraPerspective() +{ + float fov, aspectRatio; + computeCurrentFovAspectRatio(fov, aspectRatio); + + // change the perspective of the scene + if(!MainCam.empty()) + MainCam.setPerspective(fov, aspectRatio, CameraSetupZNear, ClientCfg.Vision); + // change the perspective of the root scene + if(SceneRoot) + { + UCamera cam= SceneRoot->getCam(); + cam.setPerspective(fov, aspectRatio, SceneRootCameraZNear, SceneRootCameraZFar); + } +} + +//--------------------------------------------------- +// Compare ClientCfg and LastClientCfg to know what we must update +//--------------------------------------------------- +void updateFromClientCfg() +{ + CClientConfig::setValues(); + ClientCfg.IsInvalidated = false; + + // GRAPHICS - GENERAL + //--------------------------------------------------- + if ((ClientCfg.Windowed != LastClientCfg.Windowed) || + (ClientCfg.Width != LastClientCfg.Width) || + (ClientCfg.Height != LastClientCfg.Height) || + (ClientCfg.Depth != LastClientCfg.Depth) || + (ClientCfg.Frequency != LastClientCfg.Frequency)) + { + setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, + ClientCfg.Windowed, ClientCfg.Frequency)); + } + + if (ClientCfg.DivideTextureSizeBy2 != LastClientCfg.DivideTextureSizeBy2) + { + if (ClientCfg.DivideTextureSizeBy2) + Driver->forceTextureResize(2); + else + Driver->forceTextureResize(1); + } + + //--------------------------------------------------- + if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL) + { + if(ClientCfg.WaitVBL) + Driver->setSwapVBLInterval(1); + else + Driver->setSwapVBLInterval(0); + } + + // GRAPHICS - LANDSCAPE + //--------------------------------------------------- + if (ClientCfg.LandscapeThreshold != LastClientCfg.LandscapeThreshold) + { + if (Landscape) Landscape->setThreshold(ClientCfg.getActualLandscapeThreshold()); + } + + //--------------------------------------------------- + if (ClientCfg.LandscapeTileNear != LastClientCfg.LandscapeTileNear) + { + if (Landscape) Landscape->setTileNear(ClientCfg.LandscapeTileNear); + } + + //--------------------------------------------------- + if (Landscape) + { + if (ClientCfg.Vision != LastClientCfg.Vision) + { + if (!ClientCfg.Light) + { + // Not in an indoor ? + if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor) + { + // Refresh All Zone in streaming according to the refine position + std::vector zonesAdded; + std::vector zonesRemoved; + const R2::CScenarioEntryPoints::CCompleteIsland *ci = R2::CScenarioEntryPoints::getInstance().getCompleteIslandFromCoords(CVector2f((float) UserEntity->pos().x, (float) UserEntity->pos().y)); + Landscape->refreshAllZonesAround(View.refinePos(), ClientCfg.Vision + ExtraZoneLoadingVision, zonesAdded, zonesRemoved, ProgressBar, ci ? &(ci->ZoneIDs) : NULL); + LandscapeIGManager.unloadArrayZoneIG(zonesRemoved); + LandscapeIGManager.loadArrayZoneIG(zonesAdded); + } + } + } + } + + //--------------------------------------------------- + if (ClientCfg.Vision != LastClientCfg.Vision || ClientCfg.FoV!=LastClientCfg.FoV || + ClientCfg.Windowed != LastClientCfg.Windowed || ClientCfg.ScreenAspectRatio != LastClientCfg.ScreenAspectRatio ) + { + updateCameraPerspective(); + } + + //--------------------------------------------------- + if (Landscape) + { + if (ClientCfg.MicroVeget != LastClientCfg.MicroVeget) + { + if(ClientCfg.MicroVeget) + { + // if configured, enable the vegetable and load the texture. + Landscape->enableVegetable(true); + // Default setup. TODO later by gameDev. + Landscape->setVegetableWind(CVector(0.5, 0.5, 0).normed(), 0.5, 1, 0); + // Default setup. should work well for night/day transition in 30 minutes. + // Because all vegetables will be updated every 20 seconds => 90 steps. + Landscape->setVegetableUpdateLightingFrequency(1/20.f); + // Density (percentage to ratio) + Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f); + } + else + { + Landscape->enableVegetable(false); + } + } + } + + //--------------------------------------------------- + if (ClientCfg.MicroVegetDensity != LastClientCfg.MicroVegetDensity) + { + // Density (percentage to ratio) + if (Landscape) Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f); + } + + // GRAPHICS - SPECIAL EFFECTS + //--------------------------------------------------- + if (ClientCfg.FxNbMaxPoly != LastClientCfg.FxNbMaxPoly) + { + if (Scene->getGroupLoadMaxPolygon("Fx") != ClientCfg.FxNbMaxPoly) + Scene->setGroupLoadMaxPolygon("Fx", ClientCfg.FxNbMaxPoly); + } + + //--------------------------------------------------- + if (ClientCfg.Cloud != LastClientCfg.Cloud) + { + if (ClientCfg.Cloud) + { + InitCloudScape = true; + CloudScape = Scene->createCloudScape(); + } + else + { + if (CloudScape != NULL) + Scene->deleteCloudScape(CloudScape); + CloudScape = NULL; + } + } + + //--------------------------------------------------- + if (ClientCfg.CloudQuality != LastClientCfg.CloudQuality) + { + if (CloudScape != NULL) + CloudScape->setQuality(ClientCfg.CloudQuality); + } + + //--------------------------------------------------- + if (ClientCfg.CloudUpdate != LastClientCfg.CloudUpdate) + { + if (CloudScape != NULL) + CloudScape->setNbCloudToUpdateIn80ms(ClientCfg.CloudUpdate); + } + + //--------------------------------------------------- + if (ClientCfg.Shadows != LastClientCfg.Shadows) + { + // Enable/Disable Receive on Landscape + if(Landscape) + { + Landscape->enableReceiveShadowMap(ClientCfg.Shadows); + } + // Enable/Disable Cast for all entities + for(uint i=0;iupdateCastShadowMap(); + } + } + + // GRAPHICS - CHARACTERS + //--------------------------------------------------- + if (ClientCfg.SkinNbMaxPoly != LastClientCfg.SkinNbMaxPoly) + { + if (Scene->getGroupLoadMaxPolygon("Skin") != ClientCfg.SkinNbMaxPoly) + Scene->setGroupLoadMaxPolygon("Skin", ClientCfg.SkinNbMaxPoly); + } + + //--------------------------------------------------- + if (ClientCfg.NbMaxSkeletonNotCLod != LastClientCfg.NbMaxSkeletonNotCLod ) + { + Scene->setMaxSkeletonsInNotCLodForm(ClientCfg.NbMaxSkeletonNotCLod); + } + + //--------------------------------------------------- + if (ClientCfg.CharacterFarClip != LastClientCfg.CharacterFarClip) + { + // Nothing to do + } + + //--------------------------------------------------- + if (ClientCfg.HDEntityTexture != LastClientCfg.HDEntityTexture) + { + // Don't reload Texture, will be done at next Game Start + } + + // INTERFACE works + + + // INPUTS + //--------------------------------------------------- + if (ClientCfg.CursorSpeed != LastClientCfg.CursorSpeed) + SetMouseSpeed (ClientCfg.CursorSpeed); + + if (ClientCfg.CursorAcceleration != LastClientCfg.CursorAcceleration) + SetMouseAcceleration (ClientCfg.CursorAcceleration); + + if (ClientCfg.HardwareCursor != LastClientCfg.HardwareCursor) + { + if (ClientCfg.HardwareCursor != IsMouseCursorHardware()) + { + InitMouseWithCursor (ClientCfg.HardwareCursor); + } + } + + + // SOUND + //--------------------------------------------------- + bool mustReloadSoundMngrContinent= false; + + // disable/enable sound? + if (ClientCfg.SoundOn != LastClientCfg.SoundOn) + { + if (SoundMngr && !ClientCfg.SoundOn) + { + nlwarning("Deleting sound manager..."); + delete SoundMngr; + SoundMngr = NULL; + } + else if (SoundMngr == NULL && ClientCfg.SoundOn) + { + nlwarning("Creating sound manager..."); + SoundMngr = new CSoundManager(); + try + { + SoundMngr->init(NULL); + } + catch(const Exception &e) + { + nlwarning("init : Error when creating 'SoundMngr' : %s", e.what()); + SoundMngr = 0; + } + + // re-init with good SFX/Music Volume + if(SoundMngr) + { + SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); + SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); + } + } + else + { + nlwarning("Sound config error !"); + } + + mustReloadSoundMngrContinent= true; + } + + // change EAX? + if ( SoundMngr && LastClientCfg.SoundOn && + (ClientCfg.UseEax != LastClientCfg.UseEax) ) + { + SoundMngr->reset(); + + mustReloadSoundMngrContinent= true; + } + + // change SoundForceSoftwareBuffer? + if ( SoundMngr && LastClientCfg.SoundOn && + (ClientCfg.SoundForceSoftwareBuffer != LastClientCfg.SoundForceSoftwareBuffer) ) + { + SoundMngr->reset(); + + mustReloadSoundMngrContinent= true; + } + + // change MaxTrack? don't reset + if ( SoundMngr && LastClientCfg.SoundOn && + (ClientCfg.MaxTrack != LastClientCfg.MaxTrack)) + { + SoundMngr->getMixer()->changeMaxTrack(ClientCfg.MaxTrack); + } + + // change SoundFX Volume? don't reset + if (SoundMngr && ClientCfg.SoundSFXVolume != LastClientCfg.SoundSFXVolume) + { + SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); + } + + // change Game Music Volume? don't reset + if (SoundMngr && ClientCfg.SoundGameMusicVolume != LastClientCfg.SoundGameMusicVolume) + { + SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); + } + + // reload only if active and reseted + if (mustReloadSoundMngrContinent && SoundMngr && ContinentMngr.cur() && !ContinentMngr.cur()->Indoor && UserEntity) + { + SoundMngr->loadContinent(ContinentMngr.getCurrentContinentSelectName(), UserEntity->pos()); + } + + // Ok backup the new clientcfg + LastClientCfg = ClientCfg; +} + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/main_loop_utilities.h b/code/ryzom/client/src/main_loop_utilities.h new file mode 100644 index 000000000..48d6a3880 --- /dev/null +++ b/code/ryzom/client/src/main_loop_utilities.h @@ -0,0 +1,35 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CL_MAIN_LOOP_UTILITIES_H +#define CL_MAIN_LOOP_UTILITIES_H + +#include + +// Update Utilities (configuration etc) +// Only put utility update functions here that are used in the main loop. +// This is mainly for system configuration related functions +// such as config file changes. + +/// does not belong here +void updateCameraPerspective(); + +/// Compare ClientCfg and LastClientCfg to know what we must update +void updateFromClientCfg(); + +#endif // CL_MAIN_LOOP_UTILITIES_H + +/* end of file */ From 3a4204e091146dd4fba4ccf283df8b7264cf9b9d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 27 Jun 2013 04:11:09 +0200 Subject: [PATCH 050/137] Separate some camera related functions, ref #43 --- code/ryzom/client/src/camera.cpp | 85 +++++++++++++++++++ code/ryzom/client/src/camera.h | 29 +++++++ code/ryzom/client/src/main_loop.cpp | 39 +-------- code/ryzom/client/src/main_loop_utilities.cpp | 20 +---- code/ryzom/client/src/main_loop_utilities.h | 3 - 5 files changed, 116 insertions(+), 60 deletions(-) create mode 100644 code/ryzom/client/src/camera.cpp create mode 100644 code/ryzom/client/src/camera.h diff --git a/code/ryzom/client/src/camera.cpp b/code/ryzom/client/src/camera.cpp new file mode 100644 index 000000000..66aac6f76 --- /dev/null +++ b/code/ryzom/client/src/camera.cpp @@ -0,0 +1,85 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include "camera.h" + +#include + +#include "global.h" +#include "misc.h" + +using namespace NLMISC; +using namespace NL3D; + +//--------------------------------------------------- +// update the camera perspective setup +//--------------------------------------------------- +void updateCameraPerspective() +{ + float fov, aspectRatio; + computeCurrentFovAspectRatio(fov, aspectRatio); + + // change the perspective of the scene + if(!MainCam.empty()) + MainCam.setPerspective(fov, aspectRatio, CameraSetupZNear, ClientCfg.Vision); + // change the perspective of the root scene + if(SceneRoot) + { + UCamera cam= SceneRoot->getCam(); + cam.setPerspective(fov, aspectRatio, SceneRootCameraZNear, SceneRootCameraZFar); + } +} + +void buildCameraClippingPyramid(std::vector &planes) +{ + if (StereoDisplay) StereoDisplay->getClippingFrustum(0, &MainCam); + + // Compute pyramid in view basis. + CVector pfoc(0,0,0); + const CFrustum &frustum = MainCam.getFrustum(); + InvMainSceneViewMatrix = MainCam.getMatrix(); + MainSceneViewMatrix = InvMainSceneViewMatrix; + MainSceneViewMatrix.invert(); + + CVector lb(frustum.Left, frustum.Near, frustum.Bottom ); + CVector lt(frustum.Left, frustum.Near, frustum.Top ); + CVector rb(frustum.Right, frustum.Near, frustum.Bottom ); + CVector rt(frustum.Right, frustum.Near, frustum.Top ); + + CVector lbFar(frustum.Left, ClientCfg.CharacterFarClip, frustum.Bottom); + CVector ltFar(frustum.Left, ClientCfg.CharacterFarClip, frustum.Top ); + CVector rtFar(frustum.Right, ClientCfg.CharacterFarClip, frustum.Top ); + + planes.resize (4); + // planes[0].make(lbFar, ltFar, rtFar); + planes[0].make(pfoc, lt, lb); + planes[1].make(pfoc, rt, lt); + planes[2].make(pfoc, rb, rt); + planes[3].make(pfoc, lb, rb); + + // Compute pyramid in World basis. + // The vector transformation M of a plane p is computed as p*M-1. + // Here, ViewMatrix== CamMatrix-1. Hence the following formula. + uint i; + + for (i = 0; i < 4; i++) + { + planes[i] = planes[i]*MainSceneViewMatrix; + } +} + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/camera.h b/code/ryzom/client/src/camera.h new file mode 100644 index 000000000..037661c3a --- /dev/null +++ b/code/ryzom/client/src/camera.h @@ -0,0 +1,29 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CL_CAMERA_H +#define CL_CAMERA_H + +#include + +#include + +void updateCameraPerspective(); +void buildCameraClippingPyramid(std::vector &planes); + +#endif // CL_CAMERA_H + +/* end of file */ diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 64379b7c2..7338493c1 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -142,6 +142,7 @@ // pulled from main_loop.cpp #include "ping.h" #include "profiling.h" +#include "camera.h" #include "main_loop_debug.h" #include "main_loop_temp.h" #include "main_loop_utilities.h" @@ -351,44 +352,6 @@ void displaySceneProfiles(); // validate current dialogs (end them if the player is too far from its interlocutor) void validateDialogs(const CGameContextMenu &gcm); -void buildCameraClippingPyramid (vector &planes) -{ - if (StereoDisplay) StereoDisplay->getClippingFrustum(0, &MainCam); - - // Compute pyramid in view basis. - CVector pfoc(0,0,0); - const CFrustum &frustum = MainCam.getFrustum(); - InvMainSceneViewMatrix = MainCam.getMatrix(); - MainSceneViewMatrix = InvMainSceneViewMatrix; - MainSceneViewMatrix.invert(); - - CVector lb(frustum.Left, frustum.Near, frustum.Bottom ); - CVector lt(frustum.Left, frustum.Near, frustum.Top ); - CVector rb(frustum.Right, frustum.Near, frustum.Bottom ); - CVector rt(frustum.Right, frustum.Near, frustum.Top ); - - CVector lbFar(frustum.Left, ClientCfg.CharacterFarClip, frustum.Bottom); - CVector ltFar(frustum.Left, ClientCfg.CharacterFarClip, frustum.Top ); - CVector rtFar(frustum.Right, ClientCfg.CharacterFarClip, frustum.Top ); - - planes.resize (4); - // planes[0].make(lbFar, ltFar, rtFar); - planes[0].make(pfoc, lt, lb); - planes[1].make(pfoc, rt, lt); - planes[2].make(pfoc, rb, rt); - planes[3].make(pfoc, lb, rb); - - // Compute pyramid in World basis. - // The vector transformation M of a plane p is computed as p*M-1. - // Here, ViewMatrix== CamMatrix-1. Hence the following formula. - uint i; - - for (i = 0; i < 4; i++) - { - planes[i] = planes[i]*MainSceneViewMatrix; - } -} - void preRenderNewSky () { CSky &sky = ContinentMngr.cur()->CurrentSky; diff --git a/code/ryzom/client/src/main_loop_utilities.cpp b/code/ryzom/client/src/main_loop_utilities.cpp index 26be0ab0d..7afba0a9f 100644 --- a/code/ryzom/client/src/main_loop_utilities.cpp +++ b/code/ryzom/client/src/main_loop_utilities.cpp @@ -33,29 +33,11 @@ #include "entities.h" #include "input.h" #include "sound_manager.h" +#include "camera.h" using namespace NLMISC; using namespace NL3D; -//--------------------------------------------------- -// update the camera perspective setup -//--------------------------------------------------- -void updateCameraPerspective() -{ - float fov, aspectRatio; - computeCurrentFovAspectRatio(fov, aspectRatio); - - // change the perspective of the scene - if(!MainCam.empty()) - MainCam.setPerspective(fov, aspectRatio, CameraSetupZNear, ClientCfg.Vision); - // change the perspective of the root scene - if(SceneRoot) - { - UCamera cam= SceneRoot->getCam(); - cam.setPerspective(fov, aspectRatio, SceneRootCameraZNear, SceneRootCameraZFar); - } -} - //--------------------------------------------------- // Compare ClientCfg and LastClientCfg to know what we must update //--------------------------------------------------- diff --git a/code/ryzom/client/src/main_loop_utilities.h b/code/ryzom/client/src/main_loop_utilities.h index 48d6a3880..d8ea3dedf 100644 --- a/code/ryzom/client/src/main_loop_utilities.h +++ b/code/ryzom/client/src/main_loop_utilities.h @@ -24,9 +24,6 @@ // This is mainly for system configuration related functions // such as config file changes. -/// does not belong here -void updateCameraPerspective(); - /// Compare ClientCfg and LastClientCfg to know what we must update void updateFromClientCfg(); From b04d278a27618fb2badb4db98c7da0b69456c77e Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 28 Jun 2013 23:19:32 +0200 Subject: [PATCH 051/137] Create interface classes for stereo displays and head mounted displays, see #43 --- code/nel/include/nel/3d/stereo_display.h | 139 ++++++++++++++++++ code/nel/include/nel/3d/stereo_hmd.h | 69 +++++++++ code/nel/include/nel/3d/stereo_ovr.h | 29 +--- code/nel/src/3d/stereo_display.cpp | 98 ++++++++++++ code/nel/src/3d/stereo_hmd.cpp | 55 +++++++ code/nel/src/3d/stereo_ovr.cpp | 47 +++--- code/snowballs2/client/src/camera.cpp | 44 +++--- code/snowballs2/client/src/snowballs_client.h | 6 +- 8 files changed, 423 insertions(+), 64 deletions(-) create mode 100644 code/nel/include/nel/3d/stereo_display.h create mode 100644 code/nel/include/nel/3d/stereo_hmd.h create mode 100644 code/nel/src/3d/stereo_display.cpp create mode 100644 code/nel/src/3d/stereo_hmd.cpp diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h new file mode 100644 index 000000000..b2547bef9 --- /dev/null +++ b/code/nel/include/nel/3d/stereo_display.h @@ -0,0 +1,139 @@ +/** + * \file stereo_display.h + * \brief IStereoDisplay + * \date 2013-06-27 16:29GMT + * \author Jan Boon (Kaetemi) + * IStereoDisplay + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_STEREO_DISPLAY_H +#define NL3D_STEREO_DISPLAY_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes + +namespace NL3D { + +class UCamera; +class CViewport; +class CFrustum; +class IStereoDisplay; + +class IStereoDeviceFactory : public NLMISC::CRefCount +{ +public: + IStereoDeviceFactory() { } + virtual ~IStereoDeviceFactory() { } + virtual IStereoDisplay *createDevice() const = 0; +}; + +struct CStereoDeviceInfo +{ +public: + enum TStereoDeviceClass + { + StereoDisplay, + StereoHMD, + }; + + enum TStereoDeviceLibrary + { + NeL3D, + OVR, + LibVR, + OpenHMD, + }; + + NLMISC::CSmartPtr Factory; + + TStereoDeviceLibrary Library; + TStereoDeviceClass Class; + std::string Manufacturer; + std::string ProductName; + std::string Serial; // A unique device identifier +}; + +/** + * \brief IStereoDisplay + * \date 2013-06-27 16:29GMT + * \author Jan Boon (Kaetemi) + * IStereoDisplay + */ +class IStereoDisplay +{ +public: + IStereoDisplay(); + virtual ~IStereoDisplay(); + + /// Gets the required screen resolution for this device + virtual void getScreenResolution(uint &width, uint &height) = 0; + /// Set latest camera position etcetera + virtual void updateCamera(uint cid, const NL3D::UCamera *camera) = 0; + /// Get the frustum to use for clipping + virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const = 0; + + /// Is there a next pass + virtual bool nextPass() = 0; + /// Gets the current viewport + virtual const NL3D::CViewport &getCurrentViewport() const = 0; + /// Gets the current camera frustum + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const = 0; + /// Gets the current camera frustum + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const = 0; + /// Gets the current camera matrix + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const = 0; + + /// At the start of a new render target + virtual bool beginClear() = 0; + // virtual void *getRenderTarget() const; + virtual void endClear() = 0; + + /// The 3D scene + virtual bool beginScene() = 0; + virtual void endScene() = 0; + + /// Interface within the 3D scene + virtual bool beginInterface3D() = 0; + virtual void endInterface3D() = 0; + + /// 2D Interface + virtual bool beginInterface2D() = 0; + virtual void endInterface2D() = 0; + + static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library); + static void listDevices(std::vector &devicesOut); + static IStereoDisplay *createDevice(const CStereoDeviceInfo &deviceInfo); + static void releaseUnusedLibraries(); + static void releaseAllLibraries(); + +}; /* class IStereoDisplay */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_STEREO_DISPLAY_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/stereo_hmd.h b/code/nel/include/nel/3d/stereo_hmd.h new file mode 100644 index 000000000..bbb80368e --- /dev/null +++ b/code/nel/include/nel/3d/stereo_hmd.h @@ -0,0 +1,69 @@ +/** + * \file stereo_hmd.h + * \brief IStereoHMD + * \date 2013-06-27 16:30GMT + * \author Jan Boon (Kaetemi) + * IStereoHMD + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_STEREO_HMD_H +#define NL3D_STEREO_HMD_H +#include + +// STL includes + +// NeL includes + +// Project includes +#include + +namespace NL3D { + +/** + * \brief IStereoHMD + * \date 2013-06-27 16:30GMT + * \author Jan Boon (Kaetemi) + * IStereoHMD + */ +class IStereoHMD : public IStereoDisplay +{ +public: + IStereoHMD(); + virtual ~IStereoHMD(); + + /// Get the HMD orientation + virtual NLMISC::CQuat getOrientation() const = 0; + + /// Set the head model, eye position relative to orientation point + // virtual void setEyePosition(const NLMISC::CVector &v) = 0; + /// Get the head model, eye position relative to orientation point + // virtual const NLMISC::CVector &getEyePosition() const = 0; + /// Get GUI center (1 = width, 1 = height, 0 = center) + virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const = 0; + +}; /* class IStereoHMD */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_STEREO_HMD_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index ba8d6eac6..e3c8361f8 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -49,28 +49,16 @@ // NeL includes #include + +// Project includes +#include #include #include -// Project includes - namespace NL3D { -class UCamera; - -struct CStereoDeviceInfo -{ -public: - uint8 Class; - uint8 Identifier; - NLMISC::CSmartPtr Factory; - - std::string Library; - std::string Manufacturer; - std::string ProductName; -}; - class CStereoOVRDevicePtr; +class CStereoOVRDeviceHandle; #define NL_STEREO_MAX_USER_CAMERAS 8 @@ -80,10 +68,10 @@ class CStereoOVRDevicePtr; * \author Jan Boon (Kaetemi) * CStereoOVR */ -class CStereoOVR +class CStereoOVR : public IStereoHMD { public: - CStereoOVR(const CStereoDeviceInfo &deviceInfo); + CStereoOVR(const CStereoOVRDeviceHandle *handle); virtual ~CStereoOVR(); @@ -126,18 +114,17 @@ public: /// Get the HMD orientation virtual NLMISC::CQuat getOrientation() const; /// Get GUI center (1 = width, 1 = height, 0 = center) - virtual void getInterface2DShift(uint cid, float &x, float &y, float distance); + virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const; static void listDevices(std::vector &devicesOut); - static CStereoOVR *createDevice(const CStereoDeviceInfo &deviceInfo); static bool isLibraryInUse(); static void releaseLibrary(); /// Calculates internal camera information based on the reference camera void initCamera(uint cid, const NL3D::UCamera *camera); - + /// Checks if the device used by this class was actually created bool isDeviceCreated(); private: diff --git a/code/nel/src/3d/stereo_display.cpp b/code/nel/src/3d/stereo_display.cpp new file mode 100644 index 000000000..09502a256 --- /dev/null +++ b/code/nel/src/3d/stereo_display.cpp @@ -0,0 +1,98 @@ +/** + * \file stereo_display.cpp + * \brief IStereoDisplay + * \date 2013-06-27 16:29GMT + * \author Jan Boon (Kaetemi) + * IStereoDisplay + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes +#include + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +IStereoDisplay::IStereoDisplay() +{ + +} + +IStereoDisplay::~IStereoDisplay() +{ + +} + +const char *IStereoDisplay::getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library) +{ + static const char *nel3dName = "NeL 3D"; + static const char *ovrName = "Oculus SDK"; + static const char *libvrName = "LibVR"; + static const char *openhmdName = "OpenHMD"; + switch (library) + { + case CStereoDeviceInfo::NeL3D: + return nel3dName; + case CStereoDeviceInfo::OVR: + return ovrName; + case CStereoDeviceInfo::LibVR: + return libvrName; + case CStereoDeviceInfo::OpenHMD: + return openhmdName; + } + nlerror("Invalid device library specified"); + return ""; +} + +void IStereoDisplay::listDevices(std::vector &devicesOut) +{ + CStereoOVR::listDevices(devicesOut); +} + +IStereoDisplay *IStereoDisplay::createDevice(const CStereoDeviceInfo &deviceInfo) +{ + return deviceInfo.Factory->createDevice(); +} + +void IStereoDisplay::releaseUnusedLibraries() +{ + if (!CStereoOVR::isLibraryInUse()) + CStereoOVR::releaseLibrary(); +} + +void IStereoDisplay::releaseAllLibraries() +{ + CStereoOVR::releaseLibrary(); +} + +} /* namespace NL3D */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_hmd.cpp b/code/nel/src/3d/stereo_hmd.cpp new file mode 100644 index 000000000..d28017482 --- /dev/null +++ b/code/nel/src/3d/stereo_hmd.cpp @@ -0,0 +1,55 @@ +/** + * \file stereo_hmd.cpp + * \brief IStereoHMD + * \date 2013-06-27 16:30GMT + * \author Jan Boon (Kaetemi) + * IStereoHMD + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +IStereoHMD::IStereoHMD() +{ + +} + +IStereoHMD::~IStereoHMD() +{ + +} + +} /* namespace NL3D */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index f6c063de4..f4cb61e1a 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -45,6 +45,7 @@ #include // STL includes +#include // External includes #include @@ -127,16 +128,24 @@ public: CStereoOVRSystem s_StereoOVRSystem; -class CStereoOVRDeviceHandle : public NLMISC::CRefCount -{ -public: - OVR::DeviceEnumerator DeviceHandle; -}; - sint s_DeviceCounter = 0; } +class CStereoOVRDeviceHandle : public IStereoDeviceFactory +{ +public: + OVR::DeviceEnumerator DeviceHandle; + IStereoDisplay *createDevice() const + { + CStereoOVR *stereo = new CStereoOVR(this); + if (stereo->isDeviceCreated()) + return stereo; + delete stereo; + return NULL; + } +}; + class CStereoOVRDevicePtr { public: @@ -146,12 +155,11 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoDeviceInfo &deviceInfo) : m_Stage(0), m_OrientationCached(false) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_OrientationCached(false) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); - CStereoOVRDeviceHandle *handle = static_cast(deviceInfo.Factory.getPtr()); OVR::DeviceEnumerator dh = handle->DeviceHandle; m_DevicePtr->HMDDevice = dh.CreateDevice(); @@ -406,7 +414,7 @@ NLMISC::CQuat CStereoOVR::getOrientation() const } /// Get GUI shift -void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distance) +void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distance) const { #if 0 @@ -460,7 +468,7 @@ void CStereoOVR::listDevices(std::vector &devicesOut) { s_StereoOVRSystem.Init(); OVR::DeviceEnumerator devices = s_DeviceManager->EnumerateDevices(); - uint8 id = 1; + uint id = 1; do { CStereoDeviceInfo deviceInfoOut; @@ -469,13 +477,15 @@ void CStereoOVR::listDevices(std::vector &devicesOut) { devices.GetDeviceInfo(&deviceInfo); CStereoOVRDeviceHandle *handle = new CStereoOVRDeviceHandle(); - deviceInfoOut.Factory = static_cast(handle); + deviceInfoOut.Factory = static_cast(handle); handle->DeviceHandle = devices; - deviceInfoOut.Class = 1; // OVR::HMDDevice - deviceInfoOut.Library = "Oculus SDK"; - deviceInfoOut.Identifier = id; + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; // 1; // OVR::HMDDevice + deviceInfoOut.Library = CStereoDeviceInfo::OVR; // "Oculus SDK"; deviceInfoOut.Manufacturer = deviceInfo.Manufacturer; deviceInfoOut.ProductName = deviceInfo.ProductName; + stringstream ser; + ser << id; + deviceInfoOut.Serial = ser.str(); // can't get the real serial from the sdk... devicesOut.push_back(deviceInfoOut); ++id; } @@ -483,15 +493,6 @@ void CStereoOVR::listDevices(std::vector &devicesOut) } while (devices.Next()); } -CStereoOVR *CStereoOVR::createDevice(const CStereoDeviceInfo &deviceInfo) -{ - CStereoOVR *stereo = new CStereoOVR(deviceInfo); - if (stereo->isDeviceCreated()) - return stereo; - delete stereo; - return NULL; -} - bool CStereoOVR::isLibraryInUse() { nlassert(s_DeviceCounter >= 0); diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index ef65a7a9f..f4f5ea2b4 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -34,7 +34,7 @@ #include #include -#include +#include #include "snowballs_client.h" #include "entities.h" @@ -70,7 +70,8 @@ static UInstance Sky = NULL; static UCloudScape *Clouds = NULL; -CStereoOVR *StereoHMD = NULL; +IStereoDisplay *StereoDisplay = NULL; +IStereoHMD *StereoHMD = NULL; // // Functions @@ -81,12 +82,12 @@ void initCamera() if (ConfigFile->getVar("HMDEnable").asBool()) { std::vector devices; - CStereoOVR::listDevices(devices); + IStereoDisplay::listDevices(devices); for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) { std::stringstream name; - name << std::string("[") << (uint32)it->Identifier << "] [" << it->Library << " - " << it->Manufacturer << " - " << it->ProductName << "]"; - nlinfo("Stereo Device: %s", name.str().c_str()); + name << std::string("[") << it->Serial << "] [" << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName << "]"; + nlinfo("Stereo Display: %s", name.str().c_str()); } CStereoDeviceInfo *deviceInfo = NULL; std::string hmdDeviceCfg = ConfigFile->getVar("HMDDevice").asString(); @@ -97,22 +98,28 @@ void initCamera() } else { - uint8 hmdDeviceId = (ConfigFile->getVar("HMDDeviceId").asInt() & 0xFF); + std::string hmdDeviceId = ConfigFile->getVar("HMDDeviceId").asString(); for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) { std::stringstream name; - name << it->Library << " - " << it->Manufacturer << " - " << it->ProductName; + name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName; if (name.str() == hmdDeviceCfg) deviceInfo = &(*it); - if (hmdDeviceId == it->Identifier) + if (hmdDeviceId == it->Serial) break; } } if (deviceInfo) { - nlinfo("Create HMD device!"); - StereoHMD = CStereoOVR::createDevice(*deviceInfo); + nlinfo("Create VR stereo display device"); + StereoDisplay = IStereoDisplay::createDevice(*deviceInfo); + if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD) + { + nlinfo("Stereo display device is a HMD"); + StereoHMD = static_cast(StereoDisplay); + } } + IStereoDisplay::releaseUnusedLibraries(); } // Set up directly the camera @@ -129,11 +136,6 @@ void initCamera() CamCollisionEntity = VisualCollisionManager->createEntity(); CamCollisionEntity->setCeilMode(true); - if (StereoHMD) - { - StereoHMD->initCamera(0, &Camera); - } - // Create the snowing particle system Snow = Scene->createInstance("snow.ps"); // And setup it @@ -164,9 +166,15 @@ void releaseCamera() Scene->deleteInstance(Snow); VisualCollisionManager->deleteEntity(CamCollisionEntity); - delete StereoHMD; - StereoHMD = NULL; - CStereoOVR::releaseLibrary(); + if (StereoHMD) + { + delete StereoHMD; + StereoHMD = NULL; + StereoDisplay = NULL; + } + delete StereoDisplay; + StereoDisplay = NULL; + IStereoDisplay::releaseAllLibraries(); } void updateCamera() diff --git a/code/snowballs2/client/src/snowballs_client.h b/code/snowballs2/client/src/snowballs_client.h index bc955d317..d21f925f7 100644 --- a/code/snowballs2/client/src/snowballs_client.h +++ b/code/snowballs2/client/src/snowballs_client.h @@ -42,7 +42,8 @@ namespace NL3D { class UScene; class UTextContext; class ULandscape; - class CStereoOVR; + class IStereoDisplay; + class IStereoHMD; } namespace SBCLIENT { @@ -59,7 +60,8 @@ public: }; extern NL3D::UDriver *Driver; -extern NL3D::CStereoOVR *StereoHMD; +extern NL3D::IStereoDisplay *StereoDisplay; +extern NL3D::IStereoHMD *StereoHMD; extern NL3D::UScene *Scene; extern NL3D::UTextContext *TextContext; extern NLMISC::CConfigFile *ConfigFile; From ebba0c1917a1b8021e2c474d5c96780a9e477b9e Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 1 Jul 2013 18:45:43 +0200 Subject: [PATCH 052/137] Allow linking debug and release with same mysql lib if no specific debug lib. --- code/CMakeModules/FindMySQL.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/CMakeModules/FindMySQL.cmake b/code/CMakeModules/FindMySQL.cmake index 1da6157fa..eb2102c8d 100644 --- a/code/CMakeModules/FindMySQL.cmake +++ b/code/CMakeModules/FindMySQL.cmake @@ -58,6 +58,8 @@ ELSE(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) SET(MYSQL_LIBRARIES optimized ${MYSQL_LIBRARY_RELEASE}) IF(MYSQL_LIBRARY_DEBUG) SET(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} debug ${MYSQL_LIBRARY_DEBUG}) + ELSE(MYSQL_LIBRARY_DEBUG) + SET(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} debug ${MYSQL_LIBRARY_RELEASE}) ENDIF(MYSQL_LIBRARY_DEBUG) FIND_PACKAGE(OpenSSL) IF(OPENSSL_FOUND) From 9960b9dfdb15e1b50082d0000df3150997328457 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 1 Jul 2013 20:15:55 +0200 Subject: [PATCH 053/137] Cleanup --- code/nel/src/3d/CMakeLists.txt | 7 +++++++ code/nel/src/3d/stereo_ovr.cpp | 13 +++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index 6f632e261..ec07b28b8 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -686,6 +686,13 @@ SOURCE_GROUP(Shadows FILES ../../include/nel/3d/shadow_map_manager.h shadow_poly_receiver.cpp ../../include/nel/3d/shadow_poly_receiver.h) +SOURCE_GROUP(Stereo FILES + stereo_display.cpp + ../../include/nel/3d/stereo_display.h + stereo_hmd.cpp + ../../include/nel/3d/stereo_hmd.h + stereo_ovr.cpp + ../../include/nel/3d/stereo_ovr.h) NL_TARGET_LIB(nel3d ${HEADERS} ${SRC}) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index f4cb61e1a..de27a032e 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -218,15 +218,16 @@ void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.VScreenSize / 2.0f) / m_DevicePtr->HMDInfo.EyeToScreenDistance); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); m_RightFrustum[cid] = m_LeftFrustum[cid]; + float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; - float projectionCenterOffset = 4.0f * eyeProjectionShift / m_DevicePtr->HMDInfo.HScreenSize; + float projectionCenterOffset = (eyeProjectionShift / (m_DevicePtr->HMDInfo.HScreenSize * 0.5f)) * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); // used logic for this one, but it ends up being the same as the one i made up nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset); - projectionCenterOffset *= (m_LeftFrustum[cid].Left - m_LeftFrustum[cid].Right) * 0.5f; // made this up ... - m_LeftFrustum[cid].Left += projectionCenterOffset; - m_LeftFrustum[cid].Right += projectionCenterOffset; - m_RightFrustum[cid].Left -= projectionCenterOffset; - m_RightFrustum[cid].Right -= projectionCenterOffset; + + m_LeftFrustum[cid].Left -= projectionCenterOffset; + m_LeftFrustum[cid].Right -= projectionCenterOffset; + m_RightFrustum[cid].Left += projectionCenterOffset; + m_RightFrustum[cid].Right += projectionCenterOffset; // TODO: Clipping frustum should also take into account the IPD m_ClippingFrustum[cid] = m_LeftFrustum[cid]; From 2b653d29041291f661cf9347f3d7dc53dbc0b115 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 1 Jul 2013 20:38:18 +0200 Subject: [PATCH 054/137] Allow turning off bloom in snowballs --- .../bin/snowballs_client_default.cfg | 1 + .../client/src/snowballs_client.cpp | 22 ++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/code/snowballs2/bin/snowballs_client_default.cfg b/code/snowballs2/bin/snowballs_client_default.cfg index 9d1429f83..49ec9e4d5 100755 --- a/code/snowballs2/bin/snowballs_client_default.cfg +++ b/code/snowballs2/bin/snowballs_client_default.cfg @@ -271,6 +271,7 @@ GlobalRetrieverName = "snowballs.gr"; SquareBloom = 1; DensityBloom = 128; +EnableBloom = 1; ////////////////////////////////////////////////////////////////////////////// diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 292465266..5cb7aa8df 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -152,6 +152,8 @@ LoadedOnline = false, LoadedOffline = false; // state static IStereoRender *_StereoRender = NULL; #endif /* #if SBCLIENT_DEV_STEREO */ +static bool s_EnableBloom = false; + // // Prototypes // @@ -182,6 +184,7 @@ void releaseOffline(); void cbGraphicsDriver(CConfigFile::CVar &var); void cbSquareBloom(CConfigFile::CVar &var); void cbDensityBloom(CConfigFile::CVar &var); +void cbEnableBloom(CConfigFile::CVar &var); // // Functions @@ -368,6 +371,7 @@ void initIngame() CBloomEffect::instance().init(ConfigFile->getVar("OpenGL").asInt() == 1); CConfiguration::setAndCallback("SquareBloom", cbSquareBloom); CConfiguration::setAndCallback("DensityBloom", cbDensityBloom); + CConfiguration::setAndCallback("EnableBloom", cbEnableBloom); // Init the landscape using the previously created UScene displayLoadingState("Initialize Landscape"); initLandscape(); @@ -748,9 +752,12 @@ void loopIngame() if (!StereoHMD || StereoHMD->beginClear()) { - nlassert(bloomStage == 0); - CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) - bloomStage = 1; + if (s_EnableBloom) + { + nlassert(bloomStage == 0); + CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) + bloomStage = 1; + } // 01. Render Driver (background color) Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering @@ -774,7 +781,7 @@ void loopIngame() if (!StereoHMD || StereoHMD->beginInterface3D()) { - if (bloomStage == 1) + if (s_EnableBloom && bloomStage == 1) { // End the actual bloom effect visible in the scene. if (StereoHMD) Driver->setViewport(NL3D::CViewport()); @@ -791,7 +798,7 @@ void loopIngame() if (!StereoHMD || StereoHMD->beginInterface2D()) { - if (bloomStage == 2) + if (s_EnableBloom && bloomStage == 2) { // End bloom effect system after drawing the 3d interface (z buffer related). if (StereoHMD) Driver->setViewport(NL3D::CViewport()); @@ -944,6 +951,11 @@ void cbDensityBloom(CConfigFile::CVar &var) CBloomEffect::instance().setDensityBloom((uint8)(var.asInt() & 0xFF)); } +void cbEnableBloom(CConfigFile::CVar &var) +{ + s_EnableBloom = var.asBool(); +} + // // Loading state procedure // From f25a9da7184427732a4c61f2fab6f734878a2265 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 1 Jul 2013 21:23:47 +0200 Subject: [PATCH 055/137] Add interface for stereo display render targets, ref #43 --- code/nel/include/nel/3d/stereo_display.h | 26 ++++---- code/nel/include/nel/3d/stereo_ovr.h | 24 +++---- code/nel/src/3d/stereo_ovr.cpp | 62 ++++++++++++------- .../client/src/snowballs_client.cpp | 18 ++---- 4 files changed, 69 insertions(+), 61 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index b2547bef9..ad75ad934 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -42,6 +42,8 @@ class UCamera; class CViewport; class CFrustum; class IStereoDisplay; +class UTexture; +class UDriver; class IStereoDeviceFactory : public NLMISC::CRefCount { @@ -88,6 +90,9 @@ class IStereoDisplay public: IStereoDisplay(); virtual ~IStereoDisplay(); + + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver &driver) = 0; /// Gets the required screen resolution for this device virtual void getScreenResolution(uint &width, uint &height) = 0; @@ -108,21 +113,18 @@ public: virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const = 0; /// At the start of a new render target - virtual bool beginClear() = 0; - // virtual void *getRenderTarget() const; - virtual void endClear() = 0; - + virtual bool wantClear() = 0; /// The 3D scene - virtual bool beginScene() = 0; - virtual void endScene() = 0; - + virtual bool wantScene() = 0; /// Interface within the 3D scene - virtual bool beginInterface3D() = 0; - virtual void endInterface3D() = 0; - + virtual bool wantInterface3D() = 0; /// 2D Interface - virtual bool beginInterface2D() = 0; - virtual void endInterface2D() = 0; + virtual bool wantInterface2D() = 0; + + /// Returns non-NULL if a new render target was set + virtual UTexture *beginRenderTarget(bool set) = 0; + /// Returns true if a render target was fully drawn + virtual bool endRenderTarget(bool render) = 0; static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library); static void listDevices(std::vector &devicesOut); diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index e3c8361f8..3fff84ffb 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -74,6 +74,8 @@ public: CStereoOVR(const CStereoOVRDeviceHandle *handle); virtual ~CStereoOVR(); + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver &driver); /// Gets the required screen resolution for this device virtual void getScreenResolution(uint &width, uint &height); @@ -94,21 +96,18 @@ public: virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; /// At the start of a new render target - virtual bool beginClear(); - // virtual void *getRenderTarget() const; - virtual void endClear(); - + virtual bool wantClear(); /// The 3D scene - virtual bool beginScene(); - virtual void endScene(); - + virtual bool wantScene(); /// Interface within the 3D scene - virtual bool beginInterface3D(); - virtual void endInterface3D(); - + virtual bool wantInterface3D(); /// 2D Interface - virtual bool beginInterface2D(); - virtual void endInterface2D(); + virtual bool wantInterface2D(); + + /// Returns non-NULL if a new render target was set, always NULL if not using render targets + virtual UTexture *beginRenderTarget(bool set); + /// Returns true if a render target was fully drawn, always false if not using render targets + virtual bool endRenderTarget(bool render); /// Get the HMD orientation @@ -130,6 +129,7 @@ public: private: CStereoOVRDevicePtr *m_DevicePtr; int m_Stage; + int m_SubStage; CViewport m_LeftViewport; CViewport m_RightViewport; CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index de27a032e..a4b92b39e 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -155,7 +155,7 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_OrientationCached(false) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -206,6 +206,11 @@ CStereoOVR::~CStereoOVR() --s_DeviceCounter; } +void CStereoOVR::setDriver(NL3D::UDriver &driver) +{ + // ... +} + void CStereoOVR::getScreenResolution(uint &width, uint &height) { width = m_DevicePtr->HMDInfo.HResolution; @@ -220,7 +225,7 @@ void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) m_RightFrustum[cid] = m_LeftFrustum[cid]; float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; - float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; + float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; // docs say LensSeparationDistance, why not InterpupillaryDistance? related to how the lenses work? float projectionCenterOffset = (eyeProjectionShift / (m_DevicePtr->HMDInfo.HScreenSize * 0.5f)) * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); // used logic for this one, but it ends up being the same as the one i made up nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset); @@ -255,6 +260,7 @@ bool CStereoOVR::nextPass() { case 0: ++m_Stage; + m_SubStage = 0; // stage 1: // (initBloom) // clear buffer @@ -262,39 +268,46 @@ bool CStereoOVR::nextPass() return true; case 1: ++m_Stage; + m_SubStage = 0; // stage 2: // draw scene right return true; case 2: ++m_Stage; + m_SubStage = 0; // stage 3: // (endBloom) // draw interface 3d left return true; case 3: ++m_Stage; + m_SubStage = 0; // stage 4: // draw interface 3d right return true; case 4: ++m_Stage; + m_SubStage = 0; // stage 5: // (endInterfacesDisplayBloom) // draw interface 2d left return true; case 5: ++m_Stage; + m_SubStage = 0; // stage 6: // draw interface 2d right return true; case 6: m_Stage = 0; + m_SubStage = 0; // present m_OrientationCached = false; return false; } - nlassert(false); + nlerror("Invalid stage"); m_Stage = 0; + m_SubStage = 0; m_OrientationCached = false; return false; } @@ -326,67 +339,68 @@ void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const camera->setMatrix(m_CameraMatrix[cid] * translate); } -bool CStereoOVR::beginClear() +bool CStereoOVR::wantClear() { switch (m_Stage) { case 1: + m_SubStage = 1; return true; } return false; } - -void CStereoOVR::endClear() -{ - -} -bool CStereoOVR::beginScene() +bool CStereoOVR::wantScene() { switch (m_Stage) { case 1: case 2: + m_SubStage = 2; return true; } return false; } -void CStereoOVR::endScene() -{ - -} - -bool CStereoOVR::beginInterface3D() +bool CStereoOVR::wantInterface3D() { switch (m_Stage) { case 3: case 4: + m_SubStage = 3; return true; } return false; } -void CStereoOVR::endInterface3D() -{ - -} - -bool CStereoOVR::beginInterface2D() +bool CStereoOVR::wantInterface2D() { switch (m_Stage) { case 5: case 6: + m_SubStage = 4; return true; } return false; } -void CStereoOVR::endInterface2D() -{ +/// Returns non-NULL if a new render target was set +UTexture *CStereoOVR::beginRenderTarget(bool set) +{ + // render target always set before driver clear + nlassert(m_SubStage == 1); + return NULL; +} + +/// Returns true if a render target was fully drawn +bool CStereoOVR::endRenderTarget( bool render) +{ + // after rendering of course + nlassert(m_SubStage > 1); + return false; } NLMISC::CQuat CStereoOVR::getOrientation() const diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 5cb7aa8df..e6754388a 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -750,7 +750,7 @@ void loopIngame() StereoHMD->getCurrentMatrix(0, &Camera); } - if (!StereoHMD || StereoHMD->beginClear()) + if (!StereoHMD || StereoHMD->wantClear()) { if (s_EnableBloom) { @@ -761,11 +761,9 @@ void loopIngame() // 01. Render Driver (background color) Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering - - if (StereoHMD) StereoHMD->endClear(); } - if (!StereoHMD || StereoHMD->beginScene()) + if (!StereoHMD || StereoHMD->wantScene()) { // 02. Render Sky (sky scene) updateSky(); // Render the sky scene before the main scene @@ -775,11 +773,9 @@ void loopIngame() // 05. Render Effects (flare) if (!StereoHMD) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...) - - if (StereoHMD) StereoHMD->endScene(); } - if (!StereoHMD || StereoHMD->beginInterface3D()) + if (!StereoHMD || StereoHMD->wantInterface3D()) { if (s_EnableBloom && bloomStage == 1) { @@ -791,12 +787,10 @@ void loopIngame() } // 06. Render Interface 3D (player names) - // ... - - if (StereoHMD) StereoHMD->endInterface3D(); + // ... } - if (!StereoHMD || StereoHMD->beginInterface2D()) + if (!StereoHMD || StereoHMD->wantInterface2D()) { if (s_EnableBloom && bloomStage == 2) { @@ -820,8 +814,6 @@ void loopIngame() // 08. Render Debug (stuff for dev) // ... - - if (StereoHMD) StereoHMD->endInterface2D(); } } From ffc91631e7fccb464f8f9fab535fcd360674dc92 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 1 Jul 2013 23:23:54 +0200 Subject: [PATCH 056/137] Create stereo render target, see #43 --- code/nel/include/nel/3d/stereo_display.h | 4 +- code/nel/include/nel/3d/stereo_ovr.h | 13 +++- code/nel/src/3d/CMakeLists.txt | 1 + code/nel/src/3d/stereo_ovr.cpp | 90 ++++++++++++++++++++++-- code/nel/src/3d/stereo_ovr_fp.cpp | 82 +++++++++++++++++++++ 5 files changed, 180 insertions(+), 10 deletions(-) create mode 100644 code/nel/src/3d/stereo_ovr_fp.cpp diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index ad75ad934..2f6592b60 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -92,7 +92,7 @@ public: virtual ~IStereoDisplay(); /// Sets driver and generates necessary render targets - virtual void setDriver(NL3D::UDriver &driver) = 0; + virtual void setDriver(NL3D::UDriver *driver) = 0; /// Gets the required screen resolution for this device virtual void getScreenResolution(uint &width, uint &height) = 0; @@ -124,7 +124,7 @@ public: /// Returns non-NULL if a new render target was set virtual UTexture *beginRenderTarget(bool set) = 0; /// Returns true if a render target was fully drawn - virtual bool endRenderTarget(bool render) = 0; + virtual bool endRenderTarget(bool unset) = 0; static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library); static void listDevices(std::vector &devicesOut); diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 3fff84ffb..f25ef10e0 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -49,14 +49,18 @@ // NeL includes #include +#include // Project includes #include #include #include +#include namespace NL3D { +class ITexture; +class CTextureUser; class CStereoOVRDevicePtr; class CStereoOVRDeviceHandle; @@ -75,7 +79,7 @@ public: virtual ~CStereoOVR(); /// Sets driver and generates necessary render targets - virtual void setDriver(NL3D::UDriver &driver); + virtual void setDriver(NL3D::UDriver *driver); /// Gets the required screen resolution for this device virtual void getScreenResolution(uint &width, uint &height); @@ -107,7 +111,7 @@ public: /// Returns non-NULL if a new render target was set, always NULL if not using render targets virtual UTexture *beginRenderTarget(bool set); /// Returns true if a render target was fully drawn, always false if not using render targets - virtual bool endRenderTarget(bool render); + virtual bool endRenderTarget(bool unset); /// Get the HMD orientation @@ -138,6 +142,11 @@ private: CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; mutable bool m_OrientationCached; mutable NLMISC::CQuat m_OrientationCache; + UDriver *m_Driver; + NLMISC::CSmartPtr m_BarrelTex; + NL3D::CTextureUser *m_BarrelTexU; + NL3D::UMaterial m_BarrelMat; + NLMISC::CQuadUV m_BarrelQuad; }; /* class CStereoOVR */ diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index ec07b28b8..da0288561 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -692,6 +692,7 @@ SOURCE_GROUP(Stereo FILES stereo_hmd.cpp ../../include/nel/3d/stereo_hmd.h stereo_ovr.cpp + stereo_ovr_fp.cpp ../../include/nel/3d/stereo_ovr.h) NL_TARGET_LIB(nel3d ${HEADERS} ${SRC}) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index a4b92b39e..8eb8e1f9b 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -53,6 +53,12 @@ // NeL includes // #include #include +#include +#include +#include +#include +#include +#include // Project includes @@ -61,6 +67,8 @@ using namespace std; namespace NL3D { +extern const char *g_StereoOVR_arbfp1; + namespace { class CStereoOVRLog : public OVR::Log @@ -155,7 +163,7 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_BarrelTexU(NULL) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -194,6 +202,17 @@ CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_Sub CStereoOVR::~CStereoOVR() { + if (!m_BarrelMat.empty()) + { + m_BarrelMat.getObjectPtr()->setTexture(0, NULL); + m_Driver->deleteMaterial(m_BarrelMat); + } + delete m_BarrelTexU; + m_BarrelTexU = NULL; + m_BarrelTex = NULL; // CSmartPtr + + m_Driver = NULL; + if (m_DevicePtr->SensorDevice) m_DevicePtr->SensorDevice->Release(); m_DevicePtr->SensorDevice.Clear(); @@ -206,9 +225,51 @@ CStereoOVR::~CStereoOVR() --s_DeviceCounter; } -void CStereoOVR::setDriver(NL3D::UDriver &driver) +void CStereoOVR::setDriver(NL3D::UDriver *driver) { - // ... + m_Driver = driver; + // Do not allow weird stuff. + uint32 width, height; + driver->getWindowSize(width, height); + nlassert(width == m_DevicePtr->HMDInfo.HResolution); + nlassert(height == m_DevicePtr->HMDInfo.VResolution); + + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + + m_BarrelTex = new CTextureBloom(); // lol bloom + m_BarrelTex->setReleasable(false); + m_BarrelTex->resize(width, height); + m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_BarrelTex->setWrapS(ITexture::Clamp); + m_BarrelTex->setWrapT(ITexture::Clamp); + m_BarrelTex->setRenderTarget(true); + drvInternal->setupTexture(*m_BarrelTex); + m_BarrelTexU = new CTextureUser(m_BarrelTex); + + m_BarrelMat = m_Driver->createMaterial(); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + m_BarrelMat.initUnlit(); + m_BarrelMat.setColor(CRGBA::White); + m_BarrelMat.setBlend (false); + m_BarrelMat.setAlphaTest (false); + barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero); + barrelMat->setZWrite(false); + barrelMat->setZFunc(CMaterial::always); + barrelMat->setDoubleSided(true); + barrelMat->setTexture(0, m_BarrelTex); + + m_BarrelQuad.V0 = CVector(0.f, 0.f, 0.5f); + m_BarrelQuad.V1 = CVector(1.f, 0.f, 0.5f); + m_BarrelQuad.V2 = CVector(1.f, 1.f, 0.5f); + m_BarrelQuad.V3 = CVector(0.f, 1.f, 0.5f); + + float newU = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)width : 1.f; + float newV = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)height : 1.f; + + m_BarrelQuad.Uv0 = CUV(0.f, 0.f); + m_BarrelQuad.Uv1 = CUV(newU, 0.f); + m_BarrelQuad.Uv2 = CUV(newU, newV); + m_BarrelQuad.Uv3 = CUV(0.f, newV); } void CStereoOVR::getScreenResolution(uint &width, uint &height) @@ -391,15 +452,32 @@ bool CStereoOVR::wantInterface2D() UTexture *CStereoOVR::beginRenderTarget(bool set) { // render target always set before driver clear - nlassert(m_SubStage == 1); + // nlassert(m_SubStage <= 1); + if (m_Stage == 1) + { + if (set) + { + (static_cast(m_Driver))->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0); + } + return m_BarrelTexU; + } return NULL; } /// Returns true if a render target was fully drawn -bool CStereoOVR::endRenderTarget( bool render) +bool CStereoOVR::endRenderTarget(bool unset) { // after rendering of course - nlassert(m_SubStage > 1); + // nlassert(m_SubStage > 1); + if (m_Stage == 4) + { + if (unset) + { + CTextureUser cu; + (static_cast(m_Driver))->setRenderTarget(cu); + } + return true; + } return false; } diff --git a/code/nel/src/3d/stereo_ovr_fp.cpp b/code/nel/src/3d/stereo_ovr_fp.cpp new file mode 100644 index 000000000..eaa80f14c --- /dev/null +++ b/code/nel/src/3d/stereo_ovr_fp.cpp @@ -0,0 +1,82 @@ +/************************************************************************************ + +Filename : stereo_ovf_fp.cpp +Content : Barrel fragment program compiled to a blob of assembly +Created : July 01, 2013 + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +namespace NL3D { +const char *g_StereoOVR_arbfp1 = + "!!ARBfp1.0\n" + //# cgc version 3.1.0013, build date Apr 18 2012 + //# command line args: -profile arbfp1 + //# source file: pp_oculus_vr.cg + //#vendor NVIDIA Corporation + //#version 3.1.0.13 + //#profile arbfp1 + //#program pp_oculus_vr + //#semantic pp_oculus_vr.cLensCenter + //#semantic pp_oculus_vr.cScreenCenter + //#semantic pp_oculus_vr.cScale + //#semantic pp_oculus_vr.cScaleIn + //#semantic pp_oculus_vr.cHmdWarpParam + //#semantic pp_oculus_vr.cTex0 : TEX0 + //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //#var float2 cLensCenter : : c[0] : 1 : 1 + //#var float2 cScreenCenter : : c[1] : 2 : 1 + //#var float2 cScale : : c[2] : 3 : 1 + //#var float2 cScaleIn : : c[3] : 4 : 1 + //#var float4 cHmdWarpParam : : c[4] : 5 : 1 + //#var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1 + //#var float4 oCol : $vout.COLOR : COL : 7 : 1 + //#const c[5] = 0.25 0.5 0 1 + "PARAM c[6] = { program.local[0..4],\n" + " { 0.25, 0.5, 0, 1 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "ADD R0.xy, fragment.texcoord[0], -c[0];\n" + "MUL R0.xy, R0, c[3];\n" + "MUL R0.z, R0.y, R0.y;\n" + "MAD R0.z, R0.x, R0.x, R0;\n" + "MUL R0.w, R0.z, c[4];\n" + "MUL R0.w, R0, R0.z;\n" + "MAD R1.y, R0.z, c[4], c[4].x;\n" + "MUL R1.x, R0.z, c[4].z;\n" + "MAD R1.x, R0.z, R1, R1.y;\n" + "MAD R0.z, R0.w, R0, R1.x;\n" + "MUL R0.xy, R0, R0.z;\n" + "MOV R0.zw, c[5].xyxy;\n" + "ADD R1.xy, R0.zwzw, c[1];\n" + "MUL R0.xy, R0, c[2];\n" + "ADD R0.xy, R0, c[0];\n" + "MIN R1.xy, R1, R0;\n" + "ADD R0.zw, -R0, c[1].xyxy;\n" + "MAX R0.zw, R0, R1.xyxy;\n" + "ADD R0.zw, R0, -R0.xyxy;\n" + "ABS R0.zw, R0;\n" + "CMP R0.zw, -R0, c[5].z, c[5].w;\n" + "MUL R0.z, R0, R0.w;\n" + "ABS R0.z, R0;\n" + "CMP R0.z, -R0, c[5], c[5].w;\n" + "ABS R1.x, R0.z;\n" + "TEX R0, R0, texture[0], 2D;\n" + "CMP R1.x, -R1, c[5].z, c[5].w;\n" + "CMP result.color, -R1.x, R0, c[5].z;\n" + "END\n"; + //# 28 instructions, 2 R-regs +} \ No newline at end of file From 3b630492aaea8415f77bbb8b4abd03ec23ca10de Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 2 Jul 2013 00:53:45 +0200 Subject: [PATCH 057/137] Fix a render target issue, see #43 --- code/nel/include/nel/3d/driver.h | 2 ++ code/nel/src/3d/driver/direct3d/driver_direct3d.h | 1 + .../3d/driver/direct3d/driver_direct3d_texture.cpp | 5 +++++ code/nel/src/3d/driver/opengl/driver_opengl.cpp | 2 -- code/nel/src/3d/driver/opengl/driver_opengl.h | 4 +++- .../src/3d/driver/opengl/driver_opengl_texture.cpp | 11 ++++++++--- code/nel/src/3d/shadow_map_manager.cpp | 5 +++-- 7 files changed, 22 insertions(+), 8 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 14595e05c..655a9e62b 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -859,6 +859,8 @@ public: uint32 cubeFace = 0 ) = 0 ; + virtual ITexture *getRenderTarget() const = 0; + /** Trick method : copy the current texture target into another texture without updating the current texture. * * This method copies the current texture into another texture. diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 779a62a5c..085bb7512 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -855,6 +855,7 @@ public: // todo hulud d3d buffers virtual void getZBufferPart (std::vector &zbuffer, NLMISC::CRect &rect); virtual bool setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel, uint32 cubeFace); + virtual ITexture *getRenderTarget() const; virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel); virtual bool getRenderTargetSize (uint32 &width, uint32 &height); diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp index 7922b30ea..87f41678b 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp @@ -1187,6 +1187,11 @@ bool CDriverD3D::setRenderTarget (ITexture *tex, uint32 /* x */, uint32 /* y */, return true; } +ITexture *CDriverD3D::getRenderTarget() const +{ + return _RenderTarget.Texture; +} + // *************************************************************************** bool CDriverD3D::copyTargetToTexture (ITexture * /* tex */, uint32 /* offsetx */, uint32 /* offsety */, uint32 /* x */, uint32 /* y */, uint32 /* width */, diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 42d8b4834..32244edbe 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -263,8 +263,6 @@ CDriverGL::CDriverGL() _CurrentFogColor[2]= 0; _CurrentFogColor[3]= 0; - _RenderTargetFBO = false; - _LightSetupDirty= false; _ModelViewMatrixDirty= false; _RenderSetupDirty= false; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index f88936a8a..3f0675276 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -564,6 +564,8 @@ public: virtual bool setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel, uint32 cubeFace); + virtual ITexture *getRenderTarget() const; + virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel); @@ -889,7 +891,7 @@ private: // viewport before call to setRenderTarget, if BFO extension is supported CViewport _OldViewport; - bool _RenderTargetFBO; + CSmartPtr _RenderTargetFBO; // Num lights return by GL_MAX_LIGHTS diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp index 77954a8e3..7ded32b27 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp @@ -2314,7 +2314,7 @@ bool CDriverGL::setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width newVP.init(0, 0, ((float)width/(float)w), ((float)height/(float)h)); setupViewport(newVP); - _RenderTargetFBO = true; + _RenderTargetFBO = tex; return activeFrameBufferObject(tex); } @@ -2334,7 +2334,7 @@ bool CDriverGL::setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width setupViewport(_OldViewport); _OldViewport = _CurrViewport; - _RenderTargetFBO = false; + _RenderTargetFBO = NULL; return false; } @@ -2347,12 +2347,17 @@ bool CDriverGL::setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width // Update the scissor setupScissor (_CurrScissor); - _RenderTargetFBO = false; + _RenderTargetFBO = NULL; _OldViewport = _CurrViewport; return true; } +ITexture *CDriverGL::getRenderTarget() const +{ + return _RenderTargetFBO ? _RenderTargetFBO : _TextureTarget; +} + // *************************************************************************** bool CDriverGL::copyTargetToTexture (ITexture *tex, diff --git a/code/nel/src/3d/shadow_map_manager.cpp b/code/nel/src/3d/shadow_map_manager.cpp index 79f4ade20..383a28184 100644 --- a/code/nel/src/3d/shadow_map_manager.cpp +++ b/code/nel/src/3d/shadow_map_manager.cpp @@ -244,11 +244,12 @@ void CShadowMapManager::addShadowReceiver(CTransform *model) void CShadowMapManager::renderGenerate(CScene *scene) { H_AUTO( NL3D_ShadowManager_Generate ); - + // Each frame, do a small garbage collector for unused free textures. garbageShadowTextures(scene); IDriver *driverForShadowGeneration= scene->getRenderTrav().getAuxDriver(); + CSmartPtr previousRenderTarget = driverForShadowGeneration->getRenderTarget(); // Init // ******** @@ -488,7 +489,7 @@ void CShadowMapManager::renderGenerate(CScene *scene) } // Set default render target - driverForShadowGeneration->setRenderTarget (NULL); + driverForShadowGeneration->setRenderTarget (previousRenderTarget); // Allow Writing on all. driverForShadowGeneration->setColorMask(true, true, true, true); From 3a12aa5894fa51d7382063e7a4b1f4ac728f5ad2 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 2 Jul 2013 00:55:13 +0200 Subject: [PATCH 058/137] Render the scene to a target texture for the stereo rendering filter, ref #43 --- code/nel/include/nel/3d/bloom_effect.h | 2 +- code/nel/include/nel/3d/stereo_display.h | 2 +- code/nel/include/nel/3d/stereo_ovr.h | 2 +- code/nel/src/3d/bloom_effect.cpp | 7 ++-- code/nel/src/3d/stereo_ovr.cpp | 20 +++++---- code/snowballs2/client/src/camera.cpp | 12 ++++-- .../client/src/snowballs_client.cpp | 41 +++++++++++-------- 7 files changed, 49 insertions(+), 37 deletions(-) diff --git a/code/nel/include/nel/3d/bloom_effect.h b/code/nel/include/nel/3d/bloom_effect.h index f5da7a4dd..b637fe937 100644 --- a/code/nel/include/nel/3d/bloom_effect.h +++ b/code/nel/include/nel/3d/bloom_effect.h @@ -83,7 +83,7 @@ public: // If window size exceeds 256*256 the textures used to apply blur are reinitialized with // 256*256 size. If a dimension is less than 256, the texture is initialized with the nearer // power of 2, lower than this window dimension. - void initBloom(UTexture &renderTarget); + void initBloom(UTexture *renderTarget); void initBloom(); // Called at the end of renderAll method in the main loop, recover stretched texture, apply diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index 2f6592b60..aa98dae50 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -124,7 +124,7 @@ public: /// Returns non-NULL if a new render target was set virtual UTexture *beginRenderTarget(bool set) = 0; /// Returns true if a render target was fully drawn - virtual bool endRenderTarget(bool unset) = 0; + virtual bool endRenderTarget() = 0; static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library); static void listDevices(std::vector &devicesOut); diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index f25ef10e0..1a4ebf916 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -111,7 +111,7 @@ public: /// Returns non-NULL if a new render target was set, always NULL if not using render targets virtual UTexture *beginRenderTarget(bool set); /// Returns true if a render target was fully drawn, always false if not using render targets - virtual bool endRenderTarget(bool unset); + virtual bool endRenderTarget(); /// Get the HMD orientation diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 0bc9c1e41..60b7d36b7 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -273,16 +273,15 @@ void CBloomEffect::initTexture(CSmartPtr & tex, bool isMode2D, uint32 void CBloomEffect::initBloom() { - CTextureUser cu; - initBloom(cu); + initBloom(NULL); } -void CBloomEffect::initBloom(UTexture &renderTarget) // clientcfg +void CBloomEffect::initBloom(UTexture *renderTarget) // clientcfg { if(!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) return; - m_UserRenderTarget = dynamic_cast(renderTarget).getITexture(); + m_UserRenderTarget = renderTarget ? dynamic_cast(renderTarget)->getITexture() : NULL; // don't activate bloom when PolygonMode is different from Filled if (_Driver->getPolygonMode() != UDriver::Filled) return; diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 8eb8e1f9b..68fd1400e 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -163,7 +163,7 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_BarrelTexU(NULL) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -453,7 +453,7 @@ UTexture *CStereoOVR::beginRenderTarget(bool set) { // render target always set before driver clear // nlassert(m_SubStage <= 1); - if (m_Stage == 1) + if (m_Driver && m_Stage == 1) { if (set) { @@ -465,17 +465,19 @@ UTexture *CStereoOVR::beginRenderTarget(bool set) } /// Returns true if a render target was fully drawn -bool CStereoOVR::endRenderTarget(bool unset) +bool CStereoOVR::endRenderTarget() { // after rendering of course // nlassert(m_SubStage > 1); - if (m_Stage == 4) + if (m_Driver && m_Stage == 4) { - if (unset) - { - CTextureUser cu; - (static_cast(m_Driver))->setRenderTarget(cu); - } + CTextureUser cu; + (static_cast(m_Driver))->setRenderTarget(cu); + + m_Driver->setMatrixMode2D11(); + m_Driver->setViewport(CViewport()); + m_Driver->drawQuad(m_BarrelQuad, m_BarrelMat); + return true; } return false; diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index f4f5ea2b4..92216fe98 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -113,10 +113,14 @@ void initCamera() { nlinfo("Create VR stereo display device"); StereoDisplay = IStereoDisplay::createDevice(*deviceInfo); - if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD) + if (StereoDisplay) { - nlinfo("Stereo display device is a HMD"); - StereoHMD = static_cast(StereoDisplay); + if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD) + { + nlinfo("Stereo display device is a HMD"); + StereoHMD = static_cast(StereoDisplay); + } + StereoDisplay->setDriver(Driver); // move after driver creation, move stereodisplay before driver creation } } IStereoDisplay::releaseUnusedLibraries(); @@ -212,7 +216,7 @@ void releaseSky() // -- -- random note: update and render makes more sense than animate and update void animateSky(double dt) { - Clouds->anim(dt); + if (!StereoDisplay) Clouds->anim(dt); } // this is actually render diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index e6754388a..e71136377 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -736,26 +736,28 @@ void loopIngame() { uint i = 0; uint bloomStage = 0; - while ((!StereoHMD && i == 0) || (StereoHMD && StereoHMD->nextPass())) + while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) { ++i; - if (StereoHMD) + if (StereoDisplay) { - const CViewport &vp = StereoHMD->getCurrentViewport(); + const CViewport &vp = StereoDisplay->getCurrentViewport(); Driver->setViewport(vp); Scene->setViewport(vp); SkyScene->setViewport(vp); - StereoHMD->getCurrentFrustum(0, &Camera); - StereoHMD->getCurrentFrustum(0, &SkyCamera); - StereoHMD->getCurrentMatrix(0, &Camera); + StereoDisplay->getCurrentFrustum(0, &Camera); + StereoDisplay->getCurrentFrustum(0, &SkyCamera); + StereoDisplay->getCurrentMatrix(0, &Camera); } - if (!StereoHMD || StereoHMD->wantClear()) + if (!StereoDisplay || StereoDisplay->wantClear()) { + NL3D::UTexture *rt = StereoDisplay ? StereoDisplay->beginRenderTarget(!s_EnableBloom) : NULL; + if (s_EnableBloom) { nlassert(bloomStage == 0); - CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) + CBloomEffect::instance().initBloom(/*rt*/); // start bloom effect (just before the first scene element render) bloomStage = 1; } @@ -763,7 +765,7 @@ void loopIngame() Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering } - if (!StereoHMD || StereoHMD->wantScene()) + if (!StereoDisplay || StereoDisplay->wantScene()) { // 02. Render Sky (sky scene) updateSky(); // Render the sky scene before the main scene @@ -772,17 +774,17 @@ void loopIngame() Scene->render(); // Render // 05. Render Effects (flare) - if (!StereoHMD) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...) + if (!StereoDisplay) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...) } - if (!StereoHMD || StereoHMD->wantInterface3D()) + if (!StereoDisplay || StereoDisplay->wantInterface3D()) { if (s_EnableBloom && bloomStage == 1) { // End the actual bloom effect visible in the scene. - if (StereoHMD) Driver->setViewport(NL3D::CViewport()); + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); CBloomEffect::instance().endBloom(); - if (StereoHMD) Driver->setViewport(StereoHMD->getCurrentViewport()); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); bloomStage = 2; } @@ -790,14 +792,14 @@ void loopIngame() // ... } - if (!StereoHMD || StereoHMD->wantInterface2D()) + if (!StereoDisplay || StereoDisplay->wantInterface2D()) { if (s_EnableBloom && bloomStage == 2) { // End bloom effect system after drawing the 3d interface (z buffer related). - if (StereoHMD) Driver->setViewport(NL3D::CViewport()); + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); CBloomEffect::instance().endInterfacesDisplayBloom(); - if (StereoHMD) Driver->setViewport(StereoHMD->getCurrentViewport()); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); bloomStage = 0; } @@ -810,11 +812,16 @@ void loopIngame() renderEntitiesNames(); // Render the name on top of the other players updateInterface(); // Update interface renderInformation(); - if (!StereoHMD) update3dLogo(); // broken with stereo + if (!StereoDisplay) update3dLogo(); // broken with stereo // 08. Render Debug (stuff for dev) // ... } + + if (StereoDisplay) + { + StereoDisplay->endRenderTarget(); + } } // 09. Render Buffer From 76d7146a427aef729ab64c8fee61052a6634da62 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 2 Jul 2013 01:08:49 +0200 Subject: [PATCH 059/137] Workaround in snowballs for fullscreen bug with opengl driver --- code/snowballs2/client/src/snowballs_client.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index e71136377..1faf14d67 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -311,12 +311,15 @@ void initCore() // Create the window with config file values Driver->setDisplay(UDriver::CMode(ConfigFile->getVar("ScreenWidth").asInt(), ConfigFile->getVar("ScreenHeight").asInt(), - ConfigFile->getVar("ScreenDepth").asInt(), - ConfigFile->getVar("ScreenFull").asInt()==0)); + ConfigFile->getVar("ScreenDepth").asInt())); // Set the cache size for the font manager(in bytes) Driver->setFontManagerMaxMemory(2097152); // Create a Text context for later text rendering displayLoadingState("Initialize Text"); + Driver->setMode(UDriver::CMode(ConfigFile->getVar("ScreenWidth").asInt(), + ConfigFile->getVar("ScreenHeight").asInt(), + ConfigFile->getVar("ScreenDepth").asInt(), + ConfigFile->getVar("ScreenFull").asInt()==0)); TextContext = Driver->createTextContext(CPath::lookup(ConfigFile->getVar("FontName").asString())); TextContext->setShaded(true); TextContext->setKeep800x600Ratio(false); From 6b8d43181d3ae90c608781b379a4595a60507f80 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 2 Jul 2013 02:40:27 +0200 Subject: [PATCH 060/137] Test the barrel shader, see #43 --- code/nel/include/nel/3d/stereo_ovr.h | 2 + code/nel/src/3d/stereo_ovr.cpp | 143 ++++++++++++++++++++------- code/nel/src/3d/stereo_ovr_fp.cpp | 60 +++++++++++ 3 files changed, 171 insertions(+), 34 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 1a4ebf916..8d4a924a6 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -63,6 +63,7 @@ class ITexture; class CTextureUser; class CStereoOVRDevicePtr; class CStereoOVRDeviceHandle; +class CPixelProgram; #define NL_STEREO_MAX_USER_CAMERAS 8 @@ -147,6 +148,7 @@ private: NL3D::CTextureUser *m_BarrelTexU; NL3D::UMaterial m_BarrelMat; NLMISC::CQuadUV m_BarrelQuad; + CPixelProgram *m_PixelProgram; }; /* class CStereoOVR */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 68fd1400e..4405ad313 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -68,6 +68,7 @@ using namespace std; namespace NL3D { extern const char *g_StereoOVR_arbfp1; +extern const char *g_StereoOVR_ps_2_0; namespace { @@ -163,7 +164,7 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL), m_PixelProgram(NULL) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -211,6 +212,9 @@ CStereoOVR::~CStereoOVR() m_BarrelTexU = NULL; m_BarrelTex = NULL; // CSmartPtr + delete m_PixelProgram; + m_PixelProgram = NULL; + m_Driver = NULL; if (m_DevicePtr->SensorDevice) @@ -227,49 +231,84 @@ CStereoOVR::~CStereoOVR() void CStereoOVR::setDriver(NL3D::UDriver *driver) { - m_Driver = driver; // Do not allow weird stuff. uint32 width, height; driver->getWindowSize(width, height); nlassert(width == m_DevicePtr->HMDInfo.HResolution); nlassert(height == m_DevicePtr->HMDInfo.VResolution); + nlassert(!m_PixelProgram); NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + /*static const char *program_arbfp1 = + "!!ARBfp1.0\n" + "PARAM c[1] = { { 1, 0 } };\n" + "MOV result.color.xzw, c[0].xyyx;\n" + "TEX result.color.y, fragment.texcoord[0], texture[0], 2D;\n" + "END\n"; + static const char *program_ps_2_0 = + "ps_2_0\n" + "dcl_2d s0\n" + "def c0, 1.00000000, 0.00000000, 0, 0\n" + "dcl t0.xy\n" + "texld r0, t0, s0\n" + "mov r0.z, c0.y\n" + "mov r0.xw, c0.x\n" + "mov oC0, r0\n";*/ + /*if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1)) + { + nldebug("VR: arbfp1"); + m_PixelProgram = new CPixelProgram(program_arbfp1); + } + else */ if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) + { + nldebug("VR: ps_2_0"); + m_PixelProgram = new CPixelProgram(g_StereoOVR_ps_2_0); + } - m_BarrelTex = new CTextureBloom(); // lol bloom - m_BarrelTex->setReleasable(false); - m_BarrelTex->resize(width, height); - m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); - m_BarrelTex->setWrapS(ITexture::Clamp); - m_BarrelTex->setWrapT(ITexture::Clamp); - m_BarrelTex->setRenderTarget(true); - drvInternal->setupTexture(*m_BarrelTex); - m_BarrelTexU = new CTextureUser(m_BarrelTex); + if (m_PixelProgram) + { + m_Driver = driver; - m_BarrelMat = m_Driver->createMaterial(); - NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); - m_BarrelMat.initUnlit(); - m_BarrelMat.setColor(CRGBA::White); - m_BarrelMat.setBlend (false); - m_BarrelMat.setAlphaTest (false); - barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero); - barrelMat->setZWrite(false); - barrelMat->setZFunc(CMaterial::always); - barrelMat->setDoubleSided(true); - barrelMat->setTexture(0, m_BarrelTex); + m_BarrelTex = new CTextureBloom(); // lol bloom + m_BarrelTex->setReleasable(false); + m_BarrelTex->resize(width, height); + m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_BarrelTex->setWrapS(ITexture::Clamp); + m_BarrelTex->setWrapT(ITexture::Clamp); + m_BarrelTex->setRenderTarget(true); + drvInternal->setupTexture(*m_BarrelTex); + m_BarrelTexU = new CTextureUser(m_BarrelTex); - m_BarrelQuad.V0 = CVector(0.f, 0.f, 0.5f); - m_BarrelQuad.V1 = CVector(1.f, 0.f, 0.5f); - m_BarrelQuad.V2 = CVector(1.f, 1.f, 0.5f); - m_BarrelQuad.V3 = CVector(0.f, 1.f, 0.5f); - - float newU = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)width : 1.f; - float newV = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)height : 1.f; + m_BarrelMat = m_Driver->createMaterial(); + m_BarrelMat.initUnlit(); + m_BarrelMat.setColor(CRGBA::White); + m_BarrelMat.setBlend (false); + m_BarrelMat.setAlphaTest (false); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setShader(NL3D::CMaterial::PostProcessing); + barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero); + barrelMat->setZWrite(false); + barrelMat->setZFunc(CMaterial::always); + barrelMat->setDoubleSided(true); + barrelMat->setTexture(0, m_BarrelTex); - m_BarrelQuad.Uv0 = CUV(0.f, 0.f); - m_BarrelQuad.Uv1 = CUV(newU, 0.f); - m_BarrelQuad.Uv2 = CUV(newU, newV); - m_BarrelQuad.Uv3 = CUV(0.f, newV); + m_BarrelQuad.V0 = CVector(0.f, 0.f, 0.5f); + m_BarrelQuad.V1 = CVector(1.f, 0.f, 0.5f); + m_BarrelQuad.V2 = CVector(1.f, 1.f, 0.5f); + m_BarrelQuad.V3 = CVector(0.f, 1.f, 0.5f); + + float newU = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)width : 1.f; + float newV = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)height : 1.f; + + m_BarrelQuad.Uv0 = CUV(0.f, 0.f); + m_BarrelQuad.Uv1 = CUV(newU, 0.f); + m_BarrelQuad.Uv2 = CUV(newU, newV); + m_BarrelQuad.Uv3 = CUV(0.f, newV); + } + else + { + nlwarning("VR: No pixel program support"); + } } void CStereoOVR::getScreenResolution(uint &width, uint &height) @@ -473,10 +512,46 @@ bool CStereoOVR::endRenderTarget() { CTextureUser cu; (static_cast(m_Driver))->setRenderTarget(cu); + bool fogEnabled = m_Driver->fogEnabled(); + m_Driver->enableFog(false); m_Driver->setMatrixMode2D11(); - m_Driver->setViewport(CViewport()); + CViewport vp = CViewport(); + m_Driver->setViewport(vp); + uint32 width, height; + m_Driver->getWindowSize(width, height); + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setTexture(0, m_BarrelTex); + drvInternal->activePixelProgram(m_PixelProgram); + + float w = float(vp.getWidth()),// / float(width), + h = float(vp.getHeight()),// / float(height), + x = float(vp.getX()),/// / float(width), + y = float(vp.getY());// / float(height); + + float lensOffset = m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; + float lensShift = m_DevicePtr->HMDInfo.HScreenSize * 0.25f - lensOffset; + float lensViewportShift = 4.0f * lensShift / m_DevicePtr->HMDInfo.HScreenSize; + + float lensCenterX = x + (w + lensViewportShift * 0.5f) * 0.5f; + float lensCenterY = y + h * 0.5f; + float screenCenterX = x + w * 0.5f; + float screenCenterY = y + h * 0.5f; + float scaleX = (w / 2); + float scaleY = (h / 2); + float scaleInX = (2 / w); + float scaleInY = (2 / h); + drvInternal->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(2, scaleX, scaleY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(3, scaleInX, scaleInY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(4, 1, m_DevicePtr->HMDInfo.DistortionK); + + m_Driver->drawQuad(m_BarrelQuad, m_BarrelMat); + drvInternal->activePixelProgram(NULL); + m_Driver->enableFog(fogEnabled); return true; } diff --git a/code/nel/src/3d/stereo_ovr_fp.cpp b/code/nel/src/3d/stereo_ovr_fp.cpp index eaa80f14c..d33e5fa2c 100644 --- a/code/nel/src/3d/stereo_ovr_fp.cpp +++ b/code/nel/src/3d/stereo_ovr_fp.cpp @@ -78,5 +78,65 @@ const char *g_StereoOVR_arbfp1 = "CMP R1.x, -R1, c[5].z, c[5].w;\n" "CMP result.color, -R1.x, R0, c[5].z;\n" "END\n"; +const char *g_StereoOVR_ps_2_0 = //# 28 instructions, 2 R-regs + "ps_2_0\n" + // cgc version 3.1.0013, build date Apr 18 2012 + // command line args: -profile ps_2_0 + // source file: pp_oculus_vr.cg + //vendor NVIDIA Corporation + //version 3.1.0.13 + //profile ps_2_0 + //program pp_oculus_vr + //semantic pp_oculus_vr.cLensCenter + //semantic pp_oculus_vr.cScreenCenter + //semantic pp_oculus_vr.cScale + //semantic pp_oculus_vr.cScaleIn + //semantic pp_oculus_vr.cHmdWarpParam + //semantic pp_oculus_vr.cTex0 : TEX0 + //var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //var float2 cLensCenter : : c[0] : 1 : 1 + //var float2 cScreenCenter : : c[1] : 2 : 1 + //var float2 cScale : : c[2] : 3 : 1 + //var float2 cScaleIn : : c[3] : 4 : 1 + //var float4 cHmdWarpParam : : c[4] : 5 : 1 + //var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1 + //var float4 oCol : $vout.COLOR : COL : 7 : 1 + //const c[5] = -0.25 -0.5 0.25 0.5 + //const c[6] = 1 0 + "dcl_2d s0\n" + "def c5, -0.25000000, -0.50000000, 0.25000000, 0.50000000\n" + "def c6, 1.00000000, 0.00000000, 0, 0\n" + "dcl t0.xy\n" + "add r0.xy, t0, -c0\n" + "mul r4.xy, r0, c3\n" + "mul r0.x, r4.y, r4.y\n" + "mad r0.x, r4, r4, r0\n" + "mul r1.x, r0, c4.w\n" + "mul r1.x, r1, r0\n" + "mad r3.x, r0, c4.y, c4\n" + "mul r2.x, r0, c4.z\n" + "mad r2.x, r0, r2, r3\n" + "mad r0.x, r1, r0, r2\n" + "mul r0.xy, r4, r0.x\n" + "mul r0.xy, r0, c2\n" + "add r3.xy, r0, c0\n" + "mov r1.x, c5.z\n" + "mov r1.y, c5.w\n" + "mov r2.xy, c1\n" + "add r2.xy, r1, r2\n" + "mov r1.xy, c1\n" + "min r2.xy, r2, r3\n" + "add r1.xy, c5, r1\n" + "max r1.xy, r1, r2\n" + "add r1.xy, r1, -r3\n" + "abs r1.xy, r1\n" + "cmp r1.xy, -r1, c6.x, c6.y\n" + "mul_pp r1.x, r1, r1.y\n" + "abs_pp r1.x, r1\n" + "cmp_pp r1.x, -r1, c6, c6.y\n" + "abs_pp r1.x, r1\n" + "texld r0, r3, s0\n" + "cmp r0, -r1.x, r0, c6.y\n" + "mov oC0, r0\n"; } \ No newline at end of file From a924479a5c3aa94b23ef2f326a5974b336bc0cce Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 2 Jul 2013 03:34:49 +0200 Subject: [PATCH 061/137] Render left and right deformed view, re #43 --- code/nel/include/nel/3d/stereo_ovr.h | 3 +- code/nel/src/3d/stereo_ovr.cpp | 46 +++++++++++++------ .../client/src/snowballs_client.cpp | 12 +++-- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 8d4a924a6..857c5368f 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -147,7 +147,8 @@ private: NLMISC::CSmartPtr m_BarrelTex; NL3D::CTextureUser *m_BarrelTexU; NL3D::UMaterial m_BarrelMat; - NLMISC::CQuadUV m_BarrelQuad; + NLMISC::CQuadUV m_BarrelQuadLeft; + NLMISC::CQuadUV m_BarrelQuadRight; CPixelProgram *m_PixelProgram; }; /* class CStereoOVR */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 4405ad313..63dd03d2f 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -292,18 +292,29 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) barrelMat->setDoubleSided(true); barrelMat->setTexture(0, m_BarrelTex); - m_BarrelQuad.V0 = CVector(0.f, 0.f, 0.5f); - m_BarrelQuad.V1 = CVector(1.f, 0.f, 0.5f); - m_BarrelQuad.V2 = CVector(1.f, 1.f, 0.5f); - m_BarrelQuad.V3 = CVector(0.f, 1.f, 0.5f); + m_BarrelQuadLeft.V0 = CVector(0.f, 0.f, 0.5f); + m_BarrelQuadLeft.V1 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadLeft.V2 = CVector(0.5f, 1.f, 0.5f); + m_BarrelQuadLeft.V3 = CVector(0.f, 1.f, 0.5f); + + m_BarrelQuadRight.V0 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadRight.V1 = CVector(1.f, 0.f, 0.5f); + m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f); + m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f); + nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // this code looks no good float newU = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)width : 1.f; float newV = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)height : 1.f; - m_BarrelQuad.Uv0 = CUV(0.f, 0.f); - m_BarrelQuad.Uv1 = CUV(newU, 0.f); - m_BarrelQuad.Uv2 = CUV(newU, newV); - m_BarrelQuad.Uv3 = CUV(0.f, newV); + m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f); + m_BarrelQuadLeft.Uv1 = CUV(newU * 0.5f, 0.f); + m_BarrelQuadLeft.Uv2 = CUV(newU * 0.5f, newV); + m_BarrelQuadLeft.Uv3 = CUV(0.f, newV); + + m_BarrelQuadRight.Uv0 = CUV(newU * 0.5f, 0.f); + m_BarrelQuadRight.Uv1 = CUV(newU, 0.f); + m_BarrelQuadRight.Uv2 = CUV(newU, newV); + m_BarrelQuadRight.Uv3 = CUV(newU * 0.5f, newV); } else { @@ -525,10 +536,10 @@ bool CStereoOVR::endRenderTarget() barrelMat->setTexture(0, m_BarrelTex); drvInternal->activePixelProgram(m_PixelProgram); - float w = float(vp.getWidth()),// / float(width), - h = float(vp.getHeight()),// / float(height), - x = float(vp.getX()),/// / float(width), - y = float(vp.getY());// / float(height); + float w = float(m_BarrelQuadLeft.V1.x),// / float(width), + h = float(m_BarrelQuadLeft.V2.y),// / float(height), + x = float(m_BarrelQuadLeft.V0.x),/// / float(width), + y = float(m_BarrelQuadLeft.V0.y);// / float(height); float lensOffset = m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; float lensShift = m_DevicePtr->HMDInfo.HScreenSize * 0.25f - lensOffset; @@ -549,7 +560,16 @@ bool CStereoOVR::endRenderTarget() drvInternal->setPixelProgramConstant(4, 1, m_DevicePtr->HMDInfo.DistortionK); - m_Driver->drawQuad(m_BarrelQuad, m_BarrelMat); + m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat); + + x = w; + lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f; + screenCenterX = x + w * 0.5f; + drvInternal->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f); + + m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat); + drvInternal->activePixelProgram(NULL); m_Driver->enableFog(fogEnabled); diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 1faf14d67..2522f48b6 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -311,15 +311,17 @@ void initCore() // Create the window with config file values Driver->setDisplay(UDriver::CMode(ConfigFile->getVar("ScreenWidth").asInt(), ConfigFile->getVar("ScreenHeight").asInt(), - ConfigFile->getVar("ScreenDepth").asInt())); + ConfigFile->getVar("ScreenDepth").asInt(), + (ConfigFile->getVar("OpenGL").asInt() == 1 ? true : ConfigFile->getVar("ScreenFull").asInt()==0))); // Set the cache size for the font manager(in bytes) Driver->setFontManagerMaxMemory(2097152); // Create a Text context for later text rendering displayLoadingState("Initialize Text"); - Driver->setMode(UDriver::CMode(ConfigFile->getVar("ScreenWidth").asInt(), - ConfigFile->getVar("ScreenHeight").asInt(), - ConfigFile->getVar("ScreenDepth").asInt(), - ConfigFile->getVar("ScreenFull").asInt()==0)); + if (ConfigFile->getVar("OpenGL").asInt() == 1) + Driver->setMode(UDriver::CMode(ConfigFile->getVar("ScreenWidth").asInt(), + ConfigFile->getVar("ScreenHeight").asInt(), + ConfigFile->getVar("ScreenDepth").asInt(), + ConfigFile->getVar("ScreenFull").asInt()==0)); TextContext = Driver->createTextContext(CPath::lookup(ConfigFile->getVar("FontName").asString())); TextContext->setShaded(true); TextContext->setKeep800x600Ratio(false); From 2315ae9c5a985d582cceb3a9a1c3fc6d1c5c94c0 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 2 Jul 2013 18:43:15 +0200 Subject: [PATCH 062/137] Prefer NPOT texture over RECT texture --- code/nel/src/3d/driver/opengl/driver_opengl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 32244edbe..830496681 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -701,7 +701,7 @@ bool CDriverGL::supportNonPowerOfTwoTextures() const // *************************************************************************** bool CDriverGL::isTextureRectangle(ITexture * tex) const { - return (supportTextureRectangle() && tex->isBloomTexture() && tex->mipMapOff() + return (!supportNonPowerOfTwoTextures() && supportTextureRectangle() && tex->isBloomTexture() && tex->mipMapOff() && (!isPowerOf2(tex->getWidth()) || !isPowerOf2(tex->getHeight()))); } From c6a7432d86e526a2ef12c6e9da107d385b5c68c3 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 2 Jul 2013 18:43:28 +0200 Subject: [PATCH 063/137] Properly scale seconds per frame graph in snowballs --- code/snowballs2/client/src/graph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/snowballs2/client/src/graph.cpp b/code/snowballs2/client/src/graph.cpp index 73ac726f5..8fd3dd85c 100644 --- a/code/snowballs2/client/src/graph.cpp +++ b/code/snowballs2/client/src/graph.cpp @@ -115,7 +115,7 @@ void CGraph::addValue (float value) // CGraph FpsGraph ("fps", 10.0f, 10.0f, 100.0f, 100.0f, CRGBA(128,0,0,128), 1000, 40.0f); -CGraph SpfGraph ("spf", 10.0f, 110.0f, 100.0f, 100.0f, CRGBA(0,128,0,128), 0, 200.0f); +CGraph SpfGraph ("spf", 10.0f, 110.0f, 100.0f, 100.0f, CRGBA(0,128,0,128), 0, 0.1f); CGraph DownloadGraph ("download", 10.0f, 260.0f, 100.0f, 100.0f, CRGBA(0,0,128,128), 1000, 1000.0f); CGraph UploadGraph ("upload", 10.0f, 360.0f, 100.0f, 100.0f, CRGBA(0,128,128,128), 1000, 1000.0f); From 118340d821ff7f0a411ddb366373323620195fed Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 2 Jul 2013 18:48:29 +0200 Subject: [PATCH 064/137] Test arbfp1, see #43 --- code/nel/src/3d/stereo_ovr.cpp | 35 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 63dd03d2f..745394576 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -239,27 +239,18 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) nlassert(!m_PixelProgram); NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); - /*static const char *program_arbfp1 = + static const char *program_arbfp1 = "!!ARBfp1.0\n" "PARAM c[1] = { { 1, 0 } };\n" "MOV result.color.xzw, c[0].xyyx;\n" "TEX result.color.y, fragment.texcoord[0], texture[0], 2D;\n" "END\n"; - static const char *program_ps_2_0 = - "ps_2_0\n" - "dcl_2d s0\n" - "def c0, 1.00000000, 0.00000000, 0, 0\n" - "dcl t0.xy\n" - "texld r0, t0, s0\n" - "mov r0.z, c0.y\n" - "mov r0.xw, c0.x\n" - "mov oC0, r0\n";*/ - /*if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1)) + if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { nldebug("VR: arbfp1"); m_PixelProgram = new CPixelProgram(program_arbfp1); } - else */ if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) + else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) { nldebug("VR: ps_2_0"); m_PixelProgram = new CPixelProgram(g_StereoOVR_ps_2_0); @@ -270,12 +261,12 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) m_Driver = driver; m_BarrelTex = new CTextureBloom(); // lol bloom + m_BarrelTex->setRenderTarget(true); m_BarrelTex->setReleasable(false); m_BarrelTex->resize(width, height); m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); m_BarrelTex->setWrapS(ITexture::Clamp); m_BarrelTex->setWrapT(ITexture::Clamp); - m_BarrelTex->setRenderTarget(true); drvInternal->setupTexture(*m_BarrelTex); m_BarrelTexU = new CTextureUser(m_BarrelTex); @@ -302,19 +293,17 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f); m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f); - nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // this code looks no good - float newU = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)width : 1.f; - float newV = drvInternal->isTextureRectangle(m_BarrelTex) ? (float)height : 1.f; + nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f); - m_BarrelQuadLeft.Uv1 = CUV(newU * 0.5f, 0.f); - m_BarrelQuadLeft.Uv2 = CUV(newU * 0.5f, newV); - m_BarrelQuadLeft.Uv3 = CUV(0.f, newV); + m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f); + m_BarrelQuadLeft.Uv2 = CUV(0.5f, 1.f); + m_BarrelQuadLeft.Uv3 = CUV(0.f, 1.f); - m_BarrelQuadRight.Uv0 = CUV(newU * 0.5f, 0.f); - m_BarrelQuadRight.Uv1 = CUV(newU, 0.f); - m_BarrelQuadRight.Uv2 = CUV(newU, newV); - m_BarrelQuadRight.Uv3 = CUV(newU * 0.5f, newV); + m_BarrelQuadRight.Uv0 = CUV(0.5f, 0.f); + m_BarrelQuadRight.Uv1 = CUV(1.f, 0.f); + m_BarrelQuadRight.Uv2 = CUV(1.f, 1.f); + m_BarrelQuadRight.Uv3 = CUV(0.5f, 1.f); } else { From e3784571cdec68f0e432f2446c2458812b7b35c1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 2 Jul 2013 19:39:05 +0200 Subject: [PATCH 065/137] Add arbfp1 and fp40 barrel fragment programs, see #43 --- code/nel/src/3d/stereo_ovr.cpp | 18 ++++----- code/nel/src/3d/stereo_ovr_fp.cpp | 63 ++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 745394576..d6fc56cb9 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -67,6 +67,7 @@ using namespace std; namespace NL3D { +extern const char *g_StereoOVR_fp40; extern const char *g_StereoOVR_arbfp1; extern const char *g_StereoOVR_ps_2_0; @@ -238,17 +239,16 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) nlassert(height == m_DevicePtr->HMDInfo.VResolution); nlassert(!m_PixelProgram); - NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); - static const char *program_arbfp1 = - "!!ARBfp1.0\n" - "PARAM c[1] = { { 1, 0 } };\n" - "MOV result.color.xzw, c[0].xyyx;\n" - "TEX result.color.y, fragment.texcoord[0], texture[0], 2D;\n" - "END\n"; - if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + nldebug("VR: fp40"); + m_PixelProgram = new CPixelProgram(g_StereoOVR_fp40); + } + else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { nldebug("VR: arbfp1"); - m_PixelProgram = new CPixelProgram(program_arbfp1); + m_PixelProgram = new CPixelProgram(g_StereoOVR_arbfp1); } else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) { diff --git a/code/nel/src/3d/stereo_ovr_fp.cpp b/code/nel/src/3d/stereo_ovr_fp.cpp index d33e5fa2c..46fe1451b 100644 --- a/code/nel/src/3d/stereo_ovr_fp.cpp +++ b/code/nel/src/3d/stereo_ovr_fp.cpp @@ -21,6 +21,65 @@ limitations under the License. ************************************************************************************/ namespace NL3D { +const char *g_StereoOVR_fp40 = + "!!ARBfp1.0\n" + "OPTION NV_fragment_program2;\n" + //# cgc version 3.1.0013, build date Apr 18 2012 + //# command line args: -profile fp40 + //# source file: pp_oculus_vr.cg + //#vendor NVIDIA Corporation + //#version 3.1.0.13 + //#profile fp40 + //#program pp_oculus_vr + //#semantic pp_oculus_vr.cLensCenter + //#semantic pp_oculus_vr.cScreenCenter + //#semantic pp_oculus_vr.cScale + //#semantic pp_oculus_vr.cScaleIn + //#semantic pp_oculus_vr.cHmdWarpParam + //#semantic pp_oculus_vr.cTex0 : TEX0 + //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //#var float2 cLensCenter : : c[0] : 1 : 1 + //#var float2 cScreenCenter : : c[1] : 2 : 1 + //#var float2 cScale : : c[2] : 3 : 1 + //#var float2 cScaleIn : : c[3] : 4 : 1 + //#var float4 cHmdWarpParam : : c[4] : 5 : 1 + //#var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1 + //#var float4 oCol : $vout.COLOR : COL : 7 : 1 + //#const c[5] = 0.25 0.5 0 + "PARAM c[6] = { program.env[0..4],\n" // program.local->program.env! + " { 0.25, 0.5, 0 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "SHORT TEMP H0;\n" + "TEMP RC;\n" + "TEMP HC;\n" + "OUTPUT oCol = result.color;\n" + "ADDR R0.xy, fragment.texcoord[0], -c[0];\n" + "MULR R0.xy, R0, c[3];\n" + "MULR R0.z, R0.y, R0.y;\n" + "MADR R1.x, R0, R0, R0.z;\n" + "MULR R0.zw, R1.x, c[4].xywz;\n" + "MADR R1.y, R1.x, c[4], c[4].x;\n" + "MADR R0.w, R0, R1.x, R1.y;\n" + "MULR R0.z, R0, R1.x;\n" + "MADR R0.z, R0, R1.x, R0.w;\n" + "MULR R1.xy, R0, R0.z;\n" + "MOVR R0.xy, c[5];\n" + "ADDR R1.zw, R0.xyxy, c[1].xyxy;\n" + "MOVR R0.zw, c[0].xyxy;\n" + "MADR R0.zw, R1.xyxy, c[2].xyxy, R0;\n" + "MINR R1.xy, R0.zwzw, R1.zwzw;\n" + "ADDR R0.xy, -R0, c[1];\n" + "MAXR R0.xy, R0, R1;\n" + "SEQR H0.xy, R0, R0.zwzw;\n" + "MULXC HC.x, H0, H0.y;\n" + "IF EQ.x;\n" + "MOVR oCol, c[5].z;\n" + "ELSE;\n" + "TEX oCol, R0.zwzw, texture[0], 2D;\n" + "ENDIF;\n" + "END\n"; + //# 24 instructions, 2 R-regs, 1 H-regs const char *g_StereoOVR_arbfp1 = "!!ARBfp1.0\n" //# cgc version 3.1.0013, build date Apr 18 2012 @@ -45,7 +104,7 @@ const char *g_StereoOVR_arbfp1 = //#var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1 //#var float4 oCol : $vout.COLOR : COL : 7 : 1 //#const c[5] = 0.25 0.5 0 1 - "PARAM c[6] = { program.local[0..4],\n" + "PARAM c[6] = { program.env[0..4],\n" " { 0.25, 0.5, 0, 1 } };\n" "TEMP R0;\n" "TEMP R1;\n" @@ -78,8 +137,8 @@ const char *g_StereoOVR_arbfp1 = "CMP R1.x, -R1, c[5].z, c[5].w;\n" "CMP result.color, -R1.x, R0, c[5].z;\n" "END\n"; -const char *g_StereoOVR_ps_2_0 = //# 28 instructions, 2 R-regs +const char *g_StereoOVR_ps_2_0 = "ps_2_0\n" // cgc version 3.1.0013, build date Apr 18 2012 // command line args: -profile ps_2_0 From 9516851beec67d75e93c3dbb10c0c16f40367492 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 3 Jul 2013 03:21:57 +0200 Subject: [PATCH 066/137] Remove unnecessary user render target code from bloom, see #43 --- code/nel/include/nel/3d/bloom_effect.h | 5 +--- code/nel/src/3d/bloom_effect.cpp | 38 ++++---------------------- 2 files changed, 6 insertions(+), 37 deletions(-) diff --git a/code/nel/include/nel/3d/bloom_effect.h b/code/nel/include/nel/3d/bloom_effect.h index b637fe937..77673741c 100644 --- a/code/nel/include/nel/3d/bloom_effect.h +++ b/code/nel/include/nel/3d/bloom_effect.h @@ -83,7 +83,6 @@ public: // If window size exceeds 256*256 the textures used to apply blur are reinitialized with // 256*256 size. If a dimension is less than 256, the texture is initialized with the nearer // power of 2, lower than this window dimension. - void initBloom(UTexture *renderTarget); void initBloom(); // Called at the end of renderAll method in the main loop, recover stretched texture, apply @@ -132,15 +131,13 @@ private: uint8 _DensityBloom; // render target textures - // used to display scene (FIXME: redundant when user render target provided...) + // used to display scene NLMISC::CSmartPtr _InitText; // used as stretched texture from _InitText, as displayed texture in first blur pass, // and as render target in second blur pass. NLMISC::CSmartPtr _BlurFinalTex; // used as render target in first blur pass, and as displayed texture on second blur pass. NLMISC::CSmartPtr _BlurHorizontalTex; - /// User provided render target. - NLMISC::CSmartPtr m_UserRenderTarget; // materials diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 60b7d36b7..927f8688c 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -271,18 +271,11 @@ void CBloomEffect::initTexture(CSmartPtr & tex, bool isMode2D, uint32 //----------------------------------------------------------------------------------------------------------- -void CBloomEffect::initBloom() -{ - initBloom(NULL); -} - -void CBloomEffect::initBloom(UTexture *renderTarget) // clientcfg +void CBloomEffect::initBloom() // clientcfg { if(!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) return; - m_UserRenderTarget = renderTarget ? dynamic_cast(renderTarget)->getITexture() : NULL; - // don't activate bloom when PolygonMode is different from Filled if (_Driver->getPolygonMode() != UDriver::Filled) return; @@ -355,20 +348,8 @@ void CBloomEffect::initBloom(UTexture *renderTarget) // clientcfg _DisplaySquareBlurMat.getObjectPtr()->setTexture(1, _BlurFinalTex); } } - - // For now the user target must be the window size - // to be compatible with the existing code. - // TODO: Instead, if user render target is provided, - // assume the size of the user render target as - // the screen size to be used. - if (m_UserRenderTarget.getPtr()) - { - nlassert(_WndWidth == m_UserRenderTarget->getWidth()); - nlassert(_WndHeight == m_UserRenderTarget->getHeight()); - _DisplayInitMat.getObjectPtr()->setTexture(0, m_UserRenderTarget); - } - NL3D::CTextureUser txt = (_InitBloomEffect) ? (CTextureUser(m_UserRenderTarget.getPtr() ? m_UserRenderTarget : _InitText)) : (CTextureUser()); + NL3D::CTextureUser txt = (_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()); if(!((CDriverUser *) _Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)) { nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); @@ -389,7 +370,7 @@ void CBloomEffect::endBloom() // clientcfg if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0) return; - CTextureUser txt1 = (_InitBloomEffect) ? (CTextureUser(m_UserRenderTarget.getPtr() ? m_UserRenderTarget : _InitText)) : (CTextureUser()); + CTextureUser txt1 = (_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()); CTextureUser txt2(_BlurFinalTex); CRect rect1(0, 0, _WndWidth, _WndHeight); CRect rect2(0, 0, _BlurWidth, _BlurHeight); @@ -416,7 +397,7 @@ void CBloomEffect::applyBlur() // in opengl, display in init texture if(_InitBloomEffect) { - CTextureUser txt(m_UserRenderTarget.getPtr() ? m_UserRenderTarget : _InitText); + CTextureUser txt(_InitText); if(!((CDriverUser *) _Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)) { nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); @@ -478,7 +459,7 @@ void CBloomEffect::endInterfacesDisplayBloom() // clientcfg { // Render from render target to screen if necessary. // Don't do this when the blend was done to the screen or when rendering to a user provided rendertarget. - if (_InitBloomEffect && m_UserRenderTarget.isNull()) + if (_InitBloomEffect) { if(!_Driver->supportBloomEffect() || !_Init) return; @@ -511,15 +492,6 @@ void CBloomEffect::endInterfacesDisplayBloom() // clientcfg _Driver->drawQuad(_DisplayQuad, _DisplayInitMat); _Driver->setMatrixMode3D(pCam); } - - if (m_UserRenderTarget.getPtr()) - { - if (_InitBloomEffect) - { - _DisplayInitMat.getObjectPtr()->setTexture(0, _InitText); - } - m_UserRenderTarget = NULL; - } } From 299b3ec4010b9226fe348b6eba87a750e3b164be Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 3 Jul 2013 03:53:32 +0200 Subject: [PATCH 067/137] Make bloom work together with render target used for the rift shader, ref #43 --- code/nel/include/nel/3d/bloom_effect.h | 2 + code/nel/include/nel/3d/stereo_display.h | 6 +-- code/nel/include/nel/3d/stereo_ovr.h | 4 +- code/nel/src/3d/bloom_effect.cpp | 38 +++++++++++++++---- code/nel/src/3d/stereo_ovr.cpp | 11 ++---- .../client/src/snowballs_client.cpp | 8 +++- 6 files changed, 47 insertions(+), 22 deletions(-) diff --git a/code/nel/include/nel/3d/bloom_effect.h b/code/nel/include/nel/3d/bloom_effect.h index 77673741c..c10967254 100644 --- a/code/nel/include/nel/3d/bloom_effect.h +++ b/code/nel/include/nel/3d/bloom_effect.h @@ -138,6 +138,8 @@ private: NLMISC::CSmartPtr _BlurFinalTex; // used as render target in first blur pass, and as displayed texture on second blur pass. NLMISC::CSmartPtr _BlurHorizontalTex; + // original render target + NLMISC::CSmartPtr _OriginalRenderTarget; // materials diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index aa98dae50..5819f21eb 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -121,9 +121,9 @@ public: /// 2D Interface virtual bool wantInterface2D() = 0; - /// Returns non-NULL if a new render target was set - virtual UTexture *beginRenderTarget(bool set) = 0; - /// Returns true if a render target was fully drawn + /// Returns true if a new render target was set, always fase if not using render targets + virtual bool beginRenderTarget() = 0; + /// Returns true if a render target was fully drawn, always false if not using render targets virtual bool endRenderTarget() = 0; static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library); diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 857c5368f..be3880bef 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -109,8 +109,8 @@ public: /// 2D Interface virtual bool wantInterface2D(); - /// Returns non-NULL if a new render target was set, always NULL if not using render targets - virtual UTexture *beginRenderTarget(bool set); + /// Returns true if a new render target was set, always fase if not using render targets + virtual bool beginRenderTarget(); /// Returns true if a render target was fully drawn, always false if not using render targets virtual bool endRenderTarget(); diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 927f8688c..3eb24518e 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -285,6 +285,8 @@ void CBloomEffect::initBloom() // clientcfg if(!_Init) init(); + _OriginalRenderTarget = static_cast(_Driver)->getDriver()->getRenderTarget(); + // if window resize, reinitialize textures if(_WndWidth!=_Driver->getWindowWidth() || _WndHeight!=_Driver->getWindowHeight()) { @@ -349,11 +351,14 @@ void CBloomEffect::initBloom() // clientcfg } } - NL3D::CTextureUser txt = (_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()); - if(!((CDriverUser *) _Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)) + if (!_OriginalRenderTarget) { - nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); - return; + NL3D::CTextureUser txt = (_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()); + if(!(static_cast(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight))) + { + nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); + return; + } } } @@ -370,7 +375,7 @@ void CBloomEffect::endBloom() // clientcfg if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0) return; - CTextureUser txt1 = (_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()); + CTextureUser txt1 = _OriginalRenderTarget ? CTextureUser(_OriginalRenderTarget) : ((_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser())); CTextureUser txt2(_BlurFinalTex); CRect rect1(0, 0, _WndWidth, _WndHeight); CRect rect2(0, 0, _BlurWidth, _BlurHeight); @@ -394,15 +399,30 @@ void CBloomEffect::applyBlur() { NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); + /*if (_OriginalRenderTarget) + { + CTextureUser txt(_OriginalRenderTarget); + if(!(static_cast(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight))) + { + nlwarning("setRenderTarget return false with original render target for bloom effect\n"); + return; + } + } // in opengl, display in init texture - if(_InitBloomEffect) + else if(_InitBloomEffect) { CTextureUser txt(_InitText); - if(!((CDriverUser *) _Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)) + if(!(static_cast(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight))) { nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); return; } + }*/ + CTextureUser txtApply = _OriginalRenderTarget ? CTextureUser(_OriginalRenderTarget) : ((_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser())); + if(!(static_cast(_Driver)->setRenderTarget(txtApply, 0, 0, _WndWidth, _WndHeight))) + { + nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); + return; } // display blur texture @@ -459,7 +479,7 @@ void CBloomEffect::endInterfacesDisplayBloom() // clientcfg { // Render from render target to screen if necessary. // Don't do this when the blend was done to the screen or when rendering to a user provided rendertarget. - if (_InitBloomEffect) + if ((_OriginalRenderTarget.getPtr() == NULL) && _InitBloomEffect) { if(!_Driver->supportBloomEffect() || !_Init) return; @@ -492,6 +512,8 @@ void CBloomEffect::endInterfacesDisplayBloom() // clientcfg _Driver->drawQuad(_DisplayQuad, _DisplayInitMat); _Driver->setMatrixMode3D(pCam); } + + _OriginalRenderTarget = NULL; } diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index d6fc56cb9..a5397e77f 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -488,19 +488,16 @@ bool CStereoOVR::wantInterface2D() /// Returns non-NULL if a new render target was set -UTexture *CStereoOVR::beginRenderTarget(bool set) +bool CStereoOVR::beginRenderTarget() { // render target always set before driver clear // nlassert(m_SubStage <= 1); if (m_Driver && m_Stage == 1) { - if (set) - { - (static_cast(m_Driver))->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0); - } - return m_BarrelTexU; + static_cast(m_Driver)->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0); + return true; } - return NULL; + return false; } /// Returns true if a render target was fully drawn diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 2522f48b6..c510af7ec 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -754,15 +754,19 @@ void loopIngame() StereoDisplay->getCurrentFrustum(0, &SkyCamera); StereoDisplay->getCurrentMatrix(0, &Camera); } + + if (StereoDisplay) + { + StereoDisplay->beginRenderTarget(); + } if (!StereoDisplay || StereoDisplay->wantClear()) { - NL3D::UTexture *rt = StereoDisplay ? StereoDisplay->beginRenderTarget(!s_EnableBloom) : NULL; if (s_EnableBloom) { nlassert(bloomStage == 0); - CBloomEffect::instance().initBloom(/*rt*/); // start bloom effect (just before the first scene element render) + CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) bloomStage = 1; } From a531535dfa8118cda345706d354ae22c83810f17 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 3 Jul 2013 05:21:32 +0200 Subject: [PATCH 068/137] Add minimal head model and world scale, ref #43 --- code/nel/include/nel/3d/stereo_hmd.h | 14 +++++---- code/nel/include/nel/3d/stereo_ovr.h | 11 +++++++ code/nel/src/3d/stereo_ovr.cpp | 29 +++++++++++++++---- code/snowballs2/client/src/camera.cpp | 5 +++- code/snowballs2/client/src/commands.cpp | 2 +- code/snowballs2/client/src/compass.cpp | 2 +- .../client/src/snowballs_client.cpp | 2 ++ 7 files changed, 52 insertions(+), 13 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_hmd.h b/code/nel/include/nel/3d/stereo_hmd.h index bbb80368e..95c159cfd 100644 --- a/code/nel/include/nel/3d/stereo_hmd.h +++ b/code/nel/include/nel/3d/stereo_hmd.h @@ -52,14 +52,18 @@ public: /// Get the HMD orientation virtual NLMISC::CQuat getOrientation() const = 0; - - /// Set the head model, eye position relative to orientation point - // virtual void setEyePosition(const NLMISC::CVector &v) = 0; - /// Get the head model, eye position relative to orientation point - // virtual const NLMISC::CVector &getEyePosition() const = 0; + /// Get GUI center (1 = width, 1 = height, 0 = center) virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const = 0; + /// Set the head model, eye position relative to orientation point + virtual void setEyePosition(const NLMISC::CVector &v) = 0; + /// Get the head model, eye position relative to orientation point + virtual const NLMISC::CVector &getEyePosition() const = 0; + + /// Set the scale of the game in units per meter + virtual void setScale(float s) = 0; + }; /* class IStereoHMD */ } /* namespace NL3D */ diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index be3880bef..770dd97c1 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -117,9 +117,18 @@ public: /// Get the HMD orientation virtual NLMISC::CQuat getOrientation() const; + /// Get GUI center (1 = width, 1 = height, 0 = center) virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const; + /// Set the head model, eye position relative to orientation point + virtual void setEyePosition(const NLMISC::CVector &v); + /// Get the head model, eye position relative to orientation point + virtual const NLMISC::CVector &getEyePosition() const; + + /// Set the scale of the game in units per meter + virtual void setScale(float s); + static void listDevices(std::vector &devicesOut); static bool isLibraryInUse(); @@ -150,6 +159,8 @@ private: NLMISC::CQuadUV m_BarrelQuadLeft; NLMISC::CQuadUV m_BarrelQuadRight; CPixelProgram *m_PixelProgram; + NLMISC::CVector m_EyePosition; + float m_Scale; }; /* class CStereoOVR */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index a5397e77f..f3534a10c 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -165,7 +165,7 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL), m_PixelProgram(NULL) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL), m_PixelProgram(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -433,8 +433,8 @@ void CStereoOVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const { CMatrix translate; - if (m_Stage % 2) translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); - else translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); + if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f)); + else translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f)); camera->setTransformMode(NL3D::UTransformable::DirectMatrix); camera->setMatrix(m_CameraMatrix[cid] * translate); } @@ -594,6 +594,8 @@ void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distanc { #if 0 + // todo: take into account m_EyePosition + NLMISC::CVector vector = CVector(0.f, -distance, 0.f); NLMISC::CQuat rot = getOrientation(); rot.invert(); @@ -616,11 +618,12 @@ void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distanc #elif 1 // Alternative method + // todo: take into account m_EyePosition NLMISC::CVector vec = CVector(0.f, -distance, 0.f); NLMISC::CVector ipd; - if (m_Stage % 2) ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f); - else ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f); + if (m_Stage % 2) ipd = CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f); + else ipd = CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f); NLMISC::CQuat rot = getOrientation(); @@ -640,6 +643,22 @@ void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distanc #endif } +void CStereoOVR::setEyePosition(const NLMISC::CVector &v) +{ + m_EyePosition = v; +} + +const NLMISC::CVector &CStereoOVR::getEyePosition() const +{ + return m_EyePosition; +} + +void CStereoOVR::setScale(float s) +{ + m_EyePosition = m_EyePosition * (s / m_Scale); + m_Scale = s; +} + void CStereoOVR::listDevices(std::vector &devicesOut) { s_StereoOVRSystem.Init(); diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index 92216fe98..ebb4827ab 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -119,6 +119,7 @@ void initCamera() { nlinfo("Stereo display device is a HMD"); StereoHMD = static_cast(StereoDisplay); + StereoHMD->setScale(3.0f); // snowballs is about 4 units per meter } StereoDisplay->setDriver(Driver); // move after driver creation, move stereodisplay before driver creation } @@ -189,7 +190,9 @@ void updateCamera() NLMISC::CMatrix camMatrix = Camera.getMatrix(); NLMISC::CMatrix hmdMatrix; hmdMatrix.setRot(hmdOrient); - Camera.setMatrix(camMatrix * hmdMatrix); + NLMISC::CMatrix posMatrix; // minimal head modeling, will be changed in the future + posMatrix.translate(StereoHMD->getEyePosition()); + Camera.setMatrix((camMatrix * hmdMatrix) * posMatrix); } // Set the new position of the snow emitter CMatrix mat = CMatrix::Identity; diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index e6e7a0086..6d9b23085 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -388,7 +388,7 @@ void updateCommands() if (StereoHMD) { float xshift, yshift; - StereoHMD->getInterface2DShift(0, xshift, yshift, 1.f); + StereoHMD->getInterface2DShift(0, xshift, yshift, 4.f); // snap to pixels xshift = ((float)(sint32)(xshift * width)) / width; yshift = ((float)(sint32)(yshift * height)) / height; diff --git a/code/snowballs2/client/src/compass.cpp b/code/snowballs2/client/src/compass.cpp index e01173f66..9cc6fac57 100644 --- a/code/snowballs2/client/src/compass.cpp +++ b/code/snowballs2/client/src/compass.cpp @@ -98,7 +98,7 @@ void updateCompass () if (StereoHMD) { float xshift, yshift; - StereoHMD->getInterface2DShift(0, xshift, yshift, 1.f); + StereoHMD->getInterface2DShift(0, xshift, yshift, 4.f); x += xshift; y += yshift; } diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index c510af7ec..ea0bc2648 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -933,6 +933,8 @@ void renderInformation() TextContext->setColor(CRGBA(255, 255, 255, 255)); TextContext->setFontSize(14); TextContext->printfAt(0.01f, 0.99f, "%.2f(%.2f)fps %.3fs", FramesPerSecondSmooth, FramesPerSecond, (float)LocalTimeDelta); + CVector camPos = Camera.getMatrix().getPos(); + TextContext->printfAt(0.01f, 0.89f, "CAM POS: %.3f %.3f %.3f", camPos.x, camPos.y, camPos.z); // one more frame FpsGraph.addValue(1.0f); From d57b7b39fe3725df3b6d5ae66fb236c7b848d237 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 3 Jul 2013 06:04:37 +0200 Subject: [PATCH 069/137] Use width instead of height of screen for hmd fov, re #43 --- code/nel/src/3d/stereo_ovr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index f3534a10c..e8b98c081 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -320,7 +320,7 @@ void CStereoOVR::getScreenResolution(uint &width, uint &height) void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) { float ar = (float)m_DevicePtr->HMDInfo.HResolution / ((float)m_DevicePtr->HMDInfo.VResolution * 2.0f); - float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.VScreenSize / 2.0f) / m_DevicePtr->HMDInfo.EyeToScreenDistance); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); + float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.HScreenSize * 0.5f * 0.5f) / (m_DevicePtr->HMDInfo.EyeToScreenDistance)); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); m_RightFrustum[cid] = m_LeftFrustum[cid]; From fd1d606154a7d4edfeeea0fbad80866f0dca3110 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Jul 2013 00:09:10 +0200 Subject: [PATCH 070/137] Add stereo debugger for visually comparing rendered frames, ref #43 --- code/nel/include/nel/3d/stereo_debugger.h | 130 ++++++++ code/nel/include/nel/3d/stereo_display.h | 2 +- code/nel/include/nel/3d/stereo_ovr.h | 2 +- code/nel/src/3d/CMakeLists.txt | 8 +- code/nel/src/3d/stereo_debugger.cpp | 350 ++++++++++++++++++++++ code/nel/src/3d/stereo_display.cpp | 4 + code/nel/src/3d/stereo_ovr.cpp | 4 +- code/nel/src/3d/stereo_ovr_fp.cpp | 1 + code/snowballs2/bin/pp_oculus_vr.cg | 54 ++++ code/snowballs2/bin/pp_stereo_debug.cg | 25 ++ code/snowballs2/client/src/camera.cpp | 2 +- 11 files changed, 576 insertions(+), 6 deletions(-) create mode 100644 code/nel/include/nel/3d/stereo_debugger.h create mode 100644 code/nel/src/3d/stereo_debugger.cpp create mode 100644 code/snowballs2/bin/pp_oculus_vr.cg create mode 100644 code/snowballs2/bin/pp_stereo_debug.cg diff --git a/code/nel/include/nel/3d/stereo_debugger.h b/code/nel/include/nel/3d/stereo_debugger.h new file mode 100644 index 000000000..b94ffaf6b --- /dev/null +++ b/code/nel/include/nel/3d/stereo_debugger.h @@ -0,0 +1,130 @@ +/** + * \file stereo_debugger.h + * \brief CStereoDebugger + * \date 2013-07-03 20:17GMT + * \author Jan Boon (Kaetemi) + * CStereoDebugger + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#if !FINAL_VERSION +#ifndef NL3D_STEREO_DEBUGGER_H +#define NL3D_STEREO_DEBUGGER_H +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes +#include +#include +#include +#include + +#define NL_STEREO_MAX_USER_CAMERAS 8 + +namespace NL3D { + +class ITexture; +class CTextureUser; +class CPixelProgram; + +/** + * \brief CStereoDebugger + * \date 2013-07-03 20:17GMT + * \author Jan Boon (Kaetemi) + * CStereoDebugger + */ +class CStereoDebugger : public IStereoDisplay +{ +public: + CStereoDebugger(); + virtual ~CStereoDebugger(); + + + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver *driver); + + /// Gets the required screen resolution for this device + virtual bool getScreenResolution(uint &width, uint &height); + /// Set latest camera position etcetera + virtual void updateCamera(uint cid, const NL3D::UCamera *camera); + /// Get the frustum to use for clipping + virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const; + + /// Is there a next pass + virtual bool nextPass(); + /// Gets the current viewport + virtual const NL3D::CViewport &getCurrentViewport() const; + /// Gets the current camera frustum + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const; + /// Gets the current camera frustum + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const; + /// Gets the current camera matrix + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; + + /// At the start of a new render target + virtual bool wantClear(); + /// The 3D scene + virtual bool wantScene(); + /// Interface within the 3D scene + virtual bool wantInterface3D(); + /// 2D Interface + virtual bool wantInterface2D(); + + /// Returns true if a new render target was set, always fase if not using render targets + virtual bool beginRenderTarget(); + /// Returns true if a render target was fully drawn, always false if not using render targets + virtual bool endRenderTarget(); + + + static void listDevices(std::vector &devicesOut); + +private: + UDriver *m_Driver; + + int m_Stage; + int m_SubStage; + + CViewport m_LeftViewport; + CViewport m_RightViewport; + CFrustum m_Frustum[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; + + NLMISC::CSmartPtr m_LeftTex; + NL3D::CTextureUser *m_LeftTexU; + NLMISC::CSmartPtr m_RightTex; + NL3D::CTextureUser *m_RightTexU; + NL3D::UMaterial m_Mat; + NLMISC::CQuadUV m_QuadUV; + CPixelProgram *m_PixelProgram; + +}; /* class CStereoDebugger */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_STEREO_DEBUGGER_H */ +#endif /* #if !FINAL_VERSION */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index 5819f21eb..e3b5b3716 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -95,7 +95,7 @@ public: virtual void setDriver(NL3D::UDriver *driver) = 0; /// Gets the required screen resolution for this device - virtual void getScreenResolution(uint &width, uint &height) = 0; + virtual bool getScreenResolution(uint &width, uint &height) = 0; /// Set latest camera position etcetera virtual void updateCamera(uint cid, const NL3D::UCamera *camera) = 0; /// Get the frustum to use for clipping diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 770dd97c1..3b417b871 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -83,7 +83,7 @@ public: virtual void setDriver(NL3D::UDriver *driver); /// Gets the required screen resolution for this device - virtual void getScreenResolution(uint &width, uint &height); + virtual bool getScreenResolution(uint &width, uint &height); /// Set latest camera position etcetera virtual void updateCamera(uint cid, const NL3D::UCamera *camera); /// Get the frustum to use for clipping diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index da0288561..ffdc876a9 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -164,7 +164,9 @@ SOURCE_GROUP(Driver FILES vertex_program.cpp ../../include/nel/3d/vertex_program.h vertex_program_parse.cpp - ../../include/nel/3d/vertex_program_parse.h) + ../../include/nel/3d/vertex_program_parse.h + pixel_program.cpp + ../../include/nel/3d/pixel_program.h) SOURCE_GROUP(Font FILES computed_string.cpp @@ -693,7 +695,9 @@ SOURCE_GROUP(Stereo FILES ../../include/nel/3d/stereo_hmd.h stereo_ovr.cpp stereo_ovr_fp.cpp - ../../include/nel/3d/stereo_ovr.h) + ../../include/nel/3d/stereo_ovr.h + stereo_debugger.cpp + ../../include/nel/3d/stereo_debugger.h) NL_TARGET_LIB(nel3d ${HEADERS} ${SRC}) diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp new file mode 100644 index 000000000..c24bcdc93 --- /dev/null +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -0,0 +1,350 @@ +/** + * \file stereo_debugger.cpp + * \brief CStereoDebugger + * \date 2013-07-03 20:17GMT + * \author Jan Boon (Kaetemi) + * CStereoDebugger + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#if !FINAL_VERSION +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +namespace { + +const char *a_arbfp1 = + "!!ARBfp1.0\n" + "PARAM c[1] = { { 1, 0, 0.5 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "TEMP R2;\n" + "TEX R0, fragment.texcoord[0], texture[0], 2D;\n" + "TEX R1, fragment.texcoord[0], texture[1], 2D;\n" + "ADD R2, R0, -R1;\n" + "ADD R1, R0, R1;\n" + "MUL R1, R1, c[0].z;\n" + "ABS R2, R2;\n" + "CMP R2, -R2, c[0].x, c[0].y;\n" + "ADD_SAT R2.x, R2, R2.y;\n" + "ADD_SAT R2.x, R2, R2.z;\n" + "ADD_SAT R2.x, R2, R2.w;\n" + "ABS R2.x, R2;\n" + "CMP R2.x, -R2, c[0].y, c[0];\n" + "ABS R0.x, R2;\n" + "CMP R2.x, -R0, c[0].y, c[0];\n" + "MOV R0.xzw, R1;\n" + "MAD R0.y, R1, c[0].z, c[0].z;\n" + "CMP R0, -R2.x, R1, R0;\n" + "MAD R1.x, R0, c[0].z, c[0].z;\n" + "CMP result.color.x, -R2, R1, R0;\n" + "MOV result.color.yzw, R0;\n" + "END\n"; + +class CStereoDebuggerFactory : public IStereoDeviceFactory +{ +public: + IStereoDisplay *createDevice() const + { + return new CStereoDebugger(); + } +}; + +} /* anonymous namespace */ + +CStereoDebugger::CStereoDebugger() : m_Driver(NULL), m_Stage(0), m_SubStage(0), m_LeftTexU(NULL), m_RightTexU(NULL), m_PixelProgram(NULL) +{ + +} + +CStereoDebugger::~CStereoDebugger() +{ + if (!m_Mat.empty()) + { + m_Mat.getObjectPtr()->setTexture(0, NULL); + m_Mat.getObjectPtr()->setTexture(1, NULL); + m_Driver->deleteMaterial(m_Mat); + } + + delete m_LeftTexU; + m_LeftTexU = NULL; + m_LeftTex = NULL; // CSmartPtr + + delete m_RightTexU; + m_RightTexU = NULL; + m_RightTex = NULL; // CSmartPtr + + delete m_PixelProgram; + m_PixelProgram = NULL; + + m_Driver = NULL; +} + +/// Sets driver and generates necessary render targets +void CStereoDebugger::setDriver(NL3D::UDriver *driver) +{ + nlassert(!m_PixelProgram); + + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + /*if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + nldebug("VR: fp40"); + m_PixelProgram = new CPixelProgram(a_fp40); + } + else*/ if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + nldebug("VR: arbfp1"); + m_PixelProgram = new CPixelProgram(a_arbfp1); + } + /*else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) + { + nldebug("VR: ps_2_0"); + m_PixelProgram = new CPixelProgram(a_ps_2_0); + }*/ + + if (m_PixelProgram) + { + m_Driver = driver; + + // todo: handle reso change! + + uint32 width, height; + driver->getWindowSize(width, height); + + m_LeftTex = new CTextureBloom(); + m_LeftTex->setRenderTarget(true); + m_LeftTex->setReleasable(false); + m_LeftTex->resize(width, height); + m_LeftTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_LeftTex->setWrapS(ITexture::Clamp); + m_LeftTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_LeftTex); + m_LeftTexU = new CTextureUser(m_LeftTex); + nlassert(!drvInternal->isTextureRectangle(m_LeftTex)); // not allowed + + m_RightTex = new CTextureBloom(); + m_RightTex->setRenderTarget(true); + m_RightTex->setReleasable(false); + m_RightTex->resize(width, height); + m_RightTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_RightTex->setWrapS(ITexture::Clamp); + m_RightTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_RightTex); + m_RightTexU = new CTextureUser(m_RightTex); + nlassert(!drvInternal->isTextureRectangle(m_RightTex)); // not allowed + + + m_Mat = m_Driver->createMaterial(); + m_Mat.initUnlit(); + m_Mat.setColor(CRGBA::White); + m_Mat.setBlend (false); + m_Mat.setAlphaTest (false); + NL3D::CMaterial *mat = m_Mat.getObjectPtr(); + mat->setShader(NL3D::CMaterial::PostProcessing); + mat->setBlendFunc(CMaterial::one, CMaterial::zero); + mat->setZWrite(false); + mat->setZFunc(CMaterial::always); + mat->setDoubleSided(true); + mat->setTexture(0, m_LeftTex); + mat->setTexture(1, m_RightTex); + + + m_QuadUV.V0 = CVector(0.f, 0.f, 0.5f); + m_QuadUV.V1 = CVector(1.f, 0.f, 0.5f); + m_QuadUV.V2 = CVector(1.f, 1.f, 0.5f); + m_QuadUV.V3 = CVector(0.f, 1.f, 0.5f); + + m_QuadUV.Uv0 = CUV(0.f, 0.f); + m_QuadUV.Uv1 = CUV(1.f, 0.f); + m_QuadUV.Uv2 = CUV(1.f, 1.f); + m_QuadUV.Uv3 = CUV(0.f, 1.f); + } +} + +/// Gets the required screen resolution for this device +bool CStereoDebugger::getScreenResolution(uint &width, uint &height) +{ + return false; +} + +/// Set latest camera position etcetera +void CStereoDebugger::updateCamera(uint cid, const NL3D::UCamera *camera) +{ + m_Frustum[cid] = camera->getFrustum(); +} + +/// Get the frustum to use for clipping +void CStereoDebugger::getClippingFrustum(uint cid, NL3D::UCamera *camera) const +{ + // do nothing +} + +/// Is there a next pass +bool CStereoDebugger::nextPass() +{ + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + ++m_Stage; + m_SubStage = 0; + return true; + case 2: + m_Stage = 0; + m_SubStage = 0; + return false; + } +} + +/// Gets the current viewport +const NL3D::CViewport &CStereoDebugger::getCurrentViewport() const +{ + if (m_Stage % 2) return m_LeftViewport; + else return m_RightViewport; +} + +/// Gets the current camera frustum +const NL3D::CFrustum &CStereoDebugger::getCurrentFrustum(uint cid) const +{ + return m_Frustum[cid]; +} + +/// Gets the current camera frustum +void CStereoDebugger::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const +{ + // do nothing +} + +/// Gets the current camera matrix +void CStereoDebugger::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const +{ + // do nothing +} + +/// At the start of a new render target +bool CStereoDebugger::wantClear() +{ + m_SubStage = 1; + return true; +} + +/// The 3D scene +bool CStereoDebugger::wantScene() +{ + m_SubStage = 2; + return true; +} + +/// Interface within the 3D scene +bool CStereoDebugger::wantInterface3D() +{ + m_SubStage = 3; + return true; +} + +/// 2D Interface +bool CStereoDebugger::wantInterface2D() +{ + m_SubStage = 4; + return true; +} + +/// Returns true if a new render target was set, always fase if not using render targets +bool CStereoDebugger::beginRenderTarget() +{ + if (m_Driver) + { + if (m_Stage % 2) static_cast(m_Driver)->setRenderTarget(*m_RightTexU, 0, 0, 0, 0); + else static_cast(m_Driver)->setRenderTarget(*m_LeftTexU, 0, 0, 0, 0); + return true; + } + return false; +} + +/// Returns true if a render target was fully drawn, always false if not using render targets +bool CStereoDebugger::endRenderTarget() +{ + if (m_Driver) + { + CTextureUser cu; + (static_cast(m_Driver))->setRenderTarget(cu); + bool fogEnabled = m_Driver->fogEnabled(); + m_Driver->enableFog(false); + + m_Driver->setMatrixMode2D11(); + CViewport vp = CViewport(); + m_Driver->setViewport(vp); + uint32 width, height; + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + NL3D::CMaterial *mat = m_Mat.getObjectPtr(); + mat->setTexture(0, m_LeftTex); + mat->setTexture(1, m_RightTex); + drvInternal->activePixelProgram(m_PixelProgram); + + m_Driver->drawQuad(m_QuadUV, m_Mat); + + drvInternal->activePixelProgram(NULL); + m_Driver->enableFog(fogEnabled); + + return true; + } + return false; +} + +void CStereoDebugger::listDevices(std::vector &devicesOut) +{ + CStereoDeviceInfo devInfo; + devInfo.Factory = new CStereoDebuggerFactory(); + devInfo.Library = CStereoDeviceInfo::NeL3D; + devInfo.Class = CStereoDeviceInfo::StereoDisplay; + devInfo.Manufacturer = "NeL"; + devInfo.ProductName = "Stereo Debugger"; + devInfo.Serial = "NL-3D-DEBUG"; + devicesOut.push_back(devInfo); +} + +} /* namespace NL3D */ + +#endif /* #if !FINAL_VERSION */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_display.cpp b/code/nel/src/3d/stereo_display.cpp index 09502a256..d2a8fd932 100644 --- a/code/nel/src/3d/stereo_display.cpp +++ b/code/nel/src/3d/stereo_display.cpp @@ -35,6 +35,7 @@ // Project includes #include +#include using namespace std; // using namespace NLMISC; @@ -75,6 +76,9 @@ const char *IStereoDisplay::getLibraryName(CStereoDeviceInfo::TStereoDeviceLibra void IStereoDisplay::listDevices(std::vector &devicesOut) { CStereoOVR::listDevices(devicesOut); +#if !FINAL_VERSION + CStereoDebugger::listDevices(devicesOut); +#endif } IStereoDisplay *IStereoDisplay::createDevice(const CStereoDeviceInfo &deviceInfo) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index e8b98c081..ba03990b1 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -145,6 +145,7 @@ sint s_DeviceCounter = 0; class CStereoOVRDeviceHandle : public IStereoDeviceFactory { public: + // fixme: virtual destructor??? OVR::DeviceEnumerator DeviceHandle; IStereoDisplay *createDevice() const { @@ -311,10 +312,11 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) } } -void CStereoOVR::getScreenResolution(uint &width, uint &height) +bool CStereoOVR::getScreenResolution(uint &width, uint &height) { width = m_DevicePtr->HMDInfo.HResolution; height = m_DevicePtr->HMDInfo.VResolution; + return true; } void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) diff --git a/code/nel/src/3d/stereo_ovr_fp.cpp b/code/nel/src/3d/stereo_ovr_fp.cpp index 46fe1451b..b81ee8421 100644 --- a/code/nel/src/3d/stereo_ovr_fp.cpp +++ b/code/nel/src/3d/stereo_ovr_fp.cpp @@ -3,6 +3,7 @@ Filename : stereo_ovf_fp.cpp Content : Barrel fragment program compiled to a blob of assembly Created : July 01, 2013 +Modified by : Jan Boon (Kaetemi) Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. diff --git a/code/snowballs2/bin/pp_oculus_vr.cg b/code/snowballs2/bin/pp_oculus_vr.cg new file mode 100644 index 000000000..1d84e0d54 --- /dev/null +++ b/code/snowballs2/bin/pp_oculus_vr.cg @@ -0,0 +1,54 @@ +/************************************************************************************ + +Filename : pp_oculus_vr.cg +Content : Barrel fragment program ported from Oculus SDK Samples to Cg +Created : July 01, 2013 +Modified by : Jan Boon (Kaetemi) + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + + +void pp_oculus_vr( + // Per fragment parameters + float2 texCoord : TEXCOORD0, + + // Fragment program constants + uniform float2 cLensCenter, + uniform float2 cScreenCenter, + uniform float2 cScale, + uniform float2 cScaleIn, + uniform float4 cHmdWarpParam, + uniform sampler2D cTex0 : TEX0, + + // Output color + out float4 oCol : COLOR) +{ + float2 theta = (texCoord - cLensCenter) * cScaleIn; // Scales to [-1, 1] + float rSq = theta.x * theta.x + theta.y * theta.y; + float2 theta1 = theta * (cHmdWarpParam.x + cHmdWarpParam.y * rSq + + cHmdWarpParam.z * rSq * rSq + cHmdWarpParam.w * rSq * rSq * rSq); + float2 tc = cLensCenter + cScale * theta1; + + if (!all(equal(clamp(tc, cScreenCenter-float2(0.25,0.5), cScreenCenter+float2(0.25,0.5)), tc))) + { + oCol = float4(0, 0, 0, 0); + } + else + { + oCol = tex2D(cTex0, tc); + } +} diff --git a/code/snowballs2/bin/pp_stereo_debug.cg b/code/snowballs2/bin/pp_stereo_debug.cg new file mode 100644 index 000000000..3af27864d --- /dev/null +++ b/code/snowballs2/bin/pp_stereo_debug.cg @@ -0,0 +1,25 @@ + +void pp_stereo_debug( + // Per fragment parameters + float2 texCoord : TEXCOORD0, + + // Fragment program constants + uniform sampler2D cTex0 : TEX0, + uniform sampler2D cTex1 : TEX1, + + // Output color + out float4 oCol : COLOR) +{ + float4 t1 = tex2D(cTex0, texCoord); + float4 t2 = tex2D(cTex1, texCoord); + if (!any(t1 - t2)) + { + oCol = (t1 * 0.5) + (t2 * 0.5); + oCol.g = 0.5 + (oCol.g * 0.5); + } + else + { + oCol = (t1 * 0.5) + (t2 * 0.5); + oCol.r = 0.5 + (oCol.r * 0.5); + } +} diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index ebb4827ab..42c3b0e4d 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -124,8 +124,8 @@ void initCamera() StereoDisplay->setDriver(Driver); // move after driver creation, move stereodisplay before driver creation } } - IStereoDisplay::releaseUnusedLibraries(); } + IStereoDisplay::releaseUnusedLibraries(); // Set up directly the camera Camera = Scene->getCam(); From 4b2ea661cca84234f7e29153461653aa934cce54 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Jul 2013 00:42:06 +0200 Subject: [PATCH 071/137] Fix particles being animated twice in stereo render, see #43 --- code/nel/include/nel/3d/scene.h | 3 ++- code/nel/src/3d/scene.cpp | 14 +++++++++++++- code/snowballs2/client/src/camera.cpp | 4 ++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/3d/scene.h b/code/nel/include/nel/3d/scene.h index 1d54ce7a6..e0648ebd3 100644 --- a/code/nel/include/nel/3d/scene.h +++ b/code/nel/include/nel/3d/scene.h @@ -826,7 +826,8 @@ private: void flushSSSModelRequests(); // common vb for water display CVertexBuffer _WaterVB; - + + bool _RequestParticlesAnimate; }; diff --git a/code/nel/src/3d/scene.cpp b/code/nel/src/3d/scene.cpp index f257c7206..76761bc71 100644 --- a/code/nel/src/3d/scene.cpp +++ b/code/nel/src/3d/scene.cpp @@ -191,6 +191,8 @@ CScene::CScene(bool bSmallScene) : LightTrav(bSmallScene) _WaterEnvMap = NULL; _GlobalSystemTime= 0.0; + + _RequestParticlesAnimate = false; } // *************************************************************************** void CScene::release() @@ -381,6 +383,9 @@ void CScene::endPartRender() drv->activeVertexProgram(NULL); drv->activePixelProgram(NULL); + // Ensure nothing animates on subsequent renders + _EllapsedTime = 0.f; + /* uint64 total = PSStatsRegisterPSModelObserver + PSStatsRemovePSModelObserver + @@ -617,7 +622,11 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass) // loadBalance LoadBalancingTrav.traverse(); // - _ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems + if (_RequestParticlesAnimate) + { + _ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems + _RequestParticlesAnimate = false; + } // Light LightTrav.traverse(); } @@ -863,6 +872,9 @@ void CScene::animate( TGlobalAnimationTime atTime ) // Rendered part are invalidate _RenderedPart = UScene::RenderNothing; + + // Particles are animated later due to dependencies + _RequestParticlesAnimate = true; } diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index 42c3b0e4d..28ce273bb 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -219,7 +219,8 @@ void releaseSky() // -- -- random note: update and render makes more sense than animate and update void animateSky(double dt) { - if (!StereoDisplay) Clouds->anim(dt); + if (!StereoHMD) Clouds->anim(dt); + SkyScene->animate(AnimationTime); } // this is actually render @@ -232,7 +233,6 @@ void updateSky() skyCameraMatrix.setPos(CVector::Null); SkyCamera.setMatrix(skyCameraMatrix); - SkyScene->animate(AnimationTime); SkyScene->render(); // Must clear ZBuffer For incoming rendering. Driver->clearZBuffer(); From 4402fbe1c265d8daf79a6ab11421e560b8e4bda1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Jul 2013 20:43:49 +0200 Subject: [PATCH 072/137] Correctly synchronize some more animation in snowballs, re #43 --- code/snowballs2/client/src/animation.cpp | 8 ++++---- code/snowballs2/client/src/entities.cpp | 10 +++++----- code/snowballs2/client/src/entities.h | 2 +- code/snowballs2/client/src/snowballs_client.cpp | 13 ++++++------- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/code/snowballs2/client/src/animation.cpp b/code/snowballs2/client/src/animation.cpp index ab873ffbc..dd2296e25 100644 --- a/code/snowballs2/client/src/animation.cpp +++ b/code/snowballs2/client/src/animation.cpp @@ -97,7 +97,7 @@ Anim AnimIdArray[][2] = void computeAnimation (CEntity &entity, EAnim anim) { // Get the current time - double currentTime = double (CTime::getLocalTime ())/1000.0f; + double currentTime = AnimationTime; // nlinfo ("%d playing animation", anim); // nlinfo ("%d playing animation %s ct%f st%f et%f", anim, AnimIdArray[anim][0].Name, currentTime, AnimIdArray[anim][0].Animation->getBeginTime (), AnimIdArray[anim][0].Animation->getEndTime ()); @@ -153,7 +153,7 @@ void playAnimation (CEntity &entity, EAnim anim, bool force) // nlinfo ("playAnimation() %d", anim); // Get the current time - CAnimationTime currentTime = CAnimationTime(CTime::getLocalTime ())/1000.0f; + CAnimationTime currentTime = AnimationTime; // Can't do animation without skeleton if (entity.Skeleton.empty()) @@ -224,7 +224,7 @@ void initAnimation() void updateAnimation() { // Get the current time - CAnimationTime currentTime = CAnimationTime(CTime::getLocalTime ())/1000.0f; + CAnimationTime currentTime = AnimationTime; for (EIT eit = Entities.begin (); eit != Entities.end (); eit++) { @@ -270,7 +270,7 @@ void updateAnimation() } // compute new animation position depending of the current time - PlayListManager->animate (double(CTime::getLocalTime ())/1000.0f); + PlayListManager->animate (AnimationTime); } void releaseAnimation() diff --git a/code/snowballs2/client/src/entities.cpp b/code/snowballs2/client/src/entities.cpp index af879958c..2972aebf1 100644 --- a/code/snowballs2/client/src/entities.cpp +++ b/code/snowballs2/client/src/entities.cpp @@ -105,7 +105,7 @@ bool _TestCLS = false; void CEntity::setState (TState state) { State = state; - StateStartTime = CTime::getLocalTime (); + StateStartTime = LocalTime; } @@ -376,7 +376,7 @@ void deleteAllEntities() void stateAppear (CEntity &entity) { // after 1 second, show the instance - if (CTime::getLocalTime () > entity.StateStartTime + 1000) + if (LocalTime > entity.StateStartTime + 1.0) { if (entity.Instance.getVisibility () != UTransform::Show) entity.Instance.show (); @@ -384,7 +384,7 @@ void stateAppear (CEntity &entity) // after 5 seconds, delete the particle system (if any) // and pass the entity into the Normal state - if (CTime::getLocalTime () > entity.StateStartTime + 3000) + if (LocalTime > entity.StateStartTime + 3.0) { if (!entity.Particule.empty()) { @@ -403,7 +403,7 @@ void stateAppear (CEntity &entity) void stateDisappear (CEntity &entity) { // after 1 second, remove the mesh and all collision stuff - if (CTime::getLocalTime () > entity.StateStartTime + 1000) + if (LocalTime > entity.StateStartTime + 1.0) { if (entity.Instance.getVisibility () != UTransform::Hide) { @@ -419,7 +419,7 @@ void stateDisappear (CEntity &entity) } // after 5 seconds, remove the particle system and the entity entry - if (CTime::getLocalTime () > entity.StateStartTime + 3000) + if (LocalTime > entity.StateStartTime + 3.0) { deleteEntity (entity); } diff --git a/code/snowballs2/client/src/entities.h b/code/snowballs2/client/src/entities.h index 0ad7819ee..e85ffc569 100644 --- a/code/snowballs2/client/src/entities.h +++ b/code/snowballs2/client/src/entities.h @@ -108,7 +108,7 @@ public: // The state of this entity TState State; // The date of the beginning of this state - NLMISC::TTime StateStartTime; + NLMISC::TLocalTime StateStartTime; // The type enum of the entity enum TType { Self, Other, Snowball }; diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index ea0bc2648..6c3630a8b 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -691,14 +691,14 @@ void loopIngame() CGameTime::updateTime(); CGameTime::advanceTime(1.0); - // 03. Update Input (keyboard controls, etc) + // 03. Update Incoming (network, receive messages) + updateNetwork(); + + // 04. Update Input (keyboard controls, etc) Driver->EventServer.pump(); // Pump user input messages MouseListener->update(); MouseListener->updateCamera(); - // 04. Update Incoming (network, receive messages) - updateNetwork(); - // 05. Update Weather (sky, snow, wind, fog, sun) animateSky(LocalTimeDelta); @@ -706,7 +706,7 @@ void loopIngame() updateLandscape(); // Update the landscape // ... Update Animations (TEST) - // ... + updateAnimation(); // 07. Update Entities (collisions and actions) // - Move Other Entities (move//, animations, etc) @@ -783,7 +783,7 @@ void loopIngame() Scene->render(); // Render // 05. Render Effects (flare) - if (!StereoDisplay) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...) + if (!StereoHMD) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...) } if (!StereoDisplay || StereoDisplay->wantInterface3D()) @@ -817,7 +817,6 @@ void loopIngame() updateRadar(); // Update the radar updateGraph(); // Update the radar if (ShowCommands) updateCommands(); // Update the commands panel - updateAnimation(); renderEntitiesNames(); // Render the name on top of the other players updateInterface(); // Update interface renderInformation(); From 6113b07673e511f329cc8b481f86a49d608bc075 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Jul 2013 21:12:11 +0200 Subject: [PATCH 073/137] Distort 2D gui as well, ref #43 --- code/nel/src/3d/stereo_ovr.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index ba03990b1..e58e82892 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -507,7 +507,7 @@ bool CStereoOVR::endRenderTarget() { // after rendering of course // nlassert(m_SubStage > 1); - if (m_Driver && m_Stage == 4) + if (m_Driver && m_Stage == 6) // set to 4 to turn off distortion of 2d gui { CTextureUser cu; (static_cast(m_Driver))->setRenderTarget(cu); @@ -606,13 +606,13 @@ void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distanc //if (m_Stage % 2) mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); //else mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); mat.translate(vector); - CVector proj = CStereoOVR::getCurrentFrustum().project(mat.getPos()); + CVector proj = CStereoOVR::getCurrentFrustum(cid).project(mat.getPos()); NLMISC::CVector ipd; if (m_Stage % 2) ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f); else ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f); - CVector projipd = CStereoOVR::getCurrentFrustum().project(vector + ipd); - CVector projvec = CStereoOVR::getCurrentFrustum().project(vector); + CVector projipd = CStereoOVR::getCurrentFrustum(cid).project(vector + ipd); + CVector projvec = CStereoOVR::getCurrentFrustum(cid).project(vector); x = (proj.x + projipd.x - projvec.x - 0.5f); y = (proj.y + projipd.y - projvec.y - 0.5f); From ee227aaf9cad281846d3874ae38597b06df3ae2a Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Jul 2013 22:18:19 +0200 Subject: [PATCH 074/137] Refactor fulldetail override --- .../src/interface_v3/action_handler_misc.cpp | 2 +- code/ryzom/client/src/landscape_poly_drawer.h | 6 +- code/ryzom/client/src/main_loop.cpp | 93 ++++++++++++------- code/ryzom/client/src/main_loop.h | 3 +- 4 files changed, 66 insertions(+), 38 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp index 6a21858f5..7a68f7872 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp @@ -542,7 +542,7 @@ void renderSceneScreenShot (uint left, uint right, uint top, uint bottom, uint s CCameraBackup cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight); CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, left, right, top, bottom, screenShotWidth, screenShotHeight); // sky setup are copied from main scene before rendering so no setup done here - renderAll(ClientCfg.ScreenShotFullDetail); + renderScene(ClientCfg.ScreenShotFullDetail); restoreCamera(*Scene, cbScene); restoreCamera(*SceneRoot, cbCanopy); } diff --git a/code/ryzom/client/src/landscape_poly_drawer.h b/code/ryzom/client/src/landscape_poly_drawer.h index 0012b5dcb..73d7fcadc 100644 --- a/code/ryzom/client/src/landscape_poly_drawer.h +++ b/code/ryzom/client/src/landscape_poly_drawer.h @@ -95,11 +95,11 @@ public: private: - // renderAll is called in main loop. It can called beginRenderLandscapePolyPart and renderLandscapePolyPart + // renderScene is called in main loop. It can called beginRenderLandscapePolyPart and renderLandscapePolyPart // methods. - friend void renderAll(bool); + friend void renderScene(); - // Enable stencil test and initialize function and operation of stencil at the beginning of renderAll method, + // Enable stencil test and initialize function and operation of stencil at the beginning of renderScene method, // before opaque render of canopy and main scene parts. // The eighth bit will be written with a 0 during next render to mark stencil buffer parts which will // support Shadow Volume algorithm. diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 7338493c1..6e11d3a2a 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -487,10 +487,55 @@ static void renderSkyPart(UScene::TRenderPart renderPart, TSkyMode skyMode) #endif } +struct CForceFullDetail +{ +public: + void backup() + { + maxFullDetailChar = Scene->getMaxSkeletonsInNotCLodForm(); + oldBalancingMode = Scene->getPolygonBalancingMode(); + oldSkyBalancingMode = UScene::PolygonBalancingOff; + UScene *skyScene = getSkyScene(); + if (skyScene) oldSkyBalancingMode = skyScene->getPolygonBalancingMode(); + } + void set() + { + Scene->setMaxSkeletonsInNotCLodForm(1000000); + Scene->setPolygonBalancingMode(UScene::PolygonBalancingOff); + UScene *skyScene = getSkyScene(); + if (skyScene) skyScene->setPolygonBalancingMode(UScene::PolygonBalancingOff); + } + void restore() + { + Scene->setMaxSkeletonsInNotCLodForm(maxFullDetailChar); + Scene->setPolygonBalancingMode(oldBalancingMode); + UScene *skyScene = getSkyScene(); + if (skyScene) skyScene->setPolygonBalancingMode(oldSkyBalancingMode); + } +private: + uint maxFullDetailChar; + UScene::TPolygonBalancingMode oldBalancingMode; + UScene::TPolygonBalancingMode oldSkyBalancingMode; +}; +static CForceFullDetail s_ForceFullDetail; + +void renderScene(bool forceFullDetail) +{ + if (forceFullDetail) + { + s_ForceFullDetail.backup(); + s_ForceFullDetail.set(); + } + renderScene(); + if (forceFullDetail) + { + s_ForceFullDetail.restore(); + } +} // *************************************************************************************************************************** // Render all scenes -void renderAll(bool forceFullDetail) +void renderScene() { if (ClientCfg.Bloom) { @@ -501,26 +546,6 @@ void renderAll(bool forceFullDetail) CBloomEffect::getInstance().initBloom(); } - // backup old balancing mode - uint maxFullDetailChar = Scene->getMaxSkeletonsInNotCLodForm(); - UScene *skyScene = getSkyScene(); - UScene::TPolygonBalancingMode oldBalancingMode = Scene->getPolygonBalancingMode(); - UScene::TPolygonBalancingMode oldSkyBalancingMode = UScene::PolygonBalancingOff; - if (skyScene) - { - oldSkyBalancingMode = skyScene->getPolygonBalancingMode(); - } - // disable load balancing for that frame only if asked - if (forceFullDetail) - { - Scene->setMaxSkeletonsInNotCLodForm(1000000); - Scene->setPolygonBalancingMode(UScene::PolygonBalancingOff); - if (skyScene) - { - skyScene->setPolygonBalancingMode(UScene::PolygonBalancingOff); - } - } - { H_AUTO_USE ( RZ_Client_Main_Loop_Sky_And_Weather ) @@ -649,17 +674,6 @@ void renderAll(bool forceFullDetail) // reset depth range Driver->setDepthRange(0.f, CANOPY_DEPTH_RANGE_START); - // restore load balancing mode - if (forceFullDetail) - { - Scene->setMaxSkeletonsInNotCLodForm(maxFullDetailChar); - Scene->setPolygonBalancingMode(oldBalancingMode); - if (skyScene) - { - skyScene->setPolygonBalancingMode(oldSkyBalancingMode); - } - } - // apply bloom effect if (ClientCfg.Bloom) CBloomEffect::getInstance().endBloom(); @@ -1524,7 +1538,20 @@ bool mainLoop() Scene->updateWaterEnvMaps(TimeInSec - FirstTimeInSec); } #endif - renderAll(ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail); // nb : force full detail if a screenshot is asked + + // nb : force full detail if a screenshot is asked + // todo : move outside render code + bool fullDetail = ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail; + if (fullDetail) + { + s_ForceFullDetail.backup(); + s_ForceFullDetail.set(); + } + renderScene(); + if (fullDetail) + { + s_ForceFullDetail.restore(); + } // for that frame and // tmp : display height grid diff --git a/code/ryzom/client/src/main_loop.h b/code/ryzom/client/src/main_loop.h index c8cd0af5a..f2f650b3e 100644 --- a/code/ryzom/client/src/main_loop.h +++ b/code/ryzom/client/src/main_loop.h @@ -29,7 +29,8 @@ const uint NUM_MISSION_OPTIONS = 8; bool mainLoop(); // render all -void renderAll(bool forceFullDetail = false); +void renderScene(); +void renderScene(bool forceFullDetail); void setDefaultChatWindow(CChatWindow *defaultChatWindow); void updateDayNightCycleHour(); From bfae91eb88f3e93bd9301245e9b4506744c32954 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Jul 2013 22:26:31 +0200 Subject: [PATCH 075/137] Correctly apply bloom on oversize screenshots --- .../src/interface_v3/action_handler_misc.cpp | 2 +- code/ryzom/client/src/main_loop.cpp | 47 +++++++++++++------ code/ryzom/client/src/main_loop.h | 2 +- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp index 7a68f7872..2d1fba931 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp @@ -542,7 +542,7 @@ void renderSceneScreenShot (uint left, uint right, uint top, uint bottom, uint s CCameraBackup cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight); CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, left, right, top, bottom, screenShotWidth, screenShotHeight); // sky setup are copied from main scene before rendering so no setup done here - renderScene(ClientCfg.ScreenShotFullDetail); + renderScene(ClientCfg.ScreenShotFullDetail, ClientCfg.Bloom); restoreCamera(*Scene, cbScene); restoreCamera(*SceneRoot, cbCanopy); } diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 6e11d3a2a..8cd0aea63 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -487,6 +487,8 @@ static void renderSkyPart(UScene::TRenderPart renderPart, TSkyMode skyMode) #endif } +// *************************************************************************************************************************** +// Utility to force full detail struct CForceFullDetail { public: @@ -519,8 +521,16 @@ private: }; static CForceFullDetail s_ForceFullDetail; -void renderScene(bool forceFullDetail) +void renderScene(bool forceFullDetail, bool bloom) { + if (bloom) + { + // set bloom parameters before applying bloom effect + CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); + CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); + // init bloom + CBloomEffect::getInstance().initBloom(); + } if (forceFullDetail) { s_ForceFullDetail.backup(); @@ -531,21 +541,18 @@ void renderScene(bool forceFullDetail) { s_ForceFullDetail.restore(); } + if (bloom) + { + // apply bloom effect + CBloomEffect::getInstance().endBloom(); + CBloomEffect::getInstance().endInterfacesDisplayBloom(); + } } // *************************************************************************************************************************** // Render all scenes void renderScene() { - if (ClientCfg.Bloom) - { - // set bloom parameters before applying bloom effect - CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); - CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); - // init bloom - CBloomEffect::getInstance().initBloom(); - } - { H_AUTO_USE ( RZ_Client_Main_Loop_Sky_And_Weather ) @@ -673,10 +680,6 @@ void renderScene() // reset depth range Driver->setDepthRange(0.f, CANOPY_DEPTH_RANGE_START); - - // apply bloom effect - if (ClientCfg.Bloom) - CBloomEffect::getInstance().endBloom(); } @@ -1539,6 +1542,14 @@ bool mainLoop() } #endif + if (ClientCfg.Bloom) + { + // set bloom parameters before applying bloom effect + CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); + CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); + // init bloom + CBloomEffect::getInstance().initBloom(); + } // nb : force full detail if a screenshot is asked // todo : move outside render code bool fullDetail = ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail; @@ -1547,11 +1558,19 @@ bool mainLoop() s_ForceFullDetail.backup(); s_ForceFullDetail.set(); } + + // Render scene renderScene(); + if (fullDetail) { s_ForceFullDetail.restore(); } + if (ClientCfg.Bloom) + { + // apply bloom effect + CBloomEffect::getInstance().endBloom(); + } // for that frame and // tmp : display height grid diff --git a/code/ryzom/client/src/main_loop.h b/code/ryzom/client/src/main_loop.h index f2f650b3e..82137969a 100644 --- a/code/ryzom/client/src/main_loop.h +++ b/code/ryzom/client/src/main_loop.h @@ -30,7 +30,7 @@ bool mainLoop(); // render all void renderScene(); -void renderScene(bool forceFullDetail); +void renderScene(bool forceFullDetail, bool bloom); void setDefaultChatWindow(CChatWindow *defaultChatWindow); void updateDayNightCycleHour(); From 86870d66fba492835c081a84858a5c88cce86e68 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Jul 2013 22:39:05 +0200 Subject: [PATCH 076/137] Pull weather updates out of scene render --- code/ryzom/client/src/main_loop.cpp | 129 +++++++++++++++------------- 1 file changed, 70 insertions(+), 59 deletions(-) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 8cd0aea63..95fd7086e 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -549,74 +549,82 @@ void renderScene(bool forceFullDetail, bool bloom) } } +// *************************************************************************************************************************** + +void updateWeather() +{ + H_AUTO_USE ( RZ_Client_Main_Loop_Sky_And_Weather ) + + //HeightGrid.update(Scene->getCam().getPos()); + + // update description of light cycle + updateLightDesc(); + + // server driven weather mgt + updateDBDrivenWeatherValue(); + + // Update the weather manager + updateWeatherManager(MainCam.getMatrix(), ContinentMngr.cur()); + + // compute thunder color + ThunderColor.modulateFromui(WeatherManager.getCurrWeatherState().ThunderColor, (uint) (256.f * WeatherManager.getThunderLevel())); + + // Update the lighting + LightCycleManager.setHour(DayNightCycleHour, WeatherManager, ThunderColor); + + #ifdef RENDER_CLOUDS + if (Filter3D[FilterCloud]) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Update_Cloud_Scape ); + updateClouds(); + } + #endif + + ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), MainFogState); + + // TODO: ZBuffer clear was originally before this, but should not be necessary normally. + // The anim function renders new clouds. Ensure this does not break. + // These are old-style nel clouds. + + #ifdef RENDER_CLOUDS + if (CloudScape != NULL && Filter3D[FilterCloud]) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Anim_Cloud_Scape ); + + Driver->enableFog (false); + + // Force polygon mode to filled + NL3D::UDriver::TPolygonMode oldMode = Driver->getPolygonMode(); + Driver->setPolygonMode(NL3D::UDriver::Filled); + + CloudScape->anim (DT); // WARNING this function work with screen + + Driver->enableFog (true); + + // Reset backuped polygon mode + Driver->setPolygonMode(oldMode); + } + #endif +} + // *************************************************************************************************************************** // Render all scenes void renderScene() { + if (Driver->getPolygonMode() == UDriver::Filled) { - H_AUTO_USE ( RZ_Client_Main_Loop_Sky_And_Weather ) + Driver->clearZBuffer(); + } - //HeightGrid.update(Scene->getCam().getPos()); - - // update description of light cycle - updateLightDesc(); - - // server driven weather mgt - updateDBDrivenWeatherValue(); - - // Update the weather manager - updateWeatherManager(MainCam.getMatrix(), ContinentMngr.cur()); - - // compute thunder color - ThunderColor.modulateFromui(WeatherManager.getCurrWeatherState().ThunderColor, (uint) (256.f * WeatherManager.getThunderLevel())); - - // Update the lighting - LightCycleManager.setHour(DayNightCycleHour, WeatherManager, ThunderColor); - - #ifdef RENDER_CLOUDS - if (Filter3D[FilterCloud]) + // Sky is used to clear the frame buffer now, but if in line or point polygon mode, we should draw it + if (Driver->getPolygonMode() != UDriver::Filled) + { + if (!Driver->isLost()) { - H_AUTO_USE ( RZ_Client_Main_Loop_Update_Cloud_Scape ); - updateClouds(); - } - #endif - - - ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), MainFogState); - - if (Driver->getPolygonMode() == UDriver::Filled) - { - Driver->clearZBuffer(); - } - - #ifdef RENDER_CLOUDS - if (CloudScape != NULL && Filter3D[FilterCloud]) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Anim_Cloud_Scape ); - - Driver->enableFog (false); - - // Force polygon mode to filled - NL3D::UDriver::TPolygonMode oldMode = Driver->getPolygonMode(); - Driver->setPolygonMode(NL3D::UDriver::Filled); - - CloudScape->anim (DT); // WARNING this function work with screen - - Driver->enableFog (true); - - // Reset backuped polygon mode - Driver->setPolygonMode(oldMode); - } - #endif - // Sky is used to clear the frame buffer now, but if in line or point polygon mode, we should draw it - if (Driver->getPolygonMode() != UDriver::Filled) - { - if (!Driver->isLost()) - { - Driver->clearBuffers (CRGBA(127, 127, 127)); - } + Driver->clearBuffers (CRGBA(127, 127, 127)); } } + // Update Filter Flags Scene->enableElementRender(UScene::FilterAllMeshNoVP, Filter3D[FilterMeshNoVP]); Scene->enableElementRender(UScene::FilterAllMeshVP, Filter3D[FilterMeshVP]); @@ -1541,6 +1549,9 @@ bool mainLoop() Scene->updateWaterEnvMaps(TimeInSec - FirstTimeInSec); } #endif + + // TODO: Verify that moving this out of renderScene does not negatively impact oversize screenshots. + updateWeather(); if (ClientCfg.Bloom) { From 78276ab782c52819bb7f0f4736fff41282bd2970 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Jul 2013 23:11:15 +0200 Subject: [PATCH 077/137] Make oversize screenshots be perfectly seamless --- .../src/interface_v3/action_handler_misc.cpp | 2 + code/ryzom/client/src/main_loop.cpp | 117 ++++++++++-------- code/ryzom/client/src/main_loop.h | 3 + 3 files changed, 69 insertions(+), 53 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp index 2d1fba931..7a628bb22 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp @@ -542,9 +542,11 @@ void renderSceneScreenShot (uint left, uint right, uint top, uint bottom, uint s CCameraBackup cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight); CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, left, right, top, bottom, screenShotWidth, screenShotHeight); // sky setup are copied from main scene before rendering so no setup done here + commitCameraSky(); renderScene(ClientCfg.ScreenShotFullDetail, ClientCfg.Bloom); restoreCamera(*Scene, cbScene); restoreCamera(*SceneRoot, cbCanopy); + commitCameraSky(); } // *************************************************************************** diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 95fd7086e..00a5fc092 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -352,6 +352,12 @@ void displaySceneProfiles(); // validate current dialogs (end them if the player is too far from its interlocutor) void validateDialogs(const CGameContextMenu &gcm); + +// *************************************************************************** + +enum TSkyMode { NoSky, OldSky, NewSky }; +static TSkyMode s_SkyMode = NoSky; + void preRenderNewSky () { CSky &sky = ContinentMngr.cur()->CurrentSky; @@ -362,29 +368,31 @@ void preRenderNewSky () cd.Hour = 12.f; } sky.setup(cd, SmoothedClientDate, WeatherManager.getWeatherValue(), MainFogState.FogColor, Scene->getSunDirection(), false); - // setup camera - CFrustum frust = MainCam.getFrustum(); - UCamera camSky = sky.getScene()->getCam(); - sky.getScene()->setViewport(Scene->getViewport()); - camSky.setTransformMode(UTransform::DirectMatrix); - // must have our own Far!!! - frust.Far= SkyCameraZFar; - camSky.setFrustum(frust); - CMatrix skyCameraMatrix; - skyCameraMatrix.identity(); - skyCameraMatrix= MainCam.getMatrix(); - skyCameraMatrix.setPos(CVector::Null); - camSky.setMatrix(skyCameraMatrix); } -//uint32 MainLoopCounter = 0; - +void commitCameraSky() +{ + if (s_SkyMode == NewSky) + { + CSky &sky = ContinentMngr.cur()->CurrentSky; + // setup camera + CFrustum frust = MainCam.getFrustum(); + UCamera camSky = sky.getScene()->getCam(); + sky.getScene()->setViewport(Scene->getViewport()); + camSky.setTransformMode(UTransform::DirectMatrix); + // must have our own Far!!! + frust.Far= SkyCameraZFar; + camSky.setFrustum(frust); + CMatrix skyCameraMatrix; + skyCameraMatrix.identity(); + skyCameraMatrix= MainCam.getMatrix(); + skyCameraMatrix.setPos(CVector::Null); + camSky.setMatrix(skyCameraMatrix); + } +} // *************************************************************************** -enum TSkyMode { NoSky, OldSky, NewSky }; - -// *************************************************************************** void beginRenderCanopyPart() { SceneRoot->beginPartRender(); @@ -403,17 +411,17 @@ void endRenderMainScenePart() Scene->endPartRender(true); } -void beginRenderSkyPart(TSkyMode skyMode) +void beginRenderSkyPart() { - if(skyMode == NewSky) + if (s_SkyMode == NewSky) { CSky &sky = ContinentMngr.cur()->CurrentSky; sky.getScene()->beginPartRender(); } } -void endRenderSkyPart(TSkyMode skyMode) +void endRenderSkyPart() { - if(skyMode == NewSky) + if (s_SkyMode == NewSky) { CSky &sky = ContinentMngr.cur()->CurrentSky; sky.getScene()->endPartRender(false); @@ -463,12 +471,12 @@ static void renderMainScenePart(UScene::TRenderPart renderPart) // *************************************************************************************************************************** // Render a part of the sky -static void renderSkyPart(UScene::TRenderPart renderPart, TSkyMode skyMode) +static void renderSkyPart(UScene::TRenderPart renderPart) { - nlassert(skyMode != NoSky); + nlassert(s_SkyMode != NoSky); Driver->setDepthRange(SKY_DEPTH_RANGE_START, 1.f); Driver->enableFog(false); - if (skyMode == NewSky) + if (s_SkyMode == NewSky) { CSky &sky = ContinentMngr.cur()->CurrentSky; sky.getScene()->renderPart(renderPart); @@ -605,6 +613,29 @@ void updateWeather() Driver->setPolygonMode(oldMode); } #endif + + // Update new sky + if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor) + { + if(Driver->getPolygonMode() == UDriver::Filled) + { + if (Filter3D[FilterSky]) + { + CSky &sky = ContinentMngr.cur()->CurrentSky; + if (sky.getScene()) + { + s_SkyMode = NewSky; + sky.getScene()->animate(TimeInSec-FirstTimeInSec); + // Setup the sky camera + preRenderNewSky(); + } + else + { + s_SkyMode = OldSky; + } + } + } + } } // *************************************************************************************************************************** @@ -638,36 +669,13 @@ void renderScene() if(Scene_Profile) Scene->profileNextRender(); - TSkyMode skyMode = NoSky; - if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor) - { - if(Driver->getPolygonMode() == UDriver::Filled) - { - if (Filter3D[FilterSky]) - { - CSky &sky = ContinentMngr.cur()->CurrentSky; - if (sky.getScene()) - { - skyMode = NewSky; - sky.getScene()->animate(TimeInSec-FirstTimeInSec); - // Setup the sky camera - preRenderNewSky(); - } - else - { - skyMode = OldSky; - } - } - } - } - // initialisation of polygons renderer CLandscapePolyDrawer::getInstance().beginRenderLandscapePolyPart(); // Start Part Rendering beginRenderCanopyPart(); beginRenderMainScenePart(); - beginRenderSkyPart(skyMode); + beginRenderSkyPart(); // Render part // WARNING: always must begin rendering with at least UScene::RenderOpaque, // else dynamic shadows won't work @@ -677,12 +685,12 @@ void renderScene() // render of polygons on landscape CLandscapePolyDrawer::getInstance().renderLandscapePolyPart(); - if (skyMode != NoSky) renderSkyPart((UScene::TRenderPart) (UScene::RenderOpaque | UScene::RenderTransparent), skyMode); + if (s_SkyMode != NoSky) renderSkyPart((UScene::TRenderPart) (UScene::RenderOpaque | UScene::RenderTransparent)); renderCanopyPart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare)); renderMainScenePart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare)); - if (skyMode == NewSky) renderSkyPart(UScene::RenderFlare, skyMode); + if (s_SkyMode == NewSky) renderSkyPart(UScene::RenderFlare); // End Part Rendering - endRenderSkyPart(skyMode); + endRenderSkyPart(); endRenderMainScenePart(); endRenderCanopyPart(); @@ -1550,7 +1558,7 @@ bool mainLoop() } #endif - // TODO: Verify that moving this out of renderScene does not negatively impact oversize screenshots. + // Update weather updateWeather(); if (ClientCfg.Bloom) @@ -1569,6 +1577,9 @@ bool mainLoop() s_ForceFullDetail.backup(); s_ForceFullDetail.set(); } + + // Commit camera changes to the sky camera + commitCameraSky(); // Render scene renderScene(); diff --git a/code/ryzom/client/src/main_loop.h b/code/ryzom/client/src/main_loop.h index 82137969a..b44ad764a 100644 --- a/code/ryzom/client/src/main_loop.h +++ b/code/ryzom/client/src/main_loop.h @@ -33,6 +33,9 @@ void renderScene(); void renderScene(bool forceFullDetail, bool bloom); void setDefaultChatWindow(CChatWindow *defaultChatWindow); +// Commit sky scene camera for rendering +void commitCameraSky(); + void updateDayNightCycleHour(); From 32e3da752fe3de6ec6bfb4cbf0b10040adc3f425 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 4 Jul 2013 23:41:46 +0200 Subject: [PATCH 078/137] Some more cleanup --- code/ryzom/client/src/main_loop.cpp | 95 ++++++++++++++++------------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 00a5fc092..6925533a8 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -559,6 +559,48 @@ void renderScene(bool forceFullDetail, bool bloom) // *************************************************************************************************************************** +void updateWaterEnvMap() +{ + #ifdef USE_WATER_ENV_MAP + if (WaterEnvMapRefCount > 0) // water env map needed + { + if (!WaterEnvMap) + { + CSky &sky = ContinentMngr.cur()->CurrentSky; + if (sky.getScene()) + { + nlassert(WaterEnvMapSkyCam.empty()); + WaterEnvMapSkyCam = sky.getScene()->createCamera(); // deleted in unselect + nlassert(WaterEnvMapCanopyCam.empty()); + WaterEnvMapCanopyCam = SceneRoot->createCamera(); // deleted in unselect + // Create water env map if not already created + WaterEnvMap = Driver->createWaterEnvMap(); + if(WaterEnvMap) + { + WaterEnvMap->init(128, 256, ClientCfg.WaterEnvMapUpdateTime); + WaterEnvMap->setWaterEnvMapRenderCallback(&WaterEnvMapRdr); + Scene->setWaterEnvMap(WaterEnvMap); + } + } + } + WaterEnvMapRdr.CurrDate = SmoothedClientDate; + WaterEnvMapRdr.AnimationDate = SmoothedClientDate; + if (ClientCfg.R2EDEnabled && R2::getEditor().getFixedLighting()) + { + WaterEnvMapRdr.CurrDate.Hour = 12.f; + } + WaterEnvMapRdr.CurrFogColor = MainFogState.FogColor; + WaterEnvMapRdr.CurrTime = TimeInSec - FirstTimeInSec; + WaterEnvMapRdr.CurrWeather = WeatherManager.getWeatherValue(); + CSky &sky = ContinentMngr.cur()->CurrentSky; + WaterEnvMap->setAlpha(sky.getWaterEnvMapAlpha()); + Scene->updateWaterEnvMaps(TimeInSec - FirstTimeInSec); + } + #endif +} + +// *************************************************************************************************************************** + void updateWeather() { H_AUTO_USE ( RZ_Client_Main_Loop_Sky_And_Weather ) @@ -999,6 +1041,14 @@ bool mainLoop() while( !UserEntity->permanentDeath() && !game_exit ) { + // If an action handler execute. NB: MUST BE DONE BEFORE ANY THING ELSE PROFILE CRASH!!!!!!!!!!!!!!!!! + testLaunchProfile(); + + // Test and may run a VBLock profile (only once) + testLaunchProfileVBLock(); + + // Start Bench + H_AUTO_USE ( RZ_Client_Main_Loop ) if (isBGDownloadEnabled()) { @@ -1073,11 +1123,6 @@ bool mainLoop() } { - // If an action handler execute. NB: MUST BE DONE BEFORE ANY THING ELSE PROFILE CRASH!!!!!!!!!!!!!!!!! - testLaunchProfile(); - - // Test and may run a VBLock profile (only once) - testLaunchProfileVBLock(); // Stop the Outgame music, with fade effect outgameFader.fade(); @@ -1085,10 +1130,6 @@ bool mainLoop() // update quit feature updateGameQuitting(); - // Start Bench - H_AUTO_USE ( RZ_Client_Main_Loop ) - - // update module manager NLNET::IModuleManager::getInstance().updateModules(); @@ -1523,40 +1564,8 @@ bool mainLoop() // Render if(Render) { - #ifdef USE_WATER_ENV_MAP - if (WaterEnvMapRefCount > 0) // water env map needed - { - if (!WaterEnvMap) - { - CSky &sky = ContinentMngr.cur()->CurrentSky; - if (sky.getScene()) - { - WaterEnvMapSkyCam = sky.getScene()->createCamera(); // deleted in unselect - WaterEnvMapCanopyCam = SceneRoot->createCamera(); // deleted in unselect - // Create water env map if not already created - WaterEnvMap = Driver->createWaterEnvMap(); - if(WaterEnvMap) - { - WaterEnvMap->init(128, 256, ClientCfg.WaterEnvMapUpdateTime); - WaterEnvMap->setWaterEnvMapRenderCallback(&WaterEnvMapRdr); - Scene->setWaterEnvMap(WaterEnvMap); - } - } - } - WaterEnvMapRdr.CurrDate = SmoothedClientDate; - WaterEnvMapRdr.AnimationDate = SmoothedClientDate; - if (ClientCfg.R2EDEnabled && R2::getEditor().getFixedLighting()) - { - WaterEnvMapRdr.CurrDate.Hour = 12.f; - } - WaterEnvMapRdr.CurrFogColor = MainFogState.FogColor; - WaterEnvMapRdr.CurrTime = TimeInSec - FirstTimeInSec; - WaterEnvMapRdr.CurrWeather = WeatherManager.getWeatherValue(); - CSky &sky = ContinentMngr.cur()->CurrentSky; - WaterEnvMap->setAlpha(sky.getWaterEnvMapAlpha()); - Scene->updateWaterEnvMaps(TimeInSec - FirstTimeInSec); - } - #endif + // Update water env map (happens when continent changed etc) + updateWaterEnvMap(); // Update weather updateWeather(); From 5e5cfba0356b0c71d9abad1ec443d7dc0602f0e2 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 5 Jul 2013 00:17:09 +0200 Subject: [PATCH 079/137] Some necessary changes to camera setting, re #43 --- .../src/interface_v3/action_handler_misc.cpp | 4 +- code/ryzom/client/src/main_loop.cpp | 79 +++++++++++++------ code/ryzom/client/src/main_loop.h | 2 +- 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp index 7a628bb22..779d58fc4 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp @@ -541,12 +541,12 @@ void renderSceneScreenShot (uint left, uint right, uint top, uint bottom, uint s { CCameraBackup cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight); CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, left, right, top, bottom, screenShotWidth, screenShotHeight); + commitCamera(); // sky setup are copied from main scene before rendering so no setup done here - commitCameraSky(); renderScene(ClientCfg.ScreenShotFullDetail, ClientCfg.Bloom); restoreCamera(*Scene, cbScene); restoreCamera(*SceneRoot, cbCanopy); - commitCameraSky(); + commitCamera(); } // *************************************************************************** diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 6925533a8..38752f77d 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -370,8 +370,9 @@ void preRenderNewSky () sky.setup(cd, SmoothedClientDate, WeatherManager.getWeatherValue(), MainFogState.FogColor, Scene->getSunDirection(), false); } -void commitCameraSky() +void commitCamera() { + // Set the sky camera if (s_SkyMode == NewSky) { CSky &sky = ContinentMngr.cur()->CurrentSky; @@ -389,6 +390,17 @@ void commitCameraSky() skyCameraMatrix.setPos(CVector::Null); camSky.setMatrix(skyCameraMatrix); } + + // Set The Root Camera + UCamera camRoot = SceneRoot->getCam(); + if(!camRoot.empty()) + { + // Update Camera Position/Rotation. + //camRoot.setPos(View.currentViewPos()); + //camRoot.setRotQuat(View.currentViewQuat()); + camRoot.setTransformMode(UTransformable::DirectMatrix); // FIXME + camRoot.setMatrix(MainCam.getMatrix()); + } } // *************************************************************************** @@ -439,14 +451,6 @@ static void renderCanopyPart(UScene::TRenderPart renderPart) ContinentMngr.getFogState(CanopyFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), RootFogState); RootFogState.setupInDriver(*Driver); - // Set The Root Camera - UCamera camRoot = SceneRoot->getCam(); - if(!camRoot.empty()) - { - // Update Camera Position/Rotation. - camRoot.setPos(View.currentViewPos()); - camRoot.setRotQuat(View.currentViewQuat()); - } // Render the root scene SceneRoot->renderPart(renderPart); } @@ -1364,9 +1368,17 @@ bool mainLoop() // Update Camera Position/Orientation. CVector currViewPos = View.currentViewPos(); + MainCam.setTransformMode(UTransformable::RotQuat); MainCam.setPos(currViewPos); MainCam.setRotQuat(View.currentViewQuat()); - if (StereoDisplay) StereoDisplay->updateCamera(0, &MainCam); + if (StereoDisplay) + { + StereoDisplay->updateCamera(0, &MainCam); + if (SceneRoot) + { + StereoDisplay->updateCamera(1, &SceneRoot->getCam()); + } + } // see if camera is below water (useful for sort order) if (ContinentMngr.cur()) @@ -1457,9 +1469,6 @@ bool mainLoop() } - ////////////////////////// - // RENDER THE FRAME 3D // - ////////////////////////// if (!ClientCfg.Light) { CClientDate newDate(RT.getRyzomDay(), DayNightCycleHour); @@ -1546,9 +1555,6 @@ bool mainLoop() } } - // Set the matrix in 3D Mode. - Driver->setMatrixMode3D(MainCam); - // R2ED pre render update if (ClientCfg.R2EDEnabled) @@ -1556,11 +1562,8 @@ bool mainLoop() R2::getEditor().updateBeforeRender(); } - - // Position the camera to prepare the render if (!ClientCfg.Light) { - // Render if(Render) { @@ -1569,7 +1572,42 @@ bool mainLoop() // Update weather updateWeather(); + } + } + + ////////////////////////// + // RENDER THE FRAME 3D // + ////////////////////////// + if (StereoDisplay) + { + // modify cameras for stereo display + const CViewport &vp = StereoDisplay->getCurrentViewport(); + Driver->setViewport(vp); + nlassert(Scene); + Scene->setViewport(vp); + if (SceneRoot) + { + SceneRoot->setViewport(vp); + } + MainCam.setTransformMode(UTransformable::DirectMatrix); + StereoDisplay->getCurrentMatrix(0, &MainCam); + StereoDisplay->getCurrentFrustum(0, &MainCam); + if (SceneRoot) + { + // matrix updated during commitCamera from maincam + StereoDisplay->getCurrentFrustum(1, &SceneRoot->getCam()); + } + } + + // Commit camera changes + commitCamera(); + + if (!ClientCfg.Light) + { + // Render + if(Render) + { if (ClientCfg.Bloom) { // set bloom parameters before applying bloom effect @@ -1586,9 +1624,6 @@ bool mainLoop() s_ForceFullDetail.backup(); s_ForceFullDetail.set(); } - - // Commit camera changes to the sky camera - commitCameraSky(); // Render scene renderScene(); diff --git a/code/ryzom/client/src/main_loop.h b/code/ryzom/client/src/main_loop.h index b44ad764a..21f64d37e 100644 --- a/code/ryzom/client/src/main_loop.h +++ b/code/ryzom/client/src/main_loop.h @@ -34,7 +34,7 @@ void renderScene(bool forceFullDetail, bool bloom); void setDefaultChatWindow(CChatWindow *defaultChatWindow); // Commit sky scene camera for rendering -void commitCameraSky(); +void commitCamera(); void updateDayNightCycleHour(); From 59edf6ea138028fc41678ccde6baab7415a68a53 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 5 Jul 2013 00:47:17 +0200 Subject: [PATCH 080/137] Move some more updates out of the render code, see #43 --- code/ryzom/client/src/main_loop.cpp | 93 +++++++++++++++-------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 38752f77d..e9f6312e8 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1575,9 +1575,9 @@ bool mainLoop() } } - ////////////////////////// - // RENDER THE FRAME 3D // - ////////////////////////// + /////////////////// + // SETUP CAMERAS // + /////////////////// if (StereoDisplay) { @@ -1602,6 +1602,10 @@ bool mainLoop() // Commit camera changes commitCamera(); + + ////////////////////////// + // RENDER THE FRAME 3D // + ////////////////////////// if (!ClientCfg.Light) { @@ -1711,17 +1715,6 @@ bool mainLoop() // Display some things not in the scene like the name, the entity path, etc. EntitiesMngr.updatePostRender(); - // R2ED pre render update - if (ClientCfg.R2EDEnabled) - { - // IMPORTANT : this should be called after CEntitiesMngr::updatePostRender() because - // entity may be added / removed there ! - R2::getEditor().updateAfterRender(); - } - - // Update FXs (remove them). - FXMngr.update(); - // Render the stat graphs if needed { H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) @@ -1738,6 +1731,7 @@ bool mainLoop() Driver->drawQuad(0, 0, 1, 1, ThunderColor); // TODO : boris : add sound here ! + // Needs more explosions } // Update the contextual menu @@ -1827,39 +1821,50 @@ bool mainLoop() Driver->drawBitmap(x/(float)ClientCfg.Width, y/(float)ClientCfg.Height, width/(float)ClientCfg.Width, height/(float)ClientCfg.Height, *LogoBitmaps[i]); } } - - // FPS - { - static TTicks oldTick = CTime::getPerformanceTime(); - TTicks newTick = CTime::getPerformanceTime(); - double deltaTime = CTime::ticksToSecond (newTick-oldTick); - oldTick = newTick; - smoothFPS.addValue((float)deltaTime); - moreSmoothFPS.addValue((float)deltaTime); - deltaTime = smoothFPS.getSmoothValue (); - if (deltaTime > 0.0) - { - CCDBNodeLeaf*pNL = NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:FPS"); - pNL->setValue64((sint64)(1.f/deltaTime)); - } - } - - // Detect disconnection / server down: display information text - // but keep the rendering so that the player can remember where he is - // and what he was doing. He can't move because the connection quality returns false. - - if ((connectionState == CNetworkConnection::Disconnect) && (lastConnectionState != CNetworkConnection::Disconnect) && (!FarTP.isFarTPInProgress())) - { - UserControls.stopFreeLook(); // let the player click on Exit - pIMinstance->messageBoxWithHelp(CI18N::get("uiDisconnected")); - - // If we have started a Far TP sequence and are waiting for onServerQuitOK() - // from the EGS, resume the sequence because the EGS is down and won't reply. - FarTP.onServerQuitOk(); - } } } + // FPS + { + static TTicks oldTick = CTime::getPerformanceTime(); + TTicks newTick = CTime::getPerformanceTime(); + double deltaTime = CTime::ticksToSecond (newTick-oldTick); + oldTick = newTick; + smoothFPS.addValue((float)deltaTime); + moreSmoothFPS.addValue((float)deltaTime); + deltaTime = smoothFPS.getSmoothValue (); + if (deltaTime > 0.0) + { + CCDBNodeLeaf*pNL = NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:FPS"); + pNL->setValue64((sint64)(1.f/deltaTime)); + } + } + + // R2ED post render update + if (ClientCfg.R2EDEnabled) + { + // IMPORTANT : this should be called after CEntitiesMngr::updatePostRender() because + // entity may be added / removed there ! + R2::getEditor().updateAfterRender(); + } + + // Update FXs (remove them). + FXMngr.update(); + + // Detect disconnection / server down: display information text + // but keep the rendering so that the player can remember where he is + // and what he was doing. He can't move because the connection quality returns false. + + if ((connectionState == CNetworkConnection::Disconnect) && (lastConnectionState != CNetworkConnection::Disconnect) && (!FarTP.isFarTPInProgress())) + { + UserControls.stopFreeLook(); // let the player click on Exit + pIMinstance->messageBoxWithHelp(CI18N::get("uiDisconnected")); + + // If we have started a Far TP sequence and are waiting for onServerQuitOK() + // from the EGS, resume the sequence because the EGS is down and won't reply. + FarTP.onServerQuitOk(); + } + // Yoyo: MovieShooter. if(MovieShooterSaving) { From 541f75920b1efb58ede28926ea9033eb3fc67df9 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 5 Jul 2013 02:04:34 +0200 Subject: [PATCH 081/137] Init/release VR interfaces in ryzom client, ref #43 --- code/nel/include/nel/3d/stereo_debugger.h | 4 + code/nel/src/3d/stereo_debugger.cpp | 118 ++++++++++++++-------- code/nel/src/3d/stereo_ovr.cpp | 13 +-- code/ryzom/client/src/camera.cpp | 2 +- code/ryzom/client/src/client_cfg.cpp | 7 ++ code/ryzom/client/src/client_cfg.h | 5 + code/ryzom/client/src/global.cpp | 4 +- code/ryzom/client/src/global.h | 7 +- code/ryzom/client/src/init.cpp | 66 ++++++++++++ code/ryzom/client/src/main_loop.cpp | 2 +- code/ryzom/client/src/release.cpp | 10 ++ 11 files changed, 185 insertions(+), 53 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_debugger.h b/code/nel/include/nel/3d/stereo_debugger.h index b94ffaf6b..b07a9630c 100644 --- a/code/nel/include/nel/3d/stereo_debugger.h +++ b/code/nel/include/nel/3d/stereo_debugger.h @@ -65,6 +65,10 @@ public: /// Sets driver and generates necessary render targets virtual void setDriver(NL3D::UDriver *driver); + void releaseTextures(); + void initTextures(); + void setTextures(); + void verifyTextures(); /// Gets the required screen resolution for this device virtual bool getScreenResolution(uint &width, uint &height); diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index c24bcdc93..036cb7e1b 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -96,21 +96,13 @@ CStereoDebugger::CStereoDebugger() : m_Driver(NULL), m_Stage(0), m_SubStage(0), CStereoDebugger::~CStereoDebugger() { + releaseTextures(); + if (!m_Mat.empty()) { - m_Mat.getObjectPtr()->setTexture(0, NULL); - m_Mat.getObjectPtr()->setTexture(1, NULL); m_Driver->deleteMaterial(m_Mat); } - delete m_LeftTexU; - m_LeftTexU = NULL; - m_LeftTex = NULL; // CSmartPtr - - delete m_RightTexU; - m_RightTexU = NULL; - m_RightTex = NULL; // CSmartPtr - delete m_PixelProgram; m_PixelProgram = NULL; @@ -143,33 +135,7 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) { m_Driver = driver; - // todo: handle reso change! - - uint32 width, height; - driver->getWindowSize(width, height); - - m_LeftTex = new CTextureBloom(); - m_LeftTex->setRenderTarget(true); - m_LeftTex->setReleasable(false); - m_LeftTex->resize(width, height); - m_LeftTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); - m_LeftTex->setWrapS(ITexture::Clamp); - m_LeftTex->setWrapT(ITexture::Clamp); - drvInternal->setupTexture(*m_LeftTex); - m_LeftTexU = new CTextureUser(m_LeftTex); - nlassert(!drvInternal->isTextureRectangle(m_LeftTex)); // not allowed - - m_RightTex = new CTextureBloom(); - m_RightTex->setRenderTarget(true); - m_RightTex->setReleasable(false); - m_RightTex->resize(width, height); - m_RightTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); - m_RightTex->setWrapS(ITexture::Clamp); - m_RightTex->setWrapT(ITexture::Clamp); - drvInternal->setupTexture(*m_RightTex); - m_RightTexU = new CTextureUser(m_RightTex); - nlassert(!drvInternal->isTextureRectangle(m_RightTex)); // not allowed - + initTextures(); m_Mat = m_Driver->createMaterial(); m_Mat.initUnlit(); @@ -182,9 +148,8 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) mat->setZWrite(false); mat->setZFunc(CMaterial::always); mat->setDoubleSided(true); - mat->setTexture(0, m_LeftTex); - mat->setTexture(1, m_RightTex); - + + setTextures(); m_QuadUV.V0 = CVector(0.f, 0.f, 0.5f); m_QuadUV.V1 = CVector(1.f, 0.f, 0.5f); @@ -198,6 +163,79 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) } } +void CStereoDebugger::releaseTextures() +{ + if (!m_Mat.empty()) + { + m_Mat.getObjectPtr()->setTexture(0, NULL); + m_Mat.getObjectPtr()->setTexture(1, NULL); + m_Driver->deleteMaterial(m_Mat); + } + + delete m_LeftTexU; + m_LeftTexU = NULL; + m_LeftTex = NULL; // CSmartPtr + + delete m_RightTexU; + m_RightTexU = NULL; + m_RightTex = NULL; // CSmartPtr +} + +void CStereoDebugger::initTextures() +{ + uint32 width, height; + m_Driver->getWindowSize(width, height); + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + + m_LeftTex = new CTextureBloom(); + m_LeftTex->setRenderTarget(true); + m_LeftTex->setReleasable(false); + m_LeftTex->resize(width, height); + m_LeftTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_LeftTex->setWrapS(ITexture::Clamp); + m_LeftTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_LeftTex); + m_LeftTexU = new CTextureUser(m_LeftTex); + nlassert(!drvInternal->isTextureRectangle(m_LeftTex)); // not allowed + + m_RightTex = new CTextureBloom(); + m_RightTex->setRenderTarget(true); + m_RightTex->setReleasable(false); + m_RightTex->resize(width, height); + m_RightTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_RightTex->setWrapS(ITexture::Clamp); + m_RightTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_RightTex); + m_RightTexU = new CTextureUser(m_RightTex); + nlassert(!drvInternal->isTextureRectangle(m_RightTex)); // not allowed +} + +void CStereoDebugger::setTextures() +{ + NL3D::CMaterial *mat = m_Mat.getObjectPtr(); + mat->setTexture(0, m_LeftTex); + mat->setTexture(1, m_RightTex); +} + +void CStereoDebugger::verifyTextures() +{ + if (m_Driver) + { + uint32 width, height; + m_Driver->getWindowSize(width, height); + if (m_LeftTex->getWidth() != width + || m_RightTex->getWidth() != width + || m_LeftTex->getHeight() != height + || m_RightTex->getHeight() != height) + { + nldebug("Rebuild textures"); + releaseTextures(); + initTextures(); + setTextures(); + } + } +} + /// Gets the required screen resolution for this device bool CStereoDebugger::getScreenResolution(uint &width, uint &height) { diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index e58e82892..36f48c7e3 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -233,11 +233,6 @@ CStereoOVR::~CStereoOVR() void CStereoOVR::setDriver(NL3D::UDriver *driver) { - // Do not allow weird stuff. - uint32 width, height; - driver->getWindowSize(width, height); - nlassert(width == m_DevicePtr->HMDInfo.HResolution); - nlassert(height == m_DevicePtr->HMDInfo.VResolution); nlassert(!m_PixelProgram); NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); @@ -264,7 +259,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) m_BarrelTex = new CTextureBloom(); // lol bloom m_BarrelTex->setRenderTarget(true); m_BarrelTex->setReleasable(false); - m_BarrelTex->resize(width, height); + m_BarrelTex->resize(m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); m_BarrelTex->setWrapS(ITexture::Clamp); m_BarrelTex->setWrapT(ITexture::Clamp); @@ -358,6 +353,12 @@ void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera) bool CStereoOVR::nextPass() { + // Do not allow weird stuff. + uint32 width, height; + m_Driver->getWindowSize(width, height); + nlassert(width == m_DevicePtr->HMDInfo.HResolution); + nlassert(height == m_DevicePtr->HMDInfo.VResolution); + switch (m_Stage) { case 0: diff --git a/code/ryzom/client/src/camera.cpp b/code/ryzom/client/src/camera.cpp index 66aac6f76..c409f9e58 100644 --- a/code/ryzom/client/src/camera.cpp +++ b/code/ryzom/client/src/camera.cpp @@ -17,7 +17,7 @@ #include #include "camera.h" -#include +#include #include "global.h" #include "misc.h" diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp index 5bbd90e01..67016de37 100644 --- a/code/ryzom/client/src/client_cfg.cpp +++ b/code/ryzom/client/src/client_cfg.cpp @@ -302,6 +302,10 @@ CClientConfig::CClientConfig() Contrast = 0.f; // Default Monitor Contrast. Luminosity = 0.f; // Default Monitor Luminosity. Gamma = 0.f; // Default Monitor Gamma. + + VREnable = false; + VRDisplayDevice = "Auto"; + VRDisplayDeviceId = ""; Local = false; // Default is Net Mode. FSHost = ""; // Default Host. @@ -847,6 +851,9 @@ void CClientConfig::setValues() else cfgWarning ("Default value used for 'Driver3D' !!!"); + READ_BOOL_FV(VREnable) + READ_STRING_FV(VRDisplayDevice) + READ_STRING_FV(VRDisplayDeviceId) //////////// // INPUTS // diff --git a/code/ryzom/client/src/client_cfg.h b/code/ryzom/client/src/client_cfg.h index c76cfaf36..44ddf3891 100644 --- a/code/ryzom/client/src/client_cfg.h +++ b/code/ryzom/client/src/client_cfg.h @@ -146,6 +146,11 @@ struct CClientConfig /// Monitor Gamma [-1 ~ 1], default 0 float Gamma; + // VR + bool VREnable; + std::string VRDisplayDevice; + std::string VRDisplayDeviceId; + /// Client in Local mode or not. bool Local; /// Host. diff --git a/code/ryzom/client/src/global.cpp b/code/ryzom/client/src/global.cpp index bb60f5c04..2e3ba875a 100644 --- a/code/ryzom/client/src/global.cpp +++ b/code/ryzom/client/src/global.cpp @@ -26,8 +26,8 @@ using namespace NLMISC; // *************************************************************************** // Main System NL3D::UDriver *Driver = 0; // The main 3D Driver -NL3D::CStereoOVR *StereoDisplay = NULL; // Stereo display -NL3D::CStereoOVR *StereoHMD = NULL; // Head mount display +NL3D::IStereoDisplay *StereoDisplay = NULL; // Stereo display +NL3D::IStereoHMD *StereoHMD = NULL; // Head mount display CSoundManager *SoundMngr = 0; // the sound manager NL3D::UMaterial GenericMat; // Generic Material NL3D::UTextContext *TextContext = 0; // Context for all the text in the client. diff --git a/code/ryzom/client/src/global.h b/code/ryzom/client/src/global.h index 6ec3db7ec..9e5a294ae 100644 --- a/code/ryzom/client/src/global.h +++ b/code/ryzom/client/src/global.h @@ -40,7 +40,8 @@ namespace NL3D class UMaterial; class UTextContext; class UWaterEnvMap; - class CStereoOVR; + class IStereoDisplay; + class IStereoHMD; } class CEntityAnimationManager; @@ -78,8 +79,8 @@ const float ExtraZoneLoadingVision = 100.f; // *************************************************************************** // Main System extern NL3D::UDriver *Driver; // The main 3D Driver -extern NL3D::CStereoOVR *StereoDisplay; // Stereo display -extern NL3D::CStereoOVR *StereoHMD; +extern NL3D::IStereoDisplay *StereoDisplay; // Stereo display +extern NL3D::IStereoHMD *StereoHMD; // Head mount display extern CSoundManager *SoundMngr; // the sound manager extern NL3D::UMaterial GenericMat; // Generic Material extern NL3D::UTextContext *TextContext; // Context for all the text in the client. diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 9d515fabd..4c5cd1eca 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -39,6 +39,7 @@ #include "nel/3d/u_driver.h" #include "nel/3d/u_text_context.h" #include "nel/3d/u_shape_bank.h" +#include "nel/3d/stereo_hmd.h" // Net. #include "nel/net/email.h" // Ligo. @@ -46,6 +47,7 @@ // Std. #include +#include // Game Share #include "game_share/ryzom_version.h" // Client @@ -792,6 +794,59 @@ void prelogInit() // Check driver version checkDriverVersion(); + // Initialize the VR devices (even more important than the most important part of the client) + nmsg = "Initializing VR devices..."; + ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) ); + if (ClientCfg.VREnable) + { + nldebug("VR [C]: Enabled"); + std::vector devices; + IStereoDisplay::listDevices(devices); + for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) + { + std::stringstream name; + name << std::string("[") << it->Serial << "] [" << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName << "]"; + nlinfo("VR [C]: Stereo Display: %s", name.str().c_str()); + } + CStereoDeviceInfo *deviceInfo = NULL; + if (ClientCfg.VRDisplayDevice == std::string("Auto") + && devices.begin() != devices.end()) + { + deviceInfo = &devices[0]; + } + else + { + for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) + { + std::stringstream name; + name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName; + if (name.str() == ClientCfg.VRDisplayDevice) + deviceInfo = &(*it); + if (ClientCfg.VRDisplayDeviceId == it->Serial) + break; + } + } + if (deviceInfo) + { + nlinfo("VR [C]: Create VR stereo display device"); + StereoDisplay = IStereoDisplay::createDevice(*deviceInfo); + if (StereoDisplay) + { + if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD) + { + nlinfo("VR [C]: Stereo display device is a HMD"); + StereoHMD = static_cast(StereoDisplay); + } + } + } + } + else + { + nldebug("VR [C]: NOT Enabled"); + } + IStereoDisplay::releaseUnusedLibraries(); + + // Create the driver (most important part of the client). nmsg = "Creating 3d driver..."; ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) ); @@ -860,6 +915,11 @@ void prelogInit() Driver->setSwapVBLInterval(1); else Driver->setSwapVBLInterval(0); + + if (StereoDisplay) + { + // override mode TODO + } // Set the mode of the window. if (!Driver->setDisplay (mode, false)) @@ -1102,6 +1162,12 @@ void prelogInit() // init bloom effect CBloomEffect::getInstance().init(driver != UDriver::Direct3d); + + if (StereoDisplay) + { + // Init stereo display resources + StereoDisplay->setDriver(Driver); + } nlinfo ("PROFILE: %d seconds for prelogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000); diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index e9f6312e8..ce42b3d8e 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -42,7 +42,7 @@ #include "nel/3d/u_material.h" #include "nel/3d/u_instance_material.h" #include "nel/3d/u_cloud_scape.h" -#include "nel/3d/stereo_ovr.h" +#include "nel/3d/stereo_hmd.h" // game share #include "game_share/brick_types.h" #include "game_share/light_cycle.h" diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index 0c975aebe..eea5c6ef9 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -35,6 +35,7 @@ #include "nel/3d/u_scene.h" #include "nel/3d/u_visual_collision_manager.h" #include "nel/3d/u_shape_bank.h" +#include "nel/3d/stereo_hmd.h" // Client #include "global.h" #include "release.h" @@ -559,6 +560,15 @@ void release() CEntityAnimationManager::delInstance(); EAM= NULL; + nldebug("VR [C]: VR Shutting down"); + if (StereoDisplay) + { + delete StereoDisplay; + StereoDisplay = NULL; + StereoHMD = NULL; + } + IStereoDisplay::releaseAllLibraries(); + // Delete the driver. if(Driver) { From c3f6f5b8ffb5b838f0ead3ab87c52c7e0a4b305f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 5 Jul 2013 02:38:56 +0200 Subject: [PATCH 082/137] Put stereo render loop inside ryzom client main loop, see #43 --- code/nel/src/3d/stereo_ovr.cpp | 13 +- code/ryzom/client/src/main_loop.cpp | 985 +++++++++++++++------------- 2 files changed, 536 insertions(+), 462 deletions(-) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 36f48c7e3..e7e31d557 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -438,8 +438,17 @@ void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const CMatrix translate; if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f)); else translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f)); - camera->setTransformMode(NL3D::UTransformable::DirectMatrix); - camera->setMatrix(m_CameraMatrix[cid] * translate); + CMatrix mat = m_CameraMatrix[cid] * translate; + if (camera->getTransformMode() == NL3D::UTransformable::RotQuat) + { + camera->setPos(mat.getPos()); + camera->setRotQuat(mat.getRot()); + } + else + { + // camera->setTransformMode(NL3D::UTransformable::DirectMatrix); + camera->setMatrix(mat); + } } bool CStereoOVR::wantClear() diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index ce42b3d8e..095236ef0 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -398,8 +398,8 @@ void commitCamera() // Update Camera Position/Rotation. //camRoot.setPos(View.currentViewPos()); //camRoot.setRotQuat(View.currentViewQuat()); - camRoot.setTransformMode(UTransformable::DirectMatrix); // FIXME - camRoot.setMatrix(MainCam.getMatrix()); + camRoot.setPos(MainCam.getPos()); + camRoot.setRotQuat(MainCam.getRotQuat()); } } @@ -533,6 +533,30 @@ private: }; static CForceFullDetail s_ForceFullDetail; +void clearBuffers() +{ + if (Render) + { + if (Driver->getPolygonMode() == UDriver::Filled) + { + Driver->clearZBuffer(); + } + + // Sky is used to clear the frame buffer now, but if in line or point polygon mode, we should draw it + if (Driver->getPolygonMode() != UDriver::Filled) + { + if (!Driver->isLost()) + { + Driver->clearBuffers (CRGBA(127, 127, 127)); + } + } + } + else + { + Driver->clearBuffers(ClientCfg.BGColor); + } +} + void renderScene(bool forceFullDetail, bool bloom) { if (bloom) @@ -548,6 +572,7 @@ void renderScene(bool forceFullDetail, bool bloom) s_ForceFullDetail.backup(); s_ForceFullDetail.set(); } + clearBuffers(); renderScene(); if (forceFullDetail) { @@ -688,20 +713,6 @@ void updateWeather() // Render all scenes void renderScene() { - if (Driver->getPolygonMode() == UDriver::Filled) - { - Driver->clearZBuffer(); - } - - // Sky is used to clear the frame buffer now, but if in line or point polygon mode, we should draw it - if (Driver->getPolygonMode() != UDriver::Filled) - { - if (!Driver->isLost()) - { - Driver->clearBuffers (CRGBA(127, 127, 127)); - } - } - // Update Filter Flags Scene->enableElementRender(UScene::FilterAllMeshNoVP, Filter3D[FilterMeshNoVP]); Scene->enableElementRender(UScene::FilterAllMeshVP, Filter3D[FilterMeshVP]); @@ -1371,6 +1382,10 @@ bool mainLoop() MainCam.setTransformMode(UTransformable::RotQuat); MainCam.setPos(currViewPos); MainCam.setRotQuat(View.currentViewQuat()); + if (StereoHMD) + { + // ... + } if (StereoDisplay) { StereoDisplay->updateCamera(0, &MainCam); @@ -1575,498 +1590,548 @@ bool mainLoop() } } - /////////////////// - // SETUP CAMERAS // - /////////////////// - - if (StereoDisplay) + uint i = 0; + uint bloomStage = 0; + while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) { - // modify cameras for stereo display - const CViewport &vp = StereoDisplay->getCurrentViewport(); - Driver->setViewport(vp); - nlassert(Scene); - Scene->setViewport(vp); - if (SceneRoot) - { - SceneRoot->setViewport(vp); - } - MainCam.setTransformMode(UTransformable::DirectMatrix); - StereoDisplay->getCurrentMatrix(0, &MainCam); - StereoDisplay->getCurrentFrustum(0, &MainCam); - if (SceneRoot) - { - // matrix updated during commitCamera from maincam - StereoDisplay->getCurrentFrustum(1, &SceneRoot->getCam()); - } - } + ++i; + /////////////////// + // SETUP CAMERAS // + /////////////////// - // Commit camera changes - commitCamera(); - - ////////////////////////// - // RENDER THE FRAME 3D // - ////////////////////////// - - if (!ClientCfg.Light) - { - // Render - if(Render) + if (StereoDisplay) { - if (ClientCfg.Bloom) + // modify cameras for stereo display + const CViewport &vp = StereoDisplay->getCurrentViewport(); + Driver->setViewport(vp); + nlassert(Scene); + Scene->setViewport(vp); + if (SceneRoot) { - // set bloom parameters before applying bloom effect - CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); - CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); - // init bloom - CBloomEffect::getInstance().initBloom(); + SceneRoot->setViewport(vp); } - // nb : force full detail if a screenshot is asked - // todo : move outside render code - bool fullDetail = ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail; - if (fullDetail) + //MainCam.setTransformMode(UTransformable::DirectMatrix); + StereoDisplay->getCurrentMatrix(0, &MainCam); + StereoDisplay->getCurrentFrustum(0, &MainCam); + if (SceneRoot) { - s_ForceFullDetail.backup(); - s_ForceFullDetail.set(); + // matrix updated during commitCamera from maincam + StereoDisplay->getCurrentFrustum(1, &SceneRoot->getCam()); } + } + + // Commit camera changes + commitCamera(); + + ////////////////////////// + // RENDER THE FRAME 3D // + ////////////////////////// + + if (StereoDisplay) + { + StereoDisplay->beginRenderTarget(); + } - // Render scene - renderScene(); - - if (fullDetail) + if (!StereoDisplay || StereoDisplay->wantClear()) + { + if(Render) { - s_ForceFullDetail.restore(); - } - if (ClientCfg.Bloom) - { - // apply bloom effect - CBloomEffect::getInstance().endBloom(); + if (ClientCfg.Bloom) + { + nlassert(bloomStage == 0); + // set bloom parameters before applying bloom effect + CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); + CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); + // start bloom effect (just before the first scene element render) + CBloomEffect::instance().initBloom(); + bloomStage = 1; + } } - // for that frame and - // tmp : display height grid - //static volatile bool displayHeightGrid = true; - /*if (displayHeightGrid) + // Clear buffers + clearBuffers(); + } + + if (!StereoDisplay || StereoDisplay->wantScene()) + { + if (!ClientCfg.Light) { - HeightGrid.display(*Driver); - }*/ - // display results? - if(Scene_Profile) - { - displaySceneProfiles(); - Scene_Profile= false; + // Render + if(Render) + { + // nb : force full detail if a screenshot is asked + // todo : move outside render code + bool fullDetail = ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail; + if (fullDetail) + { + s_ForceFullDetail.backup(); + s_ForceFullDetail.set(); + } + + // Render scene + renderScene(); + + if (fullDetail) + { + s_ForceFullDetail.restore(); + } + } } - // Render the primitives + } + + if (!StereoDisplay || StereoDisplay->wantInterface3D()) + { + if (!ClientCfg.Light) + { + // Render + if (Render) + { + if (ClientCfg.Bloom && bloomStage == 1) + { + // End the actual bloom effect visible in the scene. + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); + CBloomEffect::instance().endBloom(); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); + bloomStage = 2; + } + + // for that frame and + // tmp : display height grid + //static volatile bool displayHeightGrid = true; + /*if (displayHeightGrid) + { + HeightGrid.display(*Driver); + }*/ + // display results? + if(Scene_Profile) + { + displaySceneProfiles(); + Scene_Profile= false; + } + // Render the primitives + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + PrimFiles.display (*Driver); + } + } /* if (Render) */ + + // Draw Extra 3D Objects + Driver->setMatrixMode3D(MainCam); + Driver->setModelMatrix(CMatrix::Identity); + + // Display PACS borders. + if (PACSBorders) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + displayPACSBorders(); + displayPACSPrimitive(); + } + + // display Sound box + if (SoundBox) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + displaySoundBox(); + } + + // display Debug of Clusters + if (DebugClusters) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + displayDebugClusters(); + } + } /* if (!ClientCfg.Light) */ + else + { + // static UTextureFile *backgroundBitmap = NULL; + // if (backgroundBitmap == NULL) + // backgroundBitmap = Driver->createTextureFile("temp_background.tga"); + // Driver->setMatrixMode2D11(); + // Driver->drawBitmap (0.f, 0.f, 1024.f/1024.f, 1024.f/768.f, (UTexture&)*backgroundBitmap); + // Driver->setMatrixMode3D(MainCam); + + Driver->clearBuffers(CRGBA (0,0,0,0)); + displayPACSBorders(); + displayPACSPrimitive(); + } + + if (!ClientCfg.Light && !Landscape) + { + displayPACSBorders(); + } + + // Display some things not in the scene like the name, the entity path, etc. + EntitiesMngr.updatePostRender(); + + // Render the stat graphs if needed { H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - PrimFiles.display (*Driver); + CGraph::render (ShowInfos); } - } - else + + } /* if (!StereoDisplay || StereoDisplay->wantInterface3D()) */ + + if (!StereoDisplay || StereoDisplay->wantInterface2D()) { - Driver->clearBuffers(ClientCfg.BGColor); - } + // Render in 2D Mode to display 2D Interfaces and 2D texts. + Driver->setMatrixMode2D11(); - // Draw Extra 3D Objects - Driver->setMatrixMode3D(MainCam); - Driver->setModelMatrix(CMatrix::Identity); - - // Display PACS borders. - if (PACSBorders) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - displayPACSBorders(); - displayPACSPrimitive(); - } - - // display Sound box - if (SoundBox) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - displaySoundBox(); - } - - // display Debug of Clusters - if (DebugClusters) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - displayDebugClusters(); - } - - } - else - { -// static UTextureFile *backgroundBitmap = NULL; -// if (backgroundBitmap == NULL) -// backgroundBitmap = Driver->createTextureFile("temp_background.tga"); -// Driver->setMatrixMode2D11(); -// Driver->drawBitmap (0.f, 0.f, 1024.f/1024.f, 1024.f/768.f, (UTexture&)*backgroundBitmap); -// Driver->setMatrixMode3D(MainCam); - - Driver->clearBuffers(CRGBA (0,0,0,0)); - displayPACSBorders(); - displayPACSPrimitive(); - } - - if (!ClientCfg.Light && !Landscape) - { - displayPACSBorders(); - } - - // Display some things not in the scene like the name, the entity path, etc. - EntitiesMngr.updatePostRender(); - - // Render the stat graphs if needed - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - CGraph::render (ShowInfos); - } - - // Render in 2D Mode to display 2D Interfaces and 2D texts. - Driver->setMatrixMode2D11(); - - // draw a big quad to represent thunder strokes - if (Render && WeatherManager.getThunderLevel() != 0.f) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Render_Thunder ) - Driver->drawQuad(0, 0, 1, 1, ThunderColor); - - // TODO : boris : add sound here ! - // Needs more explosions - } - - // Update the contextual menu - { - H_AUTO_USE ( RZ_Client_Main_Loop_Interface ) - - // Update the game cursor. - ContextCur.check(); - GameContextMenu.update(); - - // validate dialogs - validateDialogs(GameContextMenu); - - // Display interface v3 - Driver->enableFog (false); - if (!Driver->isLost()) - { - if(ShowInterface) - pIMinstance->updateFrameViews (MainCam); - if(DebugUIView) - pIMinstance->displayUIViewBBoxs(DebugUIFilter); - if(DebugUICtrl) - pIMinstance->displayUICtrlBBoxs(DebugUIFilter); - if(DebugUIGroup) - pIMinstance->displayUIGroupBBoxs(DebugUIFilter); - } - - // special case in OpenGL : all scene has been display in render target, - // now, final texture is display with a quad - if(!ClientCfg.Light && ClientCfg.Bloom) - CBloomEffect::getInstance().endInterfacesDisplayBloom(); - } - - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - if (!Driver->isLost()) - { - // If show information is Active. - if(ShowInfos == 1) - displayDebug(); - - // If show information is Active. - if(ShowInfos == 2) - displayNetDebug(); - - // If show information is Active. - if(ShowInfos == 4) - displayDebugFps(); - - // If show information is Active. - if(ShowInfos == 5) - displayDebugUIUnderMouse(); - - // If show information is Active. - displayStreamingDebug(); - - // If Show Help is active -> Display an help. - if(ShowHelp) - displayHelp(); - - // Yoyo: indicate profiling state - if( Profiling ) - displaySpecialTextProgress("Profiling"); - - // Display frame rate - - // Create a shadow when displaying a text. - TextContext->setShaded(true); - // Set the font size. - TextContext->setFontSize(10); - // Set the text color - TextContext->setColor(CRGBA(255,255,255)); - - // temporary values for conversions - float x, y, width, height; - - for(uint i = 0; i < ClientCfg.Logos.size(); i++) + // draw a big quad to represent thunder strokes + if (Render && WeatherManager.getThunderLevel() != 0.f) { - std::vector res; - explode(ClientCfg.Logos[i],std::string(":"), res); - if(res.size()==9 && idrawQuad(0, 0, 1, 1, ThunderColor); + + // TODO : boris : add sound here ! + // Needs more explosions + } + + // Update the contextual menu + { + H_AUTO_USE ( RZ_Client_Main_Loop_Interface ) + + // Update the game cursor. + ContextCur.check(); + GameContextMenu.update(); + + // validate dialogs + validateDialogs(GameContextMenu); + + // Display interface v3 + Driver->enableFog (false); + if (!Driver->isLost()) { - fromString(res[5], x); - fromString(res[6], y); - fromString(res[7], width); - fromString(res[8], height); - Driver->drawBitmap(x/(float)ClientCfg.Width, y/(float)ClientCfg.Height, width/(float)ClientCfg.Width, height/(float)ClientCfg.Height, *LogoBitmaps[i]); + if(ShowInterface) + pIMinstance->updateFrameViews (MainCam); + if(DebugUIView) + pIMinstance->displayUIViewBBoxs(DebugUIFilter); + if(DebugUICtrl) + pIMinstance->displayUICtrlBBoxs(DebugUIFilter); + if(DebugUIGroup) + pIMinstance->displayUIGroupBBoxs(DebugUIFilter); + } + + // special case in OpenGL : all scene has been display in render target, + // now, final texture is display with a quad + if (!ClientCfg.Light && ClientCfg.Bloom && Render && bloomStage == 2) + { + // End bloom effect system after drawing the 3d interface (z buffer related). + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); + CBloomEffect::instance().endInterfacesDisplayBloom(); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); + bloomStage = 0; } } - } - } - // FPS - { - static TTicks oldTick = CTime::getPerformanceTime(); - TTicks newTick = CTime::getPerformanceTime(); - double deltaTime = CTime::ticksToSecond (newTick-oldTick); - oldTick = newTick; - smoothFPS.addValue((float)deltaTime); - moreSmoothFPS.addValue((float)deltaTime); - deltaTime = smoothFPS.getSmoothValue (); - if (deltaTime > 0.0) - { - CCDBNodeLeaf*pNL = NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:FPS"); - pNL->setValue64((sint64)(1.f/deltaTime)); - } - } - - // R2ED post render update - if (ClientCfg.R2EDEnabled) - { - // IMPORTANT : this should be called after CEntitiesMngr::updatePostRender() because - // entity may be added / removed there ! - R2::getEditor().updateAfterRender(); - } - - // Update FXs (remove them). - FXMngr.update(); - - // Detect disconnection / server down: display information text - // but keep the rendering so that the player can remember where he is - // and what he was doing. He can't move because the connection quality returns false. - - if ((connectionState == CNetworkConnection::Disconnect) && (lastConnectionState != CNetworkConnection::Disconnect) && (!FarTP.isFarTPInProgress())) - { - UserControls.stopFreeLook(); // let the player click on Exit - pIMinstance->messageBoxWithHelp(CI18N::get("uiDisconnected")); - - // If we have started a Far TP sequence and are waiting for onServerQuitOK() - // from the EGS, resume the sequence because the EGS is down and won't reply. - FarTP.onServerQuitOk(); - } - - // Yoyo: MovieShooter. - if(MovieShooterSaving) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - - // Add the buffer frame to the movie. - if(!MovieShooter.addFrame(TimeInSec, Driver)) - { - // Fail to add the frame => abort. - endMovieShooting(); - } - else - { - // Ok, just add a display. - displaySpecialTextProgress("MovieShooting"); - } - } - - if (isRecordingCamera()) - { - displaySpecialTextProgress("CameraRecording"); - } - - // Temp for weather test - if (ClientCfg.ManualWeatherSetup && ContinentMngr.cur() && ContinentMngr.cur()->WeatherFunction) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - static float displayHourDelta = 0.04f; // static for edition during debug.. - - // Display weather function - if (DisplayWeatherFunction) - { - uint64 currDay = RT.getRyzomDay(); - float currHour = DayNightCycleHour; - float singleHourDelta = fmodf(currHour, 1.f); - uint32 wndWidth, wndHeight; - Driver->getWindowSize(wndWidth, wndHeight); - Driver->setMatrixMode2D(CFrustum(0, 800, 600, 0, 0, 1, false)); - const float lineHeight = 100.f; - - // draw the weather function - for(uint x = 0; x < wndWidth; ++x) { - float weatherValue; - if(ContinentMngr.cur()) - weatherValue = ::getBlendedWeather(currDay, currHour, *WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + if (!Driver->isLost()) + { + // If show information is Active. + if(ShowInfos == 1) + displayDebug(); + + // If show information is Active. + if(ShowInfos == 2) + displayNetDebug(); + + // If show information is Active. + if(ShowInfos == 4) + displayDebugFps(); + + // If show information is Active. + if(ShowInfos == 5) + displayDebugUIUnderMouse(); + + // If show information is Active. + displayStreamingDebug(); + + // If Show Help is active -> Display an help. + if(ShowHelp) + displayHelp(); + + // Yoyo: indicate profiling state + if( Profiling ) + displaySpecialTextProgress("Profiling"); + + // Display frame rate + + // Create a shadow when displaying a text. + TextContext->setShaded(true); + // Set the font size. + TextContext->setFontSize(10); + // Set the text color + TextContext->setColor(CRGBA(255,255,255)); + + // temporary values for conversions + float x, y, width, height; + + for(uint i = 0; i < ClientCfg.Logos.size(); i++) + { + std::vector res; + explode(ClientCfg.Logos[i],std::string(":"), res); + if(res.size()==9 && idrawBitmap(x/(float)ClientCfg.Width, y/(float)ClientCfg.Height, width/(float)ClientCfg.Width, height/(float)ClientCfg.Height, *LogoBitmaps[i]); + } + } + } + } + + // FPS + { + static TTicks oldTick = CTime::getPerformanceTime(); + TTicks newTick = CTime::getPerformanceTime(); + double deltaTime = CTime::ticksToSecond (newTick-oldTick); + oldTick = newTick; + smoothFPS.addValue((float)deltaTime); + moreSmoothFPS.addValue((float)deltaTime); + deltaTime = smoothFPS.getSmoothValue (); + if (deltaTime > 0.0) + { + CCDBNodeLeaf*pNL = NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:FPS"); + pNL->setValue64((sint64)(1.f/deltaTime)); + } + } + + // R2ED post render update + if (ClientCfg.R2EDEnabled) + { + // IMPORTANT : this should be called after CEntitiesMngr::updatePostRender() because + // entity may be added / removed there ! + R2::getEditor().updateAfterRender(); + } + + // Update FXs (remove them). + FXMngr.update(); + + // Detect disconnection / server down: display information text + // but keep the rendering so that the player can remember where he is + // and what he was doing. He can't move because the connection quality returns false. + + if ((connectionState == CNetworkConnection::Disconnect) && (lastConnectionState != CNetworkConnection::Disconnect) && (!FarTP.isFarTPInProgress())) + { + UserControls.stopFreeLook(); // let the player click on Exit + pIMinstance->messageBoxWithHelp(CI18N::get("uiDisconnected")); + + // If we have started a Far TP sequence and are waiting for onServerQuitOK() + // from the EGS, resume the sequence because the EGS is down and won't reply. + FarTP.onServerQuitOk(); + } + + // Yoyo: MovieShooter. + if(MovieShooterSaving) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + + // Add the buffer frame to the movie. + if(!MovieShooter.addFrame(TimeInSec, Driver)) + { + // Fail to add the frame => abort. + endMovieShooting(); + } else - weatherValue = ::getBlendedWeather(currDay, currHour, *WeatherFunctionParams, 0); - - NLMISC::clamp(weatherValue, 0.f, 1.f); - CRGBA seasonToColor[EGSPD::CSeason::Invalid] = { - CRGBA::Green, - CRGBA::Yellow, - CRGBA::Red, - CRGBA::Blue - }; - Driver->drawLine((float) x, 0.f, (float) x, lineHeight * weatherValue, seasonToColor[CRyzomTime::getSeasonByDay((uint32)currDay)]); - currHour += displayHourDelta; - if (currHour >= 24.f) - { - ++currDay; - currHour -= 24.f; - } - singleHourDelta += displayHourDelta; - if (singleHourDelta >= 1.f) - { - singleHourDelta -= 1.f; - Driver->drawLine((float) x, 100.f, (float) x, 130, CRGBA::Red); + // Ok, just add a display. + displaySpecialTextProgress("MovieShooting"); } } - if(ContinentMngr.cur()) + if (isRecordingCamera()) { - // draw lines for current weather setups - uint numWeatherSetups = ContinentMngr.cur()->WeatherFunction[CurrSeason].getNumWeatherSetups(); - for (uint y = 0; y < numWeatherSetups; ++y) + displaySpecialTextProgress("CameraRecording"); + } + + // Temp for weather test + if (ClientCfg.ManualWeatherSetup && ContinentMngr.cur() && ContinentMngr.cur()->WeatherFunction) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + static float displayHourDelta = 0.04f; // static for edition during debug.. + + // Display weather function + if (DisplayWeatherFunction) { - float py = lineHeight * (y / (float) numWeatherSetups); - Driver->drawLine(0.f, py, 800.f, py, CRGBA::Magenta); + uint64 currDay = RT.getRyzomDay(); + float currHour = DayNightCycleHour; + float singleHourDelta = fmodf(currHour, 1.f); + uint32 wndWidth, wndHeight; + Driver->getWindowSize(wndWidth, wndHeight); + Driver->setMatrixMode2D(CFrustum(0, 800, 600, 0, 0, 1, false)); + const float lineHeight = 100.f; + + // draw the weather function + for(uint x = 0; x < wndWidth; ++x) + { + float weatherValue; + if(ContinentMngr.cur()) + weatherValue = ::getBlendedWeather(currDay, currHour, *WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); + else + weatherValue = ::getBlendedWeather(currDay, currHour, *WeatherFunctionParams, 0); + + NLMISC::clamp(weatherValue, 0.f, 1.f); + CRGBA seasonToColor[EGSPD::CSeason::Invalid] = + { + CRGBA::Green, + CRGBA::Yellow, + CRGBA::Red, + CRGBA::Blue + }; + Driver->drawLine((float) x, 0.f, (float) x, lineHeight * weatherValue, seasonToColor[CRyzomTime::getSeasonByDay((uint32)currDay)]); + currHour += displayHourDelta; + if (currHour >= 24.f) + { + ++currDay; + currHour -= 24.f; + } + singleHourDelta += displayHourDelta; + if (singleHourDelta >= 1.f) + { + singleHourDelta -= 1.f; + Driver->drawLine((float) x, 100.f, (float) x, 130, CRGBA::Red); + } + } + + if(ContinentMngr.cur()) + { + // draw lines for current weather setups + uint numWeatherSetups = ContinentMngr.cur()->WeatherFunction[CurrSeason].getNumWeatherSetups(); + for (uint y = 0; y < numWeatherSetups; ++y) + { + float py = lineHeight * (y / (float) numWeatherSetups); + Driver->drawLine(0.f, py, 800.f, py, CRGBA::Magenta); + } + } + } + + // Ctrl+ & Ctrl- change the weather value + if (Actions.valide ("inc_time")) + { + ManualWeatherValue += DT * 0.04f; + } + if (Actions.valide ("dec_time")) + { + ManualWeatherValue -= DT * 0.04f; + } + NLMISC::clamp(ManualWeatherValue, 0.f, 1.f); + + if (ForcedDayNightCycleHour < 0) // if time is forced then can't change it manually ... + { + // Ctrl-K increase hour + if (Actions.valide ("inc_hour")) + { + RT.increaseTickOffset( (uint32)(2000 * displayHourDelta) ); + RT.updateRyzomClock(NetMngr.getCurrentServerTick(), ryzomGetLocalTime() * 0.001); + } + + // Ctrl-L decrease hour + if (Actions.valide ("dec_hour")) + { + RT.decreaseTickOffset( (uint32)(2000 * displayHourDelta) ); + RT.updateRyzomClock(NetMngr.getCurrentServerTick(), ryzomGetLocalTime() * 0.001); + CTimedFXManager::getInstance().setDate(CClientDate(RT.getRyzomDay(), (float) RT.getRyzomTime())); + if (IGCallbacks) + { + IGCallbacks->changeSeason(); // the season doesn't change, but this force fxs to be recreated + } + } + } + + // Ctrl-M generate statistics in a file + /* + if (Actions.valide ("weather_stats")) + { + // Only usable if there is a continent loaded. + if(ContinentMngr.cur()) + CPredictWeather::generateWeatherStats("weather_stats.csv", WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); + }*/ + + // Ctrl-B decrease display factor + if (Actions.valide ("dec_display_factor")) + { + displayHourDelta *= 0.90f; + } + // Ctrl-J increase display factor + if (Actions.valide ("inc_display_factor")) + { + displayHourDelta *= 1.1f; + displayHourDelta = std::min(1000.f, displayHourDelta); } } - } - // Ctrl+ & Ctrl- change the weather value - if (Actions.valide ("inc_time")) - { - ManualWeatherValue += DT * 0.04f; - } - if (Actions.valide ("dec_time")) - { - ManualWeatherValue -= DT * 0.04f; - } - NLMISC::clamp(ManualWeatherValue, 0.f, 1.f); - - if (ForcedDayNightCycleHour < 0) // if time is forced then can't change it manually ... - { - // Ctrl-K increase hour - if (Actions.valide ("inc_hour")) + // Ctrl-AltGR-Z show timed FXs + if (ShowTimedFX) { - RT.increaseTickOffset( (uint32)(2000 * displayHourDelta) ); - RT.updateRyzomClock(NetMngr.getCurrentServerTick(), ryzomGetLocalTime() * 0.001); - } - - // Ctrl-L decrease hour - if (Actions.valide ("dec_hour")) - { - RT.decreaseTickOffset( (uint32)(2000 * displayHourDelta) ); - RT.updateRyzomClock(NetMngr.getCurrentServerTick(), ryzomGetLocalTime() * 0.001); - CTimedFXManager::getInstance().setDate(CClientDate(RT.getRyzomDay(), (float) RT.getRyzomTime())); - if (IGCallbacks) + if (!Driver->isLost()) { - IGCallbacks->changeSeason(); // the season doesn't change, but this force fxs to be recreated + CTimedFXManager::getInstance().displayFXBoxes(ShowTimedFXMode); } } - } - // Ctrl-M generate statistics in a file - /* - if (Actions.valide ("weather_stats")) - { - // Only usable if there is a continent loaded. - if(ContinentMngr.cur()) - CPredictWeather::generateWeatherStats("weather_stats.csv", WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); - }*/ + #if !FINAL_VERSION + CVector2f camPos(Scene->getCam().getPos().x, Scene->getCam().getPos().y); + if (!ClientCfg.Light) + { + if (DisplayMicroLifeZones) + { + CMicroLifeManager::getInstance().renderMLZones(camPos); + } + } + if (DisplayWaterMap) + { + if (ContinentMngr.cur()) + { + ContinentMngr.cur()->WaterMap.render(camPos); + } + } + #endif - // Ctrl-B decrease display factor - if (Actions.valide ("dec_display_factor")) - { - displayHourDelta *= 0.90f; - } - // Ctrl-J increase display factor - if (Actions.valide ("inc_display_factor")) - { - displayHourDelta *= 1.1f; - displayHourDelta = std::min(1000.f, displayHourDelta); - } - } + #ifdef NL_DEBUG + if (!ClientCfg.Light) + { + if (DisplayMicroLifeActiveTiles) + { + CMicroLifeManager::getInstance().renderActiveTiles(); + } + } + #endif + // tmp : debug of ground fxs + //TestGroundFX.displayFXBoxes(); - // Ctrl-AltGR-Z show timed FXs - if (ShowTimedFX) - { - if (!Driver->isLost()) - { - CTimedFXManager::getInstance().displayFXBoxes(ShowTimedFXMode); - } - } - -#if !FINAL_VERSION - CVector2f camPos(Scene->getCam().getPos().x, Scene->getCam().getPos().y); - if (!ClientCfg.Light) - { - if (DisplayMicroLifeZones) + // Temp for sound debug { - CMicroLifeManager::getInstance().renderMLZones(camPos); - } - } - if (DisplayWaterMap) - { - if (ContinentMngr.cur()) - { - ContinentMngr.cur()->WaterMap.render(camPos); - } - } + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + + if (SoundMngr != 0) + { + static bool drawSound = false; + static float camHeigh = 150.0f; + + #if FINAL_VERSION + if (ClientCfg.ExtendedCommands) #endif + if (Actions.valide ("draw_sound")) + drawSound = !drawSound; - #ifdef NL_DEBUG - if (!ClientCfg.Light) - { - if (DisplayMicroLifeActiveTiles) - { - CMicroLifeManager::getInstance().renderActiveTiles(); + if (Actions.valide ("inc_camera_height")) + camHeigh -= 10.0f; + if (Actions.valide ("dec_camera_height")) + camHeigh += 10.0f; + + if (drawSound) + SoundMngr->drawSounds(camHeigh); + } } - } - #endif - // tmp : debug of ground fxs - //TestGroundFX.displayFXBoxes(); + } /* if (!StereoDisplay || StereoDisplay->wantInterface2D()) */ - // Temp for sound debug - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - - if (SoundMngr != 0) + if (StereoDisplay) { - static bool drawSound = false; - static float camHeigh = 150.0f; - -#if FINAL_VERSION - if (ClientCfg.ExtendedCommands) -#endif - if (Actions.valide ("draw_sound")) - drawSound = !drawSound; - - if (Actions.valide ("inc_camera_height")) - camHeigh -= 10.0f; - if (Actions.valide ("dec_camera_height")) - camHeigh += 10.0f; - - if (drawSound) - SoundMngr->drawSounds(camHeigh); + StereoDisplay->endRenderTarget(); } - } + } /* stereo pass */ // Draw to screen. static CQuat MainCamOri; From cb9e5762db743b74c716275820ec0646a428a94b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 5 Jul 2013 03:42:38 +0200 Subject: [PATCH 083/137] Don't render to texture when in wireframe mode, re #43 --- code/nel/src/3d/stereo_debugger.cpp | 59 ++++++++----- code/nel/src/3d/stereo_ovr.cpp | 123 ++++++++++++++++------------ code/ryzom/client/src/main_loop.cpp | 11 +-- 3 files changed, 114 insertions(+), 79 deletions(-) diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 036cb7e1b..9255fa812 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -257,20 +257,41 @@ void CStereoDebugger::getClippingFrustum(uint cid, NL3D::UCamera *camera) const /// Is there a next pass bool CStereoDebugger::nextPass() { - switch (m_Stage) + if (m_Driver->getPolygonMode() == UDriver::Filled) { - case 0: - ++m_Stage; - m_SubStage = 0; - return true; - case 1: - ++m_Stage; - m_SubStage = 0; - return true; - case 2: - m_Stage = 0; - m_SubStage = 0; - return false; + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + ++m_Stage; + m_SubStage = 0; + return true; + case 2: + ++m_Stage; + m_SubStage = 0; + return true; + case 3: + m_Stage = 0; + m_SubStage = 0; + return false; + } + } + else + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + m_Stage = 0; + m_SubStage = 0; + return false; + } } } @@ -303,34 +324,34 @@ void CStereoDebugger::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const bool CStereoDebugger::wantClear() { m_SubStage = 1; - return true; + return m_Stage != 3; } /// The 3D scene bool CStereoDebugger::wantScene() { m_SubStage = 2; - return true; + return m_Stage != 3; } /// Interface within the 3D scene bool CStereoDebugger::wantInterface3D() { m_SubStage = 3; - return true; + return m_Stage == 3; } /// 2D Interface bool CStereoDebugger::wantInterface2D() { m_SubStage = 4; - return true; + return m_Stage == 3; } /// Returns true if a new render target was set, always fase if not using render targets bool CStereoDebugger::beginRenderTarget() { - if (m_Driver) + if (m_Stage != 3 && m_Driver && (m_Driver->getPolygonMode() == UDriver::Filled)) { if (m_Stage % 2) static_cast(m_Driver)->setRenderTarget(*m_RightTexU, 0, 0, 0, 0); else static_cast(m_Driver)->setRenderTarget(*m_LeftTexU, 0, 0, 0, 0); @@ -342,7 +363,7 @@ bool CStereoDebugger::beginRenderTarget() /// Returns true if a render target was fully drawn, always false if not using render targets bool CStereoDebugger::endRenderTarget() { - if (m_Driver) + if (m_Stage != 3 && m_Driver && (m_Driver->getPolygonMode() == UDriver::Filled)) { CTextureUser cu; (static_cast(m_Driver))->setRenderTarget(cu); diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index e7e31d557..2b91e1836 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -359,54 +359,71 @@ bool CStereoOVR::nextPass() nlassert(width == m_DevicePtr->HMDInfo.HResolution); nlassert(height == m_DevicePtr->HMDInfo.VResolution); - switch (m_Stage) + if (m_Driver->getPolygonMode() == UDriver::Filled) { - case 0: - ++m_Stage; - m_SubStage = 0; - // stage 1: - // (initBloom) - // clear buffer - // draw scene left - return true; - case 1: - ++m_Stage; - m_SubStage = 0; - // stage 2: - // draw scene right - return true; - case 2: - ++m_Stage; - m_SubStage = 0; - // stage 3: - // (endBloom) - // draw interface 3d left - return true; - case 3: - ++m_Stage; - m_SubStage = 0; - // stage 4: - // draw interface 3d right - return true; - case 4: - ++m_Stage; - m_SubStage = 0; - // stage 5: - // (endInterfacesDisplayBloom) - // draw interface 2d left - return true; - case 5: - ++m_Stage; - m_SubStage = 0; - // stage 6: - // draw interface 2d right - return true; - case 6: - m_Stage = 0; - m_SubStage = 0; - // present - m_OrientationCached = false; - return false; + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + // stage 1: + // (initBloom) + // clear buffer + // draw scene left + return true; + case 1: + ++m_Stage; + m_SubStage = 0; + // stage 2: + // draw scene right + return true; + case 2: + ++m_Stage; + m_SubStage = 0; + // stage 3: + // (endBloom) + // draw interface 3d left + return true; + case 3: + ++m_Stage; + m_SubStage = 0; + // stage 4: + // draw interface 3d right + return true; + case 4: + ++m_Stage; + m_SubStage = 0; + // stage 5: + // (endInterfacesDisplayBloom) + // draw interface 2d left + return true; + case 5: + ++m_Stage; + m_SubStage = 0; + // stage 6: + // draw interface 2d right + return true; + case 6: + m_Stage = 0; + m_SubStage = 0; + // present + m_OrientationCached = false; + return false; + } + } + else + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + m_Stage = 0; + m_SubStage = 0; + return false; + } } nlerror("Invalid stage"); m_Stage = 0; @@ -459,7 +476,7 @@ bool CStereoOVR::wantClear() m_SubStage = 1; return true; } - return false; + return m_Driver->getPolygonMode() != UDriver::Filled; } bool CStereoOVR::wantScene() @@ -471,7 +488,7 @@ bool CStereoOVR::wantScene() m_SubStage = 2; return true; } - return false; + return m_Driver->getPolygonMode() != UDriver::Filled; } bool CStereoOVR::wantInterface3D() @@ -483,7 +500,7 @@ bool CStereoOVR::wantInterface3D() m_SubStage = 3; return true; } - return false; + return m_Driver->getPolygonMode() != UDriver::Filled; } bool CStereoOVR::wantInterface2D() @@ -495,7 +512,7 @@ bool CStereoOVR::wantInterface2D() m_SubStage = 4; return true; } - return false; + return m_Driver->getPolygonMode() != UDriver::Filled; } @@ -504,7 +521,7 @@ bool CStereoOVR::beginRenderTarget() { // render target always set before driver clear // nlassert(m_SubStage <= 1); - if (m_Driver && m_Stage == 1) + if (m_Driver && m_Stage == 1 && (m_Driver->getPolygonMode() == UDriver::Filled)) { static_cast(m_Driver)->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0); return true; @@ -517,7 +534,7 @@ bool CStereoOVR::endRenderTarget() { // after rendering of course // nlassert(m_SubStage > 1); - if (m_Driver && m_Stage == 6) // set to 4 to turn off distortion of 2d gui + if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui { CTextureUser cu; (static_cast(m_Driver))->setRenderTarget(cu); diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 095236ef0..7b7c0bd9c 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1627,14 +1627,11 @@ bool mainLoop() // RENDER THE FRAME 3D // ////////////////////////// - if (StereoDisplay) - { - StereoDisplay->beginRenderTarget(); - } + bool stereoRenderTarget = (StereoDisplay != NULL) && StereoDisplay->beginRenderTarget(); if (!StereoDisplay || StereoDisplay->wantClear()) { - if(Render) + if (Render) { if (ClientCfg.Bloom) { @@ -1777,14 +1774,14 @@ bool mainLoop() Driver->setMatrixMode2D11(); // draw a big quad to represent thunder strokes - if (Render && WeatherManager.getThunderLevel() != 0.f) + /*if (Render && WeatherManager.getThunderLevel() != 0.f) { H_AUTO_USE ( RZ_Client_Main_Loop_Render_Thunder ) Driver->drawQuad(0, 0, 1, 1, ThunderColor); // TODO : boris : add sound here ! // Needs more explosions - } + }*/ // Update the contextual menu { From a1ded7183ae128faa91f52573142ea317e6905ac Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 5 Jul 2013 04:09:53 +0200 Subject: [PATCH 084/137] Handle head orientation in ryzom client, ref #43 --- code/ryzom/client/src/main_loop.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 7b7c0bd9c..c76a6964c 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1384,7 +1384,15 @@ bool mainLoop() MainCam.setRotQuat(View.currentViewQuat()); if (StereoHMD) { - // ... + NLMISC::CQuat hmdOrient = StereoHMD->getOrientation(); + NLMISC::CMatrix camMatrix = MainCam.getMatrix(); + NLMISC::CMatrix hmdMatrix; + hmdMatrix.setRot(hmdOrient); + NLMISC::CMatrix posMatrix; // minimal head modeling, will be changed in the future + posMatrix.translate(StereoHMD->getEyePosition()); + NLMISC::CMatrix mat = ((camMatrix * hmdMatrix) * posMatrix); + MainCam.setPos(mat.getPos()); + MainCam.setRotQuat(mat.getRot()); } if (StereoDisplay) { From 67ebf920ec3de6f5d26e7e373c6b11d87d45b4b5 Mon Sep 17 00:00:00 2001 From: Michael Witrant Date: Sat, 6 Jul 2013 19:33:07 +0200 Subject: [PATCH 085/137] Added LibOVR finder and Linux support, ref #43 --- code/CMakeModules/FindLibOVR.cmake | 60 ++++++++++++++++++++++++++++++ code/nel/CMakeLists.txt | 2 + code/nel/src/3d/CMakeLists.txt | 6 ++- 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 code/CMakeModules/FindLibOVR.cmake diff --git a/code/CMakeModules/FindLibOVR.cmake b/code/CMakeModules/FindLibOVR.cmake new file mode 100644 index 000000000..0ef4e1f47 --- /dev/null +++ b/code/CMakeModules/FindLibOVR.cmake @@ -0,0 +1,60 @@ +# - Locate LibOVR library +# This module defines +# LIBOVR_LIBRARIES, the libraries to link against +# LIBOVR_FOUND, if false, do not try to link to LIBOVR +# LIBOVR_INCLUDE_DIR, where to find headers. + +IF(LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIR) + # in cache already + SET(LIBOVR_FIND_QUIETLY TRUE) +ENDIF(LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIR) + +FIND_PATH(LIBOVR_INCLUDE_DIR + OVR.h + PATHS + $ENV{LIBOVR_DIR}/Include + /usr/local/include + /usr/include + /sw/include + /opt/local/include + /opt/csw/include + /opt/include +) + +IF(TARGET_CPU STREQUAL "x86_64") + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/Linux/Release/x86_64") +ELSE(TARGET_CPU STREQUAL "x86_64") + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/Linux/Release/i386") +ENDIF(TARGET_CPU STREQUAL "x86_64") + +FIND_LIBRARY(LIBOVR_LIBRARY + NAMES ovr + PATHS + $ENV{LIBOVR_DIR}/${LIBOVR_LIBRARY_BUILD_PATH} + /usr/local/lib + /usr/lib + /usr/local/X11R6/lib + /usr/X11R6/lib + /sw/lib + /opt/local/lib + /opt/csw/lib + /opt/lib + /usr/freeware/lib64 +) + +IF(LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIR) + IF(NOT LIBOVR_FIND_QUIETLY) + MESSAGE(STATUS "Found LibOVR: ${LIBOVR_LIBRARY}") + ENDIF(NOT LIBOVR_FIND_QUIETLY) + SET(LIBOVR_FOUND "YES") + SET(LIBOVR_DEFINITIONS "-DHAVE_LIBOVR") + IF(UNIX) + SET(LIBOVR_LIBRARIES ${LIBOVR_LIBRARY} X11 Xinerama udev pthread) + ELSE(UNIX) + SET(LIBOVR_LIBRARIES ${LIBOVR_LIBRARY}) + ENDIF(UNIX) +ELSE(LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIR) + IF(NOT LIBOVR_FIND_QUIETLY) + MESSAGE(STATUS "Warning: Unable to find LibOVR!") + ENDIF(NOT LIBOVR_FIND_QUIETLY) +ENDIF(LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIR) diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index 745278cd7..1ac54f332 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -41,6 +41,8 @@ IF(WITH_GTK) FIND_PACKAGE(GTK2) ENDIF(WITH_GTK) +FIND_PACKAGE(LibOVR) + IF(WITH_INSTALL_LIBRARIES) IF(UNIX) SET(prefix ${CMAKE_INSTALL_PREFIX}) diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index ffdc876a9..b92f58dba 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -701,9 +701,9 @@ SOURCE_GROUP(Stereo FILES NL_TARGET_LIB(nel3d ${HEADERS} ${SRC}) -INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS} ${LIBOVR_INCLUDE_DIR}) -TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARY}) +TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARY} ${LIBOVR_LIBRARIES}) SET_TARGET_PROPERTIES(nel3d PROPERTIES LINK_INTERFACE_LIBRARIES "") NL_DEFAULT_PROPS(nel3d "NeL, Library: NeL 3D") NL_ADD_RUNTIME_FLAGS(nel3d) @@ -713,6 +713,8 @@ NL_ADD_LIB_SUFFIX(nel3d) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) +ADD_DEFINITIONS(${LIBOVR_DEFINITIONS}) + IF(WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(nel3d ${CMAKE_CURRENT_SOURCE_DIR}/std3d.h ${CMAKE_CURRENT_SOURCE_DIR}/std3d.cpp) ENDIF(WITH_PCH) From f3936225734ea33332158a2d2106e6b33a966fc1 Mon Sep 17 00:00:00 2001 From: Michael Witrant Date: Sat, 6 Jul 2013 19:34:28 +0200 Subject: [PATCH 086/137] Fixed Linux build failure because a temporary pointer was passed, ref #43 --- code/ryzom/client/src/main_loop.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index c76a6964c..b273984ff 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -1399,7 +1399,8 @@ bool mainLoop() StereoDisplay->updateCamera(0, &MainCam); if (SceneRoot) { - StereoDisplay->updateCamera(1, &SceneRoot->getCam()); + UCamera cam = SceneRoot->getCam(); + StereoDisplay->updateCamera(1, &cam); } } @@ -1624,7 +1625,8 @@ bool mainLoop() if (SceneRoot) { // matrix updated during commitCamera from maincam - StereoDisplay->getCurrentFrustum(1, &SceneRoot->getCam()); + UCamera cam = SceneRoot->getCam(); + StereoDisplay->getCurrentFrustum(1, &cam); } } From ed8e0edfd0555a030939f596a036e6bd1f299583 Mon Sep 17 00:00:00 2001 From: Michael Witrant Date: Sat, 6 Jul 2013 19:55:08 +0200 Subject: [PATCH 087/137] Added Win32 and Apple LibOVR build paths --- code/CMakeModules/FindLibOVR.cmake | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/code/CMakeModules/FindLibOVR.cmake b/code/CMakeModules/FindLibOVR.cmake index 0ef4e1f47..1403a4b2c 100644 --- a/code/CMakeModules/FindLibOVR.cmake +++ b/code/CMakeModules/FindLibOVR.cmake @@ -21,11 +21,21 @@ FIND_PATH(LIBOVR_INCLUDE_DIR /opt/include ) -IF(TARGET_CPU STREQUAL "x86_64") - SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/Linux/Release/x86_64") -ELSE(TARGET_CPU STREQUAL "x86_64") - SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/Linux/Release/i386") -ENDIF(TARGET_CPU STREQUAL "x86_64") +IF(UNIX) + IF(TARGET_X64) + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/Linux/Release/x86_64") + ELSE(TARGET_X64) + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/Linux/Release/i386") + ENDIF(TARGET_X64) +ELSEIF(APPLE) + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/MacOS/Release") +ELSEIF(WIN32) + IF(TARGET_X64) + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/x64") + ELSE(TARGET_X64) + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/Win32") + ENDIF(TARGET_X64) +ENDIF(UNIX) FIND_LIBRARY(LIBOVR_LIBRARY NAMES ovr From 69c194f57fb85a157ad5caa5eb580a2425685ee0 Mon Sep 17 00:00:00 2001 From: Michael Witrant Date: Sat, 6 Jul 2013 20:05:19 +0200 Subject: [PATCH 088/137] LibOVR is optional, and is disabled by default --- code/CMakeModules/nel.cmake | 2 ++ code/nel/CMakeLists.txt | 4 +++- code/nel/include/nel/3d/stereo_ovr.h | 5 +++++ code/nel/src/3d/stereo_display.cpp | 6 ++++++ code/nel/src/3d/stereo_ovr.cpp | 4 ++++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index 4308d0b44..f3897cce0 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -324,6 +324,8 @@ MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS) OPTION(WITH_NEL_MAXPLUGIN "Build NeL 3dsMax Plugin" OFF) OPTION(WITH_NEL_SAMPLES "Build NeL Samples" ON ) OPTION(WITH_NEL_TESTS "Build NeL Unit Tests" ON ) + + OPTION(WITH_LIBOVR "With LibOVR support" OFF) ENDMACRO(NL_SETUP_NEL_DEFAULT_OPTIONS) MACRO(NL_SETUP_NELNS_DEFAULT_OPTIONS) diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index 1ac54f332..07474abcd 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -41,7 +41,9 @@ IF(WITH_GTK) FIND_PACKAGE(GTK2) ENDIF(WITH_GTK) -FIND_PACKAGE(LibOVR) +IF(WITH_LIBOVR) + FIND_PACKAGE(LibOVR) +ENDIF(WITH_LIBOVR) IF(WITH_INSTALL_LIBRARIES) IF(UNIX) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index 3b417b871..e8a67a45a 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -43,6 +43,9 @@ #ifndef NL3D_STEREO_OVR_H #define NL3D_STEREO_OVR_H + +#ifdef WITH_LIBOVR + #include // STL includes @@ -166,6 +169,8 @@ private: } /* namespace NL3D */ +#endif /* WITH_LIBOVR */ + #endif /* #ifndef NL3D_STEREO_OVR_H */ /* end of file */ diff --git a/code/nel/src/3d/stereo_display.cpp b/code/nel/src/3d/stereo_display.cpp index d2a8fd932..57f2722eb 100644 --- a/code/nel/src/3d/stereo_display.cpp +++ b/code/nel/src/3d/stereo_display.cpp @@ -75,7 +75,9 @@ const char *IStereoDisplay::getLibraryName(CStereoDeviceInfo::TStereoDeviceLibra void IStereoDisplay::listDevices(std::vector &devicesOut) { +#ifdef WITH_LIBOVR CStereoOVR::listDevices(devicesOut); +#endif #if !FINAL_VERSION CStereoDebugger::listDevices(devicesOut); #endif @@ -88,13 +90,17 @@ IStereoDisplay *IStereoDisplay::createDevice(const CStereoDeviceInfo &deviceInfo void IStereoDisplay::releaseUnusedLibraries() { +#ifdef WITH_LIBOVR if (!CStereoOVR::isLibraryInUse()) CStereoOVR::releaseLibrary(); +#endif } void IStereoDisplay::releaseAllLibraries() { +#ifdef WITH_LIBOVR CStereoOVR::releaseLibrary(); +#endif } } /* namespace NL3D */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 2b91e1836..3c6fb88e2 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -41,6 +41,8 @@ * so, delete this exception statement from your version. */ +#ifdef WITH_LIBOVR + #include #include @@ -736,4 +738,6 @@ bool CStereoOVR::isDeviceCreated() } /* namespace NL3D */ +#endif /* WITH_LIBOVR */ + /* end of file */ From 59dc1a6c1648fe4908abab8851b7ebee7ece6667 Mon Sep 17 00:00:00 2001 From: Michael Witrant Date: Sat, 6 Jul 2013 20:40:42 +0200 Subject: [PATCH 089/137] Fixed definition tests for optional LibOVR --- code/nel/include/nel/3d/stereo_ovr.h | 4 ++-- code/nel/src/3d/stereo_display.cpp | 6 +++--- code/nel/src/3d/stereo_ovr.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index e8a67a45a..c2dccf930 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -44,7 +44,7 @@ #ifndef NL3D_STEREO_OVR_H #define NL3D_STEREO_OVR_H -#ifdef WITH_LIBOVR +#ifdef HAVE_LIBOVR #include @@ -169,7 +169,7 @@ private: } /* namespace NL3D */ -#endif /* WITH_LIBOVR */ +#endif /* HAVE_LIBOVR */ #endif /* #ifndef NL3D_STEREO_OVR_H */ diff --git a/code/nel/src/3d/stereo_display.cpp b/code/nel/src/3d/stereo_display.cpp index 57f2722eb..0f6d0cbfb 100644 --- a/code/nel/src/3d/stereo_display.cpp +++ b/code/nel/src/3d/stereo_display.cpp @@ -75,7 +75,7 @@ const char *IStereoDisplay::getLibraryName(CStereoDeviceInfo::TStereoDeviceLibra void IStereoDisplay::listDevices(std::vector &devicesOut) { -#ifdef WITH_LIBOVR +#ifdef HAVE_LIBOVR CStereoOVR::listDevices(devicesOut); #endif #if !FINAL_VERSION @@ -90,7 +90,7 @@ IStereoDisplay *IStereoDisplay::createDevice(const CStereoDeviceInfo &deviceInfo void IStereoDisplay::releaseUnusedLibraries() { -#ifdef WITH_LIBOVR +#ifdef HAVE_LIBOVR if (!CStereoOVR::isLibraryInUse()) CStereoOVR::releaseLibrary(); #endif @@ -98,7 +98,7 @@ void IStereoDisplay::releaseUnusedLibraries() void IStereoDisplay::releaseAllLibraries() { -#ifdef WITH_LIBOVR +#ifdef HAVE_LIBOVR CStereoOVR::releaseLibrary(); #endif } diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 3c6fb88e2..a57a0ffcb 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -41,7 +41,7 @@ * so, delete this exception statement from your version. */ -#ifdef WITH_LIBOVR +#ifdef HAVE_LIBOVR #include #include @@ -738,6 +738,6 @@ bool CStereoOVR::isDeviceCreated() } /* namespace NL3D */ -#endif /* WITH_LIBOVR */ +#endif /* HAVE_LIBOVR */ /* end of file */ From cb53258f8cb2d262affc40a13513bdc1d60dbfb5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 6 Jul 2013 21:58:26 +0200 Subject: [PATCH 090/137] Fix bad includes in snowballs, re #43 --- code/snowballs2/client/src/commands.cpp | 2 +- code/snowballs2/client/src/compass.cpp | 2 +- code/snowballs2/client/src/snowballs_client.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index 6d9b23085..41faeab1e 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include "network.h" #include "snowballs_client.h" diff --git a/code/snowballs2/client/src/compass.cpp b/code/snowballs2/client/src/compass.cpp index 9cc6fac57..27e0e27f1 100644 --- a/code/snowballs2/client/src/compass.cpp +++ b/code/snowballs2/client/src/compass.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include "mouse_listener.h" #include "camera.h" diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 6c3630a8b..b401d80bc 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -51,7 +51,7 @@ #if SBCLIENT_DEV_STEREO # include #endif /* #if SBCLIENT_DEV_STEREO */ -#include +#include // Project includes #include "pacs.h" From d0a4f5ed7555b7cead92b7af0a8d6ebc87b65946 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 3 Aug 2013 21:29:47 +0200 Subject: [PATCH 091/137] Fix warning --- code/nel/src/3d/stereo_debugger.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 9255fa812..6be97d42a 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -293,6 +293,7 @@ bool CStereoDebugger::nextPass() return false; } } + return false; } /// Gets the current viewport From a45299bfe513facca5e1a3abad092d69d345ceeb Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 28 Aug 2013 08:08:22 +0200 Subject: [PATCH 092/137] Add support for LibVR --- code/CMakeModules/FindLibVR.cmake | 32 ++ code/CMakeModules/nel.cmake | 1 + code/nel/CMakeLists.txt | 4 + code/nel/include/nel/3d/stereo_libvr.h | 160 ++++++ code/nel/src/3d/CMakeLists.txt | 7 +- code/nel/src/3d/stereo_display.cpp | 4 + code/nel/src/3d/stereo_libvr.cpp | 642 +++++++++++++++++++++++++ 7 files changed, 848 insertions(+), 2 deletions(-) create mode 100644 code/CMakeModules/FindLibVR.cmake create mode 100644 code/nel/include/nel/3d/stereo_libvr.h create mode 100644 code/nel/src/3d/stereo_libvr.cpp diff --git a/code/CMakeModules/FindLibVR.cmake b/code/CMakeModules/FindLibVR.cmake new file mode 100644 index 000000000..eba9c347e --- /dev/null +++ b/code/CMakeModules/FindLibVR.cmake @@ -0,0 +1,32 @@ +# - Locate LibVR library +# This module defines +# LIBVR_LIBRARIES, the libraries to link against +# LIBVR_FOUND, if false, do not try to link to LIBVR +# LIBVR_INCLUDE_DIR, where to find headers. + +IF(LIBVR_LIBRARIES AND LIBVR_INCLUDE_DIR) + # in cache already + SET(LIBVR_FIND_QUIETLY TRUE) +ENDIF(LIBVR_LIBRARIES AND LIBVR_INCLUDE_DIR) + +FIND_PATH(LIBVR_INCLUDE_DIR hmd.h + PATH_SUFFIXES include/LibVR +) + +FIND_LIBRARY(LIBVR_LIBRARY + NAMES vr + PATH_SUFFIXES lib + PATHS +) + +IF(LIBVR_LIBRARY AND LIBVR_INCLUDE_DIR) + IF(NOT LIBVR_FIND_QUIETLY) + MESSAGE(STATUS "Found LibVR: ${LIBVR_LIBRARY}") + ENDIF(NOT LIBVR_FIND_QUIETLY) + SET(LIBVR_FOUND "YES") + SET(LIBVR_DEFINITIONS "-DHAVE_LIBVR") +ELSE(LIBVR_LIBRARY AND LIBVR_INCLUDE_DIR) + IF(NOT LIBVR_FIND_QUIETLY) + MESSAGE(STATUS "Warning: Unable to find LibVR!") + ENDIF(NOT LIBVR_FIND_QUIETLY) +ENDIF(LIBVR_LIBRARY AND LIBVR_INCLUDE_DIR) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index 1547e2260..2fa51eb3a 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -322,6 +322,7 @@ MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS) OPTION(WITH_NEL_TESTS "Build NeL Unit Tests" ON ) OPTION(WITH_LIBOVR "With LibOVR support" OFF) + OPTION(WITH_LIBVR "With LibVR support" OFF) ENDMACRO(NL_SETUP_NEL_DEFAULT_OPTIONS) MACRO(NL_SETUP_NELNS_DEFAULT_OPTIONS) diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index 2a392ddf9..53bf071e3 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -45,6 +45,10 @@ IF(WITH_LIBOVR) FIND_PACKAGE(LibOVR) ENDIF(WITH_LIBOVR) +IF(WITH_LIBVR) + FIND_PACKAGE(LibVR) +ENDIF(WITH_LIBVR) + IF(WITH_INSTALL_LIBRARIES) IF(UNIX) SET(prefix ${CMAKE_INSTALL_PREFIX}) diff --git a/code/nel/include/nel/3d/stereo_libvr.h b/code/nel/include/nel/3d/stereo_libvr.h new file mode 100644 index 000000000..76d1966fe --- /dev/null +++ b/code/nel/include/nel/3d/stereo_libvr.h @@ -0,0 +1,160 @@ +/** + * \file stereo_libvr.h + * \brief CStereoLibVR + * \date 2013-08-19 19:17MT + * \author Thibaut Girka (ThibG) + * CStereoLibVR + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_STEREO_LIBVR_H +#define NL3D_STEREO_LIBVR_H + +#ifdef HAVE_LIBVR + +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes +#include +#include +#include +#include + +namespace NL3D { + +class ITexture; +class CTextureUser; +class CStereoLibVRDevicePtr; +class CStereoLibVRDeviceHandle; +class CPixelProgram; + +#define NL_STEREO_MAX_USER_CAMERAS 8 + +/** + * \brief CStereoOVR + * \date 2013-06-25 22:22GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ +class CStereoLibVR : public IStereoHMD +{ +public: + CStereoLibVR(const CStereoLibVRDeviceHandle *handle); + virtual ~CStereoLibVR(); + + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver *driver); + + /// Gets the required screen resolution for this device + virtual bool getScreenResolution(uint &width, uint &height); + /// Set latest camera position etcetera + virtual void updateCamera(uint cid, const NL3D::UCamera *camera); + /// Get the frustum to use for clipping + virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const; + + /// Is there a next pass + virtual bool nextPass(); + /// Gets the current viewport + virtual const NL3D::CViewport &getCurrentViewport() const; + /// Gets the current camera frustum + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const; + /// Gets the current camera frustum + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const; + /// Gets the current camera matrix + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; + + /// At the start of a new render target + virtual bool wantClear(); + /// The 3D scene + virtual bool wantScene(); + /// Interface within the 3D scene + virtual bool wantInterface3D(); + /// 2D Interface + virtual bool wantInterface2D(); + + /// Returns true if a new render target was set, always fase if not using render targets + virtual bool beginRenderTarget(); + /// Returns true if a render target was fully drawn, always false if not using render targets + virtual bool endRenderTarget(); + + + /// Get the HMD orientation + virtual NLMISC::CQuat getOrientation() const; + + /// Get GUI center (1 = width, 1 = height, 0 = center) + virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const; + + /// Set the head model, eye position relative to orientation point + virtual void setEyePosition(const NLMISC::CVector &v); + /// Get the head model, eye position relative to orientation point + virtual const NLMISC::CVector &getEyePosition() const; + + /// Set the scale of the game in units per meter + virtual void setScale(float s); + + + static void listDevices(std::vector &devicesOut); + static bool isLibraryInUse(); + static void releaseLibrary(); + + + /// Calculates internal camera information based on the reference camera + void initCamera(uint cid, const NL3D::UCamera *camera); + /// Checks if the device used by this class was actually created + bool isDeviceCreated(); + +private: + CStereoLibVRDevicePtr *m_DevicePtr; + int m_Stage; + int m_SubStage; + CViewport m_LeftViewport; + CViewport m_RightViewport; + CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; + mutable bool m_OrientationCached; + mutable NLMISC::CQuat m_OrientationCache; + UDriver *m_Driver; + NLMISC::CSmartPtr m_BarrelTex; + NL3D::CTextureUser *m_BarrelTexU; + NL3D::UMaterial m_BarrelMat; + NLMISC::CQuadUV m_BarrelQuadLeft; + NLMISC::CQuadUV m_BarrelQuadRight; + CPixelProgram *m_PixelProgram; + NLMISC::CVector m_EyePosition; + float m_Scale; + +}; /* class CStereoLibVR */ + +} /* namespace NL3D */ + +#endif /* HAVE_LIBVR */ + +#endif /* #ifndef NL3D_STEREO_LIBVR_H */ + +/* end of file */ diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index b92f58dba..2769d8e2d 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -696,14 +696,16 @@ SOURCE_GROUP(Stereo FILES stereo_ovr.cpp stereo_ovr_fp.cpp ../../include/nel/3d/stereo_ovr.h + stereo_libvr.cpp + ../../include/nel/3d/stereo_libvr.h stereo_debugger.cpp ../../include/nel/3d/stereo_debugger.h) NL_TARGET_LIB(nel3d ${HEADERS} ${SRC}) -INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS} ${LIBOVR_INCLUDE_DIR}) +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS} ${LIBOVR_INCLUDE_DIR} ${LIBVR_INCLUDE_DIR}) -TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARY} ${LIBOVR_LIBRARIES}) +TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARY} ${LIBOVR_LIBRARIES} ${LIBVR_LIBRARY}) SET_TARGET_PROPERTIES(nel3d PROPERTIES LINK_INTERFACE_LIBRARIES "") NL_DEFAULT_PROPS(nel3d "NeL, Library: NeL 3D") NL_ADD_RUNTIME_FLAGS(nel3d) @@ -714,6 +716,7 @@ NL_ADD_LIB_SUFFIX(nel3d) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) ADD_DEFINITIONS(${LIBOVR_DEFINITIONS}) +ADD_DEFINITIONS(${LIBVR_DEFINITIONS}) IF(WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(nel3d ${CMAKE_CURRENT_SOURCE_DIR}/std3d.h ${CMAKE_CURRENT_SOURCE_DIR}/std3d.cpp) diff --git a/code/nel/src/3d/stereo_display.cpp b/code/nel/src/3d/stereo_display.cpp index 0f6d0cbfb..eace867fc 100644 --- a/code/nel/src/3d/stereo_display.cpp +++ b/code/nel/src/3d/stereo_display.cpp @@ -35,6 +35,7 @@ // Project includes #include +#include #include using namespace std; @@ -78,6 +79,9 @@ void IStereoDisplay::listDevices(std::vector &devicesOut) #ifdef HAVE_LIBOVR CStereoOVR::listDevices(devicesOut); #endif +#ifdef HAVE_LIBVR + CStereoLibVR::listDevices(devicesOut); +#endif #if !FINAL_VERSION CStereoDebugger::listDevices(devicesOut); #endif diff --git a/code/nel/src/3d/stereo_libvr.cpp b/code/nel/src/3d/stereo_libvr.cpp new file mode 100644 index 000000000..8ce64e07c --- /dev/null +++ b/code/nel/src/3d/stereo_libvr.cpp @@ -0,0 +1,642 @@ +/** + * \file stereo_libvr.cpp + * \brief CStereoLibVR + * \date 2013-08-19 19:17MT + * \author Thibaut Girka (ThibG) + * CStereoLibVR + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifdef HAVE_LIBVR + +#include +#include +#include + +// STL includes +#include + +// External includes +extern "C" { +#include +} + +// NeL includes +// #include +#include +#include +#include +#include +#include +#include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +extern const char *g_StereoOVR_fp40; //TODO: what? +extern const char *g_StereoOVR_arbfp1; //TODO: what? +extern const char *g_StereoOVR_ps_2_0; //TODO: what? + +namespace { +sint s_DeviceCounter = 0; +}; + +class CStereoLibVRDeviceHandle : public IStereoDeviceFactory +{ +public: + // fixme: virtual destructor??? + IStereoDisplay *createDevice() const + { + CStereoLibVR *stereo = new CStereoLibVR(this); + if (stereo->isDeviceCreated()) + return stereo; + delete stereo; + return NULL; + } +}; + +class CStereoLibVRDevicePtr +{ +public: + struct hmd *HMDDevice; + struct display_info HMDInfo; + float InterpupillaryDistance; +}; + +CStereoLibVR::CStereoLibVR(const CStereoLibVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL), m_PixelProgram(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) +{ + struct stereo_config st_conf; + + ++s_DeviceCounter; + // For now, LibVR doesn't support multiple devices... + m_DevicePtr = new CStereoLibVRDevicePtr(); + m_DevicePtr->HMDDevice = hmd_open_first(0); + m_DevicePtr->InterpupillaryDistance = 0.0647; //TODO + + if (m_DevicePtr->HMDDevice) + { + hmd_get_display_info(m_DevicePtr->HMDDevice, &m_DevicePtr->HMDInfo); + hmd_get_stereo_config(m_DevicePtr->HMDDevice, &st_conf); + nldebug("LibVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.h_screen_size, m_DevicePtr->HMDInfo.v_screen_size); + nldebug("LibVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.v_center); + nldebug("LibVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.eye_to_screen[0]); + nldebug("LibVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.lens_separation); + nldebug("LibVR: HResolution: %i, VResolution: %i", m_DevicePtr->HMDInfo.h_resolution, m_DevicePtr->HMDInfo.v_resolution); + nldebug("LibVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.distortion_k[0], m_DevicePtr->HMDInfo.distortion_k[1]); + nldebug("LibVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.distortion_k[2], m_DevicePtr->HMDInfo.distortion_k[3]); + nldebug("LibVR: Scale: %f", st_conf.distort.scale); + m_LeftViewport.init(0.f, 0.f, 0.5f, 1.0f); + m_RightViewport.init(0.5f, 0.f, 0.5f, 1.0f); + } +} + +CStereoLibVR::~CStereoLibVR() +{ + if (!m_BarrelMat.empty()) + { + m_BarrelMat.getObjectPtr()->setTexture(0, NULL); + m_Driver->deleteMaterial(m_BarrelMat); + } + delete m_BarrelTexU; + m_BarrelTexU = NULL; + m_BarrelTex = NULL; // CSmartPtr + + delete m_PixelProgram; + m_PixelProgram = NULL; + + m_Driver = NULL; + + if (m_DevicePtr->HMDDevice) + hmd_close(m_DevicePtr->HMDDevice); + + delete m_DevicePtr; + m_DevicePtr = NULL; + + --s_DeviceCounter; +} + +void CStereoLibVR::setDriver(NL3D::UDriver *driver) +{ + nlassert(!m_PixelProgram); + + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + nldebug("VR: fp40"); + m_PixelProgram = new CPixelProgram(g_StereoOVR_fp40); + } + else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + nldebug("VR: arbfp1"); + m_PixelProgram = new CPixelProgram(g_StereoOVR_arbfp1); + } + else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) + { + nldebug("VR: ps_2_0"); + m_PixelProgram = new CPixelProgram(g_StereoOVR_ps_2_0); + } + + if (m_PixelProgram) + { + m_Driver = driver; + + m_BarrelTex = new CTextureBloom(); // lol bloom + m_BarrelTex->setRenderTarget(true); + m_BarrelTex->setReleasable(false); + m_BarrelTex->resize(m_DevicePtr->HMDInfo.h_resolution, m_DevicePtr->HMDInfo.v_resolution); + m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_BarrelTex->setWrapS(ITexture::Clamp); + m_BarrelTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_BarrelTex); + m_BarrelTexU = new CTextureUser(m_BarrelTex); + + m_BarrelMat = m_Driver->createMaterial(); + m_BarrelMat.initUnlit(); + m_BarrelMat.setColor(CRGBA::White); + m_BarrelMat.setBlend (false); + m_BarrelMat.setAlphaTest (false); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setShader(NL3D::CMaterial::PostProcessing); + barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero); + barrelMat->setZWrite(false); + barrelMat->setZFunc(CMaterial::always); + barrelMat->setDoubleSided(true); + barrelMat->setTexture(0, m_BarrelTex); + + m_BarrelQuadLeft.V0 = CVector(0.f, 0.f, 0.5f); + m_BarrelQuadLeft.V1 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadLeft.V2 = CVector(0.5f, 1.f, 0.5f); + m_BarrelQuadLeft.V3 = CVector(0.f, 1.f, 0.5f); + + m_BarrelQuadRight.V0 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadRight.V1 = CVector(1.f, 0.f, 0.5f); + m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f); + m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f); + + nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed + + m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f); + m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f); + m_BarrelQuadLeft.Uv2 = CUV(0.5f, 1.f); + m_BarrelQuadLeft.Uv3 = CUV(0.f, 1.f); + + m_BarrelQuadRight.Uv0 = CUV(0.5f, 0.f); + m_BarrelQuadRight.Uv1 = CUV(1.f, 0.f); + m_BarrelQuadRight.Uv2 = CUV(1.f, 1.f); + m_BarrelQuadRight.Uv3 = CUV(0.5f, 1.f); + } + else + { + nlwarning("VR: No pixel program support"); + } +} + +bool CStereoLibVR::getScreenResolution(uint &width, uint &height) +{ + width = m_DevicePtr->HMDInfo.h_resolution; + height = m_DevicePtr->HMDInfo.v_resolution; + return true; +} + +void CStereoLibVR::initCamera(uint cid, const NL3D::UCamera *camera) +{ + struct stereo_config st_conf; + hmd_get_stereo_config(m_DevicePtr->HMDDevice, &st_conf); + + float ar = st_conf.proj.aspect_ratio; + float fov = st_conf.proj.yfov; + m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); + m_RightFrustum[cid] = m_LeftFrustum[cid]; + + float projectionCenterOffset = st_conf.proj.projection_offset * 0.5 * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); + nldebug("LibVR: projectionCenterOffset = %f", projectionCenterOffset); + + m_LeftFrustum[cid].Left -= projectionCenterOffset; + m_LeftFrustum[cid].Right -= projectionCenterOffset; + m_RightFrustum[cid].Left += projectionCenterOffset; + m_RightFrustum[cid].Right += projectionCenterOffset; + + // TODO: Clipping frustum should also take into account the IPD + m_ClippingFrustum[cid] = m_LeftFrustum[cid]; + m_ClippingFrustum[cid].Left = min(m_LeftFrustum[cid].Left, m_RightFrustum[cid].Left); + m_ClippingFrustum[cid].Right = max(m_LeftFrustum[cid].Right, m_RightFrustum[cid].Right); +} + +/// Get the frustum to use for clipping +void CStereoLibVR::getClippingFrustum(uint cid, NL3D::UCamera *camera) const +{ + camera->setFrustum(m_ClippingFrustum[cid]); +} + +void CStereoLibVR::updateCamera(uint cid, const NL3D::UCamera *camera) +{ + if (camera->getFrustum().Near != m_LeftFrustum[cid].Near + || camera->getFrustum().Far != m_LeftFrustum[cid].Far) + CStereoLibVR::initCamera(cid, camera); + m_CameraMatrix[cid] = camera->getMatrix(); +} + +bool CStereoLibVR::nextPass() +{ + // Do not allow weird stuff. + uint32 width, height; + m_Driver->getWindowSize(width, height); + nlassert(width == m_DevicePtr->HMDInfo.h_resolution); + nlassert(height == m_DevicePtr->HMDInfo.v_resolution); + + if (m_Driver->getPolygonMode() == UDriver::Filled) + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + // stage 1: + // (initBloom) + // clear buffer + // draw scene left + return true; + case 1: + ++m_Stage; + m_SubStage = 0; + // stage 2: + // draw scene right + return true; + case 2: + ++m_Stage; + m_SubStage = 0; + // stage 3: + // (endBloom) + // draw interface 3d left + return true; + case 3: + ++m_Stage; + m_SubStage = 0; + // stage 4: + // draw interface 3d right + return true; + case 4: + ++m_Stage; + m_SubStage = 0; + // stage 5: + // (endInterfacesDisplayBloom) + // draw interface 2d left + return true; + case 5: + ++m_Stage; + m_SubStage = 0; + // stage 6: + // draw interface 2d right + return true; + case 6: + m_Stage = 0; + m_SubStage = 0; + // present + m_OrientationCached = false; + return false; + } + } + else + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + m_Stage = 0; + m_SubStage = 0; + return false; + } + } + nlerror("Invalid stage"); + m_Stage = 0; + m_SubStage = 0; + m_OrientationCached = false; + return false; +} + +const NL3D::CViewport &CStereoLibVR::getCurrentViewport() const +{ + if (m_Stage % 2) return m_LeftViewport; + else return m_RightViewport; +} + +const NL3D::CFrustum &CStereoLibVR::getCurrentFrustum(uint cid) const +{ + if (m_Stage % 2) return m_LeftFrustum[cid]; + else return m_RightFrustum[cid]; +} + +void CStereoLibVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const +{ + if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]); + else camera->setFrustum(m_RightFrustum[cid]); +} + +void CStereoLibVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const +{ + CMatrix translate; + if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f)); + else translate.translate(CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f)); + CMatrix mat = m_CameraMatrix[cid] * translate; + if (camera->getTransformMode() == NL3D::UTransformable::RotQuat) + { + camera->setPos(mat.getPos()); + camera->setRotQuat(mat.getRot()); + } + else + { + // camera->setTransformMode(NL3D::UTransformable::DirectMatrix); + camera->setMatrix(mat); + } +} + +bool CStereoLibVR::wantClear() +{ + switch (m_Stage) + { + case 1: + m_SubStage = 1; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoLibVR::wantScene() +{ + switch (m_Stage) + { + case 1: + case 2: + m_SubStage = 2; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoLibVR::wantInterface3D() +{ + switch (m_Stage) + { + case 3: + case 4: + m_SubStage = 3; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoLibVR::wantInterface2D() +{ + switch (m_Stage) + { + case 5: + case 6: + m_SubStage = 4; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + + +/// Returns non-NULL if a new render target was set +bool CStereoLibVR::beginRenderTarget() +{ + // render target always set before driver clear + // nlassert(m_SubStage <= 1); + if (m_Driver && m_Stage == 1 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + static_cast(m_Driver)->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0); + return true; + } + return false; +} + +/// Returns true if a render target was fully drawn +bool CStereoLibVR::endRenderTarget() +{ + // after rendering of course + // nlassert(m_SubStage > 1); + if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui + { + struct stereo_config st_conf; + hmd_get_stereo_config(m_DevicePtr->HMDDevice, &st_conf); + CTextureUser cu; + (static_cast(m_Driver))->setRenderTarget(cu); + bool fogEnabled = m_Driver->fogEnabled(); + m_Driver->enableFog(false); + + m_Driver->setMatrixMode2D11(); + CViewport vp = CViewport(); + m_Driver->setViewport(vp); + uint32 width, height; + m_Driver->getWindowSize(width, height); + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setTexture(0, m_BarrelTex); + drvInternal->activePixelProgram(m_PixelProgram); + + float w = float(m_BarrelQuadLeft.V1.x),// / float(width), + h = float(m_BarrelQuadLeft.V2.y),// / float(height), + x = float(m_BarrelQuadLeft.V0.x),/// / float(width), + y = float(m_BarrelQuadLeft.V0.y);// / float(height); + + //TODO: stereo_config stuff + float lensViewportShift = st_conf.proj.projection_offset; + + float lensCenterX = x + (w + lensViewportShift * 0.5f) * 0.5f; + float lensCenterY = y + h * 0.5f; + float screenCenterX = x + w * 0.5f; + float screenCenterY = y + h * 0.5f; + float scaleX = (w / 2 / st_conf.distort.scale); + float scaleY = (h / 2 / st_conf.distort.scale); + float scaleInX = (2 / w); + float scaleInY = (2 / h); + drvInternal->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(2, scaleX, scaleY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(3, scaleInX, scaleInY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(4, 1, st_conf.distort.distortion_k); + + + m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat); + + x = w; + lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f; + screenCenterX = x + w * 0.5f; + drvInternal->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f); + + m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat); + + drvInternal->activePixelProgram(NULL); + m_Driver->enableFog(fogEnabled); + + return true; + } + return false; +} + +NLMISC::CQuat CStereoLibVR::getOrientation() const +{ + if (m_OrientationCached) + return m_OrientationCache; + + unsigned int t = NLMISC::CTime::getLocalTime(); + hmd_update(m_DevicePtr->HMDDevice, &t); + + float quat[4]; + hmd_get_rotation(m_DevicePtr->HMDDevice, quat); + NLMISC::CMatrix coordsys; + float csys[] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + coordsys.set(csys); + NLMISC::CMatrix matovr; + matovr.setRot(NLMISC::CQuat(quat[1], quat[2], quat[3], quat[0])); + NLMISC::CMatrix matr; + matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) + NLMISC::CMatrix matnel = matr * matovr * coordsys; + NLMISC::CQuat finalquat = matnel.getRot(); + m_OrientationCache = finalquat; + m_OrientationCached = true; + return finalquat; +} + +/// Get GUI shift +void CStereoLibVR::getInterface2DShift(uint cid, float &x, float &y, float distance) const +{ +#if 0 + + // todo: take into account m_EyePosition + + NLMISC::CVector vector = CVector(0.f, -distance, 0.f); + NLMISC::CQuat rot = getOrientation(); + rot.invert(); + NLMISC::CMatrix mat; + mat.rotate(rot); + //if (m_Stage % 2) mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); + //else mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); + mat.translate(vector); + CVector proj = CStereoOVR::getCurrentFrustum(cid).project(mat.getPos()); + + NLMISC::CVector ipd; + if (m_Stage % 2) ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f); + else ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f); + CVector projipd = CStereoOVR::getCurrentFrustum(cid).project(vector + ipd); + CVector projvec = CStereoOVR::getCurrentFrustum(cid).project(vector); + + x = (proj.x + projipd.x - projvec.x - 0.5f); + y = (proj.y + projipd.y - projvec.y - 0.5f); + +#elif 1 + + // Alternative method + // todo: take into account m_EyePosition + + NLMISC::CVector vec = CVector(0.f, -distance, 0.f); + NLMISC::CVector ipd; + if (m_Stage % 2) ipd = CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f); + else ipd = CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f); + + + NLMISC::CQuat rot = getOrientation(); + NLMISC::CQuat modrot = NLMISC::CQuat(CVector(0.f, 1.f, 0.f), NLMISC::Pi); + rot = rot * modrot; + float p = NLMISC::Pi + atan2f(2.0f * ((rot.x * rot.y) + (rot.z * rot.w)), 1.0f - 2.0f * ((rot.y * rot.y) + (rot.w * rot.w))); + if (p > NLMISC::Pi) p -= NLMISC::Pi * 2.0f; + float t = -atan2f(2.0f * ((rot.x * rot.w) + (rot.y * rot.z)), 1.0f - 2.0f * ((rot.z * rot.z) + (rot.w * rot.w)));// // asinf(2.0f * ((rot.x * rot.z) - (rot.w * rot.y))); + + CVector rotshift = CVector(p, 0.f, t) * -distance; + + CVector proj = CStereoLibVR::getCurrentFrustum(cid).project(vec + ipd + rotshift); + + x = (proj.x - 0.5f); + y = (proj.y - 0.5f); + +#endif +} + +void CStereoLibVR::setEyePosition(const NLMISC::CVector &v) +{ + m_EyePosition = v; +} + +const NLMISC::CVector &CStereoLibVR::getEyePosition() const +{ + return m_EyePosition; +} + +void CStereoLibVR::setScale(float s) +{ + m_EyePosition = m_EyePosition * (s / m_Scale); + m_Scale = s; +} + +void CStereoLibVR::listDevices(std::vector &devicesOut) +{ + // For now, LibVR doesn't support multiple devices + struct hmd *hmd = hmd_open_first(0); + if (hmd) + { + CStereoDeviceInfo deviceInfoOut; + CStereoLibVRDeviceHandle *handle = new CStereoLibVRDeviceHandle(); + deviceInfoOut.Factory = static_cast(handle); + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; + deviceInfoOut.Library = CStereoDeviceInfo::LibVR; + //TODO: manufacturer, produc name + //TODO: serial + devicesOut.push_back(deviceInfoOut); + hmd_close(hmd); + } +} + +bool CStereoLibVR::isLibraryInUse() +{ + nlassert(s_DeviceCounter >= 0); + return s_DeviceCounter > 0; +} + +void CStereoLibVR::releaseLibrary() +{ + nlassert(s_DeviceCounter == 0); +} + +bool CStereoLibVR::isDeviceCreated() +{ + return m_DevicePtr->HMDDevice != NULL; +} + +} /* namespace NL3D */ + +#endif /* HAVE_LIBVR */ + +/* end of file */ From d54774f978d295cd7bcfa05317279df3b4b689b7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 7 Sep 2013 18:33:18 +0200 Subject: [PATCH 093/137] Add abstract gpu program and source classes --- code/nel/include/nel/3d/gpu_program.h | 233 +++++++++++++++++++ code/nel/include/nel/3d/gpu_program_source.h | 91 ++++++++ code/nel/src/3d/CMakeLists.txt | 6 +- code/nel/src/3d/gpu_program.cpp | 191 +++++++++++++++ code/nel/src/3d/gpu_program_source.cpp | 47 ++++ 5 files changed, 567 insertions(+), 1 deletion(-) create mode 100644 code/nel/include/nel/3d/gpu_program.h create mode 100644 code/nel/include/nel/3d/gpu_program_source.h create mode 100644 code/nel/src/3d/gpu_program.cpp create mode 100644 code/nel/src/3d/gpu_program_source.cpp diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h new file mode 100644 index 000000000..63d6eea88 --- /dev/null +++ b/code/nel/include/nel/3d/gpu_program.h @@ -0,0 +1,233 @@ +/** + * \file gpu_program.h + * \brief CGPUProgram + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * IGPUProgram + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_GPU_PROGRAM_H +#define NL3D_GPU_PROGRAM_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes + +namespace NL3D { + +/** + * \brief CVertexProgramInfo + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * Read-only information structure. + */ +struct CVertexProgramInfo +{ +public: + std::string DisplayName; + + enum TFeatures + { + // World + // transform + + // Lights + Ambient = 0x0001, + Sun = 0x0002, + PointLight0 = 0x0004, + PointLight1 = 0x0008, + PointLight2 = 0x0010, + + // Lights, additional parameters for user shaders + /// Adds an enabled/disabled parameter to all of the lights + DynamicLights = 0x0020, + }; + + /// Bitfield containing features used by this vertex program. + uint Features; + + /// Indices of parameters used by features. + + /// Lights, NeL supports: + /// - Ambient light + uint AmbientIdx; // (Ambient) + /// - One directional light + uint SunDirectionIdx; // (Sun) + uint SunDiffuseIdx; // (Sun) + /// - Zero to three point lights + uint PointLight0PositionIdx; // (PointLight0) + uint PointLight0DiffuseIdx; // (PointLight0) + uint PointLight1PositionIdx; // (PointLight1) + uint PointLight1DiffuseIdx; // (PointLight1) + uint PointLight2PositionIdx; // (PointLight2) + uint PointLight2DiffuseIdx; // (PointLight2) + + /// DynamicLights + uint SunEnabledIdx; // (DynamicLights && Sun) + uint PointLight0EnabledIdx; // (DynamicLights && PointLight0) + uint PointLight1EnabledIdx; // (DynamicLights && PointLight1) + uint PointLight2EnabledIdx; // (DynamicLights && PointLight2) +}; + +/** + * \brief CPixelProgramInfo + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * Read-only information structure. + */ +struct CPixelProgramInfo +{ +public: + std::string DisplayName; + + enum TFeatures + { + /// Use texture stages from CMaterial as texture parameters + MaterialTextures = 0x0001, + /// Set driver fog parameters on this program + Fog = 0x0002, + /// Adds an enabled/disabled parameter to the fog, for user shaders + DynamicFog = 0x0004, + }; + + // Bitfield containing features used by this pixel program + uint Features; + + // Indices of parameters used by features + uint FogEnabledIdx; // (Fog && DynamicFog) nlFogEnabled, fog enabled + uint FogStartEndIdx; // (Fog) nlFogStartEnd, start and end of fog + uint FogColorIdx; // (Fog) nlFogColor, fog color +}; + +/** + * \brief CGeometryProgramInfo + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * Read-only information structure. + */ +struct CGeometryProgramInfo +{ +public: + /*enum TFeatures + { + + };*/ + /// Bitfield containing features used by this pixel program. + // uint Features; + /// Indices of parameters used by features. +}; + +/** + * \brief CGPUProgram + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * A compiled GPU program + */ +class IGPUProgram : public NLMISC::CRefCount +{ +public: + enum TProfile + { + // types + // Vertex Shader = 0x01 + // Pixel Shader = 0x02 + // Geometry Shader = 0x03 + + // nel - 0x31,type,bitfield + nelvp = 0x31010001, // VP supported by CVertexProgramParser, similar to arbvp1, can be translated to vs_1_1 + + // direct3d - 0xD9,type,major,minor + // vertex programs + vs_1_1 = 0xD9010101, + vs_2_0 = 0xD9010200, + // vs_2_sw = 0xD9010201, // not sure... + // vs_2_x = 0xD9010202, // not sure... + // vs_3_0 = 0xD9010300, // not supported + // pixel programs + ps_1_1 = 0xD9020101, + ps_1_2 = 0xD9020102, + ps_1_3 = 0xD9020103, + ps_1_4 = 0xD9020104, + ps_2_0 = 0xD9020200, + // ps_2_x = 0xD9020201, // not sure... + // ps_3_0 = 0xD9020300, // not supported + + // opengl - 0x61,type,bitfield + // vertex programs + // vp20 = 0x61010001, // NV_vertex_program1_1, outdated + arbvp1 = 0x61010002, // ARB_vertex_program + vp30 = 0x61010004, // NV_vertex_program2 + vp40 = 0x61010008, // NV_vertex_program3 + NV_fragment_program3 + gp4vp = 0x61010010, // NV_gpu_program4 + gp5vp = 0x61010020, // NV_gpu_program5 + // pixel programs + // fp20 = 0x61020001, // very limited and outdated, unnecessary + // fp30 = 0x61020002, // NV_fragment_program, now arbfp1, redundant + arbfp1 = 0x61020004, // ARB_fragment_program + fp40 = 0x61020008, // NV_fragment_program2, arbfp1 with "OPTION NV_fragment_program2;\n" + gp4fp = 0x61020010, // NV_gpu_program4 + gp5fp = 0x61020020, // NV_gpu_program5 + // geometry programs + gp4gp = 0x61030001, // NV_gpu_program4 + gp5gp = 0x61030001, // NV_gpu_program5 + + // glsl - 0x65,type,version + glsl330v = 0x65010330, // GLSL vertex program version 330 + glsl330f = 0x65020330, // GLSL fragment program version 330 + glsl330g = 0x65030330, // GLSL geometry program version 330 + }; + +public: + IGPUProgram(); + virtual ~IGPUProgram(); + + /// Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0 + virtual uint getParamIdx(char *name) const = 0; + + void buildVPInfo(const char *displayName, uint features); + void buildPPInfo(const char *displayName, uint features); + void buildGPInfo(const char *displayName, uint features); + + inline const CVertexProgramInfo *getVPInfo() const { return Info.VertexProgram; } + inline const CPixelProgramInfo *getPPInfo() const { return Info.PixelProgram; } + inline const CGeometryProgramInfo *getGPInfo() const { return Info.GeometryProgram; } + +private: + union + { + CVertexProgramInfo *VertexProgram; + CPixelProgramInfo *PixelProgram; + CGeometryProgramInfo *GeometryProgram; + void *Ptr; + } Info; + +}; /* class IGPUProgram */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_GPU_PROGRAM_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/gpu_program_source.h b/code/nel/include/nel/3d/gpu_program_source.h new file mode 100644 index 000000000..7e6ba81fa --- /dev/null +++ b/code/nel/include/nel/3d/gpu_program_source.h @@ -0,0 +1,91 @@ +/** + * \file gpu_program_source.h + * \brief CGPUProgramSource + * \date 2013-09-07 14:54GMT + * \author Jan Boon (Kaetemi) + * CGPUProgramSource + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_GPU_PROGRAM_SOURCE_H +#define NL3D_GPU_PROGRAM_SOURCE_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes +#include + +namespace NL3D { + +/** + * \brief CGPUProgramSource + * \date 2013-09-07 14:54GMT + * \author Jan Boon (Kaetemi) + * A single GPU program with a specific profile. + */ +struct CGPUProgramSource +{ +public: + std::string DisplayName; + + /// Minimal required profile for this GPU program + IGPUProgram::TProfile Profile; + + char *SourcePtr; + /// Copy the source string + inline void setSource(char *source) { SourceCopy = source; SourcePtr = &source[0]; } + /// Set pointer to source string without copying the string + inline void setSourcePtr(char *sourcePtr) { SourceCopy.clear(); SourcePtr = sourcePtr; } + + /// CVertexProgramInfo/CPixelProgramInfo/... NeL features + uint Features; + + /// Map with known parameter indices, used for assembly programs + std::map ParamIndices; + +private: + std::string SourceCopy; + +}; /* class CGPUProgramSource */ + +/** + * \brief CGPUProgramSourceCont + * \date 2013-09-07 14:54GMT + * \author Jan Boon (Kaetemi) + * Container for the source code of a single GPU program, allowing + * variations in different language profiles. + */ +struct CGPUProgramSourceCont +{ +public: + std::vector Sources; + +}; /* class CGPUProgramSourceCont */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_GPU_PROGRAM_SOURCE_H */ + +/* end of file */ diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index 2769d8e2d..fb5d5851a 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -166,7 +166,11 @@ SOURCE_GROUP(Driver FILES vertex_program_parse.cpp ../../include/nel/3d/vertex_program_parse.h pixel_program.cpp - ../../include/nel/3d/pixel_program.h) + ../../include/nel/3d/pixel_program.h + gpu_program.cpp + ../../include/nel/3d/gpu_program.h + gpu_program_source.cpp + ../../include/nel/3d/gpu_program_source.h) SOURCE_GROUP(Font FILES computed_string.cpp diff --git a/code/nel/src/3d/gpu_program.cpp b/code/nel/src/3d/gpu_program.cpp new file mode 100644 index 000000000..457d8b1a1 --- /dev/null +++ b/code/nel/src/3d/gpu_program.cpp @@ -0,0 +1,191 @@ +/** + * \file gpu_program.cpp + * \brief CGPUProgram + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * CGPUProgram + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +IGPUProgram::IGPUProgram() +{ + Info.Ptr = NULL; +} + +IGPUProgram::~IGPUProgram() +{ + delete Info.Ptr; + Info.Ptr = NULL; +} + +void IGPUProgram::buildVPInfo(const char *displayName, uint features) +{ + nlassert(Info.VertexProgram == NULL); + Info.VertexProgram = new CVertexProgramInfo(); + CVertexProgramInfo *info = Info.VertexProgram; + info->DisplayName = displayName; + info->Features = features; + if (features & CVertexProgramInfo::Ambient) + { + info->AmbientIdx = getParamIdx("nlAmbient"); + if (info->AmbientIdx == ~0) + { + nlwarning("Missing 'nlAmbient' in gpu program '%s', Ambient disabled", displayName); + info->Features &= ~CVertexProgramInfo::Ambient; + } + } + if (features & CVertexProgramInfo::Sun) + { + if (features & CVertexProgramInfo::DynamicLights) + { + info->SunEnabledIdx = getParamIdx("nlSunEnabled"); + if (info->SunEnabledIdx == ~0) + { + nlwarning("Missing 'nlSunEnabled' in gpu program '%s', DynamicLights disabled", displayName); + info->Features &= ~CVertexProgramInfo::DynamicLights; + } + } + info->SunDirectionIdx = getParamIdx("nlSunDirection"); + info->SunDiffuseIdx = getParamIdx("nlSunDiffuse"); + if (info->SunDirectionIdx == ~0 + || info->SunDiffuseIdx == ~0) + { + nlwarning("Missing 'nlSunDirection/nlSunDiffuse' in gpu program '%s', Sun disabled", displayName); + info->Features &= ~CVertexProgramInfo::Sun; + } + } + if (features & CVertexProgramInfo::PointLight0) + { + if (features & CVertexProgramInfo::DynamicLights) + { + info->PointLight0EnabledIdx = getParamIdx("nlPointLight0Enabled"); + if (info->PointLight0EnabledIdx == ~0) + { + nlwarning("Missing 'nlPointLight0Enabled' in gpu program '%s', DynamicLights disabled", displayName); + info->Features &= ~CVertexProgramInfo::DynamicLights; + } + } + info->PointLight0PositionIdx = getParamIdx("nlPointLight0Position"); + info->PointLight0DiffuseIdx = getParamIdx("nlPointLight0Diffuse"); + if (info->PointLight0PositionIdx == ~0 + || info->PointLight0DiffuseIdx == ~0) + { + nlwarning("Missing 'nlPointLight0Position/nlPointLight0Diffuse' in gpu program '%s', PointLight0 disabled", displayName); + info->Features &= ~CVertexProgramInfo::PointLight0; + } + } + if (features & CVertexProgramInfo::PointLight1) + { + if (features & CVertexProgramInfo::DynamicLights) + { + info->PointLight1EnabledIdx = getParamIdx("nlPointLight1Enabled"); + if (info->PointLight1EnabledIdx == ~0) + { + nlwarning("Missing 'nlPointLight1Enabled' in gpu program '%s', DynamicLights disabled", displayName); + info->Features &= ~CVertexProgramInfo::DynamicLights; + } + } + info->PointLight1PositionIdx = getParamIdx("nlPointLight1Position"); + info->PointLight1DiffuseIdx = getParamIdx("nlPointLight1Diffuse"); + if (info->PointLight1PositionIdx == ~0 + || info->PointLight1DiffuseIdx == ~0) + { + nlwarning("Missing 'nlPointLight1Position/nlPointLight1Diffuse' in gpu program '%s', PointLight1 disabled", displayName); + info->Features &= ~CVertexProgramInfo::PointLight1; + } + } + if (features & CVertexProgramInfo::PointLight2) + { + if (features & CVertexProgramInfo::DynamicLights) + { + info->PointLight2EnabledIdx = getParamIdx("nlPointLight2Enabled"); + if (info->PointLight2EnabledIdx == ~0) + { + nlwarning("Missing 'nlPointLight2Enabled' in gpu program '%s', DynamicLights disabled", displayName); + info->Features &= ~CVertexProgramInfo::DynamicLights; + } + } + info->PointLight2PositionIdx = getParamIdx("nlPointLight2Position"); + info->PointLight2DiffuseIdx = getParamIdx("nlPointLight2Diffuse"); + if (info->PointLight2PositionIdx == ~0 + || info->PointLight2DiffuseIdx == ~0) + { + nlwarning("Missing 'nlPointLight2Position/nlPointLight2Diffuse' in gpu program '%s', PointLight2 disabled", displayName); + info->Features &= ~CVertexProgramInfo::PointLight2; + } + } +} + +void IGPUProgram::buildPPInfo(const char *displayName, uint features) +{ + nlassert(Info.PixelProgram == NULL); + Info.PixelProgram = new CPixelProgramInfo(); + CPixelProgramInfo *info = Info.PixelProgram; + info->DisplayName = displayName; + info->Features = features; + if (features & CPixelProgramInfo::Fog) + { + if (features & CPixelProgramInfo::DynamicFog) + { + info->FogEnabledIdx = getParamIdx("nlFogEnabled"); + if (info->FogEnabledIdx == ~0) + { + nlwarning("Missing 'nlFogEnabled' in gpu program '%s', DynamicFog disabled", displayName); + info->Features &= ~CPixelProgramInfo::DynamicFog; + } + } + info->FogStartEndIdx = getParamIdx("nlFogStartEnd"); + info->FogColorIdx = getParamIdx("nlFogColor"); + if (info->FogStartEndIdx == ~0 + || info->FogStartEndIdx == ~0) + { + nlwarning("Missing 'nlFogStartEnd/nlFogColor' in gpu program '%s', Fog disabled", displayName); + info->Features &= ~CPixelProgramInfo::Fog; + } + } +} + +void IGPUProgram::buildGPInfo(const char *displayName, uint features) +{ + nlassert(Info.GeometryProgram == NULL); + Info.GeometryProgram = new CGeometryProgramInfo(); +} + + +} /* namespace NL3D */ + +/* end of file */ diff --git a/code/nel/src/3d/gpu_program_source.cpp b/code/nel/src/3d/gpu_program_source.cpp new file mode 100644 index 000000000..21d1cc18b --- /dev/null +++ b/code/nel/src/3d/gpu_program_source.cpp @@ -0,0 +1,47 @@ +/** + * \file gpu_program_source.cpp + * \brief CGPUProgramSource + * \date 2013-09-07 14:54GMT + * \author Jan Boon (Kaetemi) + * CGPUProgramSource + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +void gpu_program_source_cpp_dummy() { } + +} /* namespace NL3D */ + +/* end of file */ From 47716d7247e6479e155b5cb175f36fbb152f31ca Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 7 Sep 2013 20:41:07 +0200 Subject: [PATCH 094/137] Make gpu programs use abstract gpu program class --- code/nel/include/nel/3d/driver.h | 26 ++- code/nel/include/nel/3d/geometry_program.h | 83 +++++++++ code/nel/include/nel/3d/gpu_program.h | 146 ++++----------- code/nel/include/nel/3d/gpu_program_source.h | 20 +- code/nel/include/nel/3d/pixel_program.h | 99 ++++------ code/nel/include/nel/3d/shader.h | 67 ------- code/nel/include/nel/3d/vertex_program.h | 125 +++++++------ .../nel/include/nel/3d/vertex_program_parse.h | 34 ++++ code/nel/src/3d/CMakeLists.txt | 2 + code/nel/src/3d/driver.cpp | 23 ++- code/nel/src/3d/geometry_program.cpp | 59 ++++++ code/nel/src/3d/gpu_program.cpp | 171 ++++-------------- code/nel/src/3d/pixel_program.cpp | 52 ++++-- code/nel/src/3d/shader.cpp | 81 --------- code/nel/src/3d/stereo_debugger.cpp | 14 +- code/nel/src/3d/stereo_ovr.cpp | 20 +- code/nel/src/3d/vertex_program.cpp | 129 +++++++++++-- 17 files changed, 552 insertions(+), 599 deletions(-) create mode 100644 code/nel/include/nel/3d/geometry_program.h create mode 100644 code/nel/src/3d/geometry_program.cpp diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 655a9e62b..3cb0c0349 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -151,9 +151,10 @@ protected: TVBDrvInfoPtrList _VBDrvInfos; TIBDrvInfoPtrList _IBDrvInfos; TPolygonMode _PolygonMode; - TVtxPrgDrvInfoPtrList _VtxPrgDrvInfos; - TPixelPrgDrvInfoPtrList _PixelPrgDrvInfos; - TShaderDrvInfoPtrList _ShaderDrvInfos; + TGPUPrgDrvInfoPtrList _GPUPrgDrvInfos; + // TPixelPrgDrvInfoPtrList _PixelPrgDrvInfos; + // TGeomPrgDrvInfoPtrList _GeomPrgDrvInfos; + // TShaderDrvInfoPtrList _ShaderDrvInfos; uint _ResetCounter; @@ -317,11 +318,6 @@ public: virtual bool setupMaterial(CMaterial& mat)=0; - /** - * Activate a shader, NULL to disable the current shader. - */ - virtual bool activeShader(CShader *shd)=0; - /** Special for Faster Specular Setup. Call this between lot of primitives rendered with Specular Materials. * Visual Errors may arise if you don't correctly call endSpecularBatch(). */ @@ -1303,9 +1299,10 @@ protected: friend class CTextureDrvShare; friend class ITextureDrvInfos; friend class IMaterialDrvInfos; - friend class IVertexProgramDrvInfos; - friend class IPixelProgramDrvInfos; - friend class IShaderDrvInfos; + // friend class IVertexProgramDrvInfos; + // friend class IPixelProgramDrvInfos; + // friend class IShaderDrvInfos; + friend class IGPUProgramDrvInfos; /// remove ptr from the lists in the driver. void removeVBDrvInfoPtr(ItVBDrvInfoPtrList vbDrvInfoIt); @@ -1313,9 +1310,10 @@ protected: void removeTextureDrvInfoPtr(ItTexDrvInfoPtrMap texDrvInfoIt); void removeTextureDrvSharePtr(ItTexDrvSharePtrList texDrvShareIt); void removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt); - void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt); - void removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt); - void removePixelPrgDrvInfoPtr(ItPixelPrgDrvInfoPtrList pixelPrgDrvInfoIt); + // void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt); + // void removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt); + // void removePixelPrgDrvInfoPtr(ItPixelPrgDrvInfoPtrList pixelPrgDrvInfoIt); + void removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt); private: bool _StaticMemoryToVRAM; diff --git a/code/nel/include/nel/3d/geometry_program.h b/code/nel/include/nel/3d/geometry_program.h new file mode 100644 index 000000000..ac9451b27 --- /dev/null +++ b/code/nel/include/nel/3d/geometry_program.h @@ -0,0 +1,83 @@ +/** \file geometry_program.h + * Geometry program definition + */ + +/* Copyright, 2000, 2001 Nevrax Ltd. + * + * This file is part of NEVRAX NEL. + * NEVRAX NEL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + + * NEVRAX NEL is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with NEVRAX NEL; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef NL_GEOMETRY_PROGRAM_H +#define NL_GEOMETRY_PROGRAM_H + +#include +#include +#include +#include + +#include + +namespace NL3D { + +/** + * \brief CGeometryProgramInfo + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * Read-only information structure. + */ +struct CGeometryProgramInfo +{ +public: + std::string DisplayName; + + /*enum TFeatures + { + + };*/ + + // Bitfield containing features used by this geometry program + uint Features; + + // Indices of parameters used by features + // ... +}; + +class CGeometryProgram : public IGPUProgram +{ +public: + /// Constructor + CGeometryProgram(CGPUProgramSourceCont *programSource); + /// Destructor + virtual ~CGeometryProgram (); + + /// Build feature information + void buildInfo(const char *displayName, uint features); + /// Get feature information + inline const CGeometryProgramInfo *getInfo() const { return _Info; } + +private: + + /// Feature information + CGeometryProgramInfo *_Info; +}; + +} // NL3D + + +#endif // NL_GEOMETRY_PROGRAM_H + +/* End of vertex_program.h */ diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index 63d6eea88..3df13ac3d 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -1,6 +1,6 @@ /** * \file gpu_program.h - * \brief CGPUProgram + * \brief IGPUProgram * \date 2013-09-07 15:00GMT * \author Jan Boon (Kaetemi) * IGPUProgram @@ -38,110 +38,33 @@ namespace NL3D { -/** - * \brief CVertexProgramInfo - * \date 2013-09-07 15:00GMT - * \author Jan Boon (Kaetemi) - * Read-only information structure. - */ -struct CVertexProgramInfo +// List typedef. +class IDriver; +class IGPUProgramDrvInfos; +typedef std::list TGPUPrgDrvInfoPtrList; +typedef TGPUPrgDrvInfoPtrList::iterator ItGPUPrgDrvInfoPtrList; + +// Class for interaction of vertex program with Driver. +// IGPUProgramDrvInfos represent the real data of the GPU program, stored into the driver (eg: just a GLint for opengl). +class IGPUProgramDrvInfos : public NLMISC::CRefCount { +private: + IDriver *_Driver; + ItGPUPrgDrvInfoPtrList _DriverIterator; + public: - std::string DisplayName; + IGPUProgramDrvInfos (IDriver *drv, ItGPUPrgDrvInfoPtrList it); + // The virtual dtor is important. + virtual ~IGPUProgramDrvInfos(void); - enum TFeatures - { - // World - // transform - - // Lights - Ambient = 0x0001, - Sun = 0x0002, - PointLight0 = 0x0004, - PointLight1 = 0x0008, - PointLight2 = 0x0010, - - // Lights, additional parameters for user shaders - /// Adds an enabled/disabled parameter to all of the lights - DynamicLights = 0x0020, - }; - - /// Bitfield containing features used by this vertex program. - uint Features; - - /// Indices of parameters used by features. - - /// Lights, NeL supports: - /// - Ambient light - uint AmbientIdx; // (Ambient) - /// - One directional light - uint SunDirectionIdx; // (Sun) - uint SunDiffuseIdx; // (Sun) - /// - Zero to three point lights - uint PointLight0PositionIdx; // (PointLight0) - uint PointLight0DiffuseIdx; // (PointLight0) - uint PointLight1PositionIdx; // (PointLight1) - uint PointLight1DiffuseIdx; // (PointLight1) - uint PointLight2PositionIdx; // (PointLight2) - uint PointLight2DiffuseIdx; // (PointLight2) - - /// DynamicLights - uint SunEnabledIdx; // (DynamicLights && Sun) - uint PointLight0EnabledIdx; // (DynamicLights && PointLight0) - uint PointLight1EnabledIdx; // (DynamicLights && PointLight1) - uint PointLight2EnabledIdx; // (DynamicLights && PointLight2) + virtual uint getParamIdx(char *name) const { return ~0; }; // STEREO_TODO }; -/** - * \brief CPixelProgramInfo - * \date 2013-09-07 15:00GMT - * \author Jan Boon (Kaetemi) - * Read-only information structure. - */ -struct CPixelProgramInfo -{ -public: - std::string DisplayName; - - enum TFeatures - { - /// Use texture stages from CMaterial as texture parameters - MaterialTextures = 0x0001, - /// Set driver fog parameters on this program - Fog = 0x0002, - /// Adds an enabled/disabled parameter to the fog, for user shaders - DynamicFog = 0x0004, - }; - - // Bitfield containing features used by this pixel program - uint Features; - - // Indices of parameters used by features - uint FogEnabledIdx; // (Fog && DynamicFog) nlFogEnabled, fog enabled - uint FogStartEndIdx; // (Fog) nlFogStartEnd, start and end of fog - uint FogColorIdx; // (Fog) nlFogColor, fog color -}; +class CGPUProgramSource; +class CGPUProgramSourceCont; /** - * \brief CGeometryProgramInfo - * \date 2013-09-07 15:00GMT - * \author Jan Boon (Kaetemi) - * Read-only information structure. - */ -struct CGeometryProgramInfo -{ -public: - /*enum TFeatures - { - - };*/ - /// Bitfield containing features used by this pixel program. - // uint Features; - /// Indices of parameters used by features. -}; - -/** - * \brief CGPUProgram + * \brief IGPUProgram * \date 2013-09-07 15:00GMT * \author Jan Boon (Kaetemi) * A compiled GPU program @@ -202,28 +125,23 @@ public: public: IGPUProgram(); + IGPUProgram(CGPUProgramSourceCont *programSource); virtual ~IGPUProgram(); /// Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0 - virtual uint getParamIdx(char *name) const = 0; + inline uint getParamIdx(char *name) const { return _DrvInfo->getParamIdx(name); }; - void buildVPInfo(const char *displayName, uint features); - void buildPPInfo(const char *displayName, uint features); - void buildGPInfo(const char *displayName, uint features); + /// Get the program + inline const CGPUProgramSourceCont *getProgramSource() const { return _ProgramSource; }; - inline const CVertexProgramInfo *getVPInfo() const { return Info.VertexProgram; } - inline const CPixelProgramInfo *getPPInfo() const { return Info.PixelProgram; } - inline const CGeometryProgramInfo *getGPInfo() const { return Info.GeometryProgram; } +protected: + /// The progam source + NLMISC::CSmartPtr _ProgramSource; + +public: + /// The driver information. For the driver implementation only. + NLMISC::CRefPtr _DrvInfo; -private: - union - { - CVertexProgramInfo *VertexProgram; - CPixelProgramInfo *PixelProgram; - CGeometryProgramInfo *GeometryProgram; - void *Ptr; - } Info; - }; /* class IGPUProgram */ } /* namespace NL3D */ diff --git a/code/nel/include/nel/3d/gpu_program_source.h b/code/nel/include/nel/3d/gpu_program_source.h index 7e6ba81fa..0484b28d2 100644 --- a/code/nel/include/nel/3d/gpu_program_source.h +++ b/code/nel/include/nel/3d/gpu_program_source.h @@ -45,7 +45,7 @@ namespace NL3D { * \author Jan Boon (Kaetemi) * A single GPU program with a specific profile. */ -struct CGPUProgramSource +struct CGPUProgramSource : public NLMISC::CRefCount { public: std::string DisplayName; @@ -53,11 +53,11 @@ public: /// Minimal required profile for this GPU program IGPUProgram::TProfile Profile; - char *SourcePtr; - /// Copy the source string - inline void setSource(char *source) { SourceCopy = source; SourcePtr = &source[0]; } - /// Set pointer to source string without copying the string - inline void setSourcePtr(char *sourcePtr) { SourceCopy.clear(); SourcePtr = sourcePtr; } + const char *CodePtr; + /// Copy the source code string + inline void setCode(const char *source) { CodeCopy = source; CodePtr = &source[0]; } + /// Set pointer to source code string without copying the string + inline void setCodePtr(const char *sourcePtr) { CodeCopy.clear(); CodePtr = sourcePtr; } /// CVertexProgramInfo/CPixelProgramInfo/... NeL features uint Features; @@ -66,7 +66,7 @@ public: std::map ParamIndices; private: - std::string SourceCopy; + std::string CodeCopy; }; /* class CGPUProgramSource */ @@ -77,10 +77,10 @@ private: * Container for the source code of a single GPU program, allowing * variations in different language profiles. */ -struct CGPUProgramSourceCont +struct CGPUProgramSourceCont : public NLMISC::CRefCount { -public: - std::vector Sources; +public: + std::vector > Sources; }; /* class CGPUProgramSourceCont */ diff --git a/code/nel/include/nel/3d/pixel_program.h b/code/nel/include/nel/3d/pixel_program.h index 183ad2d83..e006844aa 100644 --- a/code/nel/include/nel/3d/pixel_program.h +++ b/code/nel/include/nel/3d/pixel_program.h @@ -1,7 +1,5 @@ /** \file pixel_program.h * Pixel program definition - * - * $Id: pixel_program.h,v 1.1.2.3 2007/07/06 15:58:45 legallo Exp $ */ /* Copyright, 2000, 2001 Nevrax Ltd. @@ -28,81 +26,62 @@ #include #include +#include +#include #include namespace NL3D { -// List typedef. -class IDriver; -class IPixelProgramDrvInfos; -typedef std::list TPixelPrgDrvInfoPtrList; -typedef TPixelPrgDrvInfoPtrList::iterator ItPixelPrgDrvInfoPtrList; - -// Class for interaction of pixel program with Driver. -// IPixelProgramDrvInfos represent the real data of the pixel program, stored into the driver. -class IPixelProgramDrvInfos : public NLMISC::CRefCount -{ -private: - IDriver *_Driver; - ItPixelPrgDrvInfoPtrList _DriverIterator; - -public: - IPixelProgramDrvInfos (IDriver *drv, ItPixelPrgDrvInfoPtrList it); - // The virtual dtor is important. - virtual ~IPixelProgramDrvInfos(void); -}; - - -//------------------------------------------------------------------------------- -class CPixelProgram : public NLMISC::CRefCount +/** + * \brief CPixelProgramInfo + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * Read-only information structure. + */ +struct CPixelProgramInfo { public: - - enum TProfile - { - // TODO: - // If it's more useful, change this to a flags bitfield and - // change the d3d (and gl) code to generate the bitfield of - // supported modes instead of doing a >= version check. - - // direct3d - 0xD3D0,major,minor - ps_1_1 = 0xD3D00101, - ps_1_2 = 0xD3D00102, - ps_1_3 = 0xD3D00103, - ps_1_4 = 0xD3D00104, - ps_2_0 = 0xD3D00200, - ps_2_x = 0xD3D00201, // not sure... - ps_3_0 = 0xD3D00300, - - // opengl - 0x0610,bitfield - // fp20 = 0x061B0001, // very limited and outdated, unnecessary - // fp30 = 0x06100002, // NV_fragment_program, now arbfp1, redundant - arbfp1 = 0x06100004, // ARB_fragment_program - fp40 = 0x06100008, // NV_fragment_program2, arbfp1 with "OPTION NV_fragment_program2;\n" - gp4fp = 0x06100010, // NV_gpu_program4 - gp5fp = 0x06100020, // NV_gpu_program5 + std::string DisplayName; + + enum TFeatures + { + /// Use texture stages from CMaterial as texture parameters + MaterialTextures = 0x0001, + /// Set driver fog parameters on this program + Fog = 0x0002, + /// Adds an enabled/disabled parameter to the fog, for user shaders + DynamicFog = 0x0004, }; - /// Constructor - CPixelProgram (const char* program); + // Bitfield containing features used by this pixel program + uint Features; + // Indices of parameters used by features + uint FogEnabledIdx; // (Fog && DynamicFog) nlFogEnabled, fog enabled + uint FogStartEndIdx; // (Fog) nlFogStartEnd, start and end of fog + uint FogColorIdx; // (Fog) nlFogColor, fog color +}; + +class CPixelProgram : public IGPUProgram +{ +public: + /// Constructor + CPixelProgram(CGPUProgramSourceCont *programSource); /// Destructor virtual ~CPixelProgram (); - /// Get the program - inline const std::string& getProgram() const { return _Program; }; + /// Build feature information + void buildInfo(const char *displayName, uint features); + /// Get feature information + inline const CPixelProgramInfo *getInfo() const { return _Info; } - /// The driver informations. For the driver implementation only. - NLMISC::CRefPtr _DrvInfo; +private: -protected: - - /// The progam - std::string _Program; + /// Feature information + CPixelProgramInfo *_Info; }; - } // NL3D diff --git a/code/nel/include/nel/3d/shader.h b/code/nel/include/nel/3d/shader.h index 3377c27d4..61956e8e1 100644 --- a/code/nel/include/nel/3d/shader.h +++ b/code/nel/include/nel/3d/shader.h @@ -24,73 +24,6 @@ namespace NL3D { -using NLMISC::CRefCount; - - -class IDriver; - -// List typedef. -class IShaderDrvInfos; -typedef std::list TShaderDrvInfoPtrList; -typedef TShaderDrvInfoPtrList::iterator ItShaderDrvInfoPtrList; - -/** - * Interface for shader driver infos. - */ -class IShaderDrvInfos : public CRefCount -{ -private: - IDriver *_Driver; - ItShaderDrvInfoPtrList _DriverIterator; - -public: - IShaderDrvInfos(IDriver *drv, ItShaderDrvInfoPtrList it) {_Driver= drv; _DriverIterator= it;} - // The virtual dtor is important. - virtual ~IShaderDrvInfos(); -}; - - -/** - * Shader resource for the driver. It is just a container for a ".fx" text file. - */ -/* *** IMPORTANT ******************** - * *** IF YOU MODIFY THE STRUCTURE OF THIS CLASS, PLEASE INCREMENT IDriver::InterfaceVersion TO INVALIDATE OLD DRIVER DLL - * ********************************** - */ -// -------------------------------------------------- -class CShader -{ -public: - CShader(); - ~CShader(); - - // Load a shader file - bool loadShaderFile (const char *filename); - - // Set the shader text - void setText (const char *text); - - // Get the shader text - const char *getText () const { return _Text.c_str(); } - - // Set the shader name - void setName (const char *name); - - // Get the shader name - const char *getName () const { return _Name.c_str(); } - -public: - // Private. For Driver only. - bool _ShaderChanged; - NLMISC::CRefPtr _DrvInfo; -private: - // The shader - std::string _Text; - // The shader name - std::string _Name; -}; - - } // NL3D diff --git a/code/nel/include/nel/3d/vertex_program.h b/code/nel/include/nel/3d/vertex_program.h index 903e5ccf7..b8843e182 100644 --- a/code/nel/include/nel/3d/vertex_program.h +++ b/code/nel/include/nel/3d/vertex_program.h @@ -19,90 +19,87 @@ #include "nel/misc/types_nl.h" #include "nel/misc/smart_ptr.h" +#include "nel/3d/gpu_program.h" +#include "nel/3d/gpu_program_source.h" #include - namespace NL3D { -// List typedef. -class IDriver; -class IVertexProgramDrvInfos; -typedef std::list TVtxPrgDrvInfoPtrList; -typedef TVtxPrgDrvInfoPtrList::iterator ItVtxPrgDrvInfoPtrList; - -// Class for interaction of vertex program with Driver. -// IVertexProgramDrvInfos represent the real data of the vertex program, stored into the driver (eg: just a GLint for opengl). -class IVertexProgramDrvInfos : public NLMISC::CRefCount +/** + * \brief CVertexProgramInfo + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * Read-only information structure. + */ +struct CVertexProgramInfo { -private: - IDriver *_Driver; - ItVtxPrgDrvInfoPtrList _DriverIterator; - public: - IVertexProgramDrvInfos (IDriver *drv, ItVtxPrgDrvInfoPtrList it); - // The virtual dtor is important. - virtual ~IVertexProgramDrvInfos(void); + std::string DisplayName; + + enum TFeatures + { + // World + // transform + + // Lights + Ambient = 0x0001, + Sun = 0x0002, + PointLight0 = 0x0004, + PointLight1 = 0x0008, + PointLight2 = 0x0010, + + // Lights, additional parameters for user shaders + /// Adds an enabled/disabled parameter to all of the lights + DynamicLights = 0x0020, + }; + + /// Bitfield containing features used by this vertex program. + uint Features; + + /// Indices of parameters used by features. + + /// Lights, NeL supports: + /// - Ambient light + uint AmbientIdx; // (Ambient) + /// - One directional light + uint SunDirectionIdx; // (Sun) + uint SunDiffuseIdx; // (Sun) + /// - Zero to three point lights + uint PointLight0PositionIdx; // (PointLight0) + uint PointLight0DiffuseIdx; // (PointLight0) + uint PointLight1PositionIdx; // (PointLight1) + uint PointLight1DiffuseIdx; // (PointLight1) + uint PointLight2PositionIdx; // (PointLight2) + uint PointLight2DiffuseIdx; // (PointLight2) + + /// DynamicLights + uint SunEnabledIdx; // (DynamicLights && Sun) + uint PointLight0EnabledIdx; // (DynamicLights && PointLight0) + uint PointLight1EnabledIdx; // (DynamicLights && PointLight1) + uint PointLight2EnabledIdx; // (DynamicLights && PointLight2) }; - -/** - * This class is a vertex program. - * - * D3D / OPENGL compatibility notes: - * --------------------------------- - * - * To make your program compatible with D3D and OPENGL nel drivers, please follow thoses directives to write your vertex programs - * - * - Use only v[0], v[1] etc.. syntax for input registers. Don't use v0, v1 or v[OPOS] etc.. - * - Use only c[0], c[1] etc.. syntax for constant registers. Don't use c0, c1 etc.. - * - Use only o[HPOS], o[COL0] etc.. syntax for output registers. Don't use oPos, oD0 etc.. - * - Use only uppercase for registers R1, R2 etc.. Don't use lowercase r1, r2 etc.. - * - Use a semicolon to delineate instructions. - * - Use ARL instruction to load the adress register and not MOV. - * - Don't use the NOP instruction. - * - Don't use macros. - * - * -> Thoses programs work without any change under OpenGL. - * -> Direct3D driver implementation will have to modify the syntax on the fly before the setup like this: - * - "v[0]" must be changed in "v0" etc.. - * - "o[HPOS]" must be changed in oPos etc.. - * - Semicolon must be changed in line return character. - * - ARL instruction must be changed in MOV. - * - * Behaviour of LOG may change depending on implementation: You can only expect to have dest.z = log2(abs(src.w)). - * LIT may or may not clamp the specular exponent to [-128, 128] (not done when EXT_vertex_shader is used for example ..) - * - * Depending on the implementation, some optimizations can be achieved by masking the unused output values of instructions - * as LIT, EXPP .. - * - * \author Cyril 'Hulud' Corvazier - * \author Nevrax France - * \date 2001 - */ -class CVertexProgram : public NLMISC::CRefCount +class CVertexProgram : public IGPUProgram { public: - /// Constructor - CVertexProgram (const char* program); - + CVertexProgram(CGPUProgramSourceCont *programSource); + CVertexProgram(const char *nelvp); /// Destructor virtual ~CVertexProgram (); - /// Get the program - const std::string& getProgram () const { return _Program; }; + /// Build feature information + void buildInfo(const char *displayName, uint features); + /// Get feature information + inline const CVertexProgramInfo *getInfo() const { return _Info; } private: - /// The progam - std::string _Program; -public: - /// The driver information. For the driver implementation only. - NLMISC::CRefPtr _DrvInfo; + /// Feature information + CVertexProgramInfo *_Info; }; - } // NL3D diff --git a/code/nel/include/nel/3d/vertex_program_parse.h b/code/nel/include/nel/3d/vertex_program_parse.h index cd9f414c9..88538da07 100644 --- a/code/nel/include/nel/3d/vertex_program_parse.h +++ b/code/nel/include/nel/3d/vertex_program_parse.h @@ -21,6 +21,40 @@ #include +/** + * This class is a vertex program. + * + * D3D / OPENGL compatibility notes: + * --------------------------------- + * + * To make your program compatible with D3D and OPENGL nel drivers, please follow thoses directives to write your vertex programs + * + * - Use only v[0], v[1] etc.. syntax for input registers. Don't use v0, v1 or v[OPOS] etc.. + * - Use only c[0], c[1] etc.. syntax for constant registers. Don't use c0, c1 etc.. + * - Use only o[HPOS], o[COL0] etc.. syntax for output registers. Don't use oPos, oD0 etc.. + * - Use only uppercase for registers R1, R2 etc.. Don't use lowercase r1, r2 etc.. + * - Use a semicolon to delineate instructions. + * - Use ARL instruction to load the adress register and not MOV. + * - Don't use the NOP instruction. + * - Don't use macros. + * + * -> Thoses programs work without any change under OpenGL. + * -> Direct3D driver implementation will have to modify the syntax on the fly before the setup like this: + * - "v[0]" must be changed in "v0" etc.. + * - "o[HPOS]" must be changed in oPos etc.. + * - Semicolon must be changed in line return character. + * - ARL instruction must be changed in MOV. + * + * Behaviour of LOG may change depending on implementation: You can only expect to have dest.z = log2(abs(src.w)). + * LIT may or may not clamp the specular exponent to [-128, 128] (not done when EXT_vertex_shader is used for example ..) + * + * Depending on the implementation, some optimizations can be achieved by masking the unused output values of instructions + * as LIT, EXPP .. + * + * \author Cyril 'Hulud' Corvazier + * \author Nevrax France + * \date 2001 + */ /// Swizzle of an operand in a vertex program struct CVPSwizzle diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index fb5d5851a..f469b3b62 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -167,6 +167,8 @@ SOURCE_GROUP(Driver FILES ../../include/nel/3d/vertex_program_parse.h pixel_program.cpp ../../include/nel/3d/pixel_program.h + geometry_program.cpp + ../../include/nel/3d/geometry_program.h gpu_program.cpp ../../include/nel/3d/gpu_program.h gpu_program_source.cpp diff --git a/code/nel/src/3d/driver.cpp b/code/nel/src/3d/driver.cpp index 5a08da982..25c9afb63 100644 --- a/code/nel/src/3d/driver.cpp +++ b/code/nel/src/3d/driver.cpp @@ -58,7 +58,7 @@ IDriver::~IDriver() nlassert(_MatDrvInfos.size()==0); nlassert(_VBDrvInfos.size()==0); nlassert(_IBDrvInfos.size()==0); - nlassert(_VtxPrgDrvInfos.size()==0); + nlassert(_GPUPrgDrvInfos.size()==0); } @@ -94,14 +94,14 @@ bool IDriver::release(void) // NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted); delete *itmat; } - +/* // Release Shader drv. ItShaderDrvInfoPtrList itshd; while( (itshd = _ShaderDrvInfos.begin()) != _ShaderDrvInfos.end() ) { // NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted); delete *itshd; - } + }*/ // Release VBs drv. ItVBDrvInfoPtrList itvb; @@ -119,12 +119,12 @@ bool IDriver::release(void) delete *itib; } - // Release VtxPrg drv. - ItVtxPrgDrvInfoPtrList itVtxPrg; - while( (itVtxPrg = _VtxPrgDrvInfos.begin()) != _VtxPrgDrvInfos.end() ) + // Release GPUPrg drv. + ItGPUPrgDrvInfoPtrList itGPUPrg; + while( (itGPUPrg = _GPUPrgDrvInfos.begin()) != _GPUPrgDrvInfos.end() ) { - // NB: at IVertexProgramDrvInfos deletion, this->_VtxPrgDrvInfos is updated (entry deleted); - delete *itVtxPrg; + // NB: at IVertexProgramDrvInfos deletion, this->_GPUPrgDrvInfos is updated (entry deleted); + delete *itGPUPrg; } return true; @@ -249,7 +249,7 @@ void IDriver::removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt) _MatDrvInfos.erase(shaderIt); } // *************************************************************************** -void IDriver::removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt) +/*void IDriver::removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt) { _ShaderDrvInfos.erase(shaderIt); } @@ -262,6 +262,11 @@ void IDriver::removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt) void IDriver::removePixelPrgDrvInfoPtr(ItPixelPrgDrvInfoPtrList pixelPrgDrvInfoIt) { _PixelPrgDrvInfos.erase(pixelPrgDrvInfoIt); +}*/ +// *************************************************************************** +void IDriver::removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList vtxPrgDrvInfoIt) +{ + _GPUPrgDrvInfos.erase(vtxPrgDrvInfoIt); } // *************************************************************************** diff --git a/code/nel/src/3d/geometry_program.cpp b/code/nel/src/3d/geometry_program.cpp new file mode 100644 index 000000000..ae73d669f --- /dev/null +++ b/code/nel/src/3d/geometry_program.cpp @@ -0,0 +1,59 @@ +/** \file geometry_program.cpp + * Geometry program definition + */ + +/* Copyright, 2000, 2001 Nevrax Ltd. + * + * This file is part of NEVRAX NEL. + * NEVRAX NEL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + + * NEVRAX NEL is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with NEVRAX NEL; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "std3d.h" + +#include + +#include + +namespace NL3D +{ + +// *************************************************************************** + +CGeometryProgram::CGeometryProgram(CGPUProgramSourceCont *programSource) : _Info(NULL), IGPUProgram(programSource) +{ + +} + +// *************************************************************************** + +CGeometryProgram::~CGeometryProgram () +{ + delete _Info; + _Info = NULL; +} + +// *************************************************************************** + +void CGeometryProgram::buildInfo(const char *displayName, uint features) +{ + nlassert(_Info == NULL); + _Info = new CGeometryProgramInfo(); + CGeometryProgramInfo *info = _Info; + info->DisplayName = displayName; + info->Features = features; +} + +} // NL3D diff --git a/code/nel/src/3d/gpu_program.cpp b/code/nel/src/3d/gpu_program.cpp index 457d8b1a1..fc75e44e4 100644 --- a/code/nel/src/3d/gpu_program.cpp +++ b/code/nel/src/3d/gpu_program.cpp @@ -1,9 +1,9 @@ /** * \file gpu_program.cpp - * \brief CGPUProgram + * \brief IGPUProgram * \date 2013-09-07 15:00GMT * \author Jan Boon (Kaetemi) - * CGPUProgram + * IGPUProgram */ /* @@ -35,157 +35,50 @@ #include // Project includes +#include using namespace std; // using namespace NLMISC; namespace NL3D { +// *************************************************************************** + +IGPUProgramDrvInfos::IGPUProgramDrvInfos(IDriver *drv, ItGPUPrgDrvInfoPtrList it) +{ + _Driver = drv; + _DriverIterator = it; +} + +// *************************************************************************** + +IGPUProgramDrvInfos::~IGPUProgramDrvInfos () +{ + _Driver->removeGPUPrgDrvInfoPtr(_DriverIterator); +} + +// *************************************************************************** + IGPUProgram::IGPUProgram() { - Info.Ptr = NULL; + } +// *************************************************************************** + +IGPUProgram::IGPUProgram(CGPUProgramSourceCont *programSource) : _ProgramSource(programSource) +{ + +} + +// *************************************************************************** + IGPUProgram::~IGPUProgram() { - delete Info.Ptr; - Info.Ptr = NULL; + // Must kill the drv mirror of this program. + _DrvInfo.kill(); } -void IGPUProgram::buildVPInfo(const char *displayName, uint features) -{ - nlassert(Info.VertexProgram == NULL); - Info.VertexProgram = new CVertexProgramInfo(); - CVertexProgramInfo *info = Info.VertexProgram; - info->DisplayName = displayName; - info->Features = features; - if (features & CVertexProgramInfo::Ambient) - { - info->AmbientIdx = getParamIdx("nlAmbient"); - if (info->AmbientIdx == ~0) - { - nlwarning("Missing 'nlAmbient' in gpu program '%s', Ambient disabled", displayName); - info->Features &= ~CVertexProgramInfo::Ambient; - } - } - if (features & CVertexProgramInfo::Sun) - { - if (features & CVertexProgramInfo::DynamicLights) - { - info->SunEnabledIdx = getParamIdx("nlSunEnabled"); - if (info->SunEnabledIdx == ~0) - { - nlwarning("Missing 'nlSunEnabled' in gpu program '%s', DynamicLights disabled", displayName); - info->Features &= ~CVertexProgramInfo::DynamicLights; - } - } - info->SunDirectionIdx = getParamIdx("nlSunDirection"); - info->SunDiffuseIdx = getParamIdx("nlSunDiffuse"); - if (info->SunDirectionIdx == ~0 - || info->SunDiffuseIdx == ~0) - { - nlwarning("Missing 'nlSunDirection/nlSunDiffuse' in gpu program '%s', Sun disabled", displayName); - info->Features &= ~CVertexProgramInfo::Sun; - } - } - if (features & CVertexProgramInfo::PointLight0) - { - if (features & CVertexProgramInfo::DynamicLights) - { - info->PointLight0EnabledIdx = getParamIdx("nlPointLight0Enabled"); - if (info->PointLight0EnabledIdx == ~0) - { - nlwarning("Missing 'nlPointLight0Enabled' in gpu program '%s', DynamicLights disabled", displayName); - info->Features &= ~CVertexProgramInfo::DynamicLights; - } - } - info->PointLight0PositionIdx = getParamIdx("nlPointLight0Position"); - info->PointLight0DiffuseIdx = getParamIdx("nlPointLight0Diffuse"); - if (info->PointLight0PositionIdx == ~0 - || info->PointLight0DiffuseIdx == ~0) - { - nlwarning("Missing 'nlPointLight0Position/nlPointLight0Diffuse' in gpu program '%s', PointLight0 disabled", displayName); - info->Features &= ~CVertexProgramInfo::PointLight0; - } - } - if (features & CVertexProgramInfo::PointLight1) - { - if (features & CVertexProgramInfo::DynamicLights) - { - info->PointLight1EnabledIdx = getParamIdx("nlPointLight1Enabled"); - if (info->PointLight1EnabledIdx == ~0) - { - nlwarning("Missing 'nlPointLight1Enabled' in gpu program '%s', DynamicLights disabled", displayName); - info->Features &= ~CVertexProgramInfo::DynamicLights; - } - } - info->PointLight1PositionIdx = getParamIdx("nlPointLight1Position"); - info->PointLight1DiffuseIdx = getParamIdx("nlPointLight1Diffuse"); - if (info->PointLight1PositionIdx == ~0 - || info->PointLight1DiffuseIdx == ~0) - { - nlwarning("Missing 'nlPointLight1Position/nlPointLight1Diffuse' in gpu program '%s', PointLight1 disabled", displayName); - info->Features &= ~CVertexProgramInfo::PointLight1; - } - } - if (features & CVertexProgramInfo::PointLight2) - { - if (features & CVertexProgramInfo::DynamicLights) - { - info->PointLight2EnabledIdx = getParamIdx("nlPointLight2Enabled"); - if (info->PointLight2EnabledIdx == ~0) - { - nlwarning("Missing 'nlPointLight2Enabled' in gpu program '%s', DynamicLights disabled", displayName); - info->Features &= ~CVertexProgramInfo::DynamicLights; - } - } - info->PointLight2PositionIdx = getParamIdx("nlPointLight2Position"); - info->PointLight2DiffuseIdx = getParamIdx("nlPointLight2Diffuse"); - if (info->PointLight2PositionIdx == ~0 - || info->PointLight2DiffuseIdx == ~0) - { - nlwarning("Missing 'nlPointLight2Position/nlPointLight2Diffuse' in gpu program '%s', PointLight2 disabled", displayName); - info->Features &= ~CVertexProgramInfo::PointLight2; - } - } -} - -void IGPUProgram::buildPPInfo(const char *displayName, uint features) -{ - nlassert(Info.PixelProgram == NULL); - Info.PixelProgram = new CPixelProgramInfo(); - CPixelProgramInfo *info = Info.PixelProgram; - info->DisplayName = displayName; - info->Features = features; - if (features & CPixelProgramInfo::Fog) - { - if (features & CPixelProgramInfo::DynamicFog) - { - info->FogEnabledIdx = getParamIdx("nlFogEnabled"); - if (info->FogEnabledIdx == ~0) - { - nlwarning("Missing 'nlFogEnabled' in gpu program '%s', DynamicFog disabled", displayName); - info->Features &= ~CPixelProgramInfo::DynamicFog; - } - } - info->FogStartEndIdx = getParamIdx("nlFogStartEnd"); - info->FogColorIdx = getParamIdx("nlFogColor"); - if (info->FogStartEndIdx == ~0 - || info->FogStartEndIdx == ~0) - { - nlwarning("Missing 'nlFogStartEnd/nlFogColor' in gpu program '%s', Fog disabled", displayName); - info->Features &= ~CPixelProgramInfo::Fog; - } - } -} - -void IGPUProgram::buildGPInfo(const char *displayName, uint features) -{ - nlassert(Info.GeometryProgram == NULL); - Info.GeometryProgram = new CGeometryProgramInfo(); -} - - } /* namespace NL3D */ /* end of file */ diff --git a/code/nel/src/3d/pixel_program.cpp b/code/nel/src/3d/pixel_program.cpp index 320bfa541..8fbe8c0cf 100644 --- a/code/nel/src/3d/pixel_program.cpp +++ b/code/nel/src/3d/pixel_program.cpp @@ -1,7 +1,5 @@ /** \file pixel_program.cpp * Pixel program definition - * - * $Id: pixel_program.cpp,v 1.1.2.1 2007/04/27 17:35:07 legallo Exp $ */ /* Copyright, 2000, 2001 Nevrax Ltd. @@ -33,31 +31,49 @@ namespace NL3D { // *************************************************************************** -IPixelProgramDrvInfos::IPixelProgramDrvInfos (IDriver *drv, ItPixelPrgDrvInfoPtrList it) + +CPixelProgram::CPixelProgram(CGPUProgramSourceCont *programSource) : _Info(NULL), IGPUProgram(programSource) { - _Driver= drv; - _DriverIterator= it; + } - // *************************************************************************** -IPixelProgramDrvInfos::~IPixelProgramDrvInfos () + +CPixelProgram::~CPixelProgram () { - _Driver->removePixelPrgDrvInfoPtr (_DriverIterator); + delete _Info; + _Info = NULL; } - // *************************************************************************** -CPixelProgram::CPixelProgram(const char* program) : _Program(program) + +void CPixelProgram::buildInfo(const char *displayName, uint features) { - -} - - -// *************************************************************************** -CPixelProgram::~CPixelProgram() -{ - + nlassert(_Info == NULL); + _Info = new CPixelProgramInfo(); + CPixelProgramInfo *info = _Info; + info->DisplayName = displayName; + info->Features = features; + if (features & CPixelProgramInfo::Fog) + { + if (features & CPixelProgramInfo::DynamicFog) + { + info->FogEnabledIdx = getParamIdx("nlFogEnabled"); + if (info->FogEnabledIdx == ~0) + { + nlwarning("Missing 'nlFogEnabled' in gpu program '%s', DynamicFog disabled", displayName); + info->Features &= ~CPixelProgramInfo::DynamicFog; + } + } + info->FogStartEndIdx = getParamIdx("nlFogStartEnd"); + info->FogColorIdx = getParamIdx("nlFogColor"); + if (info->FogStartEndIdx == ~0 + || info->FogStartEndIdx == ~0) + { + nlwarning("Missing 'nlFogStartEnd/nlFogColor' in gpu program '%s', Fog disabled", displayName); + info->Features &= ~CPixelProgramInfo::Fog; + } + } } } // NL3D diff --git a/code/nel/src/3d/shader.cpp b/code/nel/src/3d/shader.cpp index a0d0c3172..9c08e9980 100644 --- a/code/nel/src/3d/shader.cpp +++ b/code/nel/src/3d/shader.cpp @@ -27,85 +27,4 @@ using namespace NLMISC; namespace NL3D { -// *************************************************************************** - -CShader::~CShader() -{ - // Must kill the drv mirror of this shader. - _DrvInfo.kill(); -} - -// *************************************************************************** - -CShader::CShader() -{ - _ShaderChanged = true; -} - -// *************************************************************************** - -void CShader::setText (const char *text) -{ - _Text = text; - _ShaderChanged = true; -} - -// *************************************************************************** - -void CShader::setName (const char *name) -{ - _Name = name; - _ShaderChanged = true; -} - -// *************************************************************************** - -bool CShader::loadShaderFile (const char *filename) -{ - _Text = ""; - // Lookup - string _filename = CPath::lookup(filename, false, true, true); - if (!_filename.empty()) - { - // File length - uint size = CFile::getFileSize (_filename); - _Text.reserve (size+1); - - try - { - CIFile file; - if (file.open (_filename)) - { - // Read it - while (!file.eof ()) - { - char line[512]; - file.getline (line, 512); - _Text += line; - } - - // Set the shader name - _Name = CFile::getFilename (filename); - return true; - } - else - { - nlwarning ("Can't open the file %s for reading", _filename.c_str()); - } - } - catch (const Exception &e) - { - nlwarning ("Error while reading %s : %s", _filename.c_str(), e.what()); - } - } - return false; -} - -// *************************************************************************** - -IShaderDrvInfos::~IShaderDrvInfos() -{ - _Driver->removeShaderDrvInfoPtr(_DriverIterator); -} - } // NL3D diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 6be97d42a..17c5c8c98 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -114,7 +114,13 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) { nlassert(!m_PixelProgram); - NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + + CGPUProgramSource *source = new CGPUProgramSource(); + CGPUProgramSourceCont *sourceCont = new CGPUProgramSourceCont(); + sourceCont->Sources.push_back(source); + source->Features = CPixelProgramInfo::MaterialTextures; + /*if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { nldebug("VR: fp40"); @@ -122,8 +128,10 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) } else*/ if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { - nldebug("VR: arbfp1"); - m_PixelProgram = new CPixelProgram(a_arbfp1); + nldebug("VR: arbfp1"); + source->Profile = IGPUProgram::arbfp1; + source->setCodePtr(a_arbfp1); + m_PixelProgram = new CPixelProgram(sourceCont); } /*else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) { diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index a57a0ffcb..00db2020e 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -237,21 +237,33 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) { nlassert(!m_PixelProgram); - NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + + CGPUProgramSource *source = new CGPUProgramSource(); + CGPUProgramSourceCont *sourceCont = new CGPUProgramSourceCont(); + sourceCont->Sources.push_back(source); + source->Features = CPixelProgramInfo::MaterialTextures; + if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { nldebug("VR: fp40"); - m_PixelProgram = new CPixelProgram(g_StereoOVR_fp40); + source->Profile = IGPUProgram::fp40; + source->setCodePtr(g_StereoOVR_fp40); + m_PixelProgram = new CPixelProgram(sourceCont); } else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { nldebug("VR: arbfp1"); - m_PixelProgram = new CPixelProgram(g_StereoOVR_arbfp1); + source->Profile = IGPUProgram::arbfp1; + source->setCodePtr(g_StereoOVR_arbfp1); + m_PixelProgram = new CPixelProgram(sourceCont); } else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) { nldebug("VR: ps_2_0"); - m_PixelProgram = new CPixelProgram(g_StereoOVR_ps_2_0); + source->Profile = IGPUProgram::ps_2_0; + source->setCodePtr(g_StereoOVR_ps_2_0); + m_PixelProgram = new CPixelProgram(sourceCont); } if (m_PixelProgram) diff --git a/code/nel/src/3d/vertex_program.cpp b/code/nel/src/3d/vertex_program.cpp index 9e7587069..2f70d51af 100644 --- a/code/nel/src/3d/vertex_program.cpp +++ b/code/nel/src/3d/vertex_program.cpp @@ -24,34 +24,131 @@ namespace NL3D { - // *************************************************************************** -IVertexProgramDrvInfos::IVertexProgramDrvInfos (IDriver *drv, ItVtxPrgDrvInfoPtrList it) + +CVertexProgram::CVertexProgram(CGPUProgramSourceCont *programSource) : _Info(NULL), IGPUProgram(programSource) { - _Driver= drv; - _DriverIterator= it; + } - // *************************************************************************** -IVertexProgramDrvInfos::~IVertexProgramDrvInfos () + +CVertexProgram::CVertexProgram(const char *nelvp) : _Info(NULL) { - _Driver->removeVtxPrgDrvInfoPtr (_DriverIterator); + CGPUProgramSource *source = new CGPUProgramSource(); + _ProgramSource = new CGPUProgramSourceCont(); + _ProgramSource->Sources.push_back(source); + source->Profile = IGPUProgram::nelvp; + source->setCode(nelvp); + source->Features = 0; } - // *************************************************************************** -CVertexProgram::CVertexProgram (const char* program) -{ - _Program=program; -} - -// *************************************************************************** CVertexProgram::~CVertexProgram () { - // Must kill the drv mirror of this VB. - _DrvInfo.kill(); + delete _Info; + _Info = NULL; +} + +// *************************************************************************** + +void CVertexProgram::buildInfo(const char *displayName, uint features) +{ + nlassert(_Info == NULL); + _Info = new CVertexProgramInfo(); + CVertexProgramInfo *info = _Info; + info->DisplayName = displayName; + info->Features = features; + if (features & CVertexProgramInfo::Ambient) + { + info->AmbientIdx = getParamIdx("nlAmbient"); + if (info->AmbientIdx == ~0) + { + nlwarning("Missing 'nlAmbient' in gpu program '%s', Ambient disabled", displayName); + info->Features &= ~CVertexProgramInfo::Ambient; + } + } + if (features & CVertexProgramInfo::Sun) + { + if (features & CVertexProgramInfo::DynamicLights) + { + info->SunEnabledIdx = getParamIdx("nlSunEnabled"); + if (info->SunEnabledIdx == ~0) + { + nlwarning("Missing 'nlSunEnabled' in gpu program '%s', DynamicLights disabled", displayName); + info->Features &= ~CVertexProgramInfo::DynamicLights; + } + } + info->SunDirectionIdx = getParamIdx("nlSunDirection"); + info->SunDiffuseIdx = getParamIdx("nlSunDiffuse"); + if (info->SunDirectionIdx == ~0 + || info->SunDiffuseIdx == ~0) + { + nlwarning("Missing 'nlSunDirection/nlSunDiffuse' in gpu program '%s', Sun disabled", displayName); + info->Features &= ~CVertexProgramInfo::Sun; + } + } + if (features & CVertexProgramInfo::PointLight0) + { + if (features & CVertexProgramInfo::DynamicLights) + { + info->PointLight0EnabledIdx = getParamIdx("nlPointLight0Enabled"); + if (info->PointLight0EnabledIdx == ~0) + { + nlwarning("Missing 'nlPointLight0Enabled' in gpu program '%s', DynamicLights disabled", displayName); + info->Features &= ~CVertexProgramInfo::DynamicLights; + } + } + info->PointLight0PositionIdx = getParamIdx("nlPointLight0Position"); + info->PointLight0DiffuseIdx = getParamIdx("nlPointLight0Diffuse"); + if (info->PointLight0PositionIdx == ~0 + || info->PointLight0DiffuseIdx == ~0) + { + nlwarning("Missing 'nlPointLight0Position/nlPointLight0Diffuse' in gpu program '%s', PointLight0 disabled", displayName); + info->Features &= ~CVertexProgramInfo::PointLight0; + } + } + if (features & CVertexProgramInfo::PointLight1) + { + if (features & CVertexProgramInfo::DynamicLights) + { + info->PointLight1EnabledIdx = getParamIdx("nlPointLight1Enabled"); + if (info->PointLight1EnabledIdx == ~0) + { + nlwarning("Missing 'nlPointLight1Enabled' in gpu program '%s', DynamicLights disabled", displayName); + info->Features &= ~CVertexProgramInfo::DynamicLights; + } + } + info->PointLight1PositionIdx = getParamIdx("nlPointLight1Position"); + info->PointLight1DiffuseIdx = getParamIdx("nlPointLight1Diffuse"); + if (info->PointLight1PositionIdx == ~0 + || info->PointLight1DiffuseIdx == ~0) + { + nlwarning("Missing 'nlPointLight1Position/nlPointLight1Diffuse' in gpu program '%s', PointLight1 disabled", displayName); + info->Features &= ~CVertexProgramInfo::PointLight1; + } + } + if (features & CVertexProgramInfo::PointLight2) + { + if (features & CVertexProgramInfo::DynamicLights) + { + info->PointLight2EnabledIdx = getParamIdx("nlPointLight2Enabled"); + if (info->PointLight2EnabledIdx == ~0) + { + nlwarning("Missing 'nlPointLight2Enabled' in gpu program '%s', DynamicLights disabled", displayName); + info->Features &= ~CVertexProgramInfo::DynamicLights; + } + } + info->PointLight2PositionIdx = getParamIdx("nlPointLight2Position"); + info->PointLight2DiffuseIdx = getParamIdx("nlPointLight2Diffuse"); + if (info->PointLight2PositionIdx == ~0 + || info->PointLight2DiffuseIdx == ~0) + { + nlwarning("Missing 'nlPointLight2Position/nlPointLight2Diffuse' in gpu program '%s', PointLight2 disabled", displayName); + info->Features &= ~CVertexProgramInfo::PointLight2; + } + } } } // NL3D From f4fccab548b451ff4df1def85843e3de6f1547c3 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 7 Sep 2013 21:30:40 +0200 Subject: [PATCH 095/137] Implement new gpu program interface in opengl driver --- code/nel/include/nel/3d/gpu_program.h | 2 +- code/nel/include/nel/3d/gpu_program_source.h | 10 +- code/nel/src/3d/driver.cpp | 2 +- .../src/3d/driver/opengl/driver_opengl.cpp | 8 -- code/nel/src/3d/driver/opengl/driver_opengl.h | 30 ++++-- .../opengl/driver_opengl_pixel_program.cpp | 59 ++++++++---- .../3d/driver/opengl/driver_opengl_vertex.cpp | 4 +- .../opengl/driver_opengl_vertex_program.cpp | 93 ++++++++++++++++--- code/nel/src/3d/stereo_debugger.cpp | 2 +- code/nel/src/3d/stereo_ovr.cpp | 6 +- code/nel/src/3d/vertex_program.cpp | 2 +- 11 files changed, 157 insertions(+), 61 deletions(-) diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index 3df13ac3d..ba0afb9e4 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -57,7 +57,7 @@ public: // The virtual dtor is important. virtual ~IGPUProgramDrvInfos(void); - virtual uint getParamIdx(char *name) const { return ~0; }; // STEREO_TODO + virtual uint getParamIdx(char *name) const = 0; }; class CGPUProgramSource; diff --git a/code/nel/include/nel/3d/gpu_program_source.h b/code/nel/include/nel/3d/gpu_program_source.h index 0484b28d2..c51ac67ce 100644 --- a/code/nel/include/nel/3d/gpu_program_source.h +++ b/code/nel/include/nel/3d/gpu_program_source.h @@ -53,11 +53,13 @@ public: /// Minimal required profile for this GPU program IGPUProgram::TProfile Profile; - const char *CodePtr; + const char *SourcePtr; + size_t SourceLen; /// Copy the source code string - inline void setCode(const char *source) { CodeCopy = source; CodePtr = &source[0]; } + inline void setSource(const char *source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); } /// Set pointer to source code string without copying the string - inline void setCodePtr(const char *sourcePtr) { CodeCopy.clear(); CodePtr = sourcePtr; } + inline void setSourcePtr(const char *sourcePtr, size_t sourceLen) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = sourceLen; } + inline void setSourcePtr(const char *sourcePtr) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = strlen(sourcePtr); } /// CVertexProgramInfo/CPixelProgramInfo/... NeL features uint Features; @@ -66,7 +68,7 @@ public: std::map ParamIndices; private: - std::string CodeCopy; + std::string SourceCopy; }; /* class CGPUProgramSource */ diff --git a/code/nel/src/3d/driver.cpp b/code/nel/src/3d/driver.cpp index 25c9afb63..3bd354a62 100644 --- a/code/nel/src/3d/driver.cpp +++ b/code/nel/src/3d/driver.cpp @@ -33,7 +33,7 @@ namespace NL3D { // *************************************************************************** -const uint32 IDriver::InterfaceVersion = 0x6c; // pixel program interface +const uint32 IDriver::InterfaceVersion = 0x6d; // gpu program interface // *************************************************************************** IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" ) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 92021c65b..a93c05338 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -2573,14 +2573,6 @@ CVertexBuffer::TVertexColorType CDriverGL::getVertexColorFormat() const return CVertexBuffer::TRGBA; } -// *************************************************************************** -bool CDriverGL::activeShader(CShader * /* shd */) -{ - H_AUTO_OGL(CDriverGL_activeShader) - - return false; -} - // *************************************************************************** void CDriverGL::startBench (bool wantStandardDeviation, bool quick, bool reset) { diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 08e950b70..5289f2a26 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -406,8 +406,6 @@ public: virtual CMatrix getViewMatrix() const; - virtual bool activeShader(CShader *shd); - virtual void forceNormalize(bool normalize) { _ForceNormalize= normalize; @@ -1349,7 +1347,7 @@ private: /// \name Pixel program implementation // @{ bool activeARBPixelProgram (CPixelProgram *program); - bool setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, bool &specularWritten*/); + bool setupPixelProgram (CPixelProgram *program, GLuint id/*, bool &specularWritten*/); //@} @@ -1530,7 +1528,7 @@ private: }; // *************************************************************************** -class CVertexProgamDrvInfosGL : public IVertexProgramDrvInfos +class CVertexProgamDrvInfosGL : public IGPUProgramDrvInfos { public: // The GL Id. @@ -1551,18 +1549,36 @@ public: // The gl id is auto created here. - CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it); + CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); + + virtual uint getParamIdx(char *name) const + { + std::map::const_iterator it = ParamIndices.find(name); + if (it != ParamIndices.end()) return it->second; + return ~0; + }; + + std::map ParamIndices; }; // *************************************************************************** -class CPixelProgamDrvInfosGL : public IPixelProgramDrvInfos +class CPixelProgamDrvInfosGL : public IGPUProgramDrvInfos { public: // The GL Id. GLuint ID; // The gl id is auto created here. - CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it); + CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); + + virtual uint getParamIdx(char *name) const + { + std::map::const_iterator it = ParamIndices.find(name); + if (it != ParamIndices.end()) return it->second; + return ~0; + }; + + std::map ParamIndices; }; #ifdef NL_STATIC diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index 2bcfc185d..b2867a95a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -50,7 +50,7 @@ namespace NLDRIVERGL { #endif // *************************************************************************** -CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it) +CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it) { H_AUTO_OGL(CPixelProgamDrvInfosGL_CPixelProgamDrvInfosGL) // Extension must exist @@ -109,25 +109,25 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) if (program->_DrvInfo==NULL) { // Insert into driver list. (so it is deleted when driver is deleted). - ItPixelPrgDrvInfoPtrList it= _PixelPrgDrvInfos.insert(_PixelPrgDrvInfos.end(), (NL3D::IPixelProgramDrvInfos*)NULL); + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); // Create a driver info - *it = drvInfo = new CPixelProgamDrvInfosGL (this, it); + *it = drvInfo = new CPixelProgamDrvInfosGL(this, it); // Set the pointer - program->_DrvInfo=drvInfo; + program->_DrvInfo = drvInfo; - if(!setupARBPixelProgram(program, drvInfo->ID)) + if (!setupPixelProgram(program, drvInfo->ID)) { delete drvInfo; program->_DrvInfo = NULL; - _PixelPrgDrvInfos.erase(it); + _GPUPrgDrvInfos.erase(it); return false; } } else { // Cast the driver info pointer - drvInfo=safe_cast((IPixelProgramDrvInfos*)program->_DrvInfo); + drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); } glEnable( GL_FRAGMENT_PROGRAM_ARB ); _PixelProgramEnabled = true; @@ -148,15 +148,31 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) } // *************************************************************************** -bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, bool &specularWritten*/) +bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &specularWritten*/) { H_AUTO_OGL(CDriverGL_setupARBPixelProgram) + + CPixelProgamDrvInfosGL *drvInfo = static_cast((IGPUProgramDrvInfos *)program->_DrvInfo); - const std::string &code = program->getProgram(); + // Find a supported pixel program profile + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile)) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("No supported source profile for pixel program"); + return false; + } + // Compile the program nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, id); glGetError(); - nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, code.size(), code.c_str() ); + nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, source->SourceLen, source->SourcePtr); GLenum err = glGetError(); if (err != GL_NO_ERROR) { @@ -165,25 +181,25 @@ bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, GLint position; glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &position); nlassert(position != -1); // there was an error.. - nlassert(position < (GLint) code.size()); + nlassert(position < (GLint) source->SourceLen); uint line = 0; - const char *lineStart = program->getProgram().c_str(); + const char *lineStart = source->SourcePtr; for(uint k = 0; k < (uint) position; ++k) { - if (code[k] == '\n') + if (source->SourcePtr[k] == '\n') { - lineStart = code.c_str() + k; + lineStart = source->SourcePtr + k; ++line; } } nlwarning("ARB fragment program parse error at line %d.", (int) line); // search end of line - const char *lineEnd = code.c_str() + code.size(); - for(uint k = position; k < code.size(); ++k) + const char *lineEnd = source->SourcePtr + source->SourceLen; + for(uint k = position; k < source->SourceLen; ++k) { - if (code[k] == '\n') + if (source->SourcePtr[k] == '\n') { - lineEnd = code.c_str() + k; + lineEnd = source->SourcePtr + k; break; } } @@ -196,6 +212,13 @@ bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, nlassert(0); return false; } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); + return true; } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp index 14ed83adb..521a13baf 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp @@ -1151,7 +1151,7 @@ void CDriverGL::toggleGlArraysForEXTVertexShader() CVertexProgram *vp = _LastSetuppedVP; if (vp) { - CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IVertexProgramDrvInfos *) vp->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IGPUProgramDrvInfos *) vp->_DrvInfo); if (drvInfo) { // Disable all VertexAttribs. @@ -1396,7 +1396,7 @@ void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb) CVertexProgram *vp = _LastSetuppedVP; if (!vp) return; - CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IVertexProgramDrvInfos *) vp->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IGPUProgramDrvInfos *) vp->_DrvInfo); if (!drvInfo) return; uint32 flags= vb.VertexFormat; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp index 1ddb42a7d..34ae2365a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp @@ -41,7 +41,7 @@ namespace NLDRIVERGL { #endif // *************************************************************************** -CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it) : IVertexProgramDrvInfos (drv, it) +CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL(CDriverGL *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it) { H_AUTO_OGL(CVertexProgamDrvInfosGL_CVertexProgamDrvInfosGL); @@ -105,13 +105,28 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) // Program setuped ? if (program->_DrvInfo==NULL) { + // Find nelvp + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; + } + /** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..). * There are some incompatibilities. */ CVPParser parser; CVPParser::TProgram parsedProgram; std::string errorOutput; - bool result = parser.parse(program->getProgram().c_str(), parsedProgram, errorOutput); + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); if (!result) { nlwarning("Unable to parse a vertex program :"); @@ -123,7 +138,7 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) } // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); + ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); // Create a driver info *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); @@ -132,7 +147,7 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) program->_DrvInfo=drvInfo; // Compile the program - nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)program->getProgram().length(), (const GLubyte*)program->getProgram().c_str()); + nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr); // Get loading error code GLint errorOff; @@ -142,8 +157,8 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) if (errorOff>=0) { // String length - uint length = (uint)program->getProgram ().length(); - const char* sString= program->getProgram ().c_str(); + uint length = (uint)source->SourceLen; + const char* sString = source->SourcePtr; // Line count and char count uint line=1; @@ -176,13 +191,19 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) return false; } + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); + // Setup ok return true; } else { // Cast the driver info pointer - drvInfo=safe_cast((IVertexProgramDrvInfos*)program->_DrvInfo); + drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); } // Setup this program @@ -1503,11 +1524,26 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program) // Program setuped ? if (program->_DrvInfo==NULL) { + // Find nelvp + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; + } + // try to parse the program CVPParser parser; CVPParser::TProgram parsedProgram; std::string errorOutput; - bool result = parser.parse(program->getProgram().c_str(), parsedProgram, errorOutput); + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); if (!result) { nlwarning("Unable to parse a vertex program."); @@ -1517,7 +1553,7 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program) return false; } // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); + ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); // Create a driver info *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); @@ -1528,14 +1564,20 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program) { delete drvInfo; program->_DrvInfo = NULL; - _VtxPrgDrvInfos.erase(it); + _GPUPrgDrvInfos.erase(it); return false; } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); } else { // Cast the driver info pointer - drvInfo=safe_cast((IVertexProgramDrvInfos*)program->_DrvInfo); + drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); } glEnable( GL_VERTEX_PROGRAM_ARB ); _VertexProgramEnabled = true; @@ -1577,11 +1619,26 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program) // Program setuped ? if (program->_DrvInfo==NULL) { + // Find nelvp + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; + } + // try to parse the program CVPParser parser; CVPParser::TProgram parsedProgram; std::string errorOutput; - bool result = parser.parse(program->getProgram().c_str(), parsedProgram, errorOutput); + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); if (!result) { nlwarning("Unable to parse a vertex program."); @@ -1603,7 +1660,7 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program) */ // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); + ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); // Create a driver info *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); @@ -1614,14 +1671,20 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program) { delete drvInfo; program->_DrvInfo = NULL; - _VtxPrgDrvInfos.erase(it); + _GPUPrgDrvInfos.erase(it); return false; } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); } else { // Cast the driver info pointer - drvInfo=safe_cast((IVertexProgramDrvInfos*)program->_DrvInfo); + drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); } glEnable( GL_VERTEX_SHADER_EXT); diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 17c5c8c98..509ba4769 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -130,7 +130,7 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) { nldebug("VR: arbfp1"); source->Profile = IGPUProgram::arbfp1; - source->setCodePtr(a_arbfp1); + source->setSourcePtr(a_arbfp1); m_PixelProgram = new CPixelProgram(sourceCont); } /*else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 00db2020e..8c8c6ff63 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -248,21 +248,21 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) { nldebug("VR: fp40"); source->Profile = IGPUProgram::fp40; - source->setCodePtr(g_StereoOVR_fp40); + source->setSourcePtr(g_StereoOVR_fp40); m_PixelProgram = new CPixelProgram(sourceCont); } else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { nldebug("VR: arbfp1"); source->Profile = IGPUProgram::arbfp1; - source->setCodePtr(g_StereoOVR_arbfp1); + source->setSourcePtr(g_StereoOVR_arbfp1); m_PixelProgram = new CPixelProgram(sourceCont); } else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) { nldebug("VR: ps_2_0"); source->Profile = IGPUProgram::ps_2_0; - source->setCodePtr(g_StereoOVR_ps_2_0); + source->setSourcePtr(g_StereoOVR_ps_2_0); m_PixelProgram = new CPixelProgram(sourceCont); } diff --git a/code/nel/src/3d/vertex_program.cpp b/code/nel/src/3d/vertex_program.cpp index 2f70d51af..d0acbe775 100644 --- a/code/nel/src/3d/vertex_program.cpp +++ b/code/nel/src/3d/vertex_program.cpp @@ -39,7 +39,7 @@ CVertexProgram::CVertexProgram(const char *nelvp) : _Info(NULL) _ProgramSource = new CGPUProgramSourceCont(); _ProgramSource->Sources.push_back(source); source->Profile = IGPUProgram::nelvp; - source->setCode(nelvp); + source->setSource(nelvp); source->Features = 0; } From f4d05d25c5e326ad678fdb14b9b3f9d31b5f9b69 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sat, 7 Sep 2013 22:00:07 +0200 Subject: [PATCH 096/137] Implement new gpu program interface in direct3d driver --- code/nel/include/nel/3d/driver.h | 11 +- code/nel/include/nel/3d/material.h | 1 - code/nel/include/nel/3d/shader.h | 32 ----- code/nel/src/3d/CMakeLists.txt | 2 - code/nel/src/3d/driver.cpp | 9 -- .../3d/driver/direct3d/driver_direct3d.cpp | 7 ++ .../src/3d/driver/direct3d/driver_direct3d.h | 111 ++++++++++++++++-- .../driver_direct3d_pixel_program.cpp | 36 ++++-- .../direct3d/driver_direct3d_shader.cpp | 91 +++++++++++++- .../driver_direct3d_vertex_program.cpp | 34 +++++- code/nel/src/3d/driver/opengl/driver_opengl.h | 1 - code/nel/src/3d/material.cpp | 1 - code/nel/src/3d/shader.cpp | 30 ----- 13 files changed, 256 insertions(+), 110 deletions(-) delete mode 100644 code/nel/include/nel/3d/shader.h delete mode 100644 code/nel/src/3d/shader.cpp diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 3cb0c0349..2d10c5653 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -26,11 +26,11 @@ #include "nel/misc/uv.h" #include "nel/misc/hierarchical_timer.h" #include "nel/3d/texture.h" -#include "nel/3d/shader.h" #include "nel/3d/vertex_buffer.h" #include "nel/3d/index_buffer.h" #include "nel/3d/vertex_program.h" #include "nel/3d/pixel_program.h" +#include "nel/3d/geometry_program.h" #include "nel/3d/material.h" #include "nel/misc/mutex.h" #include "nel/3d/primitive_profile.h" @@ -152,9 +152,6 @@ protected: TIBDrvInfoPtrList _IBDrvInfos; TPolygonMode _PolygonMode; TGPUPrgDrvInfoPtrList _GPUPrgDrvInfos; - // TPixelPrgDrvInfoPtrList _PixelPrgDrvInfos; - // TGeomPrgDrvInfoPtrList _GeomPrgDrvInfos; - // TShaderDrvInfoPtrList _ShaderDrvInfos; uint _ResetCounter; @@ -1299,9 +1296,6 @@ protected: friend class CTextureDrvShare; friend class ITextureDrvInfos; friend class IMaterialDrvInfos; - // friend class IVertexProgramDrvInfos; - // friend class IPixelProgramDrvInfos; - // friend class IShaderDrvInfos; friend class IGPUProgramDrvInfos; /// remove ptr from the lists in the driver. @@ -1310,9 +1304,6 @@ protected: void removeTextureDrvInfoPtr(ItTexDrvInfoPtrMap texDrvInfoIt); void removeTextureDrvSharePtr(ItTexDrvSharePtrList texDrvShareIt); void removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt); - // void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt); - // void removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt); - // void removePixelPrgDrvInfoPtr(ItPixelPrgDrvInfoPtrList pixelPrgDrvInfoIt); void removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt); private: diff --git a/code/nel/include/nel/3d/material.h b/code/nel/include/nel/3d/material.h index bf00f9741..6d9589ca5 100644 --- a/code/nel/include/nel/3d/material.h +++ b/code/nel/include/nel/3d/material.h @@ -22,7 +22,6 @@ #include "nel/misc/rgba.h" #include "nel/misc/matrix.h" #include "nel/3d/texture.h" -#include "nel/3d/shader.h" #include diff --git a/code/nel/include/nel/3d/shader.h b/code/nel/include/nel/3d/shader.h deleted file mode 100644 index 61956e8e1..000000000 --- a/code/nel/include/nel/3d/shader.h +++ /dev/null @@ -1,32 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_SHADER_H -#define NL_SHADER_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/smart_ptr.h" -#include - - -namespace NL3D { - -} // NL3D - - -#endif // NL_SHADER_H - -/* End of shader.h */ diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index f469b3b62..242cb754c 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -153,8 +153,6 @@ SOURCE_GROUP(Driver FILES ../../include/nel/3d/scene.h scene_group.cpp ../../include/nel/3d/scene_group.h - shader.cpp - ../../include/nel/3d/shader.h texture.cpp ../../include/nel/3d/texture.h vertex_buffer.cpp diff --git a/code/nel/src/3d/driver.cpp b/code/nel/src/3d/driver.cpp index 3bd354a62..31dd4d2ec 100644 --- a/code/nel/src/3d/driver.cpp +++ b/code/nel/src/3d/driver.cpp @@ -20,7 +20,6 @@ #include "nel/misc/types_nl.h" #include "nel/3d/driver.h" -#include "nel/3d/shader.h" #include "nel/3d/vertex_buffer.h" #include "nel/misc/algo.h" @@ -94,14 +93,6 @@ bool IDriver::release(void) // NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted); delete *itmat; } -/* - // Release Shader drv. - ItShaderDrvInfoPtrList itshd; - while( (itshd = _ShaderDrvInfos.begin()) != _ShaderDrvInfos.end() ) - { - // NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted); - delete *itshd; - }*/ // Release VBs drv. ItVBDrvInfoPtrList itvb; diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index 8f8901f5c..e7c1ba693 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -1710,6 +1710,13 @@ bool CDriverD3D::release() // Call IDriver::release() before, to destroy textures, shaders and VBs... IDriver::release(); + ItShaderDrvInfoPtrList itshd; + while( (itshd = _ShaderDrvInfos.begin()) != _ShaderDrvInfos.end() ) + { + // NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted); + delete *itshd; + } + _SwapBufferCounter = 0; if (_QuadIB) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 085bb7512..d329a6f56 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -35,7 +35,6 @@ #include "nel/3d/scissor.h" #include "nel/3d/driver.h" #include "nel/3d/material.h" -#include "nel/3d/shader.h" #include "nel/3d/vertex_buffer.h" #include "nel/3d/index_buffer.h" #include "nel/3d/ptr_set.h" @@ -181,6 +180,75 @@ public: }; +using NLMISC::CRefCount; + + +class IDriver; +class CDriverD3D; + +// List typedef. +class IShaderDrvInfos; +typedef std::list TShaderDrvInfoPtrList; +typedef TShaderDrvInfoPtrList::iterator ItShaderDrvInfoPtrList; + +/** + * Interface for shader driver infos. + */ +class IShaderDrvInfos : public CRefCount +{ +private: + CDriverD3D *_Driver; + ItShaderDrvInfoPtrList _DriverIterator; + +public: + IShaderDrvInfos(CDriverD3D *drv, ItShaderDrvInfoPtrList it) {_Driver= drv; _DriverIterator= it;} + // The virtual dtor is important. + virtual ~IShaderDrvInfos(); +}; + + +/** + * Shader resource for the driver. It is just a container for a ".fx" text file. + */ +/* *** IMPORTANT ******************** + * *** IF YOU MODIFY THE STRUCTURE OF THIS CLASS, PLEASE INCREMENT IDriver::InterfaceVersion TO INVALIDATE OLD DRIVER DLL + * ********************************** + */ +// -------------------------------------------------- +class CShader +{ +public: + CShader(); + ~CShader(); + + // Load a shader file + bool loadShaderFile (const char *filename); + + // Set the shader text + void setText (const char *text); + + // Get the shader text + const char *getText () const { return _Text.c_str(); } + + // Set the shader name + void setName (const char *name); + + // Get the shader name + const char *getName () const { return _Name.c_str(); } + +public: + // Private. For Driver only. + bool _ShaderChanged; + NLMISC::CRefPtr _DrvInfo; +private: + // The shader + std::string _Text; + // The shader name + std::string _Name; +}; + + + // *************************************************************************** class CTextureDrvInfosD3D : public ITextureDrvInfos { @@ -229,29 +297,48 @@ public: }; + // *************************************************************************** -class CVertexProgamDrvInfosD3D : public IVertexProgramDrvInfos +class CVertexProgamDrvInfosD3D : public IGPUProgramDrvInfos { public: // The shader IDirect3DVertexShader9 *Shader; - CVertexProgamDrvInfosD3D(IDriver *drv, ItVtxPrgDrvInfoPtrList it); + CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it); ~CVertexProgamDrvInfosD3D(); + + virtual uint getParamIdx(char *name) const + { + std::map::const_iterator it = ParamIndices.find(name); + if (it != ParamIndices.end()) return it->second; + return ~0; + }; + + std::map ParamIndices; }; // *************************************************************************** -class CPixelProgramDrvInfosD3D : public IPixelProgramDrvInfos +class CPixelProgramDrvInfosD3D : public IGPUProgramDrvInfos { public: // The shader IDirect3DPixelShader9 *Shader; - CPixelProgramDrvInfosD3D(IDriver *drv, ItPixelPrgDrvInfoPtrList it); + CPixelProgramDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it); ~CPixelProgramDrvInfosD3D(); + + virtual uint getParamIdx(char *name) const + { + std::map::const_iterator it = ParamIndices.find(name); + if (it != ParamIndices.end()) return it->second; + return ~0; + }; + + std::map ParamIndices; }; @@ -346,7 +433,7 @@ public: // Scalar handles D3DXHANDLE ScalarFloatHandle[MaxShaderTexture]; - CShaderDrvInfosD3D(IDriver *drv, ItShaderDrvInfoPtrList it); + CShaderDrvInfosD3D(CDriverD3D *drv, ItShaderDrvInfoPtrList it); virtual ~CShaderDrvInfosD3D(); }; @@ -1048,7 +1135,7 @@ public: * ColorOp[n] = DISABLE; * AlphaOp[n] = DISABLE; */ - virtual bool activeShader(CShader *shd); + bool activeShader(CShader *shd); // Bench virtual void startBench (bool wantStandardDeviation = false, bool quick = false, bool reset = true); @@ -1922,7 +2009,7 @@ public: { H_AUTO_D3D(CDriverD3D_getPixelProgramD3D); CPixelProgramDrvInfosD3D* d3dPixelProgram; - d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IPixelProgramDrvInfos*)(pixelProgram._DrvInfo); + d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IGPUProgramDrvInfos*)(pixelProgram._DrvInfo); return d3dPixelProgram; } @@ -1931,7 +2018,7 @@ public: { H_AUTO_D3D(CDriverD3D_getVertexProgramD3D); CVertexProgamDrvInfosD3D* d3dVertexProgram; - d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IVertexProgramDrvInfos*)(vertexProgram._DrvInfo); + d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IGPUProgramDrvInfos*)(vertexProgram._DrvInfo); return d3dVertexProgram; } @@ -2114,6 +2201,8 @@ private: void findNearestFullscreenVideoMode(); + TShaderDrvInfoPtrList _ShaderDrvInfos; + // Windows std::string _WindowClass; HWND _HWnd; @@ -2563,6 +2652,10 @@ public: // Clip the wanted rectangle with window. return true if rect is not NULL. bool clipRect(NLMISC::CRect &rect); + friend class IShaderDrvInfos; + + void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt); + }; #define NL_D3DCOLOR_RGBA(rgba) (D3DCOLOR_ARGB(rgba.A,rgba.R,rgba.G,rgba.B)) 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 8234fc31d..db8763091 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 @@ -37,7 +37,7 @@ namespace NL3D // *************************************************************************** -CPixelProgramDrvInfosD3D::CPixelProgramDrvInfosD3D(IDriver *drv, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it) +CPixelProgramDrvInfosD3D::CPixelProgramDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it) { H_AUTO_D3D(CPixelProgramDrvInfosD3D_CPixelProgamDrvInfosD3D) Shader = NULL; @@ -81,18 +81,32 @@ bool CDriverD3D::activePixelProgram(CPixelProgram *program) // Program setuped ? if (program->_DrvInfo==NULL) { - _PixelPrgDrvInfos.push_front (NULL); - ItPixelPrgDrvInfoPtrList itPix = _PixelPrgDrvInfos.begin(); - *itPix = new CPixelProgramDrvInfosD3D(this, itPix); + // Find a supported pixel program profile + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile)) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("No supported source profile for pixel program"); + return false; + } + + _GPUPrgDrvInfos.push_front (NULL); + ItGPUPrgDrvInfoPtrList itPix = _GPUPrgDrvInfos.begin(); + CPixelProgramDrvInfosD3D *drvInfo; + *itPix = drvInfo = new CPixelProgramDrvInfosD3D(this, itPix); // Create a driver info structure program->_DrvInfo = *itPix; - const std::string &dest = program->getProgram(); - LPD3DXBUFFER pShader; LPD3DXBUFFER pErrorMsgs; - if (D3DXAssembleShader (dest.c_str(), dest.size(), NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK) + if (D3DXAssembleShader(source->SourcePtr, source->SourceLen, NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK) { if (_DeviceInterface->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), &(getPixelProgramD3D(*program)->Shader)) != D3D_OK) return false; @@ -103,13 +117,19 @@ bool CDriverD3D::activePixelProgram(CPixelProgram *program) nlwarning ((const char*)pErrorMsgs->GetBufferPointer()); return false; } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); } } // Set the pixel program if (program) { - CPixelProgramDrvInfosD3D *info = static_cast((IPixelProgramDrvInfos*)program->_DrvInfo); + CPixelProgramDrvInfosD3D *info = static_cast((IGPUProgramDrvInfos*)program->_DrvInfo); setPixelShader (info->Shader); float z = 0; diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp index b9b757de1..300cfe4b7 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp @@ -17,6 +17,8 @@ #include "stddirect3d.h" #include "driver_direct3d.h" +#include "nel/misc/path.h" +#include "nel/misc/file.h" using namespace std; using namespace NLMISC; @@ -24,6 +26,93 @@ using namespace NLMISC; namespace NL3D { + +// *************************************************************************** + +CShader::~CShader() +{ + // Must kill the drv mirror of this shader. + _DrvInfo.kill(); +} + +// *************************************************************************** + +CShader::CShader() +{ + _ShaderChanged = true; +} + +// *************************************************************************** + +void CShader::setText (const char *text) +{ + _Text = text; + _ShaderChanged = true; +} + +// *************************************************************************** + +void CShader::setName (const char *name) +{ + _Name = name; + _ShaderChanged = true; +} + +// *************************************************************************** + +bool CShader::loadShaderFile (const char *filename) +{ + _Text = ""; + // Lookup + string _filename = NLMISC::CPath::lookup(filename, false, true, true); + if (!_filename.empty()) + { + // File length + uint size = NLMISC::CFile::getFileSize (_filename); + _Text.reserve (size+1); + + try + { + NLMISC::CIFile file; + if (file.open (_filename)) + { + // Read it + while (!file.eof ()) + { + char line[512]; + file.getline (line, 512); + _Text += line; + } + + // Set the shader name + _Name = NLMISC::CFile::getFilename (filename); + return true; + } + else + { + nlwarning ("Can't open the file %s for reading", _filename.c_str()); + } + } + catch (const Exception &e) + { + nlwarning ("Error while reading %s : %s", _filename.c_str(), e.what()); + } + } + return false; +} + +// *************************************************************************** + +IShaderDrvInfos::~IShaderDrvInfos() +{ + _Driver->removeShaderDrvInfoPtr(_DriverIterator); +} + +void CDriverD3D::removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt) +{ + _ShaderDrvInfos.erase(shaderIt); +} + // mem allocator for state records std::allocator CStateRecord::Allocator; @@ -249,7 +338,7 @@ HRESULT CDriverD3D::SetVertexShaderConstantI(UINT StartRegister, CONST INT* pCon // *************************************************************************** -CShaderDrvInfosD3D::CShaderDrvInfosD3D(IDriver *drv, ItShaderDrvInfoPtrList it) : IShaderDrvInfos(drv, it) +CShaderDrvInfosD3D::CShaderDrvInfosD3D(CDriverD3D *drv, ItShaderDrvInfoPtrList it) : IShaderDrvInfos(drv, it) { H_AUTO_D3D(CShaderDrvInfosD3D_CShaderDrvInfosD3D) Validated = false; 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 a758aa7b3..c7b8905a1 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 @@ -26,7 +26,7 @@ namespace NL3D // *************************************************************************** -CVertexProgamDrvInfosD3D::CVertexProgamDrvInfosD3D(IDriver *drv, ItVtxPrgDrvInfoPtrList it) : IVertexProgramDrvInfos (drv, it) +CVertexProgamDrvInfosD3D::CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it) { H_AUTO_D3D(CVertexProgamDrvInfosD3D_CVertexProgamDrvInfosD3D) Shader = NULL; @@ -274,9 +274,25 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) // Program setuped ? if (program->_DrvInfo==NULL) { - _VtxPrgDrvInfos.push_front (NULL); - ItVtxPrgDrvInfoPtrList itTex = _VtxPrgDrvInfos.begin(); - *itTex = new CVertexProgamDrvInfosD3D(this, itTex); + // Find nelvp + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("Direct3D driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; + } + + _GPUPrgDrvInfos.push_front (NULL); + ItGPUPrgDrvInfoPtrList itTex = _GPUPrgDrvInfos.begin(); + CVertexProgamDrvInfosD3D *drvInfo; + *itTex = drvInfo = new CVertexProgamDrvInfosD3D(this, itTex); // Create a driver info structure program->_DrvInfo = *itTex; @@ -287,7 +303,7 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) CVPParser parser; CVPParser::TProgram parsedProgram; std::string errorOutput; - bool result = parser.parse(program->getProgram().c_str(), parsedProgram, errorOutput); + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); if (!result) { nlwarning("Unable to parse a vertex program :"); @@ -345,13 +361,19 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) nlwarning ((const char*)pErrorMsgs->GetBufferPointer()); return false; } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); } } // Set the vertex program if (program) { - CVertexProgamDrvInfosD3D *info = static_cast((IVertexProgramDrvInfos*)program->_DrvInfo); + CVertexProgamDrvInfosD3D *info = static_cast((IGPUProgramDrvInfos*)program->_DrvInfo); 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 diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 5289f2a26..29fd59957 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -49,7 +49,6 @@ #include "nel/3d/driver.h" #include "nel/3d/material.h" -#include "nel/3d/shader.h" #include "nel/3d/vertex_buffer.h" #include "nel/3d/ptr_set.h" #include "nel/3d/texture_cube.h" diff --git a/code/nel/src/3d/material.cpp b/code/nel/src/3d/material.cpp index 4f4386dc3..886f45308 100644 --- a/code/nel/src/3d/material.cpp +++ b/code/nel/src/3d/material.cpp @@ -18,7 +18,6 @@ #include "nel/3d/material.h" #include "nel/3d/texture.h" -#include "nel/3d/shader.h" #include "nel/3d/driver.h" #include "nel/misc/stream.h" diff --git a/code/nel/src/3d/shader.cpp b/code/nel/src/3d/shader.cpp deleted file mode 100644 index 9c08e9980..000000000 --- a/code/nel/src/3d/shader.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "std3d.h" - -#include "nel/3d/shader.h" -#include "nel/3d/driver.h" -#include "nel/misc/path.h" -#include "nel/misc/file.h" - -using namespace std; -using namespace NLMISC; - -namespace NL3D -{ - -} // NL3D From 58a8982ba5f3a9ab0c087d90dd64a1fd16219b74 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 8 Sep 2013 01:36:01 +0200 Subject: [PATCH 097/137] Add gpu program params storage structure --- code/nel/include/nel/3d/gpu_program_params.h | 100 +++++++++++ code/nel/src/3d/CMakeLists.txt | 4 +- code/nel/src/3d/gpu_program_params.cpp | 165 +++++++++++++++++++ 3 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 code/nel/include/nel/3d/gpu_program_params.h create mode 100644 code/nel/src/3d/gpu_program_params.cpp diff --git a/code/nel/include/nel/3d/gpu_program_params.h b/code/nel/include/nel/3d/gpu_program_params.h new file mode 100644 index 000000000..a94a0ccf8 --- /dev/null +++ b/code/nel/include/nel/3d/gpu_program_params.h @@ -0,0 +1,100 @@ +/** + * \file gpu_program_params.h + * \brief CGPUProgramParams + * \date 2013-09-07 22:17GMT + * \author Jan Boon (Kaetemi) + * CGPUProgramParams + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_GPU_PROGRAM_PARAMS_H +#define NL3D_GPU_PROGRAM_PARAMS_H +#include + +// STL includes +#include +#include + +// NeL includes + +// Project includes + +namespace NL3D { + +/** + * \brief CGPUProgramParams + * \date 2013-09-07 22:17GMT + * \author Jan Boon (Kaetemi) + * A storage for user-provided parameters for GPU programs. + * Allows for fast updating and iteration of parameters. + * NOTE TO DRIVER IMPLEMENTORS: DO NOT USE FOR STORING COPIES + * OF HARDCODED MATERIAL PARAMETERS OR DRIVER PARAMETERS!!! + */ +class CGPUProgramParams +{ +public: + enum TType { Float, Int }; + struct CMeta { uint Index, Count; TType Type; size_t Next, Prev; }; + +private: + union CVec { float F[4]; sint32 I[4]; }; + +public: + CGPUProgramParams(); + virtual ~CGPUProgramParams(); + + void set(uint index, float f0, float f1, float f2, float f3); + void set(uint index, int i0, int i1, int i2, int i3); + + // Internal + /// Allocate specified number of components if necessary + size_t allocOffset(uint index, uint count, TType type); + /// Return offset for specified index + size_t getOffset(uint index) const; + /// Remove by offset + void freeOffset(size_t offset); + + // Iteration + size_t getBegin() const { return m_Meta.size() ? m_First : s_End; } + size_t getNext(size_t offset) const { return m_Meta[offset].Next; } + size_t getEnd() const { return s_End; } + + // Data access + uint getCountByOffset(size_t offset) { return m_Meta[offset].Count; } + float *getPtrFByOffset(size_t offset) { return m_Vec[offset].F; } + int *getPtrIByOffset(size_t offset) { return m_Vec[offset].I; } + TType getTypeByOffset(size_t offset) { return m_Meta[offset].Type; } + +private: + std::vector m_Vec; + std::vector m_Meta; + std::vector m_Map; // map from index to buffer index + size_t m_First; + size_t m_Last; + static const size_t s_End = -1; + +}; /* class CGPUProgramParams */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_GPU_PROGRAM_PARAMS_H */ + +/* end of file */ diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index 242cb754c..5f5896ff9 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -170,7 +170,9 @@ SOURCE_GROUP(Driver FILES gpu_program.cpp ../../include/nel/3d/gpu_program.h gpu_program_source.cpp - ../../include/nel/3d/gpu_program_source.h) + ../../include/nel/3d/gpu_program_source.h + gpu_program_params.cpp + ../../include/nel/3d/gpu_program_params.h) SOURCE_GROUP(Font FILES computed_string.cpp diff --git a/code/nel/src/3d/gpu_program_params.cpp b/code/nel/src/3d/gpu_program_params.cpp new file mode 100644 index 000000000..78dcab15c --- /dev/null +++ b/code/nel/src/3d/gpu_program_params.cpp @@ -0,0 +1,165 @@ +/** + * \file gpu_program_params.cpp + * \brief CGPUProgramParams + * \date 2013-09-07 22:17GMT + * \author Jan Boon (Kaetemi) + * CGPUProgramParams + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +CGPUProgramParams::CGPUProgramParams() : m_First(s_End), m_Last(s_End) +{ + +} + +CGPUProgramParams::~CGPUProgramParams() +{ + +} + +void CGPUProgramParams::set(uint index, float f0, float f1, float f2, float f3) +{ + float *f = getPtrFByOffset(allocOffset(index, 4, Float)); + f[0] = f0; + f[1] = f1; + f[2] = f2; + f[3] = f3; +} + +void CGPUProgramParams::set(uint index, int i0, int i1, int i2, int i3) +{ + int *i = getPtrIByOffset(allocOffset(index, 4, Int)); + i[0] = i0; + i[1] = i1; + i[2] = i2; + i[3] = i3; +} + +/// Allocate specified number of components if necessary +size_t CGPUProgramParams::allocOffset(uint index, uint count, TType type) +{ + nlassert(count > 0); // this code will not properly handle 0 + nlassert(index < 0xFFFF); // sanity check + + size_t offset = getOffset(index); + if (offset != s_End) + { + if (getCountByOffset(offset) == count) + { + m_Meta[offset].Type = type; + return offset; + } + if (getCountByOffset(offset) > count) + { + m_Meta[offset].Type = type; + m_Meta[offset].Count = count; // reduce count + return offset; + } + if (getCountByOffset(offset) < count) + { + freeOffset(offset); + } + } + + // Allocate space + offset = m_Meta.size(); + uint blocks = (count + 3) >> 2; // per 4 components + m_Meta.resize(offset + blocks); + m_Vec.resize(offset + blocks); + + // Store offset in map + if (index >= m_Map.size()) + m_Map.resize(index + 1, s_End); + m_Map[index] = offset; + + // Fill + m_Meta[offset].Index = index; + m_Meta[offset].Count = count; + m_Meta[offset].Type = type; + m_Meta[offset].Prev = m_Last; + m_Meta[offset].Next = s_End; + + // Link + if (m_Last == s_End) + { + m_First = m_Last = offset; + } + else + { + nlassert(m_Meta[m_Last].Next == s_End); // code error otherwise + m_Meta[m_Last].Next = offset; + m_Last = offset; + } + + return offset; +} + +/// Return offset for specified index +size_t CGPUProgramParams::getOffset(uint index) const +{ + if (index >= m_Map.size()) + return s_End; + return m_Map[index]; +} + +/// Remove by offset +void CGPUProgramParams::freeOffset(size_t offset) +{ + if (offset == m_Last) + { + nlassert(m_Meta[offset].Next == s_End); + m_Last = m_Meta[offset].Prev; + } + else + { + nlassert(m_Meta[offset].Next != s_End); + m_Meta[m_Meta[offset].Next].Prev = m_Meta[offset].Prev; + } + if (offset == m_First) + { + nlassert(m_Meta[offset].Prev == s_End); + m_First = m_Meta[offset].Next; + } + else + { + nlassert(m_Meta[offset].Prev != s_End); + m_Meta[m_Meta[offset].Prev].Next = m_Meta[offset].Next; + } +} + +} /* namespace NL3D */ + +/* end of file */ From 48493b225d25a16db2aee80da07b1aa7b741271b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 8 Sep 2013 01:49:34 +0200 Subject: [PATCH 098/137] Add additional set functions --- code/nel/include/nel/3d/gpu_program_params.h | 21 +++++- code/nel/src/3d/gpu_program_params.cpp | 74 +++++++++++++++++++- 2 files changed, 90 insertions(+), 5 deletions(-) diff --git a/code/nel/include/nel/3d/gpu_program_params.h b/code/nel/include/nel/3d/gpu_program_params.h index a94a0ccf8..d1a3125a2 100644 --- a/code/nel/include/nel/3d/gpu_program_params.h +++ b/code/nel/include/nel/3d/gpu_program_params.h @@ -37,6 +37,11 @@ // Project includes +namespace NLMISC { + class CVector; + class CMatrix; +} + namespace NL3D { /** @@ -61,8 +66,17 @@ public: CGPUProgramParams(); virtual ~CGPUProgramParams(); - void set(uint index, float f0, float f1, float f2, float f3); - void set(uint index, int i0, int i1, int i2, int i3); + void setF(uint index, float f0); + void setF(uint index, float f0, float f1); + void setF(uint index, float f0, float f1, float f2); + void setF(uint index, float f0, float f1, float f2, float f3); + void setI(uint index, int i0); + void setI(uint index, int i0, int i1); + void setI(uint index, int i0, int i1, int i2); + void setI(uint index, int i0, int i1, int i2, int i3); + void setF(uint index, const NLMISC::CVector& v); + void setF(uint index, const NLMISC::CMatrix& m); + void setF(uint index, uint num, const float *src); // Internal /// Allocate specified number of components if necessary @@ -83,6 +97,9 @@ public: int *getPtrIByOffset(size_t offset) { return m_Vec[offset].I; } TType getTypeByOffset(size_t offset) { return m_Meta[offset].Type; } + // Utility + static inline uint getNbRegistersByComponents(uint count) { return (count + 3) >> 2; } // vector register per 4 components + private: std::vector m_Vec; std::vector m_Meta; diff --git a/code/nel/src/3d/gpu_program_params.cpp b/code/nel/src/3d/gpu_program_params.cpp index 78dcab15c..0a03500ea 100644 --- a/code/nel/src/3d/gpu_program_params.cpp +++ b/code/nel/src/3d/gpu_program_params.cpp @@ -32,6 +32,8 @@ // NeL includes // #include +#include +#include // Project includes @@ -50,7 +52,28 @@ CGPUProgramParams::~CGPUProgramParams() } -void CGPUProgramParams::set(uint index, float f0, float f1, float f2, float f3) +void CGPUProgramParams::setF(uint index, float f0) +{ + float *f = getPtrFByOffset(allocOffset(index, 1, Float)); + f[0] = f0; +} + +void CGPUProgramParams::setF(uint index, float f0, float f1) +{ + float *f = getPtrFByOffset(allocOffset(index, 2, Float)); + f[0] = f0; + f[1] = f1; +} + +void CGPUProgramParams::setF(uint index, float f0, float f1, float f2) +{ + float *f = getPtrFByOffset(allocOffset(index, 3, Float)); + f[0] = f0; + f[1] = f1; + f[2] = f2; +} + +void CGPUProgramParams::setF(uint index, float f0, float f1, float f2, float f3) { float *f = getPtrFByOffset(allocOffset(index, 4, Float)); f[0] = f0; @@ -59,7 +82,28 @@ void CGPUProgramParams::set(uint index, float f0, float f1, float f2, float f3) f[3] = f3; } -void CGPUProgramParams::set(uint index, int i0, int i1, int i2, int i3) +void CGPUProgramParams::setI(uint index, int i0) +{ + int *i = getPtrIByOffset(allocOffset(index, 1, Int)); + i[0] = i0; +} + +void CGPUProgramParams::setI(uint index, int i0, int i1) +{ + int *i = getPtrIByOffset(allocOffset(index, 2, Int)); + i[0] = i0; + i[1] = i1; +} + +void CGPUProgramParams::setI(uint index, int i0, int i1, int i2) +{ + int *i = getPtrIByOffset(allocOffset(index, 3, Int)); + i[0] = i0; + i[1] = i1; + i[2] = i2; +} + +void CGPUProgramParams::setI(uint index, int i0, int i1, int i2, int i3) { int *i = getPtrIByOffset(allocOffset(index, 4, Int)); i[0] = i0; @@ -68,6 +112,30 @@ void CGPUProgramParams::set(uint index, int i0, int i1, int i2, int i3) i[3] = i3; } +void CGPUProgramParams::setF(uint index, const NLMISC::CVector& v) +{ + float *f = getPtrFByOffset(allocOffset(index, 3, Float)); + f[0] = v.x; + f[1] = v.y; + f[2] = v.z; +} + +void CGPUProgramParams::setF(uint index, const NLMISC::CMatrix& m) +{ + // TODO: Verify this! + float *f = getPtrFByOffset(allocOffset(index, 16, Float)); + NLMISC::CMatrix mt = m; + mt.transpose(); + mt.get(f); +} + +void CGPUProgramParams::setF(uint index, uint num, const float *src) +{ + float *f = getPtrFByOffset(allocOffset(index, num, Float)); + for (uint i = 0; i < num; ++i) + f[i] = src[i]; +} + /// Allocate specified number of components if necessary size_t CGPUProgramParams::allocOffset(uint index, uint count, TType type) { @@ -96,7 +164,7 @@ size_t CGPUProgramParams::allocOffset(uint index, uint count, TType type) // Allocate space offset = m_Meta.size(); - uint blocks = (count + 3) >> 2; // per 4 components + uint blocks = getNbRegistersByComponents(count); // per 4 components m_Meta.resize(offset + blocks); m_Vec.resize(offset + blocks); From 7be6891bd71ce22e6d82bcfe50e6249f421d3642 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 8 Sep 2013 21:57:27 +0200 Subject: [PATCH 099/137] Cleanup driver interface --- code/nel/include/nel/3d/driver.h | 1016 ++++++++++------- code/nel/include/nel/3d/driver_user.h | 1 - code/nel/include/nel/3d/gpu_program_params.h | 67 +- code/nel/include/nel/3d/u_driver.h | 7 - code/nel/src/3d/driver.cpp | 19 +- .../src/3d/driver/direct3d/driver_direct3d.h | 1 - .../src/3d/driver/opengl/driver_opengl.cpp | 6 - code/nel/src/3d/driver/opengl/driver_opengl.h | 2 - code/nel/src/3d/driver_user.cpp | 6 - code/nel/src/3d/gpu_program_params.cpp | 36 +- code/nel/src/3d/stereo_ovr.cpp | 18 +- 11 files changed, 661 insertions(+), 518 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 2d10c5653..2414d3df5 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -31,6 +31,7 @@ #include "nel/3d/vertex_program.h" #include "nel/3d/pixel_program.h" #include "nel/3d/geometry_program.h" +#include "nel/3d/gpu_program_params.h" #include "nel/3d/material.h" #include "nel/misc/mutex.h" #include "nel/3d/primitive_profile.h" @@ -120,9 +121,9 @@ public: static const uint32 InterfaceVersion; public: - enum TMessageBoxId { okId=0, yesId, noId, abortId, retryId, cancelId, ignoreId, idCount }; - enum TMessageBoxType { okType=0, okCancelType, yesNoType, abortRetryIgnoreType, yesNoCancelType, retryCancelType, typeCount }; - enum TMessageBoxIcon { noIcon=0, handIcon, questionIcon, exclamationIcon, asteriskIcon, warningIcon, errorIcon, informationIcon, stopIcon, iconCount }; + enum TMessageBoxId { okId = 0, yesId, noId, abortId, retryId, cancelId, ignoreId, idCount }; + enum TMessageBoxType { okType = 0, okCancelType, yesNoType, abortRetryIgnoreType, yesNoCancelType, retryCancelType, typeCount }; + enum TMessageBoxIcon { noIcon = 0, handIcon, questionIcon, exclamationIcon, asteriskIcon, warningIcon, errorIcon, informationIcon, stopIcon, iconCount }; enum TCullMode { CCW = 0, CW }; enum TStencilOp { keep = 0, zero, replace, incr, decr, invert }; enum TStencilFunc { never = 0, less, lessequal, equal, notequal, greaterequal, greater, always}; @@ -132,116 +133,218 @@ public: * * \see setPolygonMode, getPolygonMode */ - enum TPolygonMode { Filled=0, Line, Point }; - + enum TPolygonMode { Filled = 0, Line, Point }; /** * Driver Max matrix count. * Kept for backward compatibility. Suppose any Hardware VertexProgram can handle only 16 matrix * */ - enum TMatrixCount { MaxModelMatrix= 16 }; + enum TMatrixCount { MaxModelMatrix = 16 }; + + enum TMatrix + { + ModelView= 0, + Projection, + ModelViewProjection, + NumMatrix + }; + + enum TTransform + { + Identity=0, + Inverse, + Transpose, + InverseTranspose, + NumTransform + }; protected: + CSynchronized _SyncTexDrvInfos; + TTexDrvSharePtrList _TexDrvShares; + TMatDrvInfoPtrList _MatDrvInfos; + TVBDrvInfoPtrList _VBDrvInfos; + TIBDrvInfoPtrList _IBDrvInfos; + TGPUPrgDrvInfoPtrList _GPUPrgDrvInfos; - CSynchronized _SyncTexDrvInfos; - - TTexDrvSharePtrList _TexDrvShares; - TMatDrvInfoPtrList _MatDrvInfos; - TVBDrvInfoPtrList _VBDrvInfos; - TIBDrvInfoPtrList _IBDrvInfos; TPolygonMode _PolygonMode; - TGPUPrgDrvInfoPtrList _GPUPrgDrvInfos; uint _ResetCounter; public: - IDriver(void); - virtual ~IDriver(void); + IDriver(); + virtual ~IDriver(); - virtual bool init (uint windowIcon = 0, emptyProc exitFunc = 0)=0; + virtual bool init(uint windowIcon = 0, emptyProc exitFunc = 0) = 0; + + /// Deriver should calls IDriver::release() first, to destroy all driver components (textures, shaders, VBuffers). + virtual bool release(); + + /// Before rendering via a driver in a thread, must activate() (per thread). + virtual bool activate() = 0; // Test if the device is lost. Can only happen with D3D. // The calling application may skip some part of its rendering when it is the case (this is not a requirement, but may save cpu for other applications) virtual bool isLost() const = 0; + /// Return true if driver is still active. Return false else. If he user close the window, must return false. + virtual bool isActive() = 0; + + + + /** Return the driver reset counter. + * The reset counter is incremented at each driver reset. + */ + uint getResetCounter() const { return _ResetCounter; } + + // get the number of call to swapBuffer since the driver was created + virtual uint64 getSwapBufferCounter() const = 0; + + + /// \name Disable Hardware Feature /** Disable some Feature that may be supported by the Hardware * Call before setDisplay() to work properly */ // @{ - virtual void disableHardwareVertexProgram()=0; - virtual void disableHardwarePixelProgram()=0; - virtual void disableHardwareVertexArrayAGP()=0; - virtual void disableHardwareTextureShader()=0; + virtual void disableHardwareVertexProgram() = 0; + virtual void disableHardwarePixelProgram() = 0; + virtual void disableHardwareVertexArrayAGP() = 0; + virtual void disableHardwareTextureShader() = 0; // @} + + + /// \name Windowing + // @{ // first param is the associated window. // Must be a HWND for Windows (WIN32). - virtual bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show = true, bool resizeable = true) throw(EBadDisplay)=0; + virtual bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show = true, bool resizeable = true) throw(EBadDisplay) = 0; // Must be called after a setDisplay that initialize the mode - virtual bool setMode(const GfxMode& mode)=0; - virtual bool getModes(std::vector &modes)=0; + virtual bool setMode(const GfxMode &mode) = 0; + virtual bool getModes(std::vector &modes) = 0; /// Set the title of the NeL window - virtual void setWindowTitle(const ucstring &title)=0; - + virtual void setWindowTitle(const ucstring &title) = 0; /// Set icon(s) of the NeL window - virtual void setWindowIcon(const std::vector &bitmaps)=0; - + virtual void setWindowIcon(const std::vector &bitmaps) = 0; /// Set the position of the NeL window - virtual void setWindowPos(sint32 x, sint32 y)=0; - + virtual void setWindowPos(sint32 x, sint32 y) = 0; /// Show or hide the NeL window - virtual void showWindow(bool show)=0; + virtual void showWindow(bool show) = 0; /// return the current screen mode (if we are in windowed, return the screen mode behind the window) - virtual bool getCurrentScreenMode(GfxMode &mode)=0; + virtual bool getCurrentScreenMode(GfxMode &mode) = 0; /// enter/leave the dialog mode - virtual void beginDialogMode() =0; - virtual void endDialogMode() =0; + virtual void beginDialogMode() = 0; + virtual void endDialogMode() = 0; // Return is the associated window information. (Implementation dependent) // Must be a HWND for Windows (WIN32). - virtual nlWindow getDisplay() =0; + virtual nlWindow getDisplay() = 0; - /** - * Setup monitor color properties. - * - * Return false if setup failed. - */ - virtual bool setMonitorColorProperties (const CMonitorColorProperties &properties) = 0; + /// Setup monitor color properties. Return false if setup failed + virtual bool setMonitorColorProperties(const CMonitorColorProperties &properties) = 0; // Return is the associated default window proc for the driver. (Implementation dependent) // Must be a void GlWndProc(IDriver *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) for Windows (WIN32). virtual emptyProc getWindowProc() = 0; - /// Before rendering via a driver in a thread, must activate() (per thread). - virtual bool activate(void) = 0; + virtual NLMISC::IEventEmitter *getEventEmitter() = 0; + + /// Copy a string to system clipboard. + virtual bool copyTextToClipboard(const ucstring &text) = 0; - /// Get the number of texture stage available, for multi texturing (Normal material shaders). Valid only after setDisplay(). - virtual uint getNbTextureStages() const = 0; + /// Paste a string from system clipboard. + virtual bool pasteTextFromClipboard(ucstring &text) = 0;/// Return the depth of the driver after init(). - /** is the texture is set up in the driver - * NB: this method is thread safe. - */ - virtual bool isTextureExist(const ITexture&tex)=0; + virtual uint8 getBitPerPixel() = 0; - virtual NLMISC::IEventEmitter* getEventEmitter(void) = 0; + /** Output a system message box and print a message with an icon. This method can be call even if the driver is not initialized. + * This method is used to return internal driver problem when string can't be displayed in the driver window. + * If the driver can't open a messageBox, it should not override this method and let the IDriver class manage it with the ASCII console. + * + * \param message This is the message to display in the message box. + * \param title This is the title of the message box. + * \param type This is the type of the message box, ie number of button and label of buttons. + * \param icon This is the icon of the message box should use like warning, error etc... + */ + virtual TMessageBoxId systemMessageBox(const char *message, const char *title, TMessageBoxType type = okType, TMessageBoxIcon icon = noIcon); - /* Clear the current target surface pixels. The function ignores the viewport settings but uses the scissor. */ + /// Get the width and the height of the window + virtual void getWindowSize(uint32 &width, uint32 &height) = 0; + + /// Get the position of the window always (0,0) in fullscreen + virtual void getWindowPos(sint32 &x, sint32 &y) = 0; + // @} + + + + /// \name Framebuffer operations + // @{ + /// Clear the current target surface pixels. The function ignores the viewport settings but uses the scissor. virtual bool clear2D(CRGBA rgba) = 0; - /* Clear the current target surface zbuffer. The function ignores the viewport settings but uses the scissor. */ + /// Clear the current target surface zbuffer. The function ignores the viewport settings but uses the scissor. virtual bool clearZBuffer(float zval=1) = 0; - /* Clear the current target surface stencil buffer. The function ignores the viewport settings but uses the scissor. */ + /// Clear the current target surface stencil buffer. The function ignores the viewport settings but uses the scissor. virtual bool clearStencilBuffer(float stencilval=0) = 0; /// Set the color mask filter through where the operation done will pass - virtual void setColorMask (bool bRed, bool bGreen, bool bBlue, bool bAlpha) = 0; + virtual void setColorMask(bool bRed, bool bGreen, bool bBlue, bool bAlpha) = 0; + // @} + + + /// \name Copy framebuffer to memory + // @{ + /** get the RGBA back buffer. After swapBuffers(), the content of the back buffer is undefined. + * + * \param bitmap the buffer will be written in this bitmap + */ + virtual void getBuffer(CBitmap &bitmap) = 0; + + /** get the ZBuffer (back buffer). + * + * \param zbuffer the returned array of Z. size of getWindowSize() . + */ + virtual void getZBuffer(std::vector &zbuffer) = 0; + + /** get a part of the RGBA back buffer. After swapBuffers(), the content of the back buffer is undefined. + * NB: 0,0 is the bottom left corner of the screen. + * + * \param bitmap the buffer will be written in this bitmap + * \param rect the in/out (wanted/clipped) part of Color buffer to retrieve. + */ + virtual void getBufferPart(CBitmap &bitmap, NLMISC::CRect &rect) = 0; + + /** get a part of the ZBuffer (back buffer). + * NB: 0,0 is the bottom left corner of the screen. + * + * \param zbuffer the returned array of Z. size of rec.Width*rec.Height. + * \param rect the in/out (wanted/clipped) part of ZBuffer to retrieve. + */ + virtual void getZBufferPart(std::vector &zbuffer, NLMISC::CRect &rect) = 0; + // @} + + + + /// \name Copy memory to framebuffer + // @{ + /** fill the RGBA back buffer + * + * \param bitmap will be written in the buffer. no-op if bad size. + * \return true if success + */ + virtual bool fillBuffer(CBitmap &bitmap) = 0; + // @} + + + + /// \name Viewport depth clipping + // @{ /** Set depth range. Depth range specify a linear mapping from device z coordinates (in the [-1, 1] range) to window coordinates (in the [0, 1] range) * This mapping occurs after clipping of primitives and division by w of vertices coordinates. * Default depth range is [0, 1]. @@ -250,11 +353,20 @@ public: virtual void setDepthRange(float znear, float zfar) = 0; // Get the current depth range virtual void getDepthRange(float &znear, float &zfar) const = 0; + // @} + + + /// \name Textures + // @{ + /** is the texture is set up in the driver + * NB: this method is thread safe. + */ + virtual bool isTextureExist(const ITexture &tex) = 0; /** setup a texture, generate and upload if needed. same as setupTextureEx(tex, true, dummy); */ - virtual bool setupTexture(ITexture& tex) = 0; + virtual bool setupTexture(ITexture &tex) = 0; /** setup a texture in the driver. * \param bUpload if true the texture is created and uploaded to VRAM, if false the texture is only created @@ -267,59 +379,81 @@ public: * is only bound to tex (thus creating and uploading nothing) * NB: the texture must be at least touch()-ed for the recreate to work. */ - virtual bool setupTextureEx (ITexture& tex, bool bUpload, bool& bAllUploaded, - bool bMustRecreateSharedTexture= false) = 0; + virtual bool setupTextureEx( ITexture &tex, bool bUpload, bool &bAllUploaded, + bool bMustRecreateSharedTexture = false) = 0; /** The texture must be created or uploadTexture do nothing. * These function can be used to upload piece by piece a texture. Use it in conjunction with setupTextureEx(..., false); * For compressed textures, the rect must aligned on pixel block. (a block of pixel size is 4x4 pixels). */ - virtual bool uploadTexture (ITexture& tex, NLMISC::CRect& rect, uint8 nNumMipMap) = 0; - virtual bool uploadTextureCube (ITexture& tex, NLMISC::CRect& rect, uint8 nNumMipMap, uint8 nNumFace) = 0; + virtual bool uploadTexture(ITexture &tex, NLMISC::CRect &rect, uint8 nNumMipMap) = 0; + virtual bool uploadTextureCube(ITexture &tex, NLMISC::CRect &rect, uint8 nNumMipMap, uint8 nNumFace) = 0; /** * Invalidate shared texture */ - bool invalidateShareTexture (ITexture &); + bool invalidateShareTexture(ITexture &); /** * Get the driver share texture name */ - static void getTextureShareName (const ITexture& tex, std::string &output); + static void getTextureShareName(const ITexture &tex, std::string &output); /** if true force all the uncompressed RGBA 32 bits and RGBA 24 bits texture to be DXTC5 compressed. * Do this only during upload if ITexture::allowDegradation() is true and if ITexture::UploadFormat is "Automatic" * and if bitmap format is RGBA. */ - virtual void forceDXTCCompression(bool dxtcComp)=0; + virtual void forceDXTCCompression(bool dxtcComp) = 0; /** if different from 0, enable anisotropic filter on textures. -1 enables max value. * Default is 0. */ - virtual void setAnisotropicFilter(sint filter)=0; + virtual void setAnisotropicFilter(sint filter) = 0; /** if !=1, force mostly all the textures (but TextureFonts lightmaps, interfaces etc..) * to be divided by Divisor (2, 4, 8...) * Default is 1. * NB: this is done only on TextureFile */ - virtual void forceTextureResize(uint divisor)=0; + virtual void forceTextureResize(uint divisor) = 0; - /** Sets enforcement of native fragment programs. This is by default enabled. - * - * \param nativeOnly If set to false, fragment programs don't need to be native to stay loaded, - * otherwise (aka if true) they will be purged. + /** Get the number of texture stage available, for multi texturing (Normal material shaders). Valid only after setDisplay(). */ - virtual void forceNativeFragmentPrograms(bool nativeOnly) = 0; + virtual uint getNbTextureStages() const = 0; + + /** Get max number of per stage constant that can be used simultaneously. + * This will usually match the number of texture stages, but with a D3D driver, this feature is not available most of the time + * so it is emulated. If pixel shaders are available this will be fully supported. + * Under OpenGL this simply returns the maximum number of texture stages (getNbTextureStages) in both return values. + */ + virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const = 0; + + // [DEPRECATED] Return if this texture is a rectangle texture that requires RECT sampler (OpenGL specific pre-NPOT functionality) + virtual bool isTextureRectangle(ITexture *tex) const = 0; + + // Return true if driver support non-power of two textures + virtual bool supportNonPowerOfTwoTextures() const = 0; + // @} + + + + /// \name Texture operations + // @{ + // copy the first texture in a second one of different dimensions + virtual bool stretchRect(ITexture *srcText, NLMISC::CRect &srcRect, ITexture *destText, NLMISC::CRect &destRect) = 0; + // @} - virtual bool setupMaterial(CMaterial& mat)=0; + + /// \name Material + // @{ + virtual bool setupMaterial(CMaterial &mat) = 0; /** Special for Faster Specular Setup. Call this between lot of primitives rendered with Specular Materials. * Visual Errors may arise if you don't correctly call endSpecularBatch(). */ - virtual void startSpecularBatch()=0; - virtual void endSpecularBatch()=0; + virtual void startSpecularBatch() = 0; + virtual void endSpecularBatch() = 0; /// \name Material multipass. /** NB: setupMaterial() must be called before those methods. @@ -327,18 +461,26 @@ public: * NB: Other render calls performs the needed setup automatically */ // @{ - /// init multipass for _CurrentMaterial. return number of pass required to render this material. - virtual sint beginMaterialMultiPass() = 0; - /// active the ith pass of this material. - virtual void setupMaterialPass(uint pass) = 0; - /// end multipass for this material. - virtual void endMaterialMultiPass() = 0; + /// init multipass for _CurrentMaterial. return number of pass required to render this material. + virtual sint beginMaterialMultiPass() = 0; + /// active the ith pass of this material. + virtual void setupMaterialPass(uint pass) = 0; + /// end multipass for this material. + virtual void endMaterialMultiPass() = 0; // @} + // Does the driver support the per-pixel lighting shader ? + virtual bool supportPerPixelLighting(bool specular) const = 0; + // @} + + + + /// \name Camera + // @{ // Setup the camera mode as a perspective/ortho camera. NB: znear and zfar must be >0 (if perspective). - virtual void setFrustum(float left, float right, float bottom, float top, float znear, float zfar, bool perspective=true)=0; - virtual void setFrustumMatrix(CMatrix &frust)=0; - virtual CMatrix getFrustumMatrix()=0; + virtual void setFrustum(float left, float right, float bottom, float top, float znear, float zfar, bool perspective = true) = 0; + virtual void setFrustumMatrix(CMatrix &frust) = 0; + virtual CMatrix getFrustumMatrix() = 0; virtual float getClipSpaceZMin() const = 0; @@ -346,7 +488,7 @@ public: * * NB: you must setupViewMatrix() BEFORE setupModelMatrix(), or else undefined results. */ - virtual void setupViewMatrix(const CMatrix& mtx)=0; + virtual void setupViewMatrix(const CMatrix &mtx)=0; /** setup the view matrix (inverse of camera matrix). * Extended: give a cameraPos (mtx.Pos() is not taken into account but for getViewMatrix()), @@ -360,38 +502,40 @@ public: * \param mtx the same view matrix (still with correct "inversed" camera position) as if passed in setupViewMatrix() * \param cameraPos position of the camera (before inversion, ie mtx.getPos()!=cameraPos ). */ - virtual void setupViewMatrixEx(const CMatrix& mtx, const CVector &cameraPos)=0; + virtual void setupViewMatrixEx(const CMatrix &mtx, const CVector &cameraPos) = 0; /** setup the model matrix. * * NB: you must setupModelMatrix() AFTER setupViewMatrix(), or else undefined results. */ - virtual void setupModelMatrix(const CMatrix& mtx)=0; + virtual void setupModelMatrix(const CMatrix &mtx) = 0; - virtual CMatrix getViewMatrix(void)const=0; + virtual CMatrix getViewMatrix() const = 0; + // @} + + /// \name Fixed pipeline vertex program + // @{ /** Force input normal to be normalized by the driver. default is false. * NB: driver force the normalization himself if: * - current Model matrix has a scale. */ - virtual void forceNormalize(bool normalize)=0; + virtual void forceNormalize(bool normalize) = 0; /** return the forceNormalize() state. */ - virtual bool isForceNormalize() const =0; + virtual bool isForceNormalize() const = 0; + // @} + - /** Get max number of per stage constant that can be used simultaneously. - * This will usually match the number of texture stages, but with a D3D driver, this feature is not available most of the time - * so it is emulated. If pixel shaders are available this will be fully supported. - */ - virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const = 0; - + /// \name Vertex Buffer Hard: Features + // @{ /** return true if driver support VertexBufferHard. */ - virtual bool supportVertexBufferHard() const =0; + virtual bool supportVertexBufferHard() const = 0; /** return true if volatile vertex buffer are supported. (e.g a vertex buffer which can be created with the flag CVertexBuffer::AGPVolatile or CVertexBuffer::RAMVolatile) * If these are not supported, a RAM vb is created instead (transparent to user) @@ -405,9 +549,13 @@ public: /** return true if driver support VertexBufferHard, but vbHard->unlock() are slow (ATI-openGL). */ - virtual bool slowUnlockVertexBufferHard() const =0; + virtual bool slowUnlockVertexBufferHard() const = 0; + // @} + + /// \name Vertex Buffer Hard: Settings + // @{ /* Returns true if static vertex and index buffers must by allocated in VRAM, false in AGP. * Default is false. */ @@ -418,16 +566,15 @@ public: */ void setStaticMemoryToVRAM(bool staticMemoryToVRAM); - /** Return the driver reset counter. - * The reset counter is incremented at each driver reset. - */ - uint getResetCounter () const { return _ResetCounter; } - /** return How many vertices VertexBufferHard support */ - virtual uint getMaxVerticesByVertexBufferHard() const =0; + virtual uint getMaxVerticesByVertexBufferHard() const = 0; + // @} + + /// \name Vertex Buffer Hard + // @{ /** Allocate the initial VertexArray Memory. (no-op if !supportVertexBufferHard()). * VertexArrayRange is first reseted, so any VBhard created before will be deleted. * NB: call it after setDisplay(). But setDisplay() by default call initVertexBufferHard(16Mo, 0); @@ -437,17 +584,21 @@ public: * \param vramMem amount of VRAM Memory required. if 0, reseted. * \return false if one the Buffer has not been allocated (at least at 500K). */ - virtual bool initVertexBufferHard(uint agpMem, uint vramMem=0) =0; + virtual bool initVertexBufferHard(uint agpMem, uint vramMem = 0) = 0; /** Return the amount of AGP memory allocated by initVertexBufferHard() to store vertices. */ - virtual uint32 getAvailableVertexAGPMemory () =0; + virtual uint32 getAvailableVertexAGPMemory() = 0; /** Return the amount of video memory allocated by initVertexBufferHard() to store vertices. */ - virtual uint32 getAvailableVertexVRAMMemory () =0; + virtual uint32 getAvailableVertexVRAMMemory() = 0; + // @} + + /// \name Vertex Buffer Objects + // @{ /** active a current VB, for future render(). * This method suppose that all vertices in the VB will be used. * @@ -457,30 +608,33 @@ public: * * \see activeVertexProgram */ - virtual bool activeVertexBuffer(CVertexBuffer& VB)=0; - + virtual bool activeVertexBuffer(CVertexBuffer &VB) = 0; /** active a current IB, for future render(). * * Don't change the index buffer format/size after having activated it. * Don't lock the index buffer after having activated it. */ - virtual bool activeIndexBuffer(CIndexBuffer& IB)=0; + virtual bool activeIndexBuffer(CIndexBuffer &IB) = 0; + // @} + + /// \name Rendering + // @{ /** Render a list of indexed lines with previously setuped VertexBuffer / IndexBuffer / Matrixes. * \param mat is the material to use during this rendering * \param firstIndex is the first index in the index buffer to use as first line. * \param nlines is the number of line to render. */ - virtual bool renderLines(CMaterial& mat, uint32 firstIndex, uint32 nlines)=0; + virtual bool renderLines(CMaterial &mat, uint32 firstIndex, uint32 nlines) = 0; /** Render a list of indexed triangles with previously setuped VertexBuffer / IndexBuffer / Matrixes. * \param mat is the material to use during this rendering * \param firstIndex is the first index in the index buffer to use as first triangle. * \param ntris is the number of triangle to render. */ - virtual bool renderTriangles(CMaterial& mat, uint32 firstIndex, uint32 ntris)=0; + virtual bool renderTriangles(CMaterial &mat, uint32 firstIndex, uint32 ntris) = 0; /** Render a list of triangles with previously setuped VertexBuffer / IndexBuffer / Matrixes, AND previously setuped MATERIAL!! * This use the last material setuped. It should be a "Normal shader" material, because no multi-pass is allowed @@ -491,7 +645,7 @@ public: * \param firstIndex is the first index in the index buffer to use as first triangle. * \param ntris is the number of triangle to render. */ - virtual bool renderSimpleTriangles(uint32 firstIndex, uint32 ntris)=0; + virtual bool renderSimpleTriangles(uint32 firstIndex, uint32 ntris) = 0; /** Render points with previously setuped VertexBuffer / Matrixes. * Points are stored as a sequence in the vertex buffer. @@ -499,7 +653,7 @@ public: * \param startVertex is the first vertex to use during this rendering. * \param numPoints is the number of point to render. */ - virtual bool renderRawPoints(CMaterial& mat, uint32 startVertex, uint32 numPoints)=0; + virtual bool renderRawPoints(CMaterial &mat, uint32 startVertex, uint32 numPoints) = 0; /** Render lines with previously setuped VertexBuffer / Matrixes. * Lines are stored as a sequence in the vertex buffer. @@ -507,7 +661,7 @@ public: * \param startVertex is the first vertex to use during this rendering. * \param numLine is the number of line to render. */ - virtual bool renderRawLines(CMaterial& mat, uint32 startVertex, uint32 numTri)=0; + virtual bool renderRawLines(CMaterial &mat, uint32 startVertex, uint32 numTri) = 0; /** Render triangles with previously setuped VertexBuffer / Matrixes. * Triangles are stored as a sequence in the vertex buffer. @@ -515,15 +669,15 @@ public: * \param startVertex is the first vertex to use during this rendering. * \param numTri is the number of triangle to render. */ - virtual bool renderRawTriangles(CMaterial& mat, uint32 startVertex, uint32 numTri)=0; + virtual bool renderRawTriangles(CMaterial &mat, uint32 startVertex, uint32 numTri) = 0; /** If the driver support it, primitive can be rendered with an offset added to each index * These are the offseted version of the 'render' functions * \see supportIndexOffset */ - virtual bool renderLinesWithIndexOffset(CMaterial& mat, uint32 firstIndex, uint32 nlines, uint indexOffset)=0; - virtual bool renderTrianglesWithIndexOffset(CMaterial& mat, uint32 firstIndex, uint32 ntris, uint indexOffset)=0; - virtual bool renderSimpleTrianglesWithIndexOffset(uint32 firstIndex, uint32 ntris, uint indexOffset)=0; + virtual bool renderLinesWithIndexOffset(CMaterial &mat, uint32 firstIndex, uint32 nlines, uint indexOffset) = 0; + virtual bool renderTrianglesWithIndexOffset(CMaterial &mat, uint32 firstIndex, uint32 ntris, uint indexOffset) = 0; + virtual bool renderSimpleTrianglesWithIndexOffset(uint32 firstIndex, uint32 ntris, uint indexOffset) = 0; /** render quads with previously setuped VertexBuffer / Matrixes. @@ -540,8 +694,13 @@ public: * \param startVertex is the first vertex to use during this rendering. * \param numQuad is the number of quad to render. */ - virtual bool renderRawQuads(CMaterial& mat, uint32 startVertex, uint32 numQuads)=0; + virtual bool renderRawQuads(CMaterial &mat, uint32 startVertex, uint32 numQuads) = 0; + // @} + + + /// \name Texture coordinates fixed pipeline + // @{ /** Say what Texture Stage use what UV coord. * by default activeVertexBuffer*() methods map all stage i to UV i. You can change this behavior, * after calling activeVertexBuffer*(), by using this method. @@ -553,63 +712,58 @@ public: * Warning!: some CMaterial Shader may change automatically this behavior too when setupMaterial() * (and so render*()) is called. But Normal shader doesn't do it. */ - virtual void mapTextureStageToUV(uint stage, uint uv)=0; + virtual void mapTextureStageToUV(uint stage, uint uv) = 0; + // @} + + + /// \name Buffer swapping + // @{ /// Swap the back and front buffers. - virtual bool swapBuffers(void)=0; - - /// Copy a string to system clipboard. - virtual bool copyTextToClipboard(const ucstring &text) =0; - - /// Paste a string from system clipboard. - virtual bool pasteTextFromClipboard(ucstring &text) =0; + virtual bool swapBuffers() = 0; /** set the number of VBL wait when a swapBuffers() is issued. 0 means no synchronisation to the VBL * Default is 1. Values >1 may be clamped to 1 by the driver. */ - virtual void setSwapVBLInterval(uint interval)=0; + virtual void setSwapVBLInterval(uint interval) = 0; /// get the number of VBL wait when a swapBuffers() is issued. 0 means no synchronisation to the VBL - virtual uint getSwapVBLInterval()=0; + virtual uint getSwapVBLInterval() = 0; + // @} + + + /// \name Profiling. // @{ - - /** Get the number of primitives rendered from the last swapBuffers() call. * \param pIn the number of requested rendered primitive. * \param pOut the number of effective rendered primitive. pOut==pIn if no multi-pass material is used * (Lightmap, Specular ...). */ - virtual void profileRenderedPrimitives(CPrimitiveProfile &pIn, CPrimitiveProfile &pOut) =0; - + virtual void profileRenderedPrimitives(CPrimitiveProfile &pIn, CPrimitiveProfile &pOut) = 0; /** Return the amount of Texture memory requested. taking mipmap, compression, texture format, etc... into account. * NB: because of GeForce*, RGB888 is considered to be 32 bits. So it may be false for others cards :). */ - virtual uint32 profileAllocatedTextureMemory() =0; - + virtual uint32 profileAllocatedTextureMemory() = 0; /** Get the number of material setuped from the last swapBuffers() call. */ - virtual uint32 profileSetupedMaterials() const =0; - + virtual uint32 profileSetupedMaterials() const = 0; /** Get the number of matrix setuped from the last swapBuffers() call. */ - virtual uint32 profileSetupedModelMatrix() const =0; - + virtual uint32 profileSetupedModelMatrix() const = 0; /** Enable the sum of texture memory used since last swapBuffers() call. To retrieve the memory used call getUsedTextureMemory(). */ - virtual void enableUsedTextureMemorySum (bool enable=true) =0; - + virtual void enableUsedTextureMemorySum (bool enable = true) = 0; /** Return the amount of texture video memory used since last swapBuffers() call. Before use this method, you should enable * the sum with enableUsedTextureMemorySum(). */ - virtual uint32 getUsedTextureMemory() const =0; - + virtual uint32 getUsedTextureMemory() const = 0; /** If the driver support it, enable profile VBHard locks. * No-Op if already profiling @@ -638,179 +792,126 @@ public: /** For each texture setuped in the driver, "print" result: type, shareName, format and size (mipmap included) */ void profileTextureUsage(std::vector &result); - // @} + /// \name Fog support. // @{ - virtual bool fogEnabled()=0; - virtual void enableFog(bool enable)=0; + virtual bool fogEnabled() = 0; + virtual void enableFog(bool enable = true) = 0; /// setup fog parameters. fog must enabled to see result. start and end are distance values. - virtual void setupFog(float start, float end, CRGBA color)=0; + virtual void setupFog(float start, float end, NLMISC::CRGBA color) = 0; /// Get. - virtual float getFogStart() const =0; - virtual float getFogEnd() const =0; - virtual CRGBA getFogColor() const =0; + virtual float getFogStart() const = 0; + virtual float getFogEnd() const = 0; + virtual NLMISC::CRGBA getFogColor() const = 0; // @} - /// Deriver should calls IDriver::release() first, to destroy all driver components (textures, shaders, VBuffers). - virtual bool release(void); - /// Return true if driver is still active. Return false else. If he user close the window, must return false. - virtual bool isActive()=0; - - /// Return the depth of the driver after init(). - virtual uint8 getBitPerPixel ()=0; - - /** Output a system message box and print a message with an icon. This method can be call even if the driver is not initialized. - * This method is used to return internal driver problem when string can't be displayed in the driver window. - * If the driver can't open a messageBox, it should not override this method and let the IDriver class manage it with the ASCII console. - * - * \param message This is the message to display in the message box. - * \param title This is the title of the message box. - * \param type This is the type of the message box, ie number of button and label of buttons. - * \param icon This is the icon of the message box should use like warning, error etc... - */ - virtual TMessageBoxId systemMessageBox (const char* message, const char* title, TMessageBoxType type=okType, TMessageBoxIcon icon=noIcon); + /// \name Viewport + // @{ /** Set the current viewport * * \param viewport is a viewport to setup as current viewport. */ - virtual void setupViewport (const class CViewport& viewport)=0; + virtual void setupViewport(const class CViewport &viewport) = 0; /** Get the current viewport */ virtual void getViewport(CViewport &viewport) = 0; - /** Set the current Scissor. * \param scissor is a scissor to setup the current Scissor, in Window relative coordinate (0,1). */ - virtual void setupScissor (const class CScissor& scissor)=0; + virtual void setupScissor(const class CScissor &scissor) = 0; + // @} + + /// \name Driver information + // @{ /** * Get the driver version. Not the same than interface version. Incremented at each implementation change. * * \see InterfaceVersion */ - virtual uint32 getImplementationVersion () const = 0; + virtual uint32 getImplementationVersion() const = 0; /** * Get driver information. * get the nel name of the driver (ex: "Opengl 1.2 NeL Driver") */ - virtual const char* getDriverInformation () = 0; + virtual const char *getDriverInformation() = 0; /** * Get videocard information. * get the official name of the driver */ - virtual const char* getVideocardInformation () = 0; + virtual const char *getVideocardInformation () = 0; + // @} + + /// \name Mouse / Keyboard / Game devices // @{ - /// show cursor if b is true, or hide it if b is false - virtual void showCursor (bool b) = 0; + /// show cursor if b is true, or hide it if b is false + virtual void showCursor(bool b) = 0; - /// x and y must be between 0.0 and 1.0 - virtual void setMousePos (float x, float y) = 0; + /// x and y must be between 0.0 and 1.0 + virtual void setMousePos(float x, float y) = 0; - /** Enable / disable low level mouse. This allow to take advantage of some options (speed of the mouse, automatic wrapping) - * It returns a interface to these parameters when it is supported, or NULL otherwise - * The interface pointer is valid as long as the low level mouse is enabled. - * A call to disable the mouse returns NULL, and restore the default mouse behavior - * NB : - In this mode the mouse cursor isn't drawn. - * - Calls to showCursor have no effects - * - Calls to setCapture have no effects - */ - virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive) = 0; + /** Enable / disable low level mouse. This allow to take advantage of some options (speed of the mouse, automatic wrapping) + * It returns a interface to these parameters when it is supported, or NULL otherwise + * The interface pointer is valid as long as the low level mouse is enabled. + * A call to disable the mouse returns NULL, and restore the default mouse behavior + * NB : - In this mode the mouse cursor isn't drawn. + * - Calls to showCursor have no effects + * - Calls to setCapture have no effects + */ + virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive) = 0; - /** Enable / disable a low level keyboard. - * Such a keyboard can only send KeyDown and KeyUp event. It just consider the keyboard as a - * gamepad with lots of buttons... - * This returns a interface to some parameters when it is supported, or NULL otherwise. - * The interface pointer is valid as long as the low level keyboard is enabled. - * A call to disable the keyboard returns NULL, and restore the default keyboard behavior - */ - virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable) = 0; + /** Enable / disable a low level keyboard. + * Such a keyboard can only send KeyDown and KeyUp event. It just consider the keyboard as a + * gamepad with lots of buttons... + * This returns a interface to some parameters when it is supported, or NULL otherwise. + * The interface pointer is valid as long as the low level keyboard is enabled. + * A call to disable the keyboard returns NULL, and restore the default keyboard behavior + */ + virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable) = 0; - /** Get the delay in ms for mouse double clicks. - */ - virtual uint getDoubleClickDelay(bool hardwareMouse) = 0; + /** Get the delay in ms for mouse double clicks. + */ + virtual uint getDoubleClickDelay(bool hardwareMouse) = 0; - /** If true, capture the mouse to force it to stay under the window. - * NB : this has no effects if a low level mouse is used - */ - virtual void setCapture (bool b) = 0; + /** If true, capture the mouse to force it to stay under the window. + * NB : this has no effects if a low level mouse is used + */ + virtual void setCapture(bool b) = 0; - // see if system cursor is currently captured - virtual bool isSystemCursorCaptured() = 0; + // see if system cursor is currently captured + virtual bool isSystemCursorCaptured() = 0; - // Add a new cursor (name is case unsensitive) - virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap) = 0; + // Add a new cursor (name is case unsensitive) + virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap) = 0; - // Display a cursor from its name (case unsensitive) - virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false) = 0; + // Display a cursor from its name (case unsensitive) + virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false) = 0; - // Change default scale for all cursors - virtual void setCursorScale(float scale) = 0; + // Change default scale for all cursors + virtual void setCursorScale(float scale) = 0; - /** Check whether there is a low level device manager available, and get its interface. Return NULL if not available - * From this interface you can deal with mouse and keyboard as above, but you can also manage game device (joysticks, joypads ...) - */ - virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager() = 0; + /** Check whether there is a low level device manager available, and get its interface. Return NULL if not available + * From this interface you can deal with mouse and keyboard as above, but you can also manage game device (joysticks, joypads ...) + */ + virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager() = 0; // @} - /// Get the width and the height of the window - virtual void getWindowSize (uint32 &width, uint32 &height) = 0; - - /// Get the position of the window always (0,0) in fullscreen - virtual void getWindowPos (sint32 &x, sint32 &y) = 0; - - /** get the RGBA back buffer. After swapBuffers(), the content of the back buffer is undefined. - * - * \param bitmap the buffer will be written in this bitmap - */ - virtual void getBuffer (CBitmap &bitmap) = 0; - - /** get the ZBuffer (back buffer). - * - * \param zbuffer the returned array of Z. size of getWindowSize() . - */ - virtual void getZBuffer (std::vector &zbuffer) = 0; - - /** get a part of the RGBA back buffer. After swapBuffers(), the content of the back buffer is undefined. - * NB: 0,0 is the bottom left corner of the screen. - * - * \param bitmap the buffer will be written in this bitmap - * \param rect the in/out (wanted/clipped) part of Color buffer to retrieve. - */ - virtual void getBufferPart (CBitmap &bitmap, NLMISC::CRect &rect) = 0; - - // copy the first texture in a second one of different dimensions - virtual bool stretchRect (ITexture * srcText, NLMISC::CRect &srcRect, ITexture * destText, NLMISC::CRect &destRect) = 0; - - // is this texture a rectangle texture ? - virtual bool isTextureRectangle(ITexture * tex) const = 0; - - // return true if driver support Bloom effect. - virtual bool supportBloomEffect() const =0; - - // return true if driver support non-power of two textures - virtual bool supportNonPowerOfTwoTextures() const =0; - - /** get a part of the ZBuffer (back buffer). - * NB: 0,0 is the bottom left corner of the screen. - * - * \param zbuffer the returned array of Z. size of rec.Width*rec.Height. - * \param rect the in/out (wanted/clipped) part of ZBuffer to retrieve. - */ - virtual void getZBufferPart (std::vector &zbuffer, NLMISC::CRect &rect) = 0; + /// \name Render target // TODO: Handle Color/ZBuffer/Stencil consistently + // @{ /** Set the current render target. * * The render target can be a texture (tex pointer) or the back buffer (tex = NULL). @@ -843,17 +944,23 @@ public: * \param cubaFace the face of the cube to copy texture to. * \return true if the render target has been changed */ - virtual bool setRenderTarget (ITexture *tex, - uint32 x = 0, - uint32 y = 0, - uint32 width = 0, - uint32 height = 0, - uint32 mipmapLevel = 0, - uint32 cubeFace = 0 - ) = 0 ; + virtual bool setRenderTarget( ITexture *tex, + uint32 x = 0, + uint32 y = 0, + uint32 width = 0, + uint32 height = 0, + uint32 mipmapLevel = 0, + uint32 cubeFace = 0 + ) = 0; virtual ITexture *getRenderTarget() const = 0; + /** Retrieve the render target size. + * If the render target is the frame buffer, it returns the size of the frame buffer. + * It the render target is a texture, it returns the size of the texture mipmap selected as render target. + */ + virtual bool getRenderTargetSize (uint32 &width, uint32 &height) = 0; + /** Trick method : copy the current texture target into another texture without updating the current texture. * * This method copies the current texture into another texture. @@ -880,30 +987,21 @@ public: * \param height height of the renderable area to copy, if 0, use the whole size. * \param mipmapLevel the mipmap to copy texture to. */ - virtual bool copyTargetToTexture (ITexture *tex, - uint32 offsetx = 0, - uint32 offsety = 0, - uint32 x = 0, - uint32 y = 0, - uint32 width = 0, - uint32 height = 0, - uint32 mipmapLevel = 0 + virtual bool copyTargetToTexture( ITexture *tex, + uint32 offsetx = 0, + uint32 offsety = 0, + uint32 x = 0, + uint32 y = 0, + uint32 width = 0, + uint32 height = 0, + uint32 mipmapLevel = 0 ) = 0; - - /** Retrieve the render target size. - * If the render target is the frame buffer, it returns the size of the frame buffer. - * It the render target is a texture, it returns the size of the texture mipmap selected as render target. - */ - virtual bool getRenderTargetSize (uint32 &width, uint32 &height) = 0; - - /** fill the RGBA back buffer - * - * \param bitmap will be written in the buffer. no-op if bad size. - * \return true if success - */ - virtual bool fillBuffer (CBitmap &bitmap) = 0; + // @} + + /// \name Render state: Polygon mode + // @{ /** Set the global polygon mode. Can be filled, line or point. The implementation driver must * call IDriver::setPolygonMode and active this mode. * @@ -915,13 +1013,27 @@ public: _PolygonMode=mode; } + /** Get the global polygon mode. + * + * \param polygon mode choose in this driver. + * \see setPolygonMode(), TPolygonMode + */ + TPolygonMode getPolygonMode () + { + return _PolygonMode; + } + // @} + + + /// \name Fixed pipeline lights + // @{ /** * return the number of light supported by driver. typically 8. * * \see enableLight() setLight() */ - virtual uint getMaxLight () const = 0; + virtual uint getMaxLight() const = 0; /** * Setup a light. @@ -932,7 +1044,7 @@ public: * \param light is a light to set in this slot. * \see enableLight() */ - virtual void setLight (uint8 num, const CLight& light) = 0; + virtual void setLight(uint8 num, const CLight &light) = 0; /** * Enable / disable light. @@ -943,7 +1055,7 @@ public: * \param enable is true to enable the light, false to disable it. * \see setLight() */ - virtual void enableLight (uint8 num, bool enable=true) = 0; + virtual void enableLight(uint8 num, bool enable = true) = 0; /** * Set ambient. @@ -951,112 +1063,134 @@ public: * \param color is the new global ambient color for the scene. * \see setLight(), enableLight() */ - virtual void setAmbientColor (CRGBA color) = 0; + virtual void setAmbientColor(NLMISC::CRGBA color) = 0; /** Setup the light used for per pixel lighting. The given values should have been modulated by the material diffuse and specular. * This is only useful for material that have their shader set as 'PerPixelLighting' * \param the light used for per pixel lighting */ - virtual void setPerPixelLightingLight(CRGBA diffuse, CRGBA specular, float shininess) = 0; + virtual void setPerPixelLightingLight(NLMISC::CRGBA diffuse, NLMISC::CRGBA specular, float shininess) = 0; /** Setup the unique light used for Lightmap Shader. * Lightmaped primitives are lit per vertex with this light (should be local attenuated for maximum efficiency) * This is only useful for material that have their shader set as 'LightMap' * \param the light used for per pixel lighting */ - virtual void setLightMapDynamicLight (bool enable, const CLight& light) = 0; + virtual void setLightMapDynamicLight(bool enable, const CLight &light) = 0; + // @} - /** Get the global polygon mode. - * - * \param polygon mode choose in this driver. - * \see setPolygonMode(), TPolygonMode - */ - TPolygonMode getPolygonMode () - { - return _PolygonMode; - } - /// \name Vertex program interface + + /// \name Vertex Program // @{ - enum TMatrix - { - ModelView= 0, - Projection, - ModelViewProjection, - NumMatrix - }; - - enum TTransform - { - Identity=0, - Inverse, - Transpose, - InverseTranspose, - NumTransform - }; - - /** - * Does the driver supports vertex programs ? - */ - virtual bool supportVertexProgram () const =0; + // Order of preference + // - activeVertexProgram + // - CMaterial pass[n] VP (uses activeVertexProgram, but does not override if one already set by code) + // - default generic VP that mimics fixed pipeline / no VP with fixed pipeline /** * Does the driver supports vertex program, but emulated by CPU ? */ - virtual bool isVertexProgramEmulated () const =0; + virtual bool isVertexProgramEmulated() const = 0; - /** - * Does the driver supports pixel programs ? + /** Return true if the driver supports the specified vertex program profile. */ - virtual bool supportPixelProgram() const =0; - virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const =0; + virtual bool supportVertexProgram(CVertexProgram::TProfile profile = CVertexProgram::nelvp) const = 0; - - - /** - * Activate / disactivate a vertex program - * - * \param program is a pointer on a vertex program. Can be NULL to disable the current vertex program. - * - * \return true if setup/unsetup succeeded, false else. + /** Compile the given vertex program, return if successful. Error information is returned as a string. */ - virtual bool activeVertexProgram (CVertexProgram *program) =0; + virtual bool compileVertexProgram(CVertexProgram *program, std::string &error) const = 0; - /** - * Activate / disactivate a pixel program - * - * \param program is a pointer on a pixel program. Can be NULL to disable the current pixel program. - * - * \return true if setup/unsetup successed, false else. - */ - virtual bool activePixelProgram (CPixelProgram *program) =0; - - /** - * Setup vertex program constant (uniform) values. + /** Set the active vertex program. This will override vertex programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL. + * The vertex program is activated immediately. */ - virtual void setConstant (uint index, float, float, float, float) =0; - virtual void setConstant (uint index, double, double, double, double) =0; - virtual void setConstant (uint index, const NLMISC::CVector& value) =0; - virtual void setConstant (uint index, const NLMISC::CVectorD& value) =0; + virtual bool activeVertexProgram(CVertexProgram *program) = 0; + + /** Get the currently active vertex program. + */ + virtual CVertexProgram *getActiveVertexProgram() const = 0; + + // Set parameters + virtual void setVertexProgram1f(uint index, float f0) = 0; + virtual void setVertexProgram2f(uint index, float f0, float f1) = 0; + virtual void setVertexProgram3f(uint index, float f0, float f1, float f2) = 0; + virtual void setVertexProgram4f(uint index, float f0, float f1, float f2, float f3) = 0; + virtual void setVertexProgram1i(uint index, sint32 i0) = 0; + virtual void setVertexProgram2i(uint index, sint32 i0, sint32 i1) = 0; + virtual void setVertexProgram3i(uint index, sint32 i0, sint32 i1, sint32 i2) = 0; + virtual void setVertexProgram4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) = 0; + virtual void setVertexProgram3f(uint index, const NLMISC::CVector& v) = 0; + virtual void setVertexProgram4f(uint index, const NLMISC::CVector& v, float f3) = 0; + virtual void setVertexProgram4x4f(uint index, const NLMISC::CMatrix& m) = 0; + virtual void setVertexProgram1fv(uint index, size_t num, const float *src) = 0; + virtual void setVertexProgram2fv(uint index, size_t num, const float *src) = 0; + virtual void setVertexProgram3fv(uint index, size_t num, const float *src) = 0; + virtual void setVertexProgram4fv(uint index, size_t num, const float *src) = 0; + // @} + + + + /// \name Pixel Program + // @{ + + // Order of preference + // - activePixelProgram + // - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code) + // - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code) + + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::nelvp) const = 0; + + /** Compile the given pixel program, return if successful. Error information is returned as a string. + */ + virtual bool compilePixelProgram(CPixelProgram *program, std::string &error) const = 0; + + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activePixelProgram(CPixelProgram *program) = 0; + + /** Get the currently active pixel program. + */ + virtual CPixelProgram *getActivePixelProgram() const = 0; + + // Set parameters + virtual void setPixelProgram1f(uint index, float f0) = 0; + virtual void setPixelProgram2f(uint index, float f0, float f1) = 0; + virtual void setPixelProgram3f(uint index, float f0, float f1, float f2) = 0; + virtual void setPixelProgram4f(uint index, float f0, float f1, float f2, float f3) = 0; + virtual void setPixelProgram1i(uint index, sint32 i0) = 0; + virtual void setPixelProgram2i(uint index, sint32 i0, sint32 i1) = 0; + virtual void setPixelProgram3i(uint index, sint32 i0, sint32 i1, sint32 i2) = 0; + virtual void setPixelProgram4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) = 0; + virtual void setPixelProgram3f(uint index, const NLMISC::CVector& v) = 0; + virtual void setPixelProgram4f(uint index, const NLMISC::CVector& v, float f3) = 0; + virtual void setPixelProgram4x4f(uint index, const NLMISC::CMatrix& m) = 0; + virtual void setPixelProgram1fv(uint index, size_t num, const float *src) = 0; + virtual void setPixelProgram2fv(uint index, size_t num, const float *src) = 0; + virtual void setPixelProgram3fv(uint index, size_t num, const float *src) = 0; + virtual void setPixelProgram4fv(uint index, size_t num, const float *src) = 0; + // @} + + + + /// \name Legacy vertex program parameter setters + // @{ + /** + * Setup constant values. + */ + inline void setConstant(uint index, float f0, float f1, float f2, float f3) { setVertexProgram4f(index, f0, f1, f2, f3); } + inline void setConstant(uint index, double d0, double d1, double d2, double d3) { setVertexProgram4f(index, (float)d0, (float)d1, (float)d2, (float)d3); } + inline void setConstant(uint index, const NLMISC::CVector &value) { setVertexProgram4f(index, value, 0.f); } + inline void setConstant(uint index, const NLMISC::CVectorD &value) { setVertexProgram4f(index, (float)value.x, (float)value.y, (float)value.z, 0.f); } /// setup several 4 float csts taken from the given tab - virtual void setConstant (uint index, uint num, const float *src) =0; - /// setup several 4 double csts taken from the given tab - virtual void setConstant (uint index, uint num, const double *src) =0; - // TODO: rename to setVertexProgramConstant - - /** - * Setup pixel program constant (uniform) values. - */ - virtual void setPixelProgramConstant (uint index, float, float, float, float) =0; - virtual void setPixelProgramConstant (uint index, double, double, double, double) =0; - virtual void setPixelProgramConstant (uint index, const NLMISC::CVector& value) =0; - virtual void setPixelProgramConstant (uint index, const NLMISC::CVectorD& value) =0; - /// setup several 4 float csts taken from the given tab - virtual void setPixelProgramConstant (uint index, uint num, const float *src) =0; - /// setup several 4 double csts taken from the given tab - virtual void setPixelProgramConstant (uint index, uint num, const double *src) =0; - // TODO: uint32 and sint32 uniform types supported in opengl from gp4fp and gp5fp and sint32 in d3d + inline void setConstant(uint index, uint num, const float *src) { setVertexProgram4fv(index, num, src); } + /// setup several 4 double csts taken from the given tab (convert to float) + virtual void setConstant(uint index, uint num, const double *src) = 0; /** * Setup constants with a current matrix. @@ -1069,20 +1203,7 @@ public: * \param transform is the transformation to apply to the matrix before store it in the constants. * */ - virtual void setPixelProgramConstantMatrix (uint index, TMatrix matrix, TTransform transform) =0; - - /** - * Setup constants with a current matrix. - * - * This call must be done after setFrustum(), setupViewMatrix() or setupModelMatrix() to get correct - * results. - * - * \param index is the base constant index where to store the matrix. This index must be a multiple of 4. - * \param matrix is the matrix id to store in the constants - * \param transform is the transformation to apply to the matrix before store it in the constants. - * - */ - virtual void setConstantMatrix (uint index, TMatrix matrix, TTransform transform) =0; + virtual void setConstantMatrix(uint index, TMatrix matrix, TTransform transform) = 0; /** * Setup the constant with the fog vector. This vector must be used to get the final fog value in a vertex shader. @@ -1096,14 +1217,26 @@ public: * \param index is the index where to store the vector. * */ - virtual void setConstantFog (uint index) =0; + virtual void setConstantFog(uint index) = 0; + // @} - /// Check if the driver support double sided colors vertex programs - virtual bool supportVertexProgramDoubleSidedColor() const = 0; + + /// \name Legacy effects + // @{ // test if support for cloud render in a single pass virtual bool supportCloudRenderSinglePass() const = 0; + // [FIXME] Return true if driver support Bloom effect // FIXME: This is terrible + virtual bool supportBloomEffect() const = 0; + // @} + + + + /// \name Backface color + // @{ + /// Check if the driver support double sided colors vertex programs + virtual bool supportVertexProgramDoubleSidedColor() const = 0; /** * Activate VertexProgram 2Sided Color mode. In 2Sided mode, the BackFace (if material 2Sided enabled) read the * result from o[BFC0], and not o[COL0]. @@ -1111,27 +1244,29 @@ public: * NB: no-op if not supported by driver */ virtual void enableVertexProgramDoubleSidedColor(bool doubleSided) =0; - // @} + + /// \name Texture addressing modes aka textures/pixels shaders // @{ - /// test whether the device supports some form of texture shader. (could be limited to DX6 EMBM for example) - virtual bool supportTextureShaders() const = 0; - // Is the shader water supported ? If not, the driver caller should implement its own version - virtual bool supportWaterShader() const = 0; - // - /// test whether a texture addressing mode is supported - virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode mode) const = 0; - /** setup the 2D matrix for the OffsetTexture, OffsetTextureScale and OffsetTexture addressing mode - * It should be stored as the following - * [a0 a1] - * [a2 a3] - */ - virtual void setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4]) = 0; + /// test whether the device supports some form of texture shader. (could be limited to DX6 EMBM for example) + virtual bool supportTextureShaders() const = 0; + // Is the shader water supported ? If not, the driver caller should implement its own version + virtual bool supportWaterShader() const = 0; + // + /// test whether a texture addressing mode is supported + virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode mode) const = 0; + /** setup the 2D matrix for the OffsetTexture, OffsetTextureScale and OffsetTexture addressing mode + * It should be stored as the following + * [a0 a1] + * [a2 a3] + */ + virtual void setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4]) = 0; //@} + /** \name EMBM support. If texture shaders are present, this is not available, must use them instead. * EMBM is a color op of CMaterial. * NB : EMBM is the equivalent of the CMaterial::OffsetTexture addressing mode. However, it is both a texture @@ -1143,38 +1278,35 @@ public: */ // @{ - // Test if EMBM is supported. - virtual bool supportEMBM() const = 0; - // Test if EMBM is supported for the given stage - virtual bool isEMBMSupportedAtStage(uint stage) const = 0; - // set the matrix used for EMBM addressing - virtual void setEMBMMatrix(const uint stage, const float mat[4]) = 0; + // Test if EMBM is supported. + virtual bool supportEMBM() const = 0; + // Test if EMBM is supported for the given stage + virtual bool isEMBMSupportedAtStage(uint stage) const = 0; + // set the matrix used for EMBM addressing + virtual void setEMBMMatrix(const uint stage, const float mat[4]) = 0; // @} - // Does the driver support the per-pixel lighting shader ? - virtual bool supportPerPixelLighting(bool specular) const = 0; /// \name Misc // @{ - /** Does the driver support Blend Constant Color ??? If yes CMaterial::blendConstant* enum can be used * for blend Src ord Dst factor. If no, using these enum will have undefined results. */ - virtual bool supportBlendConstantColor() const =0; + virtual bool supportBlendConstantColor() const = 0; /** see supportBlendConstantColor(). Set the current Blend Constant Color. */ - virtual void setBlendConstantColor(NLMISC::CRGBA col)=0; + virtual void setBlendConstantColor(NLMISC::CRGBA col) = 0; /** see supportBlendConstantColor(). Get the current Blend Constant Color. */ - virtual NLMISC::CRGBA getBlendConstantColor() const =0; + virtual NLMISC::CRGBA getBlendConstantColor() const = 0; /** force the driver to flush all command. glFinish() in opengl. * Interesting only for debug and profiling purpose. */ - virtual void finish() =0; + virtual void finish() = 0; // Flush command queue an immediately returns virtual void flush() = 0; @@ -1183,27 +1315,27 @@ public: * See GL_POLYGON_SMOOTH help, and GL_SRC_ALPHA_SATURATE OpenGL doc (not yet implemented now since * used only for alpha part in ShadowMap gen) */ - virtual void enablePolygonSmoothing(bool smooth) =0; + virtual void enablePolygonSmoothing(bool smooth) = 0; /// see enablePolygonSmoothing() - virtual bool isPolygonSmoothingEnabled() const =0; - + virtual bool isPolygonSmoothingEnabled() const = 0; // @} + /** Special method to internally swap the Driver handle of 2 textures. * USE IT WITH CARE (eg: may have Size problems, mipmap problems, format problems ...) * Actually, it is used only by CAsyncTextureManager, to manage Lods of DXTC CTextureFile. * NB: internally, all textures slots are disabled. */ - virtual void swapTextureHandle(ITexture &tex0, ITexture &tex1) =0; + virtual void swapTextureHandle(ITexture &tex0, ITexture &tex1) = 0; /** Advanced usage. Get the texture Handle.Useful for texture sorting for instance * NB: if the texture is not setuped in the driver, 0 is returned. * NB: if implementation does not support it, 0 may be returned. OpenGL ones return the Texture ID. * NB: unlike isTextureExist(), this method is not thread safe. */ - virtual uint getTextureHandle(const ITexture&tex)=0; + virtual uint getTextureHandle(const ITexture&tex) = 0; // see if the Multiply-Add Tex Env operator is supported (see CMaterial::Mad) virtual bool supportMADOperator() const = 0; @@ -1224,16 +1356,16 @@ public: }; // Get the number of hardware renderer available on the client platform. - virtual uint getNumAdapter() const=0; + virtual uint getNumAdapter() const = 0; // Get a hardware renderer description. - virtual bool getAdapter(uint adapter, CAdapter &desc) const=0; + virtual bool getAdapter(uint adapter, CAdapter &desc) const = 0; /** Choose the hardware renderer. * Call it before the setDisplay and enumModes methods * Choose adapter = 0xffffffff for the default one. */ - virtual bool setAdapter(uint adapter)=0; + virtual bool setAdapter(uint adapter) = 0; /** Tell if the vertex color memory format is RGBA (openGL) or BGRA (directx) * BGRA : @@ -1247,20 +1379,22 @@ public: */ virtual CVertexBuffer::TVertexColorType getVertexColorFormat() const =0; + + /// \name Bench // @{ - // Start the bench. See CHTimer::startBench(); - virtual void startBench (bool wantStandardDeviation = false, bool quick = false, bool reset = true) =0; + virtual void startBench(bool wantStandardDeviation = false, bool quick = false, bool reset = true) =0; // End the bench. See CHTimer::endBench(); - virtual void endBench () =0; + virtual void endBench () =0; // Display the bench result - virtual void displayBench (class NLMISC::CLog *log) =0; - + virtual void displayBench (class NLMISC::CLog *log) =0; // @} + + /// \name Occlusion query mechanism // @{ // Test whether this device supports the occlusion query mechanism @@ -1273,8 +1407,8 @@ public: virtual void deleteOcclusionQuery(IOcclusionQuery *oq) = 0; // @} - // get the number of call to swapBuffer since the driver was created - virtual uint64 getSwapBufferCounter() const = 0; + + /** Set cull mode * Useful for mirrors / cube map rendering or when the scene must be rendered upside down @@ -1291,23 +1425,25 @@ public: virtual void stencilMask(uint mask) = 0; protected: - friend class IVBDrvInfos; - friend class IIBDrvInfos; - friend class CTextureDrvShare; - friend class ITextureDrvInfos; - friend class IMaterialDrvInfos; - friend class IGPUProgramDrvInfos; + friend class IVBDrvInfos; + friend class IIBDrvInfos; + friend class CTextureDrvShare; + friend class ITextureDrvInfos; + friend class IMaterialDrvInfos; + friend class IGPUProgramDrvInfos; + friend class IGPUProgramParamsDrvInfos; /// remove ptr from the lists in the driver. - void removeVBDrvInfoPtr(ItVBDrvInfoPtrList vbDrvInfoIt); - void removeIBDrvInfoPtr(ItIBDrvInfoPtrList ibDrvInfoIt); - void removeTextureDrvInfoPtr(ItTexDrvInfoPtrMap texDrvInfoIt); - void removeTextureDrvSharePtr(ItTexDrvSharePtrList texDrvShareIt); - void removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt); - void removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt); + void removeVBDrvInfoPtr(ItVBDrvInfoPtrList vbDrvInfoIt); + void removeIBDrvInfoPtr(ItIBDrvInfoPtrList ibDrvInfoIt); + void removeTextureDrvInfoPtr(ItTexDrvInfoPtrMap texDrvInfoIt); + void removeTextureDrvSharePtr(ItTexDrvSharePtrList texDrvShareIt); + void removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt); + void removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt); private: - bool _StaticMemoryToVRAM; + bool _StaticMemoryToVRAM; + }; // -------------------------------------------------- diff --git a/code/nel/include/nel/3d/driver_user.h b/code/nel/include/nel/3d/driver_user.h index fff83d6d5..30ea98c65 100644 --- a/code/nel/include/nel/3d/driver_user.h +++ b/code/nel/include/nel/3d/driver_user.h @@ -474,7 +474,6 @@ public: virtual void forceDXTCCompression(bool dxtcComp); virtual void setAnisotropicFilter(sint filter); virtual void forceTextureResize(uint divisor); - virtual void forceNativeFragmentPrograms(bool nativeOnly); virtual bool setMonitorColorProperties (const CMonitorColorProperties &properties); // @} diff --git a/code/nel/include/nel/3d/gpu_program_params.h b/code/nel/include/nel/3d/gpu_program_params.h index d1a3125a2..08d8010d4 100644 --- a/code/nel/include/nel/3d/gpu_program_params.h +++ b/code/nel/include/nel/3d/gpu_program_params.h @@ -48,10 +48,10 @@ namespace NL3D { * \brief CGPUProgramParams * \date 2013-09-07 22:17GMT * \author Jan Boon (Kaetemi) - * A storage for user-provided parameters for GPU programs. + * A storage for USERCODE-PROVIDED parameters for GPU programs. * Allows for fast updating and iteration of parameters. * NOTE TO DRIVER IMPLEMENTORS: DO NOT USE FOR STORING COPIES - * OF HARDCODED MATERIAL PARAMETERS OR DRIVER PARAMETERS!!! + * OF HARDCODED DRIVER MATERIAL PARAMETERS OR DRIVER PARAMETERS!!! */ class CGPUProgramParams { @@ -66,36 +66,70 @@ public: CGPUProgramParams(); virtual ~CGPUProgramParams(); - void setF(uint index, float f0); - void setF(uint index, float f0, float f1); - void setF(uint index, float f0, float f1, float f2); - void setF(uint index, float f0, float f1, float f2, float f3); - void setI(uint index, int i0); - void setI(uint index, int i0, int i1); - void setI(uint index, int i0, int i1, int i2); - void setI(uint index, int i0, int i1, int i2, int i3); - void setF(uint index, const NLMISC::CVector& v); - void setF(uint index, const NLMISC::CMatrix& m); - void setF(uint index, uint num, const float *src); + // Copy from another params storage + void copy(CGPUProgramParams *params); + + // Set by index, available only when the associated program has been compiled + void set1f(uint index, float f0); + void set2f(uint index, float f0, float f1); + void set3f(uint index, float f0, float f1, float f2); + void set4f(uint index, float f0, float f1, float f2, float f3); + void set1i(uint index, sint32 i0); + void set2i(uint index, sint32 i0, sint32 i1); + void set3i(uint index, sint32 i0, sint32 i1, sint32 i2); + void set4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + void set3f(uint index, const NLMISC::CVector& v); + void set4f(uint index, const NLMISC::CVector& v, float f3); + void set4x4f(uint index, const NLMISC::CMatrix& m); + void set1fv(uint index, size_t num, const float *src); + void set2fv(uint index, size_t num, const float *src); + void set3fv(uint index, size_t num, const float *src); + void set4fv(uint index, size_t num, const float *src); + void unset(uint index); + + // Set by name, it is recommended to use index when repeatedly setting an element + void set1f(const std::string &name, float f0); + void set2f(const std::string &name, float f0, float f1); + void set3f(const std::string &name, float f0, float f1, float f2); + void set4f(const std::string &name, float f0, float f1, float f2, float f3); + void set1i(const std::string &name, sint32 i0); + void set2i(const std::string &name, sint32 i0, sint32 i1); + void set3i(const std::string &name, sint32 i0, sint32 i1, sint32 i2); + void set4i(const std::string &name, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + void set3f(const std::string &name, const NLMISC::CVector& v); + void set4f(const std::string &name, const NLMISC::CVector& v, float f3); + void set4x4f(const std::string &name, const NLMISC::CMatrix& m); + void set1fv(const std::string &name, size_t num, const float *src); + void set2fv(const std::string &name, size_t num, const float *src); + void set3fv(const std::string &name, size_t num, const float *src); + void set4fv(const std::string &name, size_t num, const float *src); + void unset(const std::string &name); + + /// Maps the given name to the given index, on duplicate entry the data set by name will be prefered as it can be assumed to have been set after the data set by index + void map(uint index, const std::string &name); // Internal /// Allocate specified number of components if necessary size_t allocOffset(uint index, uint count, TType type); + size_t allocOffset(const std::string &name, uint count, TType type); /// Return offset for specified index size_t getOffset(uint index) const; + size_t getOffset(const std::string &name) const; /// Remove by offset void freeOffset(size_t offset); - // Iteration + // Iteration (returns the offsets for access using getFooByOffset) size_t getBegin() const { return m_Meta.size() ? m_First : s_End; } size_t getNext(size_t offset) const { return m_Meta[offset].Next; } size_t getEnd() const { return s_End; } // Data access - uint getCountByOffset(size_t offset) { return m_Meta[offset].Count; } + uint getCountByOffset(size_t offset) { return m_Meta[offset].Count; } // component count (number of floats or ints) float *getPtrFByOffset(size_t offset) { return m_Vec[offset].F; } int *getPtrIByOffset(size_t offset) { return m_Vec[offset].I; } TType getTypeByOffset(size_t offset) { return m_Meta[offset].Type; } + uint getIndexByOffset(size_t offset) { return m_Meta[offset].Index; } + const std::string *getNameByOffset(size_t offset); // non-optimized for dev tools only, may return NULL if name unknown // Utility static inline uint getNbRegistersByComponents(uint count) { return (count + 3) >> 2; } // vector register per 4 components @@ -103,7 +137,8 @@ public: private: std::vector m_Vec; std::vector m_Meta; - std::vector m_Map; // map from index to buffer index + std::vector m_Map; // map from index to offset + std::map m_MapName; // map from name to offset size_t m_First; size_t m_Last; static const size_t s_End = -1; diff --git a/code/nel/include/nel/3d/u_driver.h b/code/nel/include/nel/3d/u_driver.h index 1397c9c6e..2e74ae3fe 100644 --- a/code/nel/include/nel/3d/u_driver.h +++ b/code/nel/include/nel/3d/u_driver.h @@ -673,13 +673,6 @@ public: */ virtual void forceTextureResize(uint divisor)=0; - /** Sets enforcement of native fragment programs. This is by default enabled. - * - * \param nativeOnly If set to false, fragment programs don't need to be native to stay loaded, - * otherwise (aka if true) they will be purged. - */ - virtual void forceNativeFragmentPrograms(bool nativeOnly) = 0; - /** Setup monitor color properties. * * Return false if setup failed. diff --git a/code/nel/src/3d/driver.cpp b/code/nel/src/3d/driver.cpp index 31dd4d2ec..2bfb0ea1f 100644 --- a/code/nel/src/3d/driver.cpp +++ b/code/nel/src/3d/driver.cpp @@ -240,24 +240,9 @@ void IDriver::removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt) _MatDrvInfos.erase(shaderIt); } // *************************************************************************** -/*void IDriver::removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt) +void IDriver::removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt) { - _ShaderDrvInfos.erase(shaderIt); -} -// *************************************************************************** -void IDriver::removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt) -{ - _VtxPrgDrvInfos.erase(vtxPrgDrvInfoIt); -} -// *************************************************************************** -void IDriver::removePixelPrgDrvInfoPtr(ItPixelPrgDrvInfoPtrList pixelPrgDrvInfoIt) -{ - _PixelPrgDrvInfos.erase(pixelPrgDrvInfoIt); -}*/ -// *************************************************************************** -void IDriver::removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList vtxPrgDrvInfoIt) -{ - _GPUPrgDrvInfos.erase(vtxPrgDrvInfoIt); + _GPUPrgDrvInfos.erase(gpuPrgDrvInfoIt); } // *************************************************************************** diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index d329a6f56..3494812cc 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -880,7 +880,6 @@ public: virtual void forceDXTCCompression(bool dxtcComp); virtual void setAnisotropicFilter(sint filter); virtual void forceTextureResize(uint divisor); - virtual void forceNativeFragmentPrograms(bool /* nativeOnly */) {} // ignored // Driver information virtual uint getNumAdapter() const; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index a93c05338..3eff7eebf 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -1993,12 +1993,6 @@ static void fetchPerturbedEnvMapR200() #endif } -// *************************************************************************** -void CDriverGL::forceNativeFragmentPrograms(bool nativeOnly) -{ - _ForceNativeFragmentPrograms = nativeOnly; -} - // *************************************************************************** void CDriverGL::initFragmentShaders() { diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 29fd59957..89b71c931 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -370,8 +370,6 @@ public: virtual void forceTextureResize(uint divisor); - virtual void forceNativeFragmentPrograms(bool nativeOnly); - /// Setup texture env functions. Used by setupMaterial void setTextureEnvFunction(uint stage, CMaterial& mat); diff --git a/code/nel/src/3d/driver_user.cpp b/code/nel/src/3d/driver_user.cpp index 83c7343ec..e5d814755 100644 --- a/code/nel/src/3d/driver_user.cpp +++ b/code/nel/src/3d/driver_user.cpp @@ -1496,12 +1496,6 @@ void CDriverUser::forceTextureResize(uint divisor) _Driver->forceTextureResize(divisor); } -void CDriverUser::forceNativeFragmentPrograms(bool nativeOnly) -{ - NL3D_HAUTO_UI_DRIVER; - - _Driver->forceNativeFragmentPrograms(nativeOnly); -} bool CDriverUser::setMonitorColorProperties (const CMonitorColorProperties &properties) { NL3D_HAUTO_UI_DRIVER; diff --git a/code/nel/src/3d/gpu_program_params.cpp b/code/nel/src/3d/gpu_program_params.cpp index 0a03500ea..217a9683e 100644 --- a/code/nel/src/3d/gpu_program_params.cpp +++ b/code/nel/src/3d/gpu_program_params.cpp @@ -36,6 +36,7 @@ #include // Project includes +#include using namespace std; // using namespace NLMISC; @@ -52,20 +53,20 @@ CGPUProgramParams::~CGPUProgramParams() } -void CGPUProgramParams::setF(uint index, float f0) +void CGPUProgramParams::set(uint index, float f0) { float *f = getPtrFByOffset(allocOffset(index, 1, Float)); f[0] = f0; } -void CGPUProgramParams::setF(uint index, float f0, float f1) +void CGPUProgramParams::set(uint index, float f0, float f1) { float *f = getPtrFByOffset(allocOffset(index, 2, Float)); f[0] = f0; f[1] = f1; } -void CGPUProgramParams::setF(uint index, float f0, float f1, float f2) +void CGPUProgramParams::set(uint index, float f0, float f1, float f2) { float *f = getPtrFByOffset(allocOffset(index, 3, Float)); f[0] = f0; @@ -73,7 +74,7 @@ void CGPUProgramParams::setF(uint index, float f0, float f1, float f2) f[2] = f2; } -void CGPUProgramParams::setF(uint index, float f0, float f1, float f2, float f3) +void CGPUProgramParams::set(uint index, float f0, float f1, float f2, float f3) { float *f = getPtrFByOffset(allocOffset(index, 4, Float)); f[0] = f0; @@ -82,20 +83,20 @@ void CGPUProgramParams::setF(uint index, float f0, float f1, float f2, float f3) f[3] = f3; } -void CGPUProgramParams::setI(uint index, int i0) +void CGPUProgramParams::set(uint index, int i0) { int *i = getPtrIByOffset(allocOffset(index, 1, Int)); i[0] = i0; } -void CGPUProgramParams::setI(uint index, int i0, int i1) +void CGPUProgramParams::set(uint index, int i0, int i1) { int *i = getPtrIByOffset(allocOffset(index, 2, Int)); i[0] = i0; i[1] = i1; } -void CGPUProgramParams::setI(uint index, int i0, int i1, int i2) +void CGPUProgramParams::set(uint index, int i0, int i1, int i2) { int *i = getPtrIByOffset(allocOffset(index, 3, Int)); i[0] = i0; @@ -103,7 +104,7 @@ void CGPUProgramParams::setI(uint index, int i0, int i1, int i2) i[2] = i2; } -void CGPUProgramParams::setI(uint index, int i0, int i1, int i2, int i3) +void CGPUProgramParams::set(uint index, int i0, int i1, int i2, int i3) { int *i = getPtrIByOffset(allocOffset(index, 4, Int)); i[0] = i0; @@ -112,7 +113,7 @@ void CGPUProgramParams::setI(uint index, int i0, int i1, int i2, int i3) i[3] = i3; } -void CGPUProgramParams::setF(uint index, const NLMISC::CVector& v) +void CGPUProgramParams::set(uint index, const NLMISC::CVector& v) { float *f = getPtrFByOffset(allocOffset(index, 3, Float)); f[0] = v.x; @@ -120,7 +121,7 @@ void CGPUProgramParams::setF(uint index, const NLMISC::CVector& v) f[2] = v.z; } -void CGPUProgramParams::setF(uint index, const NLMISC::CMatrix& m) +void CGPUProgramParams::set(uint index, const NLMISC::CMatrix& m) { // TODO: Verify this! float *f = getPtrFByOffset(allocOffset(index, 16, Float)); @@ -129,11 +130,18 @@ void CGPUProgramParams::setF(uint index, const NLMISC::CMatrix& m) mt.get(f); } -void CGPUProgramParams::setF(uint index, uint num, const float *src) +void CGPUProgramParams::set(uint index, const float *arr, size_t sz) { - float *f = getPtrFByOffset(allocOffset(index, num, Float)); - for (uint i = 0; i < num; ++i) - f[i] = src[i]; + float *f = getPtrFByOffset(allocOffset(index, sz, Float)); + for (uint c = 0; c < sz; ++c) + f[c] = arr[c]; +} + +void CGPUProgramParams::set(uint index, const sint32 *arr, size_t sz) +{ + int *i = getPtrIByOffset(allocOffset(index, sz, Int)); + for (uint c = 0; c < sz; ++c) + i[c] = arr[c]; } /// Allocate specified number of components if necessary diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 8c8c6ff63..e02ccd50c 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -563,6 +563,7 @@ bool CStereoOVR::endRenderTarget() NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); barrelMat->setTexture(0, m_BarrelTex); + drvInternal->activePixelProgram(m_PixelProgram); float w = float(m_BarrelQuadLeft.V1.x),// / float(width), @@ -582,20 +583,21 @@ bool CStereoOVR::endRenderTarget() float scaleY = (h / 2); float scaleInX = (2 / w); float scaleInY = (2 / h); - drvInternal->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f); - drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f); - drvInternal->setPixelProgramConstant(2, scaleX, scaleY, 0.f, 0.f); - drvInternal->setPixelProgramConstant(3, scaleInX, scaleInY, 0.f, 0.f); - drvInternal->setPixelProgramConstant(4, 1, m_DevicePtr->HMDInfo.DistortionK); - + + drvInternal->setPixelProgram2f(0, lensCenterX, lensCenterY); + drvInternal->setPixelProgram2f(1, screenCenterX, screenCenterY); + drvInternal->setPixelProgram2f(2, scaleX, scaleY); + drvInternal->setPixelProgram2f(3, scaleInX, scaleInY); + drvInternal->setPixelProgram4fv(4, 1, m_DevicePtr->HMDInfo.DistortionK); m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat); x = w; lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f; screenCenterX = x + w * 0.5f; - drvInternal->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f); - drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f); + + drvInternal->setPixelProgram2f(0, lensCenterX, lensCenterY); + drvInternal->setPixelProgram2f(1, screenCenterX, screenCenterY); m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat); From c512dfbb3dcf6be8d833670e806631a75c305887 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 01:31:15 +0200 Subject: [PATCH 100/137] Separate count and size --- code/nel/include/nel/3d/driver.h | 6 -- code/nel/include/nel/3d/gpu_program_params.h | 39 +++++----- code/nel/src/3d/gpu_program_params.cpp | 75 +++++++++----------- 3 files changed, 52 insertions(+), 68 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 2414d3df5..3e6b1e856 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1124,9 +1124,6 @@ public: virtual void setVertexProgram3f(uint index, const NLMISC::CVector& v) = 0; virtual void setVertexProgram4f(uint index, const NLMISC::CVector& v, float f3) = 0; virtual void setVertexProgram4x4f(uint index, const NLMISC::CMatrix& m) = 0; - virtual void setVertexProgram1fv(uint index, size_t num, const float *src) = 0; - virtual void setVertexProgram2fv(uint index, size_t num, const float *src) = 0; - virtual void setVertexProgram3fv(uint index, size_t num, const float *src) = 0; virtual void setVertexProgram4fv(uint index, size_t num, const float *src) = 0; // @} @@ -1170,9 +1167,6 @@ public: virtual void setPixelProgram3f(uint index, const NLMISC::CVector& v) = 0; virtual void setPixelProgram4f(uint index, const NLMISC::CVector& v, float f3) = 0; virtual void setPixelProgram4x4f(uint index, const NLMISC::CMatrix& m) = 0; - virtual void setPixelProgram1fv(uint index, size_t num, const float *src) = 0; - virtual void setPixelProgram2fv(uint index, size_t num, const float *src) = 0; - virtual void setPixelProgram3fv(uint index, size_t num, const float *src) = 0; virtual void setPixelProgram4fv(uint index, size_t num, const float *src) = 0; // @} diff --git a/code/nel/include/nel/3d/gpu_program_params.h b/code/nel/include/nel/3d/gpu_program_params.h index 08d8010d4..ce454b2ed 100644 --- a/code/nel/include/nel/3d/gpu_program_params.h +++ b/code/nel/include/nel/3d/gpu_program_params.h @@ -56,11 +56,11 @@ namespace NL3D { class CGPUProgramParams { public: - enum TType { Float, Int }; - struct CMeta { uint Index, Count; TType Type; size_t Next, Prev; }; + enum TType { Float, Int, UInt }; + struct CMeta { uint Index, Size, Count; TType Type; size_t Next, Prev; }; // size is element size, count is nb of elements private: - union CVec { float F[4]; sint32 I[4]; }; + union CVec { float F[4]; sint32 I[4]; uint32 UI[4]; }; public: CGPUProgramParams(); @@ -81,9 +81,6 @@ public: void set3f(uint index, const NLMISC::CVector& v); void set4f(uint index, const NLMISC::CVector& v, float f3); void set4x4f(uint index, const NLMISC::CMatrix& m); - void set1fv(uint index, size_t num, const float *src); - void set2fv(uint index, size_t num, const float *src); - void set3fv(uint index, size_t num, const float *src); void set4fv(uint index, size_t num, const float *src); void unset(uint index); @@ -99,9 +96,6 @@ public: void set3f(const std::string &name, const NLMISC::CVector& v); void set4f(const std::string &name, const NLMISC::CVector& v, float f3); void set4x4f(const std::string &name, const NLMISC::CMatrix& m); - void set1fv(const std::string &name, size_t num, const float *src); - void set2fv(const std::string &name, size_t num, const float *src); - void set3fv(const std::string &name, size_t num, const float *src); void set4fv(const std::string &name, size_t num, const float *src); void unset(const std::string &name); @@ -110,8 +104,8 @@ public: // Internal /// Allocate specified number of components if necessary - size_t allocOffset(uint index, uint count, TType type); - size_t allocOffset(const std::string &name, uint count, TType type); + size_t allocOffset(uint index, uint size, uint count, TType type); + size_t allocOffset(const std::string &name, uint size, uint count, TType type); /// Return offset for specified index size_t getOffset(uint index) const; size_t getOffset(const std::string &name) const; @@ -119,20 +113,23 @@ public: void freeOffset(size_t offset); // Iteration (returns the offsets for access using getFooByOffset) - size_t getBegin() const { return m_Meta.size() ? m_First : s_End; } - size_t getNext(size_t offset) const { return m_Meta[offset].Next; } - size_t getEnd() const { return s_End; } + inline size_t getBegin() const { return m_Meta.size() ? m_First : s_End; } + inline size_t getNext(size_t offset) const { return m_Meta[offset].Next; } + inline size_t getEnd() const { return s_End; } // Data access - uint getCountByOffset(size_t offset) { return m_Meta[offset].Count; } // component count (number of floats or ints) - float *getPtrFByOffset(size_t offset) { return m_Vec[offset].F; } - int *getPtrIByOffset(size_t offset) { return m_Vec[offset].I; } - TType getTypeByOffset(size_t offset) { return m_Meta[offset].Type; } - uint getIndexByOffset(size_t offset) { return m_Meta[offset].Index; } - const std::string *getNameByOffset(size_t offset); // non-optimized for dev tools only, may return NULL if name unknown + inline uint getSizeByOffset(size_t offset) const { return m_Meta[offset].Size; } // size of element (4 for float4) + inline uint getCountByOffset(size_t offset) const { return m_Meta[offset].Count; } // number of elements (usually 1) + inline uint getNbComponentsByOffset(size_t offset) const { return m_Meta[offset].Size * m_Meta[offset].Count; } // nb of components (size * count) + inline float *getPtrFByOffset(size_t offset) { return m_Vec[offset].F; } + inline sint32 *getPtrIByOffset(size_t offset) { return m_Vec[offset].I; } + inline uint32 *getPtrUIByOffset(size_t offset) { return m_Vec[offset].UI; } + inline TType getTypeByOffset(size_t offset) const { return m_Meta[offset].Type; } + inline uint getIndexByOffset(size_t offset) const { return m_Meta[offset].Index; } + const std::string *getNameByOffset(size_t offset) const; // non-optimized for dev tools only, may return NULL if name unknown // Utility - static inline uint getNbRegistersByComponents(uint count) { return (count + 3) >> 2; } // vector register per 4 components + static inline uint getNbRegistersByComponents(uint nbComponents) { return (nbComponents + 3) >> 2; } // vector register per 4 components private: std::vector m_Vec; diff --git a/code/nel/src/3d/gpu_program_params.cpp b/code/nel/src/3d/gpu_program_params.cpp index 217a9683e..bfcc4d32c 100644 --- a/code/nel/src/3d/gpu_program_params.cpp +++ b/code/nel/src/3d/gpu_program_params.cpp @@ -53,118 +53,110 @@ CGPUProgramParams::~CGPUProgramParams() } -void CGPUProgramParams::set(uint index, float f0) +void CGPUProgramParams::set1f(uint index, float f0) { - float *f = getPtrFByOffset(allocOffset(index, 1, Float)); + float *f = getPtrFByOffset(allocOffset(index, 1, 1, Float)); f[0] = f0; } -void CGPUProgramParams::set(uint index, float f0, float f1) +void CGPUProgramParams::set2f(uint index, float f0, float f1) { - float *f = getPtrFByOffset(allocOffset(index, 2, Float)); + float *f = getPtrFByOffset(allocOffset(index, 2, 1, Float)); f[0] = f0; f[1] = f1; } -void CGPUProgramParams::set(uint index, float f0, float f1, float f2) +void CGPUProgramParams::set3f(uint index, float f0, float f1, float f2) { - float *f = getPtrFByOffset(allocOffset(index, 3, Float)); + float *f = getPtrFByOffset(allocOffset(index, 3, 1, Float)); f[0] = f0; f[1] = f1; f[2] = f2; } -void CGPUProgramParams::set(uint index, float f0, float f1, float f2, float f3) +void CGPUProgramParams::set4f(uint index, float f0, float f1, float f2, float f3) { - float *f = getPtrFByOffset(allocOffset(index, 4, Float)); + float *f = getPtrFByOffset(allocOffset(index, 4, 1, Float)); f[0] = f0; f[1] = f1; f[2] = f2; f[3] = f3; } -void CGPUProgramParams::set(uint index, int i0) +void CGPUProgramParams::set1i(uint index, int i0) { - int *i = getPtrIByOffset(allocOffset(index, 1, Int)); + int *i = getPtrIByOffset(allocOffset(index, 1, 1, Int)); i[0] = i0; } -void CGPUProgramParams::set(uint index, int i0, int i1) +void CGPUProgramParams::set2i(uint index, int i0, int i1) { - int *i = getPtrIByOffset(allocOffset(index, 2, Int)); + int *i = getPtrIByOffset(allocOffset(index, 2, 1, Int)); i[0] = i0; i[1] = i1; } -void CGPUProgramParams::set(uint index, int i0, int i1, int i2) +void CGPUProgramParams::set3i(uint index, int i0, int i1, int i2) { - int *i = getPtrIByOffset(allocOffset(index, 3, Int)); + int *i = getPtrIByOffset(allocOffset(index, 3, 1, Int)); i[0] = i0; i[1] = i1; i[2] = i2; } -void CGPUProgramParams::set(uint index, int i0, int i1, int i2, int i3) +void CGPUProgramParams::set4i(uint index, int i0, int i1, int i2, int i3) { - int *i = getPtrIByOffset(allocOffset(index, 4, Int)); + int *i = getPtrIByOffset(allocOffset(index, 4, 1, Int)); i[0] = i0; i[1] = i1; i[2] = i2; i[3] = i3; } -void CGPUProgramParams::set(uint index, const NLMISC::CVector& v) +void CGPUProgramParams::set3f(uint index, const NLMISC::CVector& v) { - float *f = getPtrFByOffset(allocOffset(index, 3, Float)); + float *f = getPtrFByOffset(allocOffset(index, 3, 1, Float)); f[0] = v.x; f[1] = v.y; f[2] = v.z; } -void CGPUProgramParams::set(uint index, const NLMISC::CMatrix& m) +void CGPUProgramParams::set4x4f(uint index, const NLMISC::CMatrix& m) { // TODO: Verify this! - float *f = getPtrFByOffset(allocOffset(index, 16, Float)); + float *f = getPtrFByOffset(allocOffset(index, 4, 4, Float)); NLMISC::CMatrix mt = m; mt.transpose(); mt.get(f); } -void CGPUProgramParams::set(uint index, const float *arr, size_t sz) +void CGPUProgramParams::set4fv(uint index, size_t num, const float *src) { - float *f = getPtrFByOffset(allocOffset(index, sz, Float)); - for (uint c = 0; c < sz; ++c) - f[c] = arr[c]; -} - -void CGPUProgramParams::set(uint index, const sint32 *arr, size_t sz) -{ - int *i = getPtrIByOffset(allocOffset(index, sz, Int)); - for (uint c = 0; c < sz; ++c) - i[c] = arr[c]; + float *f = getPtrFByOffset(allocOffset(index, 4, num, Float)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + f[c] = src[c]; } /// Allocate specified number of components if necessary -size_t CGPUProgramParams::allocOffset(uint index, uint count, TType type) +size_t CGPUProgramParams::allocOffset(uint index, uint size, uint count, TType type) { nlassert(count > 0); // this code will not properly handle 0 + nlassert(size > 0); // this code will not properly handle 0 nlassert(index < 0xFFFF); // sanity check + uint nbComponents = size * count; size_t offset = getOffset(index); if (offset != s_End) { - if (getCountByOffset(offset) == count) + if (getCountByOffset(offset) >= nbComponents) { m_Meta[offset].Type = type; + m_Meta[offset].Size = size; + m_Meta[offset].Count = count; return offset; } - if (getCountByOffset(offset) > count) - { - m_Meta[offset].Type = type; - m_Meta[offset].Count = count; // reduce count - return offset; - } - if (getCountByOffset(offset) < count) + if (getCountByOffset(offset) < nbComponents) { freeOffset(offset); } @@ -172,7 +164,7 @@ size_t CGPUProgramParams::allocOffset(uint index, uint count, TType type) // Allocate space offset = m_Meta.size(); - uint blocks = getNbRegistersByComponents(count); // per 4 components + uint blocks = getNbRegistersByComponents(nbComponents); // per 4 components m_Meta.resize(offset + blocks); m_Vec.resize(offset + blocks); @@ -183,6 +175,7 @@ size_t CGPUProgramParams::allocOffset(uint index, uint count, TType type) // Fill m_Meta[offset].Index = index; + m_Meta[offset].Size = size; m_Meta[offset].Count = count; m_Meta[offset].Type = type; m_Meta[offset].Prev = m_Last; From 060bd3035e3fc08f82bd51919b084adc7df60f6d Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 01:53:02 +0200 Subject: [PATCH 101/137] Builtin parameter set functions --- code/nel/include/nel/3d/driver.h | 12 ++++++++---- code/nel/include/nel/3d/gpu_program_params.h | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 3e6b1e856..540b17962 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1125,6 +1125,9 @@ public: virtual void setVertexProgram4f(uint index, const NLMISC::CVector& v, float f3) = 0; virtual void setVertexProgram4x4f(uint index, const NLMISC::CMatrix& m) = 0; virtual void setVertexProgram4fv(uint index, size_t num, const float *src) = 0; + // Set builtin parameters + virtual void setVertexProgramMatrix(uint index, TMatrix matrix, TTransform transform) = 0; + virtual void setVertexProgramFog(uint index) = 0; // @} @@ -1168,6 +1171,9 @@ public: virtual void setPixelProgram4f(uint index, const NLMISC::CVector& v, float f3) = 0; virtual void setPixelProgram4x4f(uint index, const NLMISC::CMatrix& m) = 0; virtual void setPixelProgram4fv(uint index, size_t num, const float *src) = 0; + // Set builtin parameters + virtual void setPixelProgramMatrix(uint index, TMatrix matrix, TTransform transform) = 0; + virtual void setPixelProgramFog(uint index) = 0; // @} @@ -1183,8 +1189,6 @@ public: inline void setConstant(uint index, const NLMISC::CVectorD &value) { setVertexProgram4f(index, (float)value.x, (float)value.y, (float)value.z, 0.f); } /// setup several 4 float csts taken from the given tab inline void setConstant(uint index, uint num, const float *src) { setVertexProgram4fv(index, num, src); } - /// setup several 4 double csts taken from the given tab (convert to float) - virtual void setConstant(uint index, uint num, const double *src) = 0; /** * Setup constants with a current matrix. @@ -1197,7 +1201,7 @@ public: * \param transform is the transformation to apply to the matrix before store it in the constants. * */ - virtual void setConstantMatrix(uint index, TMatrix matrix, TTransform transform) = 0; + inline void setConstantMatrix(uint index, TMatrix matrix, TTransform transform) { setVertexProgramMatrix(index, matrix, transform); }; /** * Setup the constant with the fog vector. This vector must be used to get the final fog value in a vertex shader. @@ -1211,7 +1215,7 @@ public: * \param index is the index where to store the vector. * */ - virtual void setConstantFog(uint index) = 0; + inline void setConstantFog(uint index) { setVertexProgramFog(index); }; // @} diff --git a/code/nel/include/nel/3d/gpu_program_params.h b/code/nel/include/nel/3d/gpu_program_params.h index ce454b2ed..270c6cff5 100644 --- a/code/nel/include/nel/3d/gpu_program_params.h +++ b/code/nel/include/nel/3d/gpu_program_params.h @@ -52,6 +52,9 @@ namespace NL3D { * Allows for fast updating and iteration of parameters. * NOTE TO DRIVER IMPLEMENTORS: DO NOT USE FOR STORING COPIES * OF HARDCODED DRIVER MATERIAL PARAMETERS OR DRIVER PARAMETERS!!! + * The 4-component alignment that is done in this storage + * class is necessary to simplify support for register-based + * assembly shaders, which require setting per 4 components. */ class CGPUProgramParams { From 0cf5dbab8a854c20d848247b9e22f54b59185bd7 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 02:03:40 +0200 Subject: [PATCH 102/137] Reduce function duplication --- code/nel/include/nel/3d/driver.h | 71 +++++++++++++++----------------- code/nel/src/3d/stereo_ovr.cpp | 14 +++---- 2 files changed, 40 insertions(+), 45 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 540b17962..0fe4c6511 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -159,6 +159,13 @@ public: NumTransform }; + enum TProgram + { + VertexProgram, + PixelProgram, + GeometryProgram + }; + protected: CSynchronized _SyncTexDrvInfos; TTexDrvSharePtrList _TexDrvShares; @@ -1111,23 +1118,6 @@ public: /** Get the currently active vertex program. */ virtual CVertexProgram *getActiveVertexProgram() const = 0; - - // Set parameters - virtual void setVertexProgram1f(uint index, float f0) = 0; - virtual void setVertexProgram2f(uint index, float f0, float f1) = 0; - virtual void setVertexProgram3f(uint index, float f0, float f1, float f2) = 0; - virtual void setVertexProgram4f(uint index, float f0, float f1, float f2, float f3) = 0; - virtual void setVertexProgram1i(uint index, sint32 i0) = 0; - virtual void setVertexProgram2i(uint index, sint32 i0, sint32 i1) = 0; - virtual void setVertexProgram3i(uint index, sint32 i0, sint32 i1, sint32 i2) = 0; - virtual void setVertexProgram4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) = 0; - virtual void setVertexProgram3f(uint index, const NLMISC::CVector& v) = 0; - virtual void setVertexProgram4f(uint index, const NLMISC::CVector& v, float f3) = 0; - virtual void setVertexProgram4x4f(uint index, const NLMISC::CMatrix& m) = 0; - virtual void setVertexProgram4fv(uint index, size_t num, const float *src) = 0; - // Set builtin parameters - virtual void setVertexProgramMatrix(uint index, TMatrix matrix, TTransform transform) = 0; - virtual void setVertexProgramFog(uint index) = 0; // @} @@ -1157,23 +1147,28 @@ public: /** Get the currently active pixel program. */ virtual CPixelProgram *getActivePixelProgram() const = 0; + // @} + + + /// \name Program parameters + // @{ // Set parameters - virtual void setPixelProgram1f(uint index, float f0) = 0; - virtual void setPixelProgram2f(uint index, float f0, float f1) = 0; - virtual void setPixelProgram3f(uint index, float f0, float f1, float f2) = 0; - virtual void setPixelProgram4f(uint index, float f0, float f1, float f2, float f3) = 0; - virtual void setPixelProgram1i(uint index, sint32 i0) = 0; - virtual void setPixelProgram2i(uint index, sint32 i0, sint32 i1) = 0; - virtual void setPixelProgram3i(uint index, sint32 i0, sint32 i1, sint32 i2) = 0; - virtual void setPixelProgram4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) = 0; - virtual void setPixelProgram3f(uint index, const NLMISC::CVector& v) = 0; - virtual void setPixelProgram4f(uint index, const NLMISC::CVector& v, float f3) = 0; - virtual void setPixelProgram4x4f(uint index, const NLMISC::CMatrix& m) = 0; - virtual void setPixelProgram4fv(uint index, size_t num, const float *src) = 0; + virtual void setUniform1f(TProgram program, uint index, float f0) = 0; + virtual void setUniform2f(TProgram program, uint index, float f0, float f1) = 0; + virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2) = 0; + virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3) = 0; + virtual void setUniform1i(TProgram program, uint index, sint32 i0) = 0; + virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) = 0; + virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) = 0; + virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) = 0; + virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v) = 0; + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3) = 0; + virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) = 0; + virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src) = 0; // Set builtin parameters - virtual void setPixelProgramMatrix(uint index, TMatrix matrix, TTransform transform) = 0; - virtual void setPixelProgramFog(uint index) = 0; + virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform) = 0; + virtual void setUniformFog(TProgram program, uint index) = 0; // @} @@ -1183,12 +1178,12 @@ public: /** * Setup constant values. */ - inline void setConstant(uint index, float f0, float f1, float f2, float f3) { setVertexProgram4f(index, f0, f1, f2, f3); } - inline void setConstant(uint index, double d0, double d1, double d2, double d3) { setVertexProgram4f(index, (float)d0, (float)d1, (float)d2, (float)d3); } - inline void setConstant(uint index, const NLMISC::CVector &value) { setVertexProgram4f(index, value, 0.f); } - inline void setConstant(uint index, const NLMISC::CVectorD &value) { setVertexProgram4f(index, (float)value.x, (float)value.y, (float)value.z, 0.f); } + inline void setConstant(uint index, float f0, float f1, float f2, float f3) { setUniform4f(VertexProgram, index, f0, f1, f2, f3); } + inline void setConstant(uint index, double d0, double d1, double d2, double d3) { setUniform4f(VertexProgram, index, (float)d0, (float)d1, (float)d2, (float)d3); } + inline void setConstant(uint index, const NLMISC::CVector &value) { setUniform4f(VertexProgram, index, value, 0.f); } + inline void setConstant(uint index, const NLMISC::CVectorD &value) { setUniform4f(VertexProgram, index, (float)value.x, (float)value.y, (float)value.z, 0.f); } /// setup several 4 float csts taken from the given tab - inline void setConstant(uint index, uint num, const float *src) { setVertexProgram4fv(index, num, src); } + inline void setConstant(uint index, uint num, const float *src) { setUniform4fv(VertexProgram, index, num, src); } /** * Setup constants with a current matrix. @@ -1201,7 +1196,7 @@ public: * \param transform is the transformation to apply to the matrix before store it in the constants. * */ - inline void setConstantMatrix(uint index, TMatrix matrix, TTransform transform) { setVertexProgramMatrix(index, matrix, transform); }; + inline void setConstantMatrix(uint index, TMatrix matrix, TTransform transform) { setUniformMatrix(VertexProgram, index, matrix, transform); }; /** * Setup the constant with the fog vector. This vector must be used to get the final fog value in a vertex shader. @@ -1215,7 +1210,7 @@ public: * \param index is the index where to store the vector. * */ - inline void setConstantFog(uint index) { setVertexProgramFog(index); }; + inline void setConstantFog(uint index) { setUniformFog(VertexProgram, index); }; // @} diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index e02ccd50c..b89783cb9 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -584,11 +584,11 @@ bool CStereoOVR::endRenderTarget() float scaleInX = (2 / w); float scaleInY = (2 / h); - drvInternal->setPixelProgram2f(0, lensCenterX, lensCenterY); - drvInternal->setPixelProgram2f(1, screenCenterX, screenCenterY); - drvInternal->setPixelProgram2f(2, scaleX, scaleY); - drvInternal->setPixelProgram2f(3, scaleInX, scaleInY); - drvInternal->setPixelProgram4fv(4, 1, m_DevicePtr->HMDInfo.DistortionK); + drvInternal->setUniform2f(IDriver::PixelProgram, 0, lensCenterX, lensCenterY); + drvInternal->setUniform2f(IDriver::PixelProgram, 1, screenCenterX, screenCenterY); + drvInternal->setUniform2f(IDriver::PixelProgram, 2, scaleX, scaleY); + drvInternal->setUniform2f(IDriver::PixelProgram, 3, scaleInX, scaleInY); + drvInternal->setUniform4fv(IDriver::PixelProgram, 4, 1, m_DevicePtr->HMDInfo.DistortionK); m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat); @@ -596,8 +596,8 @@ bool CStereoOVR::endRenderTarget() lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f; screenCenterX = x + w * 0.5f; - drvInternal->setPixelProgram2f(0, lensCenterX, lensCenterY); - drvInternal->setPixelProgram2f(1, screenCenterX, screenCenterY); + drvInternal->setUniform2f(IDriver::PixelProgram, 0, lensCenterX, lensCenterY); + drvInternal->setUniform2f(IDriver::PixelProgram, 1, screenCenterX, screenCenterY); m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat); From ea25e5375d7d648e684cda50922c21d79270f13b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 12:18:20 +0200 Subject: [PATCH 103/137] Expand parameter interface --- code/nel/include/nel/3d/driver.h | 8 +- code/nel/include/nel/3d/gpu_program_params.h | 36 +- code/nel/src/3d/gpu_program_params.cpp | 334 ++++++++++++++++++- 3 files changed, 359 insertions(+), 19 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 0fe4c6511..ca6bc0601 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1132,7 +1132,7 @@ public: /** Return true if the driver supports the specified pixel program profile. */ - virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::nelvp) const = 0; + virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const = 0; /** Compile the given pixel program, return if successful. Error information is returned as a string. */ @@ -1162,10 +1162,16 @@ public: virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) = 0; virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) = 0; virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) = 0; + virtual void setUniform1ui(TProgram program, uint index, uint32 ui0) = 0; + virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1) = 0; + virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2) = 0; + virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) = 0; virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v) = 0; virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3) = 0; virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) = 0; virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src) = 0; + virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) = 0; + virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src) = 0; // Set builtin parameters virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform) = 0; virtual void setUniformFog(TProgram program, uint index) = 0; diff --git a/code/nel/include/nel/3d/gpu_program_params.h b/code/nel/include/nel/3d/gpu_program_params.h index 270c6cff5..ce6b8b2f0 100644 --- a/code/nel/include/nel/3d/gpu_program_params.h +++ b/code/nel/include/nel/3d/gpu_program_params.h @@ -60,7 +60,7 @@ class CGPUProgramParams { public: enum TType { Float, Int, UInt }; - struct CMeta { uint Index, Size, Count; TType Type; size_t Next, Prev; }; // size is element size, count is nb of elements + struct CMeta { uint Index, Size, Count; TType Type; std::string Name; size_t Next, Prev; }; // size is element size, count is nb of elements private: union CVec { float F[4]; sint32 I[4]; uint32 UI[4]; }; @@ -69,6 +69,8 @@ public: CGPUProgramParams(); virtual ~CGPUProgramParams(); + /// \name User functions + // @{ // Copy from another params storage void copy(CGPUProgramParams *params); @@ -81,10 +83,16 @@ public: void set2i(uint index, sint32 i0, sint32 i1); void set3i(uint index, sint32 i0, sint32 i1, sint32 i2); void set4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + void set1ui(uint index, uint32 ui0); + void set2ui(uint index, uint32 ui0, uint32 ui1); + void set3ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2); + void set4ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); void set3f(uint index, const NLMISC::CVector& v); void set4f(uint index, const NLMISC::CVector& v, float f3); void set4x4f(uint index, const NLMISC::CMatrix& m); void set4fv(uint index, size_t num, const float *src); + void set4iv(uint index, size_t num, const sint32 *src); + void set4uiv(uint index, size_t num, const uint32 *src); void unset(uint index); // Set by name, it is recommended to use index when repeatedly setting an element @@ -96,25 +104,42 @@ public: void set2i(const std::string &name, sint32 i0, sint32 i1); void set3i(const std::string &name, sint32 i0, sint32 i1, sint32 i2); void set4i(const std::string &name, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + void set1ui(const std::string &name, uint32 ui0); + void set2ui(const std::string &name, uint32 ui0, uint32 ui1); + void set3ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2); + void set4ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); void set3f(const std::string &name, const NLMISC::CVector& v); void set4f(const std::string &name, const NLMISC::CVector& v, float f3); void set4x4f(const std::string &name, const NLMISC::CMatrix& m); void set4fv(const std::string &name, size_t num, const float *src); + void set4iv(const std::string &name, size_t num, const sint32 *src); + void set4uiv(const std::string &name, size_t num, const uint32 *src); void unset(const std::string &name); + // @} - /// Maps the given name to the given index, on duplicate entry the data set by name will be prefered as it can be assumed to have been set after the data set by index + // Maps the given name to the given index. + // on duplicate entry the data set by name will be prefered, as it can be + // assumed to have been set after the data set by index, and the mapping + // will usually happen while iterating and finding an element with name + // but no known index. + // Unknown index will be set to ~0, unknown name will have an empty string. void map(uint index, const std::string &name); - // Internal - /// Allocate specified number of components if necessary + /// \name Internal + // @{ + /// Allocate specified number of components if necessary (internal use only) size_t allocOffset(uint index, uint size, uint count, TType type); size_t allocOffset(const std::string &name, uint size, uint count, TType type); + size_t allocOffset(uint size, uint count, TType type); /// Return offset for specified index size_t getOffset(uint index) const; size_t getOffset(const std::string &name) const; /// Remove by offset void freeOffset(size_t offset); + // @} + /// \name Driver and dev tools + // @{ // Iteration (returns the offsets for access using getFooByOffset) inline size_t getBegin() const { return m_Meta.size() ? m_First : s_End; } inline size_t getNext(size_t offset) const { return m_Meta[offset].Next; } @@ -129,7 +154,8 @@ public: inline uint32 *getPtrUIByOffset(size_t offset) { return m_Vec[offset].UI; } inline TType getTypeByOffset(size_t offset) const { return m_Meta[offset].Type; } inline uint getIndexByOffset(size_t offset) const { return m_Meta[offset].Index; } - const std::string *getNameByOffset(size_t offset) const; // non-optimized for dev tools only, may return NULL if name unknown + const std::string &getNameByOffset(size_t offset) const { return m_Meta[offset].Name; }; + // @} // Utility static inline uint getNbRegistersByComponents(uint nbComponents) { return (nbComponents + 3) >> 2; } // vector register per 4 components diff --git a/code/nel/src/3d/gpu_program_params.cpp b/code/nel/src/3d/gpu_program_params.cpp index bfcc4d32c..87ba01381 100644 --- a/code/nel/src/3d/gpu_program_params.cpp +++ b/code/nel/src/3d/gpu_program_params.cpp @@ -83,36 +83,66 @@ void CGPUProgramParams::set4f(uint index, float f0, float f1, float f2, float f3 f[3] = f3; } -void CGPUProgramParams::set1i(uint index, int i0) +void CGPUProgramParams::set1i(uint index, sint32 i0) { - int *i = getPtrIByOffset(allocOffset(index, 1, 1, Int)); + sint32 *i = getPtrIByOffset(allocOffset(index, 1, 1, Int)); i[0] = i0; } -void CGPUProgramParams::set2i(uint index, int i0, int i1) +void CGPUProgramParams::set2i(uint index, sint32 i0, sint32 i1) { - int *i = getPtrIByOffset(allocOffset(index, 2, 1, Int)); + sint32 *i = getPtrIByOffset(allocOffset(index, 2, 1, Int)); i[0] = i0; i[1] = i1; } -void CGPUProgramParams::set3i(uint index, int i0, int i1, int i2) +void CGPUProgramParams::set3i(uint index, sint32 i0, sint32 i1, sint32 i2) { - int *i = getPtrIByOffset(allocOffset(index, 3, 1, Int)); + sint32 *i = getPtrIByOffset(allocOffset(index, 3, 1, Int)); i[0] = i0; i[1] = i1; i[2] = i2; } -void CGPUProgramParams::set4i(uint index, int i0, int i1, int i2, int i3) +void CGPUProgramParams::set4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) { - int *i = getPtrIByOffset(allocOffset(index, 4, 1, Int)); + sint32 *i = getPtrIByOffset(allocOffset(index, 4, 1, Int)); i[0] = i0; i[1] = i1; i[2] = i2; i[3] = i3; } +void CGPUProgramParams::set1ui(uint index, uint32 ui0) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(index, 1, 1, UInt)); + ui[0] = ui0; +} + +void CGPUProgramParams::set2ui(uint index, uint32 ui0, uint32 ui1) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(index, 2, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; +} + +void CGPUProgramParams::set3ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(index, 3, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; + ui[2] = ui2; +} + +void CGPUProgramParams::set4ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(index, 4, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; + ui[2] = ui2; + ui[3] = ui3; +} + void CGPUProgramParams::set3f(uint index, const NLMISC::CVector& v) { float *f = getPtrFByOffset(allocOffset(index, 3, 1, Float)); @@ -121,6 +151,15 @@ void CGPUProgramParams::set3f(uint index, const NLMISC::CVector& v) f[2] = v.z; } +void CGPUProgramParams::set4f(uint index, const NLMISC::CVector& v, float f3) +{ + float *f = getPtrFByOffset(allocOffset(index, 4, 1, Float)); + f[0] = v.x; + f[1] = v.y; + f[2] = v.z; + f[3] = f3; +} + void CGPUProgramParams::set4x4f(uint index, const NLMISC::CMatrix& m) { // TODO: Verify this! @@ -138,6 +177,210 @@ void CGPUProgramParams::set4fv(uint index, size_t num, const float *src) f[c] = src[c]; } +void CGPUProgramParams::set4iv(uint index, size_t num, const sint32 *src) +{ + sint32 *i = getPtrIByOffset(allocOffset(index, 4, num, Int)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + i[c] = src[c]; +} + +void CGPUProgramParams::set4uiv(uint index, size_t num, const uint32 *src) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(index, 4, num, UInt)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + ui[c] = src[c]; +} + +void CGPUProgramParams::unset(uint index) +{ + size_t offset = getOffset(index); + if (offset != getEnd()) + { + freeOffset(offset); + } +} + +void CGPUProgramParams::set1f(const std::string &name, float f0) +{ + float *f = getPtrFByOffset(allocOffset(name, 1, 1, Float)); + f[0] = f0; +} + +void CGPUProgramParams::set2f(const std::string &name, float f0, float f1) +{ + float *f = getPtrFByOffset(allocOffset(name, 2, 1, Float)); + f[0] = f0; + f[1] = f1; +} + +void CGPUProgramParams::set3f(const std::string &name, float f0, float f1, float f2) +{ + float *f = getPtrFByOffset(allocOffset(name, 3, 1, Float)); + f[0] = f0; + f[1] = f1; + f[2] = f2; +} + +void CGPUProgramParams::set4f(const std::string &name, float f0, float f1, float f2, float f3) +{ + float *f = getPtrFByOffset(allocOffset(name, 4, 1, Float)); + f[0] = f0; + f[1] = f1; + f[2] = f2; + f[3] = f3; +} + +void CGPUProgramParams::set1i(const std::string &name, sint32 i0) +{ + sint32 *i = getPtrIByOffset(allocOffset(name, 1, 1, Int)); + i[0] = i0; +} + +void CGPUProgramParams::set2i(const std::string &name, sint32 i0, sint32 i1) +{ + sint32 *i = getPtrIByOffset(allocOffset(name, 2, 1, Int)); + i[0] = i0; + i[1] = i1; +} + +void CGPUProgramParams::set3i(const std::string &name, sint32 i0, sint32 i1, sint32 i2) +{ + sint32 *i = getPtrIByOffset(allocOffset(name, 3, 1, Int)); + i[0] = i0; + i[1] = i1; + i[2] = i2; +} + +void CGPUProgramParams::set4i(const std::string &name, sint32 i0, sint32 i1, sint32 i2, sint32 i3) +{ + sint32 *i = getPtrIByOffset(allocOffset(name, 4, 1, Int)); + i[0] = i0; + i[1] = i1; + i[2] = i2; + i[3] = i3; +} + +void CGPUProgramParams::set1ui(const std::string &name, uint32 ui0) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(name, 1, 1, UInt)); + ui[0] = ui0; +} + +void CGPUProgramParams::set2ui(const std::string &name, uint32 ui0, uint32 ui1) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(name, 2, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; +} + +void CGPUProgramParams::set3ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(name, 3, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; + ui[2] = ui2; +} + +void CGPUProgramParams::set4ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(name, 4, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; + ui[2] = ui2; + ui[3] = ui3; +} + +void CGPUProgramParams::set3f(const std::string &name, const NLMISC::CVector& v) +{ + float *f = getPtrFByOffset(allocOffset(name, 3, 1, Float)); + f[0] = v.x; + f[1] = v.y; + f[2] = v.z; +} + +void CGPUProgramParams::set4f(const std::string &name, const NLMISC::CVector& v, float f3) +{ + float *f = getPtrFByOffset(allocOffset(name, 4, 1, Float)); + f[0] = v.x; + f[1] = v.y; + f[2] = v.z; + f[3] = f3; +} + +void CGPUProgramParams::set4x4f(const std::string &name, const NLMISC::CMatrix& m) +{ + // TODO: Verify this! + float *f = getPtrFByOffset(allocOffset(name, 4, 4, Float)); + NLMISC::CMatrix mt = m; + mt.transpose(); + mt.get(f); +} + +void CGPUProgramParams::set4fv(const std::string &name, size_t num, const float *src) +{ + float *f = getPtrFByOffset(allocOffset(name, 4, num, Float)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + f[c] = src[c]; +} + +void CGPUProgramParams::set4iv(const std::string &name, size_t num, const sint32 *src) +{ + sint32 *i = getPtrIByOffset(allocOffset(name, 4, num, Int)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + i[c] = src[c]; +} + +void CGPUProgramParams::set4uiv(const std::string &name, size_t num, const uint32 *src) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(name, 4, num, UInt)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + ui[c] = src[c]; +} + +void CGPUProgramParams::unset(const std::string &name) +{ + size_t offset = getOffset(name); + if (offset != getEnd()) + { + freeOffset(offset); + } +} + +void CGPUProgramParams::map(uint index, const std::string &name) +{ + size_t offsetIndex = getOffset(index); + size_t offsetName = getOffset(name); + if (offsetName != getEnd()) + { + // Remove possible duplicate + if (offsetIndex != getEnd()) + { + freeOffset(offsetIndex); + } + + // Set index + m_Meta[offsetName].Index = index; + + // Map index to name + if (index >= m_Map.size()) + m_Map.resize(index + 1, s_End); + m_Map[index] = offsetName; + } + else if (offsetIndex != getEnd()) + { + // Set name + m_Meta[offsetIndex].Name = name; + + // Map name to index + m_MapName[name] = offsetIndex; + } +} + /// Allocate specified number of components if necessary size_t CGPUProgramParams::allocOffset(uint index, uint size, uint count, TType type) { @@ -163,18 +406,67 @@ size_t CGPUProgramParams::allocOffset(uint index, uint size, uint count, TType t } // Allocate space - offset = m_Meta.size(); - uint blocks = getNbRegistersByComponents(nbComponents); // per 4 components - m_Meta.resize(offset + blocks); - m_Vec.resize(offset + blocks); + offset = allocOffset(size, count, type); + + // Fill + m_Meta[offset].Index = index; // Store offset in map if (index >= m_Map.size()) m_Map.resize(index + 1, s_End); m_Map[index] = offset; + return offset; +} + +/// Allocate specified number of components if necessary +size_t CGPUProgramParams::allocOffset(const std::string &name, uint size, uint count, TType type) +{ + nlassert(count > 0); // this code will not properly handle 0 + nlassert(size > 0); // this code will not properly handle 0 + nlassert(!name.empty()); // sanity check + + uint nbComponents = size * count; + size_t offset = getOffset(name); + if (offset != s_End) + { + if (getCountByOffset(offset) >= nbComponents) + { + m_Meta[offset].Type = type; + m_Meta[offset].Size = size; + m_Meta[offset].Count = count; + return offset; + } + if (getCountByOffset(offset) < nbComponents) + { + freeOffset(offset); + } + } + + // Allocate space + offset = allocOffset(size, count, type); + + // Fill + m_Meta[offset].Name = name; + + // Store offset in map + m_MapName[name] = offset; + + return offset; +} + +/// Allocate specified number of components if necessary +size_t CGPUProgramParams::allocOffset(uint size, uint count, TType type) +{ + uint nbComponents = size * count; + + // Allocate space + size_t offset = m_Meta.size(); + uint blocks = getNbRegistersByComponents(nbComponents); // per 4 components + m_Meta.resize(offset + blocks); + m_Vec.resize(offset + blocks); + // Fill - m_Meta[offset].Index = index; m_Meta[offset].Size = size; m_Meta[offset].Count = count; m_Meta[offset].Type = type; @@ -207,6 +499,22 @@ size_t CGPUProgramParams::getOffset(uint index) const /// Remove by offset void CGPUProgramParams::freeOffset(size_t offset) { + uint index = getIndexByOffset(offset); + if (index != ~0) + { + if (m_Map.size() > index) + { + m_Map[index] = getEnd(); + } + } + const std::string &name = getNameByOffset(offset); + if (!name.empty()) + { + if (m_MapName.find(name) != m_MapName.end()) + { + m_MapName.erase(name); + } + } if (offset == m_Last) { nlassert(m_Meta[offset].Next == s_End); From 99a48d5511bd7e2936da6159b199c5387ca2b06b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 14:43:10 +0200 Subject: [PATCH 104/137] Implement new driver interface in OpenGL driver --- code/nel/include/nel/3d/driver.h | 26 +- code/nel/src/3d/driver/opengl/driver_opengl.h | 124 ++- .../opengl/driver_opengl_pixel_program.cpp | 217 +---- .../driver/opengl/driver_opengl_uniform.cpp | 298 ++++++ .../opengl/driver_opengl_vertex_program.cpp | 886 +++++++----------- 5 files changed, 793 insertions(+), 758 deletions(-) create mode 100644 code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index ca6bc0601..8890a9cc7 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -161,9 +161,9 @@ public: enum TProgram { - VertexProgram, - PixelProgram, - GeometryProgram + VertexProgram = 0, + PixelProgram = 1, + GeometryProgram = 2 }; protected: @@ -1105,19 +1105,17 @@ public: */ virtual bool supportVertexProgram(CVertexProgram::TProfile profile = CVertexProgram::nelvp) const = 0; - /** Compile the given vertex program, return if successful. Error information is returned as a string. + /** Compile the given vertex program, return if successful. + * If a vertex program was set active before compilation, + * the state of the active vertex program is undefined behaviour afterwards. */ - virtual bool compileVertexProgram(CVertexProgram *program, std::string &error) const = 0; + virtual bool compileVertexProgram(CVertexProgram *program) = 0; /** Set the active vertex program. This will override vertex programs specified in CMaterial render calls. * Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL. * The vertex program is activated immediately. */ virtual bool activeVertexProgram(CVertexProgram *program) = 0; - - /** Get the currently active vertex program. - */ - virtual CVertexProgram *getActiveVertexProgram() const = 0; // @} @@ -1134,19 +1132,17 @@ public: */ virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const = 0; - /** Compile the given pixel program, return if successful. Error information is returned as a string. + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. */ - virtual bool compilePixelProgram(CPixelProgram *program, std::string &error) const = 0; + virtual bool compilePixelProgram(CPixelProgram *program) = 0; /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. * Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL. * The pixel program is activated immediately. */ virtual bool activePixelProgram(CPixelProgram *program) = 0; - - /** Get the currently active pixel program. - */ - virtual CPixelProgram *getActivePixelProgram() const = 0; // @} diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 89b71c931..f70a0627f 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1299,45 +1299,115 @@ private: // @} - /// \name Vertex program interface + + + + + /// \name Vertex Program // @{ - bool supportVertexProgram () const; - bool supportPixelProgram () const; - bool supportPixelProgram (CPixelProgram::TProfile profile) const; - bool isVertexProgramEmulated () const; - bool activeVertexProgram (CVertexProgram *program); - bool activePixelProgram (CPixelProgram *program); - void setConstant (uint index, float, float, float, float); - void setConstant (uint index, double, double, double, double); - void setConstant (uint indexStart, const NLMISC::CVector& value); - void setConstant (uint indexStart, const NLMISC::CVectorD& value); - void setConstant (uint index, uint num, const float *src); - void setConstant (uint index, uint num, const double *src); - void setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform); - void setConstantFog (uint index); - void enableVertexProgramDoubleSidedColor(bool doubleSided); - bool supportVertexProgramDoubleSidedColor() const; - - // Pixel program - virtual void setPixelProgramConstant (uint index, float, float, float, float); - virtual void setPixelProgramConstant (uint index, double, double, double, double); - virtual void setPixelProgramConstant (uint index, const NLMISC::CVector& value); - virtual void setPixelProgramConstant (uint index, const NLMISC::CVectorD& value); - virtual void setPixelProgramConstant (uint index, uint num, const float *src); - virtual void setPixelProgramConstant (uint index, uint num, const double *src); - virtual void setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform); + // Order of preference + // - activeVertexProgram + // - CMaterial pass[n] VP (uses activeVertexProgram, but does not override if one already set by code) + // - default generic VP that mimics fixed pipeline / no VP with fixed pipeline + + /** + * Does the driver supports vertex program, but emulated by CPU ? + */ + virtual bool isVertexProgramEmulated() const; + + /** Return true if the driver supports the specified vertex program profile. + */ + virtual bool supportVertexProgram(CVertexProgram::TProfile profile = CVertexProgram::nelvp) const; + + /** Compile the given vertex program, return if successful. + * If a vertex program was set active before compilation, + * the state of the active vertex program is undefined behaviour afterwards. + */ + virtual bool compileVertexProgram(CVertexProgram *program); + + /** Set the active vertex program. This will override vertex programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL. + * The vertex program is activated immediately. + */ + virtual bool activeVertexProgram(CVertexProgram *program); + // @} + + + + /// \name Pixel Program + // @{ + + // Order of preference + // - activePixelProgram + // - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code) + // - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code) + + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::arbfp1) const; + + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compilePixelProgram(CPixelProgram *program); + + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activePixelProgram(CPixelProgram *program); + // @} + + + + /// \name Program parameters + // @{ + // Set parameters + virtual void setUniform1f(TProgram program, uint index, float f0); + virtual void setUniform2f(TProgram program, uint index, float f0, float f1); + virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2); + virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3); + virtual void setUniform1i(TProgram program, uint index, sint32 i0); + virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1); + virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2); + virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + virtual void setUniform1ui(TProgram program, uint index, uint32 ui0); + virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1); + virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2); + virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); + virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v); + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3); + virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m); + virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src); + virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src); + virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src); + // Set builtin parameters + virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform); + virtual void setUniformFog(TProgram program, uint index); + // @} + + + + + + virtual void enableVertexProgramDoubleSidedColor(bool doubleSided); + virtual bool supportVertexProgramDoubleSidedColor() const; virtual bool supportMADOperator() const ; - // @} /// \name Vertex program implementation // @{ bool activeNVVertexProgram (CVertexProgram *program); bool activeARBVertexProgram (CVertexProgram *program); bool activeEXTVertexShader (CVertexProgram *program); + + bool compileNVVertexProgram (CVertexProgram *program); + bool compileARBVertexProgram (CVertexProgram *program); + bool compileEXTVertexShader (CVertexProgram *program); //@} diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index b2867a95a..31e6ed482 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -50,6 +50,7 @@ namespace NLDRIVERGL { #endif // *************************************************************************** + CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it) { H_AUTO_OGL(CPixelProgamDrvInfosGL_CPixelProgamDrvInfosGL) @@ -63,11 +64,7 @@ CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoP } // *************************************************************************** -bool CDriverGL::supportPixelProgram() const -{ - H_AUTO_OGL(CPixelProgamDrvInfosGL_supportPixelProgram) - return _Extensions.ARBFragmentProgram; -} + bool CDriverGL::supportPixelProgram(CPixelProgram::TProfile profile) const { H_AUTO_OGL(CPixelProgamDrvInfosGL_supportPixelProgram_profile) @@ -82,6 +79,7 @@ bool CDriverGL::supportPixelProgram(CPixelProgram::TProfile profile) const } // *************************************************************************** + bool CDriverGL::activePixelProgram(CPixelProgram *program) { H_AUTO_OGL(CDriverGL_activePixelProgram) @@ -95,59 +93,68 @@ bool CDriverGL::activePixelProgram(CPixelProgram *program) } // *************************************************************************** + +bool CDriverGL::compilePixelProgram(NL3D::CPixelProgram *program) +{ + // Program setuped ? + if (program->_DrvInfo == NULL) + { + glDisable(GL_FRAGMENT_PROGRAM_ARB); + _PixelProgramEnabled = false; + + // Insert into driver list. (so it is deleted when driver is deleted). + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); + + // Create a driver info + CPixelProgamDrvInfosGL *drvInfo; + *it = drvInfo = new CPixelProgamDrvInfosGL(this, it); + // Set the pointer + program->_DrvInfo = drvInfo; + + if (!setupPixelProgram(program, drvInfo->ID)) + { + delete drvInfo; + program->_DrvInfo = NULL; + _GPUPrgDrvInfos.erase(it); + return false; + } + } + + return true; +} + +// *************************************************************************** + bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) { H_AUTO_OGL(CDriverGL_activeARBPixelProgram) // Setup or unsetup ? if (program) - { - // Driver info - CPixelProgamDrvInfosGL *drvInfo; - + { // Program setuped ? - if (program->_DrvInfo==NULL) - { - // Insert into driver list. (so it is deleted when driver is deleted). - ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); + if (!CDriverGL::compilePixelProgram(program)) return false; - // Create a driver info - *it = drvInfo = new CPixelProgamDrvInfosGL(this, it); - // Set the pointer - program->_DrvInfo = drvInfo; - - if (!setupPixelProgram(program, drvInfo->ID)) - { - delete drvInfo; - program->_DrvInfo = NULL; - _GPUPrgDrvInfos.erase(it); - return false; - } - } - else - { - // Cast the driver info pointer - drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); - } - glEnable( GL_FRAGMENT_PROGRAM_ARB ); + // Cast the driver info pointer + CPixelProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + + glEnable(GL_FRAGMENT_PROGRAM_ARB); _PixelProgramEnabled = true; - nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, drvInfo->ID ); - - glDisable( GL_COLOR_SUM_ARB ); // no specular written + nglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drvInfo->ID); _LastSetuppedPP = program; } else { - glDisable( GL_FRAGMENT_PROGRAM_ARB ); - glDisable( GL_COLOR_SUM_ARB ); - _PixelProgramEnabled = false; + glDisable(GL_FRAGMENT_PROGRAM_ARB); + _PixelProgramEnabled = false; } return true; } // *************************************************************************** + bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &specularWritten*/) { H_AUTO_OGL(CDriverGL_setupARBPixelProgram) @@ -170,9 +177,9 @@ bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &spe } // Compile the program - nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, id); + nglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, id); glGetError(); - nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, source->SourceLen, source->SourcePtr); + nglProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, source->SourceLen, source->SourcePtr); GLenum err = glGetError(); if (err != GL_NO_ERROR) { @@ -222,136 +229,6 @@ bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &spe return true; } -// *************************************************************************** - -void CDriverGL::setPixelProgramConstant (uint index, float f0, float f1, float f2, float f3) -{ - H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - - if (_Extensions.ARBFragmentProgram) - nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3); -} - - -// *************************************************************************** - -void CDriverGL::setPixelProgramConstant (uint index, double d0, double d1, double d2, double d3) -{ - H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - - if (_Extensions.ARBFragmentProgram) - nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, d0, d1, d2, d3); -} - - -// *************************************************************************** - -void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVector& value) -{ - H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - - if (_Extensions.ARBFragmentProgram) - nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0); -} - - -// *************************************************************************** - -void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVectorD& value) -{ - H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - - if (_Extensions.ARBFragmentProgram) - nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0); -} - - -// *************************************************************************** -void CDriverGL::setPixelProgramConstant (uint index, uint num, const float *src) -{ - H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - - if (_Extensions.ARBFragmentProgram) - { - for(uint k = 0; k < num; ++k) - { - nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k); - } - } -} - -// *************************************************************************** -void CDriverGL::setPixelProgramConstant (uint index, uint num, const double *src) -{ - H_AUTO_OGL(CDriverGL_setPixelProgramConstant) - - if (_Extensions.ARBFragmentProgram) - { - for(uint k = 0; k < num; ++k) - { - nglProgramEnvParameter4dvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k); - } - } -} - -// *************************************************************************** - -void CDriverGL::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform) -{ - H_AUTO_OGL(CDriverGL_setPixelProgramConstantMatrix) - - if (_Extensions.ARBFragmentProgram) - { - - // First, ensure that the render setup is correctly setuped. - refreshRenderSetup(); - CMatrix mat; - switch (matrix) - { - case IDriver::ModelView: - mat = _ModelViewMatrix; - break; - case IDriver::Projection: - { - refreshProjMatrixFromGL(); - mat = _GLProjMat; - } - break; - case IDriver::ModelViewProjection: - refreshProjMatrixFromGL(); - mat = _GLProjMat * _ModelViewMatrix; - break; - default: - break; - } - - switch(transform) - { - case IDriver::Identity: break; - case IDriver::Inverse: - mat.invert(); - break; - case IDriver::Transpose: - mat.transpose(); - break; - case IDriver::InverseTranspose: - mat.invert(); - mat.transpose(); - break; - default: - break; - } - mat.transpose(); - float matDatas[16]; - mat.get(matDatas); - - nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index, matDatas); - nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 1, matDatas + 4); - nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 2, matDatas + 8); - nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 3, matDatas + 12); - } -} - #ifdef NL_STATIC } // NLDRIVERGL/ES #endif diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp new file mode 100644 index 000000000..6b429e706 --- /dev/null +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -0,0 +1,298 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stdopengl.h" + +#include "driver_opengl.h" + +using namespace std; +using namespace NLMISC; + +namespace NL3D { + +#ifdef NL_STATIC +#ifdef USE_OPENGLES +namespace NLDRIVERGLES { +#else +namespace NLDRIVERGL { +#endif +#endif + +inline void CDriverGL::setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3) +{ + H_AUTO_OGL(CDriverGL_setUniform4f); + +#ifndef USE_OPENGLES + switch (program) + { + case VertexProgram: + if (_Extensions.NVVertexProgram) + { + // Setup constant + nglProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, index, f0, f1, f2, f3); + } + else if (_Extensions.ARBVertexProgram) + { + nglProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, f0, f1, f2, f3); + } + else if (_Extensions.EXTVertexShader) + { + float datas[] = { f0, f1, f2, f3 }; + nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas); + } + break; + case PixelProgram: + if (_Extensions.ARBFragmentProgram) + { + nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3); + } + break; + } +#endif +} + +inline void CDriverGL::setUniform4fv(TProgram program, uint index, size_t num, const float *src) +{ + H_AUTO_OGL(CDriverGL_setUniform4fv); + +#ifndef USE_OPENGLES + switch (program) + { + case VertexProgram: + if (_Extensions.NVVertexProgram) + { + nglProgramParameters4fvNV(GL_VERTEX_PROGRAM_NV, index, num, src); + } + else if (_Extensions.ARBVertexProgram) // ARB pixel and geometry program will only exist when ARB vertex program exists + { + for (uint k = 0; k < num; ++k) + { + nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + k, src + 4 * k); + } + } + else if (_Extensions.EXTVertexShader) + { + for (uint k = 0; k < num; ++k) + { + nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_FLOAT, (void *)(src + 4 * k)); + } + } + break; + case PixelProgram: + if (_Extensions.ARBFragmentProgram) // ARB pixel and geometry program will only exist when ARB vertex program exists + { + for (uint k = 0; k < num; ++k) + { + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k); + } + } + break; + } +#endif +} + +void CDriverGL::setUniform1f(TProgram program, uint index, float f0) +{ + CDriverGL::setUniform4f(program, index, f0, 0.f, 0.f, 0.f); +} + +void CDriverGL::setUniform2f(TProgram program, uint index, float f0, float f1) +{ + CDriverGL::setUniform4f(program, index, f0, f1, 0.f, 0.f); +} + +void CDriverGL::setUniform3f(TProgram program, uint index, float f0, float f1, float f2) +{ + CDriverGL::setUniform4f(program, index, f0, f1, f2, 0.0f); +} + +void CDriverGL::setUniform1i(TProgram program, uint index, sint32 i0) +{ + +} + +void CDriverGL::setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) +{ + +} + +void CDriverGL::setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) +{ + +} + +void CDriverGL::setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) +{ + +} + +void CDriverGL::setUniform1ui(TProgram program, uint index, uint32 ui0) +{ + +} + +void CDriverGL::setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1) +{ + +} + +void CDriverGL::setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2) +{ + +} + +void CDriverGL::setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) +{ + +} + +void CDriverGL::setUniform3f(TProgram program, uint index, const NLMISC::CVector& v) +{ + CDriverGL::setUniform4f(program, index, v.x, v.y, v.z, 0.f); +} + +void CDriverGL::setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3) +{ + CDriverGL::setUniform4f(program, index, v.x, v.y, v.z, f3); +} + +void CDriverGL::setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) +{ + H_AUTO_OGL(CDriverGL_setUniform4x4f); + + // TODO: Verify this! + NLMISC::CMatrix mat = m; + mat.transpose(); + const float *md = mat.get(); + + CDriverGL::setUniform4fv(program, index, 4, md); +} + +void CDriverGL::setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) +{ + +} + +void CDriverGL::setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src) +{ + +} + +const uint CDriverGL::GLMatrix[IDriver::NumMatrix]= +{ + GL_MODELVIEW, + GL_PROJECTION, +#ifdef USE_OPENGLES + GL_MODELVIEW +#else + GL_MODELVIEW_PROJECTION_NV +#endif +}; + +const uint CDriverGL::GLTransform[IDriver::NumTransform]= +{ +#ifdef USE_OPENGLES + 0, + 0, + 0, + 0 +#else + GL_IDENTITY_NV, + GL_INVERSE_NV, + GL_TRANSPOSE_NV, + GL_INVERSE_TRANSPOSE_NV +#endif +}; + +void CDriverGL::setUniformMatrix(NL3D::IDriver::TProgram program, uint index, NL3D::IDriver::TMatrix matrix, NL3D::IDriver::TTransform transform) +{ + H_AUTO_OGL(CDriverGL_setUniformMatrix); + +#ifndef USE_OPENGLES + // Vertex program exist ? + if (program == VertexProgram && _Extensions.NVVertexProgram) + { + // First, ensure that the render setup is correclty setuped. + refreshRenderSetup(); + + // Track the matrix + nglTrackMatrixNV(GL_VERTEX_PROGRAM_NV, index, GLMatrix[matrix], GLTransform[transform]); + // Release Track => matrix data is copied. + nglTrackMatrixNV(GL_VERTEX_PROGRAM_NV, index, GL_NONE, GL_IDENTITY_NV); + } + else + { + // First, ensure that the render setup is correctly setuped. + refreshRenderSetup(); + + CMatrix mat; + switch (matrix) + { + case IDriver::ModelView: + mat = _ModelViewMatrix; + break; + case IDriver::Projection: + { + refreshProjMatrixFromGL(); + mat = _GLProjMat; + } + break; + case IDriver::ModelViewProjection: + refreshProjMatrixFromGL(); + mat = _GLProjMat * _ModelViewMatrix; + break; + default: + break; + } + + switch(transform) + { + case IDriver::Identity: break; + case IDriver::Inverse: + mat.invert(); + break; + case IDriver::Transpose: + mat.transpose(); + break; + case IDriver::InverseTranspose: + mat.invert(); + mat.transpose(); + break; + default: + break; + } + + mat.transpose(); + const float *md = mat.get(); + + CDriverGL::setUniform4fv(program, index, 4, md); + } +#endif +} + +void CDriverGL::setUniformFog(NL3D::IDriver::TProgram program, uint index) +{ + H_AUTO_OGL(CDriverGL_setUniformFog) + + const float *values = _ModelViewMatrix.get(); + CDriverGL::setUniform4f(program, index, -values[2], -values[6], -values[10], -values[14]); +} + +#ifdef NL_STATIC +} // NLDRIVERGL/ES +#endif + +} // NL3D diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp index 34ae2365a..e0b07af2a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp @@ -70,23 +70,136 @@ CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL(CDriverGL *drv, ItGPUPrgDrvInfo // *************************************************************************** -bool CDriverGL::supportVertexProgram () const +bool CDriverGL::supportVertexProgram(CVertexProgram::TProfile profile) const { H_AUTO_OGL(CVertexProgamDrvInfosGL_supportVertexProgram) - return _Extensions.NVVertexProgram || _Extensions.EXTVertexShader || _Extensions.ARBVertexProgram; + return (profile == CVertexProgram::nelvp) + && (_Extensions.NVVertexProgram || _Extensions.EXTVertexShader || _Extensions.ARBVertexProgram); } // *************************************************************************** -bool CDriverGL::isVertexProgramEmulated () const +bool CDriverGL::isVertexProgramEmulated() const { H_AUTO_OGL(CVertexProgamDrvInfosGL_isVertexProgramEmulated) return _Extensions.NVVertexProgramEmulated; } +bool CDriverGL::compileNVVertexProgram(CVertexProgram *program) +{ + H_AUTO_OGL(CDriverGL_compileNVVertexProgram); +#ifndef USE_OPENGLES + + // Driver info + CVertexProgamDrvInfosGL *drvInfo; + + nlassert(!program->_DrvInfo); + glDisable(GL_VERTEX_PROGRAM_NV); + _VertexProgramEnabled = false; + + // Find nelvp + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; + } + + /** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..). + * There are some incompatibilities. + */ + CVPParser parser; + CVPParser::TProgram parsedProgram; + std::string errorOutput; + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); + if (!result) + { + nlwarning("Unable to parse a vertex program :"); + nlwarning(errorOutput.c_str()); + #ifdef NL_DEBUG + nlassert(0); + #endif + return false; + } + + // Insert into driver list. (so it is deleted when driver is deleted). + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); + + // Create a driver info + *it = drvInfo = new CVertexProgamDrvInfosGL(this, it); + + // Set the pointer + program->_DrvInfo = drvInfo; + + // Compile the program + nglLoadProgramNV(GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr); + + // Get loading error code + GLint errorOff; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV, &errorOff); + + // Compilation error ? + if (errorOff >= 0) + { + // String length + uint length = (uint)source->SourceLen; + const char* sString = source->SourcePtr; + + // Line count and char count + uint line=1; + uint charC=1; + + // Find the line + uint offset=0; + while ((offset < length) && (offset < (uint)errorOff)) + { + if (sString[offset]=='\n') + { + line++; + charC=1; + } + else + charC++; + + // Next character + offset++; + } + + // Show the error + nlwarning("3D: Vertex program syntax error line %d character %d\n", line, charC); + + // Setup not ok + delete drvInfo; + program->_DrvInfo = NULL; + _GPUPrgDrvInfos.erase(it); + return false; + } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); + + // Setup ok + return true; + +#else + + return false; + +#endif +} // *************************************************************************** -bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) +bool CDriverGL::activeNVVertexProgram(CVertexProgram *program) { H_AUTO_OGL(CVertexProgamDrvInfosGL_activeNVVertexProgram); @@ -94,120 +207,16 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) // Setup or unsetup ? if (program) { - // Enable vertex program - glEnable (GL_VERTEX_PROGRAM_NV); - _VertexProgramEnabled= true; - - // Driver info - CVertexProgamDrvInfosGL *drvInfo; + CVertexProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + nlassert(drvInfo); - // Program setuped ? - if (program->_DrvInfo==NULL) - { - // Find nelvp - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) - { - if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) - { - source = program->getProgramSource()->Sources[i]; - } - } - if (!source) - { - nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); - return false; - } - - /** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..). - * There are some incompatibilities. - */ - CVPParser parser; - CVPParser::TProgram parsedProgram; - std::string errorOutput; - bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); - if (!result) - { - nlwarning("Unable to parse a vertex program :"); - nlwarning(errorOutput.c_str()); - #ifdef NL_DEBUG - nlassert(0); - #endif - return false; - } - - // Insert into driver list. (so it is deleted when driver is deleted). - ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); - - // Create a driver info - *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); - - // Set the pointer - program->_DrvInfo=drvInfo; - - // Compile the program - nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr); - - // Get loading error code - GLint errorOff; - glGetIntegerv (GL_PROGRAM_ERROR_POSITION_NV, &errorOff); - - // Compilation error ? - if (errorOff>=0) - { - // String length - uint length = (uint)source->SourceLen; - const char* sString = source->SourcePtr; - - // Line count and char count - uint line=1; - uint charC=1; - - // Find the line - uint offset=0; - while ((offsetParamIndices = source->ParamIndices; - - // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); - - // Setup ok - return true; - } - else - { - // Cast the driver info pointer - drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); - } + // Enable vertex program + glEnable(GL_VERTEX_PROGRAM_NV); + _VertexProgramEnabled = true; // Setup this program - nglBindProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID); + nglBindProgramNV(GL_VERTEX_PROGRAM_NV, drvInfo->ID); _LastSetuppedVP = program; // Ok @@ -216,8 +225,8 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) else // Unsetup { // Disable vertex program - glDisable (GL_VERTEX_PROGRAM_NV); - _VertexProgramEnabled= false; + glDisable(GL_VERTEX_PROGRAM_NV); + _VertexProgramEnabled = false; // Ok return true; } @@ -1507,207 +1516,273 @@ bool CDriverGL::setupARBVertexProgram (const CVPParser::TProgram &inParsedProgra #endif } +// *************************************************************************** +bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program) +{ + H_AUTO_OGL(CDriverGL_compileARBVertexProgram); + +#ifndef USE_OPENGLES + + nlassert(!program->_DrvInfo); + glDisable(GL_VERTEX_PROGRAM_ARB); + _VertexProgramEnabled = false; + + // Find nelvp + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; + } + + // try to parse the program + CVPParser parser; + CVPParser::TProgram parsedProgram; + std::string errorOutput; + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); + if (!result) + { + nlwarning("Unable to parse a vertex program."); + #ifdef NL_DEBUG + nlerror(errorOutput.c_str()); + #endif + return false; + } + // Insert into driver list. (so it is deleted when driver is deleted). + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); + + // Create a driver info + CVertexProgamDrvInfosGL *drvInfo; + *it = drvInfo = new CVertexProgamDrvInfosGL(this, it); + // Set the pointer + program->_DrvInfo=drvInfo; + + if (!setupARBVertexProgram(parsedProgram, drvInfo->ID, drvInfo->SpecularWritten)) + { + delete drvInfo; + program->_DrvInfo = NULL; + _GPUPrgDrvInfos.erase(it); + return false; + } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); + + return true; + +#else + + return false; + +#endif +} // *************************************************************************** -bool CDriverGL::activeARBVertexProgram (CVertexProgram *program) + +bool CDriverGL::activeARBVertexProgram(CVertexProgram *program) { H_AUTO_OGL(CDriverGL_activeARBVertexProgram); #ifndef USE_OPENGLES + // Setup or unsetup ? if (program) { // Driver info - CVertexProgamDrvInfosGL *drvInfo; + CVertexProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + nlassert(drvInfo); - // Program setuped ? - if (program->_DrvInfo==NULL) - { - // Find nelvp - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) - { - if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) - { - source = program->getProgramSource()->Sources[i]; - } - } - if (!source) - { - nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); - return false; - } - - // try to parse the program - CVPParser parser; - CVPParser::TProgram parsedProgram; - std::string errorOutput; - bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); - if (!result) - { - nlwarning("Unable to parse a vertex program."); - #ifdef NL_DEBUG - nlerror(errorOutput.c_str()); - #endif - return false; - } - // Insert into driver list. (so it is deleted when driver is deleted). - ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); - - // Create a driver info - *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); - // Set the pointer - program->_DrvInfo=drvInfo; - - if (!setupARBVertexProgram(parsedProgram, drvInfo->ID, drvInfo->SpecularWritten)) - { - delete drvInfo; - program->_DrvInfo = NULL; - _GPUPrgDrvInfos.erase(it); - return false; - } - - // Set parameters for assembly programs - drvInfo->ParamIndices = source->ParamIndices; - - // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); - } - else - { - // Cast the driver info pointer - drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); - } glEnable( GL_VERTEX_PROGRAM_ARB ); _VertexProgramEnabled = true; - nglBindProgramARB( GL_VERTEX_PROGRAM_ARB, drvInfo->ID ); + nglBindProgramARB(GL_VERTEX_PROGRAM_ARB, drvInfo->ID); if (drvInfo->SpecularWritten) { - glEnable( GL_COLOR_SUM_ARB ); + glEnable(GL_COLOR_SUM_ARB); } else { - glDisable( GL_COLOR_SUM_ARB ); // no specular written + glDisable(GL_COLOR_SUM_ARB); // no specular written } _LastSetuppedVP = program; } else { - glDisable( GL_VERTEX_PROGRAM_ARB ); - glDisable( GL_COLOR_SUM_ARB ); + glDisable(GL_VERTEX_PROGRAM_ARB); + glDisable(GL_COLOR_SUM_ARB); _VertexProgramEnabled = false; } return true; + #else + return false; + #endif } // *************************************************************************** -bool CDriverGL::activeEXTVertexShader (CVertexProgram *program) + +bool CDriverGL::compileEXTVertexShader(CVertexProgram *program) { H_AUTO_OGL(CDriverGL_activeEXTVertexShader); #ifndef USE_OPENGLES - // Setup or unsetup ? - if (program) + + nlassert(program->_DrvInfo); + glDisable(GL_VERTEX_SHADER_EXT); + _VertexProgramEnabled = false; + + // Find nelvp + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) { - // Driver info - CVertexProgamDrvInfosGL *drvInfo; - - // Program setuped ? - if (program->_DrvInfo==NULL) + if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) { - // Find nelvp - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) - { - if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) - { - source = program->getProgramSource()->Sources[i]; - } - } - if (!source) - { - nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); - return false; - } - - // try to parse the program - CVPParser parser; - CVPParser::TProgram parsedProgram; - std::string errorOutput; - bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); - if (!result) - { - nlwarning("Unable to parse a vertex program."); - #ifdef NL_DEBUG - nlerror(errorOutput.c_str()); - #endif - return false; - } - - /* - FILE *f = fopen(getLogDirectory() + "test.txt", "wb"); - if (f) - { - std::string vpText; - CVPParser::dump(parsedProgram, vpText); - fwrite(vpText.c_str(), vpText.size(), 1, f); - fclose(f); - } - */ - - // Insert into driver list. (so it is deleted when driver is deleted). - ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); - - // Create a driver info - *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); - // Set the pointer - program->_DrvInfo=drvInfo; - - if (!setupEXTVertexShader(parsedProgram, drvInfo->ID, drvInfo->Variants, drvInfo->UsedVertexComponents)) - { - delete drvInfo; - program->_DrvInfo = NULL; - _GPUPrgDrvInfos.erase(it); - return false; - } - - // Set parameters for assembly programs - drvInfo->ParamIndices = source->ParamIndices; - - // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); + source = program->getProgramSource()->Sources[i]; } - else - { - // Cast the driver info pointer - drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); - } - - glEnable( GL_VERTEX_SHADER_EXT); - _VertexProgramEnabled = true; - nglBindVertexShaderEXT( drvInfo->ID ); - _LastSetuppedVP = program; } - else + if (!source) { - glDisable( GL_VERTEX_SHADER_EXT ); - _VertexProgramEnabled = false; + nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; } + + // try to parse the program + CVPParser parser; + CVPParser::TProgram parsedProgram; + std::string errorOutput; + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); + if (!result) + { + nlwarning("Unable to parse a vertex program."); + #ifdef NL_DEBUG + nlerror(errorOutput.c_str()); + #endif + return false; + } + + /* + FILE *f = fopen(getLogDirectory() + "test.txt", "wb"); + if (f) + { + std::string vpText; + CVPParser::dump(parsedProgram, vpText); + fwrite(vpText.c_str(), vpText.size(), 1, f); + fclose(f); + } + */ + + // Insert into driver list. (so it is deleted when driver is deleted). + ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); + + // Create a driver info + CVertexProgamDrvInfosGL *drvInfo; + *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); + // Set the pointer + program->_DrvInfo=drvInfo; + + if (!setupEXTVertexShader(parsedProgram, drvInfo->ID, drvInfo->Variants, drvInfo->UsedVertexComponents)) + { + delete drvInfo; + program->_DrvInfo = NULL; + _GPUPrgDrvInfos.erase(it); + return false; + } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); + return true; + #else + return false; + #endif } // *************************************************************************** -bool CDriverGL::activeVertexProgram (CVertexProgram *program) + +bool CDriverGL::activeEXTVertexShader(CVertexProgram *program) +{ + H_AUTO_OGL(CDriverGL_activeEXTVertexShader); + +#ifndef USE_OPENGLES + + // Setup or unsetup ? + if (program) + { + // Driver info + CVertexProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + nlassert(drvInfo); + + glEnable(GL_VERTEX_SHADER_EXT); + _VertexProgramEnabled = true; + nglBindVertexShaderEXT(drvInfo->ID); + _LastSetuppedVP = program; + } + else + { + glDisable(GL_VERTEX_SHADER_EXT); + _VertexProgramEnabled = false; + } + return true; + +#else + + return false; + +#endif +} + +bool CDriverGL::compileVertexProgram(NL3D::CVertexProgram *program) +{ + if (program->_DrvInfo == NULL) + { + // Extension + if (_Extensions.NVVertexProgram) + { + return compileNVVertexProgram(program); + } + else if (_Extensions.ARBVertexProgram) + { + return compileARBVertexProgram(program); + } + else if (_Extensions.EXTVertexShader) + { + return compileEXTVertexShader(program); + } + + // Can't do anything + return false; + } + return true; +} + +// *************************************************************************** + +bool CDriverGL::activeVertexProgram(CVertexProgram *program) { H_AUTO_OGL(CDriverGL_activeVertexProgram) - // Extension here ? + + // Compile if necessary + if (program && !CDriverGL::compileVertexProgram(program)) return false; + + // Extension if (_Extensions.NVVertexProgram) { return activeNVVertexProgram(program); @@ -1725,287 +1800,6 @@ bool CDriverGL::activeVertexProgram (CVertexProgram *program) return false; } - -// *************************************************************************** - -void CDriverGL::setConstant (uint index, float f0, float f1, float f2, float f3) -{ - H_AUTO_OGL(CDriverGL_setConstant); - -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - // Setup constant - nglProgramParameter4fNV (GL_VERTEX_PROGRAM_NV, index, f0, f1, f2, f3); - } - else if (_Extensions.ARBVertexProgram) - { - nglProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, f0, f1, f2, f3); - } - else if (_Extensions.EXTVertexShader) - { - float datas[] = { f0, f1, f2, f3 }; - nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas); - } -#endif -} - - -// *************************************************************************** - -void CDriverGL::setConstant (uint index, double d0, double d1, double d2, double d3) -{ - H_AUTO_OGL(CDriverGL_setConstant); - -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - // Setup constant - nglProgramParameter4dNV (GL_VERTEX_PROGRAM_NV, index, d0, d1, d2, d3); - } - else if (_Extensions.ARBVertexProgram) - { - nglProgramEnvParameter4dARB(GL_VERTEX_PROGRAM_ARB, index, d0, d1, d2, d3); - } - else if (_Extensions.EXTVertexShader) - { - double datas[] = { d0, d1, d2, d3 }; - nglSetInvariantEXT(_EVSConstantHandle + index, GL_DOUBLE, datas); - } -#endif -} - - -// *************************************************************************** - -void CDriverGL::setConstant (uint index, const NLMISC::CVector& value) -{ - H_AUTO_OGL(CDriverGL_setConstant); - -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - // Setup constant - nglProgramParameter4fNV (GL_VERTEX_PROGRAM_NV, index, value.x, value.y, value.z, 0); - } - else if (_Extensions.ARBVertexProgram) - { - nglProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, value.x, value.y, value.z, 0); - } - else if (_Extensions.EXTVertexShader) - { - float datas[] = { value.x, value.y, value.z, 0 }; - nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas); - } -#endif -} - - -// *************************************************************************** - -void CDriverGL::setConstant (uint index, const NLMISC::CVectorD& value) -{ - H_AUTO_OGL(CDriverGL_setConstant); - -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - // Setup constant - nglProgramParameter4dNV (GL_VERTEX_PROGRAM_NV, index, value.x, value.y, value.z, 0); - } - else if (_Extensions.ARBVertexProgram) - { - nglProgramEnvParameter4dARB(GL_VERTEX_PROGRAM_ARB, index, value.x, value.y, value.z, 0); - } - else if (_Extensions.EXTVertexShader) - { - double datas[] = { value.x, value.y, value.z, 0 }; - nglSetInvariantEXT(_EVSConstantHandle + index, GL_DOUBLE, datas); - } -#endif -} - - -// *************************************************************************** -void CDriverGL::setConstant (uint index, uint num, const float *src) -{ - H_AUTO_OGL(CDriverGL_setConstant); - -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - nglProgramParameters4fvNV(GL_VERTEX_PROGRAM_NV, index, num, src); - } - else if (_Extensions.ARBVertexProgram) - { - for(uint k = 0; k < num; ++k) - { - nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + k, src + 4 * k); - } - } - else if (_Extensions.EXTVertexShader) - { - for(uint k = 0; k < num; ++k) - { - nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_FLOAT, (void *) (src + 4 * k)); - } - } -#endif -} - -// *************************************************************************** -void CDriverGL::setConstant (uint index, uint num, const double *src) -{ - H_AUTO_OGL(CDriverGL_setConstant); - -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - nglProgramParameters4dvNV(GL_VERTEX_PROGRAM_NV, index, num, src); - } - else if (_Extensions.ARBVertexProgram) - { - for(uint k = 0; k < num; ++k) - { - nglProgramEnvParameter4dvARB(GL_VERTEX_PROGRAM_ARB, index + k, src + 4 * k); - } - } - else if (_Extensions.EXTVertexShader) - { - for(uint k = 0; k < num; ++k) - { - nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_DOUBLE, (void *) (src + 4 * k)); - } - } -#endif -} - -// *************************************************************************** - -const uint CDriverGL::GLMatrix[IDriver::NumMatrix]= -{ - GL_MODELVIEW, - GL_PROJECTION, -#ifdef USE_OPENGLES - GL_MODELVIEW -#else - GL_MODELVIEW_PROJECTION_NV -#endif -}; - - -// *************************************************************************** - -const uint CDriverGL::GLTransform[IDriver::NumTransform]= -{ -#ifdef USE_OPENGLES - 0, - 0, - 0, - 0 -#else - GL_IDENTITY_NV, - GL_INVERSE_NV, - GL_TRANSPOSE_NV, - GL_INVERSE_TRANSPOSE_NV -#endif -}; - - -// *************************************************************************** - -void CDriverGL::setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform) -{ - H_AUTO_OGL(CDriverGL_setConstantMatrix); - -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - // First, ensure that the render setup is correclty setuped. - refreshRenderSetup(); - - // Track the matrix - nglTrackMatrixNV (GL_VERTEX_PROGRAM_NV, index, GLMatrix[matrix], GLTransform[transform]); - // Release Track => matrix data is copied. - nglTrackMatrixNV (GL_VERTEX_PROGRAM_NV, index, GL_NONE, GL_IDENTITY_NV); - } - else - { - // First, ensure that the render setup is correctly setuped. - refreshRenderSetup(); - CMatrix mat; - switch (matrix) - { - case IDriver::ModelView: - mat = _ModelViewMatrix; - break; - case IDriver::Projection: - { - refreshProjMatrixFromGL(); - mat = _GLProjMat; - } - break; - case IDriver::ModelViewProjection: - refreshProjMatrixFromGL(); - mat = _GLProjMat * _ModelViewMatrix; - break; - default: - break; - } - - switch(transform) - { - case IDriver::Identity: break; - case IDriver::Inverse: - mat.invert(); - break; - case IDriver::Transpose: - mat.transpose(); - break; - case IDriver::InverseTranspose: - mat.invert(); - mat.transpose(); - break; - default: - break; - } - mat.transpose(); - float matDatas[16]; - mat.get(matDatas); - if (_Extensions.ARBVertexProgram) - { - nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index, matDatas); - nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + 1, matDatas + 4); - nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + 2, matDatas + 8); - nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + 3, matDatas + 12); - } - else - { - nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, matDatas); - nglSetInvariantEXT(_EVSConstantHandle + index + 1, GL_FLOAT, matDatas + 4); - nglSetInvariantEXT(_EVSConstantHandle + index + 2, GL_FLOAT, matDatas + 8); - nglSetInvariantEXT(_EVSConstantHandle + index + 3, GL_FLOAT, matDatas + 12); - } - } -#endif -} - -// *************************************************************************** - -void CDriverGL::setConstantFog (uint index) -{ - H_AUTO_OGL(CDriverGL_setConstantFog) - const float *values = _ModelViewMatrix.get(); - setConstant (index, -values[2], -values[6], -values[10], -values[14]); -} - // *************************************************************************** void CDriverGL::enableVertexProgramDoubleSidedColor(bool doubleSided) From fcb0ee720eecc8400ecd785749643cb67ac2e61f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 16:36:29 +0200 Subject: [PATCH 105/137] Implement new driver interface in Direct3D driver --- .../3d/driver/direct3d/driver_direct3d.cpp | 2 +- .../src/3d/driver/direct3d/driver_direct3d.h | 118 ++++-- .../driver_direct3d_pixel_program.cpp | 280 +++---------- .../direct3d/driver_direct3d_uniform.cpp | 218 ++++++++++ .../driver_direct3d_vertex_program.cpp | 381 +++++------------- 5 files changed, 482 insertions(+), 517 deletions(-) create mode 100644 code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index e7c1ba693..180f577f3 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -3634,7 +3634,7 @@ void CDriverD3D::CVertexProgramPtrState::apply(CDriverD3D *driver) void CDriverD3D::CPixelShaderPtrState::apply(CDriverD3D *driver) { H_AUTO_D3D(CDriverD3D_CPixelShaderPtrState); - if (!driver->supportPixelProgram()) return; + if (!driver->_PixelProgram) return; driver->_DeviceInterface->SetPixelShader(PixelShader); } diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 3494812cc..79dcc917e 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -1092,33 +1092,103 @@ public: virtual void setupMaterialPass(uint pass); virtual void endMaterialMultiPass(); - // Vertex program - virtual bool supportVertexProgram () const; - virtual bool supportPixelProgram () const; - virtual bool supportPixelProgram (CPixelProgram::TProfile profile) const; - virtual bool isVertexProgramEmulated () const; - virtual bool activeVertexProgram (CVertexProgram *program); - virtual bool activePixelProgram (CPixelProgram *program); - virtual void setConstant (uint index, float, float, float, float); - virtual void setConstant (uint index, double, double, double, double); - virtual void setConstant (uint index, const NLMISC::CVector& value); - virtual void setConstant (uint index, const NLMISC::CVectorD& value); - virtual void setConstant (uint index, uint num, const float *src); - virtual void setConstant (uint index, uint num, const double *src); - virtual void setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform); - virtual void setConstantFog (uint index); + + + + + + /// \name Vertex Program + // @{ + + // Order of preference + // - activeVertexProgram + // - CMaterial pass[n] VP (uses activeVertexProgram, but does not override if one already set by code) + // - default generic VP that mimics fixed pipeline / no VP with fixed pipeline + + /** + * Does the driver supports vertex program, but emulated by CPU ? + */ + virtual bool isVertexProgramEmulated() const; + + /** Return true if the driver supports the specified vertex program profile. + */ + virtual bool supportVertexProgram(CVertexProgram::TProfile profile = CVertexProgram::nelvp) const; + + /** Compile the given vertex program, return if successful. + * If a vertex program was set active before compilation, + * the state of the active vertex program is undefined behaviour afterwards. + */ + virtual bool compileVertexProgram(CVertexProgram *program); + + /** Set the active vertex program. This will override vertex programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL. + * The vertex program is activated immediately. + */ + virtual bool activeVertexProgram(CVertexProgram *program); + // @} + + + + /// \name Pixel Program + // @{ + + // Order of preference + // - activePixelProgram + // - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code) + // - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code) + + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const; + + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compilePixelProgram(CPixelProgram *program); + + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activePixelProgram(CPixelProgram *program); + // @} + + + + /// \name Program parameters + // @{ + // Set parameters + virtual void setUniform1f(TProgram program, uint index, float f0); + virtual void setUniform2f(TProgram program, uint index, float f0, float f1); + virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2); + virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3); + virtual void setUniform1i(TProgram program, uint index, sint32 i0); + virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1); + virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2); + virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + virtual void setUniform1ui(TProgram program, uint index, uint32 ui0); + virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1); + virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2); + virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); + virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v); + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3); + virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m); + virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src); + virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src); + virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src); + // Set builtin parameters + virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform); + virtual void setUniformFog(TProgram program, uint index); + // @} + + + + + virtual void enableVertexProgramDoubleSidedColor(bool doubleSided); virtual bool supportVertexProgramDoubleSidedColor() const; - // Pixel program - virtual void setPixelProgramConstant (uint index, float, float, float, float); - virtual void setPixelProgramConstant (uint index, double, double, double, double); - virtual void setPixelProgramConstant (uint index, const NLMISC::CVector& value); - virtual void setPixelProgramConstant (uint index, const NLMISC::CVectorD& value); - virtual void setPixelProgramConstant (uint index, uint num, const float *src); - virtual void setPixelProgramConstant (uint index, uint num, const double *src); - virtual void setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform); - // Occlusion query virtual bool supportOcclusionQuery() const; virtual IOcclusionQuery *createOcclusionQuery(); 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 db8763091..612155c38 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 @@ -54,12 +54,6 @@ CPixelProgramDrvInfosD3D::~CPixelProgramDrvInfosD3D() // *************************************************************************** -bool CDriverD3D::supportPixelProgram () const -{ - H_AUTO_D3D(CDriverD3D_supportPixelProgram) - return _PixelProgram; -} - bool CDriverD3D::supportPixelProgram (CPixelProgram::TProfile profile) const { H_AUTO_D3D(CDriverD3D_supportPixelProgram_profile) @@ -69,81 +63,77 @@ bool CDriverD3D::supportPixelProgram (CPixelProgram::TProfile profile) const // *************************************************************************** +bool CDriverD3D::compilePixelProgram(CPixelProgram *program) +{ + // Program setuped ? + if (program->_DrvInfo==NULL) + { + // Find a supported pixel program profile + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile)) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("No supported source profile for pixel program"); + return false; + } + + _GPUPrgDrvInfos.push_front (NULL); + ItGPUPrgDrvInfoPtrList itPix = _GPUPrgDrvInfos.begin(); + CPixelProgramDrvInfosD3D *drvInfo; + *itPix = drvInfo = new CPixelProgramDrvInfosD3D(this, itPix); + + // Create a driver info structure + program->_DrvInfo = *itPix; + + LPD3DXBUFFER pShader; + LPD3DXBUFFER pErrorMsgs; + if (D3DXAssembleShader(source->SourcePtr, source->SourceLen, NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK) + { + if (_DeviceInterface->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), &(getPixelProgramD3D(*program)->Shader)) != D3D_OK) + return false; + } + else + { + nlwarning ("Can't assemble pixel program:"); + nlwarning ((const char*)pErrorMsgs->GetBufferPointer()); + return false; + } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); + } + + return true; +} + +// *************************************************************************** + bool CDriverD3D::activePixelProgram(CPixelProgram *program) { H_AUTO_D3D(CDriverD3D_activePixelProgram ) if (_DisableHardwarePixelProgram) return false; - // Setup or unsetup ? - if (program) - { - // Program setuped ? - if (program->_DrvInfo==NULL) - { - // Find a supported pixel program profile - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) - { - if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile)) - { - source = program->getProgramSource()->Sources[i]; - } - } - if (!source) - { - nlwarning("No supported source profile for pixel program"); - return false; - } - - _GPUPrgDrvInfos.push_front (NULL); - ItGPUPrgDrvInfoPtrList itPix = _GPUPrgDrvInfos.begin(); - CPixelProgramDrvInfosD3D *drvInfo; - *itPix = drvInfo = new CPixelProgramDrvInfosD3D(this, itPix); - - // Create a driver info structure - program->_DrvInfo = *itPix; - - LPD3DXBUFFER pShader; - LPD3DXBUFFER pErrorMsgs; - if (D3DXAssembleShader(source->SourcePtr, source->SourceLen, NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK) - { - if (_DeviceInterface->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), &(getPixelProgramD3D(*program)->Shader)) != D3D_OK) - return false; - } - else - { - nlwarning ("Can't assemble pixel program:"); - nlwarning ((const char*)pErrorMsgs->GetBufferPointer()); - return false; - } - - // Set parameters for assembly programs - drvInfo->ParamIndices = source->ParamIndices; - - // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); - } - } - // Set the pixel program if (program) { - CPixelProgramDrvInfosD3D *info = static_cast((IGPUProgramDrvInfos*)program->_DrvInfo); - setPixelShader (info->Shader); + if (!CDriverD3D::compilePixelProgram(program)) return false; - float z = 0; - float o = 1; - setRenderState (D3DRS_FOGSTART, *((DWORD*) (&o))); - setRenderState (D3DRS_FOGEND, *((DWORD*) (&z))); + CPixelProgramDrvInfosD3D *info = static_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + setPixelShader(info->Shader); } else { - setPixelShader (NULL); - - // Set the old fog range - setRenderState (D3DRS_FOGSTART, *((DWORD*) (&_FogStart))); - setRenderState (D3DRS_FOGEND, *((DWORD*) (&_FogEnd))); + setPixelShader(NULL); } return true; @@ -151,160 +141,6 @@ bool CDriverD3D::activePixelProgram(CPixelProgram *program) // *************************************************************************** -void CDriverD3D::setPixelProgramConstant (uint index, float f0, float f1, float f2, float f3) -{ - H_AUTO_D3D(CDriverD3D_setPixelProgramConstant) - if (!_PixelProgram) - { - #ifdef NL_DEBUG - nlwarning("No pixel programs available!!"); - #endif - return; - } - const float tabl[4] = {f0, f1, f2, f3}; - setPixelShaderConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setPixelProgramConstant (uint index, double d0, double d1, double d2, double d3) -{ - H_AUTO_D3D(CDriverD3D_setPixelProgramConstant ) - if (!_PixelProgram) - { - #ifdef NL_DEBUG - nlwarning("No pixel programs available!!"); - #endif - return; - } - const float tabl[4] = {(float)d0, (float)d1, (float)d2, (float)d3}; - setPixelShaderConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setPixelProgramConstant (uint index, const NLMISC::CVector& value) -{ - H_AUTO_D3D(CDriverD3D_setPixelProgramConstant ) - if (!_PixelProgram) - { - #ifdef NL_DEBUG - nlwarning("No pixel programs available!!"); - #endif - return; - } - const float tabl[4] = {value.x, value.y, value.z, 0}; - setPixelShaderConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setPixelProgramConstant (uint index, const NLMISC::CVectorD& value) -{ - H_AUTO_D3D(CDriverD3D_setPixelProgramConstant ) - if (!_PixelProgram) - { - #ifdef NL_DEBUG - nlwarning("No pixel programs available!!"); - #endif - return; - } - const float tabl[4] = {(float)value.x, (float)value.y, (float)value.z, 0}; - setPixelShaderConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setPixelProgramConstant (uint index, uint num, const float *src) -{ - H_AUTO_D3D(CDriverD3D_setPixelProgramConstant ) - if (!_PixelProgram) - { - #ifdef NL_DEBUG - nlwarning("No pixel programs available!!"); - #endif - return; - } - uint i; - for (i=0; i_11, matPtr->_21, matPtr->_31, matPtr->_41); - setPixelProgramConstant (index+1, matPtr->_12, matPtr->_22, matPtr->_32, matPtr->_42); - setPixelProgramConstant (index+2, matPtr->_13, matPtr->_23, matPtr->_33, matPtr->_43); - setPixelProgramConstant (index+3, matPtr->_14, matPtr->_24, matPtr->_34, matPtr->_44); -} - -// *************************************************************************** - void CDriverD3D::disableHardwarePixelProgram() { H_AUTO_D3D(CDriverD3D_disableHardwarePixelProgram) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp new file mode 100644 index 000000000..27e76bfd4 --- /dev/null +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp @@ -0,0 +1,218 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stddirect3d.h" + +#include "driver_direct3d.h" + +using namespace std; +using namespace NLMISC; + +namespace NL3D +{ + +void CDriverD3D::setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3) +{ + H_AUTO_D3D(CDriverD3D_setUniform4f); + + const float tabl[4] = { f0, f1, f2, f3 }; + switch (program) + { + case VertexProgram: + if (_VertexProgram) + { + setVertexProgramConstant(index, tabl); + } + break; + case PixelProgram: + if (_PixelProgram) + { + setPixelShaderConstant(index, tabl); + } + break; + } +} + +void CDriverD3D::setUniform4fv(TProgram program, uint index, size_t num, const float *src) +{ + H_AUTO_D3D(CDriverD3D_setUniform4fv); + + switch (program) + { + case VertexProgram: + if (_VertexProgram) + { + for (uint i = 0; i < num; ++i) + { + setVertexProgramConstant(index + i, src + (i * 4)); + } + } + break; + case PixelProgram: + if (_PixelProgram) + { + for (uint i = 0; i < num; ++i) + { + setPixelShaderConstant(index + i, src + (i * 4)); + } + } + break; + } +} + +void CDriverD3D::setUniform1f(TProgram program, uint index, float f0) +{ + CDriverD3D::setUniform4f(program, index, f0, 0.f, 0.f, 0.f); +} + +void CDriverD3D::setUniform2f(TProgram program, uint index, float f0, float f1) +{ + CDriverD3D::setUniform4f(program, index, f0, f1, 0.f, 0.f); +} + +void CDriverD3D::setUniform3f(TProgram program, uint index, float f0, float f1, float f2) +{ + CDriverD3D::setUniform4f(program, index, f0, f1, f2, 0.0f); +} + +void CDriverD3D::setUniform1i(TProgram program, uint index, sint32 i0) +{ + +} + +void CDriverD3D::setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) +{ + +} + +void CDriverD3D::setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) +{ + +} + +void CDriverD3D::setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) +{ + +} + +void CDriverD3D::setUniform1ui(TProgram program, uint index, uint32 ui0) +{ + +} + +void CDriverD3D::setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1) +{ + +} + +void CDriverD3D::setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2) +{ + +} + +void CDriverD3D::setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) +{ + +} + +void CDriverD3D::setUniform3f(TProgram program, uint index, const NLMISC::CVector& v) +{ + CDriverD3D::setUniform4f(program, index, v.x, v.y, v.z, 0.f); +} + +void CDriverD3D::setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3) +{ + CDriverD3D::setUniform4f(program, index, v.x, v.y, v.z, f3); +} + +void CDriverD3D::setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) +{ + H_AUTO_D3D(CDriverD3D_setUniform4x4f); + + // TODO: Verify this! + NLMISC::CMatrix mat = m; + mat.transpose(); + const float *md = mat.get(); + + CDriverD3D::setUniform4fv(program, index, 4, md); +} + +void CDriverD3D::setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) +{ + +} + +void CDriverD3D::setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src) +{ + +} + +void CDriverD3D::setUniformMatrix(NL3D::IDriver::TProgram program, uint index, NL3D::IDriver::TMatrix matrix, NL3D::IDriver::TTransform transform) +{ + H_AUTO_D3D(CDriverD3D_setUniformMatrix); + + D3DXMATRIX mat; + D3DXMATRIX *matPtr = NULL; + switch (matrix) + { + case IDriver::ModelView: + matPtr = &_D3DModelView; + break; + case IDriver::Projection: + matPtr = &(_MatrixCache[remapMatrixIndex(D3DTS_PROJECTION)].Matrix); + break; + case IDriver::ModelViewProjection: + matPtr = &_D3DModelViewProjection; + break; + } + if (transform != IDriver::Identity) + { + switch (transform) + { + case IDriver::Inverse: + D3DXMatrixInverse(&mat, NULL, matPtr); + break; + case IDriver::Transpose: + D3DXMatrixTranspose(&mat, matPtr); + break; + case IDriver::InverseTranspose: + D3DXMatrixInverse(&mat, NULL, matPtr); + D3DXMatrixTranspose(&mat, &mat); + break; + } + matPtr = &mat; + } + + D3DXMatrixTranspose(&mat, matPtr); + + CDriverD3D::setUniform4fv(program, index, 4, &mat.m[0][0]); +} + +void CDriverD3D::setUniformFog(NL3D::IDriver::TProgram program, uint index) +{ + H_AUTO_D3D(CDriverD3D_setUniformFog) + + /* "oFog" must always be between [1, 0] what ever you set in D3DRS_FOGSTART and D3DRS_FOGEND (1 for no fog, 0 for full fog). + The Geforce4 TI 4200 (drivers 53.03 and 45.23) doesn't accept other values for "oFog". */ + const float delta = _FogEnd - _FogStart; + CDriverD3D::setUniform4f(program, index, + -_D3DModelView._13 / delta, + -_D3DModelView._23 / delta, + -_D3DModelView._33 / delta, + 1 - (_D3DModelView._43 - _FogStart) / delta); +} + +} // 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 c7b8905a1..46e0f1c14 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 @@ -43,10 +43,10 @@ CVertexProgamDrvInfosD3D::~CVertexProgamDrvInfosD3D() // *************************************************************************** -bool CDriverD3D::supportVertexProgram () const +bool CDriverD3D::supportVertexProgram (CVertexProgram::TProfile profile) const { H_AUTO_D3D(CDriverD3D_supportVertexProgram ) - return _VertexProgram; + return (profile == CVertexProgram::nelvp) && _VertexProgram; } // *************************************************************************** @@ -262,123 +262,129 @@ void dump(const CVPParser::TProgram &prg, std::string &dest) // *************************************************************************** +bool CDriverD3D::compileVertexProgram(NL3D::CVertexProgram *program) +{ + // Program setuped ? + if (program->_DrvInfo == NULL) + { + // Find nelvp + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("Direct3D driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; + } + + _GPUPrgDrvInfos.push_front (NULL); + ItGPUPrgDrvInfoPtrList itTex = _GPUPrgDrvInfos.begin(); + CVertexProgamDrvInfosD3D *drvInfo; + *itTex = drvInfo = new CVertexProgamDrvInfosD3D(this, itTex); + + // Create a driver info structure + program->_DrvInfo = *itTex; + + /** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..). + * There are some incompatibilities. + */ + CVPParser parser; + CVPParser::TProgram parsedProgram; + std::string errorOutput; + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); + if (!result) + { + nlwarning("Unable to parse a vertex program :"); + nlwarning(errorOutput.c_str()); + #ifdef NL_DEBUG_D3D + nlassert(0); + #endif // NL_DEBUG_D3D + return false; + } + + // tmp fix for Radeon 8500/9000/9200 + // Currently they hang when PaletteSkin / SkinWeight are present in the vertex declaration, but not used + // so disable them in the vertex declaration + // We don't use these component in vertex programs currently.. + #ifdef NL_DEBUG + for(uint k = 0; k < parsedProgram.size(); ++k) + { + for(uint l = 0; l < parsedProgram[k].getNumUsedSrc(); ++l) + { + const CVPOperand &op = parsedProgram[k].getSrc(l); + if (op.Type == CVPOperand::InputRegister) + { + nlassert(op.Value.InputRegisterValue != CVPOperand::IWeight); + nlassert(op.Value.InputRegisterValue != CVPOperand::IPaletteSkin); + } + } + } + #endif + + // Dump the vertex program + std::string dest; + dump(parsedProgram, dest); +#ifdef NL_DEBUG_D3D + nlinfo("Assemble Vertex Shader : "); + string::size_type lineBegin = 0; + string::size_type lineEnd; + while ((lineEnd = dest.find('\n', lineBegin)) != string::npos) + { + nlinfo(dest.substr (lineBegin, lineEnd-lineBegin).c_str()); + lineBegin = lineEnd+1; + } + nlinfo(dest.substr (lineBegin, lineEnd-lineBegin).c_str()); +#endif // NL_DEBUG_D3D + + LPD3DXBUFFER pShader; + LPD3DXBUFFER pErrorMsgs; + if (D3DXAssembleShader (dest.c_str(), (UINT)dest.size(), NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK) + { + if (_DeviceInterface->CreateVertexShader((DWORD*)pShader->GetBufferPointer(), &(getVertexProgramD3D(*program)->Shader)) != D3D_OK) + return false; + } + else + { + nlwarning ("Can't assemble vertex program:"); + nlwarning ((const char*)pErrorMsgs->GetBufferPointer()); + return false; + } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source->DisplayName.c_str(), source->Features); + } + + return true; +} + +// *************************************************************************** + bool CDriverD3D::activeVertexProgram (CVertexProgram *program) { H_AUTO_D3D(CDriverD3D_activeVertexProgram ) if (_DisableHardwareVertexProgram) return false; - // Setup or unsetup ? - if (program) - { - // Program setuped ? - if (program->_DrvInfo==NULL) - { - // Find nelvp - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) - { - if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) - { - source = program->getProgramSource()->Sources[i]; - } - } - if (!source) - { - nlwarning("Direct3D driver only supports 'nelvp' profile, vertex program cannot be used"); - return false; - } - - _GPUPrgDrvInfos.push_front (NULL); - ItGPUPrgDrvInfoPtrList itTex = _GPUPrgDrvInfos.begin(); - CVertexProgamDrvInfosD3D *drvInfo; - *itTex = drvInfo = new CVertexProgamDrvInfosD3D(this, itTex); - - // Create a driver info structure - program->_DrvInfo = *itTex; - - /** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..). - * There are some incompatibilities. - */ - CVPParser parser; - CVPParser::TProgram parsedProgram; - std::string errorOutput; - bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); - if (!result) - { - nlwarning("Unable to parse a vertex program :"); - nlwarning(errorOutput.c_str()); - #ifdef NL_DEBUG_D3D - nlassert(0); - #endif // NL_DEBUG_D3D - return false; - } - - // tmp fix for Radeon 8500/9000/9200 - // Currently they hang when PaletteSkin / SkinWeight are present in the vertex declaration, but not used - // so disable them in the vertex declaration - // We don't use these component in vertex programs currently.. - #ifdef NL_DEBUG - for(uint k = 0; k < parsedProgram.size(); ++k) - { - for(uint l = 0; l < parsedProgram[k].getNumUsedSrc(); ++l) - { - const CVPOperand &op = parsedProgram[k].getSrc(l); - if (op.Type == CVPOperand::InputRegister) - { - nlassert(op.Value.InputRegisterValue != CVPOperand::IWeight); - nlassert(op.Value.InputRegisterValue != CVPOperand::IPaletteSkin); - } - } - } - #endif - - // Dump the vertex program - std::string dest; - dump(parsedProgram, dest); -#ifdef NL_DEBUG_D3D - nlinfo("Assemble Vertex Shader : "); - string::size_type lineBegin = 0; - string::size_type lineEnd; - while ((lineEnd = dest.find('\n', lineBegin)) != string::npos) - { - nlinfo(dest.substr (lineBegin, lineEnd-lineBegin).c_str()); - lineBegin = lineEnd+1; - } - nlinfo(dest.substr (lineBegin, lineEnd-lineBegin).c_str()); -#endif // NL_DEBUG_D3D - - LPD3DXBUFFER pShader; - LPD3DXBUFFER pErrorMsgs; - if (D3DXAssembleShader (dest.c_str(), (UINT)dest.size(), NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK) - { - if (_DeviceInterface->CreateVertexShader((DWORD*)pShader->GetBufferPointer(), &(getVertexProgramD3D(*program)->Shader)) != D3D_OK) - return false; - } - else - { - nlwarning ("Can't assemble vertex program:"); - nlwarning ((const char*)pErrorMsgs->GetBufferPointer()); - return false; - } - - // Set parameters for assembly programs - drvInfo->ParamIndices = source->ParamIndices; - - // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); - } - } - // Set the vertex program if (program) { - CVertexProgamDrvInfosD3D *info = static_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + if (!CDriverD3D::compileVertexProgram(program)) return false; + + CVertexProgamDrvInfosD3D *info = NLMISC::safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); 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 (random fog flicking) with Geforce4 TI 4200 (drivers 53.03 and 45.23). The other cards seam to interpret the "oFog"'s values using D3DRS_FOGSTART, D3DRS_FOGEND. + Related to setUniformFog(). */ float z = 0; float o = 1; @@ -399,171 +405,6 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) // *************************************************************************** -void CDriverD3D::setConstant (uint index, float f0, float f1, float f2, float f3) -{ - H_AUTO_D3D(CDriverD3D_setConstant ) - if (!_VertexProgram) - { - #ifdef NL_DEBUG - nlwarning("No vertex programs available!!"); - #endif - return; - } - const float tabl[4] = {f0, f1, f2, f3}; - setVertexProgramConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setConstant (uint index, double d0, double d1, double d2, double d3) -{ - H_AUTO_D3D(CDriverD3D_setConstant ) - if (!_VertexProgram) - { - #ifdef NL_DEBUG - nlwarning("No vertex programs available!!"); - #endif - return; - } - const float tabl[4] = {(float)d0, (float)d1, (float)d2, (float)d3}; - setVertexProgramConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setConstant (uint index, const NLMISC::CVector& value) -{ - H_AUTO_D3D(CDriverD3D_setConstant ) - if (!_VertexProgram) - { - #ifdef NL_DEBUG - nlwarning("No vertex programs available!!"); - #endif - return; - } - const float tabl[4] = {value.x, value.y, value.z, 0}; - setVertexProgramConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setConstant (uint index, const NLMISC::CVectorD& value) -{ - H_AUTO_D3D(CDriverD3D_setConstant ) - if (!_VertexProgram) - { - #ifdef NL_DEBUG - nlwarning("No vertex programs available!!"); - #endif - return; - } - const float tabl[4] = {(float)value.x, (float)value.y, (float)value.z, 0}; - setVertexProgramConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setConstant (uint index, uint num, const float *src) -{ - H_AUTO_D3D(CDriverD3D_setConstant ) - if (!_VertexProgram) - { - #ifdef NL_DEBUG - nlwarning("No vertex programs available!!"); - #endif - return; - } - uint i; - for (i=0; i_11, matPtr->_21, matPtr->_31, matPtr->_41); - setConstant (index+1, matPtr->_12, matPtr->_22, matPtr->_32, matPtr->_42); - setConstant (index+2, matPtr->_13, matPtr->_23, matPtr->_33, matPtr->_43); - setConstant (index+3, matPtr->_14, matPtr->_24, matPtr->_34, matPtr->_44); -} - -// *************************************************************************** - -void CDriverD3D::setConstantFog (uint index) -{ - H_AUTO_D3D(CDriverD3D_setConstantFog ) - /* "oFog" must always be between [1, 0] what ever you set in D3DRS_FOGSTART and D3DRS_FOGEND (1 for no fog, 0 for full fog). - The Geforce4 TI 4200 (drivers 53.03 and 45.23) doesn't accept other values for "oFog". */ - const float delta = _FogEnd-_FogStart; - setConstant (index, - _D3DModelView._13/delta, -_D3DModelView._23/delta, -_D3DModelView._33/delta, 1-(_D3DModelView._43-_FogStart)/delta); -} - -// *************************************************************************** - void CDriverD3D::enableVertexProgramDoubleSidedColor(bool /* doubleSided */) { H_AUTO_D3D(CDriverD3D_enableVertexProgramDoubleSidedColor) From 057eab46809bda6f76876e3aede86ff702b3c3de Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 18:33:38 +0200 Subject: [PATCH 106/137] Cleanup abstract gpu program interface --- code/nel/include/nel/3d/driver.h | 27 +++ code/nel/include/nel/3d/geometry_program.h | 36 +--- code/nel/include/nel/3d/gpu_program.h | 156 ++++++++++++++++-- code/nel/include/nel/3d/gpu_program_source.h | 93 ----------- code/nel/include/nel/3d/pixel_program.h | 43 +---- code/nel/include/nel/3d/vertex_program.h | 67 +------- code/nel/src/3d/CMakeLists.txt | 2 - .../src/3d/driver/direct3d/driver_direct3d.h | 35 +++- .../driver_direct3d_pixel_program.cpp | 16 +- .../driver_direct3d_vertex_program.cpp | 16 +- code/nel/src/3d/driver/opengl/driver_opengl.h | 31 +++- .../opengl/driver_opengl_pixel_program.cpp | 20 +-- .../3d/driver/opengl/driver_opengl_vertex.cpp | 4 +- .../opengl/driver_opengl_vertex_program.cpp | 56 +++---- code/nel/src/3d/geometry_program.cpp | 14 +- code/nel/src/3d/gpu_program.cpp | 143 +++++++++++++++- code/nel/src/3d/gpu_program_source.cpp | 47 ------ code/nel/src/3d/pixel_program.cpp | 34 +--- code/nel/src/3d/stereo_debugger.cpp | 9 +- code/nel/src/3d/stereo_ovr.cpp | 20 ++- code/nel/src/3d/vertex_program.cpp | 113 +------------ 21 files changed, 454 insertions(+), 528 deletions(-) delete mode 100644 code/nel/include/nel/3d/gpu_program_source.h delete mode 100644 code/nel/src/3d/gpu_program_source.cpp diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 8890a9cc7..1f7739c01 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1147,6 +1147,33 @@ public: + /// \name Geometry Program + // @{ + + // Order of preference + // - activeGeometryProgram + // - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code) + // - none + + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const = 0; + + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compileGeometryProgram(CGeometryProgram *program) = 0; + + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activeGeometryProgram(CGeometryProgram *program) = 0; + // @} + + + /// \name Program parameters // @{ // Set parameters diff --git a/code/nel/include/nel/3d/geometry_program.h b/code/nel/include/nel/3d/geometry_program.h index ac9451b27..adba5f01d 100644 --- a/code/nel/include/nel/3d/geometry_program.h +++ b/code/nel/include/nel/3d/geometry_program.h @@ -27,52 +27,18 @@ #include #include #include -#include #include namespace NL3D { -/** - * \brief CGeometryProgramInfo - * \date 2013-09-07 15:00GMT - * \author Jan Boon (Kaetemi) - * Read-only information structure. - */ -struct CGeometryProgramInfo -{ -public: - std::string DisplayName; - - /*enum TFeatures - { - - };*/ - - // Bitfield containing features used by this geometry program - uint Features; - - // Indices of parameters used by features - // ... -}; - class CGeometryProgram : public IGPUProgram { public: /// Constructor - CGeometryProgram(CGPUProgramSourceCont *programSource); + CGeometryProgram(); /// Destructor virtual ~CGeometryProgram (); - - /// Build feature information - void buildInfo(const char *displayName, uint features); - /// Get feature information - inline const CGeometryProgramInfo *getInfo() const { return _Info; } - -private: - - /// Feature information - CGeometryProgramInfo *_Info; }; } // NL3D diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index ba0afb9e4..d1b234dee 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -57,11 +57,103 @@ public: // The virtual dtor is important. virtual ~IGPUProgramDrvInfos(void); - virtual uint getParamIdx(char *name) const = 0; + virtual uint getUniformIndex(char *name) const = 0; }; -class CGPUProgramSource; -class CGPUProgramSourceCont; +#define NL_GPU_PROGRAM_LIGHTS 8 + +/// Features exposed by a program. Used to set builtin parameters on user provided shaders +struct CGPUProgramFeatures +{ + CGPUProgramFeatures() : DriverFlags(0), MaterialFlags(0) /*, NumLights(0) */ { } + + // Driver builtin parameters + enum TDriverFlags + { + // Matrices + ModelView = 0x00000001, + ModelViewInverse = 0x00000002, + ModelViewTranspose = 0x00000004, + ModelViewInverseTranspose = 0x00000008, + + Projection = 0x00000010, + ProjectionInverse = 0x00000020, + ProjectionTranspose = 0x00000040, + ProjectionInverseTranspose = 0x00000080, + + ModelViewProjection = 0x00000100, + ModelViewProjectionInverse = 0x00000200, + ModelViewProjectionTranspose = 0x00000400, + ModelViewProjectionInverseTranspose = 0x00000800, + + // + // Rough example, modify as necessary. + // + + // Lighting (todo) + /// Driver ambient, must be ignored when material ambient is flagged + //DriverAmbient = 0x00001000, + /// Lights, does not set diffuses if material lights is flagged + //DriverLights = 0x00002000, + // etcetera + + // Fog (todo) + // Fog = ..., + }; + uint32 DriverFlags; + // uint NumLights; // number of lights supported by the program (not used yet, modify as necessary) + + enum TMaterialFlags + { + /// Use the CMaterial texture stages as the textures for a Pixel Program + TextureStages = 0x00000001, // <- don't remove this one, it's already used, if you want to split them up into the different stages, then it's ok to change it + + // + // Rough example, modify as necessary. + // + + // Lighting (todo) + /// Material ambient premultiplied with driver ambient + //MaterialAmbient = 0x00000002, + /// Premultiply lights diffuse with material diffuse, requires driver lights to be flagged + //MaterialLights = 0x00000004, + // etcetera + + // Add all necessary feature sets used with builtin materials here + }; + // Material builtin parameters + uint32 MaterialFlags; +}; + +/// Stucture used to cache the indices of builtin parameters +struct CGPUProgramIndices +{ + uint ModelView; + uint ModelViewInverse; + uint ModelViewTranspose; + uint ModelViewInverseTranspose; + + uint Projection; + uint ProjectionInverse; + uint ProjectionTranspose; + uint ProjectionInverseTranspose; + + uint ModelViewProjection; + uint ModelViewProjectionInverse; + uint ModelViewProjectionTranspose; + uint ModelViewProjectionInverseTranspose; + + // + // Rough example, modify as necessary. + // + //uint Ambient; + + //uint LightType[NL_GPU_PROGRAM_LIGHTS]; + //uint LightAmbient[NL_GPU_PROGRAM_LIGHTS]; + //uint LightDiffuse[NL_GPU_PROGRAM_LIGHTS]; + //uint LightPosition[NL_GPU_PROGRAM_LIGHTS]; + //uint LightDirection[NL_GPU_PROGRAM_LIGHTS]; +}; /** * \brief IGPUProgram @@ -74,6 +166,8 @@ class IGPUProgram : public NLMISC::CRefCount public: enum TProfile { + none = 0, + // types // Vertex Shader = 0x01 // Pixel Shader = 0x02 @@ -123,24 +217,66 @@ public: glsl330g = 0x65030330, // GLSL geometry program version 330 }; + struct CSource : public NLMISC::CRefCount + { + public: + std::string DisplayName; + + /// Minimal required profile for this GPU program + IGPUProgram::TProfile Profile; + + const char *SourcePtr; + size_t SourceLen; + /// Copy the source code string + inline void setSource(const char *source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); } + /// Set pointer to source code string without copying the string + inline void setSourcePtr(const char *sourcePtr, size_t sourceLen) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = sourceLen; } + inline void setSourcePtr(const char *sourcePtr) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = strlen(sourcePtr); } + + /// CVertexProgramInfo/CPixelProgramInfo/... NeL features + CGPUProgramFeatures Features; + + /// Map with known parameter indices, used for assembly programs + std::map ParamIndices; + + private: + std::string SourceCopy; + }; + public: IGPUProgram(); - IGPUProgram(CGPUProgramSourceCont *programSource); virtual ~IGPUProgram(); - /// Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0 - inline uint getParamIdx(char *name) const { return _DrvInfo->getParamIdx(name); }; + // Manage the sources, not allowed after compilation. + // Add multiple sources using different profiles, the driver will use the first one it supports. + inline size_t getSourceNb() const { return m_Sources.size(); }; + inline CSource *getSource(size_t i) const { return m_Sources[i]; }; + inline size_t addSource(CSource *source) { nlassert(!m_Source); m_Sources.push_back(source); return (m_Sources.size() - 1); } + inline void removeSource(size_t i) { nlassert(!m_Source); m_Sources.erase(m_Sources.begin() + i); } - /// Get the program - inline const CGPUProgramSourceCont *getProgramSource() const { return _ProgramSource; }; + // Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0 + inline uint getUniformIndex(char *name) const { return m_DrvInfo->getUniformIndex(name); }; + + // Get feature information of the current program + inline CSource *source() const { return m_Source; }; + inline const CGPUProgramFeatures &features() const { return m_Source->Features; }; + inline const CGPUProgramIndices &indices() const { return m_Indices; }; + inline TProfile profile() const { return m_Source->Profile; } + + // Build feature info, called automatically by the driver after compile succeeds + void buildInfo(CSource *source); protected: /// The progam source - NLMISC::CSmartPtr _ProgramSource; + std::vector > m_Sources; + + /// The source used for compilation + NLMISC::CSmartPtr m_Source; + CGPUProgramIndices m_Indices; public: /// The driver information. For the driver implementation only. - NLMISC::CRefPtr _DrvInfo; + NLMISC::CRefPtr m_DrvInfo; }; /* class IGPUProgram */ diff --git a/code/nel/include/nel/3d/gpu_program_source.h b/code/nel/include/nel/3d/gpu_program_source.h deleted file mode 100644 index c51ac67ce..000000000 --- a/code/nel/include/nel/3d/gpu_program_source.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * \file gpu_program_source.h - * \brief CGPUProgramSource - * \date 2013-09-07 14:54GMT - * \author Jan Boon (Kaetemi) - * CGPUProgramSource - */ - -/* - * Copyright (C) 2013 by authors - * - * This file is part of NL3D. - * NL3D is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * NL3D is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General - * Public License for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with NL3D. If not, see - * . - */ - -#ifndef NL3D_GPU_PROGRAM_SOURCE_H -#define NL3D_GPU_PROGRAM_SOURCE_H -#include - -// STL includes - -// NeL includes -#include - -// Project includes -#include - -namespace NL3D { - -/** - * \brief CGPUProgramSource - * \date 2013-09-07 14:54GMT - * \author Jan Boon (Kaetemi) - * A single GPU program with a specific profile. - */ -struct CGPUProgramSource : public NLMISC::CRefCount -{ -public: - std::string DisplayName; - - /// Minimal required profile for this GPU program - IGPUProgram::TProfile Profile; - - const char *SourcePtr; - size_t SourceLen; - /// Copy the source code string - inline void setSource(const char *source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); } - /// Set pointer to source code string without copying the string - inline void setSourcePtr(const char *sourcePtr, size_t sourceLen) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = sourceLen; } - inline void setSourcePtr(const char *sourcePtr) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = strlen(sourcePtr); } - - /// CVertexProgramInfo/CPixelProgramInfo/... NeL features - uint Features; - - /// Map with known parameter indices, used for assembly programs - std::map ParamIndices; - -private: - std::string SourceCopy; - -}; /* class CGPUProgramSource */ - -/** - * \brief CGPUProgramSourceCont - * \date 2013-09-07 14:54GMT - * \author Jan Boon (Kaetemi) - * Container for the source code of a single GPU program, allowing - * variations in different language profiles. - */ -struct CGPUProgramSourceCont : public NLMISC::CRefCount -{ -public: - std::vector > Sources; - -}; /* class CGPUProgramSourceCont */ - -} /* namespace NL3D */ - -#endif /* #ifndef NL3D_GPU_PROGRAM_SOURCE_H */ - -/* end of file */ diff --git a/code/nel/include/nel/3d/pixel_program.h b/code/nel/include/nel/3d/pixel_program.h index e006844aa..1bfdb84d0 100644 --- a/code/nel/include/nel/3d/pixel_program.h +++ b/code/nel/include/nel/3d/pixel_program.h @@ -27,59 +27,18 @@ #include #include #include -#include #include namespace NL3D { -/** - * \brief CPixelProgramInfo - * \date 2013-09-07 15:00GMT - * \author Jan Boon (Kaetemi) - * Read-only information structure. - */ -struct CPixelProgramInfo -{ -public: - std::string DisplayName; - - enum TFeatures - { - /// Use texture stages from CMaterial as texture parameters - MaterialTextures = 0x0001, - /// Set driver fog parameters on this program - Fog = 0x0002, - /// Adds an enabled/disabled parameter to the fog, for user shaders - DynamicFog = 0x0004, - }; - - // Bitfield containing features used by this pixel program - uint Features; - - // Indices of parameters used by features - uint FogEnabledIdx; // (Fog && DynamicFog) nlFogEnabled, fog enabled - uint FogStartEndIdx; // (Fog) nlFogStartEnd, start and end of fog - uint FogColorIdx; // (Fog) nlFogColor, fog color -}; - class CPixelProgram : public IGPUProgram { public: /// Constructor - CPixelProgram(CGPUProgramSourceCont *programSource); + CPixelProgram(); /// Destructor virtual ~CPixelProgram (); - - /// Build feature information - void buildInfo(const char *displayName, uint features); - /// Get feature information - inline const CPixelProgramInfo *getInfo() const { return _Info; } - -private: - - /// Feature information - CPixelProgramInfo *_Info; }; } // NL3D diff --git a/code/nel/include/nel/3d/vertex_program.h b/code/nel/include/nel/3d/vertex_program.h index b8843e182..2e20db584 100644 --- a/code/nel/include/nel/3d/vertex_program.h +++ b/code/nel/include/nel/3d/vertex_program.h @@ -20,84 +20,21 @@ #include "nel/misc/types_nl.h" #include "nel/misc/smart_ptr.h" #include "nel/3d/gpu_program.h" -#include "nel/3d/gpu_program_source.h" #include namespace NL3D { -/** - * \brief CVertexProgramInfo - * \date 2013-09-07 15:00GMT - * \author Jan Boon (Kaetemi) - * Read-only information structure. - */ -struct CVertexProgramInfo -{ -public: - std::string DisplayName; - - enum TFeatures - { - // World - // transform - - // Lights - Ambient = 0x0001, - Sun = 0x0002, - PointLight0 = 0x0004, - PointLight1 = 0x0008, - PointLight2 = 0x0010, - - // Lights, additional parameters for user shaders - /// Adds an enabled/disabled parameter to all of the lights - DynamicLights = 0x0020, - }; - - /// Bitfield containing features used by this vertex program. - uint Features; - - /// Indices of parameters used by features. - - /// Lights, NeL supports: - /// - Ambient light - uint AmbientIdx; // (Ambient) - /// - One directional light - uint SunDirectionIdx; // (Sun) - uint SunDiffuseIdx; // (Sun) - /// - Zero to three point lights - uint PointLight0PositionIdx; // (PointLight0) - uint PointLight0DiffuseIdx; // (PointLight0) - uint PointLight1PositionIdx; // (PointLight1) - uint PointLight1DiffuseIdx; // (PointLight1) - uint PointLight2PositionIdx; // (PointLight2) - uint PointLight2DiffuseIdx; // (PointLight2) - - /// DynamicLights - uint SunEnabledIdx; // (DynamicLights && Sun) - uint PointLight0EnabledIdx; // (DynamicLights && PointLight0) - uint PointLight1EnabledIdx; // (DynamicLights && PointLight1) - uint PointLight2EnabledIdx; // (DynamicLights && PointLight2) -}; - class CVertexProgram : public IGPUProgram { public: /// Constructor - CVertexProgram(CGPUProgramSourceCont *programSource); + CVertexProgram(); CVertexProgram(const char *nelvp); + /// Destructor virtual ~CVertexProgram (); - /// Build feature information - void buildInfo(const char *displayName, uint features); - /// Get feature information - inline const CVertexProgramInfo *getInfo() const { return _Info; } - -private: - - /// Feature information - CVertexProgramInfo *_Info; }; } // NL3D diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index 5f5896ff9..a6ecf1ce8 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -169,8 +169,6 @@ SOURCE_GROUP(Driver FILES ../../include/nel/3d/geometry_program.h gpu_program.cpp ../../include/nel/3d/gpu_program.h - gpu_program_source.cpp - ../../include/nel/3d/gpu_program_source.h gpu_program_params.cpp ../../include/nel/3d/gpu_program_params.h) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 79dcc917e..a17ae32c3 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -309,7 +309,7 @@ public: CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it); ~CVertexProgamDrvInfosD3D(); - virtual uint getParamIdx(char *name) const + virtual uint getUniformIndex(char *name) const { std::map::const_iterator it = ParamIndices.find(name); if (it != ParamIndices.end()) return it->second; @@ -331,7 +331,7 @@ public: CPixelProgramDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it); ~CPixelProgramDrvInfosD3D(); - virtual uint getParamIdx(char *name) const + virtual uint getUniformIndex(char *name) const { std::map::const_iterator it = ParamIndices.find(name); if (it != ParamIndices.end()) return it->second; @@ -1156,6 +1156,33 @@ public: + /// \name Geometry Program + // @{ + + // Order of preference + // - activeGeometryProgram + // - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code) + // - none + + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; } + + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; } + + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activeGeometryProgram(CGeometryProgram *program) { return false; } + // @} + + + /// \name Program parameters // @{ // Set parameters @@ -2078,7 +2105,7 @@ public: { H_AUTO_D3D(CDriverD3D_getPixelProgramD3D); CPixelProgramDrvInfosD3D* d3dPixelProgram; - d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IGPUProgramDrvInfos*)(pixelProgram._DrvInfo); + d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IGPUProgramDrvInfos*)(pixelProgram.m_DrvInfo); return d3dPixelProgram; } @@ -2087,7 +2114,7 @@ public: { H_AUTO_D3D(CDriverD3D_getVertexProgramD3D); CVertexProgamDrvInfosD3D* d3dVertexProgram; - d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IGPUProgramDrvInfos*)(vertexProgram._DrvInfo); + d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IGPUProgramDrvInfos*)(vertexProgram.m_DrvInfo); return d3dVertexProgram; } 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 612155c38..0d97925b3 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 @@ -66,15 +66,15 @@ bool CDriverD3D::supportPixelProgram (CPixelProgram::TProfile profile) const bool CDriverD3D::compilePixelProgram(CPixelProgram *program) { // Program setuped ? - if (program->_DrvInfo==NULL) + if (program->m_DrvInfo==NULL) { // Find a supported pixel program profile - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + IGPUProgram::CSource *source = NULL; + for (uint i = 0; i < program->getSourceNb(); ++i) { - if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile)) + if (supportPixelProgram(program->getSource(i)->Profile)) { - source = program->getProgramSource()->Sources[i]; + source = program->getSource(i); } } if (!source) @@ -89,7 +89,7 @@ bool CDriverD3D::compilePixelProgram(CPixelProgram *program) *itPix = drvInfo = new CPixelProgramDrvInfosD3D(this, itPix); // Create a driver info structure - program->_DrvInfo = *itPix; + program->m_DrvInfo = *itPix; LPD3DXBUFFER pShader; LPD3DXBUFFER pErrorMsgs; @@ -109,7 +109,7 @@ bool CDriverD3D::compilePixelProgram(CPixelProgram *program) drvInfo->ParamIndices = source->ParamIndices; // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); + program->buildInfo(source); } return true; @@ -128,7 +128,7 @@ bool CDriverD3D::activePixelProgram(CPixelProgram *program) { if (!CDriverD3D::compilePixelProgram(program)) return false; - CPixelProgramDrvInfosD3D *info = static_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + CPixelProgramDrvInfosD3D *info = static_cast((IGPUProgramDrvInfos*)program->m_DrvInfo); setPixelShader(info->Shader); } else 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 46e0f1c14..a409f20cf 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 @@ -265,15 +265,15 @@ void dump(const CVPParser::TProgram &prg, std::string &dest) bool CDriverD3D::compileVertexProgram(NL3D::CVertexProgram *program) { // Program setuped ? - if (program->_DrvInfo == NULL) + if (program->m_DrvInfo == NULL) { // Find nelvp - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + IGPUProgram::CSource *source = NULL; + for (uint i = 0; i < program->getSourceNb(); ++i) { - if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + if (program->getSource(i)->Profile == CVertexProgram::nelvp) { - source = program->getProgramSource()->Sources[i]; + source = program->getSource(i); } } if (!source) @@ -288,7 +288,7 @@ bool CDriverD3D::compileVertexProgram(NL3D::CVertexProgram *program) *itTex = drvInfo = new CVertexProgamDrvInfosD3D(this, itTex); // Create a driver info structure - program->_DrvInfo = *itTex; + program->m_DrvInfo = *itTex; /** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..). * There are some incompatibilities. @@ -359,7 +359,7 @@ bool CDriverD3D::compileVertexProgram(NL3D::CVertexProgram *program) drvInfo->ParamIndices = source->ParamIndices; // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); + program->buildInfo(source); } return true; @@ -378,7 +378,7 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) { if (!CDriverD3D::compileVertexProgram(program)) return false; - CVertexProgamDrvInfosD3D *info = NLMISC::safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + CVertexProgamDrvInfosD3D *info = NLMISC::safe_cast((IGPUProgramDrvInfos*)program->m_DrvInfo); 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 diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index f70a0627f..e76563fb3 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1362,6 +1362,33 @@ private: + /// \name Geometry Program + // @{ + + // Order of preference + // - activeGeometryProgram + // - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code) + // - none + + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; } + + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; } + + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activeGeometryProgram(CGeometryProgram *program) { return false; } + // @} + + + /// \name Program parameters // @{ // Set parameters @@ -1618,7 +1645,7 @@ public: // The gl id is auto created here. CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); - virtual uint getParamIdx(char *name) const + virtual uint getUniformIndex(char *name) const { std::map::const_iterator it = ParamIndices.find(name); if (it != ParamIndices.end()) return it->second; @@ -1638,7 +1665,7 @@ public: // The gl id is auto created here. CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); - virtual uint getParamIdx(char *name) const + virtual uint getUniformIndex(char *name) const { std::map::const_iterator it = ParamIndices.find(name); if (it != ParamIndices.end()) return it->second; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index 31e6ed482..f787530e7 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -97,7 +97,7 @@ bool CDriverGL::activePixelProgram(CPixelProgram *program) bool CDriverGL::compilePixelProgram(NL3D::CPixelProgram *program) { // Program setuped ? - if (program->_DrvInfo == NULL) + if (program->m_DrvInfo == NULL) { glDisable(GL_FRAGMENT_PROGRAM_ARB); _PixelProgramEnabled = false; @@ -109,12 +109,12 @@ bool CDriverGL::compilePixelProgram(NL3D::CPixelProgram *program) CPixelProgamDrvInfosGL *drvInfo; *it = drvInfo = new CPixelProgamDrvInfosGL(this, it); // Set the pointer - program->_DrvInfo = drvInfo; + program->m_DrvInfo = drvInfo; if (!setupPixelProgram(program, drvInfo->ID)) { delete drvInfo; - program->_DrvInfo = NULL; + program->m_DrvInfo = NULL; _GPUPrgDrvInfos.erase(it); return false; } @@ -136,7 +136,7 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) if (!CDriverGL::compilePixelProgram(program)) return false; // Cast the driver info pointer - CPixelProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + CPixelProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->m_DrvInfo); glEnable(GL_FRAGMENT_PROGRAM_ARB); _PixelProgramEnabled = true; @@ -159,15 +159,15 @@ bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &spe { H_AUTO_OGL(CDriverGL_setupARBPixelProgram) - CPixelProgamDrvInfosGL *drvInfo = static_cast((IGPUProgramDrvInfos *)program->_DrvInfo); + CPixelProgamDrvInfosGL *drvInfo = static_cast((IGPUProgramDrvInfos *)program->m_DrvInfo); // Find a supported pixel program profile - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + IGPUProgram::CSource *source = NULL; + for (uint i = 0; i < program->getSourceNb(); ++i) { - if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile)) + if (supportPixelProgram(program->getSource(i)->Profile)) { - source = program->getProgramSource()->Sources[i]; + source = program->getSource(i); } } if (!source) @@ -224,7 +224,7 @@ bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &spe drvInfo->ParamIndices = source->ParamIndices; // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); + program->buildInfo(source); return true; } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp index 521a13baf..dd1351955 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp @@ -1151,7 +1151,7 @@ void CDriverGL::toggleGlArraysForEXTVertexShader() CVertexProgram *vp = _LastSetuppedVP; if (vp) { - CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IGPUProgramDrvInfos *) vp->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IGPUProgramDrvInfos *) vp->m_DrvInfo); if (drvInfo) { // Disable all VertexAttribs. @@ -1396,7 +1396,7 @@ void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb) CVertexProgram *vp = _LastSetuppedVP; if (!vp) return; - CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IGPUProgramDrvInfos *) vp->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IGPUProgramDrvInfos *) vp->m_DrvInfo); if (!drvInfo) return; uint32 flags= vb.VertexFormat; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp index e0b07af2a..a5e00d3f1 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp @@ -93,17 +93,17 @@ bool CDriverGL::compileNVVertexProgram(CVertexProgram *program) // Driver info CVertexProgamDrvInfosGL *drvInfo; - nlassert(!program->_DrvInfo); + nlassert(!program->m_DrvInfo); glDisable(GL_VERTEX_PROGRAM_NV); _VertexProgramEnabled = false; // Find nelvp - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + IGPUProgram::CSource *source = NULL; + for (uint i = 0; i < program->getSourceNb(); ++i) { - if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + if (program->getSource(i)->Profile == CVertexProgram::nelvp) { - source = program->getProgramSource()->Sources[i]; + source = program->getSource(i); } } if (!source) @@ -136,7 +136,7 @@ bool CDriverGL::compileNVVertexProgram(CVertexProgram *program) *it = drvInfo = new CVertexProgamDrvInfosGL(this, it); // Set the pointer - program->_DrvInfo = drvInfo; + program->m_DrvInfo = drvInfo; // Compile the program nglLoadProgramNV(GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr); @@ -177,7 +177,7 @@ bool CDriverGL::compileNVVertexProgram(CVertexProgram *program) // Setup not ok delete drvInfo; - program->_DrvInfo = NULL; + program->m_DrvInfo = NULL; _GPUPrgDrvInfos.erase(it); return false; } @@ -186,7 +186,7 @@ bool CDriverGL::compileNVVertexProgram(CVertexProgram *program) drvInfo->ParamIndices = source->ParamIndices; // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); + program->buildInfo(source); // Setup ok return true; @@ -208,7 +208,7 @@ bool CDriverGL::activeNVVertexProgram(CVertexProgram *program) if (program) { // Driver info - CVertexProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->m_DrvInfo); nlassert(drvInfo); // Enable vertex program @@ -1524,17 +1524,17 @@ bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program) #ifndef USE_OPENGLES - nlassert(!program->_DrvInfo); + nlassert(!program->m_DrvInfo); glDisable(GL_VERTEX_PROGRAM_ARB); _VertexProgramEnabled = false; // Find nelvp - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + IGPUProgram::CSource *source = NULL; + for (uint i = 0; i < program->getSourceNb(); ++i) { - if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + if (program->getSource(i)->Profile == CVertexProgram::nelvp) { - source = program->getProgramSource()->Sources[i]; + source = program->getSource(i); } } if (!source) @@ -1563,12 +1563,12 @@ bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program) CVertexProgamDrvInfosGL *drvInfo; *it = drvInfo = new CVertexProgamDrvInfosGL(this, it); // Set the pointer - program->_DrvInfo=drvInfo; + program->m_DrvInfo = drvInfo; if (!setupARBVertexProgram(parsedProgram, drvInfo->ID, drvInfo->SpecularWritten)) { delete drvInfo; - program->_DrvInfo = NULL; + program->m_DrvInfo = NULL; _GPUPrgDrvInfos.erase(it); return false; } @@ -1577,7 +1577,7 @@ bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program) drvInfo->ParamIndices = source->ParamIndices; // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); + program->buildInfo(source); return true; @@ -1600,7 +1600,7 @@ bool CDriverGL::activeARBVertexProgram(CVertexProgram *program) if (program) { // Driver info - CVertexProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->m_DrvInfo); nlassert(drvInfo); glEnable( GL_VERTEX_PROGRAM_ARB ); @@ -1639,17 +1639,17 @@ bool CDriverGL::compileEXTVertexShader(CVertexProgram *program) #ifndef USE_OPENGLES - nlassert(program->_DrvInfo); + nlassert(program->m_DrvInfo); glDisable(GL_VERTEX_SHADER_EXT); _VertexProgramEnabled = false; // Find nelvp - CGPUProgramSource *source = NULL; - for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + IGPUProgram::CSource *source = NULL; + for (uint i = 0; i < program->getSourceNb(); ++i) { - if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp) + if (program->getSource(i)->Profile == CVertexProgram::nelvp) { - source = program->getProgramSource()->Sources[i]; + source = program->getSource(i); } } if (!source) @@ -1690,12 +1690,12 @@ bool CDriverGL::compileEXTVertexShader(CVertexProgram *program) CVertexProgamDrvInfosGL *drvInfo; *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); // Set the pointer - program->_DrvInfo=drvInfo; + program->m_DrvInfo=drvInfo; if (!setupEXTVertexShader(parsedProgram, drvInfo->ID, drvInfo->Variants, drvInfo->UsedVertexComponents)) { delete drvInfo; - program->_DrvInfo = NULL; + program->m_DrvInfo = NULL; _GPUPrgDrvInfos.erase(it); return false; } @@ -1704,7 +1704,7 @@ bool CDriverGL::compileEXTVertexShader(CVertexProgram *program) drvInfo->ParamIndices = source->ParamIndices; // Build the feature info - program->buildInfo(source->DisplayName.c_str(), source->Features); + program->buildInfo(source); return true; @@ -1727,7 +1727,7 @@ bool CDriverGL::activeEXTVertexShader(CVertexProgram *program) if (program) { // Driver info - CVertexProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = safe_cast((IGPUProgramDrvInfos*)program->m_DrvInfo); nlassert(drvInfo); glEnable(GL_VERTEX_SHADER_EXT); @@ -1751,7 +1751,7 @@ bool CDriverGL::activeEXTVertexShader(CVertexProgram *program) bool CDriverGL::compileVertexProgram(NL3D::CVertexProgram *program) { - if (program->_DrvInfo == NULL) + if (program->m_DrvInfo == NULL) { // Extension if (_Extensions.NVVertexProgram) diff --git a/code/nel/src/3d/geometry_program.cpp b/code/nel/src/3d/geometry_program.cpp index ae73d669f..26fb15ae9 100644 --- a/code/nel/src/3d/geometry_program.cpp +++ b/code/nel/src/3d/geometry_program.cpp @@ -32,7 +32,7 @@ namespace NL3D // *************************************************************************** -CGeometryProgram::CGeometryProgram(CGPUProgramSourceCont *programSource) : _Info(NULL), IGPUProgram(programSource) +CGeometryProgram::CGeometryProgram() { } @@ -41,19 +41,9 @@ CGeometryProgram::CGeometryProgram(CGPUProgramSourceCont *programSource) : _Info CGeometryProgram::~CGeometryProgram () { - delete _Info; - _Info = NULL; + } // *************************************************************************** -void CGeometryProgram::buildInfo(const char *displayName, uint features) -{ - nlassert(_Info == NULL); - _Info = new CGeometryProgramInfo(); - CGeometryProgramInfo *info = _Info; - info->DisplayName = displayName; - info->Features = features; -} - } // NL3D diff --git a/code/nel/src/3d/gpu_program.cpp b/code/nel/src/3d/gpu_program.cpp index fc75e44e4..55f07e32b 100644 --- a/code/nel/src/3d/gpu_program.cpp +++ b/code/nel/src/3d/gpu_program.cpp @@ -66,17 +66,144 @@ IGPUProgram::IGPUProgram() // *************************************************************************** -IGPUProgram::IGPUProgram(CGPUProgramSourceCont *programSource) : _ProgramSource(programSource) -{ - -} - -// *************************************************************************** - IGPUProgram::~IGPUProgram() { // Must kill the drv mirror of this program. - _DrvInfo.kill(); + m_DrvInfo.kill(); +} + +void IGPUProgram::buildInfo(CSource *source) +{ + nlassert(!m_Source); + + m_Source = source; + + // Fill index cache + CGPUProgramFeatures &features = m_Source->Features; + TProfile profile = m_Source->Profile; // for special cases + + if (features.DriverFlags & CGPUProgramFeatures::ModelView) + { + m_Indices.ModelView = getUniformIndex("nlModelView"); + if (m_Indices.ModelView == ~0) + { + nlwarning("Missing 'nlModelView' in gpu program '%s', ModelView disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ModelView; + } + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverse) + { + m_Indices.ModelViewInverse = getUniformIndex("nlModelViewInverse"); + if (m_Indices.ModelViewInverse == ~0) + { + nlwarning("Missing 'nlModelViewInverse' in gpu program '%s', ModelViewInverse disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ModelViewInverse; + } + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewTranspose) + { + m_Indices.ModelViewTranspose = getUniformIndex("nlModelViewTranspose"); + if (m_Indices.ModelViewTranspose == ~0) + { + nlwarning("Missing 'nlModelViewTranspose' in gpu program '%s', ModelViewTranspose disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ModelViewTranspose; + } + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverseTranspose) + { + m_Indices.ModelViewInverseTranspose = getUniformIndex("nlModelViewInverseTranspose"); + if (m_Indices.ModelViewInverseTranspose == ~0) + { + nlwarning("Missing 'nlModelViewInverseTranspose' in gpu program '%s', ModelViewInverseTranspose disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ModelViewInverseTranspose; + } + } + if (features.DriverFlags & CGPUProgramFeatures::Projection) + { + m_Indices.Projection = getUniformIndex("nlProjection"); + if (m_Indices.Projection == ~0) + { + nlwarning("Missing 'nlProjection' in gpu program '%s', Projection disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::Projection; + } + } + if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverse) + { + m_Indices.ProjectionInverse = getUniformIndex("nlProjectionInverse"); + if (m_Indices.ProjectionInverse == ~0) + { + nlwarning("Missing 'nlProjectionInverse' in gpu program '%s', ProjectionInverse disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ProjectionInverse; + } + } + if (features.DriverFlags & CGPUProgramFeatures::ProjectionTranspose) + { + m_Indices.ProjectionTranspose = getUniformIndex("nlProjectionTranspose"); + if (m_Indices.ProjectionTranspose == ~0) + { + nlwarning("Missing 'nlProjectionTranspose' in gpu program '%s', ProjectionTranspose disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ProjectionTranspose; + } + } + if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverseTranspose) + { + m_Indices.ProjectionInverseTranspose = getUniformIndex("nlProjectionInverseTranspose"); + if (m_Indices.ProjectionInverseTranspose == ~0) + { + nlwarning("Missing 'nlProjectionInverseTranspose' in gpu program '%s', ProjectionInverseTranspose disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ProjectionInverseTranspose; + } + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjection) + { + m_Indices.ModelViewProjection = getUniformIndex("nlModelViewProjection"); + if (m_Indices.ModelViewProjection == ~0) + { + nlwarning("Missing 'nlModelViewProjection' in gpu program '%s', ModelViewProjection disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjection; + } + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverse) + { + m_Indices.ModelViewProjectionInverse = getUniformIndex("nlModelViewProjectionInverse"); + if (m_Indices.ModelViewProjectionInverse == ~0) + { + nlwarning("Missing 'nlModelViewProjectionInverse' in gpu program '%s', ModelViewProjectionInverse disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionInverse; + } + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionTranspose) + { + m_Indices.ModelViewProjectionTranspose = getUniformIndex("nlModelViewProjectionTranspose"); + if (m_Indices.ModelViewProjectionTranspose == ~0) + { + nlwarning("Missing 'nlModelViewProjectionTranspose' in gpu program '%s', ModelViewProjectionTranspose disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionTranspose; + } + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverseTranspose) + { + m_Indices.ModelViewProjectionInverseTranspose = getUniformIndex("nlModelViewProjectionInverseTranspose"); + if (m_Indices.ModelViewProjectionInverseTranspose == ~0) + { + nlwarning("Missing 'nlModelViewProjectionInverseTranspose' in gpu program '%s', ModelViewProjectionInverseTranspose disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionInverseTranspose; + } + } + + // + // Rough example, modify as necessary. + // + /*if (features.DriverFlags & CGPUProgramFeatures::DriverAmbient || features.MaterialFlags & CGPUProgramFeatures::MaterialAmbient) + { + m_Indices.Ambient = getUniformIndex("nlAmbient"); + if (m_Indices.Ambient == ~0) + { + nlwarning("Missing 'nlAmbient' in gpu program '%s', Ambient disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::DriverAmbient; + features.MaterialFlags &= ~CGPUProgramFeatures::MaterialAmbient; + } + }*/ } } /* namespace NL3D */ diff --git a/code/nel/src/3d/gpu_program_source.cpp b/code/nel/src/3d/gpu_program_source.cpp deleted file mode 100644 index 21d1cc18b..000000000 --- a/code/nel/src/3d/gpu_program_source.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/** - * \file gpu_program_source.cpp - * \brief CGPUProgramSource - * \date 2013-09-07 14:54GMT - * \author Jan Boon (Kaetemi) - * CGPUProgramSource - */ - -/* - * Copyright (C) 2013 by authors - * - * This file is part of NL3D. - * NL3D is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * NL3D is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General - * Public License for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with NL3D. If not, see - * . - */ - -#include -#include - -// STL includes - -// NeL includes -// #include - -// Project includes - -using namespace std; -// using namespace NLMISC; - -namespace NL3D { - -void gpu_program_source_cpp_dummy() { } - -} /* namespace NL3D */ - -/* end of file */ diff --git a/code/nel/src/3d/pixel_program.cpp b/code/nel/src/3d/pixel_program.cpp index 8fbe8c0cf..adb2163e5 100644 --- a/code/nel/src/3d/pixel_program.cpp +++ b/code/nel/src/3d/pixel_program.cpp @@ -32,7 +32,7 @@ namespace NL3D // *************************************************************************** -CPixelProgram::CPixelProgram(CGPUProgramSourceCont *programSource) : _Info(NULL), IGPUProgram(programSource) +CPixelProgram::CPixelProgram() { } @@ -41,39 +41,9 @@ CPixelProgram::CPixelProgram(CGPUProgramSourceCont *programSource) : _Info(NULL) CPixelProgram::~CPixelProgram () { - delete _Info; - _Info = NULL; + } // *************************************************************************** -void CPixelProgram::buildInfo(const char *displayName, uint features) -{ - nlassert(_Info == NULL); - _Info = new CPixelProgramInfo(); - CPixelProgramInfo *info = _Info; - info->DisplayName = displayName; - info->Features = features; - if (features & CPixelProgramInfo::Fog) - { - if (features & CPixelProgramInfo::DynamicFog) - { - info->FogEnabledIdx = getParamIdx("nlFogEnabled"); - if (info->FogEnabledIdx == ~0) - { - nlwarning("Missing 'nlFogEnabled' in gpu program '%s', DynamicFog disabled", displayName); - info->Features &= ~CPixelProgramInfo::DynamicFog; - } - } - info->FogStartEndIdx = getParamIdx("nlFogStartEnd"); - info->FogColorIdx = getParamIdx("nlFogColor"); - if (info->FogStartEndIdx == ~0 - || info->FogStartEndIdx == ~0) - { - nlwarning("Missing 'nlFogStartEnd/nlFogColor' in gpu program '%s', Fog disabled", displayName); - info->Features &= ~CPixelProgramInfo::Fog; - } - } -} - } // NL3D diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 509ba4769..588e36fcb 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -116,10 +116,8 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); - CGPUProgramSource *source = new CGPUProgramSource(); - CGPUProgramSourceCont *sourceCont = new CGPUProgramSourceCont(); - sourceCont->Sources.push_back(source); - source->Features = CPixelProgramInfo::MaterialTextures; + IGPUProgram::CSource *source = new IGPUProgram::CSource(); + source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; /*if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { @@ -131,7 +129,8 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) nldebug("VR: arbfp1"); source->Profile = IGPUProgram::arbfp1; source->setSourcePtr(a_arbfp1); - m_PixelProgram = new CPixelProgram(sourceCont); + m_PixelProgram = new CPixelProgram(); + m_PixelProgram->addSource(source); } /*else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) { diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index b89783cb9..ac2350f3c 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -239,31 +239,37 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); - CGPUProgramSource *source = new CGPUProgramSource(); - CGPUProgramSourceCont *sourceCont = new CGPUProgramSourceCont(); - sourceCont->Sources.push_back(source); - source->Features = CPixelProgramInfo::MaterialTextures; + m_PixelProgram = new CPixelProgram(); + IGPUProgram::CSource *source = new IGPUProgram::CSource(); + source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; + source->Profile = IGPUProgram::none; if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { nldebug("VR: fp40"); source->Profile = IGPUProgram::fp40; source->setSourcePtr(g_StereoOVR_fp40); - m_PixelProgram = new CPixelProgram(sourceCont); + m_PixelProgram->addSource(source); } else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { nldebug("VR: arbfp1"); source->Profile = IGPUProgram::arbfp1; source->setSourcePtr(g_StereoOVR_arbfp1); - m_PixelProgram = new CPixelProgram(sourceCont); + m_PixelProgram->addSource(source); } else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) { nldebug("VR: ps_2_0"); source->Profile = IGPUProgram::ps_2_0; source->setSourcePtr(g_StereoOVR_ps_2_0); - m_PixelProgram = new CPixelProgram(sourceCont); + m_PixelProgram->addSource(source); + } + + if (!drvInternal->compilePixelProgram(m_PixelProgram)) + { + delete m_PixelProgram; + m_PixelProgram = NULL; } if (m_PixelProgram) diff --git a/code/nel/src/3d/vertex_program.cpp b/code/nel/src/3d/vertex_program.cpp index d0acbe775..b47e706ee 100644 --- a/code/nel/src/3d/vertex_program.cpp +++ b/code/nel/src/3d/vertex_program.cpp @@ -26,129 +26,26 @@ namespace NL3D // *************************************************************************** -CVertexProgram::CVertexProgram(CGPUProgramSourceCont *programSource) : _Info(NULL), IGPUProgram(programSource) +CVertexProgram::CVertexProgram() { } // *************************************************************************** -CVertexProgram::CVertexProgram(const char *nelvp) : _Info(NULL) +CVertexProgram::CVertexProgram(const char *nelvp) { - CGPUProgramSource *source = new CGPUProgramSource(); - _ProgramSource = new CGPUProgramSourceCont(); - _ProgramSource->Sources.push_back(source); + CSource *source = new CSource(); source->Profile = IGPUProgram::nelvp; source->setSource(nelvp); - source->Features = 0; + addSource(source); } // *************************************************************************** CVertexProgram::~CVertexProgram () { - delete _Info; - _Info = NULL; -} - -// *************************************************************************** - -void CVertexProgram::buildInfo(const char *displayName, uint features) -{ - nlassert(_Info == NULL); - _Info = new CVertexProgramInfo(); - CVertexProgramInfo *info = _Info; - info->DisplayName = displayName; - info->Features = features; - if (features & CVertexProgramInfo::Ambient) - { - info->AmbientIdx = getParamIdx("nlAmbient"); - if (info->AmbientIdx == ~0) - { - nlwarning("Missing 'nlAmbient' in gpu program '%s', Ambient disabled", displayName); - info->Features &= ~CVertexProgramInfo::Ambient; - } - } - if (features & CVertexProgramInfo::Sun) - { - if (features & CVertexProgramInfo::DynamicLights) - { - info->SunEnabledIdx = getParamIdx("nlSunEnabled"); - if (info->SunEnabledIdx == ~0) - { - nlwarning("Missing 'nlSunEnabled' in gpu program '%s', DynamicLights disabled", displayName); - info->Features &= ~CVertexProgramInfo::DynamicLights; - } - } - info->SunDirectionIdx = getParamIdx("nlSunDirection"); - info->SunDiffuseIdx = getParamIdx("nlSunDiffuse"); - if (info->SunDirectionIdx == ~0 - || info->SunDiffuseIdx == ~0) - { - nlwarning("Missing 'nlSunDirection/nlSunDiffuse' in gpu program '%s', Sun disabled", displayName); - info->Features &= ~CVertexProgramInfo::Sun; - } - } - if (features & CVertexProgramInfo::PointLight0) - { - if (features & CVertexProgramInfo::DynamicLights) - { - info->PointLight0EnabledIdx = getParamIdx("nlPointLight0Enabled"); - if (info->PointLight0EnabledIdx == ~0) - { - nlwarning("Missing 'nlPointLight0Enabled' in gpu program '%s', DynamicLights disabled", displayName); - info->Features &= ~CVertexProgramInfo::DynamicLights; - } - } - info->PointLight0PositionIdx = getParamIdx("nlPointLight0Position"); - info->PointLight0DiffuseIdx = getParamIdx("nlPointLight0Diffuse"); - if (info->PointLight0PositionIdx == ~0 - || info->PointLight0DiffuseIdx == ~0) - { - nlwarning("Missing 'nlPointLight0Position/nlPointLight0Diffuse' in gpu program '%s', PointLight0 disabled", displayName); - info->Features &= ~CVertexProgramInfo::PointLight0; - } - } - if (features & CVertexProgramInfo::PointLight1) - { - if (features & CVertexProgramInfo::DynamicLights) - { - info->PointLight1EnabledIdx = getParamIdx("nlPointLight1Enabled"); - if (info->PointLight1EnabledIdx == ~0) - { - nlwarning("Missing 'nlPointLight1Enabled' in gpu program '%s', DynamicLights disabled", displayName); - info->Features &= ~CVertexProgramInfo::DynamicLights; - } - } - info->PointLight1PositionIdx = getParamIdx("nlPointLight1Position"); - info->PointLight1DiffuseIdx = getParamIdx("nlPointLight1Diffuse"); - if (info->PointLight1PositionIdx == ~0 - || info->PointLight1DiffuseIdx == ~0) - { - nlwarning("Missing 'nlPointLight1Position/nlPointLight1Diffuse' in gpu program '%s', PointLight1 disabled", displayName); - info->Features &= ~CVertexProgramInfo::PointLight1; - } - } - if (features & CVertexProgramInfo::PointLight2) - { - if (features & CVertexProgramInfo::DynamicLights) - { - info->PointLight2EnabledIdx = getParamIdx("nlPointLight2Enabled"); - if (info->PointLight2EnabledIdx == ~0) - { - nlwarning("Missing 'nlPointLight2Enabled' in gpu program '%s', DynamicLights disabled", displayName); - info->Features &= ~CVertexProgramInfo::DynamicLights; - } - } - info->PointLight2PositionIdx = getParamIdx("nlPointLight2Position"); - info->PointLight2DiffuseIdx = getParamIdx("nlPointLight2Diffuse"); - if (info->PointLight2PositionIdx == ~0 - || info->PointLight2DiffuseIdx == ~0) - { - nlwarning("Missing 'nlPointLight2Position/nlPointLight2Diffuse' in gpu program '%s', PointLight2 disabled", displayName); - info->Features &= ~CVertexProgramInfo::PointLight2; - } - } + } } // NL3D From 0bcb0d6ffd43e5d4b35309500616a9995901550f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 20:49:59 +0200 Subject: [PATCH 107/137] Add glsl pixel program for stereo distortion --- code/nel/include/nel/3d/gpu_program.h | 3 + code/nel/include/nel/3d/stereo_ovr.h | 4 +- code/nel/src/3d/gpu_program.cpp | 7 ++ code/nel/src/3d/stereo_ovr.cpp | 161 ++++++++++++++++++++------ code/nel/src/3d/stereo_ovr_fp.cpp | 55 ++++++++- code/snowballs2/bin/pp_oculus_vr.cg | 4 +- 6 files changed, 189 insertions(+), 45 deletions(-) diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index d1b234dee..0d8d30a61 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -266,6 +266,9 @@ public: // Build feature info, called automatically by the driver after compile succeeds void buildInfo(CSource *source); + // Override this to build additional info in a subclass + virtual void buildInfo(); + protected: /// The progam source std::vector > m_Sources; diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index c2dccf930..ba6895bf0 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -66,7 +66,7 @@ class ITexture; class CTextureUser; class CStereoOVRDevicePtr; class CStereoOVRDeviceHandle; -class CPixelProgram; +class CPixelProgramOVR; #define NL_STEREO_MAX_USER_CAMERAS 8 @@ -161,7 +161,7 @@ private: NL3D::UMaterial m_BarrelMat; NLMISC::CQuadUV m_BarrelQuadLeft; NLMISC::CQuadUV m_BarrelQuadRight; - CPixelProgram *m_PixelProgram; + NLMISC::CRefPtr m_PixelProgram; NLMISC::CVector m_EyePosition; float m_Scale; diff --git a/code/nel/src/3d/gpu_program.cpp b/code/nel/src/3d/gpu_program.cpp index 55f07e32b..ee16f1104 100644 --- a/code/nel/src/3d/gpu_program.cpp +++ b/code/nel/src/3d/gpu_program.cpp @@ -204,6 +204,13 @@ void IGPUProgram::buildInfo(CSource *source) features.MaterialFlags &= ~CGPUProgramFeatures::MaterialAmbient; } }*/ + + buildInfo(); +} + +void IGPUProgram::buildInfo() +{ + } } /* namespace NL3D */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index ac2350f3c..cedfe3434 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -72,6 +72,7 @@ namespace NL3D { extern const char *g_StereoOVR_fp40; extern const char *g_StereoOVR_arbfp1; extern const char *g_StereoOVR_ps_2_0; +extern const char *g_StereoOVR_glsl330f; namespace { @@ -233,43 +234,106 @@ CStereoOVR::~CStereoOVR() --s_DeviceCounter; } +class CPixelProgramOVR : public CPixelProgram +{ +public: + struct COVRIndices + { + uint LensCenter; + uint ScreenCenter; + uint Scale; + uint ScaleIn; + uint HmdWarpParam; + }; + + CPixelProgramOVR() + { + { + CSource *source = new CSource(); + source->Profile = glsl330f; + source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_glsl330f); + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = fp40; + source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_fp40); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = arbfp1; + source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_arbfp1); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = ps_2_0; + source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_ps_2_0); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + } + + virtual ~CPixelProgramOVR() + { + + } + + virtual void buildInfo() + { + CPixelProgram::buildInfo(); + + m_OVRIndices.LensCenter = getUniformIndex("cLensCenter"); + nlassert(m_OVRIndices.LensCenter != ~0); + m_OVRIndices.ScreenCenter = getUniformIndex("cScreenCenter"); + nlassert(m_OVRIndices.ScreenCenter != ~0); + m_OVRIndices.Scale = getUniformIndex("cScale"); + nlassert(m_OVRIndices.Scale != ~0); + m_OVRIndices.ScaleIn = getUniformIndex("cScaleIn"); + nlassert(m_OVRIndices.ScaleIn != ~0); + m_OVRIndices.HmdWarpParam = getUniformIndex("cHmdWarpParam"); + nlassert(m_OVRIndices.HmdWarpParam != ~0); + } + + inline const COVRIndices &ovrIndices() { return m_OVRIndices; } + +private: + COVRIndices m_OVRIndices; + +}; + void CStereoOVR::setDriver(NL3D::UDriver *driver) { nlassert(!m_PixelProgram); NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); - m_PixelProgram = new CPixelProgram(); - - IGPUProgram::CSource *source = new IGPUProgram::CSource(); - source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; - source->Profile = IGPUProgram::none; - if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { - nldebug("VR: fp40"); - source->Profile = IGPUProgram::fp40; - source->setSourcePtr(g_StereoOVR_fp40); - m_PixelProgram->addSource(source); - } - else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) - { - nldebug("VR: arbfp1"); - source->Profile = IGPUProgram::arbfp1; - source->setSourcePtr(g_StereoOVR_arbfp1); - m_PixelProgram->addSource(source); - } - else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) - { - nldebug("VR: ps_2_0"); - source->Profile = IGPUProgram::ps_2_0; - source->setSourcePtr(g_StereoOVR_ps_2_0); - m_PixelProgram->addSource(source); - } - - if (!drvInternal->compilePixelProgram(m_PixelProgram)) - { - delete m_PixelProgram; - m_PixelProgram = NULL; + m_PixelProgram = new CPixelProgramOVR(); + if (!drvInternal->compilePixelProgram(m_PixelProgram)) + { + m_PixelProgram.kill(); + } } if (m_PixelProgram) @@ -590,11 +654,27 @@ bool CStereoOVR::endRenderTarget() float scaleInX = (2 / w); float scaleInY = (2 / h); - drvInternal->setUniform2f(IDriver::PixelProgram, 0, lensCenterX, lensCenterY); - drvInternal->setUniform2f(IDriver::PixelProgram, 1, screenCenterX, screenCenterY); - drvInternal->setUniform2f(IDriver::PixelProgram, 2, scaleX, scaleY); - drvInternal->setUniform2f(IDriver::PixelProgram, 3, scaleInX, scaleInY); - drvInternal->setUniform4fv(IDriver::PixelProgram, 4, 1, m_DevicePtr->HMDInfo.DistortionK); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().LensCenter, + lensCenterX, lensCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScreenCenter, + screenCenterX, screenCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().Scale, + scaleX, scaleY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScaleIn, + scaleInX, scaleInY); + + + drvInternal->setUniform4fv(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().HmdWarpParam, + 1, m_DevicePtr->HMDInfo.DistortionK); m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat); @@ -602,8 +682,15 @@ bool CStereoOVR::endRenderTarget() lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f; screenCenterX = x + w * 0.5f; - drvInternal->setUniform2f(IDriver::PixelProgram, 0, lensCenterX, lensCenterY); - drvInternal->setUniform2f(IDriver::PixelProgram, 1, screenCenterX, screenCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().LensCenter, + lensCenterX, lensCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScreenCenter, + screenCenterX, screenCenterY); + m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat); diff --git a/code/nel/src/3d/stereo_ovr_fp.cpp b/code/nel/src/3d/stereo_ovr_fp.cpp index b81ee8421..940be0bfe 100644 --- a/code/nel/src/3d/stereo_ovr_fp.cpp +++ b/code/nel/src/3d/stereo_ovr_fp.cpp @@ -44,7 +44,7 @@ const char *g_StereoOVR_fp40 = //#var float2 cScale : : c[2] : 3 : 1 //#var float2 cScaleIn : : c[3] : 4 : 1 //#var float4 cHmdWarpParam : : c[4] : 5 : 1 - //#var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1 + //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 //#var float4 oCol : $vout.COLOR : COL : 7 : 1 //#const c[5] = 0.25 0.5 0 "PARAM c[6] = { program.env[0..4],\n" // program.local->program.env! @@ -81,6 +81,7 @@ const char *g_StereoOVR_fp40 = "ENDIF;\n" "END\n"; //# 24 instructions, 2 R-regs, 1 H-regs + const char *g_StereoOVR_arbfp1 = "!!ARBfp1.0\n" //# cgc version 3.1.0013, build date Apr 18 2012 @@ -102,7 +103,7 @@ const char *g_StereoOVR_arbfp1 = //#var float2 cScale : : c[2] : 3 : 1 //#var float2 cScaleIn : : c[3] : 4 : 1 //#var float4 cHmdWarpParam : : c[4] : 5 : 1 - //#var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1 + //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 //#var float4 oCol : $vout.COLOR : COL : 7 : 1 //#const c[5] = 0.25 0.5 0 1 "PARAM c[6] = { program.env[0..4],\n" @@ -139,6 +140,7 @@ const char *g_StereoOVR_arbfp1 = "CMP result.color, -R1.x, R0, c[5].z;\n" "END\n"; //# 28 instructions, 2 R-regs + const char *g_StereoOVR_ps_2_0 = "ps_2_0\n" // cgc version 3.1.0013, build date Apr 18 2012 @@ -160,7 +162,7 @@ const char *g_StereoOVR_ps_2_0 = //var float2 cScale : : c[2] : 3 : 1 //var float2 cScaleIn : : c[3] : 4 : 1 //var float4 cHmdWarpParam : : c[4] : 5 : 1 - //var sampler2D cTex0 : TEX0 : texunit 0 : 6 : 1 + //var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 //var float4 oCol : $vout.COLOR : COL : 7 : 1 //const c[5] = -0.25 -0.5 0.25 0.5 //const c[6] = 1 0 @@ -199,4 +201,49 @@ const char *g_StereoOVR_ps_2_0 = "texld r0, r3, s0\n" "cmp r0, -r1.x, r0, c6.y\n" "mov oC0, r0\n"; -} \ No newline at end of file + +const char *g_StereoOVR_glsl330f = + "#version 330\n" + "\n" + "bool _TMP2;\n" + "bvec2 _TMP1;\n" + "vec2 _TMP3;\n" + "uniform vec2 cLensCenter;\n" + "uniform vec2 cScreenCenter;\n" + "uniform vec2 cScale;\n" + "uniform vec2 cScaleIn;\n" + "uniform vec4 cHmdWarpParam;\n" + "uniform sampler2D nlTex0;\n" + "vec2 _TMP10;\n" + "vec2 _b0011;\n" + "vec2 _a0011;\n" + "in vec4 nlTexCoord0;\n" + "out vec4 nlCol;\n" + "\n" + "void main()\n" + "{\n" + " vec2 _theta;\n" + " float _rSq;\n" + " vec2 _theta1;\n" + " vec2 _tc;\n" + "\n" + " _theta = (nlTexCoord0.xy - cLensCenter)*cScaleIn;\n" + " _rSq = _theta.x*_theta.x + _theta.y*_theta.y;\n" + " _theta1 = _theta*(cHmdWarpParam.x + cHmdWarpParam.y*_rSq + cHmdWarpParam.z*_rSq*_rSq + cHmdWarpParam.w*_rSq*_rSq*_rSq);\n" + " _tc = cLensCenter + cScale*_theta1;\n" + " _a0011 = cScreenCenter - vec2( 0.25, 0.5);\n" + " _b0011 = cScreenCenter + vec2( 0.25, 0.5);\n" + " _TMP3 = min(_b0011, _tc);\n" + " _TMP10 = max(_a0011, _TMP3);\n" + " _TMP1 = bvec2(_TMP10.x == _tc.x, _TMP10.y == _tc.y);\n" + " _TMP2 = _TMP1.x && _TMP1.y;\n" + " if (!_TMP2) {\n" + " nlCol = vec4(0, 0, 0, 0);\n" + " } else {\n" + " nlCol = texture(nlTex0, _tc);\n" + " }\n" + "}\n"; + +} + +/* end of file */ diff --git a/code/snowballs2/bin/pp_oculus_vr.cg b/code/snowballs2/bin/pp_oculus_vr.cg index 1d84e0d54..c7de282ef 100644 --- a/code/snowballs2/bin/pp_oculus_vr.cg +++ b/code/snowballs2/bin/pp_oculus_vr.cg @@ -32,7 +32,7 @@ void pp_oculus_vr( uniform float2 cScale, uniform float2 cScaleIn, uniform float4 cHmdWarpParam, - uniform sampler2D cTex0 : TEX0, + uniform sampler2D nlTex0 : TEX0, // Output color out float4 oCol : COLOR) @@ -49,6 +49,6 @@ void pp_oculus_vr( } else { - oCol = tex2D(cTex0, tc); + oCol = tex2D(nlTex0, tc); } } From aa85673b3b248a5e7b812c38d28780ff1609ba72 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 20:55:23 +0200 Subject: [PATCH 108/137] Flag some TODO's --- code/nel/src/3d/bloom_effect.cpp | 2 ++ code/nel/src/3d/landscapevb_allocator.cpp | 4 ++++ code/nel/src/3d/meshvp_wind_tree.cpp | 1 + code/nel/src/3d/vegetable_manager.cpp | 2 +- code/nel/src/3d/water_shape.cpp | 5 +++-- code/ryzom/client/src/decal.cpp | 2 ++ 6 files changed, 13 insertions(+), 3 deletions(-) diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 3eb24518e..23d5c1e18 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -57,6 +57,8 @@ static const char *TextureOffset = static CVertexProgram TextureOffsetVertexProgram(TextureOffset); +// TODO_VP_GLSL + //----------------------------------------------------------------------------------------------------------- diff --git a/code/nel/src/3d/landscapevb_allocator.cpp b/code/nel/src/3d/landscapevb_allocator.cpp index f57d6ef8d..eccfac66e 100644 --- a/code/nel/src/3d/landscapevb_allocator.cpp +++ b/code/nel/src/3d/landscapevb_allocator.cpp @@ -563,6 +563,7 @@ void CLandscapeVBAllocator::setupVBFormatAndVertexProgram(bool withVertexProgr string vpgram= string(NL3D_LandscapeCommonStartProgram) + string(NL3D_LandscapeFar0EndProgram); _VertexProgram[0]= new CVertexProgram(vpgram.c_str()); + // TODO_VP_GLSL } else if(_Type==Far1) { @@ -580,6 +581,7 @@ void CLandscapeVBAllocator::setupVBFormatAndVertexProgram(bool withVertexProgr string vpgram= string(NL3D_LandscapeCommonStartProgram) + string(NL3D_LandscapeFar1EndProgram); _VertexProgram[0]= new CVertexProgram(vpgram.c_str()); + // TODO_VP_GLSL } else { @@ -597,11 +599,13 @@ void CLandscapeVBAllocator::setupVBFormatAndVertexProgram(bool withVertexProgr string vpgram= string(NL3D_LandscapeCommonStartProgram) + string(NL3D_LandscapeTileEndProgram); _VertexProgram[0]= new CVertexProgram(vpgram.c_str()); + // TODO_VP_GLSL // Init the Vertex Program for lightmap pass vpgram= string(NL3D_LandscapeCommonStartProgram) + string(NL3D_LandscapeTileLightMapEndProgram); _VertexProgram[1]= new CVertexProgram(vpgram.c_str()); + // TODO_VP_GLSL } } diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index 579557012..6d7901ec2 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -158,6 +158,7 @@ void CMeshVPWindTree::initInstance(CMeshBaseInstance *mbi) + CRenderTrav::getLightVPFragment(numPls, VPLightConstantStart, specular, normalize) + WindTreeVPCodeEnd; _VertexProgram[i]= std::auto_ptr(new CVertexProgram(vpCode.c_str())); + // TODO_VP_GLSL } } diff --git a/code/nel/src/3d/vegetable_manager.cpp b/code/nel/src/3d/vegetable_manager.cpp index fe1c63dc4..6d9e15752 100644 --- a/code/nel/src/3d/vegetable_manager.cpp +++ b/code/nel/src/3d/vegetable_manager.cpp @@ -602,7 +602,7 @@ void CVegetableManager::initVertexProgram(uint vpType, bool fogEnabled) // create VP. _VertexProgram[vpType][fogEnabled ? 1 : 0] = new CVertexProgram(vpgram.c_str()); - + // TODO_VP_GLSL } diff --git a/code/nel/src/3d/water_shape.cpp b/code/nel/src/3d/water_shape.cpp index 227b85254..bb43dc5f5 100644 --- a/code/nel/src/3d/water_shape.cpp +++ b/code/nel/src/3d/water_shape.cpp @@ -223,6 +223,7 @@ static CVertexProgram *BuildWaterVP(bool diffuseMap, bool bumpMap, bool use2Bump vp += "\nEND"; return new CVertexProgram(vp.c_str()); + // TODO_VP_GLSL } @@ -330,8 +331,8 @@ void CWaterShape::initVertexProgram() _VertexProgramNoBump = std::auto_ptr(BuildWaterVP(false, false, false)); _VertexProgramNoBumpDiffuse = std::auto_ptr(BuildWaterVP(true, false, false)); // no waves - _VertexProgramNoWave.reset(new CVertexProgram(WaterVPNoWave)); - _VertexProgramNoWaveDiffuse.reset(new CVertexProgram(WaterVPNoWaveDiffuse)); + _VertexProgramNoWave.reset(new CVertexProgram(WaterVPNoWave)); // TODO_VP_GLSL + _VertexProgramNoWaveDiffuse.reset(new CVertexProgram(WaterVPNoWaveDiffuse)); // TODO_VP_GLSL created = true; } } diff --git a/code/ryzom/client/src/decal.cpp b/code/ryzom/client/src/decal.cpp index 7aa4b3c3a..da0fdcb82 100644 --- a/code/ryzom/client/src/decal.cpp +++ b/code/ryzom/client/src/decal.cpp @@ -86,6 +86,8 @@ static const char *DecalAttenuationVertexProgramCode = static NL3D::CVertexProgram DecalAttenuationVertexProgram(DecalAttenuationVertexProgramCode); +// TODO_VP_GLSL + typedef CShadowPolyReceiver::CRGBAVertex CRGBAVertex; From 01577f9f958a77be6c9ff11ba5f714560b66a74f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 21:05:12 +0200 Subject: [PATCH 109/137] Implement param storage copy --- code/nel/src/3d/gpu_program_params.cpp | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/code/nel/src/3d/gpu_program_params.cpp b/code/nel/src/3d/gpu_program_params.cpp index 87ba01381..55b14d41f 100644 --- a/code/nel/src/3d/gpu_program_params.cpp +++ b/code/nel/src/3d/gpu_program_params.cpp @@ -53,6 +53,43 @@ CGPUProgramParams::~CGPUProgramParams() } +void CGPUProgramParams::copy(CGPUProgramParams *params) +{ + size_t offset = params->getBegin(); + while (offset != params->getEnd()) + { + uint index = params->getIndexByOffset(offset); + const std::string &name = params->getNameByOffset(offset); + size_t local; + uint size = params->getSizeByOffset(offset); + uint count = params->getCountByOffset(offset); + uint nbComponents = size * count; + if (index) + { + local = allocOffset(index, size, count, params->getTypeByOffset(offset)); + if (!name.empty()) + { + map(index, name); + } + } + else + { + nlassert(!name.empty()); + local = allocOffset(name, size, count, params->getTypeByOffset(offset)); + } + + uint32 *src = params->getPtrUIByOffset(offset); + uint32 *dst = getPtrUIByOffset(local); + + for (uint c = 0; c < nbComponents; ++c) + { + dst[c] = src[c]; + } + + offset = params->getNext(offset); + } +} + void CGPUProgramParams::set1f(uint index, float f0) { float *f = getPtrFByOffset(allocOffset(index, 1, 1, Float)); From 1447e2f2d8a70770b8868cec4917629bb3aaeac6 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 21:44:14 +0200 Subject: [PATCH 110/137] Replace temporary CMaterial code --- code/nel/include/nel/3d/driver.h | 3 + code/nel/include/nel/3d/material.h | 8 +- .../src/3d/driver/direct3d/driver_direct3d.h | 7 ++ .../driver_direct3d_pixel_program.cpp | 2 + .../direct3d/driver_direct3d_uniform.cpp | 19 ++++ .../driver_direct3d_vertex_program.cpp | 2 + code/nel/src/3d/driver/opengl/driver_opengl.h | 5 + .../driver/opengl/driver_opengl_material.cpp | 50 ++++++--- .../driver/opengl/driver_opengl_uniform.cpp | 101 ++++++++++++++++++ code/nel/src/3d/flare_model.cpp | 3 + code/nel/src/3d/scene.cpp | 2 + code/nel/src/3d/stereo_debugger.cpp | 2 +- code/nel/src/3d/stereo_ovr.cpp | 2 +- 13 files changed, 186 insertions(+), 20 deletions(-) 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); From b6fde3c70612575198f77330f198f7e1db72da97 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 23:01:43 +0200 Subject: [PATCH 111/137] Missed file in last commit --- code/nel/include/nel/3d/gpu_program.h | 1 + 1 file changed, 1 insertion(+) diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index 0d8d30a61..ebb06f4c4 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -107,6 +107,7 @@ struct CGPUProgramFeatures { /// Use the CMaterial texture stages as the textures for a Pixel Program TextureStages = 0x00000001, // <- don't remove this one, it's already used, if you want to split them up into the different stages, then it's ok to change it + TextureMatrices = 0x00000002, // // Rough example, modify as necessary. From f46ef4fd0737202f0e85f244f287cf21fc8adfff Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 23:03:52 +0200 Subject: [PATCH 112/137] Fix incorrectly removed line --- code/nel/include/nel/3d/driver.h | 1 + 1 file changed, 1 insertion(+) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 9d4a0e828..36bbae255 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1200,6 +1200,7 @@ public: 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 bool setUniformMaterial(TProgram program, CMaterial &material) = 0; // set all material-specific feature params (based on program->features->MaterialFlags) (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 // @} From 14026e6f08aa58bf1bcaa8d1b87298498c09d6ac Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 23:39:18 +0200 Subject: [PATCH 113/137] Set params from storage --- .../driver/opengl/driver_opengl_uniform.cpp | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) 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 3ba97efd3..a8434b3bc 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -389,7 +389,41 @@ bool CDriverGL::setUniformMaterialInternal(TProgram program, CMaterial &material void CDriverGL::setUniformParams(TProgram program, const CGPUProgramParams ¶ms) { - // todo + IGPUProgram *prog = NULL; + switch (program) + { + case VertexProgram: + prog = _LastSetuppedVP; + break; + case PixelProgram: + prog = _LastSetuppedPP; + break; + } + if (!prog) return; + + size_t offset = params.getBegin(); + while (offset != params.getEnd()) + { + uint size = params.getSizeByOffset(offset); + uint count = params.getCountByOffset(offset); + + nlassert(size == 4 || count == 1); // only support float4 arrays + nlassert(params.getTypeByOffset(offset) == CGPUProgramParams::Float); // only support float + + uint index = params.getIndexByOffset(offset); + if (index == ~0) + { + const std::string &name = params.getNameByOffset(offset); + nlassert(!name.empty() /* missing both parameter name and index, code error */); + uint index = prog->getUniformIndex(name); + nlassert(index != ~0 /* invalid parameter name */); + params.map(index, name); + } + + setUniform4fv(program, index, count, params.getPtrFByOffset(offset)); + + offset = params.getNext(offset); + } } #ifdef NL_STATIC From 680f2608033fc2c07b10616c5b8bf03411d74fc5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 00:31:26 +0200 Subject: [PATCH 114/137] Use CSmartPtr for vertex program --- code/nel/include/nel/3d/gpu_program.h | 5 ++ .../include/nel/3d/meshvp_per_pixel_light.h | 2 +- code/nel/include/nel/3d/meshvp_wind_tree.h | 2 +- code/nel/include/nel/3d/water_shape.h | 16 +++--- .../driver/opengl/driver_opengl_uniform.cpp | 2 +- code/nel/src/3d/gpu_program.cpp | 57 +++++++++++-------- code/nel/src/3d/meshvp_per_pixel_light.cpp | 6 +- code/nel/src/3d/meshvp_wind_tree.cpp | 10 ++-- code/nel/src/3d/water_model.cpp | 6 +- code/nel/src/3d/water_shape.cpp | 32 +++++------ 10 files changed, 77 insertions(+), 61 deletions(-) diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index ebb06f4c4..6ff2ed940 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -86,6 +86,9 @@ struct CGPUProgramFeatures ModelViewProjectionTranspose = 0x00000400, ModelViewProjectionInverseTranspose = 0x00000800, + // Fog + Fog = 0x00001000, + // // Rough example, modify as necessary. // @@ -144,6 +147,8 @@ struct CGPUProgramIndices uint ModelViewProjectionTranspose; uint ModelViewProjectionInverseTranspose; + uint Fog; + // // Rough example, modify as necessary. // diff --git a/code/nel/include/nel/3d/meshvp_per_pixel_light.h b/code/nel/include/nel/3d/meshvp_per_pixel_light.h index d7be0f3f9..5df1bfc16 100644 --- a/code/nel/include/nel/3d/meshvp_per_pixel_light.h +++ b/code/nel/include/nel/3d/meshvp_per_pixel_light.h @@ -84,7 +84,7 @@ private: bool _IsPointLight; // enum { NumVp = 8}; - static std::auto_ptr _VertexProgram[NumVp]; + static NLMISC::CSmartPtr _VertexProgram[NumVp]; }; } // NL3D diff --git a/code/nel/include/nel/3d/meshvp_wind_tree.h b/code/nel/include/nel/3d/meshvp_wind_tree.h index 7553d7cca..4e5d2875a 100644 --- a/code/nel/include/nel/3d/meshvp_wind_tree.h +++ b/code/nel/include/nel/3d/meshvp_wind_tree.h @@ -112,7 +112,7 @@ private: /** The 16 versions: Specular or not (0 or 2), + normalize normal or not (0 or 1). * All multiplied by 4, because support from 0 to 3 pointLights activated. (0.., 4.., 8.., 12..) */ - static std::auto_ptr _VertexProgram[NumVp]; + static NLMISC::CSmartPtr _VertexProgram[NumVp]; // WindTree Time for this mesh param setup. Stored in mesh because same for all instances. float _CurrentTime[HrcDepth]; diff --git a/code/nel/include/nel/3d/water_shape.h b/code/nel/include/nel/3d/water_shape.h index f7a7e1b0b..ae0fda5c6 100644 --- a/code/nel/include/nel/3d/water_shape.h +++ b/code/nel/include/nel/3d/water_shape.h @@ -247,17 +247,17 @@ private: static bool _GridSizeTouched; // - static std::auto_ptr _VertexProgramBump1; - static std::auto_ptr _VertexProgramBump2; + static NLMISC::CSmartPtr _VertexProgramBump1; + static NLMISC::CSmartPtr _VertexProgramBump2; // - static std::auto_ptr _VertexProgramBump1Diffuse; - static std::auto_ptr _VertexProgramBump2Diffuse; + static NLMISC::CSmartPtr _VertexProgramBump1Diffuse; + static NLMISC::CSmartPtr _VertexProgramBump2Diffuse; // - static std::auto_ptr _VertexProgramNoBump; - static std::auto_ptr _VertexProgramNoBumpDiffuse; + static NLMISC::CSmartPtr _VertexProgramNoBump; + static NLMISC::CSmartPtr _VertexProgramNoBumpDiffuse; // - static std::auto_ptr _VertexProgramNoWave; - static std::auto_ptr _VertexProgramNoWaveDiffuse; + static NLMISC::CSmartPtr _VertexProgramNoWave; + static NLMISC::CSmartPtr _VertexProgramNoWaveDiffuse; }; 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 a8434b3bc..6fe7e1f1c 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -415,7 +415,7 @@ void CDriverGL::setUniformParams(TProgram program, const CGPUProgramParams ¶ { const std::string &name = params.getNameByOffset(offset); nlassert(!name.empty() /* missing both parameter name and index, code error */); - uint index = prog->getUniformIndex(name); + uint index = prog->getUniformIndex(name.c_str()); nlassert(index != ~0 /* invalid parameter name */); params.map(index, name); } diff --git a/code/nel/src/3d/gpu_program.cpp b/code/nel/src/3d/gpu_program.cpp index ee16f1104..0ffdb49d9 100644 --- a/code/nel/src/3d/gpu_program.cpp +++ b/code/nel/src/3d/gpu_program.cpp @@ -84,112 +84,121 @@ void IGPUProgram::buildInfo(CSource *source) if (features.DriverFlags & CGPUProgramFeatures::ModelView) { - m_Indices.ModelView = getUniformIndex("nlModelView"); + m_Indices.ModelView = getUniformIndex("modelView"); if (m_Indices.ModelView == ~0) { - nlwarning("Missing 'nlModelView' in gpu program '%s', ModelView disabled", source->DisplayName.c_str()); + nlwarning("Missing 'modelView' in gpu program '%s', ModelView disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ModelView; } } if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverse) { - m_Indices.ModelViewInverse = getUniformIndex("nlModelViewInverse"); + m_Indices.ModelViewInverse = getUniformIndex("modelViewInverse"); if (m_Indices.ModelViewInverse == ~0) { - nlwarning("Missing 'nlModelViewInverse' in gpu program '%s', ModelViewInverse disabled", source->DisplayName.c_str()); + nlwarning("Missing 'modelViewInverse' in gpu program '%s', ModelViewInverse disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ModelViewInverse; } } if (features.DriverFlags & CGPUProgramFeatures::ModelViewTranspose) { - m_Indices.ModelViewTranspose = getUniformIndex("nlModelViewTranspose"); + m_Indices.ModelViewTranspose = getUniformIndex("modelViewTranspose"); if (m_Indices.ModelViewTranspose == ~0) { - nlwarning("Missing 'nlModelViewTranspose' in gpu program '%s', ModelViewTranspose disabled", source->DisplayName.c_str()); + nlwarning("Missing 'modelViewTranspose' in gpu program '%s', ModelViewTranspose disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ModelViewTranspose; } } if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverseTranspose) { - m_Indices.ModelViewInverseTranspose = getUniformIndex("nlModelViewInverseTranspose"); + m_Indices.ModelViewInverseTranspose = getUniformIndex("modelViewInverseTranspose"); if (m_Indices.ModelViewInverseTranspose == ~0) { - nlwarning("Missing 'nlModelViewInverseTranspose' in gpu program '%s', ModelViewInverseTranspose disabled", source->DisplayName.c_str()); + nlwarning("Missing 'modelViewInverseTranspose' in gpu program '%s', ModelViewInverseTranspose disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ModelViewInverseTranspose; } } if (features.DriverFlags & CGPUProgramFeatures::Projection) { - m_Indices.Projection = getUniformIndex("nlProjection"); + m_Indices.Projection = getUniformIndex("projection"); if (m_Indices.Projection == ~0) { - nlwarning("Missing 'nlProjection' in gpu program '%s', Projection disabled", source->DisplayName.c_str()); + nlwarning("Missing 'projection' in gpu program '%s', Projection disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::Projection; } } if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverse) { - m_Indices.ProjectionInverse = getUniformIndex("nlProjectionInverse"); + m_Indices.ProjectionInverse = getUniformIndex("projectionInverse"); if (m_Indices.ProjectionInverse == ~0) { - nlwarning("Missing 'nlProjectionInverse' in gpu program '%s', ProjectionInverse disabled", source->DisplayName.c_str()); + nlwarning("Missing 'projectionInverse' in gpu program '%s', ProjectionInverse disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ProjectionInverse; } } if (features.DriverFlags & CGPUProgramFeatures::ProjectionTranspose) { - m_Indices.ProjectionTranspose = getUniformIndex("nlProjectionTranspose"); + m_Indices.ProjectionTranspose = getUniformIndex("projectionTranspose"); if (m_Indices.ProjectionTranspose == ~0) { - nlwarning("Missing 'nlProjectionTranspose' in gpu program '%s', ProjectionTranspose disabled", source->DisplayName.c_str()); + nlwarning("Missing 'projectionTranspose' in gpu program '%s', ProjectionTranspose disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ProjectionTranspose; } } if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverseTranspose) { - m_Indices.ProjectionInverseTranspose = getUniformIndex("nlProjectionInverseTranspose"); + m_Indices.ProjectionInverseTranspose = getUniformIndex("projectionInverseTranspose"); if (m_Indices.ProjectionInverseTranspose == ~0) { - nlwarning("Missing 'nlProjectionInverseTranspose' in gpu program '%s', ProjectionInverseTranspose disabled", source->DisplayName.c_str()); + nlwarning("Missing 'projectionInverseTranspose' in gpu program '%s', ProjectionInverseTranspose disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ProjectionInverseTranspose; } } if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjection) { - m_Indices.ModelViewProjection = getUniformIndex("nlModelViewProjection"); + m_Indices.ModelViewProjection = getUniformIndex("modelViewProjection"); if (m_Indices.ModelViewProjection == ~0) { - nlwarning("Missing 'nlModelViewProjection' in gpu program '%s', ModelViewProjection disabled", source->DisplayName.c_str()); + nlwarning("Missing 'modelViewProjection' in gpu program '%s', ModelViewProjection disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjection; } } if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverse) { - m_Indices.ModelViewProjectionInverse = getUniformIndex("nlModelViewProjectionInverse"); + m_Indices.ModelViewProjectionInverse = getUniformIndex("modelViewProjectionInverse"); if (m_Indices.ModelViewProjectionInverse == ~0) { - nlwarning("Missing 'nlModelViewProjectionInverse' in gpu program '%s', ModelViewProjectionInverse disabled", source->DisplayName.c_str()); + nlwarning("Missing 'modelViewProjectionInverse' in gpu program '%s', ModelViewProjectionInverse disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionInverse; } } if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionTranspose) { - m_Indices.ModelViewProjectionTranspose = getUniformIndex("nlModelViewProjectionTranspose"); + m_Indices.ModelViewProjectionTranspose = getUniformIndex("modelViewProjectionTranspose"); if (m_Indices.ModelViewProjectionTranspose == ~0) { - nlwarning("Missing 'nlModelViewProjectionTranspose' in gpu program '%s', ModelViewProjectionTranspose disabled", source->DisplayName.c_str()); + nlwarning("Missing 'modelViewProjectionTranspose' in gpu program '%s', ModelViewProjectionTranspose disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionTranspose; } } if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverseTranspose) { - m_Indices.ModelViewProjectionInverseTranspose = getUniformIndex("nlModelViewProjectionInverseTranspose"); + m_Indices.ModelViewProjectionInverseTranspose = getUniformIndex("modelViewProjectionInverseTranspose"); if (m_Indices.ModelViewProjectionInverseTranspose == ~0) { - nlwarning("Missing 'nlModelViewProjectionInverseTranspose' in gpu program '%s', ModelViewProjectionInverseTranspose disabled", source->DisplayName.c_str()); + nlwarning("Missing 'modelViewProjectionInverseTranspose' in gpu program '%s', ModelViewProjectionInverseTranspose disabled", source->DisplayName.c_str()); features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionInverseTranspose; } } + if (features.DriverFlags & CGPUProgramFeatures::Fog) + { + m_Indices.Fog = getUniformIndex("fog"); + if (m_Indices.Fog == ~0) + { + nlwarning("Missing 'fog' in gpu program '%s', Fog disabled", source->DisplayName.c_str()); + features.DriverFlags &= ~CGPUProgramFeatures::Fog; + } + } // // Rough example, modify as necessary. diff --git a/code/nel/src/3d/meshvp_per_pixel_light.cpp b/code/nel/src/3d/meshvp_per_pixel_light.cpp index dd06e951c..e4f43efc5 100644 --- a/code/nel/src/3d/meshvp_per_pixel_light.cpp +++ b/code/nel/src/3d/meshvp_per_pixel_light.cpp @@ -32,7 +32,7 @@ namespace NL3D { -std::auto_ptr CMeshVPPerPixelLight::_VertexProgram[NumVp]; +NLMISC::CSmartPtr CMeshVPPerPixelLight::_VertexProgram[NumVp]; // *************************************************************************** // Light VP fragment constants start at 24 @@ -414,7 +414,7 @@ void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) nlassert(0); } #endif - _VertexProgram[vp]= std::auto_ptr(new CVertexProgram(vpCode.c_str())); + _VertexProgram[vp] = new CVertexProgram(vpCode.c_str()); } } @@ -521,7 +521,7 @@ void CMeshVPPerPixelLight::enable(bool enabled, IDriver *drv) | (SpecularLighting ? 2 : 0) | (_IsPointLight ? 1 : 0); // - drv->activeVertexProgram(_VertexProgram[idVP].get()); + drv->activeVertexProgram(_VertexProgram[idVP]); } else { diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index 6d7901ec2..bf1bc0c4e 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -39,7 +39,7 @@ static const uint VPLightConstantStart= 24; // *************************************************************************** -std::auto_ptr CMeshVPWindTree::_VertexProgram[CMeshVPWindTree::NumVp]; +NLMISC::CSmartPtr CMeshVPWindTree::_VertexProgram[CMeshVPWindTree::NumVp]; static const char* WindTreeVPCodeWave= "!!VP1.0 \n\ @@ -157,7 +157,7 @@ void CMeshVPWindTree::initInstance(CMeshBaseInstance *mbi) vpCode= string(WindTreeVPCodeWave) + CRenderTrav::getLightVPFragment(numPls, VPLightConstantStart, specular, normalize) + WindTreeVPCodeEnd; - _VertexProgram[i]= std::auto_ptr(new CVertexProgram(vpCode.c_str())); + _VertexProgram[i] = new CVertexProgram(vpCode.c_str()); // TODO_VP_GLSL } } @@ -312,7 +312,7 @@ bool CMeshVPWindTree::begin(IDriver *driver, CScene *scene, CMeshBaseInstance *m idVP= numPls*4 + idVP; // activate VP. - driver->activeVertexProgram(_VertexProgram[idVP].get()); + driver->activeVertexProgram(_VertexProgram[idVP]); return true; @@ -383,7 +383,7 @@ void CMeshVPWindTree::beginMBRMesh(IDriver *driver, CScene *scene) _LastMBRIdVP= 0; // activate VP. - driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP].get()); + driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); } // *************************************************************************** @@ -407,7 +407,7 @@ void CMeshVPWindTree::beginMBRInstance(IDriver *driver, CScene *scene, CMeshBase if( idVP!=_LastMBRIdVP ) { _LastMBRIdVP= idVP; - driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP].get()); + driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); } } diff --git a/code/nel/src/3d/water_model.cpp b/code/nel/src/3d/water_model.cpp index e72d7bab9..7ad9274b0 100644 --- a/code/nel/src/3d/water_model.cpp +++ b/code/nel/src/3d/water_model.cpp @@ -908,6 +908,10 @@ void CWaterModel::setupMaterialNVertexShader(IDriver *drv, CWaterShape *shape, c //=========================// // setup Water material // //=========================// + shape->initVertexProgram(); + CVertexProgram *program = shape->_ColorMap ? CWaterShape::_VertexProgramNoWaveDiffuse : CWaterShape::_VertexProgramNoWave; + drv->activeVertexProgram(program); + // TODO_VP_MATERIAL CWaterModel::_WaterMat.setTexture(0, shape->_BumpMap[0]); CWaterModel::_WaterMat.setTexture(1, shape->_BumpMap[1]); CWaterModel::_WaterMat.setTexture(3, shape->_ColorMap); @@ -969,8 +973,6 @@ void CWaterModel::setupMaterialNVertexShader(IDriver *drv, CWaterShape *shape, c cst[10].set(0.5f, 0.5f, 0.f, 1.f); // used to scale reflected ray into the envmap /// set all our constants in one call drv->setConstant(cstOffset, sizeof(cst) / sizeof(cst[0]) - cstOffset, (float *) &cst[cstOffset]); - shape->initVertexProgram(); - drv->activeVertexProgram(shape->_ColorMap ? CWaterShape::_VertexProgramNoWaveDiffuse.get() : CWaterShape::_VertexProgramNoWave.get()); drv->setConstantFog(4); } diff --git a/code/nel/src/3d/water_shape.cpp b/code/nel/src/3d/water_shape.cpp index bb43dc5f5..2376cdfe6 100644 --- a/code/nel/src/3d/water_shape.cpp +++ b/code/nel/src/3d/water_shape.cpp @@ -188,15 +188,15 @@ uint32 CWaterShape::_XGridBorder = 4; uint32 CWaterShape::_YGridBorder = 4; uint32 CWaterShape::_MaxGridSize; bool CWaterShape::_GridSizeTouched = true; -std::auto_ptr CWaterShape::_VertexProgramBump1; -std::auto_ptr CWaterShape::_VertexProgramBump2; -std::auto_ptr CWaterShape::_VertexProgramBump1Diffuse; -std::auto_ptr CWaterShape::_VertexProgramBump2Diffuse; -std::auto_ptr CWaterShape::_VertexProgramNoBump; -std::auto_ptr CWaterShape::_VertexProgramNoBumpDiffuse; +NLMISC::CSmartPtr CWaterShape::_VertexProgramBump1; +NLMISC::CSmartPtr CWaterShape::_VertexProgramBump2; +NLMISC::CSmartPtr CWaterShape::_VertexProgramBump1Diffuse; +NLMISC::CSmartPtr CWaterShape::_VertexProgramBump2Diffuse; +NLMISC::CSmartPtr CWaterShape::_VertexProgramNoBump; +NLMISC::CSmartPtr CWaterShape::_VertexProgramNoBumpDiffuse; // water with no waves -std::auto_ptr CWaterShape::_VertexProgramNoWave; -std::auto_ptr CWaterShape::_VertexProgramNoWaveDiffuse; +NLMISC::CSmartPtr CWaterShape::_VertexProgramNoWave; +NLMISC::CSmartPtr CWaterShape::_VertexProgramNoWaveDiffuse; /** Build a vertex program for water depending on requirements @@ -322,17 +322,17 @@ void CWaterShape::initVertexProgram() if (!created) { // waves - _VertexProgramBump1 = std::auto_ptr(BuildWaterVP(false, true, false)); - _VertexProgramBump2 = std::auto_ptr(BuildWaterVP(false, true, true)); + _VertexProgramBump1 = BuildWaterVP(false, true, false); + _VertexProgramBump2 = BuildWaterVP(false, true, true); - _VertexProgramBump1Diffuse = std::auto_ptr(BuildWaterVP(true, true, false)); - _VertexProgramBump2Diffuse = std::auto_ptr(BuildWaterVP(true, true, true)); + _VertexProgramBump1Diffuse = BuildWaterVP(true, true, false); + _VertexProgramBump2Diffuse = BuildWaterVP(true, true, true); - _VertexProgramNoBump = std::auto_ptr(BuildWaterVP(false, false, false)); - _VertexProgramNoBumpDiffuse = std::auto_ptr(BuildWaterVP(true, false, false)); + _VertexProgramNoBump = BuildWaterVP(false, false, false); + _VertexProgramNoBumpDiffuse = BuildWaterVP(true, false, false); // no waves - _VertexProgramNoWave.reset(new CVertexProgram(WaterVPNoWave)); // TODO_VP_GLSL - _VertexProgramNoWaveDiffuse.reset(new CVertexProgram(WaterVPNoWaveDiffuse)); // TODO_VP_GLSL + _VertexProgramNoWave = new CVertexProgram(WaterVPNoWave); // TODO_VP_GLSL + _VertexProgramNoWaveDiffuse = new CVertexProgram(WaterVPNoWaveDiffuse); // TODO_VP_GLSL created = true; } } From c9a2f9dbfc4fcc28df4d922bf24579ca03a5bce3 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 01:29:53 +0200 Subject: [PATCH 115/137] Some fixes --- code/nel/include/nel/3d/driver.h | 2 +- code/nel/include/nel/3d/gpu_program.h | 4 ++-- code/nel/src/3d/driver/direct3d/driver_direct3d.h | 6 +++--- .../src/3d/driver/direct3d/driver_direct3d_uniform.cpp | 2 +- code/nel/src/3d/driver/opengl/driver_opengl.h | 6 +++--- code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp | 2 +- code/nel/src/3d/gpu_program_params.cpp | 8 ++++++++ 7 files changed, 19 insertions(+), 11 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 36bbae255..9ad704f81 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1201,7 +1201,7 @@ public: // 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 bool setUniformMaterial(TProgram program, CMaterial &material) = 0; // set all material-specific feature params (based on program->features->MaterialFlags) (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 + virtual void setUniformParams(TProgram program, CGPUProgramParams ¶ms) = 0; // set all user-provided params from the storage // @} diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index 6ff2ed940..01a48614b 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -57,7 +57,7 @@ public: // The virtual dtor is important. virtual ~IGPUProgramDrvInfos(void); - virtual uint getUniformIndex(char *name) const = 0; + virtual uint getUniformIndex(const char *name) const = 0; }; #define NL_GPU_PROGRAM_LIGHTS 8 @@ -261,7 +261,7 @@ public: inline void removeSource(size_t i) { nlassert(!m_Source); m_Sources.erase(m_Sources.begin() + i); } // Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0 - inline uint getUniformIndex(char *name) const { return m_DrvInfo->getUniformIndex(name); }; + inline uint getUniformIndex(const char *name) const { return m_DrvInfo->getUniformIndex(name); }; // Get feature information of the current program inline CSource *source() const { return m_Source; }; diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index d360fb915..a7567f0f8 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -309,7 +309,7 @@ public: CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it); ~CVertexProgamDrvInfosD3D(); - virtual uint getUniformIndex(char *name) const + virtual uint getUniformIndex(const char *name) const { std::map::const_iterator it = ParamIndices.find(name); if (it != ParamIndices.end()) return it->second; @@ -331,7 +331,7 @@ public: CPixelProgramDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it); ~CPixelProgramDrvInfosD3D(); - virtual uint getUniformIndex(char *name) const + virtual uint getUniformIndex(const char *name) const { std::map::const_iterator it = ParamIndices.find(name); if (it != ParamIndices.end()) return it->second; @@ -1210,7 +1210,7 @@ public: // 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 + virtual void setUniformParams(TProgram program, CGPUProgramParams ¶ms); // set all user-provided params from the storage // @} 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 2ade8cfb4..78799584d 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp @@ -229,7 +229,7 @@ bool CDriverD3D::setUniformMaterial(TProgram program, const CMaterial &material) return true; } -void CDriverD3D::setUniformParams(TProgram program, const CGPUProgramParams ¶ms) +void CDriverD3D::setUniformParams(TProgram program, CGPUProgramParams ¶ms) { // todo } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 48e50ab8e..aea5b825b 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1417,7 +1417,7 @@ private: 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 + virtual void setUniformParams(TProgram program, CGPUProgramParams ¶ms); // set all user-provided params from the storage // @} @@ -1650,7 +1650,7 @@ public: // The gl id is auto created here. CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); - virtual uint getUniformIndex(char *name) const + virtual uint getUniformIndex(const char *name) const { std::map::const_iterator it = ParamIndices.find(name); if (it != ParamIndices.end()) return it->second; @@ -1670,7 +1670,7 @@ public: // The gl id is auto created here. CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); - virtual uint getUniformIndex(char *name) const + virtual uint getUniformIndex(const char *name) const { std::map::const_iterator it = ParamIndices.find(name); if (it != ParamIndices.end()) return it->second; 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 6fe7e1f1c..164a40558 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -387,7 +387,7 @@ bool CDriverGL::setUniformMaterialInternal(TProgram program, CMaterial &material return true; } -void CDriverGL::setUniformParams(TProgram program, const CGPUProgramParams ¶ms) +void CDriverGL::setUniformParams(TProgram program, CGPUProgramParams ¶ms) { IGPUProgram *prog = NULL; switch (program) diff --git a/code/nel/src/3d/gpu_program_params.cpp b/code/nel/src/3d/gpu_program_params.cpp index 55b14d41f..e196154f8 100644 --- a/code/nel/src/3d/gpu_program_params.cpp +++ b/code/nel/src/3d/gpu_program_params.cpp @@ -533,6 +533,14 @@ size_t CGPUProgramParams::getOffset(uint index) const return m_Map[index]; } +size_t CGPUProgramParams::getOffset(const std::string &name) const +{ + std::map::const_iterator it = m_MapName.find(name); + if (it == m_MapName.end()) + return s_End; + return it->second; +} + /// Remove by offset void CGPUProgramParams::freeOffset(size_t offset) { From dd490a0cc450e614c741771e47b3cea031baaa15 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 02:01:57 +0200 Subject: [PATCH 116/137] Set driver parameters --- .../driver/opengl/driver_opengl_uniform.cpp | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) 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 164a40558..382d2bd8a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -309,7 +309,58 @@ bool CDriverGL::setUniformDriver(TProgram program) if (features.DriverFlags) { - // todo + if (features.DriverFlags & CGPUProgramFeatures::ModelView) + { + setUniformMatrix(program, prog->indices().ModelView, ModelView, Identity); + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverse) + { + setUniformMatrix(program, prog->indices().ModelViewInverse, ModelView, Inverse); + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewTranspose) + { + setUniformMatrix(program, prog->indices().ModelViewTranspose, ModelView, Transpose); + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverseTranspose) + { + setUniformMatrix(program, prog->indices().ModelViewInverseTranspose, ModelView, InverseTranspose); + } + if (features.DriverFlags & CGPUProgramFeatures::Projection) + { + setUniformMatrix(program, prog->indices().Projection, Projection, Identity); + } + if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverse) + { + setUniformMatrix(program, prog->indices().ProjectionInverse, Projection, Inverse); + } + if (features.DriverFlags & CGPUProgramFeatures::ProjectionTranspose) + { + setUniformMatrix(program, prog->indices().ProjectionTranspose, Projection, Transpose); + } + if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverseTranspose) + { + setUniformMatrix(program, prog->indices().ProjectionInverseTranspose, Projection, InverseTranspose); + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjection) + { + setUniformMatrix(program, prog->indices().ModelViewProjection, ModelViewProjection, Identity); + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverse) + { + setUniformMatrix(program, prog->indices().ModelViewProjectionInverse, ModelViewProjection, Inverse); + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionTranspose) + { + setUniformMatrix(program, prog->indices().ModelViewProjectionTranspose, ModelViewProjection, Transpose); + } + if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverseTranspose) + { + setUniformMatrix(program, prog->indices().ModelViewProjectionInverseTranspose, ModelViewProjection, InverseTranspose); + } + if (features.DriverFlags & CGPUProgramFeatures::Fog) + { + setUniformFog(program, prog->indices().Fog); + } } return true; From 32288eabe884851a432b616bd876c71d892faeaf Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 02:07:16 +0200 Subject: [PATCH 117/137] Use new program interface for water vertex program --- code/nel/include/nel/3d/water_shape.h | 27 ++++++++++- code/nel/src/3d/water_model.cpp | 29 +++++------- code/nel/src/3d/water_shape.cpp | 68 +++++++++++++++++++++++++-- 3 files changed, 101 insertions(+), 23 deletions(-) diff --git a/code/nel/include/nel/3d/water_shape.h b/code/nel/include/nel/3d/water_shape.h index ae0fda5c6..94bdabea1 100644 --- a/code/nel/include/nel/3d/water_shape.h +++ b/code/nel/include/nel/3d/water_shape.h @@ -49,6 +49,29 @@ const NLMISC::CClassId WaveMakerModelClassId = NLMISC::CClassId(0x16da3356, 0x7 const uint WATER_VERTEX_HARD_SIZE = sizeof(float[3]); const uint WATER_VERTEX_SOFT_SIZE = sizeof(float[5]); +// VP Water No Wave +class CVertexProgramWaterVPNoWave : public CVertexProgram +{ +public: + struct CIdx + { + uint BumpMap0Scale; + uint BumpMap0Offset; + uint BumpMap1Scale; + uint BumpMap1Offset; + uint ObserverHeight; + uint ScaleReflectedRay; + uint DiffuseMapVector0; + uint DiffuseMapVector1; + }; + CVertexProgramWaterVPNoWave(bool diffuse); + virtual ~CVertexProgramWaterVPNoWave() { } + virtual void buildInfo(); + inline const CIdx &idx() const { return m_Idx; } +private: + CIdx m_Idx; + bool m_Diffuse; +}; /** * A water shape. @@ -256,8 +279,8 @@ private: static NLMISC::CSmartPtr _VertexProgramNoBump; static NLMISC::CSmartPtr _VertexProgramNoBumpDiffuse; // - static NLMISC::CSmartPtr _VertexProgramNoWave; - static NLMISC::CSmartPtr _VertexProgramNoWaveDiffuse; + static NLMISC::CSmartPtr _VertexProgramNoWave; + static NLMISC::CSmartPtr _VertexProgramNoWaveDiffuse; }; diff --git a/code/nel/src/3d/water_model.cpp b/code/nel/src/3d/water_model.cpp index 7ad9274b0..3614d0905 100644 --- a/code/nel/src/3d/water_model.cpp +++ b/code/nel/src/3d/water_model.cpp @@ -903,15 +903,12 @@ void CWaterModel::setupMaterialNVertexShader(IDriver *drv, CWaterShape *shape, c _WaterMat.setZWrite(true); _WaterMat.setShader(CMaterial::Water); } - const uint cstOffset = 5; // 4 places for the matrix - NLMISC::CVectorH cst[13]; //=========================// // setup Water material // //=========================// shape->initVertexProgram(); - CVertexProgram *program = shape->_ColorMap ? CWaterShape::_VertexProgramNoWaveDiffuse : CWaterShape::_VertexProgramNoWave; + CVertexProgramWaterVPNoWave *program = shape->_ColorMap ? CWaterShape::_VertexProgramNoWaveDiffuse : CWaterShape::_VertexProgramNoWave; drv->activeVertexProgram(program); - // TODO_VP_MATERIAL CWaterModel::_WaterMat.setTexture(0, shape->_BumpMap[0]); CWaterModel::_WaterMat.setTexture(1, shape->_BumpMap[1]); CWaterModel::_WaterMat.setTexture(3, shape->_ColorMap); @@ -957,23 +954,21 @@ void CWaterModel::setupMaterialNVertexShader(IDriver *drv, CWaterShape *shape, c { // setup 2x3 matrix for lookup in diffuse map updateDiffuseMapMatrix(); - cst[11].set(_ColorMapMatColumn0.x, _ColorMapMatColumn1.x, 0, _ColorMapMatColumn0.x * obsPos.x + _ColorMapMatColumn1.x * obsPos.y + _ColorMapMatPos.x); - cst[12].set(_ColorMapMatColumn0.y, _ColorMapMatColumn1.y, 0, _ColorMapMatColumn0.y * obsPos.x + _ColorMapMatColumn1.y * obsPos.y + _ColorMapMatPos.y); + drv->setUniform4f(IDriver::VertexProgram, program->idx().DiffuseMapVector0, _ColorMapMatColumn0.x, _ColorMapMatColumn1.x, 0, _ColorMapMatColumn0.x * obsPos.x + _ColorMapMatColumn1.x * obsPos.y + _ColorMapMatPos.x); + drv->setUniform4f(IDriver::VertexProgram, program->idx().DiffuseMapVector1, _ColorMapMatColumn0.y, _ColorMapMatColumn1.y, 0, _ColorMapMatColumn0.y * obsPos.x + _ColorMapMatColumn1.y * obsPos.y + _ColorMapMatPos.y); } - /// set matrix - drv->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); + /// temp + // drv->setUniformMatrix(IDriver::VertexProgram, program->indices().ModelViewProjection, IDriver::ModelViewProjection, IDriver::Identity); // now set by setUniformDriver in setupMaterial + // drv->setUniformFog(IDriver::VertexProgram, program->indices().Fog); // now set by setUniformDriver in setupMaterial // retrieve current time double date = scene->getCurrentTime(); // set bumpmaps pos - cst[6].set(fmodf(obsPos.x * shape->_HeightMapScale[0].x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].x, 1), fmodf(shape->_HeightMapScale[0].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].y, 1), 0.f, 1.f); // bump map 0 offset - cst[5].set(shape->_HeightMapScale[0].x, shape->_HeightMapScale[0].y, 0, 0); // bump map 0 scale - cst[8].set(fmodf(shape->_HeightMapScale[1].x * obsPos.x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].x, 1), fmodf(shape->_HeightMapScale[1].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].y, 1), 0.f, 1.f); // bump map 1 offset - cst[7].set(shape->_HeightMapScale[1].x, shape->_HeightMapScale[1].y, 0, 0); // bump map 1 scale - cst[9].set(0, 0, obsPos.z - zHeight, 1.f); - cst[10].set(0.5f, 0.5f, 0.f, 1.f); // used to scale reflected ray into the envmap - /// set all our constants in one call - drv->setConstant(cstOffset, sizeof(cst) / sizeof(cst[0]) - cstOffset, (float *) &cst[cstOffset]); - drv->setConstantFog(4); + drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap0Offset, fmodf(obsPos.x * shape->_HeightMapScale[0].x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].x, 1), fmodf(shape->_HeightMapScale[0].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].y, 1), 0.f, 1.f); // bump map 0 offset + drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap0Scale, shape->_HeightMapScale[0].x, shape->_HeightMapScale[0].y, 0, 0); // bump map 0 scale + drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap1Offset, fmodf(shape->_HeightMapScale[1].x * obsPos.x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].x, 1), fmodf(shape->_HeightMapScale[1].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].y, 1), 0.f, 1.f); // bump map 1 offset + drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap1Scale, shape->_HeightMapScale[1].x, shape->_HeightMapScale[1].y, 0, 0); // bump map 1 scale + drv->setUniform4f(IDriver::VertexProgram, program->idx().ObserverHeight, 0, 0, obsPos.z - zHeight, 1.f); + drv->setUniform4f(IDriver::VertexProgram, program->idx().ScaleReflectedRay, 0.5f, 0.5f, 0.f, 1.f); // used to scale reflected ray into the envmap } //================================================ diff --git a/code/nel/src/3d/water_shape.cpp b/code/nel/src/3d/water_shape.cpp index 2376cdfe6..ac586d168 100644 --- a/code/nel/src/3d/water_shape.cpp +++ b/code/nel/src/3d/water_shape.cpp @@ -81,7 +81,67 @@ DP4 o[TEX3].x, v[0], c[11]; #compute uv for diffuse texture \n\ DP4 o[TEX3].y, v[0], c[12]; \n\ END"; +CVertexProgramWaterVPNoWave::CVertexProgramWaterVPNoWave(bool diffuse) +{ + m_Diffuse = diffuse; + // nelvp + { + CSource *source = new CSource(); + source->Profile = nelvp; + source->DisplayName = "WaterVPNoWave/nelvp"; + source->Features.DriverFlags = + CGPUProgramFeatures::ModelViewProjection + | CGPUProgramFeatures::Fog; + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["fog"] = 4; + source->ParamIndices["bumpMap0Scale"] = 5; + source->ParamIndices["bumpMap0Offset"] = 6; + source->ParamIndices["bumpMap1Scale"] = 7; + source->ParamIndices["bumpMap1Offset"] = 8; + source->ParamIndices["observerHeight"] = 9; + source->ParamIndices["scaleReflectedRay"] = 10; + if (diffuse) + { + source->DisplayName += "/diffuse"; + source->ParamIndices["diffuseMapVector0"] = 11; + source->ParamIndices["diffuseMapVector1"] = 12; + source->setSourcePtr(WaterVPNoWaveDiffuse); + } + else + { + source->setSourcePtr(WaterVPNoWave); + } + addSource(source); + } + // glsl330v + { + // TODO_VP_GLSL + // CSource *source = new CSource(); + // source->Profile = glsl330v; + // source->DisplayName = "WaterVPNoWave/glsl330v"; + // if (diffuse) source->DisplayName += "/diffuse"; + // source->Features.DriverFlags = + // CGPUProgramFeatures::ModelViewProjection + // | CGPUProgramFeatures::Fog; + // source->setSource... + // addSource(source); + } +} +void CVertexProgramWaterVPNoWave::buildInfo() +{ + m_Idx.BumpMap0Scale = getUniformIndex("bumpMap0Scale"); + m_Idx.BumpMap0Offset = getUniformIndex("bumpMap0Offset"); + m_Idx.BumpMap1Scale = getUniformIndex("bumpMap1Scale"); + m_Idx.BumpMap1Offset = getUniformIndex("bumpMap1Offset"); + m_Idx.ObserverHeight = getUniformIndex("observerHeight"); + m_Idx.ScaleReflectedRay = getUniformIndex("scaleReflectedRay"); + if (m_Diffuse) + { + m_Idx.DiffuseMapVector0 = getUniformIndex("diffuseMapVector0"); + m_Idx.DiffuseMapVector1 = getUniformIndex("diffuseMapVector1"); + } +} //////////////// // WAVY WATER // @@ -195,8 +255,8 @@ NLMISC::CSmartPtr CWaterShape::_VertexProgramBump2Diffuse; NLMISC::CSmartPtr CWaterShape::_VertexProgramNoBump; NLMISC::CSmartPtr CWaterShape::_VertexProgramNoBumpDiffuse; // water with no waves -NLMISC::CSmartPtr CWaterShape::_VertexProgramNoWave; -NLMISC::CSmartPtr CWaterShape::_VertexProgramNoWaveDiffuse; +NLMISC::CSmartPtr CWaterShape::_VertexProgramNoWave; +NLMISC::CSmartPtr CWaterShape::_VertexProgramNoWaveDiffuse; /** Build a vertex program for water depending on requirements @@ -331,8 +391,8 @@ void CWaterShape::initVertexProgram() _VertexProgramNoBump = BuildWaterVP(false, false, false); _VertexProgramNoBumpDiffuse = BuildWaterVP(true, false, false); // no waves - _VertexProgramNoWave = new CVertexProgram(WaterVPNoWave); // TODO_VP_GLSL - _VertexProgramNoWaveDiffuse = new CVertexProgram(WaterVPNoWaveDiffuse); // TODO_VP_GLSL + _VertexProgramNoWave = new CVertexProgramWaterVPNoWave(false); + _VertexProgramNoWaveDiffuse = new CVertexProgramWaterVPNoWave(true); // TODO_VP_GLSL created = true; } } From 4de5eeb586157d4baba09650c9336edbf073197b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 15:42:42 +0200 Subject: [PATCH 118/137] Adjust landscape vertex program to use new interface --- code/nel/include/nel/3d/driver.h | 2 + code/nel/include/nel/3d/gpu_program.h | 98 ++++------- .../include/nel/3d/landscapevb_allocator.h | 26 ++- .../src/3d/driver/direct3d/driver_direct3d.h | 1 + .../direct3d/driver_direct3d_uniform.cpp | 2 +- code/nel/src/3d/driver/opengl/driver_opengl.h | 1 + .../driver/opengl/driver_opengl_uniform.cpp | 28 ++-- code/nel/src/3d/gpu_program.cpp | 154 +++--------------- code/nel/src/3d/landscape.cpp | 35 ++-- code/nel/src/3d/landscapevb_allocator.cpp | 96 ++++++++--- code/nel/src/3d/water_model.cpp | 6 +- code/nel/src/3d/water_shape.cpp | 6 - 12 files changed, 199 insertions(+), 256 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 9ad704f81..a97606a97 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1202,6 +1202,8 @@ public: 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 bool setUniformMaterial(TProgram program, CMaterial &material) = 0; // set all material-specific feature params (based on program->features->MaterialFlags) (called automatically when rendering with cmaterial and using a user program) virtual void setUniformParams(TProgram program, CGPUProgramParams ¶ms) = 0; // set all user-provided params from the storage + // Return true if uniforms are kept as program state and switched together with programs, false if uniforms are driver state and stay accross program switches. + virtual bool isUniformProgramState() = 0; // @} diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index 01a48614b..30fa23c52 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -60,12 +60,13 @@ public: virtual uint getUniformIndex(const char *name) const = 0; }; -#define NL_GPU_PROGRAM_LIGHTS 8 - -/// Features exposed by a program. Used to set builtin parameters on user provided shaders +// Features exposed by a program. Used to set builtin parameters on user provided shaders. +// This is only used for user provided shaders, not for builtin shaders, +// as it is a slow method which has to go through all of the options every time. +// Builtin shaders should set all flags to 0. struct CGPUProgramFeatures { - CGPUProgramFeatures() : DriverFlags(0), MaterialFlags(0) /*, NumLights(0) */ { } + CGPUProgramFeatures() : DriverFlags(0), MaterialFlags(0) { } // Driver builtin parameters enum TDriverFlags @@ -73,11 +74,11 @@ struct CGPUProgramFeatures // Matrices ModelView = 0x00000001, ModelViewInverse = 0x00000002, - ModelViewTranspose = 0x00000004, + ModelViewTranspose = 0x00000004, ModelViewInverseTranspose = 0x00000008, Projection = 0x00000010, - ProjectionInverse = 0x00000020, + ProjectionInverse = 0x00000020, ProjectionTranspose = 0x00000040, ProjectionInverseTranspose = 0x00000080, @@ -88,84 +89,54 @@ struct CGPUProgramFeatures // Fog Fog = 0x00001000, - - // - // Rough example, modify as necessary. - // - - // Lighting (todo) - /// Driver ambient, must be ignored when material ambient is flagged - //DriverAmbient = 0x00001000, - /// Lights, does not set diffuses if material lights is flagged - //DriverLights = 0x00002000, - // etcetera - - // Fog (todo) - // Fog = ..., }; uint32 DriverFlags; - // uint NumLights; // number of lights supported by the program (not used yet, modify as necessary) + // uint NumLights; enum TMaterialFlags { /// Use the CMaterial texture stages as the textures for a Pixel Program - TextureStages = 0x00000001, // <- don't remove this one, it's already used, if you want to split them up into the different stages, then it's ok to change it + TextureStages = 0x00000001, TextureMatrices = 0x00000002, - - // - // Rough example, modify as necessary. - // - - // Lighting (todo) - /// Material ambient premultiplied with driver ambient - //MaterialAmbient = 0x00000002, - /// Premultiply lights diffuse with material diffuse, requires driver lights to be flagged - //MaterialLights = 0x00000004, - // etcetera - - // Add all necessary feature sets used with builtin materials here }; // Material builtin parameters uint32 MaterialFlags; }; -/// Stucture used to cache the indices of builtin parameters -struct CGPUProgramIndices +// Stucture used to cache the indices of builtin parameters which are used by the drivers +// Not used for parameters of specific nl3d programs +struct CGPUProgramIndex { - uint ModelView; - uint ModelViewInverse; - uint ModelViewTranspose; - uint ModelViewInverseTranspose; + enum TName + { + ModelView, + ModelViewInverse, + ModelViewTranspose, + ModelViewInverseTranspose, - uint Projection; - uint ProjectionInverse; - uint ProjectionTranspose; - uint ProjectionInverseTranspose; + Projection, + ProjectionInverse, + ProjectionTranspose, + ProjectionInverseTranspose, - uint ModelViewProjection; - uint ModelViewProjectionInverse; - uint ModelViewProjectionTranspose; - uint ModelViewProjectionInverseTranspose; + ModelViewProjection, + ModelViewProjectionInverse, + ModelViewProjectionTranspose, + ModelViewProjectionInverseTranspose, - uint Fog; + Fog, - // - // Rough example, modify as necessary. - // - //uint Ambient; - - //uint LightType[NL_GPU_PROGRAM_LIGHTS]; - //uint LightAmbient[NL_GPU_PROGRAM_LIGHTS]; - //uint LightDiffuse[NL_GPU_PROGRAM_LIGHTS]; - //uint LightPosition[NL_GPU_PROGRAM_LIGHTS]; - //uint LightDirection[NL_GPU_PROGRAM_LIGHTS]; + NUM_UNIFORMS + }; + static const char *Names[NUM_UNIFORMS]; + uint Indices[NUM_UNIFORMS]; }; /** * \brief IGPUProgram * \date 2013-09-07 15:00GMT * \author Jan Boon (Kaetemi) - * A compiled GPU program + * A generic GPU program */ class IGPUProgram : public NLMISC::CRefCount { @@ -234,6 +205,7 @@ public: const char *SourcePtr; size_t SourceLen; /// Copy the source code string + inline void setSource(const std::string &source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); } inline void setSource(const char *source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); } /// Set pointer to source code string without copying the string inline void setSourcePtr(const char *sourcePtr, size_t sourceLen) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = sourceLen; } @@ -262,11 +234,11 @@ public: // Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0 inline uint getUniformIndex(const char *name) const { return m_DrvInfo->getUniformIndex(name); }; + inline uint getUniformIndex(CGPUProgramIndex::TName name) const { return m_Index.Indices[name]; } // Get feature information of the current program inline CSource *source() const { return m_Source; }; inline const CGPUProgramFeatures &features() const { return m_Source->Features; }; - inline const CGPUProgramIndices &indices() const { return m_Indices; }; inline TProfile profile() const { return m_Source->Profile; } // Build feature info, called automatically by the driver after compile succeeds @@ -281,7 +253,7 @@ protected: /// The source used for compilation NLMISC::CSmartPtr m_Source; - CGPUProgramIndices m_Indices; + CGPUProgramIndex m_Index; public: /// The driver information. For the driver implementation only. diff --git a/code/nel/include/nel/3d/landscapevb_allocator.h b/code/nel/include/nel/3d/landscapevb_allocator.h index d3a081e7b..0e485e990 100644 --- a/code/nel/include/nel/3d/landscapevb_allocator.h +++ b/code/nel/include/nel/3d/landscapevb_allocator.h @@ -21,6 +21,7 @@ #include "nel/misc/smart_ptr.h" #include "nel/3d/tessellation.h" #include "nel/3d/vertex_buffer.h" +#include "nel/3d/vertex_program.h" namespace NL3D @@ -41,6 +42,7 @@ class CVertexProgram; #define NL3D_LANDSCAPE_VPPOS_DELTAPOS (CVertexBuffer::TexCoord3) #define NL3D_LANDSCAPE_VPPOS_ALPHAINFO (CVertexBuffer::TexCoord4) +class CVertexProgramLandscape; // *************************************************************************** /** @@ -107,6 +109,8 @@ public: * Give a vertexProgram Id to activate. Always 0, but 1 For tile Lightmap Pass. */ void activate(uint vpId); + void activateVP(uint vpId); + inline CVertexProgramLandscape *getVP(uint vpId) const { return _VertexProgram[vpId]; } // @} @@ -151,15 +155,35 @@ private: /// \name Vertex Program mgt . // @{ +public: enum {MaxVertexProgram= 2,}; // Vertex Program , NULL if not enabled. - CVertexProgram *_VertexProgram[MaxVertexProgram]; +private: + NLMISC::CSmartPtr _VertexProgram[MaxVertexProgram]; void deleteVertexProgram(); void setupVBFormatAndVertexProgram(bool withVertexProgram); // @} }; +class CVertexProgramLandscape : public CVertexProgram +{ +public: + struct CIdx + { + uint ProgramConstants0; + uint RefineCenter; + uint TileDist; + uint PZBModelPosition; + }; + CVertexProgramLandscape(CLandscapeVBAllocator::TType type, bool lightMap = false); + virtual ~CVertexProgramLandscape() { } + virtual void buildInfo(); +public: + const CIdx &idx() const { return m_Idx; } + CIdx m_Idx; +}; + } // NL3D diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index a7567f0f8..b3a8f5f37 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -1211,6 +1211,7 @@ public: 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, CGPUProgramParams ¶ms); // set all user-provided params from the storage + virtual bool isUniformProgramState() { return false; } // @} 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 78799584d..a77a86549 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp @@ -222,7 +222,7 @@ bool CDriverD3D::setUniformDriver(TProgram program) return true; } -bool CDriverD3D::setUniformMaterial(TProgram program, const CMaterial &material) +bool CDriverD3D::setUniformMaterial(TProgram program, CMaterial &material) { // todo diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index aea5b825b..e20d7d4fa 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1418,6 +1418,7 @@ private: 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, CGPUProgramParams ¶ms); // set all user-provided params from the storage + virtual bool isUniformProgramState() { return false; } // @} 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 382d2bd8a..a23235d06 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -311,55 +311,55 @@ bool CDriverGL::setUniformDriver(TProgram program) { if (features.DriverFlags & CGPUProgramFeatures::ModelView) { - setUniformMatrix(program, prog->indices().ModelView, ModelView, Identity); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelView), ModelView, Identity); } if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverse) { - setUniformMatrix(program, prog->indices().ModelViewInverse, ModelView, Inverse); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewInverse), ModelView, Inverse); } if (features.DriverFlags & CGPUProgramFeatures::ModelViewTranspose) { - setUniformMatrix(program, prog->indices().ModelViewTranspose, ModelView, Transpose); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewTranspose), ModelView, Transpose); } if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverseTranspose) { - setUniformMatrix(program, prog->indices().ModelViewInverseTranspose, ModelView, InverseTranspose); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewInverseTranspose), ModelView, InverseTranspose); } if (features.DriverFlags & CGPUProgramFeatures::Projection) { - setUniformMatrix(program, prog->indices().Projection, Projection, Identity); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::Projection), Projection, Identity); } if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverse) { - setUniformMatrix(program, prog->indices().ProjectionInverse, Projection, Inverse); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionInverse), Projection, Inverse); } if (features.DriverFlags & CGPUProgramFeatures::ProjectionTranspose) { - setUniformMatrix(program, prog->indices().ProjectionTranspose, Projection, Transpose); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionTranspose), Projection, Transpose); } if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverseTranspose) { - setUniformMatrix(program, prog->indices().ProjectionInverseTranspose, Projection, InverseTranspose); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionInverseTranspose), Projection, InverseTranspose); } if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjection) { - setUniformMatrix(program, prog->indices().ModelViewProjection, ModelViewProjection, Identity); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjection), ModelViewProjection, Identity); } if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverse) { - setUniformMatrix(program, prog->indices().ModelViewProjectionInverse, ModelViewProjection, Inverse); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverse), ModelViewProjection, Inverse); } if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionTranspose) { - setUniformMatrix(program, prog->indices().ModelViewProjectionTranspose, ModelViewProjection, Transpose); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionTranspose), ModelViewProjection, Transpose); } if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverseTranspose) { - setUniformMatrix(program, prog->indices().ModelViewProjectionInverseTranspose, ModelViewProjection, InverseTranspose); + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverseTranspose), ModelViewProjection, InverseTranspose); } if (features.DriverFlags & CGPUProgramFeatures::Fog) { - setUniformFog(program, prog->indices().Fog); + setUniformFog(program, prog->getUniformIndex(CGPUProgramIndex::Fog)); } } @@ -432,7 +432,7 @@ bool CDriverGL::setUniformMaterialInternal(TProgram program, CMaterial &material if (features.MaterialFlags & ~(CGPUProgramFeatures::TextureStages | CGPUProgramFeatures::TextureMatrices)) { - // todo + // none } return true; diff --git a/code/nel/src/3d/gpu_program.cpp b/code/nel/src/3d/gpu_program.cpp index 0ffdb49d9..4e5916398 100644 --- a/code/nel/src/3d/gpu_program.cpp +++ b/code/nel/src/3d/gpu_program.cpp @@ -72,6 +72,26 @@ IGPUProgram::~IGPUProgram() m_DrvInfo.kill(); } +const char *CGPUProgramIndex::Names[NUM_UNIFORMS] = +{ + "modelView", + "modelViewInverse", + "modelViewTranspose", + "modelViewInverseTranspose", + + "projection", + "projectionInverse", + "projectionTranspose", + "projectionInverseTranspose", + + "modelViewProjection", + "modelViewProjectionInverse", + "modelViewProjectionTranspose", + "modelViewProjectionInverseTranspose", + + "fog", +}; + void IGPUProgram::buildInfo(CSource *source) { nlassert(!m_Source); @@ -79,140 +99,10 @@ void IGPUProgram::buildInfo(CSource *source) m_Source = source; // Fill index cache - CGPUProgramFeatures &features = m_Source->Features; - TProfile profile = m_Source->Profile; // for special cases - - if (features.DriverFlags & CGPUProgramFeatures::ModelView) + for (int i = 0; i < CGPUProgramIndex::NUM_UNIFORMS; ++i) { - m_Indices.ModelView = getUniformIndex("modelView"); - if (m_Indices.ModelView == ~0) - { - nlwarning("Missing 'modelView' in gpu program '%s', ModelView disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ModelView; - } + m_Index.Indices[i] = getUniformIndex(m_Index.Names[i]); } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverse) - { - m_Indices.ModelViewInverse = getUniformIndex("modelViewInverse"); - if (m_Indices.ModelViewInverse == ~0) - { - nlwarning("Missing 'modelViewInverse' in gpu program '%s', ModelViewInverse disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ModelViewInverse; - } - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewTranspose) - { - m_Indices.ModelViewTranspose = getUniformIndex("modelViewTranspose"); - if (m_Indices.ModelViewTranspose == ~0) - { - nlwarning("Missing 'modelViewTranspose' in gpu program '%s', ModelViewTranspose disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ModelViewTranspose; - } - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverseTranspose) - { - m_Indices.ModelViewInverseTranspose = getUniformIndex("modelViewInverseTranspose"); - if (m_Indices.ModelViewInverseTranspose == ~0) - { - nlwarning("Missing 'modelViewInverseTranspose' in gpu program '%s', ModelViewInverseTranspose disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ModelViewInverseTranspose; - } - } - if (features.DriverFlags & CGPUProgramFeatures::Projection) - { - m_Indices.Projection = getUniformIndex("projection"); - if (m_Indices.Projection == ~0) - { - nlwarning("Missing 'projection' in gpu program '%s', Projection disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::Projection; - } - } - if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverse) - { - m_Indices.ProjectionInverse = getUniformIndex("projectionInverse"); - if (m_Indices.ProjectionInverse == ~0) - { - nlwarning("Missing 'projectionInverse' in gpu program '%s', ProjectionInverse disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ProjectionInverse; - } - } - if (features.DriverFlags & CGPUProgramFeatures::ProjectionTranspose) - { - m_Indices.ProjectionTranspose = getUniformIndex("projectionTranspose"); - if (m_Indices.ProjectionTranspose == ~0) - { - nlwarning("Missing 'projectionTranspose' in gpu program '%s', ProjectionTranspose disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ProjectionTranspose; - } - } - if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverseTranspose) - { - m_Indices.ProjectionInverseTranspose = getUniformIndex("projectionInverseTranspose"); - if (m_Indices.ProjectionInverseTranspose == ~0) - { - nlwarning("Missing 'projectionInverseTranspose' in gpu program '%s', ProjectionInverseTranspose disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ProjectionInverseTranspose; - } - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjection) - { - m_Indices.ModelViewProjection = getUniformIndex("modelViewProjection"); - if (m_Indices.ModelViewProjection == ~0) - { - nlwarning("Missing 'modelViewProjection' in gpu program '%s', ModelViewProjection disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjection; - } - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverse) - { - m_Indices.ModelViewProjectionInverse = getUniformIndex("modelViewProjectionInverse"); - if (m_Indices.ModelViewProjectionInverse == ~0) - { - nlwarning("Missing 'modelViewProjectionInverse' in gpu program '%s', ModelViewProjectionInverse disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionInverse; - } - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionTranspose) - { - m_Indices.ModelViewProjectionTranspose = getUniformIndex("modelViewProjectionTranspose"); - if (m_Indices.ModelViewProjectionTranspose == ~0) - { - nlwarning("Missing 'modelViewProjectionTranspose' in gpu program '%s', ModelViewProjectionTranspose disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionTranspose; - } - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverseTranspose) - { - m_Indices.ModelViewProjectionInverseTranspose = getUniformIndex("modelViewProjectionInverseTranspose"); - if (m_Indices.ModelViewProjectionInverseTranspose == ~0) - { - nlwarning("Missing 'modelViewProjectionInverseTranspose' in gpu program '%s', ModelViewProjectionInverseTranspose disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionInverseTranspose; - } - } - if (features.DriverFlags & CGPUProgramFeatures::Fog) - { - m_Indices.Fog = getUniformIndex("fog"); - if (m_Indices.Fog == ~0) - { - nlwarning("Missing 'fog' in gpu program '%s', Fog disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::Fog; - } - } - - // - // Rough example, modify as necessary. - // - /*if (features.DriverFlags & CGPUProgramFeatures::DriverAmbient || features.MaterialFlags & CGPUProgramFeatures::MaterialAmbient) - { - m_Indices.Ambient = getUniformIndex("nlAmbient"); - if (m_Indices.Ambient == ~0) - { - nlwarning("Missing 'nlAmbient' in gpu program '%s', Ambient disabled", source->DisplayName.c_str()); - features.DriverFlags &= ~CGPUProgramFeatures::DriverAmbient; - features.MaterialFlags &= ~CGPUProgramFeatures::MaterialAmbient; - } - }*/ buildInfo(); } diff --git a/code/nel/src/3d/landscape.cpp b/code/nel/src/3d/landscape.cpp index e842ae369..bf4cad45f 100644 --- a/code/nel/src/3d/landscape.cpp +++ b/code/nel/src/3d/landscape.cpp @@ -1193,20 +1193,29 @@ void CLandscape::render(const CVector &refineCenter, const CVector &frontVecto // If VertexShader enabled, setup VertexProgram Constants. - if(_VertexShaderOk) + if (_VertexShaderOk) { - // c[0..3] take the ModelViewProjection Matrix. - driver->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); - // c[4] take useful constants. - driver->setConstant(4, 0, 1, 0.5f, 0); - // c[5] take RefineCenter - driver->setConstant(5, refineCenter); - // c[6] take info for Geomorph trnasition to TileNear. - driver->setConstant(6, CLandscapeGlobals::TileDistFarSqr, CLandscapeGlobals::OOTileDistDeltaSqr, 0, 0); - // c[10] take the fog vector. - driver->setConstantFog(10); - // c[12] take the current landscape Center / delta Pos to apply - driver->setConstant(12, _PZBModelPosition); + bool uprogstate = driver->isUniformProgramState(); + uint nbvp = uprogstate ? CLandscapeVBAllocator::MaxVertexProgram : 1; + for (uint i = 0; i < nbvp; ++i) + { + // activate the program to set the uniforms in the program state for all programs + // note: when uniforms are driver state, the indices must be the same across programs + if (uprogstate) _TileVB.activateVP(i); + CVertexProgramLandscape *program = _TileVB.getVP(i); + // c[0..3] take the ModelViewProjection Matrix. + driver->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); + // c[4] take useful constants. + driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants0, 0, 1, 0.5f, 0); + // c[5] take RefineCenter + driver->setuniform3f(IDriver::VertexProgram, program->idx().RefineCenter, refineCenter); + // c[6] take info for Geomorph trnasition to TileNear. + driver->setUniform2f(IDriver::VertexProgram, program->idx().TileDist, CLandscapeGlobals::TileDistFarSqr, CLandscapeGlobals::OOTileDistDeltaSqr); + // c[10] take the fog vector. + driver->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::Fog)); + // c[12] take the current landscape Center / delta Pos to apply + driver->setUniform3f(IDriver::VertexProgram, program->idx().PZBModelPosition, _PZBModelPosition); + } } diff --git a/code/nel/src/3d/landscapevb_allocator.cpp b/code/nel/src/3d/landscapevb_allocator.cpp index eccfac66e..4af75c729 100644 --- a/code/nel/src/3d/landscapevb_allocator.cpp +++ b/code/nel/src/3d/landscapevb_allocator.cpp @@ -247,14 +247,23 @@ void CLandscapeVBAllocator::activate(uint vpId) nlassert(_Driver); nlassert(!_BufferLocked); + activateVP(vpId); + + _Driver->activeVertexBuffer(_VB); +} + + +// *************************************************************************** +void CLandscapeVBAllocator::activateVP(uint vpId) +{ + nlassert(_Driver); + // If enabled, activate Vertex program first. - if(_VertexProgram[vpId]) + if (_VertexProgram[vpId]) { //nlinfo("\nSTARTVP\n%s\nENDVP\n", _VertexProgram[vpId]->getProgram().c_str()); nlverify(_Driver->activeVertexProgram(_VertexProgram[vpId])); } - - _Driver->activeVertexBuffer(_VB); } @@ -516,12 +525,11 @@ const char* NL3D_LandscapeTileLightMapEndProgram= // *************************************************************************** void CLandscapeVBAllocator::deleteVertexProgram() { - for(uint i=0;iProfile = nelvp; + source->DisplayName = "Landscape/nelvp"; + switch (type) + { + case CLandscapeVBAllocator::Far0: + source->DisplayName += "/far0"; + source->setSource(std::string(NL3D_LandscapeCommonStartProgram) + + std::string(NL3D_LandscapeFar0EndProgram)); + break; + case CLandscapeVBAllocator::Far1: + source->DisplayName += "/far1"; + source->setSource(std::string(NL3D_LandscapeCommonStartProgram) + + std::string(NL3D_LandscapeFar1EndProgram)); + break; + case CLandscapeVBAllocator::Tile: + source->DisplayName += "/tile"; + if (lightMap) + { + source->DisplayName += "/lightmap"; + source->setSource(std::string(NL3D_LandscapeCommonStartProgram) + + std::string(NL3D_LandscapeTileLightMapEndProgram)); + } + else + { + source->setSource(std::string(NL3D_LandscapeCommonStartProgram) + + std::string(NL3D_LandscapeTileEndProgram)); + } + break; + } + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["programConstants0"] = 4; + source->ParamIndices["refineCenter"] = 5; + source->ParamIndices["tileDist"] = 6; + source->ParamIndices["fog"] = 10; + source->ParamIndices["pzbModelPosition"] = 12; + addSource(source); + } + // TODO_VP_GLSL + { + // .... + } +} +void CVertexProgramLandscape::buildInfo() +{ + m_Idx.ProgramConstants0 = getUniformIndex("programConstants0"); + m_Idx.RefineCenter = getUniformIndex("refineCenter"); + m_Idx.TileDist = getUniformIndex("tileDist"); + m_Idx.PZBModelPosition = getUniformIndex("pzbModelPosition"); +} } // NL3D diff --git a/code/nel/src/3d/water_model.cpp b/code/nel/src/3d/water_model.cpp index 3614d0905..6a239b6e0 100644 --- a/code/nel/src/3d/water_model.cpp +++ b/code/nel/src/3d/water_model.cpp @@ -957,9 +957,9 @@ void CWaterModel::setupMaterialNVertexShader(IDriver *drv, CWaterShape *shape, c drv->setUniform4f(IDriver::VertexProgram, program->idx().DiffuseMapVector0, _ColorMapMatColumn0.x, _ColorMapMatColumn1.x, 0, _ColorMapMatColumn0.x * obsPos.x + _ColorMapMatColumn1.x * obsPos.y + _ColorMapMatPos.x); drv->setUniform4f(IDriver::VertexProgram, program->idx().DiffuseMapVector1, _ColorMapMatColumn0.y, _ColorMapMatColumn1.y, 0, _ColorMapMatColumn0.y * obsPos.x + _ColorMapMatColumn1.y * obsPos.y + _ColorMapMatPos.y); } - /// temp - // drv->setUniformMatrix(IDriver::VertexProgram, program->indices().ModelViewProjection, IDriver::ModelViewProjection, IDriver::Identity); // now set by setUniformDriver in setupMaterial - // drv->setUniformFog(IDriver::VertexProgram, program->indices().Fog); // now set by setUniformDriver in setupMaterial + // set builtins + drv->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); + drv->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::Fog)); // retrieve current time double date = scene->getCurrentTime(); // set bumpmaps pos diff --git a/code/nel/src/3d/water_shape.cpp b/code/nel/src/3d/water_shape.cpp index ac586d168..2fff229c8 100644 --- a/code/nel/src/3d/water_shape.cpp +++ b/code/nel/src/3d/water_shape.cpp @@ -89,9 +89,6 @@ CVertexProgramWaterVPNoWave::CVertexProgramWaterVPNoWave(bool diffuse) CSource *source = new CSource(); source->Profile = nelvp; source->DisplayName = "WaterVPNoWave/nelvp"; - source->Features.DriverFlags = - CGPUProgramFeatures::ModelViewProjection - | CGPUProgramFeatures::Fog; source->ParamIndices["modelViewProjection"] = 0; source->ParamIndices["fog"] = 4; source->ParamIndices["bumpMap0Scale"] = 5; @@ -120,9 +117,6 @@ CVertexProgramWaterVPNoWave::CVertexProgramWaterVPNoWave(bool diffuse) // source->Profile = glsl330v; // source->DisplayName = "WaterVPNoWave/glsl330v"; // if (diffuse) source->DisplayName += "/diffuse"; - // source->Features.DriverFlags = - // CGPUProgramFeatures::ModelViewProjection - // | CGPUProgramFeatures::Fog; // source->setSource... // addSource(source); } From 26f4073ad71557ec8961ec618e15503dbccfc867 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 15:59:31 +0200 Subject: [PATCH 119/137] Simplify --- code/nel/include/nel/3d/gpu_program.h | 27 ++--- .../driver/opengl/driver_opengl_uniform.cpp | 100 ++++++++++-------- code/nel/src/3d/landscape.cpp | 2 +- 3 files changed, 65 insertions(+), 64 deletions(-) diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index 30fa23c52..e7112d410 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -64,6 +64,15 @@ public: // This is only used for user provided shaders, not for builtin shaders, // as it is a slow method which has to go through all of the options every time. // Builtin shaders should set all flags to 0. +// Example: +// User shader flags Matrices in the Vertex Program: +// -> When rendering with a material, the driver will call setUniformDriver, +// which will check if the flag Matrices exists, and if so, it will use +// the index cache to find which matrices are needed by the shader, +// and set those which are found. +// This does not work extremely efficient, but it's the most practical option +// for passing builtin parameters onto user provided shaders. +// Note: May need additional flags related to scene sorting, etcetera. struct CGPUProgramFeatures { CGPUProgramFeatures() : DriverFlags(0), MaterialFlags(0) { } @@ -72,26 +81,12 @@ struct CGPUProgramFeatures enum TDriverFlags { // Matrices - ModelView = 0x00000001, - ModelViewInverse = 0x00000002, - ModelViewTranspose = 0x00000004, - ModelViewInverseTranspose = 0x00000008, - - Projection = 0x00000010, - ProjectionInverse = 0x00000020, - ProjectionTranspose = 0x00000040, - ProjectionInverseTranspose = 0x00000080, - - ModelViewProjection = 0x00000100, - ModelViewProjectionInverse = 0x00000200, - ModelViewProjectionTranspose = 0x00000400, - ModelViewProjectionInverseTranspose = 0x00000800, + Matrices = 0x00000001, // Fog - Fog = 0x00001000, + Fog = 0x00000002, }; uint32 DriverFlags; - // uint NumLights; enum TMaterialFlags { 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 a23235d06..658b6739a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -309,57 +309,63 @@ bool CDriverGL::setUniformDriver(TProgram program) if (features.DriverFlags) { - if (features.DriverFlags & CGPUProgramFeatures::ModelView) + if (features.DriverFlags & CGPUProgramFeatures::Matrices) { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelView), ModelView, Identity); - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverse) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewInverse), ModelView, Inverse); - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewTranspose) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewTranspose), ModelView, Transpose); - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverseTranspose) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewInverseTranspose), ModelView, InverseTranspose); - } - if (features.DriverFlags & CGPUProgramFeatures::Projection) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::Projection), Projection, Identity); - } - if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverse) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionInverse), Projection, Inverse); - } - if (features.DriverFlags & CGPUProgramFeatures::ProjectionTranspose) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionTranspose), Projection, Transpose); - } - if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverseTranspose) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionInverseTranspose), Projection, InverseTranspose); - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjection) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjection), ModelViewProjection, Identity); - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverse) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverse), ModelViewProjection, Inverse); - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionTranspose) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionTranspose), ModelViewProjection, Transpose); - } - if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverseTranspose) - { - setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverseTranspose), ModelViewProjection, InverseTranspose); + if (prog->getUniformIndex(CGPUProgramIndex::ModelView) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelView), ModelView, Identity); + } + if (prog->getUniformIndex(CGPUProgramIndex::ModelViewInverse) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewInverse), ModelView, Inverse); + } + if (prog->getUniformIndex(CGPUProgramIndex::ModelViewTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewTranspose), ModelView, Transpose); + } + if (prog->getUniformIndex(CGPUProgramIndex::ModelViewInverseTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewInverseTranspose), ModelView, InverseTranspose); + } + if (prog->getUniformIndex(CGPUProgramIndex::Projection) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::Projection), Projection, Identity); + } + if (prog->getUniformIndex(CGPUProgramIndex::ProjectionInverse) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionInverse), Projection, Inverse); + } + if (prog->getUniformIndex(CGPUProgramIndex::ProjectionTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionTranspose), Projection, Transpose); + } + if (prog->getUniformIndex(CGPUProgramIndex::ProjectionInverseTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionInverseTranspose), Projection, InverseTranspose); + } + if (prog->getUniformIndex(CGPUProgramIndex::ModelViewProjection) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjection), ModelViewProjection, Identity); + } + if (prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverse) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverse), ModelViewProjection, Inverse); + } + if (prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionTranspose), ModelViewProjection, Transpose); + } + if (prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverseTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverseTranspose), ModelViewProjection, InverseTranspose); + } } if (features.DriverFlags & CGPUProgramFeatures::Fog) { - setUniformFog(program, prog->getUniformIndex(CGPUProgramIndex::Fog)); + if (prog->getUniformIndex(CGPUProgramIndex::Fog) != ~0) + { + setUniformFog(program, prog->getUniformIndex(CGPUProgramIndex::Fog)); + } } } diff --git a/code/nel/src/3d/landscape.cpp b/code/nel/src/3d/landscape.cpp index bf4cad45f..c6da6ec27 100644 --- a/code/nel/src/3d/landscape.cpp +++ b/code/nel/src/3d/landscape.cpp @@ -1208,7 +1208,7 @@ void CLandscape::render(const CVector &refineCenter, const CVector &frontVecto // c[4] take useful constants. driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants0, 0, 1, 0.5f, 0); // c[5] take RefineCenter - driver->setuniform3f(IDriver::VertexProgram, program->idx().RefineCenter, refineCenter); + driver->setUniform3f(IDriver::VertexProgram, program->idx().RefineCenter, refineCenter); // c[6] take info for Geomorph trnasition to TileNear. driver->setUniform2f(IDriver::VertexProgram, program->idx().TileDist, CLandscapeGlobals::TileDistFarSqr, CLandscapeGlobals::OOTileDistDeltaSqr); // c[10] take the fog vector. From 7462d731f1fc30952db72b3e573acde621c63130 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 16:24:45 +0200 Subject: [PATCH 120/137] Small adjustment to landscape vp parameter setting --- code/nel/src/3d/landscape.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/code/nel/src/3d/landscape.cpp b/code/nel/src/3d/landscape.cpp index c6da6ec27..7f9898504 100644 --- a/code/nel/src/3d/landscape.cpp +++ b/code/nel/src/3d/landscape.cpp @@ -1199,22 +1199,26 @@ void CLandscape::render(const CVector &refineCenter, const CVector &frontVecto uint nbvp = uprogstate ? CLandscapeVBAllocator::MaxVertexProgram : 1; for (uint i = 0; i < nbvp; ++i) { - // activate the program to set the uniforms in the program state for all programs - // note: when uniforms are driver state, the indices must be the same across programs - if (uprogstate) _TileVB.activateVP(i); CVertexProgramLandscape *program = _TileVB.getVP(i); - // c[0..3] take the ModelViewProjection Matrix. - driver->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); - // c[4] take useful constants. - driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants0, 0, 1, 0.5f, 0); - // c[5] take RefineCenter - driver->setUniform3f(IDriver::VertexProgram, program->idx().RefineCenter, refineCenter); - // c[6] take info for Geomorph trnasition to TileNear. - driver->setUniform2f(IDriver::VertexProgram, program->idx().TileDist, CLandscapeGlobals::TileDistFarSqr, CLandscapeGlobals::OOTileDistDeltaSqr); - // c[10] take the fog vector. - driver->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::Fog)); - // c[12] take the current landscape Center / delta Pos to apply - driver->setUniform3f(IDriver::VertexProgram, program->idx().PZBModelPosition, _PZBModelPosition); + if (program) + { + // activate the program to set the uniforms in the program state for all programs + // note: when uniforms are driver state, the indices must be the same across programs + if (uprogstate) _TileVB.activateVP(i); + + // c[0..3] take the ModelViewProjection Matrix. + driver->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); + // c[4] take useful constants. + driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants0, 0, 1, 0.5f, 0); + // c[5] take RefineCenter + driver->setUniform3f(IDriver::VertexProgram, program->idx().RefineCenter, refineCenter); + // c[6] take info for Geomorph trnasition to TileNear. + driver->setUniform2f(IDriver::VertexProgram, program->idx().TileDist, CLandscapeGlobals::TileDistFarSqr, CLandscapeGlobals::OOTileDistDeltaSqr); + // c[10] take the fog vector. + driver->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::Fog)); + // c[12] take the current landscape Center / delta Pos to apply + driver->setUniform3f(IDriver::VertexProgram, program->idx().PZBModelPosition, _PZBModelPosition); + } } } From 776f198df3be4cdd554d73e3ff7c8033e2f71ada Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 16:42:51 +0200 Subject: [PATCH 121/137] Update some test code --- code/nel/src/3d/water_env_map.cpp | 49 ++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/code/nel/src/3d/water_env_map.cpp b/code/nel/src/3d/water_env_map.cpp index 3d2f64a1f..65f66e622 100644 --- a/code/nel/src/3d/water_env_map.cpp +++ b/code/nel/src/3d/water_env_map.cpp @@ -227,8 +227,7 @@ void CWaterEnvMap::doInit() } } - -static CVertexProgram testMeshVP( +static const char *testMeshVPstr = "!!VP1.0\n\ DP4 o[HPOS].x, c[0], v[0]; \n\ DP4 o[HPOS].y, c[1], v[0]; \n\ @@ -236,8 +235,45 @@ static CVertexProgram testMeshVP( DP4 o[HPOS].w, c[3], v[0]; \n\ MAD o[COL0], v[8], c[4].xxxx, c[4].yyyy; \n\ MOV o[TEX0], v[8]; \n\ - END" -); + END"; + + +class CVertexProgramTestMeshVP : public CVertexProgram +{ +public: + struct CIdx + { + uint ProgramConstant0; + }; + CVertexProgramTestMeshVP() + { + // nelvp + { + CSource *source = new CSource(); + source->Profile = nelvp; + source->DisplayName = "testMeshVP/nelvp"; + source->setSourcePtr(testMeshVPstr); + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["programConstant0"] = 4; + addSource(source); + } + // TODO_VP_GLSL + } + virtual ~CVertexProgramTestMeshVP() + { + + } + virtual void buildInfo() + { + m_Idx.ProgramConstant0 = getUniformIndex("programConstant0"); + } + inline const CIdx &idx() { return m_Idx; } +private: + CIdx m_Idx; +}; + + +static CVertexProgramTestMeshVP testMeshVP; @@ -260,10 +296,9 @@ void CWaterEnvMap::renderTestMesh(IDriver &driver) driver.activeVertexProgram(&testMeshVP); driver.activeVertexBuffer(_TestVB); driver.activeIndexBuffer(_TestIB); - driver.setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); // tmp _MaterialPassThruZTest.setTexture(0, _EnvCubic); - driver.setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); - driver.setConstant(4, 2.f, 1.f, 0.f, 0.f); + driver.setUniformMatrix(IDriver::VertexProgram, testMeshVP.getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); + driver.setUniform2f(IDriver::VertexProgram, testMeshVP.idx().ProgramConstant0, 2.f, 1.f); //driver.renderTriangles(testMat, 0, TEST_VB_NUM_TRIS); driver.renderTriangles(_MaterialPassThruZTest, 0, TEST_VB_NUM_TRIS); driver.activeVertexProgram(NULL); From e6658bdef0b65963cc5569a7025afef38d9c1000 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 17:01:33 +0200 Subject: [PATCH 122/137] Update decal vp --- code/ryzom/client/src/decal.cpp | 74 +++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/code/ryzom/client/src/decal.cpp b/code/ryzom/client/src/decal.cpp index da0fdcb82..bac27ebb6 100644 --- a/code/ryzom/client/src/decal.cpp +++ b/code/ryzom/client/src/decal.cpp @@ -84,9 +84,59 @@ static const char *DecalAttenuationVertexProgramCode = MUL o[COL0].w, v[3], R0.w; \n\ END \n"; -static NL3D::CVertexProgram DecalAttenuationVertexProgram(DecalAttenuationVertexProgramCode); +class CVertexProgramDecalAttenuation : public CVertexProgram +{ +public: + struct CIdx + { + // 0-3 mvp + uint WorldToUV0; // 4 + uint WorldToUV1; // 5 + uint RefCamDist; // 6 + uint DistScaleBias; // 7 + uint Diffuse; // 8 + // 9 + // 10 + uint BlendScale; // 11 + }; + CVertexProgramDecalAttenuation() + { + // nelvp + { + CSource *source = new CSource(); + source->Profile = nelvp; + source->DisplayName = "nelvp/DecalAttenuation"; + source->setSourcePtr(DecalAttenuationVertexProgramCode); + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["worldToUV0"] = 4; + source->ParamIndices["worldToUV1"] = 5; + source->ParamIndices["refCamDist"] = 6; + source->ParamIndices["distScaleBias"] = 7; + source->ParamIndices["diffuse"] = 8; + source->ParamIndices["blendScale"] = 11; + addSource(source); + } + // TODO_VP_GLSL + } + ~CVertexProgramDecalAttenuation() + { + + } + virtual void buildInfo() + { + m_Idx.WorldToUV0 = getUniformIndex("worldToUV0"); + m_Idx.WorldToUV1 = getUniformIndex("worldToUV1"); + m_Idx.RefCamDist = getUniformIndex("refCamDist"); + m_Idx.DistScaleBias = getUniformIndex("distScaleBias"); + m_Idx.Diffuse = getUniformIndex("diffuse"); + m_Idx.BlendScale = getUniformIndex("blendScale"); + } + inline const CIdx &idx() const { return m_Idx; } +private: + CIdx m_Idx; +}; -// TODO_VP_GLSL +static CVertexProgramDecalAttenuation DecalAttenuationVertexProgram; typedef CShadowPolyReceiver::CRGBAVertex CRGBAVertex; @@ -312,16 +362,16 @@ void CDecal::renderTriCache(NL3D::IDriver &drv, NL3D::CShadowPolyReceiver &/* memcpy(vba.getVertexCoordPointer(), &_TriCache[0], sizeof(CRGBAVertex) * _TriCache.size()); } drv.activeVertexBuffer(_VB); - drv.setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); - drv.setConstant(4, _WorldToUVMatrix[0][0], _WorldToUVMatrix[1][0], _WorldToUVMatrix[2][0], _WorldToUVMatrix[3][0]); - drv.setConstant(5, _WorldToUVMatrix[0][1], _WorldToUVMatrix[1][1], _WorldToUVMatrix[2][1], _WorldToUVMatrix[3][1]); - drv.setConstant(8, _Diffuse.R * (1.f / 255.f), _Diffuse.G * (1.f / 255.f), _Diffuse.B * (1.f / 255.f), 1.f); + drv.setUniformMatrix(IDriver::VertexProgram, DecalAttenuationVertexProgram.getUniformIndex(CGPUProgramIndex::ModelViewProjection), NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); + drv.setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().WorldToUV0, _WorldToUVMatrix[0][0], _WorldToUVMatrix[1][0], _WorldToUVMatrix[2][0], _WorldToUVMatrix[3][0]); + drv.setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().WorldToUV1, _WorldToUVMatrix[0][1], _WorldToUVMatrix[1][1], _WorldToUVMatrix[2][1], _WorldToUVMatrix[3][1]); + drv.setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().Diffuse, _Diffuse.R * (1.f / 255.f), _Diffuse.G * (1.f / 255.f), _Diffuse.B * (1.f / 255.f), 1.f); const NLMISC::CVector &camPos = MainCam.getMatrix().getPos(); - drv.setConstant(6, camPos.x - _RefPosition.x, camPos.y - _RefPosition.y, camPos.z - _RefPosition.z, 1.f); + drv.setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().RefCamDist, camPos.x - _RefPosition.x, camPos.y - _RefPosition.y, camPos.z - _RefPosition.z, 1.f); // bottom & top blend float bottomBlendScale = 1.f / favoid0(_BottomBlendZMax - _BottomBlendZMin); float topBlendScale = 1.f / favoid0(_TopBlendZMin - _TopBlendZMax); - drv.setConstant(11, bottomBlendScale, bottomBlendScale * (_RefPosition.z - _BottomBlendZMin), + drv.setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().BlendScale, bottomBlendScale, bottomBlendScale * (_RefPosition.z - _BottomBlendZMin), topBlendScale, topBlendScale * (_RefPosition.z - _TopBlendZMax)); // static volatile bool wantSimpleMat = false; @@ -562,12 +612,12 @@ void CDecalRenderList::renderAllDecals() NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver(); // static volatile bool forceNoVertexProgram = false; - if (drvInternal->supportVertexProgram() && !forceNoVertexProgram) + if (!forceNoVertexProgram && drvInternal->compileVertexProgram(&DecalAttenuationVertexProgram)) { - //drvInternal->setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); - drvInternal->setConstant(7, _DistScale, _DistBias, 0.f, 1.f); - useVertexProgram = true; drvInternal->activeVertexProgram(&DecalAttenuationVertexProgram); + //drvInternal->setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); + drvInternal->setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().DistScaleBias, _DistScale, _DistBias, 0.f, 1.f); + useVertexProgram = true; } else { From a798aecd71221a6298d69ebb1d0499e814639773 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 19:52:14 +0200 Subject: [PATCH 123/137] Partial update of veget vp --- code/nel/include/nel/3d/gpu_program.h | 1 + code/nel/include/nel/3d/vegetable_manager.h | 4 +- code/nel/src/3d/vegetable_manager.cpp | 212 +++++++++++++++----- 3 files changed, 164 insertions(+), 53 deletions(-) diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index e7112d410..b7114a3bd 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -229,6 +229,7 @@ public: // Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0 inline uint getUniformIndex(const char *name) const { return m_DrvInfo->getUniformIndex(name); }; + inline uint getUniformIndex(const std::string &name) const { return m_DrvInfo->getUniformIndex(name.c_str()); }; inline uint getUniformIndex(CGPUProgramIndex::TName name) const { return m_Index.Indices[name]; } // Get feature information of the current program diff --git a/code/nel/include/nel/3d/vegetable_manager.h b/code/nel/include/nel/3d/vegetable_manager.h index 71ed235e4..8b3026794 100644 --- a/code/nel/include/nel/3d/vegetable_manager.h +++ b/code/nel/include/nel/3d/vegetable_manager.h @@ -48,6 +48,7 @@ class CVegetableLightEx; // default distance is 60 meters. #define NL3D_VEGETABLE_DEFAULT_DIST_MAX 60.f +class CVertexProgramVeget; // *************************************************************************** /** @@ -306,7 +307,8 @@ private: // The same, but no VBHard. CVegetableVBAllocator _VBSoftAllocator[CVegetableVBAllocator::VBTypeCount]; // Vertex Program. One VertexProgram for each rdrPass (with / without fog) - CVertexProgram *_VertexProgram[NL3D_VEGETABLE_NRDRPASS][2]; + CSmartPtr _VertexProgram[NL3D_VEGETABLE_NRDRPASS][2]; + CRefPtr _ActiveVertexProgram; // Material. Useful for texture and alphaTest diff --git a/code/nel/src/3d/vegetable_manager.cpp b/code/nel/src/3d/vegetable_manager.cpp index 6d9e15752..d8a5aa198 100644 --- a/code/nel/src/3d/vegetable_manager.cpp +++ b/code/nel/src/3d/vegetable_manager.cpp @@ -560,49 +560,144 @@ const char* NL3D_SimpleStartVegetableProgram= MOV o[COL0].xyz, v[3]; # col.RGBA= vertex color \n\ "; +class CVertexProgramVeget : public CVertexProgram +{ +public: + struct CIdx + { + // 0-3 modelViewProjection + // 4 + // 5 + // 6 fog + // 7 + uint ProgramConstants0; // 8 + uint DirectionalLight; // 9 + uint ViewCenter; // 10 + uint NegInvTransDist; // 11 + // 12 + // 13 + // 14 + // 15 + uint AngleAxis; // 16 + uint Wind; // 17 + uint CosCoeff0; // 18 + uint CosCoeff1; // 19 + uint CosCoeff2; // 20 + uint QuatConstants; // 21 + uint PiConstants; // 22 + uint LUTSize; // 23 (value = 64) + uint LUT[NL3D_VEGETABLE_VP_LUT_SIZE]; // 32+ + }; + CVertexProgramVeget(uint vpType, bool fogEnabled) + { + // nelvp + { + CSource *source = new CSource(); + source->Profile = nelvp; + source->DisplayName = "nelvp/Veget"; + + // Init the Vertex Program. + string vpgram; + // start always with Bend. + if( vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED || vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED ) + { + source->DisplayName += "/Bend"; + vpgram= NL3D_BendProgram; + } + else + { + source->DisplayName += "/FastBend"; + vpgram= NL3D_FastBendProgram; + } + // combine the VP according to Type + switch(vpType) + { + case NL3D_VEGETABLE_RDRPASS_LIGHTED: + case NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED: + source->DisplayName += "/Lighted"; + vpgram+= string(NL3D_LightedStartVegetableProgram); + break; + case NL3D_VEGETABLE_RDRPASS_UNLIT: + case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED: + source->DisplayName += "/Unlit"; + vpgram+= string(NL3D_UnlitVegetableProgram); + break; + case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED_ZSORT: + source->DisplayName += "/UnlitAlphaBlend"; + vpgram+= string(NL3D_UnlitAlphaBlendVegetableProgram); + break; + } + + // common end of VP + vpgram+= string(NL3D_CommonEndVegetableProgram); + + if (fogEnabled) + { + source->DisplayName += "/Fog"; + vpgram+= string(NL3D_VegetableProgramFog); + } + + vpgram+="\nEND\n"; + + source->setSource(vpgram); + + source->ParamIndices["programConstants0"] = 8; + source->ParamIndices["directionalLight"] = 9; + source->ParamIndices["viewCenter"] = 10; + source->ParamIndices["negInvTransDist"] = 11; + source->ParamIndices["angleAxis"] = 16; + source->ParamIndices["wind"] = 17; + source->ParamIndices["cosCoeff0"] = 18; + source->ParamIndices["cosCoeff1"] = 19; + source->ParamIndices["cosCoeff2"] = 20; + source->ParamIndices["quatConstants"] = 21; + source->ParamIndices["piConstants"] = 22; + source->ParamIndices["lutSize"] = 23; + for (uint i = 0; i < NL3D_VEGETABLE_VP_LUT_SIZE; ++i) + { + source->ParamIndices[NLMISC::toString("lut[%i]", i)] = 32 + i; + } + + addSource(source); + } + // TODO_VP_GLSL + } + virtual ~CVertexProgramVeget() + { + + } + virtual void buildInfo() + { + m_Idx.ProgramConstants0 = getUniformIndex("programConstants0"); + m_Idx.DirectionalLight = getUniformIndex("directionalLight"); + m_Idx.ViewCenter = getUniformIndex("viewCenter"); + m_Idx.NegInvTransDist = getUniformIndex("negInvTransDist"); + m_Idx.AngleAxis = getUniformIndex("angleAxis"); + m_Idx.Wind = getUniformIndex("wind"); + m_Idx.CosCoeff0 = getUniformIndex("cosCoeff0"); + m_Idx.CosCoeff1 = getUniformIndex("cosCoeff1"); + m_Idx.CosCoeff2 = getUniformIndex("cosCoeff2"); + m_Idx.QuatConstants = getUniformIndex("quatConstants"); + m_Idx.PiConstants = getUniformIndex("piConstants"); + m_Idx.LUTSize = getUniformIndex("lutSize"); + for (uint i = 0; i < NL3D_VEGETABLE_VP_LUT_SIZE; ++i) + { + m_Idx.LUT[i] = getUniformIndex(NLMISC::toString("lut[%i]", i)); + } + } + const CIdx &idx() const { return m_Idx; } +private: + CIdx m_Idx; +}; // *************************************************************************** void CVegetableManager::initVertexProgram(uint vpType, bool fogEnabled) { nlassert(_LastDriver); // update driver should have been called at least once ! - // Init the Vertex Program. - string vpgram; - // start always with Bend. - if( vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED || vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED ) - vpgram= NL3D_BendProgram; - else - vpgram= NL3D_FastBendProgram; - - // combine the VP according to Type - switch(vpType) - { - case NL3D_VEGETABLE_RDRPASS_LIGHTED: - case NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED: - vpgram+= string(NL3D_LightedStartVegetableProgram); - break; - case NL3D_VEGETABLE_RDRPASS_UNLIT: - case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED: - vpgram+= string(NL3D_UnlitVegetableProgram); - break; - case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED_ZSORT: - vpgram+= string(NL3D_UnlitAlphaBlendVegetableProgram); - break; - } - - // common end of VP - vpgram+= string(NL3D_CommonEndVegetableProgram); - - if (fogEnabled) - { - vpgram+= string(NL3D_VegetableProgramFog); - } - - vpgram+="\nEND\n"; - + // create VP. - _VertexProgram[vpType][fogEnabled ? 1 : 0] = new CVertexProgram(vpgram.c_str()); - // TODO_VP_GLSL + _VertexProgram[vpType][fogEnabled ? 1 : 0] = new CVertexProgramVeget(vpType, fogEnabled); } @@ -1758,6 +1853,9 @@ public: // *************************************************************************** void CVegetableManager::setupVertexProgramConstants(IDriver *driver) { + nlassert(_ActiveVertexProgram); + + // Standard // setup VertexProgram constants. // c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix(); @@ -1925,10 +2023,6 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front } - // setup VP constants. - setupVertexProgramConstants(driver); - - // Setup TexEnvs for Dynamic lightmapping //-------------------- // if the dynamic lightmap is provided @@ -1968,6 +2062,12 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front _VegetableMaterial.setZWrite(true); _VegetableMaterial.setAlphaTestThreshold(0.5f); + bool uprogst = driver->isUniformProgramState(); + bool progstateset[NL3D_VEGETABLE_NRDRPASS]; + for (sint rdrPass=0; rdrPass < NL3D_VEGETABLE_NRDRPASS; rdrPass++) + { + progstateset[rdrPass] = !uprogst; + } /* Prefer sort with Soft / Hard first. @@ -1995,14 +2095,20 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front // set the 2Sided flag in the material _VegetableMaterial.setDoubleSided( doubleSided ); - - // Activate the unique material. - driver->setupMaterial(_VegetableMaterial); - // activate Vertex program first. //nlinfo("\nSTARTVP\n%s\nENDVP\n", _VertexProgram[rdrPass]->getProgram().c_str()); - nlverify(driver->activeVertexProgram(_VertexProgram[rdrPass][fogged ? 1 : 0])); + _ActiveVertexProgram = _VertexProgram[rdrPass][fogged ? 1 : 0]; + nlverify(driver->activeVertexProgram(_ActiveVertexProgram)); + + // Set VP constants + if (!progstateset[uprogst ? 0 : rdrPass]) + { + setupVertexProgramConstants(driver); + } + + // Activate the unique material. + driver->setupMaterial(_VegetableMaterial); // Activate the good VBuffer vbAllocator.activate(); @@ -2222,6 +2328,7 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front // disable VertexProgram. driver->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; // restore Fog. @@ -2261,25 +2368,25 @@ void CVegetableManager::setupRenderStateForBlendLayerModel(IDriver *driver) // set model matrix to the manager matrix. driver->setupModelMatrix(_ManagerMatrix); - // setup VP constants. - setupVertexProgramConstants(driver); - // Setup RdrPass. //============= uint rdrPass= NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED_ZSORT; - // Activate the unique material (correclty setuped for AlphaBlend in render()). - driver->setupMaterial(_VegetableMaterial); - // activate Vertex program first. //nlinfo("\nSTARTVP\n%s\nENDVP\n", _VertexProgram[rdrPass]->getProgram().c_str()); - nlverify(driver->activeVertexProgram(_VertexProgram[rdrPass][fogged ? 1 : 0])); + _ActiveVertexProgram = _VertexProgram[rdrPass][fogged ? 1 : 0]; + nlverify(driver->activeVertexProgram(_ActiveVertexProgram)); + + // setup VP constants. + setupVertexProgramConstants(driver); if (fogged) { driver->setConstantFog(6); } + // Activate the unique material (correclty setuped for AlphaBlend in render()). + driver->setupMaterial(_VegetableMaterial); } @@ -2302,6 +2409,7 @@ void CVegetableManager::exitRenderStateForBlendLayerModel(IDriver *driver) { // disable VertexProgram. driver->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; // restore Fog. driver->enableFog(_BkupFog); From f0177268b457b0c4cb01cd3f1b77f2d244b7aca5 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Sep 2013 19:53:41 +0200 Subject: [PATCH 124/137] Rename of a d3d specific class --- .../src/3d/driver/direct3d/driver_direct3d.h | 58 +++++++++---------- .../direct3d/driver_direct3d_shader.cpp | 16 ++--- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index b3a8f5f37..3e2d2cdc9 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -215,11 +215,11 @@ public: * ********************************** */ // -------------------------------------------------- -class CShader +class CD3DShaderFX { public: - CShader(); - ~CShader(); + CD3DShaderFX(); + ~CD3DShaderFX(); // Load a shader file bool loadShaderFile (const char *filename); @@ -1236,7 +1236,7 @@ public: * ColorOp[n] = DISABLE; * AlphaOp[n] = DISABLE; */ - bool activeShader(CShader *shd); + bool activeShader(CD3DShaderFX *shd); // Bench virtual void startBench (bool wantStandardDeviation = false, bool quick = false, bool reset = true); @@ -2165,7 +2165,7 @@ public: void releaseInternalShaders(); bool setShaderTexture (uint textureHandle, ITexture *texture, CFXCache *cache); - bool validateShader(CShader *shader); + bool validateShader(CD3DShaderFX *shader); void activePass (uint pass) { @@ -2573,7 +2573,7 @@ private: CIndexBuffer _QuadIndexesAGP; // The last setuped shader - CShader *_CurrentShader; + CD3DShaderFX *_CurrentShader; UINT _CurrentShaderPassCount; public: struct CTextureRef @@ -2598,29 +2598,29 @@ private: CRenderVariable *_ModifiedRenderState; // Internal shaders - CShader _ShaderLightmap0; - CShader _ShaderLightmap1; - CShader _ShaderLightmap2; - CShader _ShaderLightmap3; - CShader _ShaderLightmap4; - CShader _ShaderLightmap0Blend; - CShader _ShaderLightmap1Blend; - CShader _ShaderLightmap2Blend; - CShader _ShaderLightmap3Blend; - CShader _ShaderLightmap4Blend; - CShader _ShaderLightmap0X2; - CShader _ShaderLightmap1X2; - CShader _ShaderLightmap2X2; - CShader _ShaderLightmap3X2; - CShader _ShaderLightmap4X2; - CShader _ShaderLightmap0BlendX2; - CShader _ShaderLightmap1BlendX2; - CShader _ShaderLightmap2BlendX2; - CShader _ShaderLightmap3BlendX2; - CShader _ShaderLightmap4BlendX2; - CShader _ShaderCloud; - CShader _ShaderWaterNoDiffuse; - CShader _ShaderWaterDiffuse; + CD3DShaderFX _ShaderLightmap0; + CD3DShaderFX _ShaderLightmap1; + CD3DShaderFX _ShaderLightmap2; + CD3DShaderFX _ShaderLightmap3; + CD3DShaderFX _ShaderLightmap4; + CD3DShaderFX _ShaderLightmap0Blend; + CD3DShaderFX _ShaderLightmap1Blend; + CD3DShaderFX _ShaderLightmap2Blend; + CD3DShaderFX _ShaderLightmap3Blend; + CD3DShaderFX _ShaderLightmap4Blend; + CD3DShaderFX _ShaderLightmap0X2; + CD3DShaderFX _ShaderLightmap1X2; + CD3DShaderFX _ShaderLightmap2X2; + CD3DShaderFX _ShaderLightmap3X2; + CD3DShaderFX _ShaderLightmap4X2; + CD3DShaderFX _ShaderLightmap0BlendX2; + CD3DShaderFX _ShaderLightmap1BlendX2; + CD3DShaderFX _ShaderLightmap2BlendX2; + CD3DShaderFX _ShaderLightmap3BlendX2; + CD3DShaderFX _ShaderLightmap4BlendX2; + CD3DShaderFX _ShaderCloud; + CD3DShaderFX _ShaderWaterNoDiffuse; + CD3DShaderFX _ShaderWaterDiffuse; // Backup frame buffer diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp index 300cfe4b7..5cc6c283c 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp @@ -29,7 +29,7 @@ namespace NL3D // *************************************************************************** -CShader::~CShader() +CD3DShaderFX::~CD3DShaderFX() { // Must kill the drv mirror of this shader. _DrvInfo.kill(); @@ -37,14 +37,14 @@ CShader::~CShader() // *************************************************************************** -CShader::CShader() +CD3DShaderFX::CD3DShaderFX() { _ShaderChanged = true; } // *************************************************************************** -void CShader::setText (const char *text) +void CD3DShaderFX::setText (const char *text) { _Text = text; _ShaderChanged = true; @@ -52,7 +52,7 @@ void CShader::setText (const char *text) // *************************************************************************** -void CShader::setName (const char *name) +void CD3DShaderFX::setName (const char *name) { _Name = name; _ShaderChanged = true; @@ -60,7 +60,7 @@ void CShader::setName (const char *name) // *************************************************************************** -bool CShader::loadShaderFile (const char *filename) +bool CD3DShaderFX::loadShaderFile (const char *filename) { _Text = ""; // Lookup @@ -354,7 +354,7 @@ CShaderDrvInfosD3D::~CShaderDrvInfosD3D() // *************************************************************************** -bool CDriverD3D::validateShader(CShader *shader) +bool CDriverD3D::validateShader(CD3DShaderFX *shader) { H_AUTO_D3D(CDriverD3D_validateShader) CShaderDrvInfosD3D *shaderInfo = static_cast((IShaderDrvInfos*)shader->_DrvInfo); @@ -416,7 +416,7 @@ bool CDriverD3D::validateShader(CShader *shader) // *************************************************************************** -bool CDriverD3D::activeShader(CShader *shd) +bool CDriverD3D::activeShader(CD3DShaderFX *shd) { H_AUTO_D3D(CDriverD3D_activeShader) if (_DisableHardwarePixelShader) @@ -482,7 +482,7 @@ bool CDriverD3D::activeShader(CShader *shd) } -static void setFX(CShader &s, const char *name, const char *prog, CDriverD3D *drv) +static void setFX(CD3DShaderFX &s, const char *name, const char *prog, CDriverD3D *drv) { H_AUTO_D3D(setFX) From b77101cdd476206c9671132520b65d56b71db3a1 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Wed, 11 Sep 2013 01:12:37 +0200 Subject: [PATCH 125/137] Update d3d implementation and add some debugging code --- .../src/3d/driver/direct3d/driver_direct3d.h | 4 +- .../direct3d/driver_direct3d_material.cpp | 10 ++- .../driver_direct3d_pixel_program.cpp | 4 +- .../driver_direct3d_vertex_program.cpp | 4 +- code/nel/src/3d/landscape.cpp | 2 +- code/nel/src/3d/landscapevb_allocator.cpp | 4 + code/nel/src/3d/stereo_debugger.cpp | 82 +++++++++++++++---- code/nel/src/3d/vegetable_manager.cpp | 15 ++++ code/nel/src/3d/water_env_map.cpp | 1 + code/nel/src/3d/water_shape.cpp | 8 ++ code/ryzom/client/src/decal.cpp | 6 ++ 11 files changed, 112 insertions(+), 28 deletions(-) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 3e2d2cdc9..80b39f786 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -2542,8 +2542,8 @@ private: // The last vertex buffer needs vertex color bool _FogEnabled; - bool _VertexProgramUser; - bool _PixelProgramUser; + NLMISC::CRefPtr _VertexProgramUser; + NLMISC::CRefPtr _PixelProgramUser; // *** Internal resources diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp index 07ec5187b..b8d2fa41b 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp @@ -328,7 +328,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) pShader = static_cast((IMaterialDrvInfos*)(mat._MatDrvInfo)); // Now we can get the supported shader from the cache. - CMaterial::TShader matShader = mat.getShader(); + CMaterial::TShader matShader = _PixelProgramUser ? CMaterial::Program : mat.getShader(); if (_CurrentMaterialSupportedShader != CMaterial::Normal) { @@ -648,7 +648,9 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) // Must separate texture setup and texture activation in 2 "for"... // because setupTexture() may disable all stage. - if (matShader == CMaterial::Normal || matShader == CMaterial::PostProcessing) + if (matShader == CMaterial::Normal + || ((matShader == CMaterial::Program) && (_PixelProgramUser->features().MaterialFlags & CGPUProgramFeatures::TextureStages)) + ) { uint stage; for(stage=0 ; stagefeatures().MaterialFlags & CGPUProgramFeatures::TextureStages)) + ) { uint stage; for(stage=0 ; stage((IGPUProgramDrvInfos*)program->m_DrvInfo); - _PixelProgramUser = true; + _PixelProgramUser = program; setPixelShader(info->Shader); } else { setPixelShader(NULL); - _PixelProgramUser = false; + _PixelProgramUser = NULL; } return true; 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 74ddf9011..3f069edd5 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,7 +379,7 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) if (!CDriverD3D::compileVertexProgram(program)) return false; CVertexProgamDrvInfosD3D *info = NLMISC::safe_cast((IGPUProgramDrvInfos*)program->m_DrvInfo); - _VertexProgramUser = true; + _VertexProgramUser = program; 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 @@ -395,7 +395,7 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) else { setVertexProgram (NULL, NULL); - _VertexProgramUser = false; + _VertexProgramUser = NULL; // Set the old fog range setRenderState (D3DRS_FOGSTART, *((DWORD*) (&_FogStart))); diff --git a/code/nel/src/3d/landscape.cpp b/code/nel/src/3d/landscape.cpp index 7f9898504..06054a48d 100644 --- a/code/nel/src/3d/landscape.cpp +++ b/code/nel/src/3d/landscape.cpp @@ -1204,7 +1204,7 @@ void CLandscape::render(const CVector &refineCenter, const CVector &frontVecto { // activate the program to set the uniforms in the program state for all programs // note: when uniforms are driver state, the indices must be the same across programs - if (uprogstate) _TileVB.activateVP(i); + _TileVB.activateVP(i); // c[0..3] take the ModelViewProjection Matrix. driver->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); diff --git a/code/nel/src/3d/landscapevb_allocator.cpp b/code/nel/src/3d/landscapevb_allocator.cpp index 4af75c729..79f56ab42 100644 --- a/code/nel/src/3d/landscapevb_allocator.cpp +++ b/code/nel/src/3d/landscapevb_allocator.cpp @@ -659,9 +659,13 @@ CVertexProgramLandscape::CVertexProgramLandscape(CLandscapeVBAllocator::TType ty void CVertexProgramLandscape::buildInfo() { m_Idx.ProgramConstants0 = getUniformIndex("programConstants0"); + nlassert(m_Idx.ProgramConstants0 != ~0); m_Idx.RefineCenter = getUniformIndex("refineCenter"); + nlassert(m_Idx.RefineCenter != ~0); m_Idx.TileDist = getUniformIndex("tileDist"); + nlassert(m_Idx.TileDist != ~0); m_Idx.PZBModelPosition = getUniformIndex("pzbModelPosition"); + nlassert(m_Idx.PZBModelPosition != ~0); } } // NL3D diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 4dc9a39bb..ccb2a6e96 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -78,6 +78,48 @@ const char *a_arbfp1 = "MOV result.color.yzw, R0;\n" "END\n"; +const char *a_ps_2_0 = + "ps_2_0\n" + // cgc version 3.1.0013, build date Apr 18 2012 + // command line args: -profile ps_2_0 + // source file: pp_stereo_debug.cg + //vendor NVIDIA Corporation + //version 3.1.0.13 + //profile ps_2_0 + //program pp_stereo_debug + //semantic pp_stereo_debug.cTex0 : TEX0 + //semantic pp_stereo_debug.cTex1 : TEX1 + //var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //var sampler2D cTex0 : TEX0 : texunit 0 : 1 : 1 + //var sampler2D cTex1 : TEX1 : texunit 1 : 2 : 1 + //var float4 oCol : $vout.COLOR : COL : 3 : 1 + //const c[0] = 0 1 0.5 + "dcl_2d s0\n" + "dcl_2d s1\n" + "def c0, 0.00000000, 1.00000000, 0.50000000, 0\n" + "dcl t0.xy\n" + "texld r1, t0, s1\n" + "texld r2, t0, s0\n" + "add r0, r2, -r1\n" + "add r1, r2, r1\n" + "mul r1, r1, c0.z\n" + "abs r0, r0\n" + "cmp r0, -r0, c0.x, c0.y\n" + "add_pp_sat r0.x, r0, r0.y\n" + "add_pp_sat r0.x, r0, r0.z\n" + "add_pp_sat r0.x, r0, r0.w\n" + "abs_pp r0.x, r0\n" + "cmp_pp r0.x, -r0, c0.y, c0\n" + "abs_pp r0.x, r0\n" + "mov r2.xzw, r1\n" + "mad r2.y, r1, c0.z, c0.z\n" + "cmp r2, -r0.x, r1, r2\n" + "mad r1.x, r2, c0.z, c0.z\n" + "mov r0.yzw, r2\n" + "cmp r0.x, -r0, r1, r2\n" + "mov oC0, r0\n"; +; + class CStereoDebuggerFactory : public IStereoDeviceFactory { public: @@ -116,27 +158,31 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); - IGPUProgram::CSource *source = new IGPUProgram::CSource(); - source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; - - /*if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { - nldebug("VR: fp40"); - m_PixelProgram = new CPixelProgram(a_fp40); - } - else*/ if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) - { - nldebug("VR: arbfp1"); - source->Profile = IGPUProgram::arbfp1; - source->setSourcePtr(a_arbfp1); m_PixelProgram = new CPixelProgram(); - m_PixelProgram->addSource(source); + // arbfp1 + { + IGPUProgram::CSource *source = new IGPUProgram::CSource(); + source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; + source->Profile = IGPUProgram::arbfp1; + source->setSourcePtr(a_arbfp1); + m_PixelProgram->addSource(source); + } + // ps_2_0 + { + IGPUProgram::CSource *source = new IGPUProgram::CSource(); + source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages; + source->Profile = IGPUProgram::ps_2_0; + source->setSourcePtr(a_ps_2_0); + m_PixelProgram->addSource(source); + } + if (!drvInternal->compilePixelProgram(m_PixelProgram)) + { + delete m_PixelProgram; + m_PixelProgram = NULL; + } } - /*else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) - { - nldebug("VR: ps_2_0"); - m_PixelProgram = new CPixelProgram(a_ps_2_0); - }*/ if (m_PixelProgram) { diff --git a/code/nel/src/3d/vegetable_manager.cpp b/code/nel/src/3d/vegetable_manager.cpp index d8a5aa198..2fcc25144 100644 --- a/code/nel/src/3d/vegetable_manager.cpp +++ b/code/nel/src/3d/vegetable_manager.cpp @@ -642,6 +642,8 @@ public: source->setSource(vpgram); + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["fog"] = 6; source->ParamIndices["programConstants0"] = 8; source->ParamIndices["directionalLight"] = 9; source->ParamIndices["viewCenter"] = 10; @@ -670,20 +672,33 @@ public: virtual void buildInfo() { m_Idx.ProgramConstants0 = getUniformIndex("programConstants0"); + nlassert(m_Idx.ProgramConstants0 != ~0); m_Idx.DirectionalLight = getUniformIndex("directionalLight"); + nlassert(m_Idx.DirectionalLight != ~0); m_Idx.ViewCenter = getUniformIndex("viewCenter"); + nlassert(m_Idx.ViewCenter != ~0); m_Idx.NegInvTransDist = getUniformIndex("negInvTransDist"); + nlassert(m_Idx.NegInvTransDist != ~0); m_Idx.AngleAxis = getUniformIndex("angleAxis"); + nlassert(m_Idx.AngleAxis != ~0); m_Idx.Wind = getUniformIndex("wind"); + nlassert(m_Idx.Wind != ~0); m_Idx.CosCoeff0 = getUniformIndex("cosCoeff0"); + nlassert(m_Idx.CosCoeff0 != ~0); m_Idx.CosCoeff1 = getUniformIndex("cosCoeff1"); + nlassert(m_Idx.CosCoeff1 != ~0); m_Idx.CosCoeff2 = getUniformIndex("cosCoeff2"); + nlassert(m_Idx.CosCoeff2 != ~0); m_Idx.QuatConstants = getUniformIndex("quatConstants"); + nlassert(m_Idx.QuatConstants != ~0); m_Idx.PiConstants = getUniformIndex("piConstants"); + nlassert(m_Idx.PiConstants != ~0); m_Idx.LUTSize = getUniformIndex("lutSize"); + nlassert(m_Idx.LUTSize != ~0); for (uint i = 0; i < NL3D_VEGETABLE_VP_LUT_SIZE; ++i) { m_Idx.LUT[i] = getUniformIndex(NLMISC::toString("lut[%i]", i)); + nlassert(m_Idx.LUT[i] != ~0); } } const CIdx &idx() const { return m_Idx; } diff --git a/code/nel/src/3d/water_env_map.cpp b/code/nel/src/3d/water_env_map.cpp index 65f66e622..e75fd172a 100644 --- a/code/nel/src/3d/water_env_map.cpp +++ b/code/nel/src/3d/water_env_map.cpp @@ -266,6 +266,7 @@ public: virtual void buildInfo() { m_Idx.ProgramConstant0 = getUniformIndex("programConstant0"); + nlassert(m_Idx.ProgramConstant0 != ~0); } inline const CIdx &idx() { return m_Idx; } private: diff --git a/code/nel/src/3d/water_shape.cpp b/code/nel/src/3d/water_shape.cpp index 2fff229c8..33f9bdfa4 100644 --- a/code/nel/src/3d/water_shape.cpp +++ b/code/nel/src/3d/water_shape.cpp @@ -125,15 +125,23 @@ CVertexProgramWaterVPNoWave::CVertexProgramWaterVPNoWave(bool diffuse) void CVertexProgramWaterVPNoWave::buildInfo() { m_Idx.BumpMap0Scale = getUniformIndex("bumpMap0Scale"); + nlassert(m_Idx.BumpMap0Scale != ~0); m_Idx.BumpMap0Offset = getUniformIndex("bumpMap0Offset"); + nlassert(m_Idx.BumpMap0Offset != ~0); m_Idx.BumpMap1Scale = getUniformIndex("bumpMap1Scale"); + nlassert(m_Idx.BumpMap1Scale != ~0); m_Idx.BumpMap1Offset = getUniformIndex("bumpMap1Offset"); + nlassert(m_Idx.BumpMap1Offset != ~0); m_Idx.ObserverHeight = getUniformIndex("observerHeight"); + nlassert(m_Idx.ObserverHeight != ~0); m_Idx.ScaleReflectedRay = getUniformIndex("scaleReflectedRay"); + nlassert(m_Idx.ScaleReflectedRay != ~0); if (m_Diffuse) { m_Idx.DiffuseMapVector0 = getUniformIndex("diffuseMapVector0"); + nlassert(m_Idx.DiffuseMapVector0 != ~0); m_Idx.DiffuseMapVector1 = getUniformIndex("diffuseMapVector1"); + nlassert(m_Idx.DiffuseMapVector1 != ~0); } } diff --git a/code/ryzom/client/src/decal.cpp b/code/ryzom/client/src/decal.cpp index bac27ebb6..5649b9b57 100644 --- a/code/ryzom/client/src/decal.cpp +++ b/code/ryzom/client/src/decal.cpp @@ -125,11 +125,17 @@ public: virtual void buildInfo() { m_Idx.WorldToUV0 = getUniformIndex("worldToUV0"); + nlassert(m_Idx.WorldToUV0 != ~0); m_Idx.WorldToUV1 = getUniformIndex("worldToUV1"); + nlassert(m_Idx.WorldToUV1 != ~0); m_Idx.RefCamDist = getUniformIndex("refCamDist"); + nlassert(m_Idx.RefCamDist != ~0); m_Idx.DistScaleBias = getUniformIndex("distScaleBias"); + nlassert(m_Idx.DistScaleBias != ~0); m_Idx.Diffuse = getUniformIndex("diffuse"); + nlassert(m_Idx.Diffuse != ~0); m_Idx.BlendScale = getUniformIndex("blendScale"); + nlassert(m_Idx.BlendScale != ~0); } inline const CIdx &idx() const { return m_Idx; } private: From 2ee6843cd916300c3ac0e158ac45ee97c1ce5beb Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 17:08:56 +0200 Subject: [PATCH 126/137] Fixes for d3d --- .../3d/driver/direct3d/driver_direct3d_pixel_program.cpp | 2 +- code/nel/src/3d/stereo_debugger.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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 01d3c4844..1519a9554 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 @@ -57,7 +57,7 @@ CPixelProgramDrvInfosD3D::~CPixelProgramDrvInfosD3D() bool CDriverD3D::supportPixelProgram (CPixelProgram::TProfile profile) const { H_AUTO_D3D(CDriverD3D_supportPixelProgram_profile) - return ((profile & 0xFFFF0000) == 0xD3D00000) + return ((profile & 0xFFFF0000) == 0xD9020000) && (_PixelProgramVersion >= (uint16)(profile & 0x0000FFFF)); } diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index ccb2a6e96..74d8806f0 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -118,7 +118,6 @@ const char *a_ps_2_0 = "mov r0.yzw, r2\n" "cmp r0.x, -r0, r1, r2\n" "mov oC0, r0\n"; -; class CStereoDebuggerFactory : public IStereoDeviceFactory { @@ -155,7 +154,8 @@ CStereoDebugger::~CStereoDebugger() void CStereoDebugger::setDriver(NL3D::UDriver *driver) { nlassert(!m_PixelProgram); - + + m_Driver = driver; NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) @@ -179,6 +179,8 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) } if (!drvInternal->compilePixelProgram(m_PixelProgram)) { + nlwarning("No supported pixel program for stereo debugger"); + delete m_PixelProgram; m_PixelProgram = NULL; } @@ -186,8 +188,6 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) if (m_PixelProgram) { - m_Driver = driver; - initTextures(); m_Mat = m_Driver->createMaterial(); From 2f384d9789c822ea90891283260cfb991c4fbbdd Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 17:09:05 +0200 Subject: [PATCH 127/137] Update veget implementation --- code/nel/include/nel/3d/vegetable_manager.h | 2 +- code/nel/src/3d/vegetable_manager.cpp | 49 +++++++++++---------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/code/nel/include/nel/3d/vegetable_manager.h b/code/nel/include/nel/3d/vegetable_manager.h index 8b3026794..ee21af3f3 100644 --- a/code/nel/include/nel/3d/vegetable_manager.h +++ b/code/nel/include/nel/3d/vegetable_manager.h @@ -344,7 +344,7 @@ private: /// setup the vertexProgram constants. - void setupVertexProgramConstants(IDriver *driver); + void setupVertexProgramConstants(IDriver *driver, bool fogEnabled); /** swap the RdrPass type (hard or soft) of the rdrPass of an instance group. diff --git a/code/nel/src/3d/vegetable_manager.cpp b/code/nel/src/3d/vegetable_manager.cpp index 2fcc25144..f2c8457f8 100644 --- a/code/nel/src/3d/vegetable_manager.cpp +++ b/code/nel/src/3d/vegetable_manager.cpp @@ -1866,7 +1866,7 @@ public: // *************************************************************************** -void CVegetableManager::setupVertexProgramConstants(IDriver *driver) +void CVegetableManager::setupVertexProgramConstants(IDriver *driver, bool fogEnabled) { nlassert(_ActiveVertexProgram); @@ -1874,37 +1874,40 @@ void CVegetableManager::setupVertexProgramConstants(IDriver *driver) // Standard // setup VertexProgram constants. // c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix(); - driver->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); + driver->setUniformMatrix(IDriver::VertexProgram, _ActiveVertexProgram->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); // c[6] take the Fog vector. After setupModelMatrix(); - driver->setConstantFog(6); + if (fogEnabled) + { + driver->setUniformFog(IDriver::VertexProgram, _ActiveVertexProgram->getUniformIndex(CGPUProgramIndex::Fog)); + } // c[8] take useful constants. - driver->setConstant(8, 0, 1, 0.5f, 2); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().ProgramConstants0, 0, 1, 0.5f, 2); // c[9] take normalized directional light - driver->setConstant(9, _DirectionalLight); + driver->setUniform3f(IDriver::VertexProgram, _ActiveVertexProgram->idx().DirectionalLight, _DirectionalLight); // c[10] take pos of camera - driver->setConstant(10, _ViewCenter); + driver->setUniform3f(IDriver::VertexProgram, _ActiveVertexProgram->idx().ViewCenter, _ViewCenter); // c[11] take factor for Blend formula - driver->setConstant(11, -1.f/NL3D_VEGETABLE_BLOCK_BLEND_TRANSITION_DIST, 0, 0, 0); + driver->setUniform1f(IDriver::VertexProgram, _ActiveVertexProgram->idx().NegInvTransDist, -1.f/NL3D_VEGETABLE_BLOCK_BLEND_TRANSITION_DIST); // Bend. // c[16]= quaternion axis. w==1, and z must be 0 - driver->setConstant( 16, _AngleAxis.x, _AngleAxis.y, _AngleAxis.z, 1); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().AngleAxis, _AngleAxis, 1); // c[17]= {timeAnim, WindPower, WindPower*(1-WindBendMin)/2, 0)} - driver->setConstant( 17, (float)_WindAnimTime, _WindPower, _WindPower*(1-_WindBendMin)/2, 0 ); + driver->setUniform3f(IDriver::VertexProgram, _ActiveVertexProgram->idx().Wind, (float)_WindAnimTime, _WindPower, _WindPower * (1 - _WindBendMin) / 2); // c[18]= High order Taylor cos coefficient: { -1/2, 1/24, -1/720, 1/40320 } - driver->setConstant( 18, -1/2.f, 1/24.f, -1/720.f, 1/40320.f ); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().CosCoeff0, -1/2.f, 1/24.f, -1/720.f, 1/40320.f ); // c[19]= Low order Taylor cos coefficient: { 1, -1/2, 1/24, -1/720 } - driver->setConstant( 19, 1, -1/2.f, 1/24.f, -1/720.f ); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().CosCoeff1, 1, -1/2.f, 1/24.f, -1/720.f ); // c[20]= Low order Taylor sin coefficient: { 1, -1/6, 1/120, -1/5040 } - driver->setConstant( 20, 1, -1/6.f, 1/120.f, -1/5040.f ); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().CosCoeff2, 1, -1/6.f, 1/120.f, -1/5040.f ); // c[21]= Special constant vector for quatToMatrix: { 0, 1, -1, 0 } - driver->setConstant( 21, 0.f, 1.f, -1.f, 0.f); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().QuatConstants, 0.f, 1.f, -1.f, 0.f); // c[22]= {0.5f, Pi, 2*Pi, 1/(2*Pi)} - driver->setConstant( 22, 0.5f, (float)Pi, (float)(2*Pi), (float)(1/(2*Pi)) ); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().PiConstants, 0.5f, (float)Pi, (float)(2*Pi), (float)(1/(2*Pi))); // c[23]= {NL3D_VEGETABLE_VP_LUT_SIZE, 0, 0, 0}. NL3D_VEGETABLE_VP_LUT_SIZE==64. - driver->setConstant( 23, NL3D_VEGETABLE_VP_LUT_SIZE, 0.f, 0.f, 0.f ); + driver->setUniform1f(IDriver::VertexProgram, _ActiveVertexProgram->idx().LUTSize, NL3D_VEGETABLE_VP_LUT_SIZE); // Fill constant. Start at 32. @@ -1912,7 +1915,7 @@ void CVegetableManager::setupVertexProgramConstants(IDriver *driver) { CVector2f cur= _WindTable[i]; CVector2f delta= _WindDeltaTable[i]; - driver->setConstant( 32+i, cur.x, cur.y, delta.x, delta.y ); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().LUT[i], cur.x, cur.y, delta.x, delta.y); } } @@ -2079,9 +2082,9 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front bool uprogst = driver->isUniformProgramState(); bool progstateset[NL3D_VEGETABLE_NRDRPASS]; - for (sint rdrPass=0; rdrPass < NL3D_VEGETABLE_NRDRPASS; rdrPass++) + for (sint rdrPass = 0; rdrPass < NL3D_VEGETABLE_NRDRPASS; ++rdrPass) { - progstateset[rdrPass] = !uprogst; + progstateset[rdrPass] = false; } /* @@ -2117,9 +2120,9 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front nlverify(driver->activeVertexProgram(_ActiveVertexProgram)); // Set VP constants - if (!progstateset[uprogst ? 0 : rdrPass]) + if (!progstateset[uprogst ? rdrPass : 0]) { - setupVertexProgramConstants(driver); + setupVertexProgramConstants(driver, uprogst ? fogged : true); } // Activate the unique material. @@ -2393,12 +2396,12 @@ void CVegetableManager::setupRenderStateForBlendLayerModel(IDriver *driver) nlverify(driver->activeVertexProgram(_ActiveVertexProgram)); // setup VP constants. - setupVertexProgramConstants(driver); + setupVertexProgramConstants(driver, fogged); - if (fogged) + /*if (fogged) // duplicate { driver->setConstantFog(6); - } + }*/ // Activate the unique material (correclty setuped for AlphaBlend in render()). driver->setupMaterial(_VegetableMaterial); From 7d854d54d184592bea1ab617ca1e38385c2f3d1c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 17:11:42 +0200 Subject: [PATCH 128/137] Modify calls in bloom effect --- code/nel/src/3d/bloom_effect.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 23d5c1e18..25439ee46 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -446,8 +446,8 @@ void CBloomEffect::applyBlur() // initialize vertex program drvInternal->activeVertexProgram(&TextureOffsetVertexProgram); - drvInternal->setConstant(8, 255.f, 255.f, 255.f, 255.f); - drvInternal->setConstant(9, 0.0f, 0.f, 0.f, 1.f); + drvInternal->setUniform4f(IDriver::VertexProgram, 8, 255.f, 255.f, 255.f, 255.f); + drvInternal->setUniform4f(IDriver::VertexProgram, 9, 0.0f, 0.f, 0.f, 1.f); // initialize blur material UMaterial displayBlurMat; @@ -552,8 +552,8 @@ void CBloomEffect::doBlur(bool horizontalBlur) // initialize vertex program drvInternal->activeVertexProgram(&TextureOffsetVertexProgram); - drvInternal->setConstant(8, 255.f, 255.f, 255.f, 255.f); - drvInternal->setConstant(9, 0.0f, 0.f, 0.f, 1.f); + drvInternal->setUniform4f(IDriver::VertexProgram, 8, 255.f, 255.f, 255.f, 255.f); + drvInternal->setUniform4f(IDriver::VertexProgram, 9, 0.0f, 0.f, 0.f, 1.f); // set several decal constants in order to obtain in the render target texture a mix of color // of a texel and its neighbored texels on the axe of the pass. @@ -572,10 +572,10 @@ void CBloomEffect::doBlur(bool horizontalBlur) decalR = 1.f; decal2R = 2.f; } - drvInternal->setConstant(10, (decalR/(float)_BlurWidth)*blurVec.x, (decalR/(float)_BlurHeight)*blurVec.y, 0.f, 0.f); - drvInternal->setConstant(11, (decal2R/(float)_BlurWidth)*blurVec.x, (decal2R/(float)_BlurHeight)*blurVec.y, 0.f, 0.f); - drvInternal->setConstant(12, (decalL/(float)_BlurWidth)*blurVec.x, (decalL/(float)_BlurHeight)*blurVec.y, 0.f, 0.f); - drvInternal->setConstant(13, (decal2L/(float)_BlurWidth)*blurVec.x, (decal2L/(float)_BlurHeight)*blurVec.y, 0.f, 0.f); + drvInternal->setUniform2f(IDriver::VertexProgram, 10, (decalR/(float)_BlurWidth)*blurVec.x, (decalR/(float)_BlurHeight)*blurVec.y); + drvInternal->setUniform2f(IDriver::VertexProgram, 11, (decal2R/(float)_BlurWidth)*blurVec.x, (decal2R/(float)_BlurHeight)*blurVec.y); + drvInternal->setUniform2f(IDriver::VertexProgram, 12, (decalL/(float)_BlurWidth)*blurVec.x, (decalL/(float)_BlurHeight)*blurVec.y); + drvInternal->setUniform2f(IDriver::VertexProgram, 13, (decal2L/(float)_BlurWidth)*blurVec.x, (decal2L/(float)_BlurHeight)*blurVec.y); // initialize material textures CMaterial * matObject = _BlurMat.getObjectPtr(); From ce7357ffa4e9be916795716a16341f63aca2dcbc Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 17:17:11 +0200 Subject: [PATCH 129/137] Do not use old interface here --- code/nel/src/3d/driver/opengl/driver_opengl.cpp | 6 ++++-- code/nel/src/3d/vegetable_manager.cpp | 2 +- code/ryzom/client/src/decal.cpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 3eff7eebf..946e69ee0 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -1415,11 +1415,13 @@ void CDriverGL::setupFog(float start, float end, CRGBA color) // last constant is used to store fog information (fog must be rescaled to [0, 1], because of a driver bug) if (start != end) { - setConstant(_EVSNumConstant, 1.f / (start - end), - end / (start - end), 0, 0); + float datas[] = { 1.f / (start - end), - end / (start - end), 0, 0 }; + nglSetInvariantEXT(_EVSConstantHandle + _EVSNumConstant, GL_FLOAT, datas); } else { - setConstant(_EVSNumConstant, 0.f, 0, 0, 0); + float datas[] = { 0.f, 0, 0, 0 }; + nglSetInvariantEXT(_EVSConstantHandle + _EVSNumConstant, GL_FLOAT, datas); } } } diff --git a/code/nel/src/3d/vegetable_manager.cpp b/code/nel/src/3d/vegetable_manager.cpp index f2c8457f8..ba5f721bb 100644 --- a/code/nel/src/3d/vegetable_manager.cpp +++ b/code/nel/src/3d/vegetable_manager.cpp @@ -2400,7 +2400,7 @@ void CVegetableManager::setupRenderStateForBlendLayerModel(IDriver *driver) /*if (fogged) // duplicate { - driver->setConstantFog(6); + driver->setCon/stantFog(6); }*/ // Activate the unique material (correclty setuped for AlphaBlend in render()). diff --git a/code/ryzom/client/src/decal.cpp b/code/ryzom/client/src/decal.cpp index 5649b9b57..a1cca247d 100644 --- a/code/ryzom/client/src/decal.cpp +++ b/code/ryzom/client/src/decal.cpp @@ -621,7 +621,7 @@ void CDecalRenderList::renderAllDecals() if (!forceNoVertexProgram && drvInternal->compileVertexProgram(&DecalAttenuationVertexProgram)) { drvInternal->activeVertexProgram(&DecalAttenuationVertexProgram); - //drvInternal->setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); + //drvInternal->setCons/tantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); drvInternal->setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().DistScaleBias, _DistScale, _DistBias, 0.f, 1.f); useVertexProgram = true; } From f7e80187ad08097719fb732c869707dc6b2468af Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 18:25:52 +0200 Subject: [PATCH 130/137] Adjust order for meshvp --- code/nel/src/3d/meshvp_per_pixel_light.cpp | 12 ++++++------ code/nel/src/3d/meshvp_wind_tree.cpp | 18 +++++++++++------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/code/nel/src/3d/meshvp_per_pixel_light.cpp b/code/nel/src/3d/meshvp_per_pixel_light.cpp index e4f43efc5..3e2828328 100644 --- a/code/nel/src/3d/meshvp_per_pixel_light.cpp +++ b/code/nel/src/3d/meshvp_per_pixel_light.cpp @@ -363,7 +363,7 @@ void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) { // init the vertexProgram code. static bool vpCreated= false; - if(!vpCreated) + if (!vpCreated) { vpCreated= true; @@ -437,6 +437,8 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, return false; } // + enable(true, drv); // must enable the vertex program before the vb is activated + // CRenderTrav *renderTrav= &scene->getRenderTrav(); /// Setup for gouraud lighting renderTrav->beginVPLightSetup(VPLightConstantStart, @@ -482,9 +484,7 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, // c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix(); drv->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); - // - enable(true, drv); // must enable the vertex program before the vb is activated - // + return true; } @@ -538,6 +538,8 @@ bool CMeshVPPerPixelLight::setupForMaterial(const CMaterial &mat, ) { bool enabled = (mat.getShader() == CMaterial::PerPixelLighting || mat.getShader() == CMaterial::PerPixelLightingNoSpec); + bool change = (enabled != _Enabled); + enable(enabled, drv); // enable disable the vertex program (for material that don't have the right shader) if (enabled) { CRenderTrav *renderTrav= &scene->getRenderTrav(); @@ -547,8 +549,6 @@ bool CMeshVPPerPixelLight::setupForMaterial(const CMaterial &mat, renderTrav->getStrongestLightColors(pplDiffuse, pplSpecular); drv->setPerPixelLightingLight(pplDiffuse, pplSpecular, mat.getShininess()); } - bool change = (enabled != _Enabled); - enable(enabled, drv); // enable disable the vertex program (for material that don't have the right shader) return change; } //================================================================================= diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index bf1bc0c4e..477814f6f 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -291,30 +291,34 @@ bool CMeshVPWindTree::begin(IDriver *driver, CScene *scene, CMeshBaseInstance *m if (!(driver->supportVertexProgram() && !driver->isVertexProgramEmulated())) return false; - // precompute mesh - setupPerMesh(driver, scene); - - // Setup instance constants - setupPerInstanceConstants(driver, scene, mbi, invertedModelMat); - // Activate the good VertexProgram //=============== + // Get how many pointLights are setuped now. nlassert(scene != NULL); CRenderTrav *renderTrav= &scene->getRenderTrav(); sint numPls= renderTrav->getNumVPLights()-1; clamp(numPls, 0, CRenderTrav::MaxVPLight-1); + // Enable normalize only if requested by user. Because lighting don't manage correct "scale lighting" uint idVP= (SpecularLighting?2:0) + (driver->isForceNormalize()?1:0) ; // correct VP id for correct unmber of pls. idVP= numPls*4 + idVP; - // activate VP. driver->activeVertexProgram(_VertexProgram[idVP]); + // precompute mesh + setupPerMesh(driver, scene); + + // Setup instance constants + setupPerInstanceConstants(driver, scene, mbi, invertedModelMat); + + + + return true; } From 482c13fd1a02a6c42c4a592d9122454a5813501f Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 19:03:05 +0200 Subject: [PATCH 131/137] Add container for lighted vertex program --- code/nel/include/nel/3d/render_trav.h | 41 +++++++++++++++++- code/nel/src/3d/meshvp_per_pixel_light.cpp | 4 +- code/nel/src/3d/meshvp_wind_tree.cpp | 2 +- code/nel/src/3d/render_trav.cpp | 50 +++++++++++++++++++++- 4 files changed, 91 insertions(+), 6 deletions(-) diff --git a/code/nel/include/nel/3d/render_trav.h b/code/nel/include/nel/3d/render_trav.h index 6e8d04b32..76931d68f 100644 --- a/code/nel/include/nel/3d/render_trav.h +++ b/code/nel/include/nel/3d/render_trav.h @@ -27,6 +27,7 @@ #include "nel/3d/mesh_block_manager.h" #include "nel/3d/shadow_map_manager.h" #include "nel/3d/u_scene.h" +#include "nel/3d/vertex_program.h" #include @@ -68,6 +69,41 @@ class CWaterModel; #define NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES 3000 #define NL3D_SHADOW_MESH_SKIN_MANAGER_NUMVB 8 +/// Container for lighted vertex program. +class CVertexProgramLighted : CVertexProgram +{ +public: + static const uint MaxLight = 4; + static const uint MaxPointLight = (MaxLight - 1); + struct CIdxLighted + { + uint Ambient; + uint Diffuse[MaxLight]; + uint Specular[MaxLight]; + uint DirOrPos[MaxLight]; // light 0, directional sun; light 1,2,3, omni point light + uint EyePosition; + uint DiffuseAlpha; + }; + struct CFeaturesLighted + { + /// Number of point lights that this program is generated for, varies from 0 to 3. + uint NumActivePointLights; + bool SupportSpecular; + bool Normalize; + /// Start of constants to use for lighting with assembly shaders. + uint CtStartNeLVP; + }; + CVertexProgramLighted() { } + virtual ~CVertexProgramLighted() { } + virtual void buildInfo(); + const CIdxLighted &idxLighted() const { return m_IdxLighted; } + const CFeaturesLighted &featuresLighted() const { return m_FeaturesLighted; } + +private: + CIdxLighted m_IdxLighted; + CFeaturesLighted m_FeaturesLighted; + +}; // *************************************************************************** @@ -224,7 +260,7 @@ public: // @{ // Max VP Light setup Infos. - enum {MaxVPLight= 4}; + enum {MaxVPLight = CVertexProgramLighted::MaxLight}; /** reset the lighting setup in the driver (all lights are disabled). * called at beginning of traverse(). Must be called by any model (before and after rendering) @@ -299,7 +335,8 @@ public: * \param numActivePoinLights tells how many point light from 0 to 3 this VP must handle. NB: the Sun directionnal is not option * NB: nlassert(numActiveLights<=MaxVPLight-1). */ - static std::string getLightVPFragment(uint numActivePointLights, uint ctStart, bool supportSpecular, bool normalize); + static std::string getLightVPFragmentNeLVP(uint numActivePointLights, uint ctStart, bool supportSpecular, bool normalize); + // TODO_VP_GLSL /** This returns a reference to a driver light, by its index * \see getStrongestLightIndex diff --git a/code/nel/src/3d/meshvp_per_pixel_light.cpp b/code/nel/src/3d/meshvp_per_pixel_light.cpp index 3e2828328..809dd16c8 100644 --- a/code/nel/src/3d/meshvp_per_pixel_light.cpp +++ b/code/nel/src/3d/meshvp_per_pixel_light.cpp @@ -393,10 +393,10 @@ void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) for (uint vp = 0; vp < NumVp; ++vp) { // \todo yoyo TODO_OPTIM Manage different number of pointLights - // NB: never call getLightVPFragment() with normalize, because already done by PerPixel fragment before. + // NB: never call getLightVPFragmentNeLVP() with normalize, because already done by PerPixel fragment before. std::string vpCode = std::string(vpName[vp]) + std::string("# ***************") // temp for debug - + CRenderTrav::getLightVPFragment(CRenderTrav::MaxVPLight-1, VPLightConstantStart, (vp & 2) != 0, false) + + CRenderTrav::getLightVPFragmentNeLVP(CRenderTrav::MaxVPLight-1, VPLightConstantStart, (vp & 2) != 0, false) + std::string("# ***************") // temp for debug + std::string(PPLightingVPCodeEnd); #ifdef NL_DEBUG diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index 477814f6f..85a5550e8 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -155,7 +155,7 @@ void CMeshVPWindTree::initInstance(CMeshBaseInstance *mbi) // combine fragments vpCode= string(WindTreeVPCodeWave) - + CRenderTrav::getLightVPFragment(numPls, VPLightConstantStart, specular, normalize) + + CRenderTrav::getLightVPFragmentNeLVP(numPls, VPLightConstantStart, specular, normalize) + WindTreeVPCodeEnd; _VertexProgram[i] = new CVertexProgram(vpCode.c_str()); // TODO_VP_GLSL diff --git a/code/nel/src/3d/render_trav.cpp b/code/nel/src/3d/render_trav.cpp index 5cf6fd20e..eba42e724 100644 --- a/code/nel/src/3d/render_trav.cpp +++ b/code/nel/src/3d/render_trav.cpp @@ -1168,8 +1168,56 @@ static void strReplaceAll(string &strInOut, const string &tokenSrc, const string } } +void CVertexProgramLighted::buildInfo() +{ + if (m_FeaturesLighted.CtStartNeLVP != ~0) + { + // Fixed uniform locations + m_IdxLighted.Ambient = 0; + for (uint i = 0; i < MaxLight; ++i) + { + m_IdxLighted.Diffuse[i] = 1 + i; + } + if (m_FeaturesLighted.SupportSpecular) + { + for (uint i = 0; i < MaxLight; ++i) + { + m_IdxLighted.Specular[i] = 5 + i; + } + m_IdxLighted.DirOrPos[0] = 9; + for (uint i = 1; i < MaxLight; ++i) + { + m_IdxLighted.DirOrPos[i] = (12 - 1) + i; + } + m_IdxLighted.DiffuseAlpha = 10; + m_IdxLighted.EyePosition = 11; + } + else + { + for (uint i = 0; i < MaxLight; ++i) + { + m_IdxLighted.Specular[i] = ~0; + } + for (uint i = 0; i < MaxLight; ++i) + { + m_IdxLighted.DirOrPos[i] = 5 + i; + } + m_IdxLighted.DiffuseAlpha = 9; + m_IdxLighted.EyePosition = ~0; + } + } + else + { + // Named uniform locations + // TODO_VP_GLSL + // m_IdxLighted.Ambient = getUniformIndex("ambient"); + // etc + } +} + +// generates the lighting part of a vertex program, nelvp profile // *************************************************************************** -std::string CRenderTrav::getLightVPFragment(uint numActivePointLights, uint ctStart, bool supportSpecular, bool normalize) +std::string CRenderTrav::getLightVPFragmentNeLVP(uint numActivePointLights, uint ctStart, bool supportSpecular, bool normalize) { string ret; From ba945f30a89645785d848ed9448dd2a5cdb6bae9 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 20:00:20 +0200 Subject: [PATCH 132/137] Use lighted vertex program container for per pixel light program --- .../include/nel/3d/meshvp_per_pixel_light.h | 5 +- code/nel/include/nel/3d/meshvp_wind_tree.h | 2 +- code/nel/include/nel/3d/render_trav.h | 4 +- code/nel/src/3d/meshvp_per_pixel_light.cpp | 123 ++++++++++++------ code/nel/src/3d/render_trav.cpp | 3 +- 5 files changed, 94 insertions(+), 43 deletions(-) diff --git a/code/nel/include/nel/3d/meshvp_per_pixel_light.h b/code/nel/include/nel/3d/meshvp_per_pixel_light.h index 5df1bfc16..d81143eac 100644 --- a/code/nel/include/nel/3d/meshvp_per_pixel_light.h +++ b/code/nel/include/nel/3d/meshvp_per_pixel_light.h @@ -27,6 +27,7 @@ namespace NL3D { +class CVertexProgramPerPixelLight; /** * This vertex program is used to perform perpixel lighting with meshs. Its outputs are : @@ -49,6 +50,8 @@ namespace NL3D { class CMeshVPPerPixelLight : public IMeshVertexProgram { public: + friend class CVertexProgramPerPixelLight; + /// true if want Specular Lighting. bool SpecularLighting; public: @@ -84,7 +87,7 @@ private: bool _IsPointLight; // enum { NumVp = 8}; - static NLMISC::CSmartPtr _VertexProgram[NumVp]; + static NLMISC::CSmartPtr _VertexProgram[NumVp]; }; } // NL3D diff --git a/code/nel/include/nel/3d/meshvp_wind_tree.h b/code/nel/include/nel/3d/meshvp_wind_tree.h index 4e5d2875a..a19f6b43d 100644 --- a/code/nel/include/nel/3d/meshvp_wind_tree.h +++ b/code/nel/include/nel/3d/meshvp_wind_tree.h @@ -112,7 +112,7 @@ private: /** The 16 versions: Specular or not (0 or 2), + normalize normal or not (0 or 1). * All multiplied by 4, because support from 0 to 3 pointLights activated. (0.., 4.., 8.., 12..) */ - static NLMISC::CSmartPtr _VertexProgram[NumVp]; + static NLMISC::CSmartPtr _VertexProgram[NumVp]; // WindTree Time for this mesh param setup. Stored in mesh because same for all instances. float _CurrentTime[HrcDepth]; diff --git a/code/nel/include/nel/3d/render_trav.h b/code/nel/include/nel/3d/render_trav.h index 76931d68f..fe37b5930 100644 --- a/code/nel/include/nel/3d/render_trav.h +++ b/code/nel/include/nel/3d/render_trav.h @@ -70,7 +70,7 @@ class CWaterModel; #define NL3D_SHADOW_MESH_SKIN_MANAGER_NUMVB 8 /// Container for lighted vertex program. -class CVertexProgramLighted : CVertexProgram +class CVertexProgramLighted : public CVertexProgram { public: static const uint MaxLight = 4; @@ -99,7 +99,7 @@ public: const CIdxLighted &idxLighted() const { return m_IdxLighted; } const CFeaturesLighted &featuresLighted() const { return m_FeaturesLighted; } -private: +protected: CIdxLighted m_IdxLighted; CFeaturesLighted m_FeaturesLighted; diff --git a/code/nel/src/3d/meshvp_per_pixel_light.cpp b/code/nel/src/3d/meshvp_per_pixel_light.cpp index 809dd16c8..a7a04f265 100644 --- a/code/nel/src/3d/meshvp_per_pixel_light.cpp +++ b/code/nel/src/3d/meshvp_per_pixel_light.cpp @@ -32,14 +32,13 @@ namespace NL3D { -NLMISC::CSmartPtr CMeshVPPerPixelLight::_VertexProgram[NumVp]; + +NLMISC::CSmartPtr CMeshVPPerPixelLight::_VertexProgram[NumVp]; // *************************************************************************** // Light VP fragment constants start at 24 static const uint VPLightConstantStart = 24; - - // *************************************************************************** // *************************************************************************** @@ -355,18 +354,33 @@ static const char* PPLightingVPCodeTest = "; ***************************************************************/ - - - -//================================================================================= -void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) +class CVertexProgramPerPixelLight : public CVertexProgramLighted { - // init the vertexProgram code. - static bool vpCreated= false; - if (!vpCreated) +public: + class CIdx { - vpCreated= true; + }; + CVertexProgramPerPixelLight(uint vp); + virtual ~CVertexProgramPerPixelLight() { }; + virtual void buildInfo(); + const CIdx &idx() const { return m_Idx; } + +private: + CIdx m_Idx; + +}; + +CVertexProgramPerPixelLight::CVertexProgramPerPixelLight(uint vp) +{ + // lighted settings + m_FeaturesLighted.SupportSpecular = (vp & 2) != 0; + m_FeaturesLighted.NumActivePointLights = MaxLight - 1; + m_FeaturesLighted.Normalize = false; + m_FeaturesLighted.CtStartNeLVP = VPLightConstantStart; + + // nelvp + { // Gives each vp name // Bit 0 : 1 when it is a directionnal light // Bit 1 : 1 when specular is needed @@ -389,34 +403,67 @@ void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) }; uint numvp = sizeof(vpName) / sizeof(const char *); - nlassert(NumVp == numvp); // make sure that it is in sync with header..todo : compile time assert :) + nlassert(CMeshVPPerPixelLight::NumVp == numvp); // make sure that it is in sync with header..todo : compile time assert :) + + // \todo yoyo TODO_OPTIM Manage different number of pointLights + // NB: never call getLightVPFragmentNeLVP() with normalize, because already done by PerPixel fragment before. + std::string vpCode = std::string(vpName[vp]) + + std::string("# ***************") // temp for debug + + CRenderTrav::getLightVPFragmentNeLVP( + m_FeaturesLighted.NumActivePointLights, + m_FeaturesLighted.CtStartNeLVP, + m_FeaturesLighted.SupportSpecular, + m_FeaturesLighted.Normalize) + + std::string("# ***************") // temp for debug + + std::string(PPLightingVPCodeEnd); + #ifdef NL_DEBUG + /** For test : parse those programs before they are used. + * As a matter of fact some program will works with the NV_VERTEX_PROGRAM extension, + * but won't with EXT_vertex_shader, because there are some limitations (can't read a temp + * register that hasn't been written before..) + */ + CVPParser vpParser; + CVPParser::TProgram result; + std::string parseOutput; + if (!vpParser.parse(vpCode.c_str(), result, parseOutput)) + { + nlwarning(parseOutput.c_str()); + nlassert(0); + } + #endif + + CSource *source = new CSource(); + source->DisplayName = NLMISC::toString("nelvp/MeshVPPerPixel/%i", vp); + source->Profile = CVertexProgram::nelvp; + source->setSource(vpCode); + addSource(source); + } + + // glsl + { + // TODO_VP_GLSL + } +} + +void CVertexProgramPerPixelLight::buildInfo() +{ + CVertexProgramLighted::buildInfo(); +} + + +//================================================================================= +void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) +{ + // init the vertexProgram code. + static bool vpCreated= false; + if (!vpCreated) + { + vpCreated = true; + for (uint vp = 0; vp < NumVp; ++vp) { - // \todo yoyo TODO_OPTIM Manage different number of pointLights - // NB: never call getLightVPFragmentNeLVP() with normalize, because already done by PerPixel fragment before. - std::string vpCode = std::string(vpName[vp]) - + std::string("# ***************") // temp for debug - + CRenderTrav::getLightVPFragmentNeLVP(CRenderTrav::MaxVPLight-1, VPLightConstantStart, (vp & 2) != 0, false) - + std::string("# ***************") // temp for debug - + std::string(PPLightingVPCodeEnd); - #ifdef NL_DEBUG - /** For test : parse those programs before they are used. - * As a matter of fact some program will works with the NV_VERTEX_PROGRAM extension, - * but won't with EXT_vertex_shader, because there are some limitations (can't read a temp - * register that hasn't been written before..) - */ - CVPParser vpParser; - CVPParser::TProgram result; - std::string parseOutput; - if (!vpParser.parse(vpCode.c_str(), result, parseOutput)) - { - nlwarning(parseOutput.c_str()); - nlassert(0); - } - #endif - _VertexProgram[vp] = new CVertexProgram(vpCode.c_str()); + _VertexProgram[vp] = new CVertexProgramPerPixelLight(vp); } - } } @@ -521,7 +568,7 @@ void CMeshVPPerPixelLight::enable(bool enabled, IDriver *drv) | (SpecularLighting ? 2 : 0) | (_IsPointLight ? 1 : 0); // - drv->activeVertexProgram(_VertexProgram[idVP]); + drv->activeVertexProgram((CVertexProgramPerPixelLight *)_VertexProgram[idVP]); } else { diff --git a/code/nel/src/3d/render_trav.cpp b/code/nel/src/3d/render_trav.cpp index eba42e724..5735e71e1 100644 --- a/code/nel/src/3d/render_trav.cpp +++ b/code/nel/src/3d/render_trav.cpp @@ -1170,7 +1170,8 @@ static void strReplaceAll(string &strInOut, const string &tokenSrc, const string void CVertexProgramLighted::buildInfo() { - if (m_FeaturesLighted.CtStartNeLVP != ~0) + CVertexProgram::buildInfo(); + if (profile() == nelvp) { // Fixed uniform locations m_IdxLighted.Ambient = 0; From a0fbb152ee48182df9318cf27d7ab060f36789dd Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 20:45:06 +0200 Subject: [PATCH 133/137] Updated wind tree program container --- code/nel/include/nel/3d/meshvp_wind_tree.h | 4 +- code/nel/src/3d/meshvp_wind_tree.cpp | 96 +++++++++++++++++----- 2 files changed, 78 insertions(+), 22 deletions(-) diff --git a/code/nel/include/nel/3d/meshvp_wind_tree.h b/code/nel/include/nel/3d/meshvp_wind_tree.h index a19f6b43d..b33ac7587 100644 --- a/code/nel/include/nel/3d/meshvp_wind_tree.h +++ b/code/nel/include/nel/3d/meshvp_wind_tree.h @@ -24,6 +24,7 @@ namespace NL3D { +class CVertexProgramWindTree; // *************************************************************************** /** @@ -35,6 +36,7 @@ namespace NL3D { class CMeshVPWindTree : public IMeshVertexProgram { public: + friend class CVertexProgramWindTree; enum {HrcDepth= 3}; @@ -112,7 +114,7 @@ private: /** The 16 versions: Specular or not (0 or 2), + normalize normal or not (0 or 1). * All multiplied by 4, because support from 0 to 3 pointLights activated. (0.., 4.., 8.., 12..) */ - static NLMISC::CSmartPtr _VertexProgram[NumVp]; + static NLMISC::CSmartPtr _VertexProgram[NumVp]; // WindTree Time for this mesh param setup. Stored in mesh because same for all instances. float _CurrentTime[HrcDepth]; diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index 85a5550e8..ca7964ac1 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -35,11 +35,11 @@ namespace NL3D // *************************************************************************** // Light VP fragment constants start at 24 -static const uint VPLightConstantStart= 24; +static const uint VPLightConstantStart = 24; // *************************************************************************** -NLMISC::CSmartPtr CMeshVPWindTree::_VertexProgram[CMeshVPWindTree::NumVp]; +NLMISC::CSmartPtr CMeshVPWindTree::_VertexProgram[CMeshVPWindTree::NumVp]; static const char* WindTreeVPCodeWave= "!!VP1.0 \n\ @@ -79,6 +79,59 @@ static const char* WindTreeVPCodeEnd= END \n\ "; + +class CVertexProgramWindTree : public CVertexProgramLighted +{ +public: + class CIdx + { + + }; + CVertexProgramWindTree(uint numPls, bool specular, bool normalize); + virtual ~CVertexProgramWindTree() { }; + virtual void buildInfo(); + const CIdx &idx() const { return m_Idx; } + + bool PerMeshSetup; + +private: + CIdx m_Idx; + +}; + +CVertexProgramWindTree::CVertexProgramWindTree(uint numPls, bool specular, bool normalize) +{ + // lighted settings + m_FeaturesLighted.SupportSpecular = specular; + m_FeaturesLighted.NumActivePointLights = numPls; + m_FeaturesLighted.Normalize = normalize; + m_FeaturesLighted.CtStartNeLVP = VPLightConstantStart; + + // constants cache + PerMeshSetup = false; + + // nelvp + { + std::string vpCode = std::string(WindTreeVPCodeWave) + + CRenderTrav::getLightVPFragmentNeLVP(numPls, VPLightConstantStart, specular, normalize) + + WindTreeVPCodeEnd; + + CSource *source = new CSource(); + source->DisplayName = NLMISC::toString("nelvp/MeshVPWindTree/%i/%s/%s", numPls, specular ? "spec" : "nospec", normalize ? "normalize" : "nonormalize"); + source->Profile = CVertexProgram::nelvp; + source->setSource(vpCode); + addSource(source); + } + + // TODO_VP_GLSL +} + +void CVertexProgramWindTree::buildInfo() +{ + CVertexProgramLighted::buildInfo(); +} + + // *************************************************************************** float CMeshVPWindTree::speedCos(float angle) { @@ -142,9 +195,6 @@ void CMeshVPWindTree::initInstance(CMeshBaseInstance *mbi) // All vpcode and begin() written for HrcDepth==3 nlassert(HrcDepth==3); - // combine fragments. - string vpCode; - // For all possible VP. for(uint i=0;i 0. */ - _LastMBRIdVP= 0; + _LastMBRIdVP = 0; // activate VP. driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); + + // precompute mesh + setupPerMesh(driver, scene); + _VertexProgram[_LastMBRIdVP]->PerMeshSetup = true; } // *************************************************************************** void CMeshVPWindTree::beginMBRInstance(IDriver *driver, CScene *scene, CMeshBaseInstance *mbi, const NLMISC::CMatrix &invertedModelMat) { - // setup first constants for this instance - setupPerInstanceConstants(driver, scene, mbi, invertedModelMat); - // Get how many pointLights are setuped now. nlassert(scene != NULL); CRenderTrav *renderTrav= &scene->getRenderTrav(); @@ -403,16 +447,26 @@ void CMeshVPWindTree::beginMBRInstance(IDriver *driver, CScene *scene, CMeshBase clamp(numPls, 0, CRenderTrav::MaxVPLight-1); // Enable normalize only if requested by user. Because lighting don't manage correct "scale lighting" - uint idVP= (SpecularLighting?2:0) + (driver->isForceNormalize()?1:0) ; + uint idVP = (SpecularLighting?2:0) + (driver->isForceNormalize()?1:0) ; // correct VP id for correct number of pls. - idVP= numPls*4 + idVP; + idVP = numPls*4 + idVP; // re-activate VP if idVP different from last setup - if( idVP!=_LastMBRIdVP ) + if(idVP != _LastMBRIdVP) { _LastMBRIdVP= idVP; driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); + + if (!_VertexProgram[_LastMBRIdVP]->PerMeshSetup) + { + // precompute mesh + setupPerMesh(driver, scene); + _VertexProgram[_LastMBRIdVP]->PerMeshSetup = true; + } } + + // setup first constants for this instance + setupPerInstanceConstants(driver, scene, mbi, invertedModelMat); } // *************************************************************************** From edec14807fe0715379926cba0533da239f153758 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 21:31:47 +0200 Subject: [PATCH 134/137] Use named uniform indices for lighted vertex program --- code/nel/include/nel/3d/driver.h | 1 + .../include/nel/3d/meshvp_per_pixel_light.h | 2 + code/nel/include/nel/3d/meshvp_wind_tree.h | 2 + code/nel/include/nel/3d/render_trav.h | 8 +- .../src/3d/driver/direct3d/driver_direct3d.h | 1 + .../direct3d/driver_direct3d_uniform.cpp | 5 + code/nel/src/3d/driver/opengl/driver_opengl.h | 1 + .../driver/opengl/driver_opengl_uniform.cpp | 5 + code/nel/src/3d/meshvp_per_pixel_light.cpp | 6 +- code/nel/src/3d/meshvp_wind_tree.cpp | 8 +- code/nel/src/3d/render_trav.cpp | 97 ++++++++++--------- 11 files changed, 81 insertions(+), 55 deletions(-) diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index a97606a97..38c0f6c32 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1191,6 +1191,7 @@ public: virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) = 0; virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v) = 0; virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3) = 0; + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) = 0; virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) = 0; virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src) = 0; virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) = 0; diff --git a/code/nel/include/nel/3d/meshvp_per_pixel_light.h b/code/nel/include/nel/3d/meshvp_per_pixel_light.h index d81143eac..a234feddd 100644 --- a/code/nel/include/nel/3d/meshvp_per_pixel_light.h +++ b/code/nel/include/nel/3d/meshvp_per_pixel_light.h @@ -88,6 +88,8 @@ private: // enum { NumVp = 8}; static NLMISC::CSmartPtr _VertexProgram[NumVp]; + + NLMISC::CRefPtr _ActiveVertexProgram; }; } // NL3D diff --git a/code/nel/include/nel/3d/meshvp_wind_tree.h b/code/nel/include/nel/3d/meshvp_wind_tree.h index b33ac7587..2e353da05 100644 --- a/code/nel/include/nel/3d/meshvp_wind_tree.h +++ b/code/nel/include/nel/3d/meshvp_wind_tree.h @@ -116,6 +116,8 @@ private: */ static NLMISC::CSmartPtr _VertexProgram[NumVp]; + NLMISC::CRefPtr _ActiveVertexProgram; + // WindTree Time for this mesh param setup. Stored in mesh because same for all instances. float _CurrentTime[HrcDepth]; double _LastSceneTime; diff --git a/code/nel/include/nel/3d/render_trav.h b/code/nel/include/nel/3d/render_trav.h index fe37b5930..61d62e94c 100644 --- a/code/nel/include/nel/3d/render_trav.h +++ b/code/nel/include/nel/3d/render_trav.h @@ -289,7 +289,7 @@ public: * \param supportSpecular asitsounds. PointLights and dirLight are localViewer * \param invObjectWM the inverse of object matrix: lights are mul by this. Vp compute in object space. */ - void beginVPLightSetup(uint ctStart, bool supportSpecular, const CMatrix &invObjectWM); + void beginVPLightSetup(CVertexProgramLighted *program, const CMatrix &invObjectWM); /** change the driver VP LightSetup constants which depends on material. * \param excludeStrongest This remove the strongest light from the setup. The typical use is to have it computed by using perpixel lighting. @@ -418,12 +418,14 @@ private: mutable uint _StrongestLightIndex; mutable bool _StrongestLightTouched; + // Current vp setuped with beginVPLightSetup() + NLMISC::CRefPtr _VPCurrent; // Current ctStart setuped with beginVPLightSetup() - uint _VPCurrentCtStart; + //uint _VPCurrentCtStart; // Current num of VP lights enabled. uint _VPNumLights; // Current support of specular - bool _VPSupportSpecular; + //bool _VPSupportSpecular; // Sum of all ambiant of all lights + ambiantGlobal. NLMISC::CRGBAF _VPFinalAmbient; // Diffuse/Spec comp of all light / 255. diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 80b39f786..d21bef92f 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -1200,6 +1200,7 @@ public: virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v); virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3); + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba); virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m); virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src); virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src); 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 a77a86549..e44780e89 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp @@ -138,6 +138,11 @@ void CDriverD3D::setUniform4f(TProgram program, uint index, const NLMISC::CVecto CDriverD3D::setUniform4f(program, index, v.x, v.y, v.z, f3); } +void CDriverD3D::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) +{ + CDriverD3D::setUniform4fv(program, index, 1, &rgba.R); +} + void CDriverD3D::setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) { H_AUTO_D3D(CDriverD3D_setUniform4x4f); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index e20d7d4fa..afab8209c 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1406,6 +1406,7 @@ private: virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v); virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3); + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba); virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m); virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src); virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src); 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 658b6739a..deee62379 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -169,6 +169,11 @@ void CDriverGL::setUniform4f(TProgram program, uint index, const NLMISC::CVector CDriverGL::setUniform4f(program, index, v.x, v.y, v.z, f3); } +void CDriverGL::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) +{ + CDriverGL::setUniform4fv(program, index, 1, &rgba.R); +} + void CDriverGL::setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) { H_AUTO_OGL(CDriverGL_setUniform4x4f); diff --git a/code/nel/src/3d/meshvp_per_pixel_light.cpp b/code/nel/src/3d/meshvp_per_pixel_light.cpp index a7a04f265..cf2d35f39 100644 --- a/code/nel/src/3d/meshvp_per_pixel_light.cpp +++ b/code/nel/src/3d/meshvp_per_pixel_light.cpp @@ -488,9 +488,7 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, // CRenderTrav *renderTrav= &scene->getRenderTrav(); /// Setup for gouraud lighting - renderTrav->beginVPLightSetup(VPLightConstantStart, - SpecularLighting, - invertedModelMat); + renderTrav->beginVPLightSetup(_ActiveVertexProgram, invertedModelMat); // sint strongestLightIndex = renderTrav->getStrongestLightIndex(); if (strongestLightIndex == -1) return false; // if no strongest light, disable this vertex program @@ -569,10 +567,12 @@ void CMeshVPPerPixelLight::enable(bool enabled, IDriver *drv) | (_IsPointLight ? 1 : 0); // drv->activeVertexProgram((CVertexProgramPerPixelLight *)_VertexProgram[idVP]); + _ActiveVertexProgram = _VertexProgram[idVP]; } else { drv->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; } _Enabled = enabled; } diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index ca7964ac1..17e847c3e 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -354,6 +354,7 @@ bool CMeshVPWindTree::begin(IDriver *driver, CScene *scene, CMeshBaseInstance *m idVP= numPls*4 + idVP; // activate VP. driver->activeVertexProgram(_VertexProgram[idVP]); + _ActiveVertexProgram = _VertexProgram[idVP]; // precompute mesh @@ -373,6 +374,7 @@ void CMeshVPWindTree::end(IDriver *driver) { // Disable the VertexProgram driver->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; } // *************************************************************************** @@ -398,7 +400,8 @@ void CMeshVPWindTree::setupLighting(CScene *scene, CMeshBaseInstance *mbi, const nlassert(scene != NULL); CRenderTrav *renderTrav= &scene->getRenderTrav(); // setup cte for lighting - renderTrav->beginVPLightSetup(VPLightConstantStart, SpecularLighting, invertedModelMat); + CVertexProgramWindTree *program = _ActiveVertexProgram; + renderTrav->beginVPLightSetup(program, invertedModelMat); } @@ -431,6 +434,7 @@ void CMeshVPWindTree::beginMBRMesh(IDriver *driver, CScene *scene) // activate VP. driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); + _ActiveVertexProgram = _VertexProgram[_LastMBRIdVP]; // precompute mesh setupPerMesh(driver, scene); @@ -456,6 +460,7 @@ void CMeshVPWindTree::beginMBRInstance(IDriver *driver, CScene *scene, CMeshBase { _LastMBRIdVP= idVP; driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); + _ActiveVertexProgram = _VertexProgram[_LastMBRIdVP]; if (!_VertexProgram[_LastMBRIdVP]->PerMeshSetup) { @@ -474,6 +479,7 @@ void CMeshVPWindTree::endMBRMesh(IDriver *driver) { // Disable the VertexProgram driver->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; } // *************************************************************************** diff --git a/code/nel/src/3d/render_trav.cpp b/code/nel/src/3d/render_trav.cpp index 5735e71e1..4b43d18e9 100644 --- a/code/nel/src/3d/render_trav.cpp +++ b/code/nel/src/3d/render_trav.cpp @@ -762,13 +762,15 @@ void CRenderTrav::changeLightSetup(CLightContribution *lightContribution, bool // *************************************************************************** -void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const CMatrix &invObjectWM) +void CRenderTrav::beginVPLightSetup(CVertexProgramLighted *program, const CMatrix &invObjectWM) { uint i; nlassert(MaxVPLight==4); _VPNumLights= min(_NumLightEnabled, (uint)MaxVPLight); - _VPCurrentCtStart= ctStart; - _VPSupportSpecular= supportSpecular; + // _VPCurrentCtStart= ctStart; + // _VPSupportSpecular= supportSpecular; + _VPCurrent = program; + bool supportSpecular = program->featuresLighted().SupportSpecular; // Prepare Colors (to be multiplied by material) //================ @@ -786,8 +788,11 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C // reset other to 0. for(; isetConstant(_VPCurrentCtStart+1+i, 0.f, 0.f, 0.f, 0.f); + _VPLightDiffuse[i] = CRGBA::Black; + if (program->idxLighted().Diffuse[i] != ~0) + { + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], 0.f, 0.f, 0.f, 0.f); + } } // Specular. _VPCurrentCtStart+5 to 8 (only if supportSpecular) if(supportSpecular) @@ -800,7 +805,10 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C for(; isetConstant(_VPCurrentCtStart+5+i, 0.f, 0.f, 0.f, 0.f); + if (program->idxLighted().Specular[i] != ~0) + { + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], 0.f, 0.f, 0.f, 0.f); + } } } @@ -816,40 +824,24 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C lightDir= invObjectWM.mulVector(_DriverLight[0].getDirection()); lightDir.normalize(); lightDir= -lightDir; - if(supportSpecular) - { - // Setup lightDir. - Driver->setConstant(_VPCurrentCtStart+9, lightDir); - } - else - { - // Setup lightDir. NB: no specular color! - Driver->setConstant(_VPCurrentCtStart+5, lightDir); - } + Driver->setUniform3f(IDriver::VertexProgram, program->idxLighted().DirOrPos[0], lightDir); // The sun is the same for every instance. // Setup PointLights //================ uint startPLPos; - if(supportSpecular) + if (supportSpecular) { // Setup eye in objectSpace for localViewer - Driver->setConstant(_VPCurrentCtStart+11, eye); - // Start at 12. - startPLPos= 12; - } - else - { - // Start at 6. - startPLPos= 6; + Driver->setUniform3f(IDriver::VertexProgram, program->idxLighted().EyePosition, eye); } // For all pointLight enabled (other are black: don't matter) for(i=1; i<_VPNumLights; i++) { // Setup position of light. CVector lightPos; - lightPos= invObjectWM * _DriverLight[i].getPosition(); - Driver->setConstant(_VPCurrentCtStart+startPLPos+(i-1), lightPos); + lightPos = invObjectWM * _DriverLight[i].getPosition(); + Driver->setUniform3f(IDriver::VertexProgram, program->idxLighted().DirOrPos[i], lightPos); } @@ -860,6 +852,9 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C // *************************************************************************** void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool excludeStrongest) { + CVertexProgramLighted *program = _VPCurrent; + nlassert(program); + // Must test if at least done one time. if(!_VPMaterialCacheDirty) { @@ -869,7 +864,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude _VPMaterialCacheDiffuse == mat.getDiffuse().getPacked() ) { // Same Diffuse part, test if same specular if necessary - if( !_VPSupportSpecular || + if( !program->featuresLighted().SupportSpecular || ( _VPMaterialCacheSpecular == mat.getSpecular().getPacked() && _VPMaterialCacheShininess == mat.getShininess() ) ) { @@ -899,7 +894,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude // setup Ambient + Emissive color= _VPFinalAmbient * mat.getAmbient(); color+= mat.getEmissive(); - Driver->setConstant(_VPCurrentCtStart+0, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Ambient, color); // is the strongest light is not excluded, its index should have been setup to _VPNumLights @@ -908,7 +903,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude for(i = 0; i < strongestLightIndex; ++i) { color= _VPLightDiffuse[i] * matDiff; - Driver->setConstant(_VPCurrentCtStart+1+i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], color); } @@ -917,24 +912,24 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude color= _VPLightDiffuse[i] * matDiff; _StrongestLightDiffuse.set((uint8) (255.f * color.R), (uint8) (255.f * color.G), (uint8) (255.f * color.B), (uint8) (255.f * color.A)); // setup strongest light to black for the gouraud part - Driver->setConstant(_VPCurrentCtStart + 1 + i, 0.f, 0.f, 0.f, 0.f); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], 0.f, 0.f, 0.f, 0.f); ++i; // setup other lights for(; i < _VPNumLights; i++) { color= _VPLightDiffuse[i] * matDiff; - Driver->setConstant(_VPCurrentCtStart + 1 + i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], color); } } // setup Specular - if(_VPSupportSpecular) + if (program->featuresLighted().SupportSpecular) { for(i = 0; i < strongestLightIndex; ++i) { color= _VPLightSpecular[i] * matSpec; color.A= specExp; - Driver->setConstant(_VPCurrentCtStart+5+i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], color); } if (i != _VPNumLights) @@ -943,14 +938,14 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude _StrongestLightSpecular.set((uint8) (255.f * color.R), (uint8) (255.f * color.G), (uint8) (255.f * color.B), (uint8) (255.f * color.A)); // setup strongest light to black (for gouraud part) - Driver->setConstant(_VPCurrentCtStart + 5 + i, 0.f, 0.f, 0.f, 0.f); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], 0.f, 0.f, 0.f, 0.f); ++i; // setup other lights for(; i < _VPNumLights; i++) { color= _VPLightSpecular[i] * matSpec; color.A= specExp; - Driver->setConstant(_VPCurrentCtStart + 5 + i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], color); } } } @@ -959,10 +954,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude static float alphaCte[4]= {0,0,1,0}; alphaCte[3]= matDiff.A; // setup at good place - if(_VPSupportSpecular) - Driver->setConstant(_VPCurrentCtStart+10, 1, alphaCte); - else - Driver->setConstant(_VPCurrentCtStart+9, 1, alphaCte); + Driver->setUniform4fv(IDriver::VertexProgram, program->idxLighted().DiffuseAlpha, 1, alphaCte); } // *************************************************************************** @@ -1174,24 +1166,24 @@ void CVertexProgramLighted::buildInfo() if (profile() == nelvp) { // Fixed uniform locations - m_IdxLighted.Ambient = 0; + m_IdxLighted.Ambient = m_FeaturesLighted.CtStartNeLVP + 0; for (uint i = 0; i < MaxLight; ++i) { - m_IdxLighted.Diffuse[i] = 1 + i; + m_IdxLighted.Diffuse[i] = m_FeaturesLighted.CtStartNeLVP + 1 + i; } if (m_FeaturesLighted.SupportSpecular) { for (uint i = 0; i < MaxLight; ++i) { - m_IdxLighted.Specular[i] = 5 + i; + m_IdxLighted.Specular[i] = m_FeaturesLighted.CtStartNeLVP + 5 + i; } m_IdxLighted.DirOrPos[0] = 9; for (uint i = 1; i < MaxLight; ++i) { - m_IdxLighted.DirOrPos[i] = (12 - 1) + i; + m_IdxLighted.DirOrPos[i] = m_FeaturesLighted.CtStartNeLVP + (12 - 1) + i; } - m_IdxLighted.DiffuseAlpha = 10; - m_IdxLighted.EyePosition = 11; + m_IdxLighted.DiffuseAlpha = m_FeaturesLighted.CtStartNeLVP + 10; + m_IdxLighted.EyePosition = m_FeaturesLighted.CtStartNeLVP + 11; } else { @@ -1201,9 +1193,9 @@ void CVertexProgramLighted::buildInfo() } for (uint i = 0; i < MaxLight; ++i) { - m_IdxLighted.DirOrPos[i] = 5 + i; + m_IdxLighted.DirOrPos[i] = m_FeaturesLighted.CtStartNeLVP + 5 + i; } - m_IdxLighted.DiffuseAlpha = 9; + m_IdxLighted.DiffuseAlpha = m_FeaturesLighted.CtStartNeLVP + 9; m_IdxLighted.EyePosition = ~0; } } @@ -1214,6 +1206,15 @@ void CVertexProgramLighted::buildInfo() // m_IdxLighted.Ambient = getUniformIndex("ambient"); // etc } + + nlassert(m_IdxLighted.Diffuse[0] != ~0); + if (m_FeaturesLighted.SupportSpecular) + { + nlassert(m_IdxLighted.Specular[0] != ~0); + nlassert(m_IdxLighted.EyePosition != ~0); + } + nlassert(m_IdxLighted.DirOrPos[0] != ~0); + nlassert(m_IdxLighted.DiffuseAlpha != ~0); } // generates the lighting part of a vertex program, nelvp profile From 7176cbc0af66d2309bb514c3c8f7f551c6231146 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 21:47:42 +0200 Subject: [PATCH 135/137] Use named indices for per pixel light vertex program --- code/nel/src/3d/meshvp_per_pixel_light.cpp | 41 ++++++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/code/nel/src/3d/meshvp_per_pixel_light.cpp b/code/nel/src/3d/meshvp_per_pixel_light.cpp index cf2d35f39..b607aa7d5 100644 --- a/code/nel/src/3d/meshvp_per_pixel_light.cpp +++ b/code/nel/src/3d/meshvp_per_pixel_light.cpp @@ -357,9 +357,12 @@ static const char* PPLightingVPCodeTest = class CVertexProgramPerPixelLight : public CVertexProgramLighted { public: - class CIdx + struct CIdx { - + /// Position or direction of strongest light + uint StrongestLight; + /// Viewer position + uint ViewerPos; }; CVertexProgramPerPixelLight(uint vp); virtual ~CVertexProgramPerPixelLight() { }; @@ -436,6 +439,7 @@ CVertexProgramPerPixelLight::CVertexProgramPerPixelLight(uint vp) source->DisplayName = NLMISC::toString("nelvp/MeshVPPerPixel/%i", vp); source->Profile = CVertexProgram::nelvp; source->setSource(vpCode); + source->ParamIndices["modelViewProjection"] = 0; addSource(source); } @@ -448,6 +452,27 @@ CVertexProgramPerPixelLight::CVertexProgramPerPixelLight(uint vp) void CVertexProgramPerPixelLight::buildInfo() { CVertexProgramLighted::buildInfo(); + if (profile() == nelvp) + { + m_Idx.StrongestLight = 4; + if (m_FeaturesLighted.SupportSpecular) + { + m_Idx.ViewerPos = 5; + } + else + { + m_Idx.ViewerPos = ~0; + } + } + else + { + // TODO_VP_GLSL + } + nlassert(m_Idx.StrongestLight != ~0); + if (m_FeaturesLighted.SupportSpecular) + { + nlassert(m_Idx.ViewerPos != ~0); + } } @@ -485,10 +510,12 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, } // enable(true, drv); // must enable the vertex program before the vb is activated + CVertexProgramPerPixelLight *program = _ActiveVertexProgram; + nlassert(program); // CRenderTrav *renderTrav= &scene->getRenderTrav(); /// Setup for gouraud lighting - renderTrav->beginVPLightSetup(_ActiveVertexProgram, invertedModelMat); + renderTrav->beginVPLightSetup(program, invertedModelMat); // sint strongestLightIndex = renderTrav->getStrongestLightIndex(); if (strongestLightIndex == -1) return false; // if no strongest light, disable this vertex program @@ -502,7 +529,7 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, { // put light direction in object space NLMISC::CVector lPos = invertedModelMat.mulVector(strongestLight.getDirection()); - drv->setConstant(4, lPos); + drv->setUniform3f(IDriver::VertexProgram, program->idx().StrongestLight, lPos); _IsPointLight = false; } break; @@ -510,7 +537,7 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, { // put light in object space NLMISC::CVector lPos = invertedModelMat * strongestLight.getPosition(); - drv->setConstant(4, lPos); + drv->setUniform3f(IDriver::VertexProgram, program->idx().StrongestLight, lPos); _IsPointLight = true; } break; @@ -524,11 +551,11 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, { // viewer pos in object space NLMISC::CVector vPos = invertedModelMat * viewerPos; - drv->setConstant(5, vPos); + drv->setUniform3f(IDriver::VertexProgram, program->idx().ViewerPos, vPos); } // c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix(); - drv->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); + drv->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); return true; } From 881949a5d7f3034e063eb75b9fc26b8d8426088c Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 22:20:52 +0200 Subject: [PATCH 136/137] Use named indices with wind tree program --- code/nel/src/3d/meshvp_wind_tree.cpp | 78 +++++++++++++++++++++------- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index 17e847c3e..174adfda8 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -83,9 +83,12 @@ static const char* WindTreeVPCodeEnd= class CVertexProgramWindTree : public CVertexProgramLighted { public: - class CIdx + struct CIdx { - + uint ProgramConstants[3]; + uint WindLevel1; + uint WindLevel2[4]; + uint WindLevel3[4]; }; CVertexProgramWindTree(uint numPls, bool specular, bool normalize); virtual ~CVertexProgramWindTree() { }; @@ -120,6 +123,8 @@ CVertexProgramWindTree::CVertexProgramWindTree(uint numPls, bool specular, bool source->DisplayName = NLMISC::toString("nelvp/MeshVPWindTree/%i/%s/%s", numPls, specular ? "spec" : "nospec", normalize ? "normalize" : "nonormalize"); source->Profile = CVertexProgram::nelvp; source->setSource(vpCode); + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["fog"] = 6; addSource(source); } @@ -129,6 +134,25 @@ CVertexProgramWindTree::CVertexProgramWindTree(uint numPls, bool specular, bool void CVertexProgramWindTree::buildInfo() { CVertexProgramLighted::buildInfo(); + if (profile() == nelvp) + { + m_Idx.ProgramConstants[0] = 8; + m_Idx.ProgramConstants[1] = 9; + m_Idx.ProgramConstants[2] = 10; + m_Idx.WindLevel1 = 15; + m_Idx.WindLevel2[0] = 16; + m_Idx.WindLevel2[1] = 17; + m_Idx.WindLevel2[2] = 18; + m_Idx.WindLevel2[3] = 19; + m_Idx.WindLevel3[0] = 20; + m_Idx.WindLevel3[1] = 21; + m_Idx.WindLevel3[2] = 22; + m_Idx.WindLevel3[3] = 23; + } + else + { + // TODO_VP_GLSL + } } @@ -250,21 +274,27 @@ inline void CMeshVPWindTree::setupPerMesh(IDriver *driver, CScene *scene) } } + CVertexProgramWindTree *program = _ActiveVertexProgram; + nlassert(program); + // Setup common constants for each instances. // c[8] take useful constants. - static float ct8[4]= {0, 1, 0.5f, 2}; - driver->setConstant(8, 1, ct8); + driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[0], + 0, 1, 0.5f, 2); // c[9] take other useful constants. - static float ct9[4]= {3.f, 0.f, -1.f, -2.f}; - driver->setConstant(9, 1, ct9); + driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[1], + 3.f, 0.f, -1.f, -2.f); // c[10] take Number of phase (4) for level2 and 3. -0.01 to avoid int value == 4. - static float ct10[4]= {4-0.01f, 0, 0, 0}; - driver->setConstant(10, 1, ct10); + driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[2], + 4-0.01f, 0, 0, 0); } // *************************************************************************** inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene *scene, CMeshBaseInstance *mbi, const NLMISC::CMatrix &invertedModelMat) { + CVertexProgramWindTree *program = _ActiveVertexProgram; + nlassert(program); + // get instance info float instancePhase= mbi->_VPWindTreePhase; @@ -285,16 +315,18 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene setupLighting(scene, mbi, invertedModelMat); // c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix(); - driver->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); + driver->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::ModelViewProjection), + IDriver::ModelViewProjection, IDriver::Identity); // c[4..7] take the ModelView Matrix. After setupModelMatrix();00 - driver->setConstantFog(6); + driver->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::Fog)); // c[15] take Wind of level 0. float f; f= _CurrentTime[0] + instancePhase; f= speedCos(f) + Bias[0]; - driver->setConstant(15, maxDeltaPosOS[0]*f ); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel1, + maxDeltaPosOS[0]*f ); // c[16-19] take Wind of level 1. @@ -302,16 +334,20 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene float instTime1= _CurrentTime[1] + instancePhase; // phase 0. f= speedCos( instTime1+0 ) + Bias[1]; - driver->setConstant(16+0, maxDeltaPosOS[1]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[0], + maxDeltaPosOS[1]*f); // phase 1. f= speedCos( instTime1+0.25f ) + Bias[1]; - driver->setConstant(16+1, maxDeltaPosOS[1]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[1], + maxDeltaPosOS[1]*f); // phase 2. f= speedCos( instTime1+0.50f ) + Bias[1]; - driver->setConstant(16+2, maxDeltaPosOS[1]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[2], + maxDeltaPosOS[1]*f); // phase 3. f= speedCos( instTime1+0.75f ) + Bias[1]; - driver->setConstant(16+3, maxDeltaPosOS[1]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[3], + maxDeltaPosOS[1]*f); // c[20, 23] take Wind of level 2. @@ -319,16 +355,20 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene float instTime2= _CurrentTime[2] + instancePhase; // phase 0. f= speedCos( instTime2+0 ) + Bias[2]; - driver->setConstant(20+0, maxDeltaPosOS[2]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[0], + maxDeltaPosOS[2]*f); // phase 1. f= speedCos( instTime2+0.25f ) + Bias[2]; - driver->setConstant(20+1, maxDeltaPosOS[2]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[1], + maxDeltaPosOS[2]*f); // phase 2. f= speedCos( instTime2+0.50f ) + Bias[2]; - driver->setConstant(20+2, maxDeltaPosOS[2]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[2], + maxDeltaPosOS[2]*f); // phase 3. f= speedCos( instTime2+0.75f ) + Bias[2]; - driver->setConstant(20+3, maxDeltaPosOS[2]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[3], + maxDeltaPosOS[2]*f); } // *************************************************************************** From 291c5d60120f8979b78fa8b18f3267340b7f5f8b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 13 Sep 2013 23:02:35 +0200 Subject: [PATCH 137/137] Cleanup --- code/nel/src/3d/bloom_effect.cpp | 13 ++++++++----- code/nel/src/3d/water_env_map.cpp | 13 +++++++++---- code/ryzom/client/src/decal.cpp | 25 +++++++++++++++---------- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 25439ee46..7809aba2c 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -55,15 +55,18 @@ static const char *TextureOffset = END \n"; -static CVertexProgram TextureOffsetVertexProgram(TextureOffset); - -// TODO_VP_GLSL +static NLMISC::CSmartPtr TextureOffsetVertexProgram; //----------------------------------------------------------------------------------------------------------- CBloomEffect::CBloomEffect() { + if (!TextureOffsetVertexProgram) + { + TextureOffsetVertexProgram = new CVertexProgram(TextureOffset); + } + _Driver = NULL; _Scene = NULL; _SquareBloom = true; @@ -445,7 +448,7 @@ void CBloomEffect::applyBlur() } // initialize vertex program - drvInternal->activeVertexProgram(&TextureOffsetVertexProgram); + drvInternal->activeVertexProgram(TextureOffsetVertexProgram); drvInternal->setUniform4f(IDriver::VertexProgram, 8, 255.f, 255.f, 255.f, 255.f); drvInternal->setUniform4f(IDriver::VertexProgram, 9, 0.0f, 0.f, 0.f, 1.f); @@ -551,7 +554,7 @@ void CBloomEffect::doBlur(bool horizontalBlur) } // initialize vertex program - drvInternal->activeVertexProgram(&TextureOffsetVertexProgram); + drvInternal->activeVertexProgram(TextureOffsetVertexProgram); drvInternal->setUniform4f(IDriver::VertexProgram, 8, 255.f, 255.f, 255.f, 255.f); drvInternal->setUniform4f(IDriver::VertexProgram, 9, 0.0f, 0.f, 0.f, 1.f); diff --git a/code/nel/src/3d/water_env_map.cpp b/code/nel/src/3d/water_env_map.cpp index e75fd172a..6bc6beda5 100644 --- a/code/nel/src/3d/water_env_map.cpp +++ b/code/nel/src/3d/water_env_map.cpp @@ -274,13 +274,18 @@ private: }; -static CVertexProgramTestMeshVP testMeshVP; +static NLMISC::CSmartPtr testMeshVP; // ******************************************************************************* void CWaterEnvMap::renderTestMesh(IDriver &driver) { + if (!testMeshVP) + { + testMeshVP = new CVertexProgramTestMeshVP(); + } + doInit(); CMaterial testMat; testMat.setLighting(false); @@ -294,12 +299,12 @@ void CWaterEnvMap::renderTestMesh(IDriver &driver) testMat.setZWrite(false); testMat.setZFunc(CMaterial::always); // tmp : test cubemap - driver.activeVertexProgram(&testMeshVP); + driver.activeVertexProgram(testMeshVP); driver.activeVertexBuffer(_TestVB); driver.activeIndexBuffer(_TestIB); _MaterialPassThruZTest.setTexture(0, _EnvCubic); - driver.setUniformMatrix(IDriver::VertexProgram, testMeshVP.getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); - driver.setUniform2f(IDriver::VertexProgram, testMeshVP.idx().ProgramConstant0, 2.f, 1.f); + driver.setUniformMatrix(IDriver::VertexProgram, testMeshVP->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); + driver.setUniform2f(IDriver::VertexProgram, testMeshVP->idx().ProgramConstant0, 2.f, 1.f); //driver.renderTriangles(testMat, 0, TEST_VB_NUM_TRIS); driver.renderTriangles(_MaterialPassThruZTest, 0, TEST_VB_NUM_TRIS); driver.activeVertexProgram(NULL); diff --git a/code/ryzom/client/src/decal.cpp b/code/ryzom/client/src/decal.cpp index a1cca247d..073c1ef0d 100644 --- a/code/ryzom/client/src/decal.cpp +++ b/code/ryzom/client/src/decal.cpp @@ -142,7 +142,7 @@ private: CIdx m_Idx; }; -static CVertexProgramDecalAttenuation DecalAttenuationVertexProgram; +static NLMISC::CSmartPtr DecalAttenuationVertexProgram; typedef CShadowPolyReceiver::CRGBAVertex CRGBAVertex; @@ -150,6 +150,10 @@ typedef CShadowPolyReceiver::CRGBAVertex CRGBAVertex; // **************************************************************************** CDecal::CDecal() { + if (!DecalAttenuationVertexProgram) + { + DecalAttenuationVertexProgram = new CVertexProgramDecalAttenuation(); + } _ShadowMap = new CShadowMap(&(((CSceneUser *) Scene)->getScene().getRenderTrav().getShadowMapManager())); _Material.initUnlit(); _Diffuse = CRGBA::White; @@ -361,6 +365,7 @@ void CDecal::renderTriCache(NL3D::IDriver &drv, NL3D::CShadowPolyReceiver &/* drv.setupModelMatrix(modelMat); if (useVertexProgram) { + CVertexProgramDecalAttenuation *program = DecalAttenuationVertexProgram; { CVertexBufferReadWrite vba; _VB.setNumVertices((uint32)_TriCache.size()); @@ -368,16 +373,16 @@ void CDecal::renderTriCache(NL3D::IDriver &drv, NL3D::CShadowPolyReceiver &/* memcpy(vba.getVertexCoordPointer(), &_TriCache[0], sizeof(CRGBAVertex) * _TriCache.size()); } drv.activeVertexBuffer(_VB); - drv.setUniformMatrix(IDriver::VertexProgram, DecalAttenuationVertexProgram.getUniformIndex(CGPUProgramIndex::ModelViewProjection), NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); - drv.setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().WorldToUV0, _WorldToUVMatrix[0][0], _WorldToUVMatrix[1][0], _WorldToUVMatrix[2][0], _WorldToUVMatrix[3][0]); - drv.setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().WorldToUV1, _WorldToUVMatrix[0][1], _WorldToUVMatrix[1][1], _WorldToUVMatrix[2][1], _WorldToUVMatrix[3][1]); - drv.setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().Diffuse, _Diffuse.R * (1.f / 255.f), _Diffuse.G * (1.f / 255.f), _Diffuse.B * (1.f / 255.f), 1.f); + drv.setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::ModelViewProjection), NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); + drv.setUniform4f(IDriver::VertexProgram, program->idx().WorldToUV0, _WorldToUVMatrix[0][0], _WorldToUVMatrix[1][0], _WorldToUVMatrix[2][0], _WorldToUVMatrix[3][0]); + drv.setUniform4f(IDriver::VertexProgram, program->idx().WorldToUV1, _WorldToUVMatrix[0][1], _WorldToUVMatrix[1][1], _WorldToUVMatrix[2][1], _WorldToUVMatrix[3][1]); + drv.setUniform4f(IDriver::VertexProgram, program->idx().Diffuse, _Diffuse.R * (1.f / 255.f), _Diffuse.G * (1.f / 255.f), _Diffuse.B * (1.f / 255.f), 1.f); const NLMISC::CVector &camPos = MainCam.getMatrix().getPos(); - drv.setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().RefCamDist, camPos.x - _RefPosition.x, camPos.y - _RefPosition.y, camPos.z - _RefPosition.z, 1.f); + drv.setUniform4f(IDriver::VertexProgram, program->idx().RefCamDist, camPos.x - _RefPosition.x, camPos.y - _RefPosition.y, camPos.z - _RefPosition.z, 1.f); // bottom & top blend float bottomBlendScale = 1.f / favoid0(_BottomBlendZMax - _BottomBlendZMin); float topBlendScale = 1.f / favoid0(_TopBlendZMin - _TopBlendZMax); - drv.setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().BlendScale, bottomBlendScale, bottomBlendScale * (_RefPosition.z - _BottomBlendZMin), + drv.setUniform4f(IDriver::VertexProgram, program->idx().BlendScale, bottomBlendScale, bottomBlendScale * (_RefPosition.z - _BottomBlendZMin), topBlendScale, topBlendScale * (_RefPosition.z - _TopBlendZMax)); // static volatile bool wantSimpleMat = false; @@ -618,11 +623,11 @@ void CDecalRenderList::renderAllDecals() NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver(); // static volatile bool forceNoVertexProgram = false; - if (!forceNoVertexProgram && drvInternal->compileVertexProgram(&DecalAttenuationVertexProgram)) + if (!forceNoVertexProgram && drvInternal->compileVertexProgram(DecalAttenuationVertexProgram)) { - drvInternal->activeVertexProgram(&DecalAttenuationVertexProgram); + drvInternal->activeVertexProgram(DecalAttenuationVertexProgram); //drvInternal->setCons/tantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); - drvInternal->setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram.idx().DistScaleBias, _DistScale, _DistBias, 0.f, 1.f); + drvInternal->setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram->idx().DistScaleBias, _DistScale, _DistBias, 0.f, 1.f); useVertexProgram = true; } else