New OpenGL-ES 2.x driver. This is a fully shader based render pipeline, which is compatible with, e.g., latest iPhone and other smartphone systems, and embedded devices such as the Pandora game console and the Beagle board.

The whole implementation of the new driver was provided by the folks from Amundis (http://amundis.fr/index.php?lang=en). There are more projects to come from them. Many thanks to Thibault and his colleagues for providing the code for inclusion in the engine.
Please note that you have to remove not only the OpenGL driver (automatically done in IrrCompileConfig once the ogl-es driver is enabled there), but also the linking against the opengl32.lib in the project files. Otherwise no rendering will happen.
Also note that the driver currently does not support all features of the engine. Some materials are not fully working, the shadow system seems to be missing, and the mipmapping is broken. These things will be fixed in future bug fixes.

git-svn-id: http://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@3370 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2010-08-08 17:46:48 +00:00
parent a8183ff5eb
commit 2ba228a486
36 changed files with 7793 additions and 15 deletions

View File

@ -57,22 +57,24 @@ int main()
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) OpenGL 1.5\n (b) Direct3D 9.0c\n (c) Direct3D 8.1\n"\
" (d) OpenGL-ES1\n (e) Burning's Software Renderer\n (f) Software Renderer\n"\
" (g) NullDevice\n (otherKey) exit\n\n");
" (a) OpenGL ES 2.x\n (b) OpenGL ES 1.x\n (c) OpenGL 1.x-4.x\n"\
" (d) Direct3D 9.0c\n (e) Direct3D 8.1\n"\
" (f) Burning's Software Renderer\n (g) Software Renderer\n"\
" (h) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_OPENGL; break;
case 'b': driverType = video::EDT_DIRECT3D9;break;
case 'c': driverType = video::EDT_DIRECT3D8;break;
case 'd': driverType = video::EDT_OGLES1; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_SOFTWARE; break;
case 'g': driverType = video::EDT_NULL; break;
case 'a': driverType = video::EDT_OGLES2; break;
case 'b': driverType = video::EDT_OGLES1; break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_DIRECT3D9;break;
case 'e': driverType = video::EDT_DIRECT3D8;break;
case 'f': driverType = video::EDT_BURNINGSVIDEO;break;
case 'g': driverType = video::EDT_SOFTWARE; break;
case 'h': driverType = video::EDT_NULL; break;
default: return 1;
}

View File

@ -52,9 +52,13 @@ namespace video
primitives. */
EDT_OPENGL,
//! OpenGL-ES device, for embedded and mobile systems
//! OpenGL-ES 1.x driver, for embedded and mobile systems
EDT_OGLES1,
//! OpenGL-ES 2.x driver, for embedded and mobile systems
/** Supports shaders etc. */
EDT_OGLES2,
//! No driver, just for counting the elements
EDT_COUNT
};

View File

@ -0,0 +1,38 @@
#ifndef __E_VERTEX_ATTRIBUTES_H_INCLUDED__
#define __E_VERTEX_ATTRIBUTES_H_INCLUDED__
namespace irr
{
namespace video
{
//! Enumeration for all vertex attibutes there are.
enum E_VERTEX_ATTRIBUTES
{
EVA_POSITION = 0,
EVA_NORMAL,
EVA_COLOR,
EVA_TCOORD0,
EVA_TCOORD1,
EVA_TANGENT,
EVA_BINORMAL,
EVA_COUNT
};
//! Array holding the built in vertex attribute names
const char* const sBuiltInVertexAttributeNames[] =
{
"inVertexPosition",
"inVertexNormal",
"inVertexColor",
"inTexCoord0",
"inTexCoord1",
"inVertexTangent",
"inVertexBinormal",
0
};
} // end namespace video
} // end namespace irr
#endif //__E_VERTEX_ATTRIBUTES_H_INCLUDED__

View File

@ -69,6 +69,7 @@ public:
actually done in D3D8 and D3D9 when using a normal mapped material with
a vertex type other than EVT_TANGENTS. */
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) { return true; }
virtual bool PostRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) { return true;};
//! Called by the IVideoDriver to unset this material.
/** Called during the IVideoDriver::setMaterial() call before the new

View File

@ -74,6 +74,9 @@ public:
\param userData: Userdata int which can be specified when creating the shader.
*/
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData) = 0;
virtual void OnSetAttribute(IMaterialRendererServices* services, s32 userData) {}
virtual void OnUnSetAttribute(IMaterialRendererServices* services, s32 userData) {}
};

View File

@ -135,7 +135,7 @@ headers, e.g. Summer 2004. This is a Microsoft issue, not an Irrlicht one.
//! Define _IRR_COMPILE_WITH_OPENGL_ to compile the Irrlicht engine with OpenGL.
/** If you do not wish the engine to be compiled with OpenGL, comment this
define out. */
//#define _IRR_COMPILE_WITH_OPENGL_
#define _IRR_COMPILE_WITH_OPENGL_
//! Define _IRR_COMPILE_WITH_OGLES1_ to compile the Irrlicht engine with OpenGL-ES 1.x.
/** If you do not wish the engine to be compiled with OpenGL-ES 1.x, comment
@ -144,7 +144,16 @@ You should only use this define if you really need the OpenGL-ES driver, and
it should be usually the only HW accelerated one. OpenGL is currently disabled
if using this driver, to avoid problems with the ogl-es emulators.
*/
#define _IRR_COMPILE_WITH_OGLES1_
//#define _IRR_COMPILE_WITH_OGLES1_
//! Define _IRR_COMPILE_WITH_OGLES2_ to compile the Irrlicht engine with OpenGL-ES 2.x.
/** If you do not wish the engine to be compiled with OpenGL-ES 2.x, comment
this define out.
You should only use this define if you really need the OpenGL-ES driver, and
it should be usually the only HW accelerated one. OpenGL is currently disabled
if using this driver, to avoid problems with the ogl-es emulators.
*/
//#define _IRR_COMPILE_WITH_OGLES2_
//! Define _IRR_COMPILE_WITH_SOFTWARE_ to compile the Irrlicht engine with software driver
/** If you do not need the software driver, or want to use Burning's Video instead,
@ -535,8 +544,13 @@ precision will be lower but speed higher. currently X86 only
#endif
// OpenGL-ES usually interferes with OpenGL
#ifdef _IRR_COMPILE_WITH_OGLES2_
#undef _IRR_COMPILE_WITH_OPENGL_
#undef _IRR_COMPILE_WITH_OGLES1_
#endif
#ifdef _IRR_COMPILE_WITH_OGLES1_
#undef _IRR_COMPILE_WITH_OPENGL_
#undef _IRR_COMPILE_WITH_OGLES2_
#endif
#ifndef _IRR_WINDOWS_API_

View File

@ -14,7 +14,10 @@ namespace irr
//! ask user for driver
static irr::video::E_DRIVER_TYPE driverChoiceConsole(bool allDrivers=true)
{
const char* const names[] = {"NullDriver","Software Renderer","Burning's Video","Direct3D 8.1","Direct3D 9.0c","OpenGL 1.x/2.x/3.x","OpenGL-ES 1.x"};
const char* const names[] =
{"NullDriver","Software Renderer","Burning's Video",
"Direct3D 8.1","Direct3D 9.0c",
"OpenGL 1.x/2.x/3.x","OpenGL-ES 1.x","OpenGL-ES 2.x"};
printf("Please select the driver you want:\n");
irr::u32 i=0;
for (i=irr::video::EDT_COUNT; i>0; --i)

View File

@ -0,0 +1,182 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#define MAX_TEXTURE_UNITS 4
#define FOG_EXP 1
#define FOG_LINEAR 2
#define TwoD 24
#define Solid 0
#define Solid2Layer 1
#define LightMap 2
#define DetailMap 9
#define SphereMap 10
#define Reflection2Layer 11
#define TransparentAlphaChannel 13
#define TransparentVertexAlpha 15
precision mediump float;
vec4 red = vec4(1.0, 0.0, 0.0, 1.0);
vec4 green = vec4(0.0, 1.0, 0.0, 1.0);
vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);
/* Varyings */
varying vec4 varTexCoord[MAX_TEXTURE_UNITS];
varying vec4 varVertexColor;
varying float eyeDist;
varying float varClipDist;
/* Uniforms */
uniform int uRenderMode;
uniform bool uAlphaTest;
uniform float uAlphaValue;
/* Fog Uniforms */
uniform bool uFog;
uniform int uFogType;
uniform vec4 uFogColor;
uniform float uFogStart;
uniform float uFogEnd;
uniform float uFogDensity;
/* Texture Uniforms */
uniform sampler2D uTextureUnit0;
uniform sampler2D uTextureUnit1;
uniform bool uUseTexture [MAX_TEXTURE_UNITS];
vec4 render2D(void)
{
vec4 color = varVertexColor;
vec4 texel = texture2D(uTextureUnit0, varTexCoord[0].xy);
if(uUseTexture[0])
{
color *= texel;
}
return color;
}
vec4 renderSolid(void)
{
vec4 color = varVertexColor;
vec4 texel = texture2D(uTextureUnit0, varTexCoord[0].xy);
if(uUseTexture[0])
color *= texel;
return color;
}
vec4 renderTransparentVertexAlpha(void)
{
vec4 color = renderSolid();
color.a = varVertexColor.a;
return color;
}
vec4 renderTransparentAlphaChannel(void)
{
vec4 texel = texture2D(uTextureUnit0, varTexCoord[0].xy);
vec4 color = texel * varVertexColor;
color.a = texel.a;
return color;
}
vec4 render2LayerSolid(void)
{
float blendFactor = varVertexColor.a;
vec4 texel0 = texture2D(uTextureUnit0, varTexCoord[0].xy);
vec4 texel1 = texture2D(uTextureUnit1, varTexCoord[1].xy);
vec4 color = texel0 * blendFactor + texel1 * ( 1.0 - blendFactor );
return color;
}
vec4 renderLightMap(void)
{
vec4 texel0 = texture2D(uTextureUnit0, varTexCoord[0].xy);
vec4 texel1 = texture2D(uTextureUnit1, varTexCoord[1].xy);
vec4 color = texel0 * texel1 * 4.0;
color.a = texel0.a * texel0.a;
return color;
}
vec4 renderDetailMap(void)
{
vec4 texel0 = texture2D(uTextureUnit0, varTexCoord[0].xy);
vec4 texel1 = texture2D(uTextureUnit1, varTexCoord[1].xy);
vec4 color = texel0;
color += texel1 - 0.5;
return color;
}
vec4 renderReflection2Layer(void)
{
vec4 color = varVertexColor;
vec4 texel0 = texture2D(uTextureUnit0, varTexCoord[0].xy);
vec4 texel1 = texture2D(uTextureUnit1, varTexCoord[1].xy);
color *= texel0 * texel1;
return color;
}
float ComputeFog()
{
float factor = 1.0;
if(uFogType == FOG_LINEAR)
{
factor = (uFogEnd - eyeDist) / (uFogEnd - uFogStart);
}
else if(uFogType == FOG_EXP)
{
factor = exp(-(eyeDist * uFogDensity));
}
else //uFogType == FOG_EXP2
{
factor = eyeDist * uFogDensity;
factor = exp(-(factor * factor)) ;
}
factor = clamp(factor, 0.0, 1.0);
return factor;
}
void main (void)
{
if(varClipDist < 0.0)
discard;
if( uRenderMode == TwoD)
gl_FragColor = render2D();
else if( uRenderMode == Solid)
gl_FragColor = renderSolid();
else if(uRenderMode == LightMap)
gl_FragColor = renderLightMap();
else if(uRenderMode == DetailMap)
gl_FragColor = renderDetailMap();
else if(uRenderMode == SphereMap)
gl_FragColor = renderSolid();
else if(uRenderMode == Reflection2Layer)
gl_FragColor = renderReflection2Layer();
else if(uRenderMode == TransparentVertexAlpha)
gl_FragColor = renderTransparentVertexAlpha();
else if(uRenderMode == TransparentAlphaChannel)
gl_FragColor = renderTransparentAlphaChannel();
else
gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
//gl_FragColor = varVertexColor;
if(uFog)
{
float fogFactor = ComputeFog();
gl_FragColor = gl_FragColor * fogFactor + uFogColor * (1.0 - fogFactor);
}
if(uAlphaTest && uAlphaValue > gl_FragColor.a)
discard;
}

View File

@ -0,0 +1,245 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#define MAX_TEXTURE_UNITS 4
#define MAX_LIGHTS 8
#define SphereMap 10
#define Reflection2Layer 11
const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);
const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);
const vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);
const vec4 white = vec4(1.0);
const vec4 black = vec4(0.0);
/* Vertex Attributes */
attribute vec4 inVertexPosition;
attribute vec4 inVertexColor;
attribute vec4 inTexCoord0;
attribute vec4 inTexCoord1;
attribute vec3 inVertexNormal;
uniform int uRenderMode;
/* Matrix Uniforms */
uniform mat4 uMvpMatrix;
uniform mat4 uWorldMatrix;
uniform bool uNormalize;
uniform vec3 uEyePos;
/* Light Uniforms */
uniform bool uUseLight [MAX_LIGHTS];
uniform vec4 uLightPosition [MAX_LIGHTS];
uniform vec4 uLightAmbient [MAX_LIGHTS];
uniform vec4 uLightDiffuse [MAX_LIGHTS];
#ifdef USE_SPECULAR
uniform vec4 uLightSpecular [MAX_LIGHTS];
#endif
#ifdef USE_LIGHT_CUTOFF
uniform vec3 uLightDirection [MAX_LIGHTS];
uniform float uLightCutoff [MAX_LIGHTS];
uniform float uLightExponent [MAX_LIGHTS];
#endif
uniform vec3 uLightAttenuation [MAX_LIGHTS];
uniform vec4 uAmbientColor;
uniform bool uLighting;
/* Material Uniforms */
uniform vec4 uMaterialAmbient;
uniform vec4 uMaterialEmission;
uniform vec4 uMaterialDiffuse;
uniform vec4 uMaterialSpecular;
uniform float uMaterialShininess;
uniform int uColorMaterial;
#define ECM_NONE 0
#define ECM_DIFFUSE 1
#define ECM_AMBIENT 2
#define ECM_EMISSIVE 3
#define ECM_SPECULAR 4
#define ECM_DIFFUSE_AND_AMBIENT 5
/* Texture Uniforms */
uniform bool uUseTexture [MAX_TEXTURE_UNITS];
uniform mat4 uTextureMatrix [MAX_TEXTURE_UNITS];
uniform bool uUseTexMatrix [MAX_TEXTURE_UNITS];
/* Clip Plane Uniforms */
uniform bool uClip;
uniform vec4 uClipPlane;
varying float varClipDist;
/* Varyings */
varying vec4 varTexCoord[MAX_TEXTURE_UNITS];
varying vec4 varVertexColor;
varying float eyeDist;
/* shader variables */
vec3 gNormal;
vec3 gWorldPos;
vec4 gColor;
struct material {
vec4 Ambient;
vec4 Diffuse;
vec4 Specular;
vec4 Emission;
float Shininess;
} ;
material gMaterial;
vec4 lightEquation(int lidx)
{
vec4 color = vec4(0.0);
float att = 1.0;
vec3 lightDir;
if( uLightPosition[lidx].w == 0.0) // Directional light
{
lightDir = -uLightPosition[lidx].xyz;
}
else
{
lightDir = uLightPosition[lidx].xyz - inVertexPosition.xyz;
att = 1.0 / (uLightAttenuation[lidx].y * length(lightDir));
lightDir = normalize(lightDir);
#ifdef USE_LIGHT_CUTOFF
if(uLightCutoff[lidx] < 180.0)
{
// compute spot factor
float spotEffect = dot(-lightDir, uLightDirection[lidx]);
if( spotEffect >= cos( radians( uLightCutoff[lidx])))
spotEffect = pow( spotEffect, uLightExponent[lidx]);
else
spotEffect = 0.0;
att *= spotEffect;
}
#endif
}
if(att >= 0.0 )
{
color += uLightAmbient[lidx] * gMaterial.Ambient;
//Compute cos(Light, Normal)
float NdotL = max(dot(normalize(gNormal), lightDir), 0.0);
color += NdotL * uLightDiffuse[lidx] * gMaterial.Diffuse;
//Compute cos(hvec, Normal)
#ifdef USE_SPECULAR
vec3 hvec = normalize(lightDir + vec3(0.0, 0.0, 1.0));
float NdotH = dot(gNormal, hvec);
if(NdotH > 0.0)
{
color += pow(NdotH, uMaterialShininess) * uLightSpecular[lidx] * gMaterial.Specular;
}
#endif
color *= att;
}
return color;
}
vec4 computeLighting(void)
{
vec4 color = gMaterial.Emission + gMaterial.Ambient * uAmbientColor;
for ( int i = 0 ; i < MAX_LIGHTS; ++i)
{
if ( uUseLight[i] )
{
color += lightEquation(i) ;
}
}
color.a = gMaterial.Diffuse.a;
return color;
}
void ReplaceColorMaterial(void)
{
gMaterial.Ambient = uMaterialAmbient;
gMaterial.Diffuse = uMaterialDiffuse;
gMaterial.Emission = uMaterialEmission;
gMaterial.Specular = uMaterialSpecular;
gMaterial.Shininess = uMaterialShininess;
if(uColorMaterial == ECM_DIFFUSE)
gMaterial.Diffuse = gColor;
else if(uColorMaterial == ECM_AMBIENT)
gMaterial.Ambient = gColor;
else if(uColorMaterial == ECM_DIFFUSE_AND_AMBIENT)
{
gMaterial.Diffuse = gColor;
gMaterial.Ambient = gColor;
}
else if(uColorMaterial == ECM_EMISSIVE)
gMaterial.Emission = gColor;
else if(uColorMaterial == ECM_SPECULAR)
gMaterial.Specular = gColor;
}
void main(void)
{
gl_Position = uMvpMatrix * inVertexPosition;
gWorldPos = (uWorldMatrix * inVertexPosition).xyz;
gColor = inVertexColor.bgra;
gNormal = inVertexNormal.xyz;
if(uNormalize)
gNormal = normalize(gNormal);
ReplaceColorMaterial();
if(uLighting)
varVertexColor = computeLighting();
else
varVertexColor = gColor;
for(int i = 0; i < MAX_TEXTURE_UNITS; ++i)
varTexCoord[i] = vec4(0.0);
if( uUseTexture[0])
{
if(uRenderMode == SphereMap || uRenderMode == Reflection2Layer)
{
vec3 eyeDir = normalize(inVertexPosition.xyz - uEyePos);
vec3 reflection = reflect(eyeDir, gNormal);
float m = 2.0 * sqrt(reflection.x * reflection.x +
reflection.y * reflection.y +
(reflection.z + 1.0) * (reflection.z + 1.0));
varTexCoord[0] = vec4((reflection.x / m + 0.5), (reflection.y / m + 0.5), 0.0, 0.0);
}
else
{
varTexCoord[0] = inTexCoord0;
if(uUseTexMatrix[0])
varTexCoord[0] *= uTextureMatrix[0];
}
}
if(uUseTexture[1])
{
varTexCoord[1] = inTexCoord1;
if(uUseTexMatrix[1])
varTexCoord[1] *= uTextureMatrix[1];
}
eyeDist = length(uEyePos);
varClipDist = uClip ? dot(gWorldPos, uClipPlane.xyz)-uClipPlane.w : 0.0;
varVertexColor.rgb = clamp(varVertexColor.rgb, 0.0, 1.0);
varVertexColor.a = gColor.a;
}

View File

@ -0,0 +1,36 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#define MAX_LIGHTS 2
precision mediump float;
uniform sampler2D texture0;
uniform sampler2D texture1;
varying vec4 varTexCoord;
varying vec3 varLightVector[MAX_LIGHTS];
varying vec4 varLightColor[MAX_LIGHTS];
varying vec4 debug;
void main(void)
{
// fetch color and normal map
vec4 normalMap = texture2D(texture1, varTexCoord.xy) * 2.0 - 1.0;
vec4 colorMap = texture2D(texture0, varTexCoord.xy);
// calculate color of light 0
vec4 color = clamp(varLightColor[0], 0.0, 1.0) * dot(normalMap.xyz, normalize(varLightVector[0].xyz));
// calculate color of light 1
color += clamp(varLightColor[1], 0.0, 1.0) * dot(normalMap.xyz, normalize(varLightVector[1].xyz));
//luminance * base color
color *= colorMap;
color.a = varLightColor[0].a;
gl_FragColor = color;
}

View File

@ -0,0 +1,69 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#define MAX_LIGHTS 2
attribute vec4 inVertexPosition;
attribute vec4 inVertexColor;
attribute vec4 inTexCoord0;
attribute vec3 inVertexNormal;
attribute vec3 inVertexTangent;
attribute vec3 inVertexBinormal;
uniform mat4 uMvpMatrix;
uniform vec4 uLightPos[MAX_LIGHTS];
uniform vec4 uLightColor[MAX_LIGHTS];
varying vec4 varTexCoord;
varying vec3 varLightVector[MAX_LIGHTS];
varying vec4 varLightColor[MAX_LIGHTS];
varying vec4 debug;
void main(void)
{
debug = vec4(inVertexNormal, 1.0);
// transform position to clip space
gl_Position = uMvpMatrix * inVertexPosition;
// vertex - lightpositions
vec4 tempLightVector0 = uLightPos[0] - inVertexPosition;
vec4 tempLightVector1 = uLightPos[1] - inVertexPosition;
// transform the light vector 1 with U, V, W
varLightVector[0].x = dot(inVertexTangent, tempLightVector0.xyz);
varLightVector[0].y = dot(inVertexBinormal, tempLightVector0.xyz);
varLightVector[0].z = dot(inVertexNormal, tempLightVector0.xyz);
// transform the light vector 2 with U, V, W
varLightVector[1].x = dot(inVertexTangent, tempLightVector1.xyz);
varLightVector[1].y = dot(inVertexBinormal, tempLightVector1.xyz);
varLightVector[1].z = dot(inVertexNormal, tempLightVector1.xyz);
// calculate attenuation of light 0
varLightColor[0].w = 0.0;
varLightColor[0].x = dot(tempLightVector0, tempLightVector0);
varLightColor[0].x *= uLightColor[0].w;
varLightColor[0] = vec4(inversesqrt(varLightColor[0].x));
varLightColor[0] *= uLightColor[0];
// normalize light vector 0
varLightVector[0] = normalize(varLightVector[0]);
// calculate attenuation of light 1
varLightColor[1].w = 0.0;
varLightColor[1].x = dot(tempLightVector1, tempLightVector1);
varLightColor[1].x *= uLightColor[1].w;
varLightColor[1] = vec4(inversesqrt(varLightColor[1].x));
varLightColor[1] *= uLightColor[1];
// normalize light vector 1
varLightVector[1] = normalize(varLightVector[1]);
// move out texture coordinates and original alpha value
varTexCoord = inTexCoord0;
varLightColor[0].a = inVertexColor.a;
}

View File

@ -0,0 +1,49 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#define MAX_LIGHTS 2
precision mediump float;
uniform sampler2D texture0;
uniform sampler2D texture1;
//uniform vec4 uLightDiffuse[MAX_LIGHTS];
uniform float uHeightScale;
varying vec4 varTexCoord;
varying vec3 varLightVector[MAX_LIGHTS];
varying vec4 varLightColor[MAX_LIGHTS];
varying vec3 varEyeVector;
varying vec4 debug;
void main(void)
{
// fetch color and normal map
vec4 normalMap = texture2D(texture1, varTexCoord.xy) * 2.0 - 1.0;
// height = height * scale
normalMap *= uHeightScale;
// calculate new texture coord: height * eye + oldTexCoord
vec2 offset = varEyeVector.xy * normalMap.w + varTexCoord.xy;
// fetch new textures
vec4 colorMap = texture2D(texture0, offset);
normalMap = normalize(texture2D(texture1, offset) * 2.0 - 1.0);
// calculate color of light 0
vec4 color = clamp(varLightColor[0], 0.0, 1.0) * dot(normalMap.xyz, normalize(varLightVector[0].xyz));
// calculate color of light 1
color += clamp(varLightColor[1], 0.0, 1.0) * dot(normalMap.xyz, normalize(varLightVector[1].xyz));
//luminance * base color
color *= colorMap;
color.a = varLightColor[0].a;
gl_FragColor = color;
}

View File

@ -0,0 +1,81 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#define MAX_LIGHTS 2
attribute vec4 inVertexPosition;
attribute vec4 inVertexColor;
attribute vec4 inTexCoord0;
attribute vec3 inVertexNormal;
attribute vec3 inVertexTangent;
attribute vec3 inVertexBinormal;
uniform mat4 uMvpMatrix;
uniform vec4 uLightPos[MAX_LIGHTS];
uniform vec4 uLightColor[MAX_LIGHTS];
uniform vec3 uEyePos;
varying vec4 varTexCoord;
varying vec3 varLightVector[MAX_LIGHTS];
varying vec4 varLightColor[MAX_LIGHTS];
varying vec3 varEyeVector;
varying vec4 debug;
void main(void)
{
debug = vec4(inVertexNormal, 1.0);
// transform position to clip space
gl_Position = uMvpMatrix * inVertexPosition;
// vertex - lightpositions
vec4 tempLightVector0 = uLightPos[0] - inVertexPosition;
vec4 tempLightVector1 = uLightPos[1] - inVertexPosition;
// eye vector
vec4 Temp = vec4(uEyePos, 1.0) - inVertexPosition;
// transform the light vector 1 with U, V, W
varLightVector[0].x = dot(inVertexTangent, tempLightVector0.xyz);
varLightVector[0].y = dot(inVertexBinormal, tempLightVector0.xyz);
varLightVector[0].z = dot(inVertexNormal, tempLightVector0.xyz);
// transform the light vector 2 with U, V, W
varLightVector[1].x = dot(inVertexTangent, tempLightVector1.xyz);
varLightVector[1].y = dot(inVertexBinormal, tempLightVector1.xyz);
varLightVector[1].z = dot(inVertexNormal, tempLightVector1.xyz);
// transform the eye vector with U, V, W
varEyeVector.x = dot(inVertexTangent, Temp.xyz);
varEyeVector.y = dot(inVertexBinormal, Temp.xyz);
varEyeVector.z = dot(inVertexNormal, Temp.xyz);
varEyeVector *= vec3(1.0,-1.0, -1.0);
varEyeVector = normalize(varEyeVector);
// calculate attenuation of light 0
varLightColor[0].w = 0.0;
varLightColor[0].x = dot(tempLightVector0, tempLightVector0);
varLightColor[0].x *= uLightColor[0].w;
varLightColor[0] = vec4(inversesqrt(varLightColor[0].x));
varLightColor[0] *= uLightColor[0];
// normalize light vector 0
varLightVector[0] = normalize(varLightVector[0]);
// calculate attenuation of light 1
varLightColor[1].w = 0.0;
varLightColor[1].x = dot(tempLightVector1, tempLightVector1);
varLightColor[1].x *= uLightColor[1].w;
varLightColor[1] = vec4(inversesqrt(varLightColor[1].x));
varLightColor[1] *= uLightColor[1];
// normalize light vector 1
varLightVector[1] = normalize(varLightVector[1]);
// move out texture coordinates and original alpha value
varTexCoord = inTexCoord0;
varLightColor[0].a = inVertexColor.a;
}

View File

@ -0,0 +1,29 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
precision mediump float;
uniform bool uUseTexture;
uniform sampler2D uTextureUnit;
uniform bool uAlphaTest;
uniform float uAlphaValue;
varying vec4 varVertexColor;
varying vec4 varTexCoord;
void main(void)
{
vec4 color = varVertexColor;
vec4 texel = texture2D(uTextureUnit, varTexCoord.xy);
if(uUseTexture)
{
color *= texel;
}
if(uAlphaTest && !(color.a > uAlphaValue))
discard;
gl_FragColor = color;
}

View File

@ -0,0 +1,20 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
attribute vec4 inVertexPosition;
attribute vec4 inVertexColor;
attribute vec4 inTexCoord0;
uniform mat4 uOrthoMatrix;
varying vec4 varVertexColor;
varying vec4 varTexCoord;
void main(void)
{
gl_Position = uOrthoMatrix * inVertexPosition;
varVertexColor = inVertexColor.bgra;
varTexCoord = inTexCoord0;
}

View File

@ -43,6 +43,10 @@ namespace irr
#ifdef _IRR_COMPILE_WITH_OGLES1_
IVideoDriver* createOGLES1Driver(const SIrrlichtCreationParameters& params, video::SExposedVideoData& data, io::IFileSystem* io);
#endif
#ifdef _IRR_COMPILE_WITH_OGLES2_
IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params, video::SExposedVideoData& data, io::IFileSystem* io);
#endif
}
} // end namespace irr
@ -737,6 +741,25 @@ void CIrrDeviceWin32::createDriver()
#endif
break;
case video::EDT_OGLES2:
#ifdef _IRR_COMPILE_WITH_OGLES2_
{
video::SExposedVideoData data;
data.OpenGLWin32.HWnd=HWnd;
switchToFullScreen();
VideoDriver = video::createOGLES2Driver(CreationParams, data, FileSystem);
if (!VideoDriver)
{
os::Printer::log("Could not create OpenGL-ES2 driver.", ELL_ERROR);
}
}
#else
os::Printer::log("OpenGL-ES2 driver was not compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_SOFTWARE:
#ifdef _IRR_COMPILE_WITH_SOFTWARE_

View File

@ -2239,7 +2239,7 @@ s32 CNullDriver::addShaderMaterialFromFiles(const io::path& vertexShaderProgramF
//! Creates a render target texture.
ITexture* CNullDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path&name, const ECOLOR_FORMAT format)
const io::path& name, const ECOLOR_FORMAT format)
{
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,470 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_OGLES2_DRIVER_H_INCLUDED__
#define __C_OGLES2_DRIVER_H_INCLUDED__
#include "IrrCompileConfig.h"
#if defined(_IRR_WINDOWS_API_)
// include windows headers for HWND
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
#include "MacOSX/CIrrDeviceMacOSX.h"
#elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
#include "CIrrDeviceIPhone.h"
#endif
#include "SIrrCreationParameters.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include <EGL/eglplatform.h>
#ifndef GL_BGRA
// we need to do this for the IMG_BGRA8888 extension
extern int GL_BGRA;
#endif
#include "CNullDriver.h"
#include "IMaterialRendererServices.h"
#include "EDriverFeatures.h"
#include "fast_atof.h"
#ifdef _MSC_VER
#pragma comment(lib, "libEGL.lib")
#pragma comment(lib, "libGLESv2.lib")
#endif
#include "COGLES2ExtensionHandler.h"
namespace irr
{
namespace video
{
class COGLES2Texture;
class COGLESWrapper;
class COGLES2FixedPipelineShader;
class COGLES2Renderer2d;
class COGLES2Driver : public CNullDriver, public IMaterialRendererServices, public COGLES2ExtensionHandler
{
public:
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined(_IRR_COMPILE_WITH_SDL_DEVICE_) || defined(_IRR_WINDOWS_API_) || defined(_IRR_COMPILE_WITH_CONSOLE_DEVICE_)
COGLES2Driver( const SIrrlichtCreationParameters& params,
const SExposedVideoData& data,
io::IFileSystem* io );
#endif
#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
COGLES2Driver( const SIrrlichtCreationParameters& params,
io::IFileSystem* io, CIrrDeviceMacOSX *device );
#endif
#if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
COGLES2Driver( const SIrrlichtCreationParameters& params,
const SExposedVideoData& data,
io::IFileSystem* io, MIrrIPhoneDevice const & device );
#endif
//! destructor
virtual ~COGLES2Driver();
//! clears the zbuffer
virtual bool beginScene( bool backBuffer = true, bool zBuffer = true,
SColor color = SColor( 255, 0, 0, 0 ),
const SExposedVideoData& videoData=SExposedVideoData(),
core::rect<s32>* sourceRect = 0 );
//! presents the rendered scene on the screen, returns false if failed
virtual bool endScene();
//! sets transformation
virtual void setTransform( E_TRANSFORMATION_STATE state, const core::matrix4& mat );
struct SHWBufferLink_opengl : public SHWBufferLink
{
SHWBufferLink_opengl( const scene::IMeshBuffer *_MeshBuffer ): SHWBufferLink( _MeshBuffer ), vbo_verticesID( 0 ), vbo_indicesID( 0 ) {}
u32 vbo_verticesID; //tmp
u32 vbo_indicesID; //tmp
u32 vbo_verticesSize; //tmp
u32 vbo_indicesSize; //tmp
};
bool updateVertexHardwareBuffer( SHWBufferLink_opengl *HWBuffer );
bool updateIndexHardwareBuffer( SHWBufferLink_opengl *HWBuffer );
//! updates hardware buffer if needed
virtual bool updateHardwareBuffer( SHWBufferLink *HWBuffer );
//! Create hardware buffer from mesh
virtual SHWBufferLink *createHardwareBuffer( const scene::IMeshBuffer* mb );
//! Delete hardware buffer (only some drivers can)
virtual void deleteHardwareBuffer( SHWBufferLink *HWBuffer );
//! Draw hardware buffer
virtual void drawHardwareBuffer( SHWBufferLink *HWBuffer );
//! draws a vertex primitive list
virtual void drawVertexPrimitiveList( const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType );
//! draws a vertex primitive list in 2d
// virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,
// const void* indexList, u32 primitiveCount,
// E_VERTEX_TYPE vType=EVT_STANDARD, scene::E_PRIMITIVE_TYPE pType=scene::EPT_TRIANGLES, E_INDEX_TYPE iType=EIT_16BIT);
void drawVertexPrimitiveList2d3d( const void* vertices, u32 vertexCount, const void* indexList,
u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType,
E_INDEX_TYPE iType = EIT_16BIT, bool threed = true );
//! queries the features of the driver, returns true if feature is available
virtual bool queryFeature( E_VIDEO_DRIVER_FEATURE feature ) const
{
return FeatureEnabled[feature] && COGLES2ExtensionHandler::queryFeature(feature);
}
//! Sets a material.
virtual void setMaterial( const SMaterial& material );
//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.
virtual void draw2DImage( const video::ITexture* texture, const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
SColor color = SColor( 255, 255, 255, 255 ), bool useAlphaChannelOfTexture = false );
//! draws a set of 2d images
virtual void draw2DImageBatch( const video::ITexture* texture,
const core::position2d<s32>& pos,
const core::array<core::rect<s32> >& sourceRects,
const core::array<s32>& indices,
s32 kerningWidth = 0,
const core::rect<s32>* clipRect = 0,
SColor color = SColor( 255, 255, 255, 255 ),
bool useAlphaChannelOfTexture = false );
//! Draws a part of the texture into the rectangle.
virtual void draw2DImage( const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
const video::SColor* const colors = 0, bool useAlphaChannelOfTexture = false );
void draw2DImageBatch( const video::ITexture* texture,
const core::array<core::position2d<s32> >& positions,
const core::array<core::rect<s32> >& sourceRects,
const core::rect<s32>* clipRect,
SColor color,
bool useAlphaChannelOfTexture );
//! draw an 2d rectangle
virtual void draw2DRectangle( SColor color, const core::rect<s32>& pos,
const core::rect<s32>* clip = 0 );
//!Draws an 2d rectangle with a gradient.
virtual void draw2DRectangle( const core::rect<s32>& pos,
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
const core::rect<s32>* clip = 0 );
//! Draws a 2d line.
virtual void draw2DLine( const core::position2d<s32>& start,
const core::position2d<s32>& end,
SColor color = SColor( 255, 255, 255, 255 ) );
//! Draws a 3d line.
virtual void draw3DLine( const core::vector3df& start,
const core::vector3df& end,
SColor color = SColor( 255, 255, 255, 255 ) );
//! Draws a pixel
// virtual void drawPixel(u32 x, u32 y, const SColor & color);
//! Returns the name of the video driver.
virtual const wchar_t* getName() const;
//! deletes all dynamic lights there are
virtual void deleteAllDynamicLights();
//! adds a dynamic light
virtual s32 addDynamicLight( const SLight& light );
//! Turns a dynamic light on or off
//! \param lightIndex: the index returned by addDynamicLight
//! \param turnOn: true to turn the light on, false to turn it off
virtual void turnLightOn( s32 lightIndex, bool turnOn );
//! returns the maximal amount of dynamic lights the device can handle
virtual u32 getMaximalDynamicLightAmount() const;
//! Sets the dynamic ambient light color.
virtual void setAmbientLight( const SColorf& color );
//! return the dynamic ambient light color.
const SColorf& getAmbientLight() const;
//! Returns the maximum texture size supported.
virtual core::dimension2du getMaxTextureSize() const;
//! Draws a shadow volume into the stencil buffer.
virtual void drawStencilShadowVolume( const core::vector3df* triangles, s32 count, bool zfail );
//! Fills the stencil shadow with color.
virtual void drawStencilShadow( bool clearStencilBuffer = false,
video::SColor leftUpEdge = video::SColor( 0, 0, 0, 0 ),
video::SColor rightUpEdge = video::SColor( 0, 0, 0, 0 ),
video::SColor leftDownEdge = video::SColor( 0, 0, 0, 0 ),
video::SColor rightDownEdge = video::SColor( 0, 0, 0, 0 ) );
//! sets a viewport
virtual void setViewPort( const core::rect<s32>& area );
//! Only used internally by the engine
virtual void OnResize( const core::dimension2d<u32>& size );
//! Returns type of video driver
virtual E_DRIVER_TYPE getDriverType() const;
//! get color format of the current color buffer
virtual ECOLOR_FORMAT getColorFormat() const;
//! Returns the transformation set by setTransform
virtual const core::matrix4& getTransform( E_TRANSFORMATION_STATE state ) const;
//! Can be called by an IMaterialRenderer to make its work easier.
virtual void setBasicRenderStates( const SMaterial& material, const SMaterial& lastmaterial,
bool resetAllRenderstates );
//! Sets a vertex shader constant.
virtual void setVertexShaderConstant( const f32* data, s32 startRegister, s32 constantAmount = 1 );
//! Sets a pixel shader constant.
virtual void setPixelShaderConstant( const f32* data, s32 startRegister, s32 constantAmount = 1 );
//! Sets a constant for the vertex shader based on a name.
virtual bool setVertexShaderConstant( const c8* name, const f32* floats, int count );
//! Sets a constant for the pixel shader based on a name.
virtual bool setPixelShaderConstant( const c8* name, const f32* floats, int count );
//! Sets a vertex pointer the vertex shader based on a name.
virtual bool setVertexShaderPointer( const c8* name, const void* pointer, s32 size = 3, bool normalized = false, u16 stride = 0 );
//! sets the current Texture
bool setTexture( u32 stage, const video::ITexture* texture );
//! disables all textures beginning with fromStage.
bool disableTextures( u32 fromStage = 0 );
//! Adds a new material renderer to the VideoDriver
virtual s32 addShaderMaterial( const c8* vertexShaderProgram, const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial, s32 userData );
//! Adds a new material renderer to the VideoDriver
virtual s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName = 0,
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = 0,
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0);
//! Returns pointer to the IGPUProgrammingServices interface.
virtual IGPUProgrammingServices* getGPUProgrammingServices();
//! Returns a pointer to the IVideoDriver interface.
virtual IVideoDriver* getVideoDriver();
//! Returns the maximum amount of primitives
virtual u32 getMaximalPrimitiveCount() const;
virtual ITexture* addRenderTargetTexture( const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN );
virtual bool setRenderTarget( video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color );
//! set or reset special render targets
// virtual bool setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
// bool clearZBuffer, SColor color);
//! Sets multiple render targets
// virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
// bool clearBackBuffer=true, bool clearZBuffer=true, SColor color=SColor(0,0,0,0));
//! Clears the ZBuffer.
virtual void clearZBuffer();
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot();
//! checks if an OpenGL error has happend and prints it
bool testGLError();
//! checks if an OGLES1 error has happend and prints it
bool testEGLError();
//! Set/unset a clipping plane.
virtual bool setClipPlane( u32 index, const core::plane3df& plane, bool enable = false );
//! returns the current amount of user clip planes set.
u32 getClipPlaneCount() const;
//! returns the 0 indexed Plane
const core::plane3df& getClipPlane( u32 index ) const;
//! Enable/disable a clipping plane.
virtual void enableClipPlane( u32 index, bool enable );
//! Returns the graphics card vendor name.
virtual core::stringc getVendorInfo()
{
return vendorName;
};
ITexture* createDepthTexture( ITexture* texture, bool shared = true );
void removeDepthTexture( ITexture* texture );
void renderHighLevelShader( bool state = true )
{
NoHighLevelShader = !state;
}
COGLES2FixedPipelineShader* fixedPipeline()
{
return FixedPipeline;
}
virtual void reloadShaders();
//native ogles2 which was ogles1 extensions.
void deleteFramebuffers( s32 n, const u32 *framebuffers );
void deleteRenderbuffers( s32 n, const u32 *renderbuffers );
void enableBlend();
void disableBlend();
void blendFunc( E_BLEND_FACTOR sFactor, E_BLEND_FACTOR dFactor );
private:
void uploadClipPlane( u32 index );
//! inits the opengl-es driver
bool genericDriverInit( const core::dimension2d<u32>& screenSize, bool stencilBuffer );
//! returns a device dependent texture from a software surface (IImage)
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData);
//! creates a transposed matrix in supplied GLfloat array to pass to OGLES1
inline void createGLMatrix( float gl_matrix[16], const core::matrix4& m );
inline void createGLTextureMatrix( float gl_matrix[16], const core::matrix4& m );
//! Map Irrlicht wrap mode to OpenGL enum
GLint getTextureWrapMode(u8 clamp) const;
//! Set GL pipeline to desired texture wrap modes of the material
void setWrapMode( const SMaterial& material );
//! sets the needed renderstates
void setRenderStates3DMode();
//! sets the needed renderstates
void setRenderStates2DMode( bool alpha, bool texture, bool alphaChannel );
// returns the current size of the screen or rendertarget
virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const;
void createMaterialRenderers();
core::stringw Name;
core::matrix4 Matrices[ETS_COUNT];
//! enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates.
enum E_RENDER_MODE
{
ERM_NONE = 0, // no render state has been set yet.
ERM_2D, // 2d drawing rendermode
ERM_3D // 3d rendering mode
};
E_RENDER_MODE CurrentRenderMode;
//! bool to make all renderstates reset if set to true.
bool ResetRenderStates;
bool Transformation3DChanged;
u8 AntiAlias;
SMaterial Material, LastMaterial;
COGLES2Texture* RenderTargetTexture;
const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES];
core::array<ITexture*> DepthTextures;
struct SUserClipPlane
{
core::plane3df Plane;
bool Enabled;
};
core::array<SUserClipPlane> UserClipPlane;
core::dimension2d<u32> CurrentRendertargetSize;
core::stringc vendorName;
core::matrix4 TextureFlipMatrix;
//! Color buffer format
ECOLOR_FORMAT ColorFormat;
//! All the lights that have been requested; a hardware limited
//! number of them will be used at once.
struct RequestedLight
{
RequestedLight( SLight const & lightData )
: LightData( lightData ), DesireToBeOn( true ) { }
SLight LightData;
bool DesireToBeOn;
};
core::array<RequestedLight> RequestedLights;
SColorf AmbientLight;
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
HDC HDc;
#endif
NativeWindowType EglWindow;
void* EglDisplay;
void* EglSurface;
void* EglContext;
COGLES2FixedPipelineShader* FixedPipeline;
COGLES2Renderer2d* TwoDRenderer;
bool NoHighLevelShader;
bool BlendEnabled;
E_BLEND_FACTOR SourceFactor;
E_BLEND_FACTOR DestFactor;
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OPENGL_
#endif

View File

@ -0,0 +1,189 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2ExtensionHandler.h"
#include "COGLES2Driver.h"
#include "fast_atof.h"
#include "irrString.h"
namespace irr
{
namespace video
{
static const char* const OGLES2FeatureStrings[COGLES2ExtensionHandler::IRR_OGLES2_Feature_Count] =
{
"GL_AMD_compressed_3DC_texture",
"GL_AMD_compressed_ATC_texture",
"GL_AMD_performance_monitor",
"GL_AMD_program_binary_Z400",
"GL_ARB_texture_env_combine",
"GL_ARB_texture_env_dot3",
"GL_EXT_multi_draw_arrays",
"GL_EXT_texture_compression_dxt1",
"GL_EXT_texture_filter_anisotropic",
"GL_EXT_texture_format_BGRA8888",
"GL_EXT_texture_type_2_10_10_10_REV",
"GL_IMG_read_format",
"GL_IMG_texture_compression_pvrtc",
"GL_IMG_texture_env_enhanced_fixed_function",
"GL_IMG_texture_format_BGRA8888",
"GL_IMG_user_clip_planes",
"GL_IMG_vertex_program",
"GL_NV_fence",
"GL_OES_blend_equation_separate",
"GL_OES_blend_func_separate",
"GL_OES_blend_subtract",
"GL_OES_byte_coordinates",
"GL_OES_compressed_ETC1_RGB8_texture",
"GL_OES_compressed_paletted_texture",
"GL_OES_depth24",
"GL_OES_depth32",
"GL_OES_depth_texture",
"GL_OES_draw_texture",
"GL_OES_EGL_image",
"GL_OES_element_index_uint",
"GL_OES_extended_matrix_palette",
"GL_OES_fbo_render_mipmap",
"GL_OES_fixed_point",
"GL_OES_fragment_precision_high",
"GL_OES_framebuffer_object",
"GL_OES_get_program_binary",
"GL_OES_mapbuffer",
"GL_OES_matrix_get",
"GL_OES_matrix_palette",
"GL_OES_packed_depth_stencil",
"GL_OES_point_size_array",
"GL_OES_point_sprite",
"GL_OES_query_matrix",
"GL_OES_read_format",
"GL_OES_rgb8_rgba8",
"GL_OES_single_precision",
"GL_OES_standard_derivatives",
"GL_OES_stencil1",
"GL_OES_stencil4",
"GL_OES_stencil8",
"GL_OES_stencil_wrap",
"GL_OES_texture_3D",
"GL_OES_texture_cube_map",
"GL_OES_texture_env_crossbar",
"GL_OES_texture_float",
"GL_OES_texture_float_linear",
"GL_OES_texture_half_float",
"GL_OES_texture_half_float_linear",
"GL_OES_texture_mirrored_repeat",
"GL_OES_texture_npot",
"GL_OES_vertex_half_float",
"GL_OES_vertex_type_10_10_10_2",
"GL_QCOM_driver_control",
"GL_QCOM_performance_monitor_global_mode"
};
COGLES2ExtensionHandler::COGLES2ExtensionHandler() :
EGLVersion( 0 ), Version( 0 ), MaxTextureUnits( 0 ), MaxLights( 0 ), MaxAnisotropy( 1 ),
MaxUserClipPlanes( 1 ), MaxTextureSize(1), CommonProfile( false ), MultiTextureExtension( false ),
MultiSamplingExtension( false ), StencilBuffer( false )
{
for ( u32 i = 0; i < IRR_OGLES2_Feature_Count; ++i )
FeatureAvailable[i] = false;
}
void COGLES2ExtensionHandler::dump() const
{
for ( u32 i = 0; i < IRR_OGLES2_Feature_Count; ++i )
os::Printer::log( OGLES2FeatureStrings[i], FeatureAvailable[i] ? " true" : " false" );
}
void COGLES2ExtensionHandler::initExtensions( COGLES2Driver* driver,
#ifdef EGL_VERSION_1_0
EGLDisplay display,
#endif
bool withStencil )
{
#ifdef EGL_VERSION_1_0
const f32 egl_ver = core::fast_atof( reinterpret_cast<const c8*>( eglQueryString( display, EGL_VERSION ) ) );
EGLVersion = static_cast<u16>( core::floor32( egl_ver ) * 100 + core::round32( core::fract( egl_ver ) * 10.0f ) );
core::stringc eglExtensions = eglQueryString( display, EGL_EXTENSIONS );
os::Printer::log( eglExtensions.c_str() );
#endif
const core::stringc stringVer( glGetString( GL_VERSION ) );
//CommonProfile = ( stringVer[11] == 'M' );
const f32 ogl_ver = core::fast_atof( stringVer.c_str() + 13 );
Version = static_cast<u16>( core::floor32( ogl_ver ) * 100 + core::round32( core::fract( ogl_ver ) * 10.0f ) );
core::stringc extensions = glGetString( GL_EXTENSIONS );
os::Printer::log( extensions.c_str() );
{
const u32 size = extensions.size() + 1;
c8* str = new c8[size];
strncpy( str, extensions.c_str(), extensions.size() );
str[extensions.size()] = ' ';
c8* p = str;
for ( u32 i = 0; i < size; ++i )
{
if ( str[i] == ' ' )
{
str[i] = 0;
if ( *p )
for ( u32 j = 0; j < IRR_OGLES2_Feature_Count; ++j )
{
if ( !strcmp( OGLES2FeatureStrings[j], p ) )
{
FeatureAvailable[j] = true;
break;
}
}
p = p + strlen( p ) + 1;
}
}
delete [] str;
}
#ifndef GL_BGRA
// whoa, pretty badly implemented extension...
if ( FeatureAvailable[IRR_IMG_texture_format_BGRA8888] || FeatureAvailable[IRR_EXT_texture_format_BGRA8888] )
GL_BGRA = 0x80E1;
else
GL_BGRA = GL_RGBA;
#endif
GLint val = 0;
glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS, &val );
MaxTextureUnits = core::min_( MATERIAL_MAX_TEXTURES, static_cast<u32>( val ) );
MultiTextureExtension = true;
//TODO : OpenGL ES 2.0 Port
//glGetIntegerv(GL_MAX_LIGHTS, &val);
MaxLights = static_cast<u8>( val );
#ifdef GL_EXT_texture_filter_anisotropic
if ( FeatureAvailable[GL_EXT_texture_filter_anisotropic] )
{
glGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &val );
MaxAnisotropy = static_cast<u8>( val );
}
#endif
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &val);
MaxTextureSize=static_cast<u32>(val);
if (( Version > 100 ) || FeatureAvailable[IRR_IMG_user_clip_planes] )
{
//TODO : OpenGL ES 2.0 Port
//glGetIntegerv(GL_MAX_CLIP_PLANES, &val);
val = 6;
MaxUserClipPlanes = static_cast<u8>( val );
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OGLES21_

View File

@ -0,0 +1,156 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_OGLES2_EXTENSION_HANDLER_H_INCLUDED__
#define __C_OGLES2_EXTENSION_HANDLER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "os.h"
#include "EDriverFeatures.h"
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
namespace irr
{
namespace video
{
class COGLES2Driver;
class COGLES2ExtensionHandler
{
public:
enum EOGLES2Features
{
IRR_AMD_compressed_3DC_texture = 0, //39
IRR_AMD_compressed_ATC_texture, //40
IRR_AMD_performance_monitor, //50
IRR_AMD_program_binary_Z400, //48
IRR_ARB_texture_env_combine, //ogl, IMG simulator
IRR_ARB_texture_env_dot3, //ogl, IMG simulator
IRR_EXT_multi_draw_arrays, //ogl, IMG simulator
IRR_EXT_texture_compression_dxt1, //49
IRR_EXT_texture_filter_anisotropic, //41
IRR_EXT_texture_format_BGRA8888, //51
IRR_EXT_texture_type_2_10_10_10_REV, //42
IRR_IMG_read_format, //53
IRR_IMG_texture_compression_pvrtc, //54
IRR_IMG_texture_env_enhanced_fixed_function, // non-standard
IRR_IMG_texture_format_BGRA8888, // replaced by EXT version
IRR_IMG_user_clip_planes, // non-standard
IRR_IMG_vertex_program, // non-standard
IRR_NV_fence, //52
IRR_OES_blend_equation_separate, //1
IRR_OES_blend_func_separate, //2
IRR_OES_blend_subtract, //3
IRR_OES_byte_coordinates, //4
IRR_OES_compressed_ETC1_RGB8_texture, //5
IRR_OES_compressed_paletted_texture, //6
IRR_OES_depth24, //24
IRR_OES_depth32, //25
IRR_OES_depth_texture, //43
IRR_OES_draw_texture, //7
IRR_OES_EGL_image, //23
IRR_OES_element_index_uint, //26
IRR_OES_extended_matrix_palette, //8
IRR_OES_fbo_render_mipmap, //27
IRR_OES_fixed_point, //9
IRR_OES_fragment_precision_high, //28
IRR_OES_framebuffer_object, //10
IRR_OES_get_program_binary, //47
IRR_OES_mapbuffer, //29
IRR_OES_matrix_get, //11
IRR_OES_matrix_palette, //12
IRR_OES_packed_depth_stencil, //44
IRR_OES_point_size_array, //14
IRR_OES_point_sprite, //15
IRR_OES_query_matrix, //16
IRR_OES_read_format, //17
IRR_OES_rgb8_rgba8, //30
IRR_OES_single_precision, //18
IRR_OES_standard_derivatives, //45
IRR_OES_stencil1, //31
IRR_OES_stencil4, //32
IRR_OES_stencil8, //33
IRR_OES_stencil_wrap, //19
IRR_OES_texture_3D, //34
IRR_OES_texture_cube_map, //20
IRR_OES_texture_env_crossbar, //21
IRR_OES_texture_float, //36
IRR_OES_texture_float_linear, //35
IRR_OES_texture_half_float, //36
IRR_OES_texture_half_float_linear, //35
IRR_OES_texture_mirrored_repeat, //22
IRR_OES_texture_npot, //37
IRR_OES_vertex_half_float, //38
IRR_OES_vertex_type_10_10_10_2, //46
IRR_QCOM_driver_control, //55
IRR_QCOM_performance_monitor_global_mode, //56
IRR_OGLES2_Feature_Count
};
//! queries the features of the driver, returns true if feature is available
bool queryOpenGLFeature( EOGLES2Features feature ) const
{
return FeatureAvailable[feature];
}
protected:
COGLES2ExtensionHandler();
bool queryFeature( video::E_VIDEO_DRIVER_FEATURE feature ) const
{
switch ( feature )
{
case EVDF_RENDER_TO_TARGET:
return true;
case EVDF_MULTITEXTURE:
return MultiTextureExtension;
case EVDF_BILINEAR_FILTER:
return true;
case EVDF_MIP_MAP:
return true;
case EVDF_MIP_MAP_AUTO_UPDATE:
return Version > 100; // Supported in version 1.1
case EVDF_STENCIL_BUFFER:
return StencilBuffer;
case EVDF_TEXTURE_NSQUARE:
return true; // non-square is always supported
default:
return false;
}
}
void dump() const;
void initExtensions( COGLES2Driver* driver,
void* display,
bool withStencil );
protected:
u16 EGLVersion;
u16 Version;
u8 MaxTextureUnits;
u8 MaxLights;
u8 MaxAnisotropy;
u8 MaxUserClipPlanes;
u32 MaxTextureSize;
bool CommonProfile;
bool MultiTextureExtension;
bool MultiSamplingExtension;
bool StencilBuffer;
bool FeatureAvailable[IRR_OGLES2_Feature_Count];
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OGLES21_
#endif

View File

@ -0,0 +1,322 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "COGLES2FixedPipelineShader.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2SLMaterialRenderer.h"
#include "COGLES2Utils.h"
namespace irr
{
namespace video
{
const char* const COGLES2FixedPipelineShader::sBuiltInShaderUniformNames[] =
{
"uRenderMode",
"uMvpMatrix",
"uWorldMatrix",
"uNormalize",
"uEyePos",
"uUseLight",
"uLightPosition",
"uLightAmbient",
"uLightDiffuse",
"uLightSpecular",
"uLightDirection",
"uLightAttenuation",
"uLightExponent",
"uLightCutoff",
"uAmbientColor",
"uLighting",
"uMaterialAmbient",
"uMaterialEmission",
"uMaterialDiffuse",
"uMaterialSpecular",
"uMaterialShininess",
"uColorMaterial",
"uUseTexture",
"uTextureMatrix",
"uUseTexMatrix",
"uClip",
"uClipPlane",
"uAlphaTest",
"uAlphaValue",
"uFog",
"uFogType",
"uFogColor",
"uFogStart",
"uFogEnd",
"uFogDensity",
"uTextureUnit0",
"uTextureUnit1",
0
};
const c8 VertexShaderFile[] = "../../media/Shaders/COGLES2FixedPipeline.vsh";
const c8 FragmentShaderFile[] = "../../media/Shaders/COGLES2FixedPipeline.fsh";
COGLES2FixedPipelineShader::COGLES2FixedPipelineShader( video::COGLES2Driver *driver, io::IFileSystem* fs )
: COGLES2SLMaterialRenderer( driver, fs, 0, 0, sBuiltInShaderUniformNames, UNIFORM_COUNT ), Normalize( 0 ), AlphaTest( 0 ), AlphaValue( 0.f ),
AlphaFunction( ALPHA_GREATER ), Lighting( 0 ), Fog( 0 ), FogType( 0 ), FogStart( 0.f ), FogEnd( 0.f ), FogDensity( 0.f ),
ColorMaterial( 0 ), MaterialShininess( 0.f ), RenderMode( EMT_SOLID )
{
s32 dummy;
initFromFiles( dummy, VertexShaderFile, FragmentShaderFile, false );
initData();
};
void COGLES2FixedPipelineShader::reload()
{
reloadFromFiles( VertexShaderFile, FragmentShaderFile );
//initData();
}
void COGLES2FixedPipelineShader::initData()
{
for ( size_t i = 0; i < MAX_TEXTURE_UNITS; ++i )
TextureUnits[i] = i;
memset( UseTexture, 0, sizeof( UseTexture ) );
memset( UseTexMatrix, 0, sizeof( UseTexMatrix ) );
memset( UseLight, 0, sizeof( UseLight ) );
memset( LightPosition, 0, sizeof( LightPosition ) );
memset( LightAmbient, 0, sizeof( LightAmbient ) );
memset( LightDiffuse, 0, sizeof( LightDiffuse ) );
memset( LightSpecular, 0, sizeof( LightSpecular ) );
memset( LightDirection, 0, sizeof( LightDirection ) );
memset( LightAttenuation, 0, sizeof( LightAttenuation ) );
memset( LightExponent, 0, sizeof( LightExponent ) );
memset( LightCutoff, 0, sizeof( LightCutoff ) );
memset( &AmbientColor, 0, sizeof( AmbientColor ) );
memset( FogColor, 0, sizeof( FogColor ) );
memset( &ClipPlane, 0, sizeof( ClipPlane ) );
memset( &MaterialAmbient, 0, sizeof( MaterialAmbient ) );
memset( &MaterialEmission, 0, sizeof( MaterialEmission ) );
memset( &MaterialDiffuse, 0, sizeof( MaterialDiffuse ) );
memset( &MaterialSpecular, 0, sizeof( MaterialSpecular ) );
}
bool COGLES2FixedPipelineShader::OnRender( IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype )
{
Driver->testGLError();
bool statusOk = true;
/* Matrices Upload */
core::matrix4 world = Driver->getTransform( ETS_WORLD );
//statusOk &= setVertexShaderConstant( "uWorldMatrix", world.pointer(), 16 );
//glUniformMatrix4fv(locWorldMatrix, 1, false, world.pointer() );
setUniform( WORLD_MATRIX, world.pointer() );
core::matrix4 worldViewProj = Driver->getTransform( video::ETS_PROJECTION );
worldViewProj *= Driver->getTransform( video::ETS_VIEW );
worldViewProj *= Driver->getTransform( ETS_WORLD );
//statusOk &= setVertexShaderConstant( "uMvpMatrix", worldViewProj.pointer(), 16 );
//glUniformMatrix4fv(locMvpMatrix, 1, false, worldViewProj.pointer());
setUniform( MVP_MATRIX, worldViewProj.pointer() );
/* Textures Upload */
//statusOk &= setVertexShaderConstant("uTextureUnit", (f32*)TextureUnits, MAX_TEXTURE_UNITS);
//statusOk &= setVertexShaderConstant( "uTextureUnit0", ( f32* ) & TextureUnits[0], 1 );
setUniform( TEXTURE_UNIT0, &TextureUnits[0] );
//statusOk &= setVertexShaderConstant( "uTextureUnit1", ( f32* ) & TextureUnits[1], 1 );
setUniform( TEXTURE_UNIT1, &TextureUnits[1] );
//statusOk &= setVertexShaderConstant( "uUseTexture", ( f32* )UseTexture, MAX_TEXTURE_UNITS );
setUniform( USE_TEXTURE, UseTexture, MAX_TEXTURE_UNITS );
//statusOk &= setVertexShaderConstant( "uUseTexMatrix", ( f32* )UseTexMatrix, MAX_TEXTURE_UNITS );
setUniform( USE_TEXTURE_MATRIX, UseTexMatrix, MAX_TEXTURE_UNITS );
//statusOk &= setVertexShaderConstant( "uTextureMatrix", ( f32* )TextureMatrix, MAX_TEXTURE_UNITS * 16 );
setUniform( TEXTURE_MATRIX, TextureMatrix, MAX_TEXTURE_UNITS );
core::matrix4 invWorld;
/* Lights (in Object Space) Upload */
if ( Lighting )
{
u32 cnt = Driver->getDynamicLightCount();
Driver->getTransform( ETS_WORLD ).getInverse( invWorld );
for ( size_t i = 0; i < MAX_LIGHTS; ++i )
{
if ( i < cnt )
{
UseLight[i] = 1;
video::SLight light;
light = Driver->getDynamicLight( i );
switch ( light.Type )
{
case ELT_DIRECTIONAL:
invWorld.rotateVect(( f32* )&LightPosition[i], light.Direction );
LightPosition[i].data[4] = 0.0;
break;
case ELT_SPOT:
invWorld.rotateVect( LightDirection[i], light.Direction );
LightExponent[i] = light.Falloff;
LightCutoff[i] = light.OuterCone;
//no break on purpose !
case ELT_POINT:
invWorld.transformVect(( f32* )&LightPosition[i], light.Position );
LightPosition[i].data[4] = 1.0;
LightAttenuation[i] = light.Attenuation;
break;
default:
UseLight[i] = 0;
break;
}
LightAmbient[i] = light.AmbientColor;
LightDiffuse[i] = light.DiffuseColor;
LightSpecular[i] = light.SpecularColor;
LightAttenuation[i] = light.Attenuation;
}
else
{
UseLight[i] = 0;
}
}
//statusOk &= setVertexShaderConstant( "uLighting", ( f32* ) & Lighting, 1 );
//statusOk &= setVertexShaderConstant( "uUseLight", ( f32* )UseLight, MAX_LIGHTS );
setUniform( USE_LIGHT, UseLight, MAX_LIGHTS );
//statusOk &= setVertexShaderConstant( "uLightPosition", ( f32* )LightPosition, MAX_LIGHTS * 4 );
setUniform( LIGHT_POSITION, LightPosition, MAX_LIGHTS );
//statusOk &= setVertexShaderConstant( "uLightDirection", ( f32* )LightDirection, MAX_LIGHTS * 3 );
setUniform( LIGHT_DIRECTION, LightDirection, MAX_LIGHTS );
//statusOk &= setVertexShaderConstant( "uLightAmbient", ( f32* )LightAmbient, MAX_LIGHTS * 4 );
setUniform( LIGHT_AMBIENT, LightAmbient, MAX_LIGHTS );
//statusOk &= setVertexShaderConstant( "uLightDiffuse", ( f32* )LightDiffuse, MAX_LIGHTS * 4 );
setUniform( LIGHT_DIFFUSE, LightDiffuse, MAX_LIGHTS );
//statusOk &= setVertexShaderConstant( "uLightSpecular", ( f32* )LightSpecular, MAX_LIGHTS * 4 );
setUniform( LIGHT_SPECULAR, LightSpecular, MAX_LIGHTS );
//statusOk &= setVertexShaderConstant( "uLightAttenuation", ( f32* )LightAttenuation, MAX_LIGHTS * 3 );
setUniform( LIGHT_ATTENUATION, LightAttenuation, MAX_LIGHTS );
//statusOk &= setVertexShaderConstant( "uLightExponent", LightExponent, MAX_LIGHTS );
setUniform( LIGHT_EXPONENT, LightExponent, MAX_LIGHTS );
//statusOk &= setVertexShaderConstant( "uLightCutoff", LightCutoff, MAX_LIGHTS );
setUniform( LIGHT_CUTOFF, LightCutoff, MAX_LIGHTS );
AmbientColor = Driver->getAmbientLight();
setUniform( LIGHT_AMBIENT, &AmbientColor );
}
/* Fog */
/* statusOk &= setVertexShaderConstant( "uFog", ( f32* ) & Fog, 1 );
statusOk &= setVertexShaderConstant( "uFogType", ( f32* ) & FogType, 1 );
statusOk &= setVertexShaderConstant( "uFogColor", FogColor, 4 );
statusOk &= setVertexShaderConstant( "uFogStart", &FogStart, 1 );
statusOk &= setVertexShaderConstant( "uFogEnd", &FogEnd, 1 );
statusOk &= setVertexShaderConstant( "uFogDensity", &FogDensity, 1 );*/
/* Clip Plane */
u32 cnt = Driver->getClipPlaneCount();
if ( cnt > 0 )
{
Clip = 1;
ClipPlane = Driver->getClipPlane( 0 );
}
else
{
Clip = 0;
}
/* Eye/Camera Position in ObjectSpace */
if ( Clip || RenderMode == 10 || RenderMode == 11 ) // Need clipping or reflection
{
if ( !Lighting )
Driver->getTransform( ETS_WORLD ).getInverse( invWorld );
core::vector3df viewPos( 0.0f, 0.0f, 0.0f );
core::matrix4 inverseView;
Driver->getTransform( video::ETS_VIEW ).getInverse( inverseView );
inverseView.transformVect( viewPos );
invWorld.transformVect( viewPos );
//setVertexShaderConstant( "uEyePos", &viewPos.X, 3 );
setUniform( EYE_POSITION, &viewPos.X );
}
//statusOk &= setVertexShaderConstant( "uClip", ( f32* ) & Clip );
setUniform( CLIP, &Clip );
//statusOk &= setVertexShaderConstant( "uClipPlane", ( f32* ) & ClipPlane );
setUniform( CLIP_PLANE, &ClipPlane );
//statusOk &= setVertexShaderConstant( "uRenderMode", ( f32* ) & RenderMode );
setUniform( RENDER_MODE, &RenderMode );
//statusOk &= setVertexShaderConstant( "uNormalize", ( f32* ) & Normalize, 1 );
return statusOk ;
};
void COGLES2FixedPipelineShader::setMaterial( const SMaterial &material )
{
if (Fog != static_cast<int>(material.FogEnable))
{
Fog = material.FogEnable;
setUniform( FOG, &Fog );
}
if (Lighting != static_cast<int>(material.Lighting))
{
Lighting = material.Lighting;
setUniform( LIGHTING, &Lighting );
}
if (Normalize != static_cast<float>(material.NormalizeNormals))
{
Normalize = material.NormalizeNormals;
setUniform( NORMALIZE, &Normalize );
}
for ( size_t i = 0; i < MAX_TEXTURE_UNITS; ++i )
{
UseTexture[i] = material.getTexture( i ) != 0;
if ( UseTexture[i] )
{
UseTexMatrix[i] = false;
core::matrix4 texMat = material.getTextureMatrix( i );
if ( !texMat.isIdentity() )
{
UseTexMatrix[i] = true;
memcpy( &TextureMatrix[i], texMat.pointer(), sizeof( mat4 ) );
}
}
}
if ( ColorMaterial != material.ColorMaterial )
{
ColorMaterial = material.ColorMaterial;
setUniform( COLOR_MATERIAL, &ColorMaterial );
}
if ( MaterialAmbient != material.AmbientColor )
{
MaterialAmbient = material.AmbientColor;
setUniform( MATERIAL_AMBIENT, &MaterialAmbient );
}
if ( MaterialEmission != material.EmissiveColor )
{
MaterialEmission = material.EmissiveColor;
setUniform( MATERIAL_EMISSION, &MaterialEmission );
}
if ( MaterialDiffuse != material.DiffuseColor )
{
MaterialDiffuse = material.DiffuseColor;
setUniform( MATERIAL_DIFFUSE, &MaterialDiffuse );
}
if ( MaterialSpecular != material.SpecularColor )
{
MaterialSpecular = material.SpecularColor;
setUniform( MATERIAL_SPECULAR, &MaterialSpecular );
}
if ( MaterialShininess != material.Shininess )
{
MaterialShininess = material.Shininess;
setUniform( MATERIAL_SHININESS, &MaterialShininess );
}
}
}
}
#endif //_IRR_COMPILE_WITH_OGLES2_

View File

@ -0,0 +1,196 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_OGLES2_FIXED_PIPELINE_SHADER_H_INCLUDED__
#define __C_OGLES2_FIXED_PIPELINE_SHADER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2Driver.h"
#include "COGLES2SLMaterialRenderer.h"
#include "EVertexAttributes.h"
namespace irr
{
namespace video
{
#define MAX_LIGHTS 8
#define MAX_TEXTURE_UNITS 4
enum AlphaFunc
{
ALPHA_GREATER = 0
};
class COGLES2FixedPipelineShader : public COGLES2SLMaterialRenderer
{
public:
COGLES2FixedPipelineShader( video::COGLES2Driver* driver, io::IFileSystem* fs );
void updateMatrices();
void bindTexture();
virtual bool OnRender( IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype );
public:
/*void enableNormalize() { Normalize = true; }
void disableNormalize() { Normalize = false; }*/
void enableAlphaTest()
{
AlphaTest = true;
}
void disableAlphaTest()
{
AlphaTest = false;
}
void setAlphaValue( float value )
{
AlphaValue = value;
}
/*void enableLighting() { Lighting = true; }
void disableLighting() { Lighting = false; }
bool isLightingEnabled() { return (Lighting == 1); }*/
void setAmbientLight( const SColorf& color );
void enableFog()
{
Fog = true;
}
void disableFog()
{
Fog = false;
}
bool isFogEnabled()
{
return ( Fog == 1 );
}
void setFog( E_FOG_TYPE type, const SColor& color, f32 start, f32 end, f32 density );
void setMaterial( const SMaterial& material );
void setRenderMode( E_MATERIAL_TYPE mode )
{
RenderMode = mode;
}
void reload();
private:
void initData();
private:
struct vec3
{
float data[3];
};
struct vec4
{
float data[4];
};
struct mat4
{
float data[16];
};
float Normalize;
int TextureUnits[MAX_TEXTURE_UNITS];
int UseTexture[MAX_TEXTURE_UNITS];
mat4 TextureMatrix[MAX_TEXTURE_UNITS];
int UseTexMatrix[MAX_TEXTURE_UNITS];
float AlphaTest;
float AlphaValue;
AlphaFunc AlphaFunction;
int Lighting;
int UseLight[MAX_LIGHTS];
vec4 LightPosition [MAX_LIGHTS];
SColorf LightAmbient [MAX_LIGHTS];
SColorf LightDiffuse [MAX_LIGHTS];
SColorf LightSpecular [MAX_LIGHTS];
core::vector3df LightDirection[MAX_LIGHTS];
core::vector3df LightAttenuation[MAX_LIGHTS];
float LightExponent [MAX_LIGHTS];
float LightCutoff [MAX_LIGHTS];
SColorf AmbientColor;
int Fog;
int FogType;
float FogColor[4];
float FogStart;
float FogEnd;
float FogDensity;
int Clip;
core::plane3df ClipPlane;
u32 ColorMaterial;
SColorf MaterialAmbient;
SColorf MaterialEmission;
SColorf MaterialDiffuse;
SColorf MaterialSpecular;
float MaterialShininess;
E_MATERIAL_TYPE RenderMode;
private :
enum SHADER_UNIFORM
{
RENDER_MODE = 0,
MVP_MATRIX,
WORLD_MATRIX,
NORMALIZE,
EYE_POSITION,
USE_LIGHT,
LIGHT_POSITION,
LIGHT_AMBIENT,
LIGHT_DIFFUSE,
LIGHT_SPECULAR,
LIGHT_DIRECTION,
LIGHT_ATTENUATION,
LIGHT_EXPONENT,
LIGHT_CUTOFF,
AMBIENT_COLOR,
LIGHTING,
MATERIAL_AMBIENT,
MATERIAL_EMISSION,
MATERIAL_DIFFUSE,
MATERIAL_SPECULAR,
MATERIAL_SHININESS,
COLOR_MATERIAL,
USE_TEXTURE,
TEXTURE_MATRIX,
USE_TEXTURE_MATRIX,
CLIP,
CLIP_PLANE,
ALPHA_TEST,
ALPHA_VALUE,
FOG,
FOG_TYPE,
FOG_COLOR,
FOG_START,
FOG_END,
FOG_DENSITY,
TEXTURE_UNIT0,
TEXTURE_UNIT1,
UNIFORM_COUNT
};
static const char* const sBuiltInShaderUniformNames[];
};
}
}
#endif //_IRR_COMPILE_WITH_OGLES2_
#endif //__C_OGLES2_FIXED_PIPELINE_SHADER_H_INCLUDED__

View File

@ -0,0 +1,598 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_OGLES2_MATERIAL_RENDERER_H_INCLUDED__
#define __C_OGLES2_MATERIAL_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2SLMaterialRenderer.h"
#include "COGLES2FixedPipelineShader.h"
namespace irr
{
namespace video
{
//! Base class for all internal OGLES2 material renderers
class COGLES2MaterialRenderer : public IMaterialRenderer
{
public:
//! Constructor
COGLES2MaterialRenderer( video::COGLES2Driver* driver ) :
Driver( driver ),
FixedPipeline( driver->fixedPipeline() )
{
}
virtual bool OnRender( IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype )
{
return FixedPipeline->OnRender( service, vtxtype );
}
protected:
video::COGLES2Driver* Driver;
COGLES2FixedPipelineShader* FixedPipeline;
};
//! Solid material renderer
class COGLES2MaterialRenderer_SOLID : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_SOLID( video::COGLES2Driver* d ) :
COGLES2MaterialRenderer( d )
{
}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
if ( resetAllRenderstates || ( material.MaterialType != lastMaterial.MaterialType ) )
{
FixedPipeline->useProgram();
FixedPipeline->setRenderMode( EMT_SOLID );
}
FixedPipeline->setMaterial( material );
Driver->disableTextures( 1 );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
}
};
//! Generic Texture Blend
class COGLES2MaterialRenderer_ONETEXTURE_BLEND : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_ONETEXTURE_BLEND( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
Driver->disableTextures( 1 );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
FixedPipeline->setMaterial( material );
FixedPipeline->useProgram();
// if (material.MaterialType != lastMaterial.MaterialType ||
// material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
// resetAllRenderstates)
{
E_BLEND_FACTOR srcFact, dstFact;
E_MODULATE_FUNC modulate;
u32 alphaSource;
unpack_texureBlendFunc( srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam );
//TODO : OpenGL ES 2.0 Port glTexEnvf
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
//glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
//glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
//glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
//rgbModulatePreviousTexture
//glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, (f32) modulate );
//glBlendFunc( getGLBlend(srcFact), getGLBlend(dstFact) );
FixedPipeline->enableAlphaTest();
FixedPipeline->setAlphaValue( 0.f );
Driver->enableBlend();
Driver->blendFunc( srcFact, dstFact );
if ( textureBlendFunc_hasAlpha( srcFact ) || textureBlendFunc_hasAlpha( dstFact ) )
{
//TODO : OpenGL ES 2.0 Port glTexEnvf
//glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
//glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
//glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
}
}
}
virtual void OnUnsetMaterial()
{
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 1.f );
//glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
Driver->disableBlend();
FixedPipeline->disableAlphaTest();
}
//! Returns if the material is transparent.
/** Is not always transparent, but mostly. */
virtual bool isTransparent() const
{
return true;
}
};
//! Solid 2 layer material renderer
class COGLES2MaterialRenderer_SOLID_2_LAYER : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_SOLID_2_LAYER( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
Driver->disableTextures( 2 );
Driver->setTexture( 1, material.getTexture( 1 ) );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates )
{
if ( Driver->queryFeature( EVDF_MULTITEXTURE ) )
{
//Driver->extGlActiveTexture(GL_TEXTURE1);
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
//glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
//glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR);
//glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
//glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
//glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
//glTexEnvf(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PRIMARY_COLOR);
//glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
}
}
}
virtual void OnUnsetMaterial()
{
if ( Driver->queryFeature( EVDF_MULTITEXTURE ) )
{
//Driver->extGlActiveTexture(GL_TEXTURE1);
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
//Driver->extGlActiveTexture(GL_TEXTURE0);
}
}
};
//! Transparent add color material renderer
class COGLES2MaterialRenderer_TRANSPARENT_ADD_COLOR : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_TRANSPARENT_ADD_COLOR( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
if (( material.MaterialType != lastMaterial.MaterialType ) || resetAllRenderstates )
{
Driver->blendFunc( EBF_ONE, EBF_ONE_MINUS_SRC_COLOR );
Driver->enableBlend();
FixedPipeline->useProgram();
FixedPipeline->setRenderMode( EMT_SOLID );
}
FixedPipeline->setMaterial( material );
Driver->disableTextures( 1 );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
}
virtual void OnUnsetMaterial()
{
Driver->disableBlend();
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
//! Transparent vertex alpha material renderer
class COGLES2MaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_TRANSPARENT_VERTEX_ALPHA( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates )
{
Driver->blendFunc( EBF_ONE, EBF_ONE_MINUS_SRC_ALPHA );
Driver->enableBlend();
FixedPipeline->useProgram();
FixedPipeline->setRenderMode( EMT_TRANSPARENT_VERTEX_ALPHA );
}
FixedPipeline->setMaterial( material );
Driver->disableTextures( 1 );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
}
virtual void OnUnsetMaterial()
{
Driver->disableBlend();
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
//! Transparent alpha channel material renderer
class COGLES2MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
Driver->disableTextures( 1 );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates
|| material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
{
Driver->blendFunc( EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA );
Driver->enableBlend();
FixedPipeline->useProgram();
FixedPipeline->setMaterial( material );
FixedPipeline->enableAlphaTest();
FixedPipeline->setAlphaValue( material.MaterialTypeParam );
FixedPipeline->setRenderMode( EMT_TRANSPARENT_ALPHA_CHANNEL );
}
}
virtual void OnUnsetMaterial()
{
FixedPipeline->disableAlphaTest();
Driver->disableBlend();
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
//! Transparent alpha channel material renderer
class COGLES2MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
Driver->disableTextures( 1 );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates )
{
FixedPipeline->enableAlphaTest();
FixedPipeline->setAlphaValue( 0.5f );
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
}
virtual void OnUnsetMaterial()
{
FixedPipeline->disableAlphaTest();
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return false; // this material is not really transparent because it does no blending.
}
};
//! material renderer for all kinds of lightmaps
class COGLES2MaterialRenderer_LIGHTMAP : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_LIGHTMAP( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates )
{
FixedPipeline->useProgram();
FixedPipeline->setRenderMode( EMT_LIGHTMAP );
}
FixedPipeline->setMaterial( material );
Driver->disableTextures( 2 );
Driver->setTexture( 1, material.getTexture( 1 ) );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates )
{
// diffuse map
switch ( material.MaterialType )
{
case EMT_LIGHTMAP_LIGHTING:
case EMT_LIGHTMAP_LIGHTING_M2:
case EMT_LIGHTMAP_LIGHTING_M4:
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
break;
case EMT_LIGHTMAP_ADD:
case EMT_LIGHTMAP:
case EMT_LIGHTMAP_M2:
case EMT_LIGHTMAP_M4:
default:
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
break;
}
if ( Driver->queryFeature( EVDF_MULTITEXTURE ) )
{
// lightmap
//Driver->extGlActiveTexture(GL_TEXTURE1);
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
if ( material.MaterialType == EMT_LIGHTMAP_ADD )
{
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED);
}
else
{
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
}
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
//glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
//glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
//glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
//glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS);
switch ( material.MaterialType )
{
case EMT_LIGHTMAP_M4:
case EMT_LIGHTMAP_LIGHTING_M4:
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 4.0f);
break;
case EMT_LIGHTMAP_M2:
case EMT_LIGHTMAP_LIGHTING_M2:
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 2.0f);
break;
default:
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 1.0f);
break;
}
}
}
}
virtual void OnUnsetMaterial()
{
if ( Driver->queryFeature( EVDF_MULTITEXTURE ) )
{
//Driver->extGlActiveTexture(GL_TEXTURE1);
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 1.f );
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//Driver->extGlActiveTexture(GL_TEXTURE0);
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
}
};
//! detail map material renderer
class COGLES2MaterialRenderer_DETAIL_MAP : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_DETAIL_MAP( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates )
{
FixedPipeline->useProgram();
FixedPipeline->setRenderMode( EMT_DETAIL_MAP );
}
FixedPipeline->setMaterial( material );
Driver->disableTextures( 2 );
Driver->setTexture( 1, material.getTexture( 1 ) );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
}
};
//! sphere map material renderer
class COGLES2MaterialRenderer_SPHERE_MAP : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_SPHERE_MAP( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates )
{
FixedPipeline->useProgram();
FixedPipeline->setRenderMode( EMT_SPHERE_MAP );
}
FixedPipeline->setMaterial( material );
Driver->disableTextures( 1 );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
}
virtual void OnUnsetMaterial()
{
}
};
//! reflection 2 layer material renderer
class COGLES2MaterialRenderer_REFLECTION_2_LAYER : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_REFLECTION_2_LAYER( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates )
{
FixedPipeline->useProgram();
FixedPipeline->setRenderMode( EMT_REFLECTION_2_LAYER );
}
FixedPipeline->setMaterial( material );
Driver->disableTextures( 2 );
Driver->setTexture( 0, material.getTexture( 1 ) );
Driver->setTexture( 1, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
}
};
//! reflection 2 layer material renderer
class COGLES2MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public COGLES2MaterialRenderer
{
public:
COGLES2MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER( video::COGLES2Driver* d )
: COGLES2MaterialRenderer( d ) {}
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services )
{
Driver->disableTextures( 2 );
Driver->setTexture( 1, material.getTexture( 1 ) );
Driver->setTexture( 0, material.getTexture( 0 ) );
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates )
{
if ( Driver->queryFeature( EVDF_MULTITEXTURE ) )
{
//Driver->extGlActiveTexture(GL_TEXTURE1);
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
//glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
//glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
//glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
}
// glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
// glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
// glEnable(GL_TEXTURE_GEN_S);
// glEnable(GL_TEXTURE_GEN_T);
Driver->blendFunc( EBF_ONE, EBF_ONE_MINUS_SRC_ALPHA );
Driver->enableBlend();
}
}
virtual void OnUnsetMaterial()
{
if ( Driver->queryFeature( EVDF_MULTITEXTURE ) )
{
//Driver->extGlActiveTexture(GL_TEXTURE1);
//TODO : OpenGL ES 2.0 Port glTexEnv
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
// glDisable(GL_TEXTURE_GEN_S);
// glDisable(GL_TEXTURE_GEN_T);
if ( Driver->queryFeature( EVDF_MULTITEXTURE ) )
{
//Driver->extGlActiveTexture(GL_TEXTURE0);
}
Driver->disableBlend();
}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
} // end namespace video
} // end namespace irr
#endif
#endif

View File

@ -0,0 +1,163 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2NormalMapRenderer.h"
#include "IGPUProgrammingServices.h"
#include "IShaderConstantSetCallBack.h"
#include "IVideoDriver.h"
#include "os.h"
#include "COGLES2Driver.h"
#include "COGLES2Utils.h"
#define MAX_LIGHTS 2
namespace irr
{
namespace video
{
const char* const COGLES2NormalMapRenderer::sBuiltInShaderUniformNames[] =
{
"uMvpMatrix",
"uLightPos",
"uLightColor",
"texture0",
"texture1",
0
};
// Irrlicht Engine OGLES2 render path normal map vertex shader
const c8 VertexShaderFile[] = "../../media/Shaders/COGLES2NormalMap.vsh";
const c8 FragmentShaderFile[] = "../../media/Shaders/COGLES2NormalMap.fsh";
//! Constructor
COGLES2NormalMapRenderer::COGLES2NormalMapRenderer( video::COGLES2Driver* driver,
io::IFileSystem* fs, s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial )
: COGLES2SLMaterialRenderer( driver, fs, 0, baseMaterial, sBuiltInShaderUniformNames, UNIFORM_COUNT ), CompiledShaders( true )
{
#ifdef _DEBUG
setDebugName( "COGLES2NormalMapRenderer" );
#endif
// set this as callback. We could have done this in
// the initialization list, but some compilers don't like it.
CallBack = this;
// check if already compiled normal map shaders are there.
video::IMaterialRenderer* renderer = driver->getMaterialRenderer( EMT_NORMAL_MAP_SOLID );
if ( renderer )
{
// use the already compiled shaders
video::COGLES2NormalMapRenderer* nmr = reinterpret_cast<video::COGLES2NormalMapRenderer*>( renderer );
CompiledShaders = false;
Program = nmr->Program;
UniformInfo = nmr->UniformInfo;
AttributeInfo = nmr->AttributeInfo;
outMaterialTypeNr = driver->addMaterialRenderer( this );
}
else
{
// compile shaders on our own
initFromFiles( outMaterialTypeNr, VertexShaderFile, FragmentShaderFile );
useProgram();
int dummy = 0;
setUniform( TEXTURE_UNIT0, &dummy );
dummy = 1;
setUniform( TEXTURE_UNIT1, &dummy );
}
// fallback if compilation has failed
if ( -1 == outMaterialTypeNr )
outMaterialTypeNr = driver->addMaterialRenderer( this );
}
COGLES2NormalMapRenderer::~COGLES2NormalMapRenderer()
{
if ( CallBack == this )
CallBack = 0;
if ( !CompiledShaders )
{
// prevent this from deleting shaders we did not create
Program = 0;
}
}
//! Returns the render capability of the material.
s32 COGLES2NormalMapRenderer::getRenderCapability() const
{
if ( Driver->queryFeature( video::EVDF_ARB_FRAGMENT_PROGRAM_1 ) &&
Driver->queryFeature( video::EVDF_ARB_VERTEX_PROGRAM_1 ) )
return 0;
return 1;
}
//! Called by the engine when the vertex and/or pixel shader constants for an
//! material renderer should be set.
void COGLES2NormalMapRenderer::OnSetConstants( IMaterialRendererServices* services, s32 userData )
{
video::IVideoDriver* driver = services->getVideoDriver();
// set transposed worldViewProj matrix
core::matrix4 worldViewProj( driver->getTransform( video::ETS_PROJECTION ) );
worldViewProj *= driver->getTransform( video::ETS_VIEW );
worldViewProj *= driver->getTransform( video::ETS_WORLD );
setUniform( MVP_MATRIX, worldViewProj.pointer() );
// here we fetch the fixed function lights from the driver
// and set them as constants
u32 cnt = driver->getDynamicLightCount();
// Load the inverse world matrix.
core::matrix4 invWorldMat;
driver->getTransform( video::ETS_WORLD ).getInverse( invWorldMat );
float lightPosition[4*MAX_LIGHTS];
float lightColor[4*MAX_LIGHTS];
for ( u32 i = 0; i < MAX_LIGHTS; ++i )
{
video::SLight light;
if ( i < cnt )
light = driver->getDynamicLight( i );
else
{
light.DiffuseColor.set( 0, 0, 0 ); // make light dark
light.Radius = 1.0f;
}
light.DiffuseColor.a = 1.0f / ( light.Radius * light.Radius ); // set attenuation
// Transform the light by the inverse world matrix to get it into object space.
invWorldMat.transformVect( light.Position );
memcpy( lightPosition + i*4, &light.Position, sizeof( float )*4 );
memcpy( lightColor + i*4, &light.DiffuseColor, sizeof( float )*4 );
}
setUniform( LIGHT_POSITION, lightPosition, MAX_LIGHTS );
setUniform( LIGHT_COLOR, lightColor, MAX_LIGHTS );
}
} // end namespace video
} // end namespace irr
#endif

View File

@ -0,0 +1,62 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_OGLES2_NORMAL_MAP_RENDERER_H_INCLUDED__
#define __C_OGLES2_NORMAL_MAP_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2SLMaterialRenderer.h"
#include "IShaderConstantSetCallBack.h"
namespace irr
{
namespace video
{
//! Class for rendering normal maps with OGLES2
class COGLES2NormalMapRenderer : public COGLES2SLMaterialRenderer, public IShaderConstantSetCallBack
{
public:
//! Constructor
COGLES2NormalMapRenderer( video::COGLES2Driver* driver, io::IFileSystem* fs,
s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial );
//! Destructor
virtual ~COGLES2NormalMapRenderer();
//! Called by the engine when the vertex and/or pixel shader constants for an
//! material renderer should be set.
virtual void OnSetConstants( IMaterialRendererServices* services, s32 userData );
//! Returns the render capability of the material.
virtual s32 getRenderCapability() const;
protected:
bool CompiledShaders;
private:
enum SHADER_UNIFORM
{
MVP_MATRIX = 0,
LIGHT_POSITION,
LIGHT_COLOR,
TEXTURE_UNIT0,
TEXTURE_UNIT1,
UNIFORM_COUNT
};
static const char* const sBuiltInShaderUniformNames[];
};
} // end namespace video
} // end namespace irr
#endif
#endif

View File

@ -0,0 +1,190 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2ParallaxMapRenderer.h"
#include "COGLES2Driver.h"
#include "IGPUProgrammingServices.h"
#include "IShaderConstantSetCallBack.h"
#include "IVideoDriver.h"
#include "os.h"
#define MAX_LIGHTS 2
namespace irr
{
namespace video
{
const char * const COGLES2ParallaxMapRenderer::sBuiltInShaderUniformNames[] =
{
"uMvpMatrix",
"uLightPos",
"uLightColor",
"uEyePos",
"texture0",
"texture1",
"uLightDiffuse",
"uHeightScale",
0
};
// Irrlicht Engine OGLES2 render path normal map vertex shader
const c8 VertexShaderFile[] = "../../media/Shaders/COGLES2ParallaxMap.vsh";
const c8 FragmentShaderFile[] = "../../media/Shaders/COGLES2ParallaxMap.fsh";
//! Constructor
COGLES2ParallaxMapRenderer::COGLES2ParallaxMapRenderer( video::COGLES2Driver* driver,
io::IFileSystem* fs, s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial )
: COGLES2SLMaterialRenderer( driver, fs, 0, baseMaterial, sBuiltInShaderUniformNames, UNIFORM_COUNT ), CompiledShaders( true )
{
#ifdef _DEBUG
setDebugName( "COGLES2ParallaxMapRenderer" );
#endif
// set this as callback. We could have done this in
// the initialization list, but some compilers don't like it.
CallBack = this;
// basically, this simply compiles the hard coded shaders if the
// hardware is able to do them, otherwise it maps to the base material
// check if already compiled normal map shaders are there.
video::IMaterialRenderer* renderer = driver->getMaterialRenderer( EMT_PARALLAX_MAP_SOLID );
if ( renderer )
{
// use the already compiled shaders
video::COGLES2ParallaxMapRenderer* pmr = reinterpret_cast<video::COGLES2ParallaxMapRenderer*>( renderer );
CompiledShaders = false;
Program = pmr->Program;
UniformInfo = pmr->UniformInfo;
AttributeInfo = pmr->AttributeInfo;
outMaterialTypeNr = driver->addMaterialRenderer( this );
}
else
{
// compile shaders on our own
initFromFiles( outMaterialTypeNr, VertexShaderFile, FragmentShaderFile );
useProgram();
int dummy = 0;
setUniform( TEXTURE_UNIT0, &dummy );
dummy = 1;
setUniform( TEXTURE_UNIT1, &dummy );
}
// fallback if compilation has failed
if ( -1 == outMaterialTypeNr )
outMaterialTypeNr = driver->addMaterialRenderer( this );
}
//! Destructor
COGLES2ParallaxMapRenderer::~COGLES2ParallaxMapRenderer()
{
if ( CallBack == this )
CallBack = 0;
if ( !CompiledShaders )
{
// prevent this from deleting shaders we did not create
Program = 0;
}
}
void COGLES2ParallaxMapRenderer::OnSetMaterial( const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates, video::IMaterialRendererServices* services )
{
COGLES2SLMaterialRenderer::OnSetMaterial( material, lastMaterial,
resetAllRenderstates, services );
CurrentScale = material.MaterialTypeParam;
}
//! Called by the engine when the vertex and/or pixel shader constants for an
//! material renderer should be set.
void COGLES2ParallaxMapRenderer::OnSetConstants( IMaterialRendererServices* services, s32 userData )
{
video::IVideoDriver* driver = services->getVideoDriver();
// set transposed worldViewProj matrix
core::matrix4 worldViewProj( driver->getTransform( video::ETS_PROJECTION ) );
worldViewProj *= driver->getTransform( video::ETS_VIEW );
worldViewProj *= driver->getTransform( video::ETS_WORLD );
setUniform( MVP_MATRIX, worldViewProj.pointer() );
// here we fetch the fixed function lights from the driver
// and set them as constants
u32 cnt = driver->getDynamicLightCount();
// Load the inverse world matrix.
core::matrix4 invWorldMat;
driver->getTransform( video::ETS_WORLD ).getInverse( invWorldMat );
float lightPosition[4*MAX_LIGHTS];
float lightColor[4*MAX_LIGHTS];
for ( u32 i = 0; i < 2; ++i )
{
video::SLight light;
if ( i < cnt )
light = driver->getDynamicLight( i );
else
{
light.DiffuseColor.set( 0, 0, 0 ); // make light dark
light.Radius = 1.0f;
}
light.DiffuseColor.a = 1.0f / ( light.Radius * light.Radius ); // set attenuation
// Transform the light by the inverse world matrix to get it into object space.
invWorldMat.transformVect( light.Position );
memcpy( lightPosition + i*4, &light.Position, sizeof( float )*4 );
memcpy( lightColor + i*4, &light.DiffuseColor, sizeof( float )*4 );
}
setUniform( LIGHT_POSITION, lightPosition, MAX_LIGHTS );
setUniform( LIGHT_COLOR, lightColor, MAX_LIGHTS );
// Obtain the view position by transforming 0,0,0 by the inverse view matrix
// and then multiply this by the inverse world matrix.
core::vector3df viewPos( 0.0f, 0.0f, 0.0f );
core::matrix4 inverseView;
driver->getTransform( video::ETS_VIEW ).getInverse( inverseView );
inverseView.transformVect( viewPos );
invWorldMat.transformVect( viewPos );
setUniform( EYE_POSITION, &viewPos.X );
// set scale factor
f32 factor = 0.02f; // default value
if ( CurrentScale != 0.0f )
factor = CurrentScale;
setUniform( HEIGHT_SCALE, &factor );
}
} // end namespace video
} // end namespace irr
#endif

View File

@ -0,0 +1,69 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_OGLES2_PARALLAX_MAP_RENDERER_H_INCLUDED__
#define __C_OGLES2_PARALLAX_MAP_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2SLMaterialRenderer.h"
#include "IShaderConstantSetCallBack.h"
namespace irr
{
namespace video
{
//! Class for rendering normal maps with OGLES2
class COGLES2ParallaxMapRenderer : public COGLES2SLMaterialRenderer, public IShaderConstantSetCallBack
{
public:
//! Constructor
COGLES2ParallaxMapRenderer( video::COGLES2Driver* driver, io::IFileSystem* fs,
s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial );
//! Destructor
virtual ~COGLES2ParallaxMapRenderer();
//! Called by the engine when the vertex and/or pixel shader constants for an
//! material renderer should be set.
virtual void OnSetConstants( IMaterialRendererServices* services, s32 userData );
virtual void OnSetMaterial( const SMaterial& material ) { }
virtual void OnSetMaterial( const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates, video::IMaterialRendererServices* services );
protected:
bool CompiledShaders;
f32 CurrentScale;
private:
enum SHADER_UNIFORM
{
MVP_MATRIX = 0,
LIGHT_POSITION,
LIGHT_COLOR,
EYE_POSITION,
TEXTURE_UNIT0,
TEXTURE_UNIT1,
LIGHT_DIFFUSE,
HEIGHT_SCALE,
UNIFORM_COUNT
};
static const char* const sBuiltInShaderUniformNames[];
};
} // end namespace video
} // end namespace irr
#endif
#endif

View File

@ -0,0 +1,80 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "COGLES2Renderer2D.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
namespace irr
{
namespace video
{
const char* const COGLES2Renderer2d::sBuiltInShaderUniformNames[] =
{
"uOrthoMatrix",
"uUseTexture",
"uTextureUnit",
"uAlphaTest",
"uAlphaValue",
0
};
static const char* vertexShaderFile = "../../media/Shaders/COGLES2Renderer2D.vsh";
static const char* fragmentShaderFile = "../../media/Shaders/COGLES2Renderer2D.fsh";
COGLES2Renderer2d::COGLES2Renderer2d( irr::video::COGLES2Driver *driver, irr::io::IFileSystem *fs )
: COGLES2SLMaterialRenderer( driver, fs, 0, 0, sBuiltInShaderUniformNames, UNIFORM_COUNT )
{
#ifdef _DEBUG
setDebugName( "COGLES2Renderer2d" );
#endif
s32 dummy = -1;
initFromFiles( dummy, vertexShaderFile, fragmentShaderFile, false );
useProgram();
int texUnit = 0;
setUniform( TEXTURE_UNIT, &texUnit );
}
void COGLES2Renderer2d::useTexture( bool param )
{
if ( param != UseTexture )
{
UseTexture = param;
int dummy = param ? 1 : 0;
setUniform( USE_TEXTURE, &dummy );
}
}
void COGLES2Renderer2d::useAlphaTest( bool param )
{
if ( param != UseAlphaTest )
{
UseAlphaTest = param;
int dummy = param ? 1 : 0;
setUniform( ALPHA_TEST, &dummy );
}
}
void COGLES2Renderer2d::setAlphaTestValue( float value )
{
if ( value != AlphaTestValue )
{
AlphaTestValue = value;
setUniform( ALPHA_VALUE, &AlphaTestValue );
}
}
void COGLES2Renderer2d::setOrthoMatrix( const core::matrix4 &matrix )
{
if ( matrix != OrthoMatrix )
{
OrthoMatrix = matrix;
setUniform( ORTHO_MATRIX, OrthoMatrix.pointer() );
}
}
}
}
#endif

View File

@ -0,0 +1,54 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_OGLES2_RENDERER_2D_H_INCLUDED__
#define __C_OGLES2_RENDERER_2D_H_INCLUDED__
#include "COGLES2SLMaterialRenderer.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
namespace irr
{
namespace io
{
class IFileSystem;
}
namespace video
{
class COGLES2Driver;
class COGLES2Renderer2d : public COGLES2SLMaterialRenderer
{
public:
COGLES2Renderer2d( COGLES2Driver* driver, io::IFileSystem* fs );
virtual ~COGLES2Renderer2d() {};
void useTexture( bool param );
void useAlphaTest( bool param );
void setAlphaTestValue( float param );
void setOrthoMatrix( const core::matrix4& matrix );
private :
bool UseTexture;
bool UseAlphaTest;
float AlphaTestValue;
core::matrix4 OrthoMatrix;
private:
enum SHADER_UNIFORM
{
ORTHO_MATRIX = 0,
USE_TEXTURE,
TEXTURE_UNIT,
ALPHA_TEST,
ALPHA_VALUE,
UNIFORM_COUNT
};
static const char* const sBuiltInShaderUniformNames[];
};
}
}
#endif
#endif

View File

@ -0,0 +1,545 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2SLMaterialRenderer.h"
#include "IGPUProgrammingServices.h"
#include "IShaderConstantSetCallBack.h"
#include "IMaterialRendererServices.h"
#include "IVideoDriver.h"
#include "os.h"
#include "COGLES2Driver.h"
#include "EVertexAttributes.h"
#include "COGLES2Texture.h"
#include <GLES2/gl2.h>
namespace irr
{
namespace video
{
//! Constructor
COGLES2SLMaterialRenderer::COGLES2SLMaterialRenderer( video::COGLES2Driver* driver,
s32& outMaterialTypeNr, const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback,
video::IMaterialRenderer* baseMaterial,
s32 userData )
: Driver( driver ), CallBack( callback ), BaseMaterial( baseMaterial ), FileSystem( 0 ),
Program( 0 ), UserData( userData ), UniformStringTable( 0 ), UniformCount( 0 )
{
#ifdef _DEBUG
setDebugName( "COGLES2SLMaterialRenderer" );
#endif
//entry points must always be main, and the compile target isn't selectable
//it is fine to ignore what has been asked for, as the compiler should spot anything wrong
//just check that GLSL is available
if ( BaseMaterial )
BaseMaterial->grab();
if ( CallBack )
CallBack->grab();
init( outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram );
}
//! constructor only for use by derived classes who want to
//! create a fall back material for example.
COGLES2SLMaterialRenderer::COGLES2SLMaterialRenderer( COGLES2Driver* driver,
io::IFileSystem* fs,
IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial,
const char* const * uniformStringTable,
const u32& uniformCount,
s32 userData )
: Driver( driver ), CallBack( callback ), BaseMaterial( baseMaterial ), FileSystem( fs ),
Program( 0 ), UserData( userData ), UniformStringTable( uniformStringTable ),
UniformCount( uniformCount )
{
if ( BaseMaterial )
BaseMaterial->grab();
if ( CallBack )
CallBack->grab();
}
//! Destructor
COGLES2SLMaterialRenderer::~COGLES2SLMaterialRenderer()
{
if ( CallBack )
CallBack->drop();
if ( Program )
{
glDeleteProgram( Program );
Program = 0;
}
UniformInfo.clear();
AttributeInfo.clear();
if ( BaseMaterial )
BaseMaterial->drop();
}
void COGLES2SLMaterialRenderer::init( s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
bool registerMaterial )
{
outMaterialTypeNr = -1;
if ( Program == 0 && !createProgram() )
return;
if ( vertexShaderProgram )
if ( !createShader( GL_VERTEX_SHADER, vertexShaderProgram, "" ) )
return;
if ( pixelShaderProgram )
if ( !createShader( GL_FRAGMENT_SHADER, pixelShaderProgram, "" ) )
return;
if ( !linkProgram() )
return;
// register myself as new material
if ( registerMaterial )
outMaterialTypeNr = Driver->addMaterialRenderer( this );
}
void COGLES2SLMaterialRenderer::initFromFiles( s32 &outMaterialTypeNr,
const c8 *vertexShaderFile,
const c8 *pixelShaderFile,
bool registerMaterial )
{
if ( !createProgram() )
{
os::Printer::log( "Could not create shader program.", ELL_ERROR );
}
if ( !readVertexShader( vertexShaderFile ) )
{
os::Printer::log( "Error reading fixed pipeline vertex shader.", ELL_ERROR );
}
if ( !readFragmentShader( pixelShaderFile ) )
{
os::Printer::log( "Error reading fixed pipeline fragment shader.", ELL_ERROR );
}
for ( size_t i = 0; i < EVA_COUNT; ++i )
glBindAttribLocation( Program, i, sBuiltInVertexAttributeNames[i] );
if ( !linkProgram() )
{
os::Printer::log( "Error linking fixed pipeline shader program.", ELL_ERROR );
}
if ( registerMaterial )
outMaterialTypeNr = Driver->addMaterialRenderer( this );
}
void COGLES2SLMaterialRenderer::reloadFromFiles( const c8 *vertexShaderFile,
const c8 *pixelShaderFile )
{
GLsizei shaderCount;
GLuint shaderHandles[2];
glGetAttachedShaders( Program, 2, &shaderCount, shaderHandles );
glDetachShader( Program, shaderHandles[0] );
glDeleteShader( shaderHandles[0] );
glDetachShader( Program, shaderHandles[1] );
glDeleteShader( shaderHandles[1] );
if ( !readVertexShader( vertexShaderFile ) )
{
os::Printer::log( "Error reading fixed pipeline vertex shader.", ELL_ERROR );
}
if ( !readFragmentShader( pixelShaderFile ) )
{
os::Printer::log( "Error reading fixed pipeline fragment shader.", ELL_ERROR );
}
if ( !linkProgram() )
{
os::Printer::log( "Error linking fixed pipeline shader program.", ELL_ERROR );
}
}
bool COGLES2SLMaterialRenderer::readShader( GLenum shaderType, const c8* shaderFile )
{
wchar_t buf[512];
io::IReadFile* file = 0;
file = FileSystem->createAndOpenFile( shaderFile );
if ( !file )
{
swprintf( buf, 512, L"Could not open shader file : %S", shaderFile );
os::Printer::log( buf, ELL_ERROR );
return false;
}
const long size = file->getSize();
if ( !size )
{
swprintf( buf, 512, L"%S shader file is empty", shaderFile );
os::Printer::log( buf, ELL_ERROR );
file->drop();
return false;
}
c8* shader = new c8[size+1];
file->read( shader, size );
shader[size] = 0;
bool success = createShader( shaderType, shader, shaderFile );
file->drop();
delete shader;
return success;
}
bool COGLES2SLMaterialRenderer::readVertexShader( const c8 *vertexShaderFile )
{
return readShader( GL_VERTEX_SHADER, vertexShaderFile );
}
bool COGLES2SLMaterialRenderer::readFragmentShader( const c8 *fragmentShaderFile )
{
return readShader( GL_FRAGMENT_SHADER, fragmentShaderFile );
}
bool COGLES2SLMaterialRenderer::OnRender( IMaterialRendererServices* service,
E_VERTEX_TYPE vtxtype )
{
// call callback to set shader constants and attributes
if ( CallBack && Program )
{
CallBack->OnSetAttribute( this, UserData );
CallBack->OnSetConstants( this, UserData );
}
return true;
}
bool COGLES2SLMaterialRenderer::PostRender( IMaterialRendererServices* service,
E_VERTEX_TYPE vtxtype )
{
// call callback to unset shader attributes
if ( CallBack && Program )
CallBack->OnUnSetAttribute( this, UserData );
return true;
}
void COGLES2SLMaterialRenderer::OnSetMaterial( const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates,
video::IMaterialRendererServices* services )
{
if ( material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates )
{
if ( Program )
glUseProgram( Program );
//let callback know used material
if ( CallBack )
CallBack->OnSetMaterial( material );
}
//if (BaseMaterial)
//BaseMaterial->OnSetMaterial(material, material, true, this);
//for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
// Driver->setActiveTexture(i, material.getTexture(i));
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
}
void COGLES2SLMaterialRenderer::OnUnsetMaterial()
{
glUseProgram( 0 );
//if (BaseMaterial)
// BaseMaterial->OnUnsetMaterial();
}
//! Returns if the material is transparent.
bool COGLES2SLMaterialRenderer::isTransparent() const
{
return BaseMaterial ? BaseMaterial->isTransparent() : false;
}
bool COGLES2SLMaterialRenderer::createProgram()
{
Program = glCreateProgram();
return true;
}
bool COGLES2SLMaterialRenderer::createShader( GLenum shaderType, const char* shader, const char* shaderFile )
{
GLuint shaderHandle = glCreateShader( shaderType );
os::Printer::log("Loading shader", shaderFile);
glShaderSource( shaderHandle, 1, &shader, NULL );
glCompileShader( shaderHandle );
int status = 0;
glGetShaderiv( shaderHandle, GL_COMPILE_STATUS, &status );
if ( !status )
{
wchar_t buf[512];
swprintf( buf, 512, L"GLSL shader failed to compile : %S", shaderFile );
os::Printer::log( buf, ELL_ERROR );
// check error message and log it
int maxLength = 0;
GLsizei length;
glGetShaderiv( shaderHandle, GL_INFO_LOG_LENGTH, &maxLength );
char *pInfoLog = new char[maxLength];
glGetShaderInfoLog( shaderHandle, maxLength, &length, pInfoLog );
os::Printer::log( reinterpret_cast<const c8*>( pInfoLog ), ELL_ERROR );
delete [] pInfoLog;
return false;
}
glAttachShader( Program, shaderHandle );
return true;
}
bool COGLES2SLMaterialRenderer::linkProgram()
{
glLinkProgram( Program );
int status = 0;
glGetProgramiv( Program, GL_LINK_STATUS, &status );
if ( !status )
{
os::Printer::log( "GLSL shader program failed to link", ELL_ERROR );
// check error message and log it
int maxLength = 0;
GLsizei length;
glGetProgramiv( Program, GL_INFO_LOG_LENGTH, &maxLength );
char *pInfoLog = new char[maxLength];
glGetProgramInfoLog( Program, maxLength, &length, pInfoLog );
os::Printer::log( reinterpret_cast<const c8*>( pInfoLog ), ELL_ERROR );
delete [] pInfoLog;
return false;
}
// get uniforms information
int num = 0;
glGetProgramiv( Program, GL_ACTIVE_UNIFORMS, &num );
int maxlen = 0;
glGetProgramiv( Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlen );
if ( maxlen == 0 && num != 0 )
{
os::Printer::log( "GLSL: failed to retrieve uniform information", ELL_ERROR );
return false;
}
c8 *buf = new c8[maxlen];
UniformInfo.clear();
UniformInfo.reallocate( num );
core::array<core::stringc> names( num );
core::array<SUniformInfo> uni( num );
for ( int i = 0; i < num; ++i )
{
memset( buf, 0, maxlen );
GLint size;
SUniformInfo ui;
glGetActiveUniform( Program, i, maxlen, 0, &size, &ui.type, reinterpret_cast<char*>( buf ) );
ui.location = glGetUniformLocation( Program, buf );
uni.push_back( ui );
names.push_back( buf );
}
delete [] buf;
for ( int i = 0; i < UniformCount; ++i )
{
int j;
for ( j = 0; j < num; ++j )
{
if ( names[j] == UniformStringTable[i] )
break;
}
if ( j < num )
{
UniformInfo.push_back( uni[j] );
}
else
{
wchar_t buf[512];
swprintf( buf, 512, L"Unable to find uniform : %S", UniformStringTable[i] );
os::Printer::log( buf, ELL_WARNING );
SUniformInfo blank;
blank.location = -1;
blank.type = GL_INVALID_ENUM;
UniformInfo.push_back( blank );
}
}
return true;
}
void COGLES2SLMaterialRenderer::setBasicRenderStates( const SMaterial& material,
const SMaterial& lastMaterial,
bool resetAllRenderstates )
{
// forward
Driver->setBasicRenderStates( material, lastMaterial, resetAllRenderstates );
}
bool COGLES2SLMaterialRenderer::setVertexShaderConstant( const c8* name, const f32* floats, int count )
{
return setPixelShaderConstant( name, floats, count );
}
void COGLES2SLMaterialRenderer::setVertexShaderConstant( const f32* data, s32 startRegister, s32 constantAmount )
{
os::Printer::log( "Cannot set constant, please use high level shader call instead.", ELL_WARNING );
}
bool COGLES2SLMaterialRenderer::setVertexShaderPointer( const c8* name, const void* pointer,
s32 size, bool normalized, u16 stride )
{
os::Printer::log( "Cannot set constant, use high level shader call.", ELL_WARNING );
return false;
}
void COGLES2SLMaterialRenderer::enableVertexShaderPointer( const c8* name )
{
os::Printer::log( "Cannot set constant, use high level shader call.", ELL_WARNING );
}
void COGLES2SLMaterialRenderer::disableVertexShaderPointer( const c8* name )
{
os::Printer::log( "Cannot set constant, use high level shader call.", ELL_WARNING );
}
bool COGLES2SLMaterialRenderer::setPixelShaderConstant( const c8* name, const f32* floats, int count )
{
os::Printer::log( "Cannot set constant, use high level shader call.", ELL_WARNING );
return false;
}
bool COGLES2SLMaterialRenderer::setUniform( int index, const void* data, int count )
{
SUniformInfo& ui = UniformInfo[index];
if ( ui.location == -1 )
return false;
switch ( ui.type )
{
case GL_FLOAT:
glUniform1fv( ui.location, count, static_cast<const GLfloat*>( data ) );
break;
case GL_FLOAT_VEC2:
glUniform2fv( ui.location, count, static_cast<const GLfloat*>( data ) );
break;
case GL_FLOAT_VEC3:
glUniform3fv( ui.location, count, static_cast<const GLfloat*>( data ) );
break;
case GL_FLOAT_VEC4:
glUniform4fv( ui.location, count, static_cast<const GLfloat*>( data ) );
break;
case GL_FLOAT_MAT2:
glUniformMatrix2fv( ui.location, count, false, static_cast<const GLfloat*>( data ) );
break;
case GL_FLOAT_MAT3:
glUniformMatrix3fv( ui.location, count, false, static_cast<const GLfloat*>( data ) );
break;
case GL_FLOAT_MAT4:
glUniformMatrix4fv( ui.location, count, false, static_cast<const GLfloat*>( data ) );
break;
default:
glUniform1iv( ui.location, count, static_cast<const GLint*>( data ) );
break;
}
return !Driver->testGLError();
}
bool COGLES2SLMaterialRenderer::setTextureUnit( const c8* name, int unit )
{
os::Printer::log( "Cannot set constant, use high level shader call.", ELL_WARNING );
return false;
}
bool COGLES2SLMaterialRenderer::enableMaterialTexture( const c8* name, int materialId )
{
ITexture * t = Driver->getTextureByIndex( materialId );
COGLES2Texture * tex = reinterpret_cast<COGLES2Texture*>( t );
if ( !tex )
return false;
int unit = tex->getOGLES2TextureName();
glActiveTexture( GL_TEXTURE0 + unit );
glBindTexture( GL_TEXTURE_2D, unit );
return setTextureUnit( name, unit );
}
bool COGLES2SLMaterialRenderer::disableMaterialTexture( int materialId )
{
COGLES2Texture * tex = reinterpret_cast<COGLES2Texture*>( Driver->getTextureByIndex( materialId ) );
if ( !tex )
return false;
int unit = tex->getOGLES2TextureName();
glActiveTexture( GL_TEXTURE0 + unit );
glBindTexture( GL_TEXTURE_2D, 0 );
return true;
}
void COGLES2SLMaterialRenderer::setPixelShaderConstant( const f32* data, s32 startRegister, s32 constantAmount )
{
os::Printer::log( "Cannot set constant, use high level shader call.", ELL_WARNING );
}
IVideoDriver* COGLES2SLMaterialRenderer::getVideoDriver()
{
return Driver;
}
void COGLES2SLMaterialRenderer::useProgram()
{
glUseProgram( Program );
}
} // end namespace video
} // end namespace irr
#endif //_IRR_COMPILE_WITH_OPENGLES2_

View File

@ -0,0 +1,141 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_OGLES2_SL_MATERIAL_RENDERER_H_INCLUDED__
#define __C_OGLES2_SL_MATERIAL_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "IMaterialRenderer.h"
#include "IMaterialRendererServices.h"
#include "IGPUProgrammingServices.h"
#include "irrArray.h"
#include "irrString.h"
namespace irr
{
namespace io
{
class IFileSystem;
}
namespace video
{
class COGLES2Driver;
class IShaderConstantSetCallBack;
//! Class for using GLSL shaders with OpenGL
//! Please note: This renderer implements its own IMaterialRendererServices
class COGLES2SLMaterialRenderer : public IMaterialRenderer, public IMaterialRendererServices
{
protected:
struct SUniformInfo
{
u32 type;
s32 location;
};
typedef SUniformInfo SAttributeInfo;
public:
//! Constructor
COGLES2SLMaterialRenderer(
COGLES2Driver* driver,
s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial,
s32 userData );
//! Destructor
virtual ~COGLES2SLMaterialRenderer();
virtual void OnSetMaterial( const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services );
virtual bool OnRender( IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype );
virtual bool PostRender( IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype );
virtual void OnUnsetMaterial();
//! Returns if the material is transparent.
virtual bool isTransparent() const;
// implementations for the render services
virtual void setBasicRenderStates( const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates );
virtual bool setVertexShaderConstant( const c8* name, const f32* floats, int count );
virtual void setVertexShaderConstant( const f32* data, s32 startRegister, s32 constantAmount = 1 );
virtual bool setPixelShaderConstant( const c8* name, const f32* floats, int count );
virtual void setPixelShaderConstant( const f32* data, s32 startRegister, s32 constantAmount = 1 );
bool setUniform( int index, const void* data, int count = 1 );
virtual bool setVertexShaderPointer( const c8* name, const void* pointer, s32 size = 3, bool normalized = false, u16 stride = 0 );
virtual void enableVertexShaderPointer( const c8* name );
virtual void disableVertexShaderPointer( const c8* name );
bool setTextureUnit( const c8* name, int unit );
virtual bool enableMaterialTexture( const c8* name, int materialId );
virtual bool disableMaterialTexture( int materialId );
virtual IVideoDriver* getVideoDriver();
void useProgram();
protected:
//! constructor only for use by derived classes who want to
//! create a fall back material for example.
COGLES2SLMaterialRenderer( COGLES2Driver* driver,
io::IFileSystem* fs,
IShaderConstantSetCallBack* callback,
IMaterialRenderer* baseMaterial,
const char* const* uniformStringTable,
const u32& uniformCount,
s32 userData = 0 );
void init( s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
bool registerMaterial = true );
void initFromFiles( s32& outMaterialTypeNr,
const c8* vertexShaderFile,
const c8* pixelShaderFile,
bool registerMaterial = true );
void reloadFromFiles( const c8* vertexShaderFile,
const c8* pixelShaderFile );
bool readVertexShader( const c8* vertexShaderFile );
bool readFragmentShader( const c8* fragmentShaderFile );
bool readShader( u32 shaderType, const c8* shaderFile );
bool createProgram();
bool createShader( u32 shaderType, const char* shader, const char* shaderFile );
bool linkProgram();
COGLES2Driver* Driver;
IShaderConstantSetCallBack* CallBack;
IMaterialRenderer* BaseMaterial;
io::IFileSystem* FileSystem;
u32 Program;
core::array<SUniformInfo> UniformInfo;
core::array<SAttributeInfo> AttributeInfo;
s32 UserData;
const char* const* UniformStringTable;
const int UniformCount;
};
} // end namespace video
} // end namespace irr
#endif //_IRR_COMPILE_WITH_OPENGLES2_
#endif //__C_OPEN_GL_ES2_SL_MATERIAL_RENDERER_H_INCLUDED__

View File

@ -0,0 +1,738 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "irrTypes.h"
#include "COGLES2Texture.h"
#include "COGLES2Driver.h"
#include "os.h"
#include "CImage.h"
#include "CColorConverter.h"
#include "irrString.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
namespace irr
{
namespace video
{
//! constructor for usual textures
COGLES2Texture::COGLES2Texture( IImage* origImage, const io::path& name, COGLES2Driver* driver )
: ITexture( name ), Driver( driver ), Image( 0 ),
TextureName( 0 ), InternalFormat( GL_RGBA ), PixelFormat( GL_RGBA ),
// TODO ogl-es
// PixelFormat(GL_BGRA),
PixelType( GL_UNSIGNED_BYTE ),
HasMipMaps( true ), IsRenderTarget( false ), AutomaticMipmapUpdate( false ),
UseStencil( false ), ReadOnlyLock( false )
{
#ifdef _DEBUG
setDebugName( "COGLES2Texture" );
#endif
HasMipMaps = Driver->getTextureCreationFlag( ETCF_CREATE_MIP_MAPS );
getImageData( origImage );
if ( Image )
{
glGenTextures( 1, &TextureName );
copyTexture();
}
}
//! constructor for basic setup (only for derived classes)
COGLES2Texture::COGLES2Texture( const io::path& name, COGLES2Driver* driver )
: ITexture( name ), Driver( driver ), Image( 0 ),
TextureName( 0 ), InternalFormat( GL_RGBA ), PixelFormat( GL_RGBA ),
PixelType( GL_UNSIGNED_BYTE ),
HasMipMaps( true ), IsRenderTarget( false ), AutomaticMipmapUpdate( false ),
ReadOnlyLock( false )
{
#ifdef _DEBUG
setDebugName( "COGLES2Texture" );
#endif
}
//! destructor
COGLES2Texture::~COGLES2Texture()
{
glDeleteTextures( 1, &TextureName );
if ( Image )
Image->drop();
}
ECOLOR_FORMAT COGLES2Texture::getBestColorFormat( ECOLOR_FORMAT format )
{
ECOLOR_FORMAT destFormat = ECF_A8R8G8B8;
switch ( format )
{
case ECF_A1R5G5B5:
if ( !Driver->getTextureCreationFlag( ETCF_ALWAYS_32_BIT ) )
destFormat = ECF_A1R5G5B5;
break;
case ECF_R5G6B5:
if ( !Driver->getTextureCreationFlag( ETCF_ALWAYS_32_BIT ) )
destFormat = ECF_A1R5G5B5;
break;
case ECF_A8R8G8B8:
if ( Driver->getTextureCreationFlag( ETCF_ALWAYS_16_BIT ) ||
Driver->getTextureCreationFlag( ETCF_OPTIMIZED_FOR_SPEED ) )
destFormat = ECF_A1R5G5B5;
break;
case ECF_R8G8B8:
if ( Driver->getTextureCreationFlag( ETCF_ALWAYS_16_BIT ) ||
Driver->getTextureCreationFlag( ETCF_OPTIMIZED_FOR_SPEED ) )
destFormat = ECF_A1R5G5B5;
break;
default:
destFormat = ECF_A8R8G8B8;
break;
}
if ( Driver->getTextureCreationFlag( ETCF_NO_ALPHA_CHANNEL ) )
{
switch ( destFormat )
{
case ECF_A1R5G5B5:
destFormat = ECF_R5G6B5;
break;
case ECF_A8R8G8B8:
destFormat = ECF_R8G8B8;
break;
default:
break;
}
}
return destFormat;
}
void COGLES2Texture::getImageData( IImage* image )
{
if ( !image )
{
os::Printer::log( "No image for OGLES2 texture.", ELL_ERROR );
return;
}
ImageSize = image->getDimension();
if ( !ImageSize.Width || !ImageSize.Height )
{
os::Printer::log( "Invalid size of image for OGLES2 Texture.", ELL_ERROR );
return;
}
const core::dimension2d<u32> nImageSize = ImageSize.getOptimalSize( !Driver->queryFeature( EVDF_TEXTURE_NPOT ) );
const ECOLOR_FORMAT destFormat = getBestColorFormat( image->getColorFormat() );
Image = new CImage( destFormat, nImageSize );
// copy texture
image->copyToScaling( Image );
}
//! copies the the texture into an open gl texture.
void COGLES2Texture::copyTexture( bool newTexture )
{
if ( !Image )
{
os::Printer::log( "No image for OGLES2 texture to upload", ELL_ERROR );
return;
}
void( *convert )( const void*, s32, void* ) = 0;
switch ( Image->getColorFormat() )
{
case ECF_A1R5G5B5:
InternalFormat = GL_RGBA;
PixelFormat = GL_RGBA;
PixelType = GL_UNSIGNED_SHORT_5_5_5_1;
convert = CColorConverter::convert_A1R5G5B5toR5G5B5A1;
break;
case ECF_R5G6B5:
InternalFormat = GL_RGB;
PixelFormat = GL_RGB;
PixelType = GL_UNSIGNED_SHORT_5_6_5;
break;
case ECF_R8G8B8:
InternalFormat = GL_RGB;
PixelFormat = GL_RGB;
PixelType = GL_UNSIGNED_BYTE;
convert = CColorConverter::convert_R8G8B8toB8G8R8;
break;
case ECF_A8R8G8B8:
PixelType = GL_UNSIGNED_BYTE;
if ( !Driver->queryOpenGLFeature( COGLES2ExtensionHandler::IRR_IMG_texture_format_BGRA8888 ) && !Driver->queryOpenGLFeature( COGLES2ExtensionHandler::IRR_EXT_texture_format_BGRA8888 ) )
{
convert = CColorConverter::convert_A8R8G8B8toA8B8G8R8;
InternalFormat = GL_RGBA;
PixelFormat = GL_RGBA;
}
else
{
InternalFormat = GL_BGRA;
PixelFormat = GL_BGRA;
}
break;
default:
os::Printer::log( "Unsupported texture format", ELL_ERROR );
break;
}
glBindTexture( GL_TEXTURE_2D, TextureName );
if ( Driver->testGLError() )
os::Printer::log( "Could not bind Texture", ELL_ERROR );
if ( newTexture )
{
#ifndef DISABLE_MIPMAPPING
{
AutomaticMipmapUpdate = false;
regenerateMipMapLevels();
}
#else
HasMipMaps = false;
os::Printer::log( "Did not create OGLES2 texture mip maps.", ELL_ERROR );
#endif
{
// enable bilinear filter without mipmaps
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}
}
void* source = 0;
IImage* tmpImage = 0;
source = Image->lock();
if ( convert )
{
tmpImage = new CImage( Image->getColorFormat(), Image->getDimension() );
void* dest = tmpImage->lock();
convert( source, Image->getDimension().getArea(), dest );
Image->unlock();
source = dest;
}
if ( newTexture )
glTexImage2D( GL_TEXTURE_2D, 0, InternalFormat, Image->getDimension().Width,
Image->getDimension().Height, 0, PixelFormat, PixelType, source );
else
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, Image->getDimension().Width,
Image->getDimension().Height, PixelFormat, PixelType, source );
if ( convert )
{
tmpImage->unlock();
tmpImage->drop();
}
else
Image->unlock();
if ( Driver->testGLError() )
os::Printer::log( "Could not glTexImage2D", ELL_ERROR );
}
//! lock function
/** TODO: support miplevel */
void* COGLES2Texture::lock( bool readOnly, u32 mipmapLevel )
{
ReadOnlyLock |= readOnly;
if ( !Image )
Image = new CImage( ECF_A8R8G8B8, ImageSize );
if ( IsRenderTarget )
{
u8* pPixels = static_cast<u8*>( Image->lock() );
if ( !pPixels )
{
return 0;
}
// we need to keep the correct texture bound...
GLint tmpTexture;
glGetIntegerv( GL_TEXTURE_BINDING_2D, &tmpTexture );
glBindTexture( GL_TEXTURE_2D, TextureName );
// TODO ogl-es
// glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pPixels);
// opengl images are horizontally flipped, so we have to fix that here.
const u32 pitch = Image->getPitch();
u8* p2 = pPixels + ( ImageSize.Height - 1 ) * pitch;
u8* tmpBuffer = new u8[pitch];
for ( u32 i = 0; i < ImageSize.Height; i += 2 )
{
memcpy( tmpBuffer, pPixels, pitch );
memcpy( pPixels, p2, pitch );
memcpy( p2, tmpBuffer, pitch );
pPixels += pitch;
p2 -= pitch;
}
delete [] tmpBuffer;
Image->unlock();
//reset old bound texture
glBindTexture( GL_TEXTURE_2D, tmpTexture );
}
return Image->lock();
}
//! unlock function
void COGLES2Texture::unlock()
{
Image->unlock();
if ( !ReadOnlyLock )
copyTexture( false );
ReadOnlyLock = false;
}
//! Returns size of the original image.
const core::dimension2d<u32>& COGLES2Texture::getOriginalSize() const
{
return ImageSize;
}
//! Returns size of the texture.
const core::dimension2d<u32>& COGLES2Texture::getSize() const
{
if ( Image )
return Image->getDimension();
else
return ImageSize;
}
//! returns driver type of texture, i.e. the driver, which created the texture
E_DRIVER_TYPE COGLES2Texture::getDriverType() const
{
return EDT_OGLES2;
}
//! returns color format of texture
ECOLOR_FORMAT COGLES2Texture::getColorFormat() const
{
if ( Image )
return Image->getColorFormat();
else
return ECF_A8R8G8B8;
}
//! returns pitch of texture (in bytes)
u32 COGLES2Texture::getPitch() const
{
if ( Image )
return Image->getPitch();
else
return 0;
}
//! return open gl texture name
GLuint COGLES2Texture::getOGLES2TextureName() const
{
return TextureName;
}
//! Returns whether this texture has mipmaps
bool COGLES2Texture::hasMipMaps() const
{
return HasMipMaps;
}
//! Regenerates the mip map levels of the texture.
void COGLES2Texture::regenerateMipMapLevels(void* mipmapData)
{
if ( AutomaticMipmapUpdate || !HasMipMaps )
return;
if (( Image->getDimension().Width == 1 ) && ( Image->getDimension().Height == 1 ) )
return;
// Manually create mipmaps
u32 width = Image->getDimension().Width;
u32 height = Image->getDimension().Height;
u32 i = 0;
u8* target = new u8[Image->getImageDataSizeInBytes()];
do
{
if ( width > 1 )
width >>= 1;
if ( height > 1 )
height >>= 1;
++i;
Image->copyToScaling( target, width, height, Image->getColorFormat() );
glTexImage2D( GL_TEXTURE_2D, i, InternalFormat, width, height,
0, PixelFormat, PixelType, target );
}
while ( width != 1 || height != 1 );
delete [] target;
Image->unlock();
}
bool COGLES2Texture::isRenderTarget() const
{
return IsRenderTarget;
}
bool COGLES2Texture::isFrameBufferObject() const
{
return false;
}
void COGLES2Texture::setIsRenderTarget( bool isTarget )
{
IsRenderTarget = isTarget;
}
//! Bind Render Target Texture
void COGLES2Texture::bindRTT()
{
glViewport( 0, 0, getSize().Width, getSize().Height );
}
//! Unbind Render Target Texture
void COGLES2Texture::unbindRTT()
{
glBindTexture( GL_TEXTURE_2D, getOGLES2TextureName() );
// Copy Our ViewPort To The Texture
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, getSize().Width, getSize().Height );
}
/* FBO Textures */
#ifdef GL_OES_framebuffer_object
// helper function for render to texture
static bool checkFBOStatus( COGLES2Driver* Driver );
#endif
//! RTT ColorFrameBuffer constructor
COGLES2FBOTexture::COGLES2FBOTexture( const core::dimension2d<u32>& size,
const io::path& name,
COGLES2Driver* driver, ECOLOR_FORMAT format )
: COGLES2Texture( name, driver ), DepthTexture( 0 ), ColorFrameBuffer( 0 )
{
#ifdef _DEBUG
setDebugName( "COGLES2Texture_FBO" );
#endif
ECOLOR_FORMAT col = getBestColorFormat( format );
switch ( col )
{
case ECF_A8R8G8B8:
#ifdef GL_OES_rgb8_rgba8
if ( driver->queryOpenGLFeature( video::COGLES2ExtensionHandler::IRR_OES_rgb8_rgba8 ) )
InternalFormat = GL_RGBA8_OES;
else
#endif
InternalFormat = GL_RGB5_A1;
break;
case ECF_R8G8B8:
#ifdef GL_OES_rgb8_rgba8
if ( driver->queryOpenGLFeature( video::COGLES2ExtensionHandler::IRR_OES_rgb8_rgba8 ) )
InternalFormat = GL_RGB8_OES;
else
#endif
InternalFormat = GL_RGB565;
break;
case ECF_A1R5G5B5:
InternalFormat = GL_RGB5_A1;
break;
case ECF_R5G6B5:
InternalFormat = GL_RGB565;
break;
default:
os::Printer::log( "color format not handled", ELL_WARNING );
break;
}
PixelFormat = GL_RGBA;
PixelType = GL_UNSIGNED_BYTE;
ImageSize = size;
HasMipMaps = false;
IsRenderTarget = true;
#ifdef GL_OES_framebuffer_object
// generate frame buffer
Driver->extGlGenFramebuffers( 1, &ColorFrameBuffer );
Driver->extGlBindFramebuffer( GL_FRAMEBUFFER_OES, ColorFrameBuffer );
// generate color texture
glGenTextures( 1, &TextureName );
glBindTexture( GL_TEXTURE_2D, TextureName );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_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 );
glTexImage2D( GL_TEXTURE_2D, 0, InternalFormat, ImageSize.Width,
ImageSize.Height, 0, PixelFormat, PixelType, 0 );
// attach color texture to frame buffer
Driver->extGlFramebufferTexture2D( GL_FRAMEBUFFER_OES,
GL_COLOR_ATTACHMENT0_OES,
GL_TEXTURE_2D,
TextureName,
0 );
#endif
unbindRTT();
}
//! destructor
COGLES2FBOTexture::~COGLES2FBOTexture()
{
if ( DepthTexture )
if ( DepthTexture->drop() )
Driver->removeDepthTexture( DepthTexture );
if ( ColorFrameBuffer )
Driver->deleteFramebuffers( 1, &ColorFrameBuffer );
}
bool COGLES2FBOTexture::isFrameBufferObject() const
{
return true;
}
//! Bind Render Target Texture
void COGLES2FBOTexture::bindRTT()
{
#ifdef GL_OES_framebuffer_object
if ( ColorFrameBuffer != 0 )
Driver->extGlBindFramebuffer( GL_FRAMEBUFFER_OES, ColorFrameBuffer );
#endif
}
//! Unbind Render Target Texture
void COGLES2FBOTexture::unbindRTT()
{
#ifdef GL_OES_framebuffer_object
if ( ColorFrameBuffer != 0 )
Driver->extGlBindFramebuffer( GL_FRAMEBUFFER_OES, 0 );
#endif
}
/* FBO Depth Textures */
//! RTT DepthBuffer constructor
COGLES2FBODepthTexture::COGLES2FBODepthTexture(
const core::dimension2d<u32>& size,
const io::path& name,
COGLES2Driver* driver,
bool useStencil )
: COGLES2FBOTexture( size, name, driver ), DepthRenderBuffer( 0 ),
StencilRenderBuffer( 0 ), UseStencil( useStencil )
{
#ifdef _DEBUG
setDebugName( "COGLES2TextureFBO_Depth" );
#endif
ImageSize = size;
#ifdef GL_OES_depth24
InternalFormat = GL_DEPTH_COMPONENT24_OES;
#elif defined(GL_OES_depth32)
InternalFormat = GL_DEPTH_COMPONENT32_OES;
#else
InternalFormat = GL_DEPTH_COMPONENT16_OES;
#endif
PixelFormat = GL_RGBA;
PixelType = GL_UNSIGNED_BYTE;
HasMipMaps = false;
if ( useStencil )
{
#ifdef GL_OES_packed_depth_stencil
glGenTextures( 1, &DepthRenderBuffer );
glBindTexture( GL_TEXTURE_2D, DepthRenderBuffer );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_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 );
if ( Driver->queryOpenGLFeature( COGLES2ExtensionHandler::IRR_OES_packed_depth_stencil ) )
{
// generate packed depth stencil texture
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL_OES, ImageSize.Width,
ImageSize.Height, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, 0 );
StencilRenderBuffer = DepthRenderBuffer; // stencil is packed with depth
return;
}
#endif
#if defined(GL_OES_framebuffer_object) && (defined(GL_OES_stencil1) || defined(GL_OES_stencil4) || defined(GL_OES_stencil8))
// generate stencil buffer
Driver->extGlGenRenderbuffers( 1, &StencilRenderBuffer );
Driver->extGlBindRenderbuffer( GL_RENDERBUFFER_OES, StencilRenderBuffer );
Driver->extGlRenderbufferStorage( GL_RENDERBUFFER_OES,
#if defined(GL_OES_stencil8)
GL_STENCIL_INDEX8_OES,
#elif defined(GL_OES_stencil4)
GL_STENCIL_INDEX4_OES,
#elif defined(GL_OES_stencil1)
GL_STENCIL_INDEX1_OES,
#endif
ImageSize.Width, ImageSize.Height );
#endif
}
#ifdef GL_OES_framebuffer_object
// generate depth buffer
Driver->extGlGenRenderbuffers( 1, &DepthRenderBuffer );
Driver->extGlBindRenderbuffer( GL_RENDERBUFFER_OES, DepthRenderBuffer );
Driver->extGlRenderbufferStorage( GL_RENDERBUFFER_OES,
InternalFormat, ImageSize.Width, ImageSize.Height );
#endif
}
//! destructor
COGLES2FBODepthTexture::~COGLES2FBODepthTexture()
{
if ( DepthRenderBuffer && UseStencil )
glDeleteTextures( 1, &DepthRenderBuffer );
else
Driver->deleteRenderbuffers( 1, &DepthRenderBuffer );
if ( StencilRenderBuffer && StencilRenderBuffer != DepthRenderBuffer )
glDeleteTextures( 1, &StencilRenderBuffer );
}
//combine depth texture and rtt
void COGLES2FBODepthTexture::attach( ITexture* renderTex )
{
if ( !renderTex )
return;
video::COGLES2FBOTexture* rtt = static_cast<video::COGLES2FBOTexture*>( renderTex );
rtt->bindRTT();
#ifdef GL_OES_framebuffer_object
if ( UseStencil )
{
// attach stencil texture to stencil buffer
Driver->extGlFramebufferTexture2D( GL_FRAMEBUFFER_OES,
GL_STENCIL_ATTACHMENT_OES,
GL_TEXTURE_2D,
StencilRenderBuffer,
0 );
// attach depth texture to depth buffer
Driver->extGlFramebufferTexture2D( GL_FRAMEBUFFER_OES,
GL_DEPTH_ATTACHMENT_OES,
GL_TEXTURE_2D,
DepthRenderBuffer,
0 );
}
else
{
// attach depth renderbuffer to depth buffer
Driver->extGlFramebufferRenderbuffer( GL_FRAMEBUFFER_OES,
GL_DEPTH_ATTACHMENT_OES,
GL_RENDERBUFFER_OES,
DepthRenderBuffer );
}
// check the status
if ( !checkFBOStatus( Driver ) )
os::Printer::log( "FBO incomplete" );
#endif
rtt->DepthTexture = this;
grab(); // grab the depth buffer, not the RTT
rtt->unbindRTT();
}
//! Bind Render Target Texture
void COGLES2FBODepthTexture::bindRTT()
{
}
//! Unbind Render Target Texture
void COGLES2FBODepthTexture::unbindRTT()
{
}
#ifdef GL_OES_framebuffer_object
bool checkFBOStatus( COGLES2Driver* Driver )
{
GLenum status = Driver->extGlCheckFramebufferStatus( GL_FRAMEBUFFER_OES );
switch ( status )
{
//Our FBO is perfect, return true
case GL_FRAMEBUFFER_COMPLETE_OES:
return true;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
os::Printer::log( "FBO has one or several incomplete image attachments", ELL_ERROR );
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
os::Printer::log( "FBO missing an image attachment", ELL_ERROR );
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
os::Printer::log( "FBO has one or several image attachments with different dimensions", ELL_ERROR );
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
os::Printer::log( "FBO has one or several image attachments with different internal formats", ELL_ERROR );
break;
// not part of all implementations
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES:
os::Printer::log( "FBO has invalid draw buffer", ELL_ERROR );
break;
#endif
// not part of all implementations
#ifdef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES:
os::Printer::log( "FBO has invalid read buffer", ELL_ERROR );
break;
#endif
// not part of fbo_object anymore, but won't harm as it is just a return value
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_OES
case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_OES:
os::Printer::log( "FBO has a duplicate image attachment", ELL_ERROR );
break;
#endif
case GL_FRAMEBUFFER_UNSUPPORTED_OES:
os::Printer::log( "FBO format unsupported", ELL_ERROR );
break;
default:
break;
}
os::Printer::log( "FBO error", ELL_ERROR );
return false;
}
#endif
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OGLES21_

View File

@ -0,0 +1,163 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_OGLES2_TEXTURE_H_INCLUDED__
#define __C_OGLES2_TEXTURE_H_INCLUDED__
#include "ITexture.h"
#include "IImage.h"
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
namespace irr
{
namespace video
{
class COGLES2Driver;
//! OGLES21 texture.
class COGLES2Texture : public ITexture
{
public:
//! constructor
COGLES2Texture( IImage* surface, const io::path& name, COGLES2Driver* driver = 0 );
//! destructor
virtual ~COGLES2Texture();
//! lock function
virtual void* lock( bool readOnly=false, u32 mipmapLevel=0 );
//! unlock function
virtual void unlock();
//! Returns original size of the texture (image).
virtual const core::dimension2d<u32>& getOriginalSize() const;
//! Returns size of the texture.
virtual const core::dimension2d<u32>& getSize() const;
//! returns driver type of texture (=the driver, that created it)
virtual E_DRIVER_TYPE getDriverType() const;
//! returns color format of texture
virtual ECOLOR_FORMAT getColorFormat() const;
//! returns pitch of texture (in bytes)
virtual u32 getPitch() const;
//! return open gl texture name
u32 getOGLES2TextureName() const;
//! return whether this texture has mipmaps
virtual bool hasMipMaps() const;
//! Regenerates the mip map levels of the texture.
virtual void regenerateMipMapLevels(void* mipmapData=0);
//! Is it a render target?
virtual bool isRenderTarget() const;
//! Is it a FrameBufferObject?
virtual bool isFrameBufferObject() const;
//! Bind RenderTargetTexture
void bindRTT();
//! Unbind RenderTargetTexture
void unbindRTT();
//! sets whether this texture is intended to be used as a render target.
void setIsRenderTarget( bool isTarget );
protected:
//! protected constructor with basic setup, no GL texture name created, for derived classes
COGLES2Texture( const io::path& name, COGLES2Driver* driver );
//! get the desired color format based on texture creation flags and the input format.
ECOLOR_FORMAT getBestColorFormat( ECOLOR_FORMAT format );
//! convert the image into an internal image with better properties for this driver.
void getImageData( IImage* image );
//! copies the the texture into an open gl texture.
void copyTexture( bool newTexture = true );
core::dimension2d<u32> ImageSize;
COGLES2Driver* Driver;
IImage* Image;
u32 TextureName;
s32 InternalFormat;
u32 PixelFormat;
u32 PixelType;
bool HasMipMaps;
bool IsRenderTarget;
bool AutomaticMipmapUpdate;
bool UseStencil;
bool ReadOnlyLock;
};
//! OGLES21 FBO texture.
class COGLES2FBOTexture : public COGLES2Texture
{
public:
//! FrameBufferObject constructor
COGLES2FBOTexture( const core::dimension2d<u32>& size, const io::path& name, COGLES2Driver* driver = 0, ECOLOR_FORMAT format = ECF_UNKNOWN );
//! destructor
virtual ~COGLES2FBOTexture();
//! Is it a FrameBufferObject?
virtual bool isFrameBufferObject() const;
//! Bind RenderTargetTexture
virtual void bindRTT();
//! Unbind RenderTargetTexture
virtual void unbindRTT();
ITexture* DepthTexture;
protected:
u32 ColorFrameBuffer;
};
//! OGLES21 FBO depth texture.
class COGLES2FBODepthTexture : public COGLES2FBOTexture
{
public:
//! FrameBufferObject depth constructor
COGLES2FBODepthTexture( const core::dimension2d<u32>& size, const io::path& name, COGLES2Driver* driver = 0, bool useStencil = false );
//! destructor
virtual ~COGLES2FBODepthTexture();
//! Bind RenderTargetTexture
virtual void bindRTT();
//! Unbind RenderTargetTexture
virtual void unbindRTT();
void attach( ITexture* );
protected:
u32 DepthRenderBuffer;
u32 StencilRenderBuffer;
bool UseStencil;
};
} // end namespace video
} // end namespace irr
#endif
#endif // _IRR_COMPILE_WITH_OGLES2_

View File

@ -0,0 +1,58 @@
// Copyright (C) 2009-2010 Amundis
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __OGLES2_UTILS_H_INCLUDED__
#define __OGLES2_UTILS_H_INCLUDED__
namespace irr
{
namespace video
{
inline void scolorfToRGBAfloat4( const SColorf& inColor, float* outColor )
{
outColor[0] = inColor.r;
outColor[1] = inColor.g;
outColor[2] = inColor.b;
outColor[3] = inColor.a;
}
inline void vector3dfToFloat4( const core::vector3df& inVector, float* outVector, float inW )
{
outVector[0] = inVector.X;
outVector[1] = inVector.Y;
outVector[2] = inVector.Z;
outVector[3] = inW;
}
inline void vector3dfToFloat3( const core::vector3df& inVector, float* outVector )
{
outVector[0] = inVector.X;
outVector[1] = inVector.Y;
outVector[2] = inVector.Z;
}
inline void scolortoFloat4( const SColor &irrColor, float *glColor )
{
const float inv = 1.f / 255.f;
glColor[0] = irrColor.getRed() * inv;
glColor[1] = irrColor.getGreen() * inv;
glColor[2] = irrColor.getBlue() * inv;
glColor[3] = irrColor.getAlpha() * inv;
}
inline bool operator!=( const SColorf& a, const SColorf& b )
{
if ( a.r != b.r ) return true;
if ( a.g != b.g ) return true;
if ( a.b != b.b ) return true;
if ( a.a != b.a ) return true;
return false;
}
} // end namespace video
} // end namespace irr
#endif //__OGLES2_UTILS_H_INCLUDED__

View File

@ -2668,6 +2668,82 @@
>
</File>
</Filter>
<Filter
Name="OpenGL-ES2"
>
<File
RelativePath=".\COGLES2Driver.cpp"
>
</File>
<File
RelativePath=".\COGLES2Driver.h"
>
</File>
<File
RelativePath=".\COGLES2ExtensionHandler.cpp"
>
</File>
<File
RelativePath=".\COGLES2ExtensionHandler.h"
>
</File>
<File
RelativePath=".\COGLES2FixedPipelineShader.cpp"
>
</File>
<File
RelativePath=".\COGLES2FixedPipelineShader.h"
>
</File>
<File
RelativePath=".\COGLES2MaterialRenderer.h"
>
</File>
<File
RelativePath=".\COGLES2NormalMapRenderer.cpp"
>
</File>
<File
RelativePath=".\COGLES2NormalMapRenderer.h"
>
</File>
<File
RelativePath=".\COGLES2ParallaxMapRenderer.cpp"
>
</File>
<File
RelativePath=".\COGLES2ParallaxMapRenderer.h"
>
</File>
<File
RelativePath=".\COGLES2Renderer2D.cpp"
>
</File>
<File
RelativePath=".\COGLES2Renderer2D.h"
>
</File>
<File
RelativePath=".\COGLES2SLMaterialRenderer.cpp"
>
</File>
<File
RelativePath=".\COGLES2SLMaterialRenderer.h"
>
</File>
<File
RelativePath=".\COGLES2Texture.cpp"
>
</File>
<File
RelativePath=".\COGLES2Texture.h"
>
</File>
<File
RelativePath=".\COGLES2Utils.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="irr"