From b1777ff546912ccc94de2a3da35e822cb17d33e2 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 3 Aug 2013 06:48:13 +0200 Subject: [PATCH] Projection matrix is now generated and managed by Nel and only loaded into OpenGL when dirty. --HG-- branch : gsoc2013-dfighter --- code/nel/include/nel/misc/matrix.h | 7 ++ .../src/3d/driver/OpenGL3/driver_opengl.cpp | 18 ++--- .../nel/src/3d/driver/OpenGL3/driver_opengl.h | 5 +- .../driver/OpenGL3/driver_opengl_matrix.cpp | 38 +++++------ .../OpenGL3/driver_opengl_vertex_program.cpp | 2 - code/nel/src/misc/matrix.cpp | 65 +++++++++++++++++-- 6 files changed, 90 insertions(+), 45 deletions(-) diff --git a/code/nel/include/nel/misc/matrix.h b/code/nel/include/nel/misc/matrix.h index 700eb4a14..6c427f1ac 100644 --- a/code/nel/include/nel/misc/matrix.h +++ b/code/nel/include/nel/misc/matrix.h @@ -163,6 +163,10 @@ public: * \param i : column index. * \param j : line index. */ + + void setFlags(); + + void setCoefficient(float coeff, sint i, sint j) { M[ (j<<2) + i] = coeff; @@ -357,6 +361,9 @@ public: /// Plane (line vector) multiplication. friend CPlane operator*(const CPlane &p, const CMatrix &m); + void frustum(float left, float right, float bottom, float top, float znear, float zfar ); + + void ortho(float left, float right, float bottom, float top, float znear, float zfar ); private: float M[16]; diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl.cpp b/code/nel/src/3d/driver/OpenGL3/driver_opengl.cpp index bb3ac3dee..2456ee6b2 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl.cpp @@ -275,6 +275,12 @@ CDriverGL3::CDriverGL3() #endif } + for( i = 0; i < IDRV_MAT_MAXTEXTURES; i++ ) + _UserTexMatDirty[ i ] = false; + + for( i = 0; i < IDRV_MAT_MAXTEXTURES; i++ ) + _UserTexMat[ i ].identity(); + _UserTexMatEnabled = 0; // Ligtmap preca. @@ -1447,18 +1453,6 @@ uint CDriverGL3::getNbTextureStages() const return inlGetNumTextStages(); } -// *************************************************************************** -void CDriverGL3::refreshProjMatrixFromGL() -{ - H_AUTO_OGL(CDriverGL3_refreshProjMatrixFromGL) - - if (!_ProjMatDirty) return; - float mat[16]; - glGetFloatv(GL_PROJECTION_MATRIX, mat); - _GLProjMat.set(mat); - _ProjMatDirty = false; -} - // *************************************************************************** bool CDriverGL3::supportEMBM() const { diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl.h b/code/nel/src/3d/driver/OpenGL3/driver_opengl.h index b173f37bc..18d51324f 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl.h +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl.h @@ -1001,9 +1001,6 @@ private: // reset the cursor shape to the system arrow void setSystemArrow(); - // Get the proj matrix setupped in GL - void refreshProjMatrixFromGL(); - bool setupVertexBuffer(CVertexBuffer& VB); // Activate Texture Environnement. Do it with caching. bool activateTexture(uint stage, ITexture *tex); @@ -1330,8 +1327,8 @@ private: // user texture matrix NLMISC::CMatrix _UserTexMat[IDRV_MAT_MAXTEXTURES]; + bool _UserTexMatDirty[IDRV_MAT_MAXTEXTURES]; uint _UserTexMatEnabled; // bitm ask for user texture coords - //NLMISC::CMatrix _UserTexMat[IDRV_MAT_MAXTEXTURES]; // Static const static const uint NumCoordinatesType[CVertexBuffer::NumType]; diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl_matrix.cpp b/code/nel/src/3d/driver/OpenGL3/driver_opengl_matrix.cpp index 2509ddec0..121317cad 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl_matrix.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl_matrix.cpp @@ -28,20 +28,14 @@ void CDriverGL3::setFrustum(float left, float right, float bottom, float top, fl { H_AUTO_OGL(CDriverGL3_setFrustum); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - if (perspective) - glFrustum(left,right,bottom,top,znear,zfar); + if( perspective ) + _GLProjMat.frustum( left, right, bottom, top, znear, zfar ); else - glOrtho(left,right,bottom,top,znear,zfar); + _GLProjMat.ortho( left, right, bottom, top, znear, zfar ); _ProjMatDirty = true; + _OODeltaZ = 1 / ( zfar - znear ); - // Backup znear and zfar for zbias setup - _OODeltaZ = 1 / (zfar - znear); - - glMatrixMode(GL_MODELVIEW); } // *************************************************************************** @@ -49,11 +43,10 @@ void CDriverGL3::setFrustum(float left, float right, float bottom, float top, fl void CDriverGL3::setFrustumMatrix(CMatrix &frustumMatrix) { H_AUTO_OGL(CDriverGL3_setFrustum) - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(((GLfloat*)frustumMatrix.get())); + _GLProjMat = frustumMatrix; + _ProjMatDirty = true; - glMatrixMode(GL_MODELVIEW); } // *************************************************************************** @@ -62,16 +55,7 @@ CMatrix CDriverGL3::getFrustumMatrix() { H_AUTO_OGL(CDriverGL3_getFrustum) - glMatrixMode(GL_PROJECTION); - - CMatrix frustumMatrix; - float frustum[16]; - glGetFloatv(GL_PROJECTION_MATRIX, ((GLfloat*)&frustum)); - frustumMatrix.set(frustum); - - glMatrixMode(GL_MODELVIEW); - - return frustumMatrix; + return _GLProjMat; } // *************************************************************************** @@ -180,6 +164,14 @@ void CDriverGL3::doRefreshRenderSetup() // Check light setup is good nlassert (_LightSetupDirty==false); + if( _ProjMatDirty ) + { + glMatrixMode( GL_PROJECTION ); + glLoadMatrixf( _GLProjMat.get() ); + glMatrixMode( GL_MODELVIEW ); + _ProjMatDirty = false; + } + // Check if must update the modelViewMatrix if( _ModelViewMatrixDirty ) diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/OpenGL3/driver_opengl_vertex_program.cpp index d1f33a09f..0d677ab47 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl_vertex_program.cpp @@ -1828,12 +1828,10 @@ void CDriverGL3::setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver break; case IDriver::Projection: { - refreshProjMatrixFromGL(); mat = _GLProjMat; } break; case IDriver::ModelViewProjection: - refreshProjMatrixFromGL(); mat = _GLProjMat * _ModelViewMatrix; break; default: diff --git a/code/nel/src/misc/matrix.cpp b/code/nel/src/misc/matrix.cpp index dd884f4d5..4660cd7ce 100644 --- a/code/nel/src/misc/matrix.cpp +++ b/code/nel/src/misc/matrix.cpp @@ -313,11 +313,15 @@ void CMatrix::resetProj() // ====================================================================================================== void CMatrix::set(const float m44[16]) { - StateBit= MAT_IDENTITY; - - StateBit|= MAT_ROT | MAT_SCALEANY; memcpy(M, m44, 16*sizeof(float)); Scale33= 1.0f; + setFlags(); +} + +void CMatrix::setFlags() +{ + StateBit= MAT_IDENTITY; + StateBit|= MAT_ROT | MAT_SCALEANY; // Check Trans state. if(a14!=0 || a24!=0 || a34!=0) @@ -1561,8 +1565,61 @@ void CMatrix::setArbitraryRotK(const CVector &kdir) normalize(CMatrix::ZYX); } +void CMatrix::frustum(float left, float right, float bottom, float top, float znear, float zfar ) +{ + // http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml + + a11 = 2.0f * znear / ( right - left ); + a12 = 0.0f; + a13 = ( right + left ) / ( right - left ); + a14 = 0.0f; + + a21 = 0.0f; + a22 = 2.0f * znear / ( top - bottom ); + a23 = ( top + bottom ) / ( top - bottom ); + a24 = 0.0f; + + a31 = 0.0f; + a32 = 0.0f; + a33 = -1.0f * ( zfar + znear ) / ( zfar - znear ); + a34 = -1.0f * 2.0f * zfar * znear / ( zfar - znear ); + + a41 = 0.0f; + a42 = 0.0f; + a43 = -1.0f; + a44 = 0.0f; + + Scale33 = 1.0f; + setFlags(); +} - +void CMatrix::ortho(float left, float right, float bottom, float top, float znear, float zfar ) +{ + // http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml + + a11 = 2.0f / ( right - left ); + a12 = 0.0f; + a13 = 0.0f; + a14 = -1.0f * ( right + left ) / ( right - left ); + + a21 = 0.0f; + a22 = 2.0f / ( top - bottom ); + a23 = 0.0f; + a24 = -1.0f * ( top + bottom ) / ( top - bottom ); + + a31 = 0.0f; + a32 = 0.0f; + a33 = -2.0f / ( zfar - znear ); + a34 = -1.0f * ( zfar + znear ) / ( zfar - znear ); + + a41 = 0.0f; + a42 = 0.0f; + a43 = 0.0f; + a44 = 1.0f; + + Scale33 = 1.0f; + setFlags(); +} }