- Fixed 2d material rendering in OGL ES2.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@4436 dfc29bdd-3216-0410-991c-e03cc46cb475
master
nadro 2013-01-15 19:23:46 +00:00
parent 40b42e6010
commit a682d8393d
8 changed files with 257 additions and 199 deletions

View File

@ -3,27 +3,21 @@
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
precision mediump float;
uniform bool uUseTexture;
uniform sampler2D uTextureUnit;
uniform bool uAlphaTest;
uniform float uAlphaValue;
varying vec4 varVertexColor;
varying vec4 varTexCoord;
varying vec4 vVertexColor;
varying vec2 vTexCoord;
void main(void)
{
vec4 color = varVertexColor;
vec4 texel = texture2D(uTextureUnit, varTexCoord.xy);
vec4 Color = vVertexColor;
if(uUseTexture)
{
color *= texel;
}
Color *= texture2D(uTextureUnit, vTexCoord);
if(uAlphaTest && !(color.a > uAlphaValue))
discard;
gl_FragColor = color;
gl_FragColor = Color;
}

View File

@ -3,18 +3,19 @@
// and OpenGL ES driver implemented by Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
attribute vec4 inVertexPosition;
attribute vec4 inVertexColor;
attribute vec4 inTexCoord0;
attribute vec2 inTexCoord0;
uniform mat4 uOrthoMatrix;
varying vec4 varVertexColor;
varying vec4 varTexCoord;
varying vec4 vVertexColor;
varying vec2 vTexCoord;
void main(void)
{
gl_Position = uOrthoMatrix * inVertexPosition;
varVertexColor = inVertexColor.bgra;
varTexCoord = inTexCoord0;
gl_Position = uOrthoMatrix * inVertexPosition;
vVertexColor = inVertexColor.bgra;
vTexCoord = inTexCoord0;
}

View File

@ -279,6 +279,7 @@ namespace video
COGLES2Driver::~COGLES2Driver()
{
deleteMaterialRenders();
delete MaterialRenderer2D;
deleteAllTextures();
if (BridgeCalls)
@ -312,8 +313,6 @@ namespace video
ViewDepthRenderbuffer = 0;
}
#endif
// delete TwoDRenderer;
}
// -----------------------------------------------------------------------
@ -361,8 +360,6 @@ namespace video
DriverAttributes->setAttribute("Version", Version);
DriverAttributes->setAttribute("AntiAlias", AntiAlias);
// TwoDRenderer = new COGLES2Renderer2d(this, FileSystem);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
// Reset The Current Viewport
@ -441,6 +438,12 @@ namespace video
FPFSData[Size] = 0;
}
if (FPVSFile)
FPVSFile->drop();
if (FPFSFile)
FPFSFile->drop();
// Normal Mapping.
core::stringc NMVSPath = IRR_OGLES2_SHADER_PATH;
@ -477,6 +480,12 @@ namespace video
NMFSData[Size] = 0;
}
if (NMVSFile)
NMVSFile->drop();
if (NMFSFile)
NMFSFile->drop();
// Parallax Mapping.
core::stringc PMVSPath = IRR_OGLES2_SHADER_PATH;
@ -513,6 +522,12 @@ namespace video
PMFSData[Size] = 0;
}
if (PMVSFile)
PMVSFile->drop();
if (PMFSFile)
PMFSFile->drop();
// Create materials.
addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_SOLID, this));
@ -540,6 +555,50 @@ namespace video
addAndDropMaterialRenderer(new COGLES2ParallaxMapRenderer(PMVSData, PMFSData, EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA, this));
addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_ONETEXTURE_BLEND, this));
// Create 2D material renderer.
core::stringc R2DVSPath = IRR_OGLES2_SHADER_PATH;
R2DVSPath += "COGLES2Renderer2D.vsh";
core::stringc R2DFSPath = IRR_OGLES2_SHADER_PATH;
R2DFSPath += "COGLES2Renderer2D.fsh";
io::IReadFile* R2DVSFile = FileSystem->createAndOpenFile(R2DVSPath);
io::IReadFile* R2DFSFile = FileSystem->createAndOpenFile(R2DFSPath);
c8* R2DVSData = 0;
c8* R2DFSData = 0;
Size = R2DVSFile->getSize();
if (Size)
{
R2DVSData = new c8[Size+1];
R2DVSFile->read(R2DVSData, Size);
R2DVSData[Size] = 0;
}
Size = R2DFSFile->getSize();
if (Size)
{
// if both handles are the same we must reset the file
if (R2DFSFile == PMVSFile)
R2DFSFile->seek(0);
R2DFSData = new c8[Size+1];
R2DFSFile->read(R2DFSData, Size);
R2DFSData[Size] = 0;
}
if (R2DVSFile)
R2DVSFile->drop();
if (R2DFSFile)
R2DFSFile->drop();
MaterialRenderer2D = new COGLES2Renderer2D(R2DVSData, R2DFSData, this);
}
@ -1800,7 +1859,10 @@ namespace video
{
// unset old material
if (LastMaterial.MaterialType != Material.MaterialType &&
// unset last 3d material
if (CurrentRenderMode == ERM_2D)
MaterialRenderer2D->OnUnsetMaterial();
else if (LastMaterial.MaterialType != Material.MaterialType &&
static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size())
MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
@ -2051,7 +2113,7 @@ namespace video
//! sets the needed renderstates
void COGLES2Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel)
{
if (CurrentRenderMode != ERM_2D || Transformation3DChanged)
if (CurrentRenderMode != ERM_2D)
{
// unset last 3d material
if (CurrentRenderMode == ERM_3D)
@ -2060,66 +2122,42 @@ namespace video
MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
}
//TwoDRenderer->useProgram(); //Fixed Pipeline Shader needed to render 2D
if (Transformation3DChanged)
{
const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
core::matrix4 m(core::matrix4::EM4CONST_NOTHING);
m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f);
m.setTranslation(core::vector3df(-1,1,0));
//TwoDRenderer->setOrthoMatrix(m);
// Make sure we set first texture matrix
BridgeCalls->setActiveTexture(GL_TEXTURE0);
Transformation3DChanged = false;
}
if (!OverrideMaterial2DEnabled)
{
setBasicRenderStates(InitMaterial2D, LastMaterial, true);
LastMaterial = InitMaterial2D;
}
BridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
CurrentRenderMode = ERM_2D;
}
if (!OverrideMaterial2DEnabled)
Material = InitMaterial2D;
if (OverrideMaterial2DEnabled)
{
OverrideMaterial2D.Lighting=false;
setBasicRenderStates(OverrideMaterial2D, LastMaterial, false);
LastMaterial = OverrideMaterial2D;
OverrideMaterial2D.ZWriteEnable=false;
OverrideMaterial2D.ZBuffer=ECFN_NEVER; // it will be ECFN_DISABLED after merge
OverrideMaterial2D.Lighting=false;
Material = OverrideMaterial2D;
}
if (texture)
MaterialRenderer2D->setTexture(CurrentTexture[0]);
else
MaterialRenderer2D->setTexture(0);
MaterialRenderer2D->OnSetMaterial(Material, LastMaterial, true, 0);
LastMaterial = Material;
// no alphaChannel without texture
alphaChannel &= texture;
if (alphaChannel || alpha)
{
BridgeCalls->setBlend(true);
//TwoDRenderer->useAlphaTest(true);
//TwoDRenderer->setAlphaTestValue(0.f);
BridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
{
BridgeCalls->setBlend(false);
//TwoDRenderer->useAlphaTest(false);
}
if (texture)
{
if (OverrideMaterial2DEnabled)
setTextureRenderStates(OverrideMaterial2D, false);
else
setTextureRenderStates(InitMaterial2D, false);
Material.setTexture(0, const_cast<video::ITexture*>(CurrentTexture[0]));
setTransform(ETS_TEXTURE_0, core::IdentityMatrix);
// Due to the transformation change, the previous line would call a reset each frame
// but we can safely reset the variable as it was false before
Transformation3DChanged=false;
}
CurrentRenderMode = ERM_2D;
MaterialRenderer2D->OnRender(this, video::EVT_STANDARD);
}
@ -2837,7 +2875,7 @@ namespace video
BlendSource(GL_ONE), BlendDestination(GL_ZERO), Blend(false),
CullFaceMode(GL_BACK), CullFace(false),
DepthFunc(GL_LESS), DepthMask(true), DepthTest(false),
ActiveTexture(GL_TEXTURE0)
Program(0), ActiveTexture(GL_TEXTURE0)
{
// Initial OpenGL values from specification.
@ -2937,6 +2975,15 @@ namespace video
DepthTest = enable;
}
}
void COGLES2CallBridge::setProgram(GLuint program)
{
if (Program != program)
{
glUseProgram(program);
Program = program;
}
}
void COGLES2CallBridge::setActiveTexture(GLenum texture)
{

View File

@ -51,11 +51,10 @@ namespace video
class COGLES2CallBridge;
class COGLES2Texture;
class COGLES2FixedPipelineRenderer;
class COGLES2Renderer2D;
class COGLES2NormalMapRenderer;
class COGLES2ParallaxMapRenderer;
//class COGLES2Renderer2d;
class COGLES2Driver : public CNullDriver, public IMaterialRendererServices, public COGLES2ExtensionHandler
{
friend class COGLES2CallBridge;
@ -356,6 +355,9 @@ namespace video
void deleteFramebuffers(s32 n, const u32 *framebuffers);
void deleteRenderbuffers(s32 n, const u32 *renderbuffers);
// returns the current size of the screen or rendertarget
virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const;
//! Convert E_BLEND_FACTOR to OpenGL equivalent
GLenum getGLBlend(E_BLEND_FACTOR factor) const;
@ -391,9 +393,6 @@ namespace video
//! sets the needed renderstates
void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel);
// returns the current size of the screen or rendertarget
virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const;
void createMaterialRenderers();
core::stringw Name;
@ -449,6 +448,8 @@ namespace video
core::array<RequestedLight> RequestedLights;
SColorf AmbientLight;
COGLES2Renderer2D* MaterialRenderer2D;
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
HDC HDc;
#endif
@ -463,8 +464,6 @@ namespace video
void* EglSurface;
void* EglContext;
#endif
//COGLES2Renderer2d* TwoDRenderer;
};
//! This bridge between Irlicht pseudo OpenGL calls
@ -494,6 +493,10 @@ namespace video
void setDepthMask(bool enable);
void setDepthTest(bool enable);
// Program calls.
void setProgram(GLuint program);
// Texture calls.
@ -514,6 +517,8 @@ namespace video
GLenum DepthFunc;
bool DepthMask;
bool DepthTest;
GLuint Program;
GLenum ActiveTexture;

View File

@ -66,6 +66,8 @@ bool COGLES2FixedPipelineRenderer::OnRender(IMaterialRendererServices* service,
return SharedRenderer->OnRender(service, vtxtype);
else
{
Driver->setTextureRenderStates(Driver->getCurrentMaterial(), false);
/* Vertex Shader part */
/* Matrices Upload */

View File

@ -156,29 +156,27 @@ void COGLES2MaterialRenderer::OnSetMaterial(const video::SMaterial& material,
bool resetAllRenderstates,
video::IMaterialRendererServices* services)
{
Driver->getBridgeCalls()->setProgram(Program);
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
if (FixedBlending)
{
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);
}
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);
}
else
Driver->getBridgeCalls()->setBlend(false);
if (CallBack)
CallBack->OnSetMaterial(material);
@ -187,11 +185,6 @@ void COGLES2MaterialRenderer::OnSetMaterial(const video::SMaterial& material,
void COGLES2MaterialRenderer::OnUnsetMaterial()
{
if (Program)
glUseProgram(0);
if (Blending || FixedBlending)
Driver->getBridgeCalls()->setBlend(false);
}

View File

@ -1,84 +1,100 @@
// 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 "COGLES2Renderer2D.h"
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2Renderer2D.h"
#include "IGPUProgrammingServices.h"
#include "os.h"
#include "COGLES2Driver.h"
namespace irr
{
namespace video
{
const char* const COGLES2Renderer2d::sBuiltInShaderUniformNames[] =
{
"uOrthoMatrix",
"uUseTexture",
"uTextureUnit",
"uAlphaTest",
"uAlphaValue",
0
};
//! Constructor
COGLES2Renderer2D::COGLES2Renderer2D(const c8* vertexShaderProgram, const c8* pixelShaderProgram, COGLES2Driver* driver)
: COGLES2MaterialRenderer(driver, 0, EMT_SOLID), RenderTargetSize(core::dimension2d<u32>(0,0)),
Matrix(core::matrix4::EM4CONST_NOTHING), Texture(0)
{
#ifdef _DEBUG
setDebugName("COGLES2Renderer2D");
#endif
static const char* vertexShaderFile = IRR_OGLES2_SHADER_PATH "COGLES2Renderer2D.vsh";
static const char* fragmentShaderFile = IRR_OGLES2_SHADER_PATH "COGLES2Renderer2D.fsh";
int Temp = 0;
COGLES2Renderer2d::COGLES2Renderer2d( irr::video::COGLES2Driver *driver, irr::io::IFileSystem *fs )
: COGLES2MaterialRenderer( driver )
{
#ifdef _DEBUG
setDebugName( "COGLES2Renderer2d" );
#endif
/*s32 dummy = -1;
if (!initFromFiles( dummy, vertexShaderFile, fragmentShaderFile, false))
return;
useProgram();
int texUnit = 0;
setUniform( TEXTURE_UNIT, &texUnit );*/
}
init(Temp, vertexShaderProgram, pixelShaderProgram, false);
void COGLES2Renderer2d::useTexture( bool param )
{
/*if ( param != UseTexture )
{
UseTexture = param;
int dummy = param ? 1 : 0;
setUniform( USE_TEXTURE, &dummy );
}*/
}
Driver->getBridgeCalls()->setProgram(Program);
void COGLES2Renderer2d::useAlphaTest( bool param )
{
/*if ( param != UseAlphaTest )
{
UseAlphaTest = param;
int dummy = param ? 1 : 0;
setUniform( ALPHA_TEST, &dummy );
}*/
}
// These states doesn't change later.
void COGLES2Renderer2d::setAlphaTestValue( float value )
{
/*if ( value != AlphaTestValue )
{
AlphaTestValue = value;
setUniform( ALPHA_VALUE, &AlphaTestValue );
}*/
}
MatrixID = getPixelShaderConstantID("uOrthoMatrix");
UseTextureID = getPixelShaderConstantID("uUseTexture");
s32 TextureUnitID = getPixelShaderConstantID("uTextureUnit");
void COGLES2Renderer2d::setOrthoMatrix( const core::matrix4 &matrix )
{
/*if ( matrix != OrthoMatrix )
{
OrthoMatrix = matrix;
setUniform( ORTHO_MATRIX, OrthoMatrix.pointer() );
}*/
}
}
int TextureUnit = 0;
setPixelShaderConstant(TextureUnitID, &TextureUnit, 1);
Driver->getBridgeCalls()->setProgram(0);
}
#endif
//! Destructor
COGLES2Renderer2D::~COGLES2Renderer2D()
{
}
void COGLES2Renderer2D::OnSetMaterial(const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates,
video::IMaterialRendererServices* services)
{
Driver->getBridgeCalls()->setProgram(Program);
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
}
bool COGLES2Renderer2D::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{
Driver->setTextureRenderStates(Driver->getCurrentMaterial(), false);
const core::dimension2d<u32>& renderTargetSize = Driver->getCurrentRenderTargetSize();
if (RenderTargetSize != renderTargetSize)
{
Matrix.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f);
Matrix.setTranslation(core::vector3df(-1,1,0));
setPixelShaderConstant(MatrixID, Matrix.pointer(), 16);
RenderTargetSize = renderTargetSize;
}
int UseTexture = Texture ? 1 : 0;
setPixelShaderConstant(UseTextureID, &UseTexture, 1);
return true;
}
void COGLES2Renderer2D::setTexture(const ITexture* texture)
{
Texture = texture;
}
} // end namespace video
} // end namespace irr
#endif

View File

@ -1,55 +1,55 @@
// 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_RENDERER_2D_H_INCLUDED__
#define __C_OGLES2_RENDERER_2D_H_INCLUDED__
#include "COGLES2MaterialRenderer.h"
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "COGLES2MaterialRenderer.h"
namespace irr
{
namespace io
{
class IFileSystem;
}
namespace video
{
class COGLES2Driver;
class COGLES2Renderer2d : public COGLES2MaterialRenderer
{
public:
COGLES2Renderer2d( COGLES2Driver* driver, io::IFileSystem* fs );
//! Class for renderer 2D in OpenGL ES 2.0
class COGLES2Renderer2D : public COGLES2MaterialRenderer
{
public:
//! Constructor
COGLES2Renderer2D(const c8* vertexShaderProgram, const c8* pixelShaderProgram, COGLES2Driver* driver);
void useTexture( bool param );
void useAlphaTest( bool param );
void setAlphaTestValue( float param );
void setOrthoMatrix( const core::matrix4& matrix );
private :
bool UseTexture;
bool UseAlphaTest;
float AlphaTestValue;
core::matrix4 OrthoMatrix;
private:
enum SHADER_UNIFORM
{
ORTHO_MATRIX = 0,
USE_TEXTURE,
TEXTURE_UNIT,
ALPHA_TEST,
ALPHA_VALUE,
UNIFORM_COUNT
};
static const char* const sBuiltInShaderUniformNames[];
};
//! Destructor
~COGLES2Renderer2D();
}
}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services);
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype);
void setTexture(const ITexture* texture);
protected:
core::dimension2d<u32> RenderTargetSize;
core::matrix4 Matrix;
const ITexture* Texture;
s32 MatrixID;
s32 UseTextureID;
};
} // end namespace video
} // end namespace irr
#endif
#endif