• Advertisement
Sign in to follow this  

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
  • Advertisement
  • Popular Now

  • Advertisement
  • Similar Content

    • By howie_007
      angelscript/add_on/scriptstdstring/scriptstdstring.cpp:39: virtual CStdStringFactory::~CStdStringFactory(): Assertion `stringCache.size() == 0' failed.
      The above error happens when I quit out my application. I'm developing on Linux. I'm not sure why the stringCache still has strings in it. Shouldn't the destructor just clean-up the left over strings instead of asserting?
    • By RoKabium Games
      Another one of our new UI for #screenshotsaturday. This is the inventory screen for showing what animal fossils you have collected so far. #gamedev #indiedev #sama
    • By Dave Haylett
      Hi everyone. I need some help with my project. It's a 2D-graphics-heavy WPF front-end app written in C#, which talks to two Access 2000 databases (yes I know, it's all I've got). It will be distributed freely on the internet, and so will be being used by Windows users of various installations/versions of Windows, Office, etc.
      One of the two databases (let's call it A), is intended to be read-only, and will be distributed with the app. It has half a dozen relational tables which I as the developer have populated, and is connected to in the app via OleDB Jet 4 with SQL querying the data now and then as the user uses the front-end. The database will be replaced whenever I release an update to the app.
      Database B is read/write, and contains end-user preferences, for example when they favourite something in my front-end, a Favourites table in here gets appended to. This database is not distributed with my app, and should not be overwritten, as it will lose user prefs, etc. and annoy my users.
      Whenever my app is run by a user, during initialisation database A will suck in the user data from database B (using simple SQL SELECT * INTO...), so that all the tables can be joined together by the SQL in database A (to include user prefs/favourites in SQL queries), and whenever the user favourites something, a record is created both in A (for the short-term session) and B (permanently). Database B isn't just about holding favourites, there is other user data in here as well, so there are 3 or 4 tables in B.
      So far, this is all working fine and I'm happy...
      Unfortunately my app is currently 32-bit, and it now needs to break the 32-bit memory barrier what with the size and volume of the graphics I'm pulling in (using the HDD is not really an option, as different graphics are needed kind of instantly and the hard disc would be being hosed and the app dog-slow otherwise, I suspect even off an SSD).
      I'm using VS2015, and switching to 64-bit will probably fix the memory problem, but it breaks Jet 4.0. I'm sure this is old news to most of you.
      To try to keep with 32-bit (and Jet4) but get the memory I need I've tried the -largeaddressaware toggle, and I've tried the editbin suggestion, but I just can't get these solutions to work in VS2015 no matter how hard I try. Are these definitely 100% solutions to 2gb memory limit in 32-bit applications? Should they always work? Am I dumb in being unable to get this to work?
      So otherwise I'm resigned to migrating to 64-bit, and having to get around the database issue, not the memory issue.
      My users will be using a variety of Windows versions (probably 7 and 10), and I'm sure various versions of Office, and so my solution for querying my two Access databases needs to be pretty open if possible.
      Googling has suggested I switch from JET4 to ACE12, but this is apparently requiring me to uninstall Office 2000 and install a 64-bit version (which I don't have), so I can't use it, and I suspect any users who also have an old version of Office installed won't be able to use it either?
      Googling has also suggested I use MS SQL Server. This sounds fine if there's such a thing as a "lite" local version which can manage database access, but I still need to somehow get the data from the databases (A.mdb and B.mdb) into the SQL Server each time the users fire up my app.
      The only solution I can think of at the minute, is to export all the tables from database A into CSVs every time I update the data in there, and have the app import them in a lame way, and also convert database B into some crappy text file which gets written to whenever the user changes a preference. I'd much rather use SQL to do all this if possible, as when the user browses around the app, queries involving joining several tables in A are regularly created and executed to adjust the user's experience/return search results/etc.
      So to summarise my misery, is there either an easy reliable way for me to keep with 32-bit/Jet4 and be able to address >2gb. Or is there instead an easy reliable way for me to switch to 64-bit and successfully query two Access databases without requiring all my users to have 64-bit Office installed?
      Thanks for reading and I hope someone can help.
    • By dekronoth9
      I'm wondering if I have this understood correctly:
      A basic 3d game engine ONLY renders the modelsw tthemselves, nothing else.
      Models a fairly crude looking by themselves.
      Curved edges and other round appeaarences are accomplished through post-processing effects, such anti-aliasing etc.
      New model and image enhancing effects are being developed all the time, thus needing new, built from the ground-up engines to be developed in order to support them.
      Now comes my question.
      What if the only thing the engine itself did was render those base models and geometry, and each of the post-processing effects came as pluggable, seperate "modules", so each time a new one was invented, a new module could be developed to accomodate them, thus avoiding the need to code a completely new engine.
      Is this idea feasible?
      Please let me know what would/wouldn't work about this idea, as well as anything I didn't/misunderstood
    • By 123iamking
      Let me explain why I call it: 3rd person camera-based movement (honestly, I don't know if that's the official name)
      In GTA Vice city, you can see, when you turn the camera, the main character turns with the camera. When you press Back, the character walks backward, press Left, the character walks left-ward. I call this 3rd person character-based movement.
      In GTA SanAndreas (also GTA IV, GTA V, Sleeping Dogs, Prince of Persia,... ), when you turn the camera, the character won't turn, but the camera rotate orbit around the character, when you press Back, the character walks toward the camera, when you press Left, the character walk toward the left of the camera. So I call this 3rd person camera-based movement.
      So I see that 3rd person camera-based movement is pretty popular, I wonder if there is a good implement of 3rd person camera-based movement (that's from open-source, books, forums,... I tried searching but I haven't found any) so that I can learn from.
  • Advertisement