Even more GLES compatibility

This was SVN commit r11060.
This commit is contained in:
Ykkrosh 2012-02-13 15:06:25 +00:00
parent 4bf59b9a7d
commit a9eca31bad
13 changed files with 98 additions and 118 deletions

View File

@ -44,6 +44,7 @@ class CCamera
// Methods for projection
void SetProjection(float nearp, float farp, float fov);
void SetProjection(const CMatrix3D& matrix) { m_ProjMat = matrix; }
void SetProjectionTile(int tiles, int tile_x, int tile_y);
CMatrix3D& GetProjection() { return m_ProjMat; }
const CMatrix3D& GetProjection() const { return m_ProjMat; }

View File

@ -29,11 +29,15 @@ void CShaderPass::Bind()
{
m_Shader->Bind();
#if !CONFIG2_GLES
if (m_HasAlpha)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(m_AlphaFunc, m_AlphaRef);
}
#endif
// TODO: maybe emit some warning if GLSL shaders try to use alpha test;
// the test should be done inside the shader itself
if (m_HasBlend)
{
@ -55,15 +59,13 @@ void CShaderPass::Unbind()
{
m_Shader->Unbind();
#if !CONFIG2_GLES
if (m_HasAlpha)
{
glDisable(GL_ALPHA_TEST);
}
#endif
if (m_HasBlend)
{
glDisable(GL_BLEND);
}
if (m_HasColorMask)
glColorMask(1, 1, 1, 1);

View File

@ -70,6 +70,7 @@ actually supported).
// some functions that are extensions in GL are core functions in GLES,
// so we should use them without the function pointer indirection
#define pglActiveTextureARB glActiveTexture
#define pglBlendColorEXT glBlendColor
#define pglBlendEquationEXT glBlendEquation
#define pglClientActiveTextureARB glClientActiveTexture
#define pglCompressedTexImage2DARB glCompressedTexImage2D

View File

@ -88,7 +88,11 @@ public:
return _data[row*4+col];
}
float operator[](int idx) const
float& operator[](int idx)
{
return _data[idx];
}
const float& operator[](int idx) const
{
return _data[idx];
}

View File

@ -163,6 +163,7 @@ void OverlayRenderer::RenderOverlaysBeforeWater()
{
PROFILE3_GPU("overlays (before)");
pglActiveTextureARB(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glEnable(GL_BLEND);

View File

@ -30,6 +30,7 @@
#include "graphics/TextureManager.h"
#if !CONFIG2_GLES
///////////////////////////////////////////////////////////////////////////////////////////////////
// FastPlayerColorRender
@ -289,3 +290,5 @@ void SolidPlayerColorRender::PrepareModel(int UNUSED(pass), CModel* model)
// Send the player color
glColor3f(colour.r, colour.g, colour.b);
}
#endif // !CONFIG2_GLES

View File

@ -25,6 +25,7 @@
#include "RenderModifiers.h"
#if !CONFIG2_GLES
/**
* Class FastPlayerColorRender: Render models fully textured and lit
@ -94,5 +95,6 @@ public:
void PrepareModel(int pass, CModel* model);
};
#endif // !CONFIG2_GLES
#endif

View File

@ -77,6 +77,8 @@ void LitRenderModifier::SetLightEnv(const CLightEnv* lightenv)
}
#if !CONFIG2_GLES
///////////////////////////////////////////////////////////////////////////////////////////////
// PlainRenderModifier implementation
@ -130,62 +132,6 @@ void PlainRenderModifier::PrepareTexture(int UNUSED(pass), CTexturePtr& texture)
}
///////////////////////////////////////////////////////////////////////////////////////////////
// WireframeRenderModifier implementation
WireframeRenderModifier::WireframeRenderModifier()
{
}
WireframeRenderModifier::~WireframeRenderModifier()
{
}
int WireframeRenderModifier::BeginPass(int pass)
{
ENSURE(pass == 0);
// first switch on wireframe
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// setup some renderstate ..
glDepthMask(0);
ogl_tex_bind(0, 0);
glColor4f(1,1,1,0.75f);
glLineWidth(1.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
return STREAM_POS;
}
bool WireframeRenderModifier::EndPass(int UNUSED(pass))
{
// .. restore the renderstates
glDisable(GL_BLEND);
glDepthMask(1);
// restore fill mode, and we're done
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
return true;
}
void WireframeRenderModifier::PrepareTexture(int UNUSED(pass), CTexturePtr& UNUSED(texture))
{
}
void WireframeRenderModifier::PrepareModel(int UNUSED(pass), CModel* UNUSED(model))
{
}
///////////////////////////////////////////////////////////////////////////////////////////////
// SolidColorRenderModifier implementation
@ -217,6 +163,7 @@ void SolidColorRenderModifier::PrepareModel(int UNUSED(pass), CModel* UNUSED(mod
{
}
#endif // !CONFIG2_GLES
///////////////////////////////////////////////////////////////////////////////////////////////
// ShaderRenderModifier implementation

View File

@ -139,6 +139,8 @@ private:
};
#if !CONFIG2_GLES
/**
* Class PlainRenderModifier: RenderModifier that simply uses opaque textures
* modulated by primary color. It is used for normal, no-frills models.
@ -156,23 +158,6 @@ public:
};
/**
* Class WireframeRenderModifier: RenderModifier that renders wireframe models.
*/
class WireframeRenderModifier : public RenderModifier
{
public:
WireframeRenderModifier();
~WireframeRenderModifier();
// Implementation
int BeginPass(int pass);
bool EndPass(int pass);
void PrepareTexture(int pass, CTexturePtr& texture);
void PrepareModel(int pass, CModel* model);
};
/**
* Class SolidColorRenderModifier: Render all models using the same
* solid color without lighting.
@ -192,6 +177,8 @@ public:
void PrepareModel(int pass, CModel* model);
};
#endif // !CONFIG2_GLES
/**
* A RenderModifier that can be used with any CShaderTechnique.
* Uniforms and textures get set appropriately.

View File

@ -294,7 +294,6 @@ public:
ModelVertexRendererPtr VertexInstancingShader;
// generic RenderModifiers that are supposed to be used directly
RenderModifierPtr ModWireframe;
RenderModifierPtr ModSolidColor;
RenderModifierPtr ModSolidPlayerColor;
RenderModifierPtr ModTransparentDepthShadow;
@ -375,11 +374,15 @@ public:
camera.m_Orientation.GetInverse(view);
const CMatrix3D& proj = camera.GetProjection();
#if CONFIG2_GLES
#warning TODO: fix CRenderer camera handling for GLES (don't use global matrixes)
#else
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(&proj._11);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&view._11);
#endif
const SViewPort &vp = camera.GetViewPort();
glViewport((GLint)vp.m_X,(GLint)vp.m_Y,(GLsizei)vp.m_Width,(GLsizei)vp.m_Height);
@ -647,13 +650,12 @@ bool CRenderer::Open(int width, int height)
m->Model.pal_PlayerInstancingShader = new BatchModelRenderer(m->Model.VertexInstancingShader);
m->Model.pal_TranspShader = new SortModelRenderer(m->Model.VertexRendererShader);
m->Model.ModWireframe = RenderModifierPtr(new WireframeRenderModifier);
#if !CONFIG2_GLES
m->Model.ModPlainUnlit = RenderModifierPtr(new PlainRenderModifier);
SetFastPlayerColor(true);
m->Model.ModSolidColor = RenderModifierPtr(new SolidColorRenderModifier);
m->Model.ModSolidPlayerColor = RenderModifierPtr(new SolidPlayerColorRender);
m->Model.ModTransparentUnlit = RenderModifierPtr(new TransparentRenderModifier);
#if !CONFIG2_GLES
m->Model.ModTransparentOpaqueUnlit = RenderModifierPtr(new TransparentOpaqueRenderModifier);
m->Model.ModTransparentBlendUnlit = RenderModifierPtr(new TransparentBlendRenderModifier);
m->Model.ModTransparentDepthShadow = RenderModifierPtr(new TransparentDepthShadowModifier);
@ -823,6 +825,7 @@ CRenderer::RenderPath CRenderer::GetRenderPathByName(const CStr& name)
// SetFastPlayerColor
void CRenderer::SetFastPlayerColor(bool fast)
{
#if !CONFIG2_GLES
m_FastPlayerColor = fast;
if (m_FastPlayerColor)
@ -838,6 +841,7 @@ void CRenderer::SetFastPlayerColor(bool fast)
m->Model.ModPlayerUnlit = RenderModifierPtr(new FastPlayerColorRender);
else
m->Model.ModPlayerUnlit = RenderModifierPtr(new SlowPlayerColorRender);
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -941,8 +945,12 @@ void CRenderer::RenderShadowMap()
m->shadow->BeginRender();
#if CONFIG2_GLES
#warning TODO: implement shadow transparency for GLES
#else
float shadowTransp = m_LightEnv->GetTerrainShadowTransparency();
glColor3f(shadowTransp, shadowTransp, shadowTransp);
#endif
{
PROFILE("render patches");
@ -963,7 +971,9 @@ void CRenderer::RenderShadowMap()
glEnable(GL_CULL_FACE);
}
#if !CONFIG2_GLES
glColor3f(1.0, 1.0, 1.0);
#endif
m->shadow->EndRender();
}
@ -981,11 +991,15 @@ void CRenderer::RenderPatches(const CFrustum* frustum)
filtered = true;
}
#if CONFIG2_GLES
#warning TODO: implement wireface/edged rendering mode GLES
#else
// switch on wireframe if we need it
if (m_TerrainRenderMode == WIREFRAME)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
#endif
// render all the patches, including blend pass
if (GetRenderPath() == RP_SHADER)
@ -994,6 +1008,7 @@ void CRenderer::RenderPatches(const CFrustum* frustum)
m->terrainRenderer->RenderTerrain(filtered);
#if !CONFIG2_GLES
if (m_TerrainRenderMode == WIREFRAME)
{
// switch wireframe off again
@ -1025,6 +1040,7 @@ void CRenderer::RenderPatches(const CFrustum* frustum)
glLineWidth(1.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
#endif
}
class CModelCuller : public CModelFilter
@ -1053,14 +1069,17 @@ void CRenderer::RenderModels(const CFrustum* frustum)
m->FilterModels(culler, flags);
}
#if !CONFIG2_GLES
if (m_ModelRenderMode == WIREFRAME)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
#endif
m->CallModelRenderers(m->Model.ModNormal, m->Model.ModNormalInstancing,
m->Model.ModPlayer, m->Model.ModPlayerInstancing, flags);
#if !CONFIG2_GLES
if (m_ModelRenderMode == WIREFRAME)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@ -1076,6 +1095,7 @@ void CRenderer::RenderModels(const CFrustum* frustum)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
#endif
}
void CRenderer::RenderTransparentModels(ETransparentMode transparentMode, const CFrustum* frustum)
@ -1090,11 +1110,13 @@ void CRenderer::RenderTransparentModels(ETransparentMode transparentMode, const
m->Model.Transp->Filter(culler, flags);
}
#if !CONFIG2_GLES
// switch on wireframe if we need it
if (m_ModelRenderMode == WIREFRAME)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
#endif
// disable face culling for two-sided models in sub-renders
if (flags)
@ -1110,6 +1132,7 @@ void CRenderer::RenderTransparentModels(ETransparentMode transparentMode, const
if (flags)
glEnable(GL_CULL_FACE);
#if !CONFIG2_GLES
if (m_ModelRenderMode == WIREFRAME)
{
// switch wireframe off again
@ -1125,49 +1148,29 @@ void CRenderer::RenderTransparentModels(ETransparentMode transparentMode, const
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
#endif
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// GetModelViewProjectionMatrix: save the current OpenGL model-view-projection matrix
CMatrix3D CRenderer::GetModelViewProjectionMatrix()
{
CMatrix3D proj;
CMatrix3D view;
glGetFloatv(GL_PROJECTION_MATRIX, &proj._11);
glGetFloatv(GL_MODELVIEW_MATRIX, &view._11);
return proj*view;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// SetObliqueFrustumClipping: change the near plane to the given clip plane (in world space)
// Based on code from Game Programming Gems 5, from http://www.terathon.com/code/oblique.html
// - worldPlane is a clip plane in world space (worldPlane.Dot(v) >= 0 for any vector v passing the clipping test)
void CRenderer::SetObliqueFrustumClipping(const CVector4D& worldPlane)
{
float matrix[16];
CVector4D q;
// First, we'll convert the given clip plane to camera space, then we'll
// Get the view matrix and normal matrix (top 3x3 part of view matrix)
CMatrix3D normalMatrix = m_ViewCamera.m_Orientation.GetTranspose();
CVector4D camPlane = normalMatrix.Transform(worldPlane);
// Grab the current projection matrix from OpenGL
{
PROFILE3("get proj matrix (oblique clipping)"); // sometimes the vsync delay gets accounted here
glGetFloatv(GL_PROJECTION_MATRIX, matrix);
}
CMatrix3D matrix = m_ViewCamera.GetProjection();
// Calculate the clip-space corner point opposite the clipping plane
// as (sgn(camPlane.x), sgn(camPlane.y), 1, 1) and
// transform it into camera space by multiplying it
// by the inverse of the projection matrix
CVector4D q;
q.m_X = (sgn(camPlane.m_X) - matrix[8]/matrix[11]) / matrix[0];
q.m_Y = (sgn(camPlane.m_Y) - matrix[9]/matrix[11]) / matrix[5];
q.m_Z = 1.0f/matrix[11];
@ -1182,11 +1185,9 @@ void CRenderer::SetObliqueFrustumClipping(const CVector4D& worldPlane)
matrix[10] = c.m_Z - matrix[11];
matrix[14] = c.m_W;
// Load it back into OpenGL
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(matrix);
glMatrixMode(GL_MODELVIEW);
// Load it back into the camera
m_ViewCamera.SetProjection(matrix);
m->SetOpenGLCamera(m_ViewCamera);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -1227,7 +1228,7 @@ SScreenRect CRenderer::RenderReflections(const CBoundingBoxAligned& scissor)
SetObliqueFrustumClipping(camPlane);
// Save the model-view-projection matrix so the shaders can use it for projective texturing
wm.m_ReflectionMatrix = GetModelViewProjectionMatrix();
wm.m_ReflectionMatrix = m_ViewCamera.GetViewProjection();
SScreenRect screenScissor;
screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vp.m_Width);
@ -1259,7 +1260,7 @@ SScreenRect CRenderer::RenderReflections(const CBoundingBoxAligned& scissor)
glDisable(GL_SCISSOR_TEST);
// Copy the image to a texture
pglActiveTextureARB(GL_TEXTURE0_ARB);
pglActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
@ -1311,7 +1312,7 @@ SScreenRect CRenderer::RenderRefractions(const CBoundingBoxAligned &scissor)
SetObliqueFrustumClipping(camPlane);
// Save the model-view-projection matrix so the shaders can use it for projective texturing
wm.m_RefractionMatrix = GetModelViewProjectionMatrix();
wm.m_RefractionMatrix = m_ViewCamera.GetViewProjection();
SScreenRect screenScissor;
screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vp.m_Width);
@ -1337,7 +1338,7 @@ SScreenRect CRenderer::RenderRefractions(const CBoundingBoxAligned &scissor)
glDisable(GL_SCISSOR_TEST);
// Copy the image to a texture
pglActiveTextureARB(GL_TEXTURE0_ARB);
pglActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
@ -1399,10 +1400,14 @@ void CRenderer::RenderSilhouettes()
PROFILE("render transparent occluders");
if (GetRenderPath() == RP_SHADER)
{
#if CONFIG2_GLES
#warning TODO: implement occluder alpha testing for GLES
#else
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.4f);
m->Model.Transp->Render(m->Model.ModShaderSolidTex, MODELFLAG_SILHOUETTE_OCCLUDER);
glDisable(GL_ALPHA_TEST);
#endif
}
else
{
@ -1473,6 +1478,7 @@ void CRenderer::RenderParticles()
m->particleRenderer.RenderParticles();
#if !CONFIG2_GLES
if (m_ModelRenderMode == EDGED_FACES)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@ -1494,6 +1500,7 @@ void CRenderer::RenderParticles()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
#endif
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -1616,9 +1623,11 @@ void CRenderer::RenderSubmissions()
RenderSilhouettes();
#if !CONFIG2_GLES
// Clean up texture blend mode so particles and other things render OK
// (really this should be cleaned up by whoever set it)
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
#endif
// render debug lines
if (m_DisplayFrustum)
@ -1671,6 +1680,9 @@ void CRenderer::EndFrame()
// - red: bounds of shadow casting objects
void CRenderer::DisplayFrustum()
{
#if CONFIG2_GLES
#warning TODO: implement CRenderer::DisplayFrustum for GLES
#else
glDepthMask(0);
glDisable(GL_CULL_FACE);
glDisable(GL_TEXTURE_2D);
@ -1688,6 +1700,7 @@ void CRenderer::DisplayFrustum()
glEnable(GL_CULL_FACE);
glDepthMask(1);
#endif
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -1947,7 +1960,7 @@ int CRenderer::LoadAlphaMaps()
m_hCompositeAlphaMap = ogl_tex_wrap(&t, g_VFS, key);
(void)ogl_tex_set_filter(m_hCompositeAlphaMap, GL_LINEAR);
(void)ogl_tex_set_wrap (m_hCompositeAlphaMap, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
int ret = ogl_tex_upload(m_hCompositeAlphaMap, 0, 0, GL_INTENSITY);
int ret = ogl_tex_upload(m_hCompositeAlphaMap, GL_ALPHA, 0, 0);
return ret;
}

View File

@ -242,9 +242,6 @@ public:
// return the current cull camera
const CCamera& GetCullCamera() const { return m_CullCamera; }
// get the current OpenGL model-view-projection matrix into the given float[]
CMatrix3D GetModelViewProjectionMatrix();
/**
* GetWaterManager: Return the renderer's water manager.
*

View File

@ -124,6 +124,10 @@ std::vector<CStrW> SkyManager::GetSkySets() const
// Render sky
void SkyManager::RenderSky()
{
#if CONFIG2_GLES
#warning TODO: implement SkyManager::RenderSky for GLES
#else
// Draw the sky as a small box around the camera position, with depth write enabled.
// This will be done before anything else is drawn so we'll be overlapped by everything else.
@ -223,4 +227,6 @@ void SkyManager::RenderSky()
glPopMatrix();
glDepthMask( GL_TRUE );
#endif
}

View File

@ -97,6 +97,9 @@ void TerrainOverlay::RenderOverlays()
PROFILE3_GPU("terrain overlays");
#if CONFIG2_GLES
#warning TODO: implement TerrainOverlay::RenderOverlays for GLES
#else
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_FALSE);
@ -119,6 +122,7 @@ void TerrainOverlay::RenderOverlays()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
#endif
}
//////////////////////////////////////////////////////////////////////////
@ -186,6 +190,10 @@ void TerrainOverlay::RenderTile(const CColor& colour, bool draw_hidden, ssize_t
glEnable(GL_CULL_FACE);
}
#if CONFIG2_GLES
#warning TODO: implement TerrainOverlay::RenderTile for GLES
#else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
CVector3D pos;
@ -212,6 +220,8 @@ void TerrainOverlay::RenderTile(const CColor& colour, bool draw_hidden, ssize_t
m_Terrain->CalcPosition(i, j, pos); glVertex3fv(pos.GetFloatArray());
}
glEnd();
#endif
}
void TerrainOverlay::RenderTileOutline(const CColor& colour, int line_width, bool draw_hidden)
@ -232,6 +242,10 @@ void TerrainOverlay::RenderTileOutline(const CColor& colour, int line_width, boo
glEnable(GL_CULL_FACE);
}
#if CONFIG2_GLES
#warning TODO: implement TerrainOverlay::RenderTileOutline for GLES
#else
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
if (line_width != 1)
@ -248,4 +262,6 @@ void TerrainOverlay::RenderTileOutline(const CColor& colour, int line_width, boo
if (line_width != 1)
glLineWidth(1.0f);
#endif
}