diff --git a/binaries/data/mods/public/shaders/particle.xml b/binaries/data/mods/public/shaders/particle.xml index 8ea627d905..2929ed9061 100644 --- a/binaries/data/mods/public/shaders/particle.xml +++ b/binaries/data/mods/public/shaders/particle.xml @@ -1,7 +1,12 @@ - + + + + + + diff --git a/binaries/data/mods/public/shaders/particle_solid.xml b/binaries/data/mods/public/shaders/particle_solid.xml index 58758dc06b..bab6a8d5ec 100644 --- a/binaries/data/mods/public/shaders/particle_solid.xml +++ b/binaries/data/mods/public/shaders/particle_solid.xml @@ -1,7 +1,11 @@ - + + + + + diff --git a/source/graphics/ParticleEmitter.cpp b/source/graphics/ParticleEmitter.cpp index 908daf984d..034d683643 100644 --- a/source/graphics/ParticleEmitter.cpp +++ b/source/graphics/ParticleEmitter.cpp @@ -153,7 +153,7 @@ void CParticleEmitter::Bind() glBlendFunc(m_Type->m_BlendFuncSrc, m_Type->m_BlendFuncDst); } -void CParticleEmitter::RenderArray() +void CParticleEmitter::RenderArray(CShaderProgramPtr& shader) { // Some drivers apparently don't like count=0 in glDrawArrays here, // so skip all drawing in that case @@ -164,19 +164,21 @@ void CParticleEmitter::RenderArray() GLsizei stride = (GLsizei)m_VertexArray.GetStride(); - glVertexPointer(3, GL_FLOAT, stride, base + m_AttributePos.offset); + shader->VertexPointer(3, GL_FLOAT, stride, base + m_AttributePos.offset); // Pass the sin/cos axis components as texcoords for no particular reason // other than that they fit. (Maybe this should be glVertexAttrib* instead?) - pglClientActiveTextureARB(GL_TEXTURE1); - glTexCoordPointer(2, GL_FLOAT, stride, base + m_AttributeAxis.offset); + shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, base + m_AttributeUV.offset); + shader->TexCoordPointer(GL_TEXTURE1, 2, GL_FLOAT, stride, base + m_AttributeAxis.offset); - pglClientActiveTextureARB(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, stride, base + m_AttributeUV.offset); - - glColorPointer(4, GL_UNSIGNED_BYTE, stride, base + m_AttributeColor.offset); + shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, base + m_AttributeColor.offset); + shader->AssertPointersBound(); +#if CONFIG2_GLES +#warning TODO: change CParticleEmitter to use (indexed?) triangles instead of quads, for GLES +#else glDrawArrays(GL_QUADS, 0, m_Particles.size()*4); +#endif g_Renderer.GetStats().m_DrawCalls++; g_Renderer.GetStats().m_Particles += m_Particles.size(); diff --git a/source/graphics/ParticleEmitter.h b/source/graphics/ParticleEmitter.h index f55121c01a..295ab155da 100644 --- a/source/graphics/ParticleEmitter.h +++ b/source/graphics/ParticleEmitter.h @@ -103,7 +103,7 @@ public: /** * Draw the vertex array. */ - void RenderArray(); + void RenderArray(CShaderProgramPtr& shader); /** * Stop this emitter emitting new particles, and pass responsibility for rendering diff --git a/source/graphics/ShaderProgram.cpp b/source/graphics/ShaderProgram.cpp index 7463d0113a..716589109d 100644 --- a/source/graphics/ShaderProgram.cpp +++ b/source/graphics/ShaderProgram.cpp @@ -687,7 +687,30 @@ CStr CShaderProgram::Preprocess(CPreprocessor& preprocessor, const CStr& input) return ret; } -#if !CONFIG2_GLES +#if CONFIG2_GLES + +// These should all be overridden by CShaderProgramGLSL +void CShaderProgram::VertexPointer(GLint UNUSED(size), GLenum UNUSED(type), GLsizei UNUSED(stride), void* UNUSED(pointer)) +{ + debug_warn("CShaderProgram::VertexPointer should be overridden"); +} +void CShaderProgram::NormalPointer(GLenum UNUSED(type), GLsizei UNUSED(stride), void* UNUSED(pointer)) +{ + debug_warn("CShaderProgram::NormalPointer should be overridden"); +} +void CShaderProgram::ColorPointer(GLint UNUSED(size), GLenum UNUSED(type), GLsizei UNUSED(stride), void* UNUSED(pointer)) +{ + debug_warn("CShaderProgram::ColorPointer should be overridden"); +} +void CShaderProgram::TexCoordPointer(GLenum UNUSED(texture), GLint UNUSED(size), GLenum UNUSED(type), GLsizei UNUSED(stride), void* UNUSED(pointer)) +{ + debug_warn("CShaderProgram::TexCoordPointer should be overridden"); +} + +#else + +// These are overridden by CShaderProgramGLSL, but fixed-function and ARB shaders +// both use the fixed-function vertex attribute pointers: void CShaderProgram::VertexPointer(GLint size, GLenum type, GLsizei stride, void* pointer) { diff --git a/source/lib/external_libraries/glext_funcs.h b/source/lib/external_libraries/glext_funcs.h index a7f03c2316..c9ab586315 100644 --- a/source/lib/external_libraries/glext_funcs.h +++ b/source/lib/external_libraries/glext_funcs.h @@ -106,6 +106,17 @@ actually supported). #define pglDeleteBuffersARB glDeleteBuffers #define pglGenBuffersARB glGenBuffers +#define pglBindFramebufferEXT glBindFramebuffer +#define pglCheckFramebufferStatusEXT glCheckFramebufferStatus +#define pglDeleteFramebuffersEXT glDeleteFramebuffers +#define pglFramebufferTexture2DEXT glFramebufferTexture2D +#define pglGenFramebuffersEXT glGenFramebuffers + +#define GL_DEPTH_ATTACHMENT_EXT GL_DEPTH_ATTACHMENT +#define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0 +#define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE +#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER + #define GL_CLAMP_TO_BORDER GL_CLAMP_TO_EDGE // TODO: should fix code that relies on GL_CLAMP_TO_BORDER typedef GLuint GLhandleARB; diff --git a/source/renderer/FixedFunctionModelRenderer.cpp b/source/renderer/FixedFunctionModelRenderer.cpp index 5354d1519e..a575709842 100644 --- a/source/renderer/FixedFunctionModelRenderer.cpp +++ b/source/renderer/FixedFunctionModelRenderer.cpp @@ -38,6 +38,7 @@ #include "renderer/RenderModifiers.h" #include "renderer/VertexArray.h" +#if !CONFIG2_GLES /////////////////////////////////////////////////////////////////////////////////////////////// // FixedFunctionModelRenderer implementation @@ -283,3 +284,5 @@ void FixedFunctionModelRenderer::RenderModel(CShaderProgramPtr& UNUSED(shader), g_Renderer.m_Stats.m_DrawCalls++; g_Renderer.m_Stats.m_ModelTris += numFaces; } + +#endif // !CONFIG2_GLES diff --git a/source/renderer/FixedFunctionModelRenderer.h b/source/renderer/FixedFunctionModelRenderer.h index d9952c9aa6..919b9e5533 100644 --- a/source/renderer/FixedFunctionModelRenderer.h +++ b/source/renderer/FixedFunctionModelRenderer.h @@ -25,6 +25,8 @@ #include "renderer/ModelVertexRenderer.h" +#if !CONFIG2_GLES + struct FixedFunctionModelRendererInternals; /** @@ -51,5 +53,6 @@ private: FixedFunctionModelRendererInternals* m; }; +#endif // !CONFIG2_GLES #endif // INCLUDED_FIXEDFUNCTIONMODELRENDERER diff --git a/source/renderer/HWLightingModelRenderer.cpp b/source/renderer/HWLightingModelRenderer.cpp index dc9aeab5c9..df0bfa5383 100644 --- a/source/renderer/HWLightingModelRenderer.cpp +++ b/source/renderer/HWLightingModelRenderer.cpp @@ -177,29 +177,11 @@ void ShaderModelRenderer::DestroyModelData(CModel* UNUSED(model), void* data) void ShaderModelRenderer::BeginPass(int streamflags) { ENSURE(streamflags == (streamflags & (STREAM_POS|STREAM_NORMAL|STREAM_UV0))); - - if (streamflags & STREAM_POS) - glEnableClientState(GL_VERTEX_ARRAY); - - if (streamflags & STREAM_NORMAL) - glEnableClientState(GL_NORMAL_ARRAY); - - if (streamflags & STREAM_UV0) - glEnableClientState(GL_TEXTURE_COORD_ARRAY); } // Cleanup one rendering pass void ShaderModelRenderer::EndPass(int streamflags) { - if (streamflags & STREAM_POS) - glDisableClientState(GL_VERTEX_ARRAY); - - if (streamflags & STREAM_NORMAL) - glDisableClientState(GL_NORMAL_ARRAY); - - if (streamflags & STREAM_UV0) - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - CVertexBuffer::Unbind(); } @@ -245,8 +227,13 @@ void ShaderModelRenderer::RenderModel(CShaderProgramPtr& shader, int streamflags if (!g_Renderer.m_SkipSubmit) { + // Draw with DrawRangeElements where available, since it might be more efficient +#if CONFIG2_GLES + glDrawElements(GL_TRIANGLES, (GLsizei)numFaces*3, GL_UNSIGNED_SHORT, indexBase); +#else pglDrawRangeElementsEXT(GL_TRIANGLES, 0, (GLuint)mdldef->GetNumVertices()-1, - (GLsizei)numFaces*3, GL_UNSIGNED_SHORT, indexBase); + (GLsizei)numFaces*3, GL_UNSIGNED_SHORT, indexBase); +#endif } // bump stats diff --git a/source/renderer/InstancingModelRenderer.cpp b/source/renderer/InstancingModelRenderer.cpp index 945b7fcffb..3a681ae79f 100644 --- a/source/renderer/InstancingModelRenderer.cpp +++ b/source/renderer/InstancingModelRenderer.cpp @@ -198,8 +198,13 @@ void InstancingModelRenderer::RenderModel(CShaderProgramPtr& UNUSED(shader), int if (!g_Renderer.m_SkipSubmit) { + // Draw with DrawRangeElements where available, since it might be more efficient +#if CONFIG2_GLES + glDrawElements(GL_TRIANGLES, (GLsizei)numFaces*3, GL_UNSIGNED_SHORT, m->imodeldefIndexBase); +#else pglDrawRangeElementsEXT(GL_TRIANGLES, 0, (GLuint)mdldef->GetNumVertices()-1, (GLsizei)numFaces*3, GL_UNSIGNED_SHORT, m->imodeldefIndexBase); +#endif } // bump stats diff --git a/source/renderer/OverlayRenderer.cpp b/source/renderer/OverlayRenderer.cpp index e4b6409891..bdccc14940 100644 --- a/source/renderer/OverlayRenderer.cpp +++ b/source/renderer/OverlayRenderer.cpp @@ -163,6 +163,9 @@ void OverlayRenderer::RenderOverlaysBeforeWater() { PROFILE3_GPU("overlays (before)"); +#if CONFIG2_GLES +#warning TODO: implement OverlayRenderer::RenderOverlaysBeforeWater for GLES +#else pglActiveTextureARB(GL_TEXTURE0); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); @@ -186,6 +189,7 @@ void OverlayRenderer::RenderOverlaysBeforeWater() glLineWidth(1.f); glDisable(GL_BLEND); +#endif } void OverlayRenderer::RenderOverlaysAfterWater() @@ -242,11 +246,6 @@ void OverlayRenderer::RenderOverlaysAfterWater() g_Renderer.BindTexture(0, 0); CVertexBuffer::Unbind(); - glDisableClientState(GL_VERTEX_ARRAY); - pglClientActiveTextureARB(GL_TEXTURE1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglClientActiveTextureARB(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDepthMask(1); glDisable(GL_BLEND); @@ -300,6 +299,9 @@ void OverlayRenderer::RenderForegroundOverlays(const CCamera& viewCamera) { PROFILE3_GPU("overlays (fg)"); +#if CONFIG2_GLES +#warning TODO: implement OverlayRenderer::RenderForegroundOverlays for GLES +#else glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); @@ -338,6 +340,7 @@ void OverlayRenderer::RenderForegroundOverlays(const CCamera& viewCamera) glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); +#endif } void CTexturedLineRData::Update() diff --git a/source/renderer/ParticleRenderer.cpp b/source/renderer/ParticleRenderer.cpp index b23e6db842..09ae6f8350 100644 --- a/source/renderer/ParticleRenderer.cpp +++ b/source/renderer/ParticleRenderer.cpp @@ -121,21 +121,12 @@ void ParticleRenderer::RenderParticles(bool solidColor) glEnable(GL_BLEND); glDepthMask(0); - glEnableClientState(GL_VERTEX_ARRAY); - if (!solidColor) - glEnableClientState(GL_COLOR_ARRAY); - - pglClientActiveTextureARB(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - pglClientActiveTextureARB(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - for (size_t i = 0; i < m->emitters.size(); ++i) { CParticleEmitter* emitter = m->emitters[i]; emitter->Bind(); - emitter->RenderArray(); + emitter->RenderArray(shader); } CVertexBuffer::Unbind(); @@ -143,14 +134,6 @@ void ParticleRenderer::RenderParticles(bool solidColor) pglBlendEquationEXT(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - pglClientActiveTextureARB(GL_TEXTURE1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglClientActiveTextureARB(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisable(GL_BLEND); glDepthMask(1); diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 505cfde8b7..9ae326761f 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -375,7 +375,7 @@ public: const CMatrix3D& proj = camera.GetProjection(); #if CONFIG2_GLES -#warning TODO: fix CRenderer camera handling for GLES (don't use global matrixes) +#warning TODO: fix CRenderer camera handling for GLES (do not use global matrixes) #else glMatrixMode(GL_PROJECTION); glLoadMatrixf(&proj._11); diff --git a/source/renderer/ShadowMap.cpp b/source/renderer/ShadowMap.cpp index 4379d58233..a977c0fb60 100644 --- a/source/renderer/ShadowMap.cpp +++ b/source/renderer/ShadowMap.cpp @@ -351,7 +351,7 @@ void ShadowMapInternals::CreateTexture() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } glGenTextures(1, &Texture); @@ -362,22 +362,28 @@ void ShadowMapInternals::CreateTexture() switch(DepthTextureBits) { case 16: format = GL_DEPTH_COMPONENT16; break; +#if !CONFIG2_GLES case 24: format = GL_DEPTH_COMPONENT24; break; case 32: format = GL_DEPTH_COMPONENT32; break; +#endif default: format = GL_DEPTH_COMPONENT; break; } glTexImage2D(GL_TEXTURE_2D, 0, format, Width, Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); +#if CONFIG2_GLES +#warning TODO: implement shadows with non-depth textures and explicit comparisons in the GLSL +#else glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); +#endif // set texture parameters - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // bind to framebuffer object glBindTexture(GL_TEXTURE_2D, 0); @@ -391,10 +397,16 @@ void ShadowMapInternals::CreateTexture() } else { +#if CONFIG2_GLES +#warning TODO: figure out whether the glDrawBuffer/glReadBuffer stuff is needed, since it is not supported by GLES +#else glDrawBuffer(GL_NONE); +#endif } +#if !CONFIG2_GLES glReadBuffer(GL_NONE); +#endif GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); @@ -447,6 +459,9 @@ void ShadowMap::BeginRender() // setup viewport glViewport(0, 0, m->EffectiveWidth, m->EffectiveHeight); +#if CONFIG2_GLES +#warning TODO: implement ShdaowMap::BeginRender GLES +#else glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadMatrixf(&m->LightProjection._11); @@ -454,6 +469,7 @@ void ShadowMap::BeginRender() glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadMatrixf(&m->LightTransform._11); +#endif glEnable(GL_SCISSOR_TEST); glScissor(1,1, m->EffectiveWidth-2, m->EffectiveHeight-2); @@ -475,11 +491,13 @@ void ShadowMap::EndRender() glColorMask(1,1,1,1); +#if !CONFIG2_GLES // restore matrix stack glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); +#endif } @@ -600,6 +618,9 @@ void ShadowMap::RenderDebugDisplay() #endif // Render the shadow map +#if CONFIG2_GLES +#warning TODO: implement ShadowMap::RenderDebugDisplay for GLES +#else glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); @@ -626,6 +647,7 @@ void ShadowMap::RenderDebugDisplay() glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); +#endif glEnable(GL_DEPTH_TEST); glDepthMask(1);