Jump to content
  • Advertisement
Sign in to follow this  
Gothmog

OpenGL Problem with a multithreaded GL app

This topic is 4614 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 have a problem with a very simple multithreaded openGL program. I wanted to write a simple app which would create mutiple windows, each with OpenGL. But when I run it, only one (sometimes two) window initializes properly. Every time SetPixelFormat() returns FALSE, and i get a 'The specified resource type cannot be found in the image file' system error message. Here's the full source:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>

#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")

DWORD WINAPI GL_Thread(LPVOID);
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);

void ErrorMsg()
{
	LPVOID lpMsgBuf;
	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
				  FORMAT_MESSAGE_FROM_SYSTEM|
				  FORMAT_MESSAGE_IGNORE_INSERTS,
				  NULL,
				  GetLastError(),
				  MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
				  (LPTSTR)&lpMsgBuf,
				  0,
				  NULL);

	MessageBox(NULL,(LPCTSTR)lpMsgBuf,0,MB_ICONINFORMATION);

	LocalFree( lpMsgBuf );
}

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int)
{
	WNDCLASS wc=
	{
		CS_OWNDC,
		WndProc,
		0,0,
		hInst,
		NULL,
		NULL,
		(HBRUSH)NULL,
		NULL,
		"GL_TestWndClass"
	};

	RegisterClass(&wc);

	DWORD threadIds[3];
	HANDLE threads[3]=
	{
		CreateThread(NULL,0,GL_Thread,(LPVOID)hInst,0,&threadIds[0]),
		CreateThread(NULL,0,GL_Thread,(LPVOID)hInst,0,&threadIds[1]),
		CreateThread(NULL,0,GL_Thread,(LPVOID)hInst,0,&threadIds[2])
	};

	WaitForMultipleObjects(3,threads,TRUE,INFINITE);

	UnregisterClass("GL_TestWndClass",hInst);

	return 0;
}

DWORD WINAPI GL_Thread(LPVOID param)
{
	HINSTANCE hInst=(HINSTANCE)param;

	HWND hwnd=CreateWindow("GL_TestWndClass",
						   "GL_Test window",
						   WS_VISIBLE|WS_POPUP|WS_SYSMENU|WS_CAPTION,
						   CW_USEDEFAULT,CW_USEDEFAULT,
						   256,256,
						   NULL,
						   NULL,
						   hInst,
						   NULL);

	if(!hwnd)
	{
		MessageBox(NULL,"Could not create the window",0,MB_ICONERROR);
		ErrorMsg();
		return 1;
	}

	HDC dc=GetDC(hwnd);
	if(!dc)
	{
		MessageBox(NULL,"DC is invalid",0,MB_ICONERROR);
		ErrorMsg();
		return 2;
	}

	PIXELFORMATDESCRIPTOR pfd=
	{
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
		PFD_TYPE_RGBA,
		32,
		0,0,0,0,0,0,0,0,
		0,0,0,0,0,
		16,
		0,
		0,
		0,0,0,0,0
	};

	int iFormat=ChoosePixelFormat(dc,&pfd);
	if(!iFormat)
	{
		MessageBox(NULL,"Could not choose pixel format",0,MB_ICONERROR);
		ErrorMsg();
		return 3;
	}

	if(!SetPixelFormat(dc,iFormat,&pfd))
	{
		MessageBox(NULL,"Could not set pixel format",0,MB_ICONERROR);
		ErrorMsg();
		return 4;
	}

	HGLRC rc=wglCreateContext(dc);
	if(!rc)
	{
		MessageBox(NULL,"Could not create the rendering context",0,MB_ICONERROR);
		ErrorMsg();
		return 5;
	}

	if(!wglMakeCurrent(dc,rc))
	{
		MessageBox(NULL,"Could not make the rendering context current",0,MB_ICONERROR);
		ErrorMsg();
		return 6;
	}

	MSG msg;
	bool bRun=true;

	GLUquadricObj *quad=gluNewQuadric();
	gluQuadricNormals(quad,GLU_SMOOTH);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
	gluPerspective(90.0f,1.0f,1.0f,100.0f);
        glMatrixMode(GL_MODELVIEW);

	glTranslatef(0.0f,0.0f,-15.0f);

	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);
	glDisable(GL_CULL_FACE);

	while(bRun)
	{
		while(PeekMessage(&msg,hwnd,0,0,PM_REMOVE))
		{
			if(msg.message==WM_QUIT)
				bRun=false;
			else
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}

		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
		
		glRotatef(0.1f,1.0f,1.0f,1.0f);
		gluCylinder(quad,5,5,10,20,5);

		glFlush();
		SwapBuffers(dc);
	}

	gluDeleteQuadric(quad);

	wglMakeCurrent(NULL,NULL);
	wglDeleteContext(rc);

	return (DWORD)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	switch(msg)
	{
	case WM_CLOSE:
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hwnd,msg,wparam,lparam);
	}

	return 0;
}


Anybody has an idea what's happening? Thanks in advance. [Edited by - Gothmog on November 6, 2005 2:00:41 AM]

Share this post


Link to post
Share on other sites
Advertisement
Perhaps this is your problem

SetPixelFormat description from msdn
Quote:

If hdc references a window, calling the SetPixelFormat function also changes the pixel format of the window. Setting the pixel format of a window more than once can lead to significant complications for the Window Manager and for multithread applications, so it is not allowed. An application can only set the pixel format of a window one time. Once a window's pixel format is set, it cannot be changed.

Share this post


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

  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!