Porting QuickGUI to Ogre3D 1.11.5 OpenGL3

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
EricB
Gnome
Posts: 314
Joined: Fri Apr 09, 2010 5:28 am
Location: Florida
x 103
Contact:

Porting QuickGUI to Ogre3D 1.11.5 OpenGL3

Post by EricB » 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:

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)
QuickGUI creates the material like this every time it needs to:

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);
	}
I initialize RTSS as such:

Header

Code: Select all

#include "OgreRTShaderSystem.h"
#include "Bites/OgreSGTechniqueResolverListener.h"
...
Ogre::RTShader::ShaderGenerator*  mShaderGenerator;
OgreBites::SGTechniqueResolverListener* mMaterialMgrListener;
src

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);
              }
}
And finally, in my main menu state, I do this:

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~
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. :)
0 x
Image

paroj
OGRE Team Member
OGRE Team Member
Posts: 798
Joined: Sun Mar 30, 2014 2:51 pm
x 127
Contact:

Re: Porting QuickGUI to Ogre3D 1.11.5 OpenGL3

Post by paroj » Mon Jan 14, 2019 12:12 pm

EricB wrote:
Mon Jan 14, 2019 9:32 am
, since I could not find any information. Is the OpenGL3 renderer significantly faster FPS wise than the OpenGL1/2 renderer?
no, its likely slower: https://github.com/OGRECave/ogre/issues/662

The thing is that the FFP path got very optimized in the GL drivers - beyond the point what Ogre could do by its FFP emulation. So if all you need is vertex lighting, then shaders will not give you anything.
Of course if you want pixel lighting you already must use shaders.

Also if you have many objects to render (1000+), GL3 gives you access to acceleration primitives like instancing or bindless textures. But these techniques are not used out of the box with Ogre1 - this is what Ogre2 is offering. But again if you only render one car inside one room, you will not notice any improvement.

The bottleneck for you is likely texture copying; e.g. PF_R8G8B8A8 has ABGR byte order on little endian machines, which is neither Windows nor Linux native -> copy + byte reorder. Also GPU > CPU > GPU ping-pong will kill performance.
EricB wrote:
Mon Jan 14, 2019 9:32 am
So here is my questions. Did I set up RTSS incorrectly?
from the code you posted, it seems correct. You should however try adding Quickgui here:
https://github.com/OGRECave/ogre/blob/m ... tstrap.cpp

which correctly sets up RTSS for GL3+.
0 x

User avatar
EricB
Gnome
Posts: 314
Joined: Fri Apr 09, 2010 5:28 am
Location: Florida
x 103
Contact:

Re: Porting QuickGUI to Ogre3D 1.11.5 OpenGL3

Post by EricB » Mon Jan 14, 2019 3:54 pm

paroj wrote:
Mon Jan 14, 2019 12:12 pm
EricB wrote:
Mon Jan 14, 2019 9:32 am
, since I could not find any information. Is the OpenGL3 renderer significantly faster FPS wise than the OpenGL1/2 renderer?
no, its likely slower: https://github.com/OGRECave/ogre/issues/662
Thanks! I thought I saw this page before, but I couldn't find it again. Maybe my google-fu is getting bad with age.
The thing is that the FFP path got very optimized in the GL drivers - beyond the point what Ogre could do by its FFP emulation. So if all you need is vertex lighting, then shaders will not give you anything.
Of course if you want pixel lighting you already must use shaders.

Also if you have many objects to render (1000+), GL3 gives you access to acceleration primitives like instancing or bindless textures. But these techniques are not used out of the box with Ogre1 - this is what Ogre2 is offering. But again if you only render one car inside one room, you will not notice any improvement.
Yeah, my game is like 99% GUI. So I would only be using vertex lighting shaders.
The bottleneck for you is likely texture copying; e.g. PF_R8G8B8A8 has ABGR byte order on little endian machines, which is neither Windows nor Linux native -> copy + byte reorder. Also GPU > CPU > GPU ping-pong will kill performance.
I also believe the bottleneck is in the pixel format. However it works fairly well with DX9, so I was hoping GL3 would handle it better. The GPU > CPU > GPU ping-pong is easily fixable by using Chromium's software renderer.
EricB wrote:
Mon Jan 14, 2019 9:32 am
So here is my questions. Did I set up RTSS incorrectly?
from the code you posted, it seems correct. You should however try adding Quickgui here:
https://github.com/OGRECave/ogre/blob/m ... tstrap.cpp

which correctly sets up RTSS for GL3+.
There are a few more things I can do to squeeze out some performance with CEF, and worst case scenario the old 32-bit build works fine for non-Mac users. Since GL3 won't improve the issue I have, I'll revisit my GL3 implementation post release. Gotta love time crunches, I've been in one for about 6 years now... I'll try setting up QuickGUI in the bootstrap and report back when it gets done in a few months or so.
0 x
Image

Post Reply