[Feature] OpenGL Quad Buffer patch

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France
x 17

[Feature] OpenGL Quad Buffer patch

Post by Nodrev »

I ear you from there:
"Ho damn, not another opengl quad buffer patch..."

But, cause there's a but, this one have a little different implementation than the other on the forum: it only modify RenderSystemGL plugin, nothing more (although the camera listener patch I mentioned in another post is necessary). And so, I wish that this patch could officially be approved, this will be far easier to use this functionality with Ogre than the actual way of doing which is very complicated (search for the patches in the forum, determine which one is the more recent, apply it... etc!).

To enable quad buffer on an existing application (let's say the sample browser for example), you just have to add 2 line to the camera creation code:

Code: Select all

cam->setFocalLength(10.0f);
cam->setFrustumOffset(Ogre::Vector2(-0.05f, 0.0f));
The focal length being the distance to the parallax plane, and "-0.05" being the frustum offset computed for the right eye position (so in the setup below, i have an eye separation of 0.1 Ogre's units). The camera is automatically displaced correctly in the render code.

There's some stuff that do not work (but those technique are known to make problems with quad buffer, so it's not a surprise):
* Character demo (certainly the texture shadow used)
* Compositor demo (strange because the deferred demo seem to work, although it use compositors, need to investigate here)
* New instancing (don't know why at this time)
* Shadows (stencil ok, without surprise textures shadows are ko)
* Skeletal animation (texture shadow again?)

I will work on a way to disable the textures shadows automatically when quad buffer is enabled, but it's not mandatory to check the actual patch implementation :).
Another work is to implement it for linux, but it should be 4 or 5 lines to modify in the "OgreWin32GLSupport.cpp" linux equivalent class, just have to setup a linux on my quad buffer pc.

<edit>I forgot to mention that this implementation renders the first frame a camera is used with normal double buffer, and all the other with quadbuffer, but at 120Hz, who cares!?</edit>
<edit>Last version of the patch: https://ogre3d.atlassian.net/browse/OGRE-143</edit>
Last edited by Nodrev on Tue Feb 12, 2013 1:43 pm, edited 1 time in total.
User avatar
Brocan
Orc
Posts: 441
Joined: Tue Aug 01, 2006 1:43 am
Location: Spain!!
x 8

Re: [Feature] OpenGL Quad Buffer patch

Post by Brocan »

Really really great!

We've two 3D projectors that only work with Quadro's quadbuffers, this patch is going to bea great addition for it! :D
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58

Re: [Feature] OpenGL Quad Buffer patch

Post by CABAListic »

We are already in feature freeze for Ogre 1.8, with a final release imminent. So please be a little patient as we wrap that up. After that we can begin concentrating on 1.9 and reviewing feature requests.
Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France
x 17

Re: [Feature] OpenGL Quad Buffer patch

Post by Nodrev »

I easily understand that, and it seems totally normal to me to delay such modification regardly actual milestone.
Anyway, any feedback from potential quad buffer users is welcome, so that's why I post this patch now :)
Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France
x 17

Re: [Feature] OpenGL Quad Buffer patch

Post by Nodrev »

I just updated the patch, textures shadows are now working, (all the demos mentioned before have shadow textures, so no more crash in the demos, although compositors rendering is still not perfect).
Brocan, if you want to try the quad buffer rendering, I uploaded a binary version of it at http://iserver.i-maginer.org/~jeff/ogre ... rowser.rar, I wish it'll work on your hardware, let me know :)
Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France
x 17

Re: [Feature] OpenGL Quad Buffer patch

Post by Nodrev »

I just like to do one modification to OgreMain to keep the Ogre's way of doing, concerning card capabilities handling, adding a new element to "enum Capabilities" in "OgreRenderSystemCapabilities.h":

Code: Select all

	enum Capabilities
	{
		...
		/// Support for Separate Shader Objects
		RSC_SEPARATE_SHADER_OBJECTS = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 9),
		/// Support for Quad buffer
		RSC_QUAD_BUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 10)
	};
I think it's acceptable, but what does the Ogre team thinks about that?
However, i'm not sure how to effectively detect stereo capability, I did not find any OpenGL extension refering to stereo or quad buffer, so the forward way should be to use:

Code: Select all

glGetBooleanv(GL_STEREO)
I saw on some forum that there should be some issues if no window was created (http://forums.nvidia.com/index.php?showtopic=63155), but as RenderSystemCapabilities are populated on first render window creation, it should be ok.
Any GL master opinion on this?
Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France
x 17

Re: [Feature] OpenGL Quad Buffer patch

Post by Nodrev »

Just updated the patch with RSC_QUAD_BUFFER capability detection.
Code cleaned too, the "Stereo Mode"="Quad Buffer" option is not in both rendersystem and renderwindow anymore, it's now only in rendersystem (so all the renderwindows created when this flag is active on the render system will use quad buffer).
User avatar
Brocan
Orc
Posts: 441
Joined: Tue Aug 01, 2006 1:43 am
Location: Spain!!
x 8

Re: [Feature] OpenGL Quad Buffer patch

Post by Brocan »

Unfortunately, I haven't had time to test it yet :cry:
Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France
x 17

Re: [Feature] OpenGL Quad Buffer patch

Post by Nodrev »

Hi Brocan, I thought you had forgotten me :)!
I have not updated the binaries demos provided above with the last patch, I have to do it, I will let you know when they will be online.
Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France
x 17

Re: [Feature] OpenGL Quad Buffer patch

Post by Nodrev »

Demos binaries updated, same link as before (http://iserver.i-maginer.org/~jeff/ogre ... rowser.rar).
User avatar
Brocan
Orc
Posts: 441
Joined: Tue Aug 01, 2006 1:43 am
Location: Spain!!
x 8

Re: [Feature] OpenGL Quad Buffer patch

Post by Brocan »

First of all, sorry for the long delay :oops:

Finally i've time to test your binaries in our system. It's perfectly working!

Congrats! great work! :mrgreen:
Petrolionga
Gnoblar
Posts: 4
Joined: Wed Sep 19, 2012 3:26 pm

Re: [Feature] OpenGL Quad Buffer patch

Post by Petrolionga »

Hello,
I want to run an application written with the OGRE engine in stereo mode.

My System consists of Ubuntu Linux 11.10 with a Nvidia Quadro graphics card and new driver 304.43. I'm using Nvidia 3D Vision 2 glasses.
Driver is installed correctly, and I tested the quad buffered stereo with the application VMD successfully.

Now my question:
Is it possible to force stereo output for openGL applications that do not support it directly? I think this is possible under Windows, but how to do it under Linux?

Or is a modification of source code necessary?
Maybe this patch is the right thing for me?

Could you help me to apply this patch on Linux?

Thanks for your support,
Markus Noack
Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France
x 17

Re: [Feature] OpenGL Quad Buffer patch

Post by Nodrev »

I just replied to your mail, it was just a couple of seconds ago :)
So, i re-post my response here:
Hello Petrolionga,

About your questions:

I need to get a existing application to work in stereo mode
with quad buffer - is this the right patch for me?
Yes it is, this patch allows you to enable quad buffer in your existing application with 2 lines of code :). The only thing that do not work well is compositor rendering, so as far your application do not use this, it will be ok.


I\'am new to OGRE, is there any documentation on how to apply
this patch? maybe you could give me a hint.
You'll need to download Ogre source from bitbucket, using a mercurial client, and apply the patch using a diff tool.
I let you check this page http://www.ogre3d.org/developers/mercurial to understand how to download the sources.

According to your description there is some extra work to do on Linux?
Hum, yes, not much work to do, but there's some, indeed.
You'll need to modify the linux class that inherits from GLSupport class the same way i have done with Win32GLSupport class. But it shall not be too difficult.

Maybe you could provide some \"sample\" application where the
patch already was implemented?
The tool i am currently developping, OpenSpace3D, have quad buffer option.
Otherwise, this is pretty straightforward to enable quad buffer:

- Enable the option on the opengl renderer:
Ogre::RenderSystem myRs = O3Root->getRenderSystemByName("OpenGL Rendering Subsystem");
myRs->setConfigOption("Stereo Mode", "QuadBuffer");

- Configure eyes offset on the camera:
ogreCamera->setFocalLength(10.0f);
ogreCamera->setFrustumOffset(Ogre::Vector2(-0.05f, 0.0f));

And that's all :)

For informations about what is the meaning of the frustrum offset value, check the first message of the post:
http://www.ogre3d.org/forums/viewtopic. ... er#p458029

Let me know if you need more information (or directly in the forum's post, it will be even better).
Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France
x 17

Re: [Feature] OpenGL Quad Buffer patch

Post by Nodrev »

Ho, and by the way, thanks to Brocan for his feedback :)
Petrolionga
Gnoblar
Posts: 4
Joined: Wed Sep 19, 2012 3:26 pm

Re: [Feature] OpenGL Quad Buffer patch

Post by Petrolionga »

Nodrev wrote:
You'll need to modify the linux class that inherits from GLSupport class the same way i have done with Win32GLSupport class. But it shall not be too difficult.
I tried to do so. I think the right class for Ubuntu Linux is "OgreGLXGLSupport"?

If yes, there are some lines of code where i cannot find an equivalent from OgreWin32GLSupport.cpp to OgreGLXGLSupport.cpp: So i don't know how to add these lines of your patch to the linux file:

In the Linux file, there is no "PIXELFORMATDESCRIPTOR". Is this something to worry about?

Code: Select all

@@ -528,7 +544,7 @@
 		pfd.nVersion = 1;
 		pfd.cColorBits = 16;
 		pfd.cDepthBits = 15;
-		pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER;
+		pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER|PFD_STEREO;
 		pfd.iPixelType = PFD_TYPE_RGBA;
 		
 		// if these fail, wglCreateContext will also quietly fail
@@ -605,6 +621,19 @@
                     remove_duplicates(mFSAALevels);
                 }
 			}
+
+			// check for left & right (stereo) color buffer support
+			PFNWGLGETPIXELFORMATATTRIBIVARBPROC _wglGetPixelFormatAttribivARB =
+				(PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
+				wglGetProcAddress("wglGetPixelFormatAttribivARB");
+			int query = WGL_STEREO_ARB, stereo;
+			if (_wglGetPixelFormatAttribivARB(hdc, format, 0, 1, &query, &stereo))
+			{
+				if (stereo != 0)
+				{
+					mHasQuadBuffer = true;
+				}
+			}
 			
 			wglMakeCurrent(oldhdc, oldrc);
 			wglDeleteContext(hrc);
@@ -632,6 +661,8 @@
 		pfd.cAlphaBits = (colourDepth > 16)? 8 : 0;
 		pfd.cDepthBits = 24;
 		pfd.cStencilBits = 8;
+		if(mHasQuadBuffer)
+			pfd.dwFlags |= PFD_STEREO;
 
 		int format = 0;
Nodrev
Gremlin
Posts: 193
Joined: Fri Jan 25, 2008 6:55 pm
Location: Nantes / France
x 17

Re: [Feature] OpenGL Quad Buffer patch

Post by Nodrev »

I found those webpages talking about stereo rendering and glx:
http://www-f9.ijs.si/~matevz/docs/007-2 ... /ch04.html
http://www.opengl.org/sdk/docs/man/xhtm ... Config.xml

So the right function to call with a GLX_STEREO attribute seem to be "glXChooseFBConfig".
It's called in "GLXFBConfig* GLXGLSupport::chooseFBConfig(const GLint *attribList, GLint *nElements)".
I hope that helps.
Petrolionga
Gnoblar
Posts: 4
Joined: Wed Sep 19, 2012 3:26 pm

Re: [Feature] OpenGL Quad Buffer patch

Post by Petrolionga »

Okay, thanks for your help!!

But since I am not so much into Ogre/C++/Linux I think I cannot do that myself..

Maybe you know a similar patch, thats already has been done with Linux? There are many old threads in the forums, but nothing leaded to success for me so far..
LarrxX

Re: [Feature] OpenGL Quad Buffer patch

Post by LarrxX »

Hi!

I am also trying to adapt this patch for use under Linux and it is unfortunately not as straightforward as it seems. The chooseFBConfig() method is called multiple times within the GLXGLSupport class: in the constructor, getFBConfigFromVisualID() and selectFBConfig(). And there are also direct calls to glxChooseFBConfig in getFBConfigFromContext(), getFBConfigFromDrawable().

My questions are:
  • Where do I put the code for testing Quadbuffer capacity (the equivalent of what is done in OgreWin32GlSupport::initializeWGL() )?
  • Where do I put the code to create the Quadbuffer context (the equivalent of what is done in OgreWin32GlSupport::selectPixelFormat() )?
Thanks a bunch for any help or insight anyone might have.
LarrxX

Re: [Feature] OpenGL Quad Buffer patch

Post by LarrxX »

OK, here's what I have so far:

I have a windows app that works perfectly with Quadbuffering under Windows. And it compiles under Linux with no hassle. So, if I understand it correctly, I only need to patch the GLXGLSupport class to have everything work under Linux, right?

What I did was:

Add the mHasQuadBuffer member to the class (that's the easy part :D).

Test quadbuffering support at the end of the constructor with the following:

Code: Select all

//------ Begin quadbuffer patch
int stereoAttrib[] = { GLX_STEREO, True, None };
fbConfigs = chooseFBConfig( stereoAttrib, &nConfigs );
if( fbConfigs )
{
   mHasQuadBuffer = true;
}
//------ End quadbuffer patch

XFree (fbConfigs);
Add the "Stereo Mode" option in the addConfig method. This part is basically the same as what is done in the Win32SUpport class:

Code: Select all

ConfigOption optStereoMode;


optStereoMode.name = "Stereo Mode";
optStereoMode.possibleValues.push_back("Mono");
if (mHasQuadBuffer)
{
	optStereoMode.possibleValues.push_back("QuadBuffer");
	optStereoMode.currentValue = optStereoMode.possibleValues[1];
	optStereoMode.immutable = false;
}
else
{
	optStereoMode.currentValue = optStereoMode.possibleValues[0];
	optStereoMode.immutable = true;
}


mOptions[optStereoMode.name] = optStereoMode;
And finally, add the GLX_STEREO option to the GLX context if quadbuffering is selected.

Ideally, I would have liked to add this in the createNewContext method, but I could'nt find a way to modify the fbConfig parameter passed as an argument. Instead, what I did, was change the chooseFBConfig to add the GLX_STEREO attribute if needed. Here's my code for the method:

Code: Select all

GLXFBConfig* GLXGLSupport::chooseFBConfig(const GLint *attribList, GLint *nElements)
{
	GLXFBConfig *fbConfigs;
	
	//------ Begin Stereo Patch
	ConfigOptionMap::iterator opt;
			
	if( attribList && (opt = mOptions.find("Stereo Mode")) != mOptions.end() )
	{
		LogManager::getSingleton().logMessage( "Stereo Mode is " +  opt->second.currentValue );
			   
		if (opt->second.currentValue == "QuadBuffer")
		{
			////Add GLX_STEREO
			int attribListSize = 0;
			
			//First iterate to get the number of attributes
			while( attribList[attribListSize] != None )
				++attribListSize;
							
			//Add one more to get the correct size
			++attribListSize;
							
			//Now create a copy of the attrib list and add two values to it to activate stereo
			GLint* newAttribList = new GLint[ attribListSize + 2];
			for( int i = 0; i < attribListSize; ++i )
			{
				newAttribList[i] = attribList[i];
			}
			
			newAttribList[attribListSize] = GLX_STEREO;
			newAttribList[attribListSize + 1] = True;
			newAttribList[attribListSize + 2] = None;
							
			if (GLXEW_VERSION_1_3)
				fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements);
			else
				fbConfigs = glXChooseFBConfigSGIX(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements);
				
			delete newAttribList;
			
			if( !fbConfigs )
			{
				OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Stereo not supported with currently selected options.", "GLXGLSupport::chooseFBConfig");
			}
			else
			{
				LogManager::getSingleton().logMessage( ">>>>>>>>>>>>>> Adding Stereo succeeded! :-D" );
			}
			return fbConfigs;
		}
	}
	
	//------ End Stereo Patch

	if (GLXEW_VERSION_1_3)
		fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements);
	else
		fbConfigs = glXChooseFBConfigSGIX(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements);
	
	return fbConfigs;
}
Now what happens is everything works as it should, I do get the ">>>>>>>>>>>>>> Adding Stereo succeeded! :-D" message in the log, but nothing else happens. My app does not run in stereo. WHY? :'(

For the record, my Linux is correctly set up to run stereo apps. I tested it with glxgears -stereo which works fine.

I think that ideally, it would be better to make the modifications in the createNewContext method so, if anybody has any idea how that can be done, I'd be willing to give it a try and report back here.
LarrxX

Re: [Feature] OpenGL Quad Buffer patch

Post by LarrxX »

Just added the following code in the createNewContext method:

Code: Select all

int stereo;
if( glXGetFBConfigAttrib( mGLDisplay, fbConfig, GLX_STEREO, &stereo ) == 0 )
{
   if( stereo == True )
  {
	 LogManager::getSingleton().logMessage( ">>>>>>>>>>>>>> createNewContext has Stereo fbConfig." );
  }
  else
  {
	 LogManager::getSingleton().logMessage( ">>>>>>>>>>>>>> createNewContext NO Stereo fbConfig." );
  }
}
else
{
   LogManager::getSingleton().logMessage( ">>>>>>>>>>>>>> createNewContext error getting GLX_STEREO param from fbConfig." );
}
As I suspected, I get the NO Stereo fbConfig in the logs. Seems the fbConfig I create in the modified chooseFBConfig method gets lost along the way.

HEEEEEEEEEELP! Please! This is frustratingly ridiculous. Doesn't ANYONE know how the GLX context creation works? I know what I have to do, but I can't figure out where to do it! :'(
LarrxX

Re: [Feature] OpenGL Quad Buffer patch

Post by LarrxX »

Just for the heck of it, I tried manually overriding the fbConfig in the createContext method by creating a stereo context and I still don't have stereo! Why is that? I have a feeling that I'm going to have to patch the creation of the X Visual to make everything work.

This is getting frustrating. I don't know what I'm doing, I keep trying and dying. Hasn't anybody got any pointers at all? Is anyone even reading this? :'(
User avatar
Brocan
Orc
Posts: 441
Joined: Tue Aug 01, 2006 1:43 am
Location: Spain!!
x 8

Re: [Feature] OpenGL Quad Buffer patch

Post by Brocan »

LarrxX wrote:Just for the heck of it, I tried manually overriding the fbConfig in the createContext method by creating a stereo context and I still don't have stereo! Why is that? I have a feeling that I'm going to have to patch the creation of the X Visual to make everything work.

This is getting frustrating. I don't know what I'm doing, I keep trying and dying. Hasn't anybody got any pointers at all? Is anyone even reading this? :'(
Ask directly to masterfalcon, i think that he is the current manteiner for OpenGL render system. Maybe he could answer your questions about contexts. :wink:
LarrxX

Re: [Feature] OpenGL Quad Buffer patch

Post by LarrxX »

Thanks for the info. Just PMed him, fingers crossed :)
LarrxX

Re: [Feature] OpenGL Quad Buffer patch

Post by LarrxX »

Got an answer from Masterfalcon saying he'll be taking a look at this. So, for now, I keep on tweeking and hoping.

Just replaced:

Code: Select all

fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), fbConfigAttrib, &nElements);
with:

Code: Select all

fbConfigs = chooseFBConfig( fbConfigAttrib, &nElements );
In both getFBConfigFromContext and getFBConfigFromDrawable so that they call my modified chooseFBConfig method that adds the GLX_STEREO flag.

I still get a no stereo context in createNewContext. Where is my extra stereo attribute going and who is removing it? :x
LarrxX

Re: [Feature] OpenGL Quad Buffer patch

Post by LarrxX »

Solved it! My basic idea was sound, but my algorithm to add the GL_STEREO attribute in chooseFBConfig had 2bugs:
  • The most obvious one was that I didn't pass the modified attribute list to the glx methods (thank you copy/paste!)
  • The second one was that I added the GLX_STEREO parameter after the None key value of the original attribute list :?
So the correct code for the complete chooseFBConfig follows:

Code: Select all

    GLXFBConfig* GLXGLSupport::chooseFBConfig(const GLint *attribList, GLint *nElements)
    {
       GLXFBConfig *fbConfigs;
       
       //------ Begin Stereo Patch
       ConfigOptionMap::iterator opt;
             
       if( attribList && (opt = mOptions.find("Stereo Mode")) != mOptions.end() )
       {
          LogManager::getSingleton().logMessage( "Stereo Mode is " +  opt->second.currentValue );
                
          if (opt->second.currentValue == "QuadBuffer")
          {
             //Add GLX_STEREO
             int attribListSize = 0;
             
             //First iterate to get the number of attributes (omitting the final "None" parameter)
             while( attribList[attribListSize] != None )
                ++attribListSize;
                         
             //Now create a copy of the attrib list and add two values to it to activate stereo
             GLint* newAttribList = new GLint[ attribListSize + 2];
             for( int i = 0; i < attribListSize; ++i )
             {
                newAttribList[i] = attribList[i];
             }
             
             newAttribList[attribListSize] = GLX_STEREO;
             newAttribList[attribListSize + 1] = True;
             newAttribList[attribListSize + 2] = None;
                         
             if (GLXEW_VERSION_1_3)
                fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), newAttribList, nElements);
             else
                fbConfigs = glXChooseFBConfigSGIX(mGLDisplay, DefaultScreen(mGLDisplay), newAttribList, nElements);
                
             delete newAttribList;
             
             if( !fbConfigs )
             {
                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Stereo not supported with currently selected options.", "GLXGLSupport::chooseFBConfig");
             }
             return fbConfigs;
          }
       }
       
       //------ End Stereo Patch

       if (GLXEW_VERSION_1_3)
          fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements);
       else
          fbConfigs = glXChooseFBConfigSGIX(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements);
       
       return fbConfigs;
    }
This currently works for me, on my own test machine. I don't know if it's good enough to work in all test cases (but it should since I replaced the direct calls to glxChooseFBConfig to calls to the modified chooseFBConfig as stated in my previous post).

If anybody wants to give this a try and get back to me, I'd be more than happy to try and look into it.