Jump to content
  • Advertisement
Sign in to follow this  
cnlohr

OpenGL OpenGL Threadding Success (with GLUT and X11)

This topic is 3608 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I don't know if this is a re-post but virtually all Google Topics when searching for how to do OpenGL multithreading turn up either blank threads or "It can't be done." I don't know if this is an appropriate place to put this post, so if it's wrong feel fee to move it or delete it. After some messing around, I found a surprisingly trivial way to do it. You can share everything between textures, lists even the primary output buffer between multiple threads (at least in Linux). I happen to like using FreeGLUT, but any OpenGL windowing system, or do it yourself works since you don't need to already know anything about the X11 display or current context. Here's a picture (This was at least tested on a GeForce 6600, my previous test was on an old ATI M200, so it appears to be pretty platform independent. http://userpages.umbc.edu/~lohr1/multithreaded.png I did this on a utility I wrote a while ago, cppgpgpu http://cppgpgpu.sf.net/ . The code for doing this is found below:
#include <GLUTCore.h>
#include <OGLParts.h>

void MyDraw();

#include <GL/glx.h>
#include <pthread.h>

Shader S1;
Texture T1;

GLXContext CTX;
Display * DPY;
GLXDrawable DWB;

static int attrListDbl[] =
{
    GLX_RGBA,    None
};

void * tthread( void * d )
{
	GLuint t;
	GLXContext this_context;

	printf( "%p %p\n", DPY, CTX );

	XVisualInfo * vi = glXChooseVisual( DPY, 0, attrListDbl);
	this_context = glXCreateContext(DPY, vi, CTX, GL_TRUE);
	glXMakeCurrent(DPY, DWB, this_context);


	glEnable(GL_DEPTH_TEST);

	while(1)
	{
		T1.ActivateTexture( 0 );
		glLoadIdentity();
		glScalef( 0.3,-0.4,0.4 );
		glTranslatef( -2.,0,0 );
		DrawSquare();
		T1.DeactivateTexture( 0 );
		
	}

	return 0;
	
}

int main( int argc, char ** argv )
{
	pthread_t ptt;

	//This must be set before init.
	GLUT.SetDrawFunct( MyDraw );

	GLUT.Init( argc, argv, 640, 480, "Multithreading Demo" );

	glEnable(GL_DEPTH_TEST);

	T1.LoadTextureFile( "1.ppm" );
	S1.LoadShader( "Mandelbrot/Mandelbrot" );

	CTX = glXGetCurrentContext();
	DPY = glXGetCurrentDisplay();
	DWB = glXGetCurrentDrawable();

	pthread_create( &ptt, NULL, tthread, 0 );

	GLUT.DrawAndDoMainLoop();
}

void MyDraw()
{
	vector< string > SamplerLocs;
	glClearColor( .1f, .1f, .2f, 0.0f );
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glPushMatrix();

	glTranslatef( 1.5, 0, 0 );
	T1.ActivateTexture( 0 );
	S1.ActivateShader( SamplerLocs );
	DrawSquare();
	S1.DeactivateShader();
	T1.DeactivateTexture( 0 );

	glPopMatrix();

	S1.CheckForNewer( "Mandelbrot/Mandelbrot" );

	GLUT.TackFPS();
	glutSwapBuffers();
	glutPostRedisplay();
}
As you can see, you need three values:
	GLXContext CTX;
	Display * DPY;
	GLXDrawable DWB;
The main thread needs to get them with:
	CTX = glXGetCurrentContext();
	DPY = glXGetCurrentDisplay();
	DWB = glXGetCurrentDrawable();
The thread that wants to join in needs to run:
	XVisualInfo * vi = glXChooseVisual( DPY, 0, attrListDbl);
	this_context = glXCreateContext(DPY, vi, CTX, GL_TRUE);
	glXMakeCurrent(DPY, DWB, this_context);
Note that the attrListDbl for the glX list does not have to be a comprehensive one. It just needs the GLX_RGBA attribute. From there on out, both threads share the same context. Note that some things like Matrices and states are static, and all objects are shared.

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!