From e064e0d6a75c7cbdddb7c71ccd05b7eacedbb012 Mon Sep 17 00:00:00 2001 From: "spartanj@gmail.com" Date: Mon, 11 Jun 2012 16:59:18 -0300 Subject: [PATCH] Splited GL3 and GLES2 renderer in two separated renderers. Optimized the GLES2 renderer for the iPhone/iPod devices ( not perfect yet, but much more usable ). --- include/eepp/graphics/cbatchrenderer.hpp | 3 + include/eepp/graphics/renderer/cgl.hpp | 16 + .../eepp/graphics/renderer/crenderergl3.hpp | 25 +- .../eepp/graphics/renderer/crenderergles2.hpp | 156 ++++ include/eepp/physics/cphysicsmanager.hpp | 6 + include/eepp/physics/cshape.hpp | 4 +- include/eepp/physics/cshapepoly.hpp | 2 + src/eepp/graphics/cbatchrenderer.cpp | 12 +- src/eepp/graphics/cshader.cpp | 19 +- src/eepp/graphics/ctexturefactory.cpp | 4 +- src/eepp/graphics/renderer/cgl.cpp | 19 +- src/eepp/graphics/renderer/crenderergl3.cpp | 379 +++++---- src/eepp/graphics/renderer/crenderergles2.cpp | 742 ++++++++++++++++++ src/eepp/graphics/renderer/shaders/base.frag | 19 + src/eepp/graphics/renderer/shaders/base.vert | 26 + .../graphics/renderer/shaders/basegl3.frag | 34 + .../graphics/renderer/shaders/basegl3.vert | 34 + .../graphics/renderer/shaders/clipped.frag | 34 + .../graphics/renderer/shaders/clipped.vert | 35 + .../renderer/shaders/pointsprite.frag | 13 + .../renderer/shaders/pointsprite.vert | 20 + .../graphics/renderer/shaders/primitive.frag | 12 + .../graphics/renderer/shaders/primitive.vert | 18 + src/eepp/physics/cshape.cpp | 6 + src/eepp/physics/cshapepoly.cpp | 17 +- src/eepp/physics/cspace.cpp | 9 + src/eepp/window/cwindow.cpp | 10 +- src/test/eetest.cpp | 10 +- 28 files changed, 1436 insertions(+), 248 deletions(-) create mode 100644 include/eepp/graphics/renderer/crenderergles2.hpp create mode 100644 src/eepp/graphics/renderer/crenderergles2.cpp create mode 100644 src/eepp/graphics/renderer/shaders/base.frag create mode 100644 src/eepp/graphics/renderer/shaders/base.vert create mode 100644 src/eepp/graphics/renderer/shaders/basegl3.frag create mode 100644 src/eepp/graphics/renderer/shaders/basegl3.vert create mode 100644 src/eepp/graphics/renderer/shaders/clipped.frag create mode 100644 src/eepp/graphics/renderer/shaders/clipped.vert create mode 100644 src/eepp/graphics/renderer/shaders/pointsprite.frag create mode 100644 src/eepp/graphics/renderer/shaders/pointsprite.vert create mode 100644 src/eepp/graphics/renderer/shaders/primitive.frag create mode 100644 src/eepp/graphics/renderer/shaders/primitive.vert diff --git a/include/eepp/graphics/cbatchrenderer.hpp b/include/eepp/graphics/cbatchrenderer.hpp index b458910e2..feb802487 100755 --- a/include/eepp/graphics/cbatchrenderer.hpp +++ b/include/eepp/graphics/cbatchrenderer.hpp @@ -18,6 +18,8 @@ struct eeVertex { eeColorA color; }; +class cTextureFactory; + /** @brief A batch rendering class. */ class EE_API cBatchRenderer { public: @@ -205,6 +207,7 @@ class EE_API cBatchRenderer { eeUint mNumVertex; const cTexture * mTexture; + cTextureFactory * mTF; EE_PRE_BLEND_FUNC mBlend; eeTexCoord mTexCoord[4]; diff --git a/include/eepp/graphics/renderer/cgl.hpp b/include/eepp/graphics/renderer/cgl.hpp index a8e099608..125ba8e51 100644 --- a/include/eepp/graphics/renderer/cgl.hpp +++ b/include/eepp/graphics/renderer/cgl.hpp @@ -6,6 +6,19 @@ namespace EE { namespace Graphics { +#ifndef EE_MAX_PLANES +#define EE_MAX_PLANES 6 +#endif + +/** Just for reference */ +enum EEGL_ARRAY_STATES { + EEGL_VERTEX_ARRAY = 0, + EEGL_NORMAL_ARRAY, + EEGL_COLOR_ARRAY, + EEGL_ARRAY_STATES_COUNT, + EEGL_TEXTURE_COORD_ARRAY +}; + enum EEGL_extensions { EEGL_ARB_texture_non_power_of_two = 0, EEGL_ARB_point_parameters, @@ -31,6 +44,7 @@ enum EEGL_version { class cRendererGL; class cRendererGL3; +class cRendererGLES2; class EE_API cGL { static cGL * ms_singleton; @@ -122,6 +136,8 @@ class EE_API cGL { cRendererGL3 * GetRendererGL3(); + cRendererGLES2 * GetRendererGLES2(); + virtual void PointSize( GLfloat size ) = 0; virtual GLfloat PointSize() = 0; diff --git a/include/eepp/graphics/renderer/crenderergl3.hpp b/include/eepp/graphics/renderer/crenderergl3.hpp index 3bca13e5b..e12021555 100644 --- a/include/eepp/graphics/renderer/crenderergl3.hpp +++ b/include/eepp/graphics/renderer/crenderergl3.hpp @@ -18,20 +18,9 @@ namespace EE { namespace Graphics { -#define EE_MAX_PLANES 6 - -/** Just for reference */ -enum EEGL_ARRAY_STATES { - EEGL_VERTEX_ARRAY = 0, - EEGL_NORMAL_ARRAY, - EEGL_COLOR_ARRAY, - EEGL_ARRAY_STATES_COUNT, - EEGL_TEXTURE_COORD_ARRAY -}; - -enum EEGL_SHADERS { - EEGL_SHADER_BASE, - EEGL_SHADERS_COUNT +enum EEGL3_SHADERS { + EEGL3_SHADER_BASE, + EEGL3_SHADERS_COUNT }; class EE_API cRendererGL3 : public cGL { @@ -90,7 +79,7 @@ class EE_API cRendererGL3 : public cGL { void SetShader( cShaderProgram * Shader ); - void SetShader( const EEGL_SHADERS& Shader ); + void SetShader( const EEGL3_SHADERS& Shader ); GLint GetStateIndex( const Uint32& State ); @@ -128,9 +117,10 @@ class EE_API cRendererGL3 : public cGL { GLint mModelViewMatrix_id; // cpu-side hook to shader uniform GLenum mCurrentMode; std::stack* mCurMatrix; - cShaderProgram * mShaders[ EEGL_SHADERS_COUNT ]; + cShaderProgram * mShaders[ EEGL3_SHADERS_COUNT ]; cShaderProgram * mCurShader; - GLint mStates[ EEGL_ARRAY_STATES_COUNT ]; + GLint mAttribsLoc[ EEGL_ARRAY_STATES_COUNT ]; + GLint mAttribsLocStates[ EEGL_ARRAY_STATES_COUNT ]; GLint mPlanes[ EE_MAX_PLANES ]; GLint mPlanesStates[ EE_MAX_PLANES ]; cShaderProgram * mShaderPrev; @@ -140,6 +130,7 @@ class EE_API cRendererGL3 : public cGL { GLint mClippingEnabledLoc; GLfloat mPointSize; GLint mTextureUnits[ EE_MAX_TEXTURE_UNITS ]; + GLint mTextureUnitsStates[ EE_MAX_TEXTURE_UNITS ]; GLint mCurActiveTex; bool mLoaded; std::string mBaseVertexShader; diff --git a/include/eepp/graphics/renderer/crenderergles2.hpp b/include/eepp/graphics/renderer/crenderergles2.hpp new file mode 100644 index 000000000..b740eb453 --- /dev/null +++ b/include/eepp/graphics/renderer/crenderergles2.hpp @@ -0,0 +1,156 @@ +#ifndef EE_GRAPHICS_CRENDERERGLES2_HPP +#define EE_GRAPHICS_CRENDERERGLES2_HPP + +#include + +#ifdef EE_GL3_ENABLED + +// GLM doesn't support forward declaration of the internal types +// Xlib Madness +#ifdef True +#undef True +#endif + +#ifdef False +#undef False +#endif +#include + +namespace EE { namespace Graphics { + +enum EEGLES2_SHADERS { + EEGLES2_SHADER_BASE, + EEGLES2_SHADER_CLIPPED, + EEGLES2_SHADER_POINTSPRITE, + EEGLES2_SHADER_PRIMITIVE, + EEGLES2_SHADERS_COUNT +}; + +class EE_API cRendererGLES2 : public cGL { + public: + cRendererGLES2(); + + ~cRendererGLES2(); + + EEGL_version Version(); + + std::string VersionStr(); + + void Init(); + + void PointSize( GLfloat size ); + + GLfloat PointSize(); + + void PushMatrix(); + + void PopMatrix(); + + void LoadIdentity(); + + void Disable ( GLenum cap ); + + void Enable( GLenum cap ); + + void Translatef( GLfloat x, GLfloat y, GLfloat z ); + + void Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ); + + void Scalef( GLfloat x, GLfloat y, GLfloat z ); + + void MatrixMode (GLenum mode); + + void Ortho ( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar ); + + void LookAt( GLfloat eyeX, GLfloat eyeY, GLfloat eyeZ, GLfloat centerX, GLfloat centerY, GLfloat centerZ, GLfloat upX, GLfloat upY, GLfloat upZ ); + + void Perspective ( GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar ); + + void EnableClientState( GLenum array ); + + void DisableClientState( GLenum array ); + + void VertexPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer, GLuint allocate ); + + void ColorPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer, GLuint allocate ); + + void TexCoordPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer, GLuint allocate ); + + void ClientActiveTexture( GLenum texture ); + + GLuint BaseShaderId(); + + void SetShader( cShaderProgram * Shader ); + + void SetShader( const EEGLES2_SHADERS& Shader ); + + GLint GetStateIndex( const Uint32& State ); + + void Clip2DPlaneEnable( const Int32& x, const Int32& y, const Int32& Width, const Int32& Height ); + + void Clip2DPlaneDisable(); + + void MultMatrixf ( const GLfloat *m ); + + void ClipPlane( GLenum plane, const GLdouble *equation ); + + void TexEnvi( GLenum target, GLenum pname, GLint param ); + + void LoadMatrixf( const GLfloat *m ); + + void Frustum( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near_val, GLfloat far_val ); + + void GetCurrentMatrix( GLenum mode, GLfloat * m ); + + glm::mat4 toGLMmat4( const GLfloat * m ); + + void fromGLMmat4( glm::mat4 from, GLfloat * to ); + + GLenum GetCurrentMatrixMode(); + + std::string GetBaseVertexShader(); + + GLint Project( GLfloat objx, GLfloat objy, GLfloat objz, const GLfloat modelMatrix[16], const GLfloat projMatrix[16], const GLint viewport[4], GLfloat *winx, GLfloat *winy, GLfloat *winz ); + + GLint UnProject( GLfloat winx, GLfloat winy, GLfloat winz, const GLfloat modelMatrix[16], const GLfloat projMatrix[16], const GLint viewport[4], GLfloat *objx, GLfloat *objy, GLfloat *objz ); + protected: + std::stack mProjectionMatrix; // cpu-side + GLint mProjectionMatrix_id; // cpu-side hook to shader uniform + std::stack mModelViewMatrix; // cpu-side + GLint mModelViewMatrix_id; // cpu-side hook to shader uniform + GLenum mCurrentMode; + std::stack* mCurMatrix; + cShaderProgram * mShaders[ EEGLES2_SHADERS_COUNT ]; + cShaderProgram * mCurShader; + GLint mAttribsLoc[ EEGL_ARRAY_STATES_COUNT ]; + GLint mAttribsLocStates[ EEGL_ARRAY_STATES_COUNT ]; + GLint mPlanes[ EE_MAX_PLANES ]; + GLint mPlanesStates[ EE_MAX_PLANES ]; + cShaderProgram * mShaderPrev; + Int32 mTexActive; + GLint mTexActiveLoc; + GLint mClippingEnabledLoc; + GLfloat mPointSize; + GLint mTextureUnits[ EE_MAX_TEXTURE_UNITS ]; + GLint mTextureUnitsStates[ EE_MAX_TEXTURE_UNITS ]; + GLint mCurActiveTex; + Uint8 mClippingEnabled; + Uint8 mPointSpriteEnabled; + bool mLoaded; + bool mCurShaderLocal; + std::string mBaseVertexShader; + + void UpdateMatrix(); + + void PlaneStateCheck( bool tryEnable ); + + void ReloadShader( cShaderProgram * Shader ); + + void CheckLocalShader(); +}; + +}} + +#endif + +#endif diff --git a/include/eepp/physics/cphysicsmanager.hpp b/include/eepp/physics/cphysicsmanager.hpp index 84bf6b823..df2d0876d 100644 --- a/include/eepp/physics/cphysicsmanager.hpp +++ b/include/eepp/physics/cphysicsmanager.hpp @@ -19,6 +19,11 @@ class CP_API cPhysicsManager { cDrawSpaceOptions() : DrawBBs( false ), DrawShapes( true ), + #ifdef EE_GLES + DrawShapesBorders( false ), + #else + DrawShapesBorders( true ), + #endif CollisionPointSize( 0.0f ), BodyPointSize( 0.0f ), LineThickness( 0.0f ) @@ -26,6 +31,7 @@ class CP_API cPhysicsManager { bool DrawBBs; bool DrawShapes; + bool DrawShapesBorders; cpFloat CollisionPointSize; cpFloat BodyPointSize; cpFloat LineThickness; diff --git a/include/eepp/physics/cshape.hpp b/include/eepp/physics/cshape.hpp index 89ce7b90b..f12b3dd00 100644 --- a/include/eepp/physics/cshape.hpp +++ b/include/eepp/physics/cshape.hpp @@ -79,7 +79,9 @@ class CP_API cShape { cShapeSegment * GetAsSegment(); - virtual void Draw( cSpace * space ) = 0; + virtual void Draw( cSpace * space ); + + virtual void DrawBorder( cSpace * space ); virtual void DrawBB(); diff --git a/include/eepp/physics/cshapepoly.hpp b/include/eepp/physics/cshapepoly.hpp index 2f54b7555..21defa495 100644 --- a/include/eepp/physics/cshapepoly.hpp +++ b/include/eepp/physics/cshapepoly.hpp @@ -25,6 +25,8 @@ class CP_API cShapePoly : public cShape { virtual void Draw( cSpace * space ); + virtual void DrawBorder( cSpace * space ); + static void Recenter( int numVerts, cVect * verts ); static cVect Centroid( int numVerts, const cVect * verts ); diff --git a/src/eepp/graphics/cbatchrenderer.cpp b/src/eepp/graphics/cbatchrenderer.cpp index 03cf23b79..a8e0321e8 100755 --- a/src/eepp/graphics/cbatchrenderer.cpp +++ b/src/eepp/graphics/cbatchrenderer.cpp @@ -8,6 +8,7 @@ cBatchRenderer::cBatchRenderer() : mVertex( NULL ), mNumVertex(0), mTexture(NULL), + mTF( cTextureFactory::instance() ), mBlend(ALPHA_NORMAL), mCurrentMode(DM_QUADS), mRotation(0.0f), @@ -24,6 +25,7 @@ cBatchRenderer::cBatchRenderer() : cBatchRenderer::cBatchRenderer( const eeUint& Prealloc ) : mNumVertex(0), mTexture(NULL), + mTF( cTextureFactory::instance() ), mBlend(ALPHA_NORMAL), mCurrentMode(DM_QUADS), mRotation(0.0f), @@ -101,7 +103,7 @@ void cBatchRenderer::Flush() { bool CreateMatrix = ( mRotation || mScale != 1.0f || mPosition.x || mPosition.y ); - cTextureFactory::instance()->SetPreBlendFunc( mBlend ); + mTF->SetPreBlendFunc( mBlend ); if ( mCurrentMode == DM_POINTS && NULL != mTexture ) { GLi->Enable( GL_POINT_SPRITE ); @@ -120,17 +122,17 @@ void cBatchRenderer::Flush() { Uint32 alloc = sizeof(eeVertex) * NumVertex; - GLi->VertexPointer ( 2, GL_FP , sizeof(eeVertex), reinterpret_cast ( &mVertex[0] ) , alloc ); - GLi->ColorPointer ( 4, GL_UNSIGNED_BYTE , sizeof(eeVertex), reinterpret_cast ( &mVertex[0] ) + sizeof(eeVector2f) + sizeof(eeTexCoord) , alloc ); - if ( NULL != mTexture ) { - cTextureFactory::instance()->Bind( mTexture ); + mTF->Bind( mTexture ); GLi->TexCoordPointer( 2, GL_FP , sizeof(eeVertex), reinterpret_cast ( &mVertex[0] ) + sizeof(eeVector2f) , alloc ); } else { GLi->Disable( GL_TEXTURE_2D ); GLi->DisableClientState( GL_TEXTURE_COORD_ARRAY ); } + GLi->VertexPointer ( 2, GL_FP , sizeof(eeVertex), reinterpret_cast ( &mVertex[0] ) , alloc ); + GLi->ColorPointer ( 4, GL_UNSIGNED_BYTE , sizeof(eeVertex), reinterpret_cast ( &mVertex[0] ) + sizeof(eeVector2f) + sizeof(eeTexCoord) , alloc ); + #ifdef EE_GLES if ( DM_QUADS == mCurrentMode ) { GLi->DrawArrays( DM_TRIANGLES, 0, NumVertex ); diff --git a/src/eepp/graphics/cshader.cpp b/src/eepp/graphics/cshader.cpp index 1f589eb3d..d25a73ec5 100644 --- a/src/eepp/graphics/cshader.cpp +++ b/src/eepp/graphics/cshader.cpp @@ -1,6 +1,7 @@ #include #include #include +#include namespace EE { namespace Graphics { @@ -117,25 +118,23 @@ void cShader::EnsureVersion() { if ( GL_VERTEX_SHADER == mType ) { if ( mSource.find( "ftransform" ) != std::string::npos || mSource.find("dgl_Vertex") == std::string::npos ) { - mSource = GLi->GetRendererGL3()->GetBaseVertexShader(); + if ( GLi->Version() == GLv_3 ) { + mSource = GLi->GetRendererGL3()->GetBaseVertexShader(); + } else { + mSource = GLi->GetRendererGLES2()->GetBaseVertexShader(); + } } } else { if ( mSource.find( "gl_FragColor" ) != std::string::npos ) { - if ( GLi->Version() == GLv_3 ) { - mSource = "#version 150\nuniform int dgl_TexActive = 1;\ninvariant in vec4 gl_Color;\ninvariant in vec4 gl_TexCoord[ 4 ];\nout vec4 gl_FragColor;\n" + mSource; - } else { - mSource = "#ifdef GL_ES\nprecision mediump float;\nprecision lowp int;\n#endif\nuniform int dgl_TexActive;\nvarying vec4 gl_Color;\nvarying vec4 gl_TexCoord[ 4 ];\n" + mSource; - } - - if ( GLi->Version() == GLv_3 ) { - ReplaceSubStr( mSource, "gl_FragColor" , "dgl_FragColor" ); - } + mSource = "#ifdef GL_ES\nprecision mediump float;\nprecision lowp int;\n#endif\nvarying vec4 gl_Color;\nvarying vec4 gl_TexCoord[ 1 ];\n" + mSource; ReplaceSubStr( mSource, "gl_Color" , "dgl_Color" ); ReplaceSubStr( mSource, "gl_TexCoord" , "dgl_TexCoord" ); } } + + /// cLog::instance()->Write( "Shader " + GetName() + " converted looks like: \n" + mSource + "\n" ); } #endif } diff --git a/src/eepp/graphics/ctexturefactory.cpp b/src/eepp/graphics/ctexturefactory.cpp index a824d4997..abbbaca1f 100755 --- a/src/eepp/graphics/ctexturefactory.cpp +++ b/src/eepp/graphics/ctexturefactory.cpp @@ -99,14 +99,14 @@ Uint32 cTextureFactory::FindFreeSlot() { void cTextureFactory::Bind( const cTexture* Tex, const Uint32& TextureUnit ) { if( NULL != Tex && mCurrentTexture[ TextureUnit ] != (Int32)Tex->Handle() ) { - if ( GLi->IsExtension( EEGL_ARB_multitexture ) ) + if ( TextureUnit && GLi->IsExtension( EEGL_ARB_multitexture ) ) SetActiveTextureUnit( TextureUnit ); GLi->BindTexture( GL_TEXTURE_2D, Tex->Handle() ); mCurrentTexture[ TextureUnit ] = Tex->Handle(); - if ( GLi->IsExtension( EEGL_ARB_multitexture ) ) + if ( TextureUnit && GLi->IsExtension( EEGL_ARB_multitexture ) ) SetActiveTextureUnit( 0 ); } } diff --git a/src/eepp/graphics/renderer/cgl.cpp b/src/eepp/graphics/renderer/cgl.cpp index e1404f571..70bc7ef71 100644 --- a/src/eepp/graphics/renderer/cgl.cpp +++ b/src/eepp/graphics/renderer/cgl.cpp @@ -1,6 +1,7 @@ #include #include #include +#include namespace EE { namespace Graphics { @@ -14,11 +15,17 @@ cGL * cGL::CreateSingleton( EEGL_version ver ) { ver = GLv_2; #else if ( GLv_default == ver ) - ver = GLv_3; + ver = GLv_ES2; #endif switch ( ver ) { case GLv_ES2: + { + #if defined( EE_GL3_ENABLED ) || defined( EE_GLES2 ) + ms_singleton = eeNew( cRendererGLES2, () ); + break; + #endif + } case GLv_3: { #if defined( EE_GL3_ENABLED ) || defined( EE_GLES2 ) @@ -43,7 +50,7 @@ cGL * cGL::CreateSingleton( EEGL_version ver ) { cGL * cGL::CreateSingleton() { if ( ms_singleton == 0 ) { #ifdef EE_GLES2 - ms_singleton = eeNew( cRendererGL3, () ); + ms_singleton = eeNew( cRendererGLES2, () ); #elif defined( EE_GLES1 ) ms_singleton = eeNew( cRendererGL, () ); #else @@ -88,6 +95,10 @@ cRendererGL3 * cGL::GetRendererGL3() { return reinterpret_cast( this ); } +cRendererGLES2 * cGL::GetRendererGLES2() { + return reinterpret_cast( this ); +} + void cGL::WriteExtension( Uint8 Pos, Uint32 BitWrite ) { Write32BitKey( &mExtensions, Pos, BitWrite ); } @@ -147,7 +158,11 @@ bool cGL::IsExtension( EEGL_extensions name ) { } bool cGL::PointSpriteSupported() { +#ifdef EE_GLES + return true; +#else return IsExtension( EEGL_ARB_point_parameters ) && IsExtension( EEGL_ARB_point_sprite ); +#endif } bool cGL::ShadersSupported() { diff --git a/src/eepp/graphics/renderer/crenderergl3.cpp b/src/eepp/graphics/renderer/crenderergl3.cpp index 374a376e1..9f6e1d6f7 100644 --- a/src/eepp/graphics/renderer/crenderergl3.cpp +++ b/src/eepp/graphics/renderer/crenderergl3.cpp @@ -4,20 +4,20 @@ namespace EE { namespace Graphics { -const char * EEGL_STATES_NAME[] = { +const char * EEGL3_STATES_NAME[] = { "dgl_Vertex", "dgl_Normal", "dgl_FrontColor" }; -const char * EEGL_TEXTUREUNIT_NAMES[] = { +const char * EEGL3_TEXTUREUNIT_NAMES[] = { "dgl_MultiTexCoord0", "dgl_MultiTexCoord1", "dgl_MultiTexCoord2", "dgl_MultiTexCoord3" }; -const char * EEGL_PLANES_ENABLED_NAME[] = { +const char * EEGL3_PLANES_ENABLED_NAME[] = { "dgl_ClipEnabled[0]", "dgl_ClipEnabled[1]", "dgl_ClipEnabled[2]", @@ -26,7 +26,7 @@ const char * EEGL_PLANES_ENABLED_NAME[] = { "dgl_ClipEnabled[5]" }; -const char * EEGL_PLANES_NAME[] = { +const char * EEGL3_PLANES_NAME[] = { "dgl_ClipPlane[0]", "dgl_ClipPlane[1]", "dgl_ClipPlane[2]", @@ -35,77 +35,11 @@ const char * EEGL_PLANES_NAME[] = { "dgl_ClipPlane[5]" }; -const GLchar * EEGL_SHADER_BASE_VS[] = { - "#define MAX_CLIP_PLANES 6\n", - "#ifdef GL_ES\n", - "precision mediump float;\n", - "precision lowp int;\n", - "#else\n", - "#version 120\n", - "#endif\n", - "uniform mat4 dgl_ProjectionMatrix;\n", - "uniform mat4 dgl_ModelViewMatrix;\n", - "uniform int dgl_ClippingEnabled;\n", - "uniform int dgl_ClipEnabled[ MAX_CLIP_PLANES ];\n", - "uniform vec4 dgl_ClipPlane[ MAX_CLIP_PLANES ];\n", - "uniform float dgl_PointSize;\n", - "attribute vec4 dgl_Vertex;\n", - "attribute vec4 dgl_FrontColor;\n", - "attribute vec4 dgl_MultiTexCoord0;\n", - "varying vec4 dgl_Color;\n", - "varying vec4 dgl_TexCoord[ 1 ];\n", - "varying float dgl_ClipDistance[ MAX_CLIP_PLANES ];\n", - "void main(void)\n", - "{\n", - " gl_PointSize = dgl_PointSize;\n", - " dgl_Color = dgl_FrontColor;\n", - " dgl_TexCoord[0] = dgl_MultiTexCoord0;\n", - " vec4 vEye = dgl_ModelViewMatrix * dgl_Vertex;\n", - " gl_Position = dgl_ProjectionMatrix * vEye;\n", - " if ( 1 == dgl_ClippingEnabled ) {\n", - " for ( int i = 0; i < MAX_CLIP_PLANES; i++ ) {\n", - " if ( 1 == dgl_ClipEnabled[i] )\n", - " dgl_ClipDistance[i] = dot( vEye, dgl_ClipPlane[i] );\n", - " }\n", - " }\n", - "}\n" -}; +const GLchar * EEGL3_SHADER_BASE_VS = +#include "shaders/basegl3.vert" -const GLchar * EEGL_SHADER_BASE_FS[] = { - "#define MAX_CLIP_PLANES 6\n", - "#ifdef GL_ES\n", - "precision mediump float;\n", - "precision lowp int;\n", - "#else\n", - "#version 120\n", - "#endif\n", - "uniform sampler2D textureUnit0;\n", - "uniform int dgl_TexActive;\n", - "uniform int dgl_PointSpriteActive;\n", - "uniform int dgl_ClippingEnabled;\n", - "uniform int dgl_ClipEnabled[ MAX_CLIP_PLANES ];\n", - "uniform vec4 dgl_ClipPlane[ MAX_CLIP_PLANES ];\n", - "varying vec4 dgl_Color;\n", - "varying vec4 dgl_TexCoord[ 1 ];\n", - "varying float dgl_ClipDistance[ MAX_CLIP_PLANES ];\n", - "void main(void)\n", - "{\n", - " if ( 1 == dgl_ClippingEnabled ) {\n", - " for ( int i = 0; i < MAX_CLIP_PLANES; i++ ) {\n", - " if ( 1 == dgl_ClipEnabled[i] )\n", - " if ( dgl_ClipDistance[i] < 0.0 )\n", - " discard;\n", - " }\n", - " }\n", - " if ( 0 == dgl_PointSpriteActive ) {\n", - " if ( 1 == dgl_TexActive )\n", - " gl_FragColor = dgl_Color * texture2D( textureUnit0, dgl_TexCoord[ 0 ].xy );\n", - " else\n", - " gl_FragColor = dgl_Color;\n", - " } else\n", - " gl_FragColor = dgl_Color * texture2D( textureUnit0, gl_PointCoord );\n", - "}\n", -}; +const GLchar * EEGL3_SHADER_BASE_FS = +#include "shaders/basegl3.frag" cRendererGL3::cRendererGL3() : mProjectionMatrix_id(0), @@ -129,19 +63,58 @@ cRendererGL3::~cRendererGL3() { } EEGL_version cRendererGL3::Version() { - #ifndef EE_GLES2 return GLv_3; - #else - return GLv_ES2; - #endif } std::string cRendererGL3::VersionStr() { - #ifndef EE_GLES2 return "OpenGL 3"; - #else - return "OpenGL ES 2"; - #endif +} + +void cRendererGL3::Init() { + if ( !mLoaded ) { + Uint32 i; + + cGL::Init(); + + std::string vs( EEGL3_SHADER_BASE_VS ); + std::string fs( EEGL3_SHADER_BASE_FS ); + + mBaseVertexShader = vs; + + for ( i = 0; i < EEGL_ARRAY_STATES_COUNT; i++ ) { + mAttribsLoc[ i ] = -1; + mAttribsLocStates[ i ] = 0; + } + + for ( i = 0; i < EE_MAX_PLANES; i++ ) { + mPlanes[i] = -1; + mPlanesStates[i] = 0; + } + + for ( i = 0; i < EE_MAX_TEXTURE_UNITS; i++ ) { + mTextureUnits[i] = -1; + mTextureUnitsStates[i] = 0; + } + + cShader::Ensure = false; + + mShaders[ EEGL3_SHADER_BASE ] = eeNew( cShaderProgram, ( vs.c_str(), vs.size(), fs.c_str(), fs.size() ) ); + mShaders[ EEGL3_SHADER_BASE ]->SetReloadCb( cb::Make1( this, &cRendererGL3::ReloadShader ) ); + + cShader::Ensure = true; + + SetShader( EEGL3_SHADER_BASE ); + } else { + mCurShader = NULL; + + mShaders[ EEGL3_SHADER_BASE ]->Reload(); + + SetShader( EEGL3_SHADER_BASE ); + } + + ClientActiveTexture( GL_TEXTURE0 ); + + mLoaded = true; } GLuint cRendererGL3::BaseShaderId() { @@ -154,19 +127,23 @@ void cRendererGL3::ReloadShader( cShaderProgram * Shader ) { SetShader( Shader ); } -void cRendererGL3::SetShader( const EEGL_SHADERS& Shader ) { +void cRendererGL3::SetShader( const EEGL3_SHADERS& Shader ) { SetShader( mShaders[ Shader ] ); } void cRendererGL3::SetShader( cShaderProgram * Shader ) { if ( NULL == Shader ) { - Shader = mShaders[ EEGL_SHADER_BASE ]; + Shader = mShaders[ EEGL3_SHADER_BASE ]; } if ( mCurShader == Shader ) { return; } + DisableClientState( GL_VERTEX_ARRAY ); + DisableClientState( GL_TEXTURE_COORD_ARRAY ); + DisableClientState( GL_COLOR_ARRAY ); + mShaderPrev = mCurShader; mCurShader = Shader; mProjectionMatrix_id = mCurShader->UniformLocation( "dgl_ProjectionMatrix" ); @@ -179,23 +156,28 @@ void cRendererGL3::SetShader( cShaderProgram * Shader ) { Uint32 i; for ( i = 0; i < EEGL_ARRAY_STATES_COUNT; i++ ) { - mStates[ i ] = mCurShader->AttributeLocation( EEGL_STATES_NAME[ i ] ); + mAttribsLoc[ i ] = mCurShader->AttributeLocation( EEGL3_STATES_NAME[ i ] ); } for ( i = 0; i < EE_MAX_PLANES; i++ ) { - mPlanes[ i ] = mCurShader->UniformLocation( EEGL_PLANES_NAME[ i ] ); + mPlanes[ i ] = mCurShader->UniformLocation( EEGL3_PLANES_NAME[ i ] ); } for ( i = 0; i < EE_MAX_TEXTURE_UNITS; i++ ) { - mTextureUnits[ i ] = mCurShader->AttributeLocation( EEGL_TEXTUREUNIT_NAMES[ i ] ); + mTextureUnits[ i ] = mCurShader->AttributeLocation( EEGL3_TEXTUREUNIT_NAMES[ i ] ); } - DisableClientState( GL_VERTEX_ARRAY ); - DisableClientState( GL_TEXTURE_COORD_ARRAY ); - DisableClientState( GL_COLOR_ARRAY ); - glUseProgram( mCurShader->Handler() ); + if ( -1 != mAttribsLoc[ EEGL_VERTEX_ARRAY ] ) + EnableClientState( GL_VERTEX_ARRAY ); + + if ( -1 != mAttribsLoc[ EEGL_COLOR_ARRAY ] ) + EnableClientState( GL_COLOR_ARRAY ); + + if ( -1 != mTextureUnits[ mCurActiveTex ] ) + EnableClientState( GL_TEXTURE_COORD_ARRAY ); + GLenum CM = mCurrentMode; MatrixMode( GL_PROJECTION ); @@ -204,7 +186,6 @@ void cRendererGL3::SetShader( cShaderProgram * Shader ) { UpdateMatrix(); MatrixMode( CM ); - #ifdef EE_GLES2 if ( -1 != mTexActiveLoc ) { mCurShader->SetUniform( mTexActiveLoc, 1 ); } @@ -213,14 +194,13 @@ void cRendererGL3::SetShader( cShaderProgram * Shader ) { for ( i = 0; i < EE_MAX_PLANES; i++ ) { if ( -1 != mPlanes[ i ] ) { - mCurShader->SetUniform( EEGL_PLANES_ENABLED_NAME[ i ], 0 ); + mCurShader->SetUniform( EEGL3_PLANES_ENABLED_NAME[ i ], 0 ); } } if ( -1 != mPointSpriteLoc ) { mCurShader->SetUniform( mPointSpriteLoc, 0 ); } - #endif } void cRendererGL3::Enable( GLenum cap ) { @@ -229,6 +209,7 @@ void cRendererGL3::Enable( GLenum cap ) { { if ( 0 == mTexActive ) { mTexActive = 1; + mCurShader->SetUniform( mTexActiveLoc, mTexActive ); } @@ -245,8 +226,10 @@ void cRendererGL3::Enable( GLenum cap ) { if ( 0 == mPlanesStates[ plane ] ) { mPlanesStates[ plane ] = 1; + PlaneStateCheck( true ); - mCurShader->SetUniform( EEGL_PLANES_ENABLED_NAME[ plane ], 1 ); + + mCurShader->SetUniform( EEGL3_PLANES_ENABLED_NAME[ plane ], 1 ); } return; @@ -270,6 +253,7 @@ void cRendererGL3::Disable ( GLenum cap ) { { if ( 1 == mTexActive ) { mTexActive = 0; + mCurShader->SetUniform( mTexActiveLoc, mTexActive ); } @@ -286,8 +270,10 @@ void cRendererGL3::Disable ( GLenum cap ) { if ( 1 == mPlanesStates[ plane ] ) { mPlanesStates[ plane ] = 0; + PlaneStateCheck( false ); - mCurShader->SetUniform( EEGL_PLANES_ENABLED_NAME[ plane ], 0 ); + + mCurShader->SetUniform( EEGL3_PLANES_ENABLED_NAME[ plane ], 0 ); } return; @@ -305,6 +291,101 @@ void cRendererGL3::Disable ( GLenum cap ) { cGL::Disable( cap ); } +void cRendererGL3::EnableClientState( GLenum array ) { + GLint state; + + if ( GL_TEXTURE_COORD_ARRAY == array ) { + if ( -1 != ( state = mTextureUnits[ mCurActiveTex ] ) ) { + mTextureUnitsStates[ mCurActiveTex ] = 1; + + glEnableVertexAttribArray( state ); + } + } else { + Int32 Pos = array - GL_VERTEX_ARRAY; + + if ( -1 != ( state = mAttribsLoc[ Pos ] ) ) { + mAttribsLocStates[ Pos ] = 1; + + glEnableVertexAttribArray( state ); + } + } +} + +void cRendererGL3::DisableClientState( GLenum array ) { + GLint state; + + if ( GL_TEXTURE_COORD_ARRAY == array ) { + if ( -1 != ( state = mTextureUnits[ mCurActiveTex ] ) ) { + mTextureUnitsStates[ mCurActiveTex ] = 0; + + glDisableVertexAttribArray( state ); + } + } else { + Int32 Pos = array - GL_VERTEX_ARRAY; + + if ( -1 != ( state = mAttribsLoc[ Pos ] ) ) { + mAttribsLocStates[ Pos ] = 0; + + glDisableVertexAttribArray( state ); + } + } +} + +void cRendererGL3::VertexPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid * pointer, GLuint allocate ) { + const GLint index = mAttribsLoc[ EEGL_VERTEX_ARRAY ]; + + if ( -1 != index ) { + if ( 0 == mAttribsLocStates[ EEGL_VERTEX_ARRAY ] ) { + mAttribsLocStates[ EEGL_VERTEX_ARRAY ] = 1; + + glEnableVertexAttribArray( index ); + } + + glVertexAttribPointerARB( index, size, type, GL_FALSE, stride, pointer ); + } +} + +void cRendererGL3::ColorPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer, GLuint allocate ) { + const GLint index = mAttribsLoc[ EEGL_COLOR_ARRAY ]; + + if ( -1 != index ) { + if ( 0 == mAttribsLocStates[ EEGL_COLOR_ARRAY ] ) { + mAttribsLocStates[ EEGL_COLOR_ARRAY ] = 1; + + glEnableVertexAttribArray( index ); + } + + if ( type == GL_UNSIGNED_BYTE ) { + glVertexAttribPointerARB( index, size, type, GL_TRUE, stride, pointer ); + } else { + glVertexAttribPointerARB( index, size, type, GL_FALSE, stride, pointer ); + } + } +} + +void cRendererGL3::TexCoordPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer, GLuint allocate ) { + const GLint index = mTextureUnits[ mCurActiveTex ]; + + if ( -1 != index ) { + if ( 0 == mTextureUnitsStates[ mCurActiveTex ] ) { + mTextureUnitsStates[ mCurActiveTex ] = 1; + + glEnableVertexAttribArray( index ); + } + + glVertexAttribPointerARB( index, size, type, GL_FALSE, stride, pointer ); + } +} + +GLint cRendererGL3::GetStateIndex( const Uint32& State ) { + eeASSERT( State < EEGL_ARRAY_STATES_COUNT ); + + if ( EEGL_TEXTURE_COORD_ARRAY == State ) + return mTextureUnits[ mCurActiveTex ]; + + return mAttribsLoc[ State ]; +} + void cRendererGL3::PlaneStateCheck( bool tryEnable ) { GLint i; @@ -326,45 +407,6 @@ void cRendererGL3::PlaneStateCheck( bool tryEnable ) { } } -void cRendererGL3::Init() { - if ( !mLoaded ) { - cGL::Init(); - - mBaseVertexShader = ""; - - for ( Uint32 i = 0; i < sizeof(EEGL_SHADER_BASE_VS)/sizeof(const GLchar*); i++ ) { - mBaseVertexShader += std::string( EEGL_SHADER_BASE_VS[i] ); - } - - Uint32 i; - - for ( i = 0; i < EE_MAX_PLANES; i++ ) { - mPlanes[i] = -1; - mPlanesStates[i] = 0; - } - - for ( i = 0; i < EE_MAX_TEXTURE_UNITS; i++ ) - mTextureUnits[i] = -1; - - cShader::Ensure = false; - mShaders[ EEGL_SHADER_BASE ] = eeNew( cShaderProgram, ( (const char**)EEGL_SHADER_BASE_VS, sizeof(EEGL_SHADER_BASE_VS)/sizeof(const GLchar*), (const char**)EEGL_SHADER_BASE_FS, sizeof(EEGL_SHADER_BASE_FS)/sizeof(const GLchar*), "EEGL_SHADER_BASE_TEX" ) ); - mShaders[ EEGL_SHADER_BASE ]->SetReloadCb( cb::Make1( this, &cRendererGL3::ReloadShader ) ); - cShader::Ensure = true; - - SetShader( mShaders[ EEGL_SHADER_BASE ] ); - } else { - mCurShader = NULL; - - mShaders[ EEGL_SHADER_BASE ]->Reload(); - - SetShader( mShaders[ EEGL_SHADER_BASE ] ); - } - - ClientActiveTexture( GL_TEXTURE0 ); - - mLoaded = true; -} - void cRendererGL3::UpdateMatrix() { switch ( mCurrentMode ) { case GL_PROJECTION: @@ -503,73 +545,6 @@ void cRendererGL3::MatrixMode(GLenum mode) { } } -void cRendererGL3::EnableClientState( GLenum array ) { - GLint state; - - if ( GL_TEXTURE_COORD_ARRAY == array ) { - if ( -1 != ( state = mTextureUnits[ mCurActiveTex ] ) ) - glEnableVertexAttribArray( state ); - } else { - if ( -1 != ( state = mStates[ array - GL_VERTEX_ARRAY ] ) ) - glEnableVertexAttribArray( state ); - } -} - -void cRendererGL3::DisableClientState( GLenum array ) { - GLint state; - - if ( GL_TEXTURE_COORD_ARRAY == array ) { - if ( -1 != ( state = mTextureUnits[ mCurActiveTex ] ) ) - glDisableVertexAttribArray( state ); - } else { - if ( -1 != ( state = mStates[ array - GL_VERTEX_ARRAY ] ) ) - glDisableVertexAttribArray( state ); - } -} - -void cRendererGL3::VertexPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid * pointer, GLuint allocate ) { - const GLint index = mStates[ EEGL_VERTEX_ARRAY ]; - - if ( -1 != index ) { - glEnableVertexAttribArray( index ); - - glVertexAttribPointerARB( index, size, type, GL_FALSE, stride, pointer ); - } -} - -void cRendererGL3::ColorPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer, GLuint allocate ) { - const GLint index = mStates[ EEGL_COLOR_ARRAY ]; - - if ( -1 != index ) { - glEnableVertexAttribArray( index ); - - if ( type == GL_UNSIGNED_BYTE ) { - glVertexAttribPointerARB( index, size, type, GL_TRUE, stride, pointer ); - } else { - glVertexAttribPointerARB( index, size, type, GL_FALSE, stride, pointer ); - } - } -} - -void cRendererGL3::TexCoordPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer, GLuint allocate ) { - const GLint index = mTextureUnits[ mCurActiveTex ]; - - if ( -1 != index ) { - glEnableVertexAttribArray( index ); - - glVertexAttribPointerARB( index, size, type, GL_FALSE, stride, pointer ); - } -} - -GLint cRendererGL3::GetStateIndex( const Uint32& State ) { - eeASSERT( State < EEGL_ARRAY_STATES_COUNT ); - - if ( EEGL_TEXTURE_COORD_ARRAY == State ) - return mTextureUnits[ mCurActiveTex ]; - - return mStates[ State ]; -} - void cRendererGL3::Clip2DPlaneEnable( const Int32& x, const Int32& y, const Int32& Width, const Int32& Height ) { GLfloat tX = (GLfloat)x; GLfloat tY = (GLfloat)y; diff --git a/src/eepp/graphics/renderer/crenderergles2.cpp b/src/eepp/graphics/renderer/crenderergles2.cpp new file mode 100644 index 000000000..9fc6d2c04 --- /dev/null +++ b/src/eepp/graphics/renderer/crenderergles2.cpp @@ -0,0 +1,742 @@ +#include + +#ifdef EE_GL3_ENABLED + +namespace EE { namespace Graphics { + +const char * EEGLES2_STATES_NAME[] = { + "dgl_Vertex", + "dgl_Normal", + "dgl_FrontColor" +}; + +const char * EEGLES2_TEXTUREUNIT_NAMES[] = { + "dgl_MultiTexCoord0", + "dgl_MultiTexCoord1", + "dgl_MultiTexCoord2", + "dgl_MultiTexCoord3" +}; + +const char * EEGLES2_PLANES_ENABLED_NAME[] = { + "dgl_ClipEnabled[0]", + "dgl_ClipEnabled[1]", + "dgl_ClipEnabled[2]", + "dgl_ClipEnabled[3]", + "dgl_ClipEnabled[4]", + "dgl_ClipEnabled[5]" +}; + +const char * EEGLES2_PLANES_NAMENABLED_NAME[] = { + "dgl_ClipPlane[0]", + "dgl_ClipPlane[1]", + "dgl_ClipPlane[2]", + "dgl_ClipPlane[3]", + "dgl_ClipPlane[4]", + "dgl_ClipPlane[5]" +}; + +const GLchar * EEGLES2_SHADER_BASE_VS = +#include "shaders/base.vert" + +const GLchar * EEGLES2_SHADER_BASE_FS = +#include "shaders/base.frag" + +const GLchar * EEGLES2_SHADER_CLIPPED_VS = +#include "shaders/clipped.vert" + +const GLchar * EEGLES2_SHADER_CLIPPED_FS = +#include "shaders/clipped.frag" + +const GLchar * EEGLES2_SHADER_POINTSPRITE_VS = +#include "shaders/pointsprite.vert" + +const GLchar * EEGLES2_SHADER_POINTSPRITE_FS = +#include "shaders/pointsprite.frag" + +const GLchar * EEGLES2_SHADER_PRIMITIVE_VS = +#include "shaders/primitive.vert" + +const GLchar * EEGLES2_SHADER_PRIMITIVE_FS = +#include "shaders/primitive.frag" + +cRendererGLES2::cRendererGLES2() : + mProjectionMatrix_id(0), + mModelViewMatrix_id(0), + mCurrentMode(0), + mCurShader(NULL), + mShaderPrev(NULL), + mTexActive(1), + mTexActiveLoc(-1), + mClippingEnabledLoc(-1), + mPointSize(1.f), + mCurActiveTex( 0 ), + mClippingEnabled( false ), + mPointSpriteEnabled( false ), + mLoaded( false ), + mCurShaderLocal( true ) +{ + mProjectionMatrix.push ( glm::mat4( 1.0f ) ); // identity matrix + mModelViewMatrix.push ( glm::mat4( 1.0f ) ); // identity matrix +} + +cRendererGLES2::~cRendererGLES2() { +} + +EEGL_version cRendererGLES2::Version() { + return GLv_ES2; +} + +std::string cRendererGLES2::VersionStr() { + return "OpenGL ES 2"; +} + +void cRendererGLES2::Init() { + if ( !mLoaded ) { + Uint32 i; + + cGL::Init(); + + std::string vs( EEGLES2_SHADER_BASE_VS ); + std::string fs( EEGLES2_SHADER_BASE_FS ); + + mBaseVertexShader = vs; + + for ( i = 0; i < EEGL_ARRAY_STATES_COUNT; i++ ) { + mAttribsLoc[ i ] = -1; + mAttribsLocStates[ i ] = 0; + } + + for ( i = 0; i < EE_MAX_PLANES; i++ ) { + mPlanes[i] = -1; + mPlanesStates[i] = 0; + } + + for ( i = 0; i < EE_MAX_TEXTURE_UNITS; i++ ) { + mTextureUnits[i] = -1; + mTextureUnitsStates[i] = 0; + } + + cShader::Ensure = false; + + mShaders[ EEGLES2_SHADER_BASE ] = eeNew( cShaderProgram, ( vs.c_str(), vs.size(), fs.c_str(), fs.size() ) ); + mShaders[ EEGLES2_SHADER_BASE ]->SetReloadCb( cb::Make1( this, &cRendererGLES2::ReloadShader ) ); + + vs = EEGLES2_SHADER_CLIPPED_VS; + fs = EEGLES2_SHADER_CLIPPED_FS; + + mShaders[ EEGLES2_SHADER_CLIPPED ] = eeNew( cShaderProgram, ( vs.c_str(), vs.size(), fs.c_str(), fs.size() ) ); + mShaders[ EEGLES2_SHADER_CLIPPED ]->SetReloadCb( cb::Make1( this, &cRendererGLES2::ReloadShader ) ); + + vs = EEGLES2_SHADER_POINTSPRITE_VS; + fs = EEGLES2_SHADER_POINTSPRITE_FS; + + mShaders[ EEGLES2_SHADER_POINTSPRITE ] = eeNew( cShaderProgram, ( vs.c_str(), vs.size(), fs.c_str(), fs.size() ) ); + mShaders[ EEGLES2_SHADER_POINTSPRITE ]->SetReloadCb( cb::Make1( this, &cRendererGLES2::ReloadShader ) ); + + vs = EEGLES2_SHADER_PRIMITIVE_VS; + fs = EEGLES2_SHADER_PRIMITIVE_FS; + + mShaders[ EEGLES2_SHADER_PRIMITIVE ] = eeNew( cShaderProgram, ( vs.c_str(), vs.size(), fs.c_str(), fs.size() ) ); + mShaders[ EEGLES2_SHADER_PRIMITIVE ]->SetReloadCb( cb::Make1( this, &cRendererGLES2::ReloadShader ) ); + + cShader::Ensure = true; + + SetShader( EEGLES2_SHADER_BASE ); + } else { + mCurShader = NULL; + + mShaders[ EEGLES2_SHADER_BASE ]->Reload(); + + SetShader( EEGLES2_SHADER_BASE ); + } + + ClientActiveTexture( GL_TEXTURE0 ); + + mLoaded = true; +} + +GLuint cRendererGLES2::BaseShaderId() { + return mCurShader->Handler(); +} + +void cRendererGLES2::ReloadShader( cShaderProgram * Shader ) { + mCurShader = NULL; + + SetShader( Shader ); +} + +void cRendererGLES2::SetShader( const EEGLES2_SHADERS& Shader ) { + SetShader( mShaders[ Shader ] ); +} + +void cRendererGLES2::CheckLocalShader() { + for ( Uint32 i = 0; i < EEGLES2_SHADERS_COUNT; i++ ) { + if ( mShaders[i] == mCurShader ) { + mCurShaderLocal = true; + return; + } + } + + mCurShaderLocal = false; +} + +void cRendererGLES2::SetShader( cShaderProgram * Shader ) { + if ( NULL == Shader ) { + Shader = mShaders[ EEGLES2_SHADER_BASE ]; + } + + if ( mCurShader == Shader ) { + return; + } + + DisableClientState( GL_VERTEX_ARRAY ); + DisableClientState( GL_TEXTURE_COORD_ARRAY ); + DisableClientState( GL_COLOR_ARRAY ); + + mShaderPrev = mCurShader; + mCurShader = Shader; + + CheckLocalShader(); + + mProjectionMatrix_id = mCurShader->UniformLocation( "dgl_ProjectionMatrix" ); + mModelViewMatrix_id = mCurShader->UniformLocation( "dgl_ModelViewMatrix" ); + mTexActiveLoc = mCurShader->UniformLocation( "dgl_TexActive" ); + mClippingEnabledLoc = mCurShader->UniformLocation( "dgl_ClippingEnabled" ); + mCurActiveTex = 0; + + Uint32 i; + + for ( i = 0; i < EEGL_ARRAY_STATES_COUNT; i++ ) { + mAttribsLoc[ i ] = mCurShader->AttributeLocation( EEGLES2_STATES_NAME[ i ] ); + } + + for ( i = 0; i < EE_MAX_PLANES; i++ ) { + if ( -1 != mClippingEnabledLoc ) { + mPlanes[ i ] = mCurShader->UniformLocation( EEGLES2_PLANES_NAMENABLED_NAME[ i ] ); + } else { + mPlanes[ i ] = -1; + } + } + + for ( i = 0; i < EE_MAX_TEXTURE_UNITS; i++ ) { + mTextureUnits[ i ] = mCurShader->AttributeLocation( EEGLES2_TEXTUREUNIT_NAMES[ i ] ); + } + + glUseProgram( mCurShader->Handler() ); + + if ( -1 != mAttribsLoc[ EEGL_VERTEX_ARRAY ] ) + EnableClientState( GL_VERTEX_ARRAY ); + + if ( -1 != mAttribsLoc[ EEGL_COLOR_ARRAY ] ) + EnableClientState( GL_COLOR_ARRAY ); + + if ( -1 != mTextureUnits[ mCurActiveTex ] ) + EnableClientState( GL_TEXTURE_COORD_ARRAY ); + + GLenum CM = mCurrentMode; + + MatrixMode( GL_PROJECTION ); + UpdateMatrix(); + MatrixMode( GL_MODELVIEW ); + UpdateMatrix(); + MatrixMode( CM ); + + if ( -1 != mTexActiveLoc ) { + mCurShader->SetUniform( mTexActiveLoc, mTexActive ); + } + + if ( -1 != mClippingEnabledLoc ) { + mCurShader->SetUniform( mClippingEnabledLoc, 0 ); + } + + for ( i = 0; i < EE_MAX_PLANES; i++ ) { + if ( -1 != mPlanes[ i ] ) { + mCurShader->SetUniform( EEGLES2_PLANES_ENABLED_NAME[ i ], 0 ); + } + } +} + +void cRendererGLES2::Enable( GLenum cap ) { + switch ( cap ) { + case GL_TEXTURE_2D: + { + if ( 0 == mTexActive ) { + mTexActive = 1; + + #ifdef EE_GLES2 + SetShader( EEGLES2_SHADER_BASE ); + #endif + } + + return; + } + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + { + GLint plane = cap - GL_CLIP_PLANE0; + + SetShader( EEGLES2_SHADER_CLIPPED ); + + mPlanesStates[ plane ] = 1; + + PlaneStateCheck( true ); + + mCurShader->SetUniform( EEGLES2_PLANES_ENABLED_NAME[ plane ], 1 ); + + return; + } + case GL_POINT_SPRITE: + { + mPointSpriteEnabled = 1; + + cGL::Enable( GL_VERTEX_PROGRAM_POINT_SIZE ); + + SetShader( EEGLES2_SHADER_POINTSPRITE ); + + break; + } + } + + cGL::Enable( cap ); +} + +void cRendererGLES2::Disable ( GLenum cap ) { + switch ( cap ) { + case GL_TEXTURE_2D: + { + if ( 1 == mTexActive ) { + mTexActive = 0; + + SetShader( EEGLES2_SHADER_PRIMITIVE ); + } + + return; + } + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + { + GLint plane = cap - GL_CLIP_PLANE0; + + if ( mTexActive ) { + SetShader( EEGLES2_SHADER_BASE ); + } else { + SetShader( EEGLES2_SHADER_PRIMITIVE ); + } + + mPlanesStates[ plane ] = 0; + + PlaneStateCheck( false ); + + return; + } + case GL_POINT_SPRITE: + { + mPointSpriteEnabled = 0; + + cGL::Disable( GL_VERTEX_PROGRAM_POINT_SIZE ); + + SetShader( EEGLES2_SHADER_BASE ); + + break; + } + } + + cGL::Disable( cap ); +} + +void cRendererGLES2::EnableClientState( GLenum array ) { + GLint state; + + if ( GL_TEXTURE_COORD_ARRAY == array ) { + if ( -1 != ( state = mTextureUnits[ mCurActiveTex ] ) ) { + mTextureUnitsStates[ mCurActiveTex ] = 1; + + glEnableVertexAttribArray( state ); + } + } else { + Int32 Pos = array - GL_VERTEX_ARRAY; + + if ( -1 != ( state = mAttribsLoc[ Pos ] ) ) { + mAttribsLocStates[ Pos ] = 1; + + glEnableVertexAttribArray( state ); + } + } +} + +void cRendererGLES2::DisableClientState( GLenum array ) { + GLint state; + + if ( GL_TEXTURE_COORD_ARRAY == array ) { + if ( -1 != ( state = mTextureUnits[ mCurActiveTex ] ) ) { + mTextureUnitsStates[ mCurActiveTex ] = 0; + + glDisableVertexAttribArray( state ); + } + } else { + Int32 Pos = array - GL_VERTEX_ARRAY; + + if ( -1 != ( state = mAttribsLoc[ Pos ] ) ) { + mAttribsLocStates[ Pos ] = 0; + + glDisableVertexAttribArray( state ); + } + } +} + +void cRendererGLES2::VertexPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid * pointer, GLuint allocate ) { + const GLint index = mAttribsLoc[ EEGL_VERTEX_ARRAY ]; + + if ( -1 != index ) { + if ( 0 == mAttribsLocStates[ EEGL_VERTEX_ARRAY ] ) { + mAttribsLocStates[ EEGL_VERTEX_ARRAY ] = 1; + + glEnableVertexAttribArray( index ); + } + + glVertexAttribPointerARB( index, size, type, GL_FALSE, stride, pointer ); + } +} + +void cRendererGLES2::ColorPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer, GLuint allocate ) { + const GLint index = mAttribsLoc[ EEGL_COLOR_ARRAY ]; + + if ( -1 != index ) { + if ( 0 == mAttribsLocStates[ EEGL_COLOR_ARRAY ] ) { + mAttribsLocStates[ EEGL_COLOR_ARRAY ] = 1; + + glEnableVertexAttribArray( index ); + } + + if ( type == GL_UNSIGNED_BYTE ) { + glVertexAttribPointerARB( index, size, type, GL_TRUE, stride, pointer ); + } else { + glVertexAttribPointerARB( index, size, type, GL_FALSE, stride, pointer ); + } + } +} + +void cRendererGLES2::TexCoordPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer, GLuint allocate ) { + if ( mCurShaderLocal ) { + if ( 1 == mTexActive ) { + if ( mCurShader == mShaders[ EEGLES2_SHADER_PRIMITIVE ] ) { + if ( mClippingEnabled ) { + SetShader( EEGLES2_SHADER_CLIPPED ); + } else if ( mPointSpriteEnabled ) { + SetShader( EEGLES2_SHADER_POINTSPRITE ); + } else { + SetShader( EEGLES2_SHADER_BASE ); + } + } + } + } + + const GLint index = mTextureUnits[ mCurActiveTex ]; + + if ( -1 != index ) { + if ( 0 == mTextureUnitsStates[ mCurActiveTex ] ) { + mTextureUnitsStates[ mCurActiveTex ] = 1; + + glEnableVertexAttribArray( index ); + } + + glVertexAttribPointerARB( index, size, type, GL_FALSE, stride, pointer ); + } +} + +GLint cRendererGLES2::GetStateIndex( const Uint32& State ) { + eeASSERT( State < EEGL_ARRAY_STATES_COUNT ); + + if ( EEGL_TEXTURE_COORD_ARRAY == State ) + return mTextureUnits[ mCurActiveTex ]; + + return mAttribsLoc[ State ]; +} + +void cRendererGLES2::PlaneStateCheck( bool tryEnable ) { + GLint i; + + if ( tryEnable ) { + for ( i = 0; i < EE_MAX_PLANES; i++ ) { + if ( 0 != mPlanesStates[ i ] ) { + mCurShader->SetUniform( mClippingEnabledLoc, 1 ); + + mClippingEnabled = 1; + + return; + } + } + } else { + for ( i = 0; i < EE_MAX_PLANES; i++) { + if ( 0 != mPlanesStates[ i ] ) { + return; + } + } + + mClippingEnabled = 0; + } +} + +void cRendererGLES2::UpdateMatrix() { + switch ( mCurrentMode ) { + case GL_PROJECTION: + { + if ( -1 != mProjectionMatrix_id ) { + mCurShader->SetUniformMatrix( mProjectionMatrix_id, &mProjectionMatrix.top()[0][0] ); + } + + break; + } + case GL_MODELVIEW: + { + if ( -1 != mModelViewMatrix_id ) { + mCurShader->SetUniformMatrix( mModelViewMatrix_id, &mModelViewMatrix.top()[0][0] ); + } + + break; + } + } +} + +void cRendererGLES2::PushMatrix() { + mCurMatrix->push( mCurMatrix->top() ); + UpdateMatrix(); +} + +void cRendererGLES2::PopMatrix() { + mCurMatrix->pop(); + UpdateMatrix(); +} + +void cRendererGLES2::LoadIdentity() { + mCurMatrix->top() = glm::mat4(1.0); + UpdateMatrix(); +} + +glm::mat4 cRendererGLES2::toGLMmat4( const GLfloat * m ) { + return glm::mat4( m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15] ); +} + +void cRendererGLES2::MultMatrixf ( const GLfloat * m ) { + mCurMatrix->top() *= toGLMmat4( m ); + UpdateMatrix(); +} + +void cRendererGLES2::Translatef( GLfloat x, GLfloat y, GLfloat z ) { + mCurMatrix->top() *= glm::translate( glm::vec3( x, y, z ) ); + UpdateMatrix(); +} + +void cRendererGLES2::Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) { + mCurMatrix->top() *= glm::rotate( angle, glm::vec3( x, y, z ) ); + UpdateMatrix(); +} + +void cRendererGLES2::Scalef( GLfloat x, GLfloat y, GLfloat z ) { + mCurMatrix->top() *= glm::scale( glm::vec3( x, y, z ) ); + UpdateMatrix(); +} + +void cRendererGLES2::Ortho( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar ) { + mCurMatrix->top() *= glm::ortho( left, right, bottom, top , zNear, zFar ); + UpdateMatrix(); +} + +void cRendererGLES2::LookAt( GLfloat eyeX, GLfloat eyeY, GLfloat eyeZ, GLfloat centerX, GLfloat centerY, GLfloat centerZ, GLfloat upX, GLfloat upY, GLfloat upZ ) { + mCurMatrix->top() *= glm::lookAt( glm::vec3(eyeX, eyeY, eyeZ), glm::vec3(centerX, centerY, centerZ), glm::vec3(upX, upY, upZ) ); + UpdateMatrix(); +} + +void cRendererGLES2::Perspective ( GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar ) { + mCurMatrix->top() *= glm::perspective( fovy, aspect, zNear, zFar ); + UpdateMatrix(); +} + +void cRendererGLES2::LoadMatrixf( const GLfloat * m ) { + mCurMatrix->top() = toGLMmat4( m ); + UpdateMatrix(); +} + +void cRendererGLES2::Frustum( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near_val, GLfloat far_val ) { + mCurMatrix->top() *= glm::frustum( left, right, bottom, top, near_val, far_val ); + UpdateMatrix(); +} + +void cRendererGLES2::fromGLMmat4( glm::mat4 from, GLfloat * to ) { + Int32 i,p; + + for ( i = 0; i < 4; i++ ) { + glm::vec4 v = from[i]; + p = i * 4; + to[p ] = v.x; + to[p+1] = v.y; + to[p+2] = v.z; + to[p+3] = v.w; + } +} + +void cRendererGLES2::GetCurrentMatrix( GLenum mode, GLfloat * m ) { + switch ( mode ) { + case GL_PROJECTION: + case GL_PROJECTION_MATRIX: + { + fromGLMmat4( mProjectionMatrix.top(), m ); + break; + } + case GL_MODELVIEW: + case GL_MODELVIEW_MATRIX: + { + fromGLMmat4( mModelViewMatrix.top(), m ); + break; + } + } +} + +GLenum cRendererGLES2::GetCurrentMatrixMode() { + return mCurrentMode; +} + +void cRendererGLES2::MatrixMode(GLenum mode) { + mCurrentMode = mode; + + switch ( mCurrentMode ) { + case GL_PROJECTION: + case GL_PROJECTION_MATRIX: + { + mCurMatrix = &mProjectionMatrix; + break; + } + case GL_MODELVIEW: + case GL_MODELVIEW_MATRIX: + { + mCurMatrix = &mModelViewMatrix; + break; + } + } +} + +void cRendererGLES2::Clip2DPlaneEnable( const Int32& x, const Int32& y, const Int32& Width, const Int32& Height ) { + GLfloat tX = (GLfloat)x; + GLfloat tY = (GLfloat)y; + GLfloat tW = (GLfloat)Width; + GLfloat tH = (GLfloat)Height; + + glm::vec4 vclip_left ( 1.0 , 0.0 , 0.0 , -tX ); + glm::vec4 vclip_right ( -1.0 , 0.0 , 0.0 , tX + tW ); + glm::vec4 vclip_top ( 0.0 , 1.0 , 0.0 , -tY ); + glm::vec4 vclip_bottom ( 0.0 , -1.0 , 0.0 , tY + tH ); + + glm::mat4 invMV = glm::inverse( mModelViewMatrix.top() ); + + vclip_left = vclip_left * invMV; + vclip_right = vclip_right * invMV; + vclip_top = vclip_top * invMV; + vclip_bottom = vclip_bottom * invMV; + + GLi->Enable(GL_CLIP_PLANE0); + GLi->Enable(GL_CLIP_PLANE1); + GLi->Enable(GL_CLIP_PLANE2); + GLi->Enable(GL_CLIP_PLANE3); + + glUniform4fv( mPlanes[0], 1, static_cast( &vclip_left[0] ) ); + glUniform4fv( mPlanes[1], 1, static_cast( &vclip_right[0] ) ); + glUniform4fv( mPlanes[2], 1, static_cast( &vclip_top[0] ) ); + glUniform4fv( mPlanes[3], 1, static_cast( &vclip_bottom[0] ) ); +} + +void cRendererGLES2::Clip2DPlaneDisable() { + GLi->Disable(GL_CLIP_PLANE0); + GLi->Disable(GL_CLIP_PLANE1); + GLi->Disable(GL_CLIP_PLANE2); + GLi->Disable(GL_CLIP_PLANE3); +} + +void cRendererGLES2::PointSize( GLfloat size ) { + #ifndef EE_GLES2 + glPointSize( size );; + #endif + + mCurShader->SetUniform( "dgl_PointSize", size ); + + mPointSize = size; +} + +void cRendererGLES2::ClipPlane( GLenum plane, const GLdouble * equation ) { + Int32 nplane = plane - GL_CLIP_PLANE0; + Int32 location; + + if ( nplane < EE_MAX_PLANES ) { + location = mPlanes[ nplane ]; + } else { + std::string planeNum( "dgl_ClipPlane[" + toStr( nplane ) + "]" ); + + location = glGetUniformLocation( mCurShader->Handler(), (GLchar*)&planeNum[0] ); + } + + glm::vec4 teq( equation[0], equation[1], equation[2], equation[3] ); + + teq = teq * glm::inverse( mModelViewMatrix.top() ); /// Apply the inverse of the model view matrix to the equation + + glUniform4f( location, (GLfloat)teq[0], (GLfloat)teq[1], (GLfloat)teq[2], (GLfloat)teq[3] ); +} + +GLfloat cRendererGLES2::PointSize() { + return mPointSize; +} + +void cRendererGLES2::ClientActiveTexture( GLenum texture ) { + mCurActiveTex = texture - GL_TEXTURE0; + + if ( mCurActiveTex >= EE_MAX_TEXTURE_UNITS ) + mCurActiveTex = 0; +} + +void cRendererGLES2::TexEnvi( GLenum target, GLenum pname, GLint param ) { + //! @TODO: Implement TexEnvi +} + +std::string cRendererGLES2::GetBaseVertexShader() { + return mBaseVertexShader; +} + +GLint cRendererGLES2::Project( GLfloat objx, GLfloat objy, GLfloat objz, const GLfloat modelMatrix[16], const GLfloat projMatrix[16], const GLint viewport[4], GLfloat *winx, GLfloat *winy, GLfloat *winz ) { + glm::vec3 tv3( glm::project( glm::vec3( objx, objy, objz ), toGLMmat4( modelMatrix ), toGLMmat4( projMatrix ), glm::vec4( viewport[0], viewport[1], viewport[2], viewport[3] ) ) ); + + if ( NULL != winx ) + *winx = tv3.x; + + if ( NULL != winy ) + *winy = tv3.y; + + if ( NULL != winz ) + *winz = tv3.z; + + return GL_TRUE; +} + +GLint cRendererGLES2::UnProject( GLfloat winx, GLfloat winy, GLfloat winz, const GLfloat modelMatrix[16], const GLfloat projMatrix[16], const GLint viewport[4], GLfloat *objx, GLfloat *objy, GLfloat *objz ) { + glm::vec3 tv3( glm::unProject( glm::vec3( winx, winy, winz ), toGLMmat4( modelMatrix ), toGLMmat4( projMatrix ), glm::vec4( viewport[0], viewport[1], viewport[2], viewport[3] ) ) ); + + if ( NULL != objx ) + *objx = tv3.x; + + if ( NULL != objy ) + *objy = tv3.y; + + if ( NULL != objz ) + *objz = tv3.z; + + return GL_TRUE; +} + +}} + +#endif diff --git a/src/eepp/graphics/renderer/shaders/base.frag b/src/eepp/graphics/renderer/shaders/base.frag new file mode 100644 index 000000000..da701280e --- /dev/null +++ b/src/eepp/graphics/renderer/shaders/base.frag @@ -0,0 +1,19 @@ +"#define MAX_CLIP_PLANES 6\n\ +#ifdef GL_ES\n\ +precision lowp float;\n\ +precision lowp int;\n\ +#else\n\ +#version 120\n\ +#endif\n\ +uniform sampler2D textureUnit0;\n\ +varying vec4 dgl_Color;\n\ +#ifndef GL_ES\n\ +varying vec4 dgl_TexCoord[ 1 ];\n\ +#else\n\ +varying mediump vec4 dgl_TexCoord[ 1 ];\n\ +#endif\n\ +void main(void)\n\ +{\n\ + gl_FragColor = dgl_Color * texture2D( textureUnit0, dgl_TexCoord[ 0 ].xy );\n\ +}"; + diff --git a/src/eepp/graphics/renderer/shaders/base.vert b/src/eepp/graphics/renderer/shaders/base.vert new file mode 100644 index 000000000..5fba05d68 --- /dev/null +++ b/src/eepp/graphics/renderer/shaders/base.vert @@ -0,0 +1,26 @@ +"#define MAX_CLIP_PLANES 6\n\ +#ifdef GL_ES\n\ +precision lowp float;\n\ +precision lowp int;\n\ +#else\n\ +#version 120\n\ +#endif\n\ +uniform mat4 dgl_ProjectionMatrix;\n\ +uniform mat4 dgl_ModelViewMatrix;\n\ +attribute vec4 dgl_Vertex;\n\ +attribute vec4 dgl_FrontColor;\n\ +attribute vec4 dgl_MultiTexCoord0;\n\ +varying vec4 dgl_Color;\n\ +#ifndef GL_ES\n\ +varying vec4 dgl_TexCoord[ 1 ];\n\ +#else\n\ +varying mediump vec4 dgl_TexCoord[ 1 ];\n\ +#endif\n\ +void main(void)\n\ +{\n\ + dgl_Color = dgl_FrontColor;\n\ + dgl_TexCoord[0] = dgl_MultiTexCoord0;\n\ + vec4 vEye = dgl_ModelViewMatrix * dgl_Vertex;\n\ + gl_Position = dgl_ProjectionMatrix * vEye;\n\ +}\n\ +"; diff --git a/src/eepp/graphics/renderer/shaders/basegl3.frag b/src/eepp/graphics/renderer/shaders/basegl3.frag new file mode 100644 index 000000000..fbe8ad80a --- /dev/null +++ b/src/eepp/graphics/renderer/shaders/basegl3.frag @@ -0,0 +1,34 @@ +"#define MAX_CLIP_PLANES 6\n\ +#ifdef GL_ES\n\ +precision mediump float;\n\ +precision lowp int;\n\ +#else\n\ +#version 120\n\ +#endif\n\ +uniform sampler2D textureUnit0;\n\ +uniform int dgl_TexActive;\n\ +uniform int dgl_PointSpriteActive;\n\ +uniform int dgl_ClippingEnabled;\n\ +uniform int dgl_ClipEnabled[ MAX_CLIP_PLANES ];\n\ +uniform vec4 dgl_ClipPlane[ MAX_CLIP_PLANES ];\n\ +varying vec4 dgl_Color;\n\ +varying vec4 dgl_TexCoord[ 1 ];\n\ +varying float dgl_ClipDistance[ MAX_CLIP_PLANES ];\n\ +void main(void)\n\ +{\n\ + if ( 1 == dgl_ClippingEnabled ) {\n\ + for ( int i = 0; i < MAX_CLIP_PLANES; i++ ) {\n\ + if ( 1 == dgl_ClipEnabled[i] )\n\ + if ( dgl_ClipDistance[i] < 0.0 )\n\ + discard;\n\ + }\n\ + }\n\ + if ( 0 == dgl_PointSpriteActive ) {\n\ + if ( 1 == dgl_TexActive )\n\ + gl_FragColor = dgl_Color * texture2D( textureUnit0, dgl_TexCoord[ 0 ].xy );\n\ + else\n\ + gl_FragColor = dgl_Color;\n\ + } else\n\ + gl_FragColor = dgl_Color * texture2D( textureUnit0, gl_PointCoord );\n\ +}\n\ +"; diff --git a/src/eepp/graphics/renderer/shaders/basegl3.vert b/src/eepp/graphics/renderer/shaders/basegl3.vert new file mode 100644 index 000000000..d5751e3fb --- /dev/null +++ b/src/eepp/graphics/renderer/shaders/basegl3.vert @@ -0,0 +1,34 @@ +"#define MAX_CLIP_PLANES 6\n\ +#ifdef GL_ES\n\ +precision mediump float;\n\ +precision lowp int;\n\ +#else\n\ +#version 120\n\ +#endif\n\ +uniform mat4 dgl_ProjectionMatrix;\n\ +uniform mat4 dgl_ModelViewMatrix;\n\ +uniform int dgl_ClippingEnabled;\n\ +uniform int dgl_ClipEnabled[ MAX_CLIP_PLANES ];\n\ +uniform vec4 dgl_ClipPlane[ MAX_CLIP_PLANES ];\n\ +uniform float dgl_PointSize;\n\ +attribute vec4 dgl_Vertex;\n\ +attribute vec4 dgl_FrontColor;\n\ +attribute vec4 dgl_MultiTexCoord0;\n\ +varying vec4 dgl_Color;\n\ +varying vec4 dgl_TexCoord[ 1 ];\n\ +varying float dgl_ClipDistance[ MAX_CLIP_PLANES ];\n\ +void main(void)\n\ +{\n\ + gl_PointSize = dgl_PointSize;\n\ + dgl_Color = dgl_FrontColor;\n\ + dgl_TexCoord[0] = dgl_MultiTexCoord0;\n\ + vec4 vEye = dgl_ModelViewMatrix * dgl_Vertex;\n\ + gl_Position = dgl_ProjectionMatrix * vEye;\n\ + if ( 1 == dgl_ClippingEnabled ) {\n\ + for ( int i = 0; i < MAX_CLIP_PLANES; i++ ) {\n\ + if ( 1 == dgl_ClipEnabled[i] )\n\ + dgl_ClipDistance[i] = dot( vEye, dgl_ClipPlane[i] );\n\ + }\n\ + }\n\ +}\n\ +"; diff --git a/src/eepp/graphics/renderer/shaders/clipped.frag b/src/eepp/graphics/renderer/shaders/clipped.frag new file mode 100644 index 000000000..b04196721 --- /dev/null +++ b/src/eepp/graphics/renderer/shaders/clipped.frag @@ -0,0 +1,34 @@ +"#define MAX_CLIP_PLANES 6\n\ +#ifdef GL_ES\n\ +precision lowp float;\n\ +precision lowp int;\n\ +#else\n\ +#version 120\n\ +#endif\n\ +uniform sampler2D textureUnit0;\n\ +uniform int dgl_TexActive;\n\ +uniform int dgl_ClippingEnabled;\n\ +uniform int dgl_ClipEnabled[ MAX_CLIP_PLANES ];\n\ +uniform vec4 dgl_ClipPlane[ MAX_CLIP_PLANES ];\n\ +varying vec4 dgl_Color;\n\ +#ifndef GL_ES\n\ +varying vec4 dgl_TexCoord[ 1 ];\n\ +#else\n\ +varying mediump vec4 dgl_TexCoord[ 1 ];\n\ +#endif\n\ +varying float dgl_ClipDistance[ MAX_CLIP_PLANES ];\n\ +void main(void)\n\ +{\n\ + if ( 1 == dgl_ClippingEnabled ) {\n\ + for ( int i = 0; i < MAX_CLIP_PLANES; i++ ) {\n\ + if ( 1 == dgl_ClipEnabled[i] )\n\ + if ( dgl_ClipDistance[i] < 0.0 )\n\ + discard;\n\ + }\n\ + }\n\ + if ( 1 == dgl_TexActive )\n\ + gl_FragColor = dgl_Color * texture2D( textureUnit0, dgl_TexCoord[ 0 ].xy );\n\ + else\n\ + gl_FragColor = dgl_Color;\n\ +}"; + diff --git a/src/eepp/graphics/renderer/shaders/clipped.vert b/src/eepp/graphics/renderer/shaders/clipped.vert new file mode 100644 index 000000000..b01401bb3 --- /dev/null +++ b/src/eepp/graphics/renderer/shaders/clipped.vert @@ -0,0 +1,35 @@ +"#define MAX_CLIP_PLANES 6\n\ +#ifdef GL_ES\n\ +precision lowp float;\n\ +precision lowp int;\n\ +#else\n\ +#version 120\n\ +#endif\n\ +uniform mat4 dgl_ProjectionMatrix;\n\ +uniform mat4 dgl_ModelViewMatrix;\n\ +uniform int dgl_ClippingEnabled;\n\ +uniform int dgl_ClipEnabled[ MAX_CLIP_PLANES ];\n\ +uniform vec4 dgl_ClipPlane[ MAX_CLIP_PLANES ];\n\ +attribute vec4 dgl_Vertex;\n\ +attribute vec4 dgl_FrontColor;\n\ +attribute vec4 dgl_MultiTexCoord0;\n\ +varying vec4 dgl_Color;\n\ +#ifndef GL_ES\n\ +varying vec4 dgl_TexCoord[ 1 ];\n\ +#else\n\ +varying mediump vec4 dgl_TexCoord[ 1 ];\n\ +#endif\n\ +varying float dgl_ClipDistance[ MAX_CLIP_PLANES ];\n\ +void main(void)\n\ +{\n\ + dgl_Color = dgl_FrontColor;\n\ + dgl_TexCoord[0] = dgl_MultiTexCoord0;\n\ + vec4 vEye = dgl_ModelViewMatrix * dgl_Vertex;\n\ + gl_Position = dgl_ProjectionMatrix * vEye;\n\ + if ( 1 == dgl_ClippingEnabled ) {\n\ + for ( int i = 0; i < MAX_CLIP_PLANES; i++ ) {\n\ + if ( 1 == dgl_ClipEnabled[i] )\n\ + dgl_ClipDistance[i] = dot( vEye, dgl_ClipPlane[i] );\n\ + }\n\ + }\n\ +}"; diff --git a/src/eepp/graphics/renderer/shaders/pointsprite.frag b/src/eepp/graphics/renderer/shaders/pointsprite.frag new file mode 100644 index 000000000..8fd4af522 --- /dev/null +++ b/src/eepp/graphics/renderer/shaders/pointsprite.frag @@ -0,0 +1,13 @@ +"#define MAX_CLIP_PLANES 6\n\ +#ifdef GL_ES\n\ +precision lowp float;\n\ +precision lowp int;\n\ +#else\n\ +#version 120\n\ +#endif\n\ +uniform sampler2D textureUnit0;\n\ +varying vec4 dgl_Color;\n\ +void main(void)\n\ +{\n\ + gl_FragColor = dgl_Color * texture2D( textureUnit0, gl_PointCoord );\n\ +}"; diff --git a/src/eepp/graphics/renderer/shaders/pointsprite.vert b/src/eepp/graphics/renderer/shaders/pointsprite.vert new file mode 100644 index 000000000..bf1afe809 --- /dev/null +++ b/src/eepp/graphics/renderer/shaders/pointsprite.vert @@ -0,0 +1,20 @@ +"#define MAX_CLIP_PLANES 6\n\ +#ifdef GL_ES\n\ +precision lowp float;\n\ +precision lowp int;\n\ +#else\n\ +#version 120\n\ +#endif\n\ +uniform mat4 dgl_ProjectionMatrix;\n\ +uniform mat4 dgl_ModelViewMatrix;\n\ +uniform float dgl_PointSize;\n\ +attribute vec4 dgl_Vertex;\n\ +attribute vec4 dgl_FrontColor;\n\ +varying vec4 dgl_Color;\n\ +void main(void)\n\ +{\n\ + gl_PointSize = dgl_PointSize;\n\ + dgl_Color = dgl_FrontColor;\n\ + vec4 vEye = dgl_ModelViewMatrix * dgl_Vertex;\n\ + gl_Position = dgl_ProjectionMatrix * vEye;\n\ +}"; diff --git a/src/eepp/graphics/renderer/shaders/primitive.frag b/src/eepp/graphics/renderer/shaders/primitive.frag new file mode 100644 index 000000000..9bcde1e0c --- /dev/null +++ b/src/eepp/graphics/renderer/shaders/primitive.frag @@ -0,0 +1,12 @@ +"#define MAX_CLIP_PLANES 6\n\ +#ifdef GL_ES\n\ +precision lowp float;\n\ +precision lowp int;\n\ +#else\n\ +#version 120\n\ +#endif\n\ +varying vec4 dgl_Color;\n\ +void main(void)\n\ +{\n\ + gl_FragColor = dgl_Color;\n\ +}"; diff --git a/src/eepp/graphics/renderer/shaders/primitive.vert b/src/eepp/graphics/renderer/shaders/primitive.vert new file mode 100644 index 000000000..76336ba53 --- /dev/null +++ b/src/eepp/graphics/renderer/shaders/primitive.vert @@ -0,0 +1,18 @@ +"#define MAX_CLIP_PLANES 6\n\ +#ifdef GL_ES\n\ +precision lowp float;\n\ +precision lowp int;\n\ +#else\n\ +#version 120\n\ +#endif\n\ +uniform mat4 dgl_ProjectionMatrix;\n\ +uniform mat4 dgl_ModelViewMatrix;\n\ +attribute vec4 dgl_Vertex;\n\ +attribute vec4 dgl_FrontColor;\n\ +varying vec4 dgl_Color;\n\ +void main(void)\n\ +{\n\ + dgl_Color = dgl_FrontColor;\n\ + vec4 vEye = dgl_ModelViewMatrix * dgl_Vertex;\n\ + gl_Position = dgl_ProjectionMatrix * vEye;\n\ +}"; diff --git a/src/eepp/physics/cshape.cpp b/src/eepp/physics/cshape.cpp index d66694a06..86a11ffc2 100644 --- a/src/eepp/physics/cshape.cpp +++ b/src/eepp/physics/cshape.cpp @@ -186,4 +186,10 @@ void cShape::Data( void * data ) { mData = data; } +void cShape::Draw( cSpace * space ) { +} + +void cShape::DrawBorder( cSpace * space ) { +} + CP_NAMESPACE_END diff --git a/src/eepp/physics/cshapepoly.cpp b/src/eepp/physics/cshapepoly.cpp index ed5c68ffa..1ae47972a 100644 --- a/src/eepp/physics/cshapepoly.cpp +++ b/src/eepp/physics/cshapepoly.cpp @@ -80,7 +80,18 @@ void cShapePoly::Draw( cSpace * space ) { BR->DrawOpt(); } -#ifndef EE_GLES + + #endif +} + +void cShapePoly::DrawBorder( cSpace *space ) { +#ifdef PHYSICS_RENDERER_ENABLED + cpPolyShape * poly = (cpPolyShape*)mShape; + + cBatchRenderer * BR = cGlobalBatchRenderer::instance(); + + eeColorA Col = ColorForShape( (cpShape *)poly, space->Space() ); + BR->LineLoopBegin(); BR->LineLoopSetColor( Col ); @@ -88,10 +99,8 @@ void cShapePoly::Draw( cSpace * space ) { BR->BatchLineLoop( poly->CP_PRIVATE(tVerts)[i].x, poly->CP_PRIVATE(tVerts)[i].y ); } - BR->DrawOpt(); + BR->Draw(); #endif - - #endif } CP_NAMESPACE_END diff --git a/src/eepp/physics/cspace.cpp b/src/eepp/physics/cspace.cpp index a7e390c28..21326ecda 100644 --- a/src/eepp/physics/cspace.cpp +++ b/src/eepp/physics/cspace.cpp @@ -271,6 +271,10 @@ static void drawObject( cpShape * shape, cpSpace * space ) { reinterpret_cast ( shape->data )->Draw( reinterpret_cast( space->data ) ); } +static void drawObjectBorder( cpShape * shape, cpSpace * space ) { + reinterpret_cast ( shape->data )->DrawBorder( reinterpret_cast( space->data ) ); +} + static void drawBB( cpShape *shape, void * unused ) { reinterpret_cast ( shape->data )->DrawBB(); } @@ -298,6 +302,11 @@ void cSpace::Draw() { cpSpatialIndexEach( mSpace->CP_PRIVATE(staticShapes), (cpSpatialIndexIteratorFunc)drawObject, mSpace ); } + if ( options->DrawShapesBorders ) { + cpSpatialIndexEach( mSpace->CP_PRIVATE(activeShapes), (cpSpatialIndexIteratorFunc)drawObjectBorder, mSpace ); + cpSpatialIndexEach( mSpace->CP_PRIVATE(staticShapes), (cpSpatialIndexIteratorFunc)drawObjectBorder, mSpace ); + } + BR->SetLineWidth( lw ); if ( options->DrawBBs ){ diff --git a/src/eepp/window/cwindow.cpp b/src/eepp/window/cwindow.cpp index 064627a4b..e10a60ce2 100644 --- a/src/eepp/window/cwindow.cpp +++ b/src/eepp/window/cwindow.cpp @@ -114,9 +114,11 @@ void cWindow::Setup2D( const bool& KeepView ) { #endif } - GLi->EnableClientState( GL_VERTEX_ARRAY ); - GLi->EnableClientState( GL_TEXTURE_COORD_ARRAY ); - GLi->EnableClientState( GL_COLOR_ARRAY ); + if ( GLv_2 == GLi->Version() || GLv_ES1 == GLi->Version() ) { + GLi->EnableClientState( GL_VERTEX_ARRAY ); + GLi->EnableClientState( GL_TEXTURE_COORD_ARRAY ); + GLi->EnableClientState( GL_COLOR_ARRAY ); + } } const WindowInfo * cWindow::GetWindowInfo() const { @@ -323,7 +325,7 @@ void cWindow::SendVideoResizeCb() { } void cWindow::LogSuccessfulInit( const std::string& BackendName ) { - cLog::instance()->Write( "Engine Initialized Succesfully.\n\tOS: " + GetOSName() + "\n\tArch: " + GetOSArchitecture() + " \n\tWindow/Input Backend: " + BackendName + "\n\tGL Backend: " + GLi->VersionStr() + "\n\tGL Vendor: " + GLi->GetVendor() + "\n\tGL Renderer: " + GLi->GetRenderer() + "\n\tGL Version: " + GLi->GetVersion() + "\n\tGL Shading Language Version: " + GLi->GetShadingLanguageVersion() + "\n\tResolution: " + toStr( GetWidth() ) + "x" + toStr( GetHeight() ) ); + cLog::instance()->Write( "Engine Initialized Succesfully.\n\tOS: " + GetOSName() + "\n\tArch: " + GetOSArchitecture() + " \n\tWindow/Input Backend: " + BackendName + "\n\tGL Backend: " + GLi->VersionStr() + "\n\tGL Vendor: " + GLi->GetVendor() + "\n\tGL Renderer: " + GLi->GetRenderer() + "\n\tGL Version: " + GLi->GetVersion() + "\n\tGL Shading Language Version: " + GLi->GetShadingLanguageVersion() + "\n\tResolution: " + toStr( GetWidth() ) + "x" + toStr( GetHeight() ) + "\n\tGL extensions supported:\n" + GLi->GetExtensions() ); } void cWindow::LogFailureInit( const std::string& ClassName, const std::string& BackendName ) { diff --git a/src/test/eetest.cpp b/src/test/eetest.cpp index 582473d00..8a1c57b45 100644 --- a/src/test/eetest.cpp +++ b/src/test/eetest.cpp @@ -29,6 +29,7 @@ void cEETest::Init() { mMapEditor = NULL; mETGEditor = NULL; Mus = NULL; + mUIWindow = NULL; MyPath = GetProcessPath(); @@ -51,6 +52,8 @@ void cEETest::Init() { if ( 3 == GLVersion ) GLVer = GLv_3; + else if ( 4 == GLVersion ) + GLVer = GLv_ES2; else GLVer = GLv_2; @@ -811,8 +814,13 @@ void cEETest::LoadTextures() { cTextureGroupLoader tgl( PAK, "tiles.etg" ); cShapeGroup * SG = cShapeGroupManager::instance()->GetByName( "tiles" ); + Uint32 ORTO = TF->Load( MyPath + "data/tilesortogonal.png" ); + + Graphics::cShape * OrtoShape = cGlobalShapeGroup::instance()->Add( ORTO ); + for ( i = 0; i < 6; i++ ) { - Tiles[i] = SG->GetByName( toStr( i+1 ) ); + //Tiles[i] = SG->GetByName( toStr( i+1 ) ); + Tiles[i] = OrtoShape; } Tiles[6] = SG->Add( TF->LoadFromPack( PAK, "objects/1.png" ), "7" );