Porting QuickGUI to Ogre3D 1.11.5 OpenGL3
Posted: Mon Jan 14, 2019 9:32 am
Ogre Version: 1.11.5
Operating System: Linux, Windows, OS X (Currently using Linux)
Render System: OpenGL3
Hello all,
I've recently begun upgrading GearCity from 1.7.1 to 1.11.5 in anticipation of finally being fully finished with the game and with the end of "classic" 1.x Ogre. I have noticed that the OpenGL1/2 renderer is a bit sluggish with Chromium Embedded Framework (it works wonderfully with Berkelium however). So I have went about implementing the OpenGL3 renderer to test it out.
For the last 20 years of programming or so, I have only worked with FFP. So the absolute need for shaders is a foreign concept to me. I used RTSS in the past for some reflective shaders for DX9 in Ogre 1.7, but I have hit a wall trying to implement FFP emulation in Ogre 1.11.5 for GL3.
Before I get into the main issue, a quick question, since I could not find any information. Is the OpenGL3 renderer significantly faster FPS wise than the OpenGL1/2 renderer? If there is only a couple percent performance gains, this is probably not worth my time.
The error I am getting is from QuickGUI. To be fair, it's the only materials I generate in my main menu. QuickGUI's brush function creates a new material at run time. It is my understanding that with a listener and a scene node, the RTSS is supposed to catch the .material at render time and create a shader for it. But it seems like it's not. This is what I get in my Ogre.logs:
QuickGUI creates the material like this every time it needs to:
I initialize RTSS as such:
Header
src
And finally, in my main menu state, I do this:
My resources.cfg points to the RTShaderLib/GLSL and RTShaderLib/materials folders (provided by the samples). And my cache path is valid.
And the rest is history, It blows up after I render a frame.
So here is my questions. Did I set up RTSS incorrectly? Shouldn't it be triggering a missing shader with the above listener and then generating one for QuickGUI? Assuming that I set it up incorrectly, would creating a texture dynamically like this be slow if RTSS had to make a shader for it each time brush was called? Would it be better for me to implement the shader on my own for this case? And if so, what should go there?
Thanks for any answers. 3:30am, I am going to bed.
Operating System: Linux, Windows, OS X (Currently using Linux)
Render System: OpenGL3
Hello all,
I've recently begun upgrading GearCity from 1.7.1 to 1.11.5 in anticipation of finally being fully finished with the game and with the end of "classic" 1.x Ogre. I have noticed that the OpenGL1/2 renderer is a bit sluggish with Chromium Embedded Framework (it works wonderfully with Berkelium however). So I have went about implementing the OpenGL3 renderer to test it out.
For the last 20 years of programming or so, I have only worked with FFP. So the absolute need for shaders is a foreign concept to me. I used RTSS in the past for some reflective shaders for DX9 in Ogre 1.7, but I have hit a wall trying to implement FFP emulation in Ogre 1.11.5 for GL3.
Before I get into the main issue, a quick question, since I could not find any information. Is the OpenGL3 renderer significantly faster FPS wise than the OpenGL1/2 renderer? If there is only a couple percent performance gains, this is probably not worth my time.
The error I am getting is from QuickGUI. To be fair, it's the only materials I generate in my main menu. QuickGUI's brush function creates a new material at run time. It is my understanding that with a listener and a scene node, the RTSS is supposed to catch the .material at render time and create a shader for it. But it seems like it's not. This is what I get in my Ogre.logs:
Code: Select all
InvalidStateException: RenderSystem does not support FixedFunction, but technique of 'QuickGUI.Material' has no Vertex Shader. Use the RTSS or write custom shaders. in SceneManager::_setPass at /home/eric/Programming/ogre-1.11.5/OgreMain/src/OgreSceneManager.cpp (line 920)
Code: Select all
Brush::Brush() :
mSceneManager(NULL),
mDefaultViewport(NULL),
mRenderTarget(NULL),
mQueuedItems(false),
mBufferPtr(NULL),
mFilterMode(BRUSHFILTER_LINEAR),
mBrushBlendMode(BRUSHBLEND_ALPHA)
{
mRenderSystem = Ogre::Root::getSingleton().getRenderSystem();
_createVertexBuffer();
// Initialise texture address modes to be used. We use this every frame, so we'll set them up now to save time later.
mTextureAddressMode.u = Ogre::TextureUnitState::TAM_CLAMP;
mTextureAddressMode.v = Ogre::TextureUnitState::TAM_CLAMP;
mTextureAddressMode.w = Ogre::TextureUnitState::TAM_CLAMP;
// Search for "GL" somewhere in name, to see if we using OpenGL
Ogre::String rSysName = mRenderSystem->getName();
mUsingOpenGL = (rSysName.find("GL") != Ogre::String::npos);
// Store Texel offset for quick use
mHorizontalTexelOffset = mRenderSystem->getHorizontalTexelOffset();
mVerticalTexelOffset = mRenderSystem->getVerticalTexelOffset();
// Create default texture
mDefaultTexture = Ogre::TextureManager::getSingleton().createManual(
"QuickGUI.Brush.DefaultTexture",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D, 64, 64, 1, 0, Ogre::PF_R8G8B8A8, Ogre::TU_DEFAULT );
// Clear default texture
void* buffer = mDefaultTexture->getBuffer()->lock(Ogre::HardwareBuffer::HBL_DISCARD);
memset(buffer, 0, mDefaultTexture->getBuffer()->getSizeInBytes());
mDefaultTexture->getBuffer()->unlock();
mColourValue = ColourValue::White;
/*
mGUIMaterial = Ogre::MaterialManager::getSingleton().load("GuiMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
mGUIPass = mGUIMaterial->getTechnique(0)->getPass(0);
mGUIPass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
*/
mGUIMaterial = Ogre::MaterialManager::getSingleton().create("QuickGUI.Material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
mGUIPass = mGUIMaterial->getTechnique(0)->getPass(0);
mGUIPass->setCullingMode(Ogre::CULL_NONE);
mGUIPass->setDepthCheckEnabled(false);
mGUIPass->setDepthWriteEnabled(false);
mGUIPass->setLightingEnabled(false);
mGUIPass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
Ogre::TextureUnitState* tus = mGUIPass->createTextureUnitState();
tus->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
tus->setTextureFiltering(Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_NONE);
}
Header
Code: Select all
#include "OgreRTShaderSystem.h"
#include "Bites/OgreSGTechniqueResolverListener.h"
...
Ogre::RTShader::ShaderGenerator* mShaderGenerator;
OgreBites::SGTechniqueResolverListener* mMaterialMgrListener;
Code: Select all
shaderCachePath=execPath + "/GearCity/Cache/";
if (Ogre::RTShader::ShaderGenerator::initialize())
{
// Grab the shader generator pointer.
mShaderGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
// Set shader cache path.
mShaderGenerator->setShaderCachePath(shaderCachePath);
if (!mMaterialMgrListener)
{
mMaterialMgrListener = new OgreBites::SGTechniqueResolverListener(mShaderGenerator);
Ogre::MaterialManager::getSingleton().addListener(mMaterialMgrListener);
}
}
Code: Select all
m_pSceneMgr = m_pRoot->createSceneManager(Ogre::SceneType::ST_GENERIC, "MenuSceneMgr");
mShaderGenerator->addSceneManager(m_pSceneMgr);
...
QuickGUI::GUIManagerDesc descGUI;
descGUI.sceneManager = m_pSceneMgr;
GuiManager = QuickGUI::Root::getSingletonPtr()->createGUIManager(descGUI);
...
update()/renderoneframe()/QuickGUI->draw();/etc...
~Crash~
And the rest is history, It blows up after I render a frame.
So here is my questions. Did I set up RTSS incorrectly? Shouldn't it be triggering a missing shader with the above listener and then generating one for QuickGUI? Assuming that I set it up incorrectly, would creating a texture dynamically like this be slow if RTSS had to make a shader for it each time brush was called? Would it be better for me to implement the shader on my own for this case? And if so, what should go there?
Thanks for any answers. 3:30am, I am going to bed.