- First version of rewritten OpenGL ES 2.0 driver (IDE projects aren't updated, 2d drawing methods doesn't work, only basic functionality of fixed pipeline materials). This driver will be improved soon.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@4435 dfc29bdd-3216-0410-991c-e03cc46cb475
master
nadro 2013-01-15 00:31:37 +00:00
parent 0511665722
commit 40b42e6010
23 changed files with 1603 additions and 3158 deletions

View File

@ -180,7 +180,11 @@ int main()
case video::EDT_OGLES1:
case video::EDT_OGLES2:
UseHighLevelShaders=true;
// fallthrough!
{
psFileName = "../../media/ogles2.frag";
vsFileName = "../../media/ogles2.vert";
}
break;
case video::EDT_OPENGL:
if (UseHighLevelShaders)
{
@ -208,7 +212,7 @@ int main()
least the vertex shader in action, without the pixel shader.
*/
if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
/*if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))
{
device->getLogger()->log("WARNING: Pixel shaders disabled "\
@ -222,7 +226,7 @@ int main()
device->getLogger()->log("WARNING: Vertex shaders disabled "\
"because of missing driver/hardware support.");
vsFileName = "";
}
}*/
/*
Now lets create the new materials. As you maybe know from previous
@ -391,8 +395,8 @@ int main()
if (lastFPS != fps)
{
core::stringw str = L"Irrlicht Engine - Vertex and pixel shader example [";
str += driver->getName();
core::stringw str = L"[";
//str += driver->getName();
str += "] FPS:";
str += fps;

View File

@ -1,182 +1,23 @@
// 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 vec2 varTexCoord0;
varying vec2 varTexCoord1;
varying vec4 varVertexColor;
varying float eyeDist;
varying float varClipDist;
/* Uniforms */
uniform int uFRenderMode;
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 color = vec4(1.0);//varVertexColor;
vec4 texel = texture2D(uTextureUnit0, varTexCoord0);
color *= texel;
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( uFRenderMode == TwoD)
gl_FragColor = render2D();
else if( uFRenderMode == Solid)
gl_FragColor = renderSolid();
else if(uFRenderMode == LightMap)
gl_FragColor = renderLightMap();
else if(uFRenderMode == DetailMap)
gl_FragColor = renderDetailMap();
else if(uFRenderMode == SphereMap)
gl_FragColor = renderSolid();
else if(uFRenderMode == Reflection2Layer)
gl_FragColor = renderReflection2Layer();
else if(uFRenderMode == TransparentVertexAlpha)
gl_FragColor = renderTransparentVertexAlpha();
else if(uFRenderMode == 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;
}
gl_FragColor = renderSolid();
}

View File

@ -1,247 +1,21 @@
// 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 inVertexPosition;
attribute vec3 inVertexNormal;
attribute vec3 inVertexTangent;
attribute vec3 inVertexBinormal;
uniform int uVRenderMode;
/* Matrix Uniforms */
attribute vec4 inVertexColor;
attribute vec2 inTexCoord0;
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 vec2 varTexCoord0;
varying vec2 varTexCoord1;
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;
gl_Position = uMvpMatrix * vec4(inVertexPosition,1.0);
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(uVRenderMode == SphereMap || uVRenderMode == 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;
varTexCoord0 = inTexCoord0;
varTexCoord1 = inTexCoord0;
}

13
media/ogles2.frag Normal file
View File

@ -0,0 +1,13 @@
precision mediump float;
varying vec2 v_texCoord;
varying vec4 v_color;
uniform sampler2D myTexture;
void main (void)
{
vec4 col = texture2D(myTexture, v_texCoord);
col *= v_color;
gl_FragColor = col * 4.0;
}

34
media/ogles2.vert Normal file
View File

@ -0,0 +1,34 @@
attribute vec3 inVertexPosition;
attribute vec3 inVertexNormal;
attribute vec4 inVertexColor;
attribute vec2 inTexCoord0;
uniform mat4 mWorldViewProj;
uniform mat4 mInvWorld;
uniform mat4 mTransWorld;
uniform vec3 mLightPos;
uniform vec4 mLightColor;
varying mediump vec4 v_color;
varying mediump vec2 v_texCoord;
void main(void)
{
gl_Position = mWorldViewProj * vec4(inVertexPosition,1.0);
vec4 normal = vec4(inVertexNormal, 0.0);
normal = mInvWorld * normal;
normal = normalize(normal);
vec4 worldpos = vec4(inVertexPosition,1.0) * mTransWorld;
vec4 lightVector = worldpos - vec4(mLightPos,1.0);
lightVector = normalize(lightVector);
float tmp2 = dot(-lightVector, normal);
vec4 tmp = mLightColor * tmp2;
v_color = vec4(tmp.x, tmp.y, tmp.z, 0.0);
v_texCoord = inTexCoord0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,10 @@
// Copyright (C) 2009-2010 Amundis
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// 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__
@ -46,12 +48,18 @@ namespace irr
{
namespace video
{
class COGLES2CallBridge;
class COGLES2Texture;
class COGLES2FixedPipelineShader;
class COGLES2Renderer2d;
class COGLES2FixedPipelineRenderer;
class COGLES2NormalMapRenderer;
class COGLES2ParallaxMapRenderer;
//class COGLES2Renderer2d;
class COGLES2Driver : public CNullDriver, public IMaterialRendererServices, public COGLES2ExtensionHandler
{
friend class COGLES2CallBridge;
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,
@ -234,9 +242,10 @@ namespace video
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);
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, bool resetAllRenderstates);
//! Compare in SMaterial doesn't check texture parameters, so we should call this on each OnRender call.
virtual void setTextureRenderStates(const SMaterial& material, bool resetAllRenderstates);
//! Sets a vertex shader constant.
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1);
@ -344,24 +353,21 @@ namespace video
ITexture* createDepthTexture(ITexture* texture, bool shared = true);
void removeDepthTexture(ITexture* texture);
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();
u32 getGLBlend(E_BLEND_FACTOR factor);
void blendFunc(E_BLEND_FACTOR sFactor, E_BLEND_FACTOR dFactor);
//! Convert E_BLEND_FACTOR to OpenGL equivalent
GLenum getGLBlend(E_BLEND_FACTOR factor) const;
//! Get current material.
const SMaterial& getCurrentMaterial() const;
//! Get bridge calls.
COGLES2CallBridge* getBridgeCalls() const;
private:
// Bridge calls.
COGLES2CallBridge* BridgeCalls;
void uploadClipPlane(u32 index);
@ -379,9 +385,6 @@ namespace video
//! 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();
@ -461,14 +464,62 @@ namespace video
void* EglContext;
#endif
COGLES2FixedPipelineShader* FixedPipeline;
COGLES2Renderer2d* TwoDRenderer;
bool BlendEnabled;
E_BLEND_FACTOR SourceFactor;
E_BLEND_FACTOR DestFactor;
//COGLES2Renderer2d* TwoDRenderer;
};
//! This bridge between Irlicht pseudo OpenGL calls
//! and true OpenGL calls.
class COGLES2CallBridge
{
public:
COGLES2CallBridge(COGLES2Driver* driver);
// Blending calls.
void setBlendFunc(GLenum source, GLenum destination);
void setBlend(bool enable);
// Cull face calls.
void setCullFaceFunc(GLenum mode);
void setCullFace(bool enable);
// Depth calls.
void setDepthFunc(GLenum mode);
void setDepthMask(bool enable);
void setDepthTest(bool enable);
// Texture calls.
void setActiveTexture(GLenum texture);
void setTexture(u32 stage);
private:
COGLES2Driver* Driver;
GLenum BlendSource;
GLenum BlendDestination;
bool Blend;
GLenum CullFaceMode;
bool CullFace;
GLenum DepthFunc;
bool DepthMask;
bool DepthTest;
GLenum ActiveTexture;
const ITexture* Texture[MATERIAL_MAX_TEXTURES];
};
} // end namespace video
} // end namespace irr

View File

@ -0,0 +1,96 @@
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// 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 "COGLES2FixedPipelineRenderer.h"
#include "IGPUProgrammingServices.h"
#include "os.h"
#include "COGLES2Driver.h"
namespace irr
{
namespace video
{
//! Constructor
COGLES2FixedPipelineRenderer::COGLES2FixedPipelineRenderer(const c8* vertexShaderProgram,
const c8* pixelShaderProgram, E_MATERIAL_TYPE baseMaterial,
COGLES2Driver* driver)
: COGLES2MaterialRenderer(driver, 0, baseMaterial)
{
#ifdef _DEBUG
setDebugName("COGLES2FixedPipelineRenderer");
#endif
int Temp = 0;
SharedRenderer = reinterpret_cast<COGLES2MaterialRenderer*>(driver->getMaterialRenderer(EMT_SOLID));
if (SharedRenderer)
SharedRenderer->grab();
else
init(Temp, vertexShaderProgram, pixelShaderProgram, false);
}
//! Destructor
COGLES2FixedPipelineRenderer::~COGLES2FixedPipelineRenderer()
{
if(SharedRenderer)
SharedRenderer->drop();
}
void COGLES2FixedPipelineRenderer::OnSetMaterial(const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates,
video::IMaterialRendererServices* services)
{
if (SharedRenderer)
SharedRenderer->OnSetMaterial(material, lastMaterial, resetAllRenderstates, services);
else
COGLES2MaterialRenderer::OnSetMaterial(material, lastMaterial, resetAllRenderstates, services);
}
bool COGLES2FixedPipelineRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{
if (SharedRenderer)
return SharedRenderer->OnRender(service, vtxtype);
else
{
/* Vertex Shader part */
/* Matrices Upload */
core::matrix4 world = Driver->getTransform(ETS_WORLD);
setPixelShaderConstant("uWorldMatrix", world.pointer(), 16);
core::matrix4 worldViewProj = Driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= Driver->getTransform(video::ETS_VIEW);
worldViewProj *= Driver->getTransform(ETS_WORLD);
setPixelShaderConstant("uMvpMatrix", worldViewProj.pointer(), 16);
/* Textures Upload */
int TextureUnit0 = 0;
int TextureUnit1 = 1;
setPixelShaderConstant("uTextureUnit0", &TextureUnit0, 1);
setPixelShaderConstant("uTextureUnit1", &TextureUnit1, 1);
return true;
}
}
} // end namespace video
} // end namespace irr
#endif

View File

@ -0,0 +1,49 @@
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// 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 "COGLES2MaterialRenderer.h"
namespace irr
{
namespace video
{
//! Class for rendering fixed pipeline stuff with OpenGL ES 2.0
class COGLES2FixedPipelineRenderer : public COGLES2MaterialRenderer
{
public:
//! Constructor
COGLES2FixedPipelineRenderer(const c8* vertexShaderProgram,
const c8* pixelShaderProgram, E_MATERIAL_TYPE baseMaterial,
COGLES2Driver* driver);
//! Destructor
~COGLES2FixedPipelineRenderer();
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services);
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype);
protected:
COGLES2MaterialRenderer* SharedRenderer;
};
} // end namespace video
} // end namespace irr
#endif
#endif

View File

@ -1,301 +0,0 @@
// 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[] =
{
"uVRenderMode",
"uFRenderMode",
"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[] = IRR_OGLES2_SHADER_PATH "COGLES2FixedPipeline.vsh";
const c8 FragmentShaderFile[] = IRR_OGLES2_SHADER_PATH "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 (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++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);
setUniform(WORLD_MATRIX, world.pointer());
core::matrix4 worldViewProj = Driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= Driver->getTransform(video::ETS_VIEW);
worldViewProj *= Driver->getTransform(ETS_WORLD);
setUniform(MVP_MATRIX, worldViewProj.pointer());
/* Textures Upload */
//statusOk &= setVertexShaderConstant("uTextureUnit", (f32*)TextureUnits, MAX_TEXTURE_UNITS);
setUniform(TEXTURE_UNIT0, &TextureUnits[0]);
setUniform(TEXTURE_UNIT1, &TextureUnits[1]);
setUniform(USE_TEXTURE, UseTexture, MATERIAL_MAX_TEXTURES);
setUniform(USE_TEXTURE_MATRIX, UseTexMatrix, MATERIAL_MAX_TEXTURES);
setUniform(TEXTURE_MATRIX, TextureMatrix, MATERIAL_MAX_TEXTURES);
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 );
setUniform( USE_LIGHT, UseLight, MAX_LIGHTS );
setUniform( LIGHT_POSITION, LightPosition, MAX_LIGHTS );
setUniform( LIGHT_DIRECTION, LightDirection, MAX_LIGHTS );
setUniform( LIGHT_AMBIENT, LightAmbient, MAX_LIGHTS );
setUniform( LIGHT_DIFFUSE, LightDiffuse, MAX_LIGHTS );
setUniform( LIGHT_SPECULAR, LightSpecular, MAX_LIGHTS );
setUniform( LIGHT_ATTENUATION, LightAttenuation, MAX_LIGHTS );
setUniform( LIGHT_EXPONENT, LightExponent, 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 == EMT_SPHERE_MAP || RenderMode == EMT_REFLECTION_2_LAYER) // 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);
setUniform(EYE_POSITION, &viewPos.X);
}
setUniform(CLIP, &Clip);
setUniform(CLIP_PLANE, &ClipPlane);
setUniform(VRENDER_MODE, &RenderMode);
setUniform(FRENDER_MODE, &RenderMode);
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 (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
{
UseTexture[i] = material.getTexture(i) != 0;
if (UseTexture[i])
{
UseTexMatrix[i] = false;
const 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

@ -1,197 +0,0 @@
// 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
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[MATERIAL_MAX_TEXTURES];
int UseTexture[MATERIAL_MAX_TEXTURES];
mat4 TextureMatrix[MATERIAL_MAX_TEXTURES];
int UseTexMatrix[MATERIAL_MAX_TEXTURES];
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
{
VRENDER_MODE = 0,
FRENDER_MODE,
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,464 @@
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// 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 "COGLES2MaterialRenderer.h"
#include "IGPUProgrammingServices.h"
#include "IShaderConstantSetCallBack.h"
#include "IMaterialRendererServices.h"
#include "IVideoDriver.h"
#include "os.h"
#include "COGLES2Driver.h"
#include "COGLES2MaterialRenderer.h"
namespace irr
{
namespace video
{
//! Constructor
COGLES2MaterialRenderer::COGLES2MaterialRenderer(COGLES2Driver* driver,
s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
: Driver(driver), CallBack(callback), Program(0), Alpha(false), Blending(false), FixedBlending(false), UserData(userData)
{
#ifdef _DEBUG
setDebugName("COGLES2MaterialRenderer");
#endif
if (baseMaterial == EMT_TRANSPARENT_VERTEX_ALPHA || baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL ||
baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL_REF || baseMaterial == EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA ||
baseMaterial == EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA)
{
Alpha = true;
}
else if (baseMaterial == EMT_TRANSPARENT_ADD_COLOR || baseMaterial == EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR ||
baseMaterial == EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR)
{
FixedBlending = true;
}
else if (baseMaterial == EMT_ONETEXTURE_BLEND)
Blending = true;
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.
COGLES2MaterialRenderer::COGLES2MaterialRenderer(COGLES2Driver* driver,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial, s32 userData)
: Driver(driver), CallBack(callback), Program(0), Alpha(false), Blending(false), FixedBlending(false), UserData(userData)
{
if (baseMaterial == EMT_TRANSPARENT_VERTEX_ALPHA || baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL ||
baseMaterial == EMT_TRANSPARENT_ALPHA_CHANNEL_REF || baseMaterial == EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA ||
baseMaterial == EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA)
{
Alpha = true;
}
else if (baseMaterial == EMT_TRANSPARENT_ADD_COLOR || baseMaterial == EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR ||
baseMaterial == EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR)
{
FixedBlending = true;
}
else if (baseMaterial == EMT_ONETEXTURE_BLEND)
Blending = true;
if (CallBack)
CallBack->grab();
}
//! Destructor
COGLES2MaterialRenderer::~COGLES2MaterialRenderer()
{
if (CallBack)
CallBack->drop();
if (Program)
{
GLuint shaders[8];
GLint count;
glGetAttachedShaders(Program, 8, &count, shaders);
// avoid bugs in some drivers, which return larger numbers
count=core::min_(count,8);
for (GLint i=0; i<count; ++i)
glDeleteShader(shaders[i]);
glDeleteProgram(Program);
Program = 0;
}
UniformInfo.clear();
}
void COGLES2MaterialRenderer::init(s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
bool addMaterial)
{
outMaterialTypeNr = -1;
Program = glCreateProgram();
if (!Program)
return;
if (vertexShaderProgram)
if (!createShader(GL_VERTEX_SHADER, vertexShaderProgram))
return;
if (pixelShaderProgram)
if (!createShader(GL_FRAGMENT_SHADER, pixelShaderProgram))
return;
for ( size_t i = 0; i < EVA_COUNT; ++i )
glBindAttribLocation( Program, i, sBuiltInVertexAttributeNames[i]);
if (!linkProgram())
return;
// register myself as new material
if (addMaterial)
outMaterialTypeNr = Driver->addMaterialRenderer(this);
}
bool COGLES2MaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{
Driver->setTextureRenderStates(Driver->getCurrentMaterial(), false);
// call callback to set shader constants
if (CallBack && Program)
CallBack->OnSetConstants(this, UserData);
return true;
}
void COGLES2MaterialRenderer::OnSetMaterial(const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates,
video::IMaterialRendererServices* services)
{
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
{
if (Program)
glUseProgram(Program);
if (FixedBlending)
{
Driver->getBridgeCalls()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
Driver->getBridgeCalls()->setBlend(true);
}
else if (Blending)
{
E_BLEND_FACTOR srcFact,dstFact;
E_MODULATE_FUNC modulate;
u32 alphaSource;
unpack_textureBlendFunc(srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam);
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact));
Driver->getBridgeCalls()->setBlend(true);
}
}
if (CallBack)
CallBack->OnSetMaterial(material);
}
void COGLES2MaterialRenderer::OnUnsetMaterial()
{
if (Program)
glUseProgram(0);
if (Blending || FixedBlending)
Driver->getBridgeCalls()->setBlend(false);
}
//! Returns if the material is transparent.
bool COGLES2MaterialRenderer::isTransparent() const
{
return (Alpha || Blending || FixedBlending);
}
bool COGLES2MaterialRenderer::createShader(GLenum shaderType, const char* shader)
{
if (Program)
{
GLuint shaderHandle = glCreateShader(shaderType);
glShaderSource(shaderHandle, 1, &shader, NULL);
glCompileShader(shaderHandle);
GLint status = 0;
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE)
{
os::Printer::log("GLSL shader failed to compile", ELL_ERROR);
// check error message and log it
GLint maxLength=0;
GLint length;
glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH,
&maxLength);
if (maxLength)
{
GLchar *infoLog = new GLchar[maxLength];
glGetShaderInfoLog(shaderHandle, maxLength, &length, infoLog);
os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);
delete [] infoLog;
}
return false;
}
glAttachShader(Program, shaderHandle);
}
return true;
}
bool COGLES2MaterialRenderer::linkProgram()
{
if (Program)
{
glLinkProgram(Program);
GLint 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
GLint maxLength=0;
GLsizei length;
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &maxLength);
if (maxLength)
{
GLchar *infoLog = new GLchar[maxLength];
glGetProgramInfoLog(Program, maxLength, &length, infoLog);
os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);
delete [] infoLog;
}
return false;
}
// get uniforms information
GLint num = 0;
glGetProgramiv(Program, GL_ACTIVE_UNIFORMS, &num);
if (num == 0)
{
// no uniforms
return true;
}
GLint maxlen = 0;
glGetProgramiv(Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlen);
if (maxlen == 0)
{
os::Printer::log("GLSL: failed to retrieve uniform information", ELL_ERROR);
return false;
}
// seems that some implementations use an extra null terminator
++maxlen;
c8 *buf = new c8[maxlen];
UniformInfo.clear();
UniformInfo.reallocate(num);
for (GLint i=0; i < num; ++i)
{
SUniformInfo ui;
memset(buf, 0, maxlen);
GLint size;
glGetActiveUniform(Program, i, maxlen, 0, &size, &ui.type, reinterpret_cast<GLchar*>(buf));
ui.name = buf;
ui.location = glGetUniformLocation(Program, buf);
UniformInfo.push_back(ui);
}
delete [] buf;
}
return true;
}
void COGLES2MaterialRenderer::setBasicRenderStates(const SMaterial& material,
const SMaterial& lastMaterial,
bool resetAllRenderstates)
{
// forward
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
}
s32 COGLES2MaterialRenderer::getVertexShaderConstantID(const c8* name)
{
return getPixelShaderConstantID(name);
}
s32 COGLES2MaterialRenderer::getPixelShaderConstantID(const c8* name)
{
for (u32 i = 0; i < UniformInfo.size(); ++i)
{
if (UniformInfo[i].name == name)
return i;
}
return -1;
}
void COGLES2MaterialRenderer::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
{
os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);
}
void COGLES2MaterialRenderer::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
{
os::Printer::log("Cannot set constant, use high level shader call.", ELL_WARNING);
}
bool COGLES2MaterialRenderer::setVertexShaderConstant(s32 index, const f32* floats, int count)
{
return setPixelShaderConstant(index, floats, count);
}
bool COGLES2MaterialRenderer::setVertexShaderConstant(s32 index, const s32* ints, int count)
{
return setPixelShaderConstant(index, ints, count);
}
bool COGLES2MaterialRenderer::setPixelShaderConstant(s32 index, const f32* floats, int count)
{
if(index < 0 || UniformInfo[index].location < 0)
return false;
bool status = true;
switch (UniformInfo[index].type)
{
case GL_FLOAT:
glUniform1fv(UniformInfo[index].location, count, floats);
break;
case GL_FLOAT_VEC2:
glUniform2fv(UniformInfo[index].location, count/2, floats);
break;
case GL_FLOAT_VEC3:
glUniform3fv(UniformInfo[index].location, count/3, floats);
break;
case GL_FLOAT_VEC4:
glUniform4fv(UniformInfo[index].location, count/4, floats);
break;
case GL_FLOAT_MAT2:
glUniformMatrix2fv(UniformInfo[index].location, count/4, false, floats);
break;
case GL_FLOAT_MAT3:
glUniformMatrix3fv(UniformInfo[index].location, count/9, false, floats);
break;
case GL_FLOAT_MAT4:
glUniformMatrix4fv(UniformInfo[index].location, count/16, false, floats);
break;
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
{
if(floats)
{
const GLint id = *floats;
glUniform1iv(UniformInfo[index].location, 1, &id);
}
else
status = false;
}
break;
default:
status = false;
break;
}
return status;
}
bool COGLES2MaterialRenderer::setPixelShaderConstant(s32 index, const s32* ints, int count)
{
if(index < 0 || UniformInfo[index].location < 0)
return false;
bool status = true;
switch (UniformInfo[index].type)
{
case GL_INT:
case GL_BOOL:
glUniform1iv(UniformInfo[index].location, count, ints);
break;
case GL_INT_VEC2:
case GL_BOOL_VEC2:
glUniform2iv(UniformInfo[index].location, count/2, ints);
break;
case GL_INT_VEC3:
case GL_BOOL_VEC3:
glUniform3iv(UniformInfo[index].location, count/3, ints);
break;
case GL_INT_VEC4:
case GL_BOOL_VEC4:
glUniform4iv(UniformInfo[index].location, count/4, ints);
break;
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
glUniform1iv(UniformInfo[index].location, 1, ints);
break;
default:
status = false;
break;
}
return status;
}
IVideoDriver* COGLES2MaterialRenderer::getVideoDriver()
{
return Driver;
}
} // end namespace video
} // end namespace irr
#endif

View File

@ -1,600 +1,142 @@
// Copyright (C) 2009-2010 Amundis
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// 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__
#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 "COGLES2SLMaterialRenderer.h"
#include "COGLES2FixedPipelineShader.h"
#if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#else
#include <GLES2/gl2.h>
#include <EGL/eglplatform.h>
#endif
#include "EMaterialTypes.h"
#include "EVertexAttributes.h"
#include "IMaterialRenderer.h"
#include "IMaterialRendererServices.h"
#include "IGPUProgrammingServices.h"
#include "IShaderConstantSetCallBack.h"
#include "irrArray.h"
#include "irrString.h"
namespace irr
{
namespace video
namespace video
{
//! Base class for all internal OGLES2 material renderers
class COGLES2MaterialRenderer : public IMaterialRenderer
class COGLES2Driver;
//! Class for using GLSL shaders with OpenGL ES 2.0
//! Please note: This renderer implements its own IMaterialRendererServices
class COGLES2MaterialRenderer : public IMaterialRenderer, public IMaterialRendererServices
{
public:
//! Constructor
COGLES2MaterialRenderer(
COGLES2Driver* driver,
s32& outMaterialTypeNr,
const c8* vertexShaderProgram = 0,
const c8* pixelShaderProgram = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = EMT_SOLID,
s32 userData = 0);
//! Destructor
virtual ~COGLES2MaterialRenderer();
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services);
virtual bool OnRender(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 s32 getVertexShaderConstantID(const c8* name);
virtual s32 getPixelShaderConstantID(const c8* name);
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1);
virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1);
virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count);
virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count);
virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count);
virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count);
//! For compatybility with old irrlicht revisions.
bool setVertexShaderConstant(const c8* name, const f32* floats, int count)
{
public:
return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count);
}
//! Constructor
COGLES2MaterialRenderer( video::COGLES2Driver* driver ) :
Driver( driver ),
FixedPipeline( driver->fixedPipeline() )
{
}
bool setVertexShaderConstant(const c8* name, const s32* ints, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), ints, count);
}
virtual bool OnRender( IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype )
{
return FixedPipeline->OnRender( service, vtxtype );
}
bool setPixelShaderConstant(const c8* name, const f32* floats, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), floats, count);
}
protected:
bool setPixelShaderConstant(const c8* name, const s32* ints, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), ints, count);
}
video::COGLES2Driver* Driver;
COGLES2FixedPipelineShader* FixedPipeline;
virtual IVideoDriver* getVideoDriver();
protected:
//! constructor only for use by derived classes who want to
//! create a fall back material for example.
COGLES2MaterialRenderer(COGLES2Driver* driver,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = EMT_SOLID,
s32 userData = 0);
void init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, bool addMaterial = true);
bool createShader(GLenum shaderType, const char* shader);
bool linkProgram();
COGLES2Driver* Driver;
IShaderConstantSetCallBack* CallBack;
bool Alpha;
bool Blending;
bool FixedBlending;
struct SUniformInfo
{
core::stringc name;
GLenum type;
GLint location;
};
GLuint Program;
core::array<SUniformInfo> UniformInfo;
s32 UserData;
};
//! 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->setActiveTexture(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->setActiveTexture( 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_textureBlendFunc( 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 (alphaSource&EAS_TEXTURE)
FixedPipeline->setRenderMode( EMT_TRANSPARENT_ALPHA_CHANNEL );
else
FixedPipeline->setRenderMode( EMT_TRANSPARENT_VERTEX_ALPHA );
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->setActiveTexture( 1, material.getTexture( 1 ) );
Driver->setActiveTexture( 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->setActiveTexture( 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->setActiveTexture( 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->setActiveTexture( 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->setActiveTexture( 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->setActiveTexture( 1, material.getTexture( 1 ) );
Driver->setActiveTexture( 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->setActiveTexture( 1, material.getTexture( 1 ) );
Driver->setActiveTexture( 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->setActiveTexture( 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->setActiveTexture( 0, material.getTexture( 1 ) );
Driver->setActiveTexture( 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->setActiveTexture( 1, material.getTexture( 1 ) );
Driver->setActiveTexture( 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
#endif // compile with OpenGL ES 2.0
#endif // if included

View File

@ -1,160 +1,76 @@
// Copyright (C) 2009-2010 Amundis
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// 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[] =
//! Constructor
COGLES2NormalMapRenderer::COGLES2NormalMapRenderer(const c8* vertexShaderProgram,
const c8* pixelShaderProgram, E_MATERIAL_TYPE baseMaterial,
COGLES2Driver* driver)
: COGLES2MaterialRenderer(driver, 0, baseMaterial)
{
#ifdef _DEBUG
setDebugName("COGLES2NormalMapRenderer");
#endif
int Temp = 0;
SharedRenderer = reinterpret_cast<COGLES2MaterialRenderer*>(driver->getMaterialRenderer(EMT_NORMAL_MAP_SOLID));
if (SharedRenderer)
SharedRenderer->grab();
else
init(Temp, vertexShaderProgram, pixelShaderProgram, false);
}
//! Destructor
COGLES2NormalMapRenderer::~COGLES2NormalMapRenderer()
{
if(SharedRenderer)
SharedRenderer->drop();
}
void COGLES2NormalMapRenderer::OnSetMaterial(const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates,
video::IMaterialRendererServices* services)
{
if (SharedRenderer)
SharedRenderer->OnSetMaterial(material, lastMaterial, resetAllRenderstates, services);
else
COGLES2MaterialRenderer::OnSetMaterial(material, lastMaterial, resetAllRenderstates, services);
}
bool COGLES2NormalMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{
if (SharedRenderer)
return SharedRenderer->OnRender(service, vtxtype);
else
{
"uMvpMatrix",
"uLightPos",
"uLightColor",
"texture0",
"texture1",
0
};
/* Vertex Shader part */
// Irrlicht Engine OGLES2 render path normal map vertex shader
const c8 VertexShaderFile[] = IRR_OGLES2_SHADER_PATH "COGLES2NormalMap.vsh";
const c8 FragmentShaderFile[] = IRR_OGLES2_SHADER_PATH "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
if (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 );
return true;
}
}
} // end namespace video
@ -162,4 +78,3 @@ namespace video
#endif

View File

@ -1,6 +1,7 @@
// Copyright (C) 2009-2010 Amundis
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
@ -8,51 +9,37 @@
#define __C_OGLES2_NORMAL_MAP_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2SLMaterialRenderer.h"
#include "IShaderConstantSetCallBack.h"
#include "COGLES2MaterialRenderer.h"
namespace irr
{
namespace video
{
//! Class for rendering normal maps with OGLES2
class COGLES2NormalMapRenderer : public COGLES2SLMaterialRenderer, public IShaderConstantSetCallBack
{
public:
//! Class for normal mapping in OpenGL ES 2.0
class COGLES2NormalMapRenderer : public COGLES2MaterialRenderer
{
public:
//! Constructor
COGLES2NormalMapRenderer(const c8* vertexShaderProgram,
const c8* pixelShaderProgram, E_MATERIAL_TYPE baseMaterial,
COGLES2Driver* driver);
//! Constructor
COGLES2NormalMapRenderer(video::COGLES2Driver* driver, io::IFileSystem* fs,
s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial);
//! Destructor
~COGLES2NormalMapRenderer();
//! Destructor
virtual ~COGLES2NormalMapRenderer();
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services);
//! 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 bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype);
//! Returns the render capability of the material.
virtual s32 getRenderCapability() const;
protected:
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[];
};
COGLES2MaterialRenderer* SharedRenderer;
};
} // end namespace video

View File

@ -1,187 +1,76 @@
// Copyright (C) 2009-2010 Amundis
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// 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
#include "COGLES2Driver.h"
namespace irr
{
namespace video
{
const char * const COGLES2ParallaxMapRenderer::sBuiltInShaderUniformNames[] =
//! Constructor
COGLES2ParallaxMapRenderer::COGLES2ParallaxMapRenderer(const c8* vertexShaderProgram,
const c8* pixelShaderProgram, E_MATERIAL_TYPE baseMaterial,
COGLES2Driver* driver)
: COGLES2MaterialRenderer(driver, 0, baseMaterial)
{
#ifdef _DEBUG
setDebugName("COGLES2ParallaxMapRenderer");
#endif
int Temp = 0;
SharedRenderer = reinterpret_cast<COGLES2MaterialRenderer*>(driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID));
if (SharedRenderer)
SharedRenderer->grab();
else
init(Temp, vertexShaderProgram, pixelShaderProgram, false);
}
//! Destructor
COGLES2ParallaxMapRenderer::~COGLES2ParallaxMapRenderer()
{
if(SharedRenderer)
SharedRenderer->drop();
}
void COGLES2ParallaxMapRenderer::OnSetMaterial(const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates,
video::IMaterialRendererServices* services)
{
if (SharedRenderer)
SharedRenderer->OnSetMaterial(material, lastMaterial, resetAllRenderstates, services);
else
COGLES2MaterialRenderer::OnSetMaterial(material, lastMaterial, resetAllRenderstates, services);
}
bool COGLES2ParallaxMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{
if (SharedRenderer)
return SharedRenderer->OnRender(service, vtxtype);
else
{
"uMvpMatrix",
"uLightPos",
"uLightColor",
"uEyePos",
"texture0",
"texture1",
"uLightDiffuse",
"uHeightScale",
0
};
/* Vertex Shader part */
// Irrlicht Engine OGLES2 render path normal map vertex shader
const c8 VertexShaderFile[] = IRR_OGLES2_SHADER_PATH "COGLES2ParallaxMap.vsh";
const c8 FragmentShaderFile[] = IRR_OGLES2_SHADER_PATH "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
if (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 );
return true;
}
}
} // end namespace video
@ -189,4 +78,3 @@ namespace video
#endif

View File

@ -1,6 +1,7 @@
// Copyright (C) 2009-2010 Amundis
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
@ -8,57 +9,37 @@
#define __C_OGLES2_PARALLAX_MAP_RENDERER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2SLMaterialRenderer.h"
#include "IShaderConstantSetCallBack.h"
#include "COGLES2MaterialRenderer.h"
namespace irr
{
namespace video
{
//! Class for rendering normal maps with OGLES2
class COGLES2ParallaxMapRenderer : public COGLES2SLMaterialRenderer, public IShaderConstantSetCallBack
{
public:
//! Class for parallax mapping in OpenGL ES 2.0
class COGLES2ParallaxMapRenderer : public COGLES2MaterialRenderer
{
public:
//! Constructor
COGLES2ParallaxMapRenderer(const c8* vertexShaderProgram,
const c8* pixelShaderProgram, E_MATERIAL_TYPE baseMaterial,
COGLES2Driver* driver);
//! Constructor
COGLES2ParallaxMapRenderer( video::COGLES2Driver* driver, io::IFileSystem* fs,
s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial );
//! Destructor
~COGLES2ParallaxMapRenderer();
//! Destructor
virtual ~COGLES2ParallaxMapRenderer();
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services);
//! 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 bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype);
virtual void OnSetMaterial( const SMaterial& material ) { }
virtual void OnSetMaterial( const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates, video::IMaterialRendererServices* services );
protected:
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[];
};
COGLES2MaterialRenderer* SharedRenderer;
};
} // end namespace video
@ -67,3 +48,4 @@ namespace video
#endif
#endif

View File

@ -27,55 +27,55 @@ namespace video
static const char* fragmentShaderFile = IRR_OGLES2_SHADER_PATH "COGLES2Renderer2D.fsh";
COGLES2Renderer2d::COGLES2Renderer2d( irr::video::COGLES2Driver *driver, irr::io::IFileSystem *fs )
: COGLES2SLMaterialRenderer( driver, fs, 0, 0, sBuiltInShaderUniformNames, UNIFORM_COUNT )
: COGLES2MaterialRenderer( driver )
{
#ifdef _DEBUG
setDebugName( "COGLES2Renderer2d" );
#endif
s32 dummy = -1;
/*s32 dummy = -1;
if (!initFromFiles( dummy, vertexShaderFile, fragmentShaderFile, false))
return;
useProgram();
int texUnit = 0;
setUniform( TEXTURE_UNIT, &texUnit );
setUniform( TEXTURE_UNIT, &texUnit );*/
}
void COGLES2Renderer2d::useTexture( bool param )
{
if ( param != UseTexture )
/*if ( param != UseTexture )
{
UseTexture = param;
int dummy = param ? 1 : 0;
setUniform( USE_TEXTURE, &dummy );
}
}*/
}
void COGLES2Renderer2d::useAlphaTest( bool param )
{
if ( param != UseAlphaTest )
/*if ( param != UseAlphaTest )
{
UseAlphaTest = param;
int dummy = param ? 1 : 0;
setUniform( ALPHA_TEST, &dummy );
}
}*/
}
void COGLES2Renderer2d::setAlphaTestValue( float value )
{
if ( value != AlphaTestValue )
/*if ( value != AlphaTestValue )
{
AlphaTestValue = value;
setUniform( ALPHA_VALUE, &AlphaTestValue );
}
}*/
}
void COGLES2Renderer2d::setOrthoMatrix( const core::matrix4 &matrix )
{
if ( matrix != OrthoMatrix )
/*if ( matrix != OrthoMatrix )
{
OrthoMatrix = matrix;
setUniform( ORTHO_MATRIX, OrthoMatrix.pointer() );
}
}*/
}
}
}

View File

@ -7,7 +7,7 @@
#ifndef __C_OGLES2_RENDERER_2D_H_INCLUDED__
#define __C_OGLES2_RENDERER_2D_H_INCLUDED__
#include "COGLES2SLMaterialRenderer.h"
#include "COGLES2MaterialRenderer.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
@ -21,7 +21,7 @@ namespace video
{
class COGLES2Driver;
class COGLES2Renderer2d : public COGLES2SLMaterialRenderer
class COGLES2Renderer2d : public COGLES2MaterialRenderer
{
public:
COGLES2Renderer2d( COGLES2Driver* driver, io::IFileSystem* fs );

View File

@ -1,646 +0,0 @@
// 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"
#if !defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
#include <GLES2/gl2.h>
#endif
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();
}
bool COGLES2SLMaterialRenderer::init(s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
bool registerMaterial )
{
outMaterialTypeNr = -1;
if ( Program == 0 && !createProgram() )
return false;
if ( vertexShaderProgram )
if ( !createShader( GL_VERTEX_SHADER, vertexShaderProgram, "" ) )
return false;
if ( pixelShaderProgram )
if ( !createShader( GL_FRAGMENT_SHADER, pixelShaderProgram, "" ) )
return false;
for ( size_t i = 0; i < EVA_COUNT; ++i )
glBindAttribLocation( Program, i, sBuiltInVertexAttributeNames[i] );
if ( !linkProgram() )
return false;
// register myself as new material
if ( registerMaterial )
outMaterialTypeNr = Driver->addMaterialRenderer( this );
return true;
}
bool COGLES2SLMaterialRenderer::initFromFiles( s32 &outMaterialTypeNr,
const c8 *vertexShaderFile,
const c8 *pixelShaderFile,
bool registerMaterial )
{
outMaterialTypeNr = -1;
if ( !createProgram() )
{
os::Printer::log( "Could not create shader program.", ELL_ERROR );
return false;
}
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 );
return false;
}
if ( registerMaterial )
outMaterialTypeNr = Driver->addMaterialRenderer( this );
return true;
}
bool 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 );
return false;
}
else
return true;
}
bool COGLES2SLMaterialRenderer::readShader( GLenum shaderType, const c8* shaderFile )
{
io::IReadFile* file = FileSystem->createAndOpenFile(shaderFile);
if (!file)
{
os::Printer::log("Could not open shader file", shaderFile, ELL_ERROR);
return false;
}
const long size = file->getSize();
if (!size)
{
os::Printer::log( "Shader file is empty", shaderFile, 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 );
}
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 )
{
os::Printer::log("GLSL shader failed to compile", shaderFile, 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(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(pInfoLog, ELL_ERROR);
delete [] pInfoLog;
return false;
}
// get uniforms information
int num = 0;
glGetProgramiv( Program, GL_ACTIVE_UNIFORMS, &num );
if (num == 0)
return true;
int maxlen = 0;
glGetProgramiv( Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlen );
if (maxlen == 0)
{
os::Printer::log("GLSL: failed to retrieve uniform information", ELL_ERROR);
return false;
}
maxlen++;
c8 *buf = new c8[maxlen];
UniformInfo.clear();
UniformInfo.reallocate(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.name = buf;
ui.location = glGetUniformLocation( Program, buf );
UniformInfo.push_back(ui);
}
delete [] buf;
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 );
}
bool COGLES2SLMaterialRenderer::setVertexShaderConstant( const c8* name, const s32* ints, int count )
{
return setPixelShaderConstant( name, ints, 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 )
{
u32 i;
const u32 num = UniformInfo.size();
for (i=0; i < num; ++i)
{
if (UniformInfo[i].name == name)
break;
}
if (i == num)
return false;
if(UniformInfo[i].location == -1)
return false;
bool status = true;
switch (UniformInfo[i].type)
{
case GL_FLOAT:
glUniform1fv(UniformInfo[i].location, count, floats);
break;
case GL_FLOAT_VEC2:
glUniform2fv(UniformInfo[i].location, count/2, floats);
break;
case GL_FLOAT_VEC3:
glUniform3fv(UniformInfo[i].location, count/3, floats);
break;
case GL_FLOAT_VEC4:
glUniform4fv(UniformInfo[i].location, count/4, floats);
break;
case GL_FLOAT_MAT2:
glUniformMatrix2fv(UniformInfo[i].location, count/4, false, floats);
break;
case GL_FLOAT_MAT3:
glUniformMatrix3fv(UniformInfo[i].location, count/9, false, floats);
break;
case GL_FLOAT_MAT4:
glUniformMatrix4fv(UniformInfo[i].location, count/16, false, floats);
break;
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
{
if(floats)
{
GLint id = *floats;
glUniform1iv(UniformInfo[i].location, 1, &id);
}
}
break;
default:
status = false;
break;
}
return status;
}
bool COGLES2SLMaterialRenderer::setPixelShaderConstant( const c8* name, const s32* ints, int count )
{
u32 i;
const u32 num = UniformInfo.size();
for (i=0; i < num; ++i)
{
if (UniformInfo[i].name == name)
break;
}
if (i == num)
return false;
if(UniformInfo[i].location == -1)
return false;
bool status = true;
switch (UniformInfo[i].type)
{
case GL_INT_VEC2:
case GL_BOOL_VEC2:
glUniform2iv(UniformInfo[i].location, count/2, ints);
break;
case GL_INT_VEC3:
case GL_BOOL_VEC3:
glUniform3iv(UniformInfo[i].location, count/3, ints);
break;
case GL_INT_VEC4:
case GL_BOOL_VEC4:
glUniform4iv(UniformInfo[i].location, count/4, ints);
break;
case GL_INT:
case GL_BOOL:
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
glUniform1iv(UniformInfo[i].location, count, ints);
break;
default:
status = false;
break;
}
return status;
}
bool COGLES2SLMaterialRenderer::setUniform( int index, const void* data, int count )
{
if ((u32)index>=UniformInfo.size())
return false;
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_INT:
case GL_BOOL:
glUniform1iv( ui.location, count, static_cast<const GLint*>( data ) );
break;
case GL_INT_VEC2:
case GL_BOOL_VEC2:
glUniform2iv( ui.location, count, static_cast<const GLint*>( data ) );
break;
case GL_INT_VEC3:
case GL_BOOL_VEC3:
glUniform3iv( ui.location, count, static_cast<const GLint*>( data ) );
break;
case GL_INT_VEC4:
case GL_BOOL_VEC4:
glUniform4iv( ui.location, count, static_cast<const GLint*>( 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: // sampler
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;
const GLuint 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;
const GLuint 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

@ -1,144 +0,0 @@
// 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
{
core::stringc name;
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 bool setVertexShaderConstant(const c8* name, const s32* ints, 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 bool setPixelShaderConstant(const c8* name, const s32* ints, 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);
bool init(s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
bool registerMaterial = true);
bool initFromFiles(s32& outMaterialTypeNr,
const c8* vertexShaderFile,
const c8* pixelShaderFile,
bool registerMaterial = true);
bool 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

@ -1,6 +1,7 @@
// Copyright (C) 2009-2010 Amundis
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
@ -217,6 +218,10 @@ namespace video
// 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 );
StatesCache.BilinearFilter = true;
StatesCache.TrilinearFilter = false;
StatesCache.MipMapStatus = false;
}
void* source = 0;
@ -447,6 +452,12 @@ namespace video
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, getSize().Width, getSize().Height );
}
//! Get an access to texture states cache.
COGLES2Texture::SStatesCache& COGLES2Texture::getStatesCache() const
{
return StatesCache;
}
/* FBO Textures */
// helper function for render to texture
@ -503,6 +514,11 @@ namespace video
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
StatesCache.BilinearFilter = true;
StatesCache.WrapU = ETC_CLAMP_TO_EDGE;
StatesCache.WrapV = ETC_CLAMP_TO_EDGE;
glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, ImageSize.Width,
ImageSize.Height, 0, PixelFormat, PixelType, 0);

View File

@ -1,12 +1,14 @@
// Copyright (C) 2009-2010 Amundis
// Copyright (C) 2013 Patryk Nadrowski
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
// and OpenGL ES driver implemented by Christian Stehno
// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
// driver implemented by Amundis.
// 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 "SMaterialLayer.h"
#include "ITexture.h"
#include "IImage.h"
@ -25,6 +27,25 @@ namespace video
{
public:
//! Cache structure.
struct SStatesCache
{
SStatesCache() : WrapU(ETC_REPEAT), WrapV(ETC_REPEAT), BilinearFilter(false),
TrilinearFilter(false), AnisotropicFilter(0), MipMapStatus(false), IsCached(false), LODBias(0)
{
}
u8 WrapU;
u8 WrapV;
bool BilinearFilter;
bool TrilinearFilter;
u8 AnisotropicFilter;
bool MipMapStatus;
s8 LODBias;
bool IsCached;
};
//! constructor
COGLES2Texture(IImage* surface, const io::path& name, COGLES2Driver* driver = 0);
@ -76,6 +97,9 @@ namespace video
//! sets whether this texture is intended to be used as a render target.
void setIsRenderTarget(bool isTarget);
//! Get an access to texture states cache.
SStatesCache& getStatesCache() const;
protected:
//! protected constructor with basic setup, no GL texture name created, for derived classes
@ -104,6 +128,8 @@ namespace video
bool AutomaticMipmapUpdate;
bool UseStencil;
bool ReadOnlyLock;
mutable SStatesCache StatesCache;
};