Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 7 of 7

Thread: About Multi-Thread in Win32 API

  1. #1
    Junior Member Newbie
    Join Date
    Mar 2013
    Posts
    12

    About Multi-Thread in Win32 API

    Hi everyone,I has an problem puzzled me up over these day
    It's began days ago, Because i try to make an Multi-Thread OpenGL application with Win32 API.
    In this program ,i want let WndProc Function process WM_RBUTTONUP message to change OpenGL shading mode
    (I got two thread in program, one is redering thread,and one is Win32 main thread)
    Code is somewhat lengthly,But in follows:
    Code :
    #include <gl\glew.h>
    #include <gl\wglew.h>
    #include <gl\glut.h>
    #include <Windows.h>
     
    //Just because it's was a test,
    //so i declare them global
    HWND hWnd;
    HDC hdc;
    HGLRC hPrimaryRC;    //This handle rendering thread
    HGLRC hSlaverRC;      //This handle WndProc Message
    LPDWORD lpThreadId;
     
    //Here is Pixelformat function
    void SetRCPixelFormat(HDC hdc)
    {
    	int pfdNum;
     
    	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,
    		PFD_MAIN_PLANE,
    		0,
    		0,0,0
    	};
     
    	pfdNum = ChoosePixelFormat(hdc,&pfd);
    	SetPixelFormat(hdc,pfdNum,&pfd);
    }
     
    void ActiveGL()
    {
    	GLenum err = glewInit();
    }
     
    void Resize(int width,int height)
    {
    	GLdouble aspect = (GLdouble)width/(GLdouble)height;
    	GLdouble fovy = 90.0;
    	GLdouble pNear = 1.0;
    	GLdouble pFar = 32000.0;
     
    	glViewport(0,0,width,height);
     
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
     
    	gluPerspective(fovy,aspect,pNear,pFar);
    }
     
    void Configure()
    {
    	glClearColor(0.2f,0.2f,0.2f,1.0f);
     
    	glShadeModel(GL_SMOOTH);
    	glFrontFace(GL_CCW);
     
    	glEnable(GL_CULL_FACE);
    	glEnable(GL_DEPTH_TEST);
    	glEnable(GL_BLEND);
    	glEnable(GL_MULTISAMPLE);
     
    	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
     
    	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    }
     
    //Here is rendering thread
    void Render(PVOID pParam)
    {
            //Everything goes well at here
    	SetRCPixelFormat(hdc);
    	hPrimaryRC = wglCreateContext(hdc);
     
    	wglMakeCurrent(hdc,hPrimaryRC);
     
    	RECT rect;
    	GetClientRect(hWnd,&rect);
    	Resize(rect.right,rect.bottom);
     
    	Configure();
     
    	float yRot = 0.0f;
     
    	while(1)
    	{
     
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
    		glMatrixMode(GL_MODELVIEW);
     
    		glPushMatrix();
     
    		gluLookAt(0.0,0.0,200.0,0.0,0.0,0.0,0.0,1.0,0.0);
     
    		glPushMatrix();
                    //Draw an rotate cube at origin
    		glColor4f(1.0f,0.0f,0.0f,0.2f);
    		glRotatef(yRot,0.0f,1.0f,0.0f);
    		glutSolidCube(50.0);
     
    		glPopMatrix();
     
    		glPushMatrix();
     
                   //And draw the background behind that cube
    		glBegin(GL_QUADS);
    		glColor4f(1.0f,0.0f,0.0f,0.9f);
    		glVertex3f(-500.0f,500.0f,-100.0f);
    		glColor4f(0.0f,1.0f,0.0f,0.9f);
    		glVertex3f(-500.0f,-500.0f,-100.0f);
    		glColor4f(0.0f,0.0f,1.0f,0.9f);
    		glVertex3f(500.0f,-500.0f,-100.0f);
    		glColor4f(1.0f,1.0f,1.0f,1.0f);
    		glVertex3f(500.0f,500.0f,-100.0f);
    		glEnd();
     
    		glPopMatrix();
     
    		glPopMatrix();
     
    		glFlush();
    		SwapBuffers(hdc);
     
    		yRot += 0.5f;
    	}
            //When program exit
    	ReleaseDC(hWnd,hdc);
    }
     
    LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
    {
            //But, yes...something going wrong here
    	switch(msg)
    	{
    	case WM_CREATE:
                    //I thought following codes is ok
                    //Cuz‘s Rendering Thread is working well
    		hdc = GetDC(hWnd);
    		SetRCPixelFormat(hdc);
    		hSlaverRC = wglCreateContext(hdc);
    		wglShareLists(hPrimaryRC,hSlaverRC);
    		break;
    	case WM_RBUTTONUP:
                    //But here comes problem
                    //I want change OpenGL shading mode
                    //when i right click the window, but infact...it's doesn't work
                    //Can someone give me some advise?
    		wglMakeCurrent(hdc,hSlaverRC);
    		glShadeModel(GL_FLAT);
    		glFinish();
    		break;
    	case WM_DESTROY:
    		ReleaseDC(hWnd,hdc);
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hWnd,msg,wParam,lParam);
    	}
     
    	return 0;
    }
     
    int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow)
    {
    	MSG msg;
    	WNDCLASSEX wndex;
     
    	wndex.cbSize = sizeof(WNDCLASSEX);
    	wndex.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
    	wndex.cbClsExtra = 0;
    	wndex.cbWndExtra = 0;
    	wndex.lpfnWndProc = WndProc;
    	wndex.hInstance = hInstance;
    	wndex.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
    	wndex.hCursor = LoadCursor(NULL,IDC_ARROW);
    	wndex.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    	wndex.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
    	wndex.lpszClassName = TEXT("MainWindow");
    	wndex.lpszMenuName = NULL;
     
    	if(!RegisterClassEx(&wndex))
    	{
    		MessageBox(NULL,TEXT("程序初始化失败"),TEXT("启动失败"),MB_OK);
    		return 0;
    	}
     
    	hWnd = CreateWindow(TEXT("MainWindow"),TEXT("MultGL"),
    		WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,720,480,NULL,NULL,hInstance,NULL);
     
    	ShowWindow(hWnd,SW_MAXIMIZE);
    	UpdateWindow(hWnd);
     
            //Just called glewInit
    	ActiveGL();
     
    	CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)Render,NULL,NULL,lpThreadId);
     
    	while(GetMessage(&msg,NULL,NULL,NULL))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
     
    	wglMakeCurrent(NULL,NULL);
    	wglDeleteContext(hPrimaryRC);
    	wglDeleteContext(hSlaverRC);
     
    	return msg.wParam;
    }

    Question are following up in those description
    I Search a lot of bbs ,but in the end, i still can't solve that problem.
    Please help T^T, and forgive my english not well... it's teach by my math teacher
    Last edited by Caesirekin; 11-12-2013 at 07:26 AM. Reason: Edit content

  2. #2
    Junior Member Newbie
    Join Date
    Mar 2013
    Posts
    12
    If nobody could hlep me slove this problem,
    May some one give me some references document what may helpful for me?
    I'm really interesting about multi-thread opengl,and i don't want use others libraries
    It's not good for a beginner to understanding those thinking, i thought
    Thanks everyone

  3. #3
    Senior Member OpenGL Pro Aleksandar's Avatar
    Join Date
    Jul 2009
    Posts
    1,144
    Your problem is not OpenGL related. You have to learn how to use events to send "commands" to rendering thread.
    What you've done is making two contexts that share resources using "an old way" through wglShareLists(), and then you changed state of non-rendering context hoping it would change state of the rendering context too. Well, it is totally wrong assumption.

    Advice: Use a single GL context in the rendering thread and whenever something have to be changed send a message to that thread. Use events to signal addition of a message to a command queue.

  4. #4
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    455
    You are setting glShadeModel(GL_FLAT) in one context, but rendering with the other context. Since this state is per-context it never affects rendering. Only certain objects are shared between contexts - see the OpenGL spec. appendices.

  5. #5
    Junior Member Newbie
    Join Date
    Mar 2013
    Posts
    12
    Quote Originally Posted by Aleksandar View Post
    Your problem is not OpenGL related. You have to learn how to use events to send "commands" to rendering thread.
    What you've done is making two contexts that share resources using "an old way" through wglShareLists(), and then you changed state of non-rendering context hoping it would change state of the rendering context too. Well, it is totally wrong assumption.

    Advice: Use a single GL context in the rendering thread and whenever something have to be changed send a message to that thread. Use events to signal addition of a message to a command queue.
    Thanks very much
    And yes,I was using and old tutorial to learning those thing, really
    My Win32 API tutorial was published may has ten years ago(those book was diffcult to find in china),
    And my OpenGL tutorial is SuperBible (Fourth Edition),I buy the fifth edition too, but haven't read yet.
    I'll keep learning,Anyway,As you've said, i think i should learning more about Win32 API and OpenGL more deeply
    Thanks again.

  6. #6
    Junior Member Newbie
    Join Date
    Mar 2013
    Posts
    12
    Quote Originally Posted by Dan Bartlett View Post
    You are setting glShadeModel(GL_FLAT) in one context, but rendering with the other context. Since this state is per-context it never affects rendering. Only certain objects are shared between contexts - see the OpenGL spec. appendices.
    Thanks for your hlep,someone told me that wglMakeCurrent can changing the current redering context to another thread, so i try these code
    Whatever, i will try that book(is it a book?),a book is very useful help for me

  7. #7
    Junior Member Newbie
    Join Date
    Mar 2013
    Posts
    12
    Quote Originally Posted by Dan Bartlett View Post
    You are setting glShadeModel(GL_FLAT) in one context, but rendering with the other context. Since this state is per-context it never affects rendering. Only certain objects are shared between contexts - see the OpenGL spec. appendices.
    Well ... I thought i misunderstanding your means, i'll see the OpenGL specification right now...= =!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •