Jump to content
  • Advertisement
Sign in to follow this  
Vortez

OpenGL Trouble with OpenGL + threads...

Recommended Posts

Hi guys, im having a little problem fixing a bug in my program since i multi-threaded it. The app is a little video converter i wrote for fun. To help you understand the problem, ill first explain how the program is made. Im using Delphi to do the GUI/Windows part of the code, then im loading a c++ dll for the video conversion. The problem is not related to the video conversion, but with OpenGL only. The code work like this:


 

DWORD WINAPI JobThread(void *params)
{
    for each files {
      
      ...
      
      _ConvertVideo(input_name, output_name);
    }
}

void EXP_FUNC _ConvertVideo(char *input_fname, char *output_fname)
{
	// Note that im re-initializing and cleaning up OpenGL each time this function is called...
	CGLEngine GLEngine; 
  
	...
  
	// Initialize OpenGL
	GLEngine.Initialize(render_wnd);
	GLEngine.CreateTexture(dst_width, dst_height, 4);
    
	// decode the video and render the frames...
	for each frames {

		...
      
		GLEngine.UpdateTexture(pY, pU, pV);
		GLEngine.Render();   
	}
      
cleanup:
  	GLEngine.DeleteTexture();
	GLEngine.Shutdown();

 	// video cleanup code...
}

 

With a single thread, everything work fine. The problem arise when im starting the thread for a second time, nothing get rendered, but the encoding work fine. For example, if i start the thread with 3 files to process, all of them render fine, but if i start the thread again (with the same batch of files or not...), OpenGL fail to render anything.

Im pretty sure it has something to do with the rendering context (or maybe the window DC?). Here a snippet of my OpenGL class:

bool CGLEngine::Initialize(HWND hWnd)
{
	hDC = GetDC(hWnd);

	if(!SetupPixelFormatDescriptor(hDC)){
		ReleaseDC(hWnd, hDC);
		return false;
	}

	hRC = wglCreateContext(hDC);
	wglMakeCurrent(hDC, hRC);	                        

	// more code ...

	return true;
}

void CGLEngine::Shutdown()
{
	// some code...

	if(hRC){wglDeleteContext(hRC);}
	if(hDC){ReleaseDC(hWnd, hDC);}
	hDC = hRC = NULL;
}

 

The full source code is available here. The most relevant files are:

-OpenGL class (header / source)

-Main code (header / source)

 

Thx in advance if anyone can help me.

Edited by Vortez

Share this post


Link to post
Share on other sites
Advertisement

I was not deeply into your code, but at first glance I could not see any context sharing.

This is the main piece when doing multithreaded OpenGL programs.

When sharing contexts most of the objects will be shared except containers (you'll have to recreate these containers on both contexts if needed).

For more information see this link and this one.

For creating such shared context, use glXCreateContext or (since you seem to be under Windows) its equivalent one.

Share this post


Link to post
Share on other sites
33 minutes ago, _Silence_ said:

I was not deeply into your code, but at first glance I could not see any context sharing.

Not sure what you mean by this, since i don't think i need any sharing.

That's what im trying to explain, im only using a secondary thread to do the conversion and rendering, so the main thread is not blocked, but im not lauching more than one (secondary) thread at once. ie:

 

Step 1: User add file(s) he want to convert in a listbox

Step 2: Main thread launch secondary thread and do it's thing until it finish (the main thread is not blocked)

    (User interface is disabled until the thread dies)

    (Secondary thread encode all the files in the list, work well the first time for one or multiple files)

Step 3: Just before the thread exit, it post a message to the main thread so the user interface is re-enabled again

Then you can go to step 1 again (that's where opengl don't work anymore), or close the application, whatever.

 

Hope this clear things a bit.

 

Edited by Vortez

Share this post


Link to post
Share on other sites
1 hour ago, Vortez said:

Not sure what you mean by this, since i don't think i need any sharing.

That's what im trying to explain, im only using a secondary thread to do the conversion and rendering, so the main thread is not blocked, but im not lauching more than one (secondary) thread at once. ie:

OK. This was not clear to me. And things are still not clear enough:

On which thread do you create your OpenGL window (which thread own the context). The thread were the window and the context was created and first made current, must be the same thread that renders. Note that most of the times APIs that allow to create OpenGL windows will create it in the caller thread, which is usually the main thread.

On which thread do you render (from reading you, it seems to be the second thread) ? If so, this second thread must create the window, the context and makes it current.

Do you create any OpenGL objects on the non-rendering thread ?

 

Hope that could help a bit more :)

Edited by _Silence_

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
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!