thanks masterfalcon for giving me pointers in fixing my last issue. Really helps me a lot. I am now trying to implement GLES2.0 onto my current project as my studio wants to achieve better graphics (shaders and such). Currently as it stands, 1.8 works well with GLES1.1. However, when I switched to GLES2.0, my app crashes when my custom RenderQueueListener for our UI system tries to render. The RenderQueueListener is modified from the SpriteManager2d from the wiki. Here's what I did:
Code: Select all
Gui::Gui()
{
sprWatermark_=0;
wmFont_=0;
wmText_=0;
init(Graphics::GetSingleton()->getSceneManager(),Ogre::RENDER_QUEUE_OVERLAY, true);
}
void Gui::init(Ogre::SceneManager* sceneMan, Ogre::uint8 targetQueue, bool afterQueue)
{
Gui::sceneMan=sceneMan;
Gui::afterQueue=afterQueue;
Gui::targetQueue=targetQueue;
hardwareBuffer.setNull();
sceneMan->addRenderQueueListener(this);
}
Gui::~Gui()
{
Clear();
end();
}
Gui* Gui::GetSingleton()
{
static Gui* gui = 0;
if (gui == 0)
gui = new Gui();
return gui;
}
void Gui::end()
{
if (!hardwareBuffer.isNull())
destroyHardwareBuffer();
sceneMan->removeRenderQueueListener(this);
}
void Gui::destroyHardwareBuffer()
{
delete renderOp.vertexData;
renderOp.vertexData=0;
hardwareBuffer.setNull();
}
//------------------------------OGRE SPRITES RENDER QUEUE--------------------------------------
#pragma mark Sprites functions
void Gui::renderQueueStarted(
Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation)
{
if (!afterQueue && queueGroupId==targetQueue)
{
renderBuffer();
}
}
void Gui::renderQueueEnded(
Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation)
{
if (afterQueue && queueGroupId==targetQueue)
{
renderBuffer();
}
}
void Gui::renderBuffer()
{
Ogre::RenderSystem* rs=Ogre::Root::getSingleton().getRenderSystem();
std::list<Sprite*>::iterator currSpr, endSpr;
VertexChunk thisChunk;
std::list<VertexChunk> chunks;
unsigned int newSize;
std::list<Sprite*> rsprites;
for (std::list<Sprite*>::iterator currSpr = sprites.begin(); currSpr != sprites.end(); currSpr++)
{
Sprite* tmp = *currSpr;
if(!tmp->IsHidden())
{
rsprites.push_back(tmp);
}
}
newSize=rsprites.size()*6;
if (newSize<OGRE2D_MINIMAL_HARDWARE_BUFFER_SIZE)
newSize=OGRE2D_MINIMAL_HARDWARE_BUFFER_SIZE;
// grow hardware buffer if needed
if (hardwareBuffer.isNull() || hardwareBuffer->getNumVertices()<newSize)
{
if (!hardwareBuffer.isNull())
destroyHardwareBuffer();
createHardwareBuffer(newSize);
}
if (rsprites.empty()) return;
// write quads to the hardware buffer, and remember chunks
float* buffer;
float z=-1;
buffer=(float*)hardwareBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
endSpr=rsprites.end();
currSpr=rsprites.begin();
thisChunk.texHandle=(*currSpr)->texHandle;
thisChunk.vertexCount=0;
thisChunk.alphaVal = (*currSpr)->alpha_;
thisChunk.colourVal = (*currSpr)->colour_;
thisChunk.rotAngle = (*currSpr)->rotAngle_;
while (currSpr!=endSpr)
{
if((*currSpr)->rotAngle_==0)
//if(true)
{
// 1st point (left bottom)
*buffer=(*currSpr)->relx1; buffer++;
*buffer=(*currSpr)->rely1; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx1; buffer++;
*buffer=(*currSpr)->ty1; buffer++;
// 2st point (right top)
*buffer=(*currSpr)->relx2; buffer++;
*buffer=(*currSpr)->rely2; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx2; buffer++;
*buffer=(*currSpr)->ty2; buffer++;
// 3rd point (left top)
*buffer=(*currSpr)->relx2; buffer++;
*buffer=(*currSpr)->rely1; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx1; buffer++;
*buffer=(*currSpr)->ty2; buffer++;
// 4th point (left bottom)
*buffer=(*currSpr)->relx1; buffer++;
*buffer=(*currSpr)->rely1; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx1; buffer++;
*buffer=(*currSpr)->ty1; buffer++;
// 5th point (right bottom)
*buffer=(*currSpr)->relx1; buffer++;
*buffer=(*currSpr)->rely2; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx2; buffer++;
*buffer=(*currSpr)->ty1; buffer++;
// 6th point (right top)
*buffer=(*currSpr)->relx2; buffer++;
*buffer=(*currSpr)->rely2; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx2; buffer++;
*buffer=(*currSpr)->ty2; buffer++;
}else {
// 1st point (left bottom)
*buffer=(*currSpr)->bl.x; buffer++;
*buffer=(*currSpr)->bl.y; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx1; buffer++;
*buffer=(*currSpr)->ty1; buffer++;
// 2st point (right top)
*buffer=(*currSpr)->tr.x; buffer++;
*buffer=(*currSpr)->tr.y; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx2; buffer++;
*buffer=(*currSpr)->ty2; buffer++;
// 3rd point (left top)
*buffer=(*currSpr)->tl.x; buffer++;
*buffer=(*currSpr)->tl.y; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx1; buffer++;
*buffer=(*currSpr)->ty2; buffer++;
// 4th point (left bottom)
*buffer=(*currSpr)->bl.x; buffer++;
*buffer=(*currSpr)->bl.y; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx1; buffer++;
*buffer=(*currSpr)->ty1; buffer++;
// 5th point (right bottom)
*buffer=(*currSpr)->br.x; buffer++;
*buffer=(*currSpr)->br.y; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx2; buffer++;
*buffer=(*currSpr)->ty1; buffer++;
// 6th point (right top)
*buffer=(*currSpr)->tr.x; buffer++;
*buffer=(*currSpr)->tr.y; buffer++;
*buffer=z; buffer++;
*buffer=(*currSpr)->tx2; buffer++;
*buffer=(*currSpr)->ty2; buffer++;
}
// remember this chunk
thisChunk.vertexCount+=6;
//}
currSpr++;
if (currSpr==endSpr || thisChunk.texHandle!=(*currSpr)->texHandle || thisChunk.alphaVal!=(*currSpr)->alpha_ || thisChunk.colourVal!=(*currSpr)->colour_)
{
chunks.push_back(thisChunk);
if (currSpr!=endSpr)
{
thisChunk.texHandle=(*currSpr)->texHandle;
thisChunk.vertexCount=0;
thisChunk.colourVal = (*currSpr)->colour_;
thisChunk.alphaVal = (*currSpr)->alpha_;
thisChunk.rotAngle = (*currSpr)->rotAngle_;
thisChunk.relativex1 = (*currSpr)->relx1;
thisChunk.relativey1 = (*currSpr)->rely1;
thisChunk.relativex2 = (*currSpr)->relx2;
thisChunk.relativey2 = (*currSpr)->rely2;
}
}
}
hardwareBuffer->unlock();
// set up...
prepareForRender();
// do the real render!
Ogre::TexturePtr tp;
std::list<VertexChunk>::iterator currChunk, endChunk;
endChunk=chunks.end();
renderOp.vertexData->vertexStart=0;
for (currChunk=chunks.begin(); currChunk!=endChunk; currChunk++)
{
prepareAlpha(currChunk->alphaVal);
prepareColour(currChunk->colourVal);
//prepareRotation(currChunk->rotAngle,currChunk->relativex1,currChunk->relativey1,currChunk->relativex2,currChunk->relativey2);
renderOp.vertexData->vertexCount=currChunk->vertexCount;
tp=Ogre::TextureManager::getSingleton().getByHandle(currChunk->texHandle);
rs->_setTexture(0, true, tp->getName());
rs->_render(renderOp);
renderOp.vertexData->vertexStart+=currChunk->vertexCount;
}
rs->_setProjectionMatrix(Ogre::Matrix4::IDENTITY);
// sprites go home!
rsprites.clear();
}
void Gui::prepareAlpha(double aval)
{
Ogre::LayerBlendModeEx alphaBlendMode;
Ogre::RenderSystem* rs=Ogre::Root::getSingleton().getRenderSystem();
alphaBlendMode.alphaArg1 = 0;
alphaBlendMode.alphaArg2 = aval;
alphaBlendMode.source1 = Ogre::LBS_TEXTURE;
alphaBlendMode.source2 = Ogre::LBS_MANUAL;
alphaBlendMode.blendType = Ogre::LBT_COLOUR;
alphaBlendMode.operation = Ogre::LBX_MODULATE;
alphaBlendMode.factor = aval;
rs->_setTextureBlendMode(0, alphaBlendMode);
rs->_setAlphaRejectSettings(Ogre::CMPF_GREATER_EQUAL,0,true);
}
void Gui::prepareColour(Ogre::ColourValue cval)
{
Ogre::LayerBlendModeEx colourBlendMode;
Ogre::RenderSystem* rs=Ogre::Root::getSingleton().getRenderSystem();
colourBlendMode.colourArg1 = Ogre::ColourValue::ZERO;
colourBlendMode.colourArg2 = cval;
colourBlendMode.source1 = Ogre::LBS_TEXTURE;
colourBlendMode.source2 = Ogre::LBS_MANUAL;
colourBlendMode.blendType = Ogre::LBT_COLOUR;
colourBlendMode.operation = Ogre::LBX_MODULATE;
colourBlendMode.factor = 1.0;
rs->_setTextureBlendMode(0, colourBlendMode);
}
void Gui::prepareForRender()
{
Ogre::LayerBlendModeEx colorBlendMode;
Ogre::LayerBlendModeEx alphaBlendMode;
Ogre::TextureUnitState::UVWAddressingMode uvwAddressMode;
Ogre::RenderSystem* rs=Ogre::Root::getSingleton().getRenderSystem();
colorBlendMode.blendType=Ogre::LBT_COLOUR;
colorBlendMode.source1=Ogre::LBS_TEXTURE;
colorBlendMode.operation=Ogre::LBX_SOURCE1;
// set alpha
//LayerBlendModeEx_NativePtr alphaBlendMode = LayerBlendModeEx_NativePtr.Create();
alphaBlendMode.alphaArg1 = 0;
alphaBlendMode.alphaArg2 = 0.5;
alphaBlendMode.source1 = Ogre::LBS_TEXTURE;
alphaBlendMode.source2 = Ogre::LBS_MANUAL;
alphaBlendMode.blendType = Ogre::LBT_ALPHA;
alphaBlendMode.operation = Ogre::LBX_MODULATE;
alphaBlendMode.factor = 1.0;
rs->_setTextureBlendMode(0, alphaBlendMode);
// alphaBlendMode.blendType=Ogre::LBT_ALPHA;
// alphaBlendMode.source1=Ogre::LBS_TEXTURE;
// alphaBlendMode.operation=Ogre::LBX_SOURCE1;
uvwAddressMode.u=Ogre::TextureUnitState::TAM_CLAMP;
uvwAddressMode.v=Ogre::TextureUnitState::TAM_CLAMP;
uvwAddressMode.w=Ogre::TextureUnitState::TAM_CLAMP;
rs->_setWorldMatrix(Ogre::Matrix4::IDENTITY);
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS
Ogre::Matrix3 rotmat;
rotmat.FromAxisAngle(Ogre::Vector3(0,0,1), Ogre::Radian(Ogre::Degree(90)));
Ogre::Matrix4 trans1;
trans1.makeTrans(-1, -1, 0);
Ogre::Matrix4 trans2;
trans2.makeTrans(1, 1, 0);
float ratio1;
float ratio2;
if (Graphics::GetSingleton()->GetDeviceMode() == Graphics::IPAD)
{
ratio1 = 1.3333333333f;
ratio2 = 0.75f;
}
else if (Graphics::GetSingleton()->GetDeviceMode() == Graphics::IPHONE || Graphics::GetSingleton()->GetDeviceMode() == Graphics::IPHONE4)
{
ratio1 = 1.5f;
ratio2 = 0.6666666666f;
}
Ogre::Matrix4 scalemat(ratio1,0,0,0,
0,ratio2,0,0,
0,0,0,0,
0,0,0,1);
rs->_setViewMatrix(Ogre::Matrix4(rotmat)* trans2 * scalemat * trans1);
#endif
rs->_setProjectionMatrix(Ogre::Matrix4::IDENTITY);
rs->_setTextureMatrix(0, Ogre::Matrix4::IDENTITY);
rs->_setTextureCoordSet(0, 0);
rs->_setTextureCoordCalculation(0, Ogre::TEXCALC_NONE);
std::cout << "Setting Texture unit filtering" << std::endl;
rs->_setTextureUnitFiltering(0, Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_POINT);
std::cout << "Finish setting texture unit filtering" << std::endl;
rs->_setTextureBlendMode(0, colorBlendMode);
rs->_setTextureBlendMode(0, alphaBlendMode);
rs->_setTextureAddressingMode(0, uvwAddressMode);
rs->_disableTextureUnitsFrom(1);
rs->setLightingEnabled(false);
rs->_setFog(Ogre::FOG_NONE);
rs->_setCullingMode(Ogre::CULL_NONE);
rs->_setDepthBufferParams(false, false);
rs->_setColourBufferWriteEnabled(true, true, true, false);
rs->setShadingType(Ogre::SO_GOURAUD);
rs->_setPolygonMode(Ogre::PM_SOLID);
rs->unbindGpuProgram(Ogre::GPT_FRAGMENT_PROGRAM);
rs->unbindGpuProgram(Ogre::GPT_VERTEX_PROGRAM);
rs->_setSceneBlending(Ogre::SBF_SOURCE_ALPHA, Ogre::SBF_ONE_MINUS_SOURCE_ALPHA);
rs->_setAlphaRejectSettings(Ogre::CMPF_ALWAYS_PASS, 0, true);
}
void Gui::createHardwareBuffer(unsigned int size)
{
Ogre::VertexDeclaration* vd;
renderOp.vertexData=new Ogre::VertexData;
renderOp.vertexData->vertexStart=0;
vd=renderOp.vertexData->vertexDeclaration;
vd->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
vd->addElement(0, Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
hardwareBuffer=Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
vd->getVertexSize(0),
size,// buffer size
Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
false);// use shadow buffer? no
renderOp.vertexData->vertexBufferBinding->setBinding(0, hardwareBuffer);
renderOp.operationType=Ogre::RenderOperation::OT_TRIANGLE_LIST;
renderOp.useIndexes=false;
}
void Gui::spriteBltFull(Sprite* spr)
{
Ogre::TexturePtr tp;
tp=Ogre::TextureManager::getSingleton().getByName(spr->texturePath);
spr->texHandle=tp->getHandle();
sprites.push_back(spr);
}
Code: Select all
OpenGL error 0x0500 in virtual void Ogre::GLES2RenderSystem::_setTextureUnitFiltering(size_t, Ogre::FilterType, Ogre::FilterOptions) at line 1439 in /Users/developer/projectsHg/be2/ogre/RenderSystems/GLES2/src/OgreGLES2RenderSystem.cpp
OpenGL error 0x0500 in virtual void Ogre::GLES2RenderSystem::_setTextureUnitFiltering(size_t, Ogre::FilterType, Ogre::FilterOptions) at line 1450 in /Users/developer/projectsHg/be2/ogre/RenderSystems/GLES2/src/OgreGLES2RenderSystem.cpp
OpenGL error 0x0500 in virtual void Ogre::GLES2RenderSystem::_setTextureUnitFiltering(size_t, Ogre::FilterType, Ogre::FilterOptions) at line 1476 in /Users/developer/projectsHg/be2/ogre/RenderSystems/GLES2/src/OgreGLES2RenderSystem.cpp
OpenGL error 0x0500 in virtual void Ogre::GLES2RenderSystem::_setTextureAddressingMode(size_t, const Ogre::TextureUnitState::UVWAddressingMode&) at line 766 in /Users/developer/projectsHg/be2/ogre/RenderSystems/GLES2/src/OgreGLES2RenderSystem.cpp
OpenGL error 0x0500 in virtual void Ogre::GLES2RenderSystem::_setTextureAddressingMode(size_t, const Ogre::TextureUnitState::UVWAddressingMode&) at line 768 in /Users/developer/projectsHg/be2/ogre/RenderSystems/GLES2/src/OgreGLES2RenderSystem.cpp
Have I done anything which I am not supposed to do in GLES2.0. Any advice would be appreciated.
Thanks a million.