Advertisement

Threads and pointers

Started by January 31, 2004 10:17 AM
4 comments, last by mattfulford 21 years, 1 month ago
I have a public pointer to an object of type Terrain: Terrain terrainObj; Terrain * pTerrain = &terrainObj In my MFC / OpenGL app initialization I want to call the Terrain object''s time consuming load() method to work in the background. I''m using this code: _beginthread(LoadTerrain, 0, g_pclGLView); // g_pclGLView is a pointer to my OpenGLWindow. ... void LoadTerrain(LPVOID pParam) { COpenGLWindow* pWnd = (COpenGLWindow*)pParam; pWnd->Init(); // Init() calls the Terrain object''s time consuming load() method. pWnd->terrainLoaded = true; } When the terrainLoaded flag is set, I want to start my normal drawing loop, but when I do so, my terrain stuff isn''t displayed. I''m guessing it''s something to do with the thread because when I just call LoadTerrain(g_pclGLView); instead of _beginthread(...), the terrain shows up fine. Does anyone have any ideas?? Thanks, Matt
The problem is that your flag that indicates when the terrain is loaded is a resource that is shared between threads. Often when this is the case they will have their own cached copy of the variable, so setting it in one will not affect the other.

I would recommend making the pWnd->terrainLoaded variable be only accesible through functions such as IsLoaded(), and SetLoaded(). Then you can wrap those functions in a critical section and your problem should be solved.

To use critical sections, you can look up the following functions up on MSDN:
InitializeCriticalSection
EnterCriticalSection
LeaveCriticalSection
DeleteCriticalSection


J.W.
Advertisement
The terrainLoaded flag is being set to true after the loading is done, because my DrawGLScene() method is being executed. This method contains the Terrain object''s draw method but this doesn''t seem to be working.

Could the pointer be pointing to the wrong place??
I found this in another forum:
quote:
A thread that makes OpenGL calls must have a current rendering context. If an application makes OpenGL calls from a thread that lacks a current rendering context, nothing happens; the call has no effect. An application commonly creates a rendering context, sets it as a thread''s current rendering context, and then calls OpenGL functions. When it finishes calling OpenGL functions, the application uncouples the rendering context from the thread, and then deletes the rendering context. A window can have multiple rendering contexts drawing to it at one time, but a thread can have only one current, active rendering context.


Could this be my problem, and if so, how would I give the thread a current rendering context?
I think you are exactly right. Your thread may not have an active rendering context, so all the gl operations are going nowhere. You can set the current context by:

wglMakeCurrent(HDC, HRC);

HDC is the device context, HRC is the rendering context. You are probably creating the rendering context somewhere in the beginning of your app, so just store it as a member COpenGLWindow and call the above at the start of your thread.
variant is right, however i had trouble with the window size when i only made the rc current so i do this to activate a window for drawing:

wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC);
CRect r;
GetClientRect(&r);
OnSize(0,r.Width(),r.Height());

Else, the used window size would be the size of the active window when that window is being resized. I don''t know if you''ll have that problem too, if so, this is a probable solution to it.

This topic is closed to new replies.

Advertisement