Skip to main content
GameDev.net gamedev.net
🔒 Locked

Rendering in two windows

Started by Sh@dow Sep 2, 2009 at 8:29 AM 5 replies 1.4k views
Original Post
Sh@dow
Sh@dow
Hi all. I'm trying to render in two windows,which were created using pure API(Windows XP). The windows were created like this: //////////////////////CODE/////////////////////////////////////// WNDCLASSEX wndclass; wndclass.cbSize=sizeof(wndclass); wndclass.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndclass.lpfnWndProc=wndproc1; wndclass.cbClsExtra=NULL; wndclass.cbWndExtra=NULL; wndclass.hInstance=NULL; wndclass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(668));; wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground=(HBRUSH)13; wndclass.lpszMenuName=NULL; wndclass.lpszClassName=classname; wndclass.hIconSm=NULL; RegisterClassEx(&wndclass); HWND winhandle=CreateWindowEx(NULL,classname,L"FIRST",WS_OVERLAPPEDWINDOW|WS_MAXIMIZE, 0,0,790,550,NULL,NULL, NULL,NULL); HDC mDC = GetDC(winhandle); PIXELFORMATDESCRIPTOR pfd; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cRedBits = 8; pfd.cRedShift = 16; pfd.cGreenBits = 8; pfd.cGreenShift = 8; pfd.cBlueBits = 8; pfd.cBlueShift = 0; pfd.cAlphaBits = 0; pfd.cAlphaShift = 0; pfd.cAccumBits = 64; pfd.cAccumRedBits = 16; pfd.cAccumGreenBits = 16; pfd.cAccumBlueBits = 16; pfd.cAccumAlphaBits = 0; pfd.cDepthBits = 32; pfd.cStencilBits = 8; pfd.cAuxBuffers = 0; pfd.iLayerType = PFD_MAIN_PLANE; pfd.bReserved = 0; pfd.dwLayerMask = 0; pfd.dwVisibleMask = 0; pfd.dwDamageMask = 0; int PixelFormat = ChoosePixelFormat(mDC,&pfd); if(PixelFormat==0) DescribePixelFormat(mDC,1,sizeof(PIXELFORMATDESCRIPTOR),&pfd); else { if(!SetPixelFormat(mDC,PixelFormat,&pfd)) MessageBox(0,L"Error setting pixel format",L"Error",MB_OK); } HGLRC mRC = wglCreateContext(mDC); if(mRC == 0) MessageBox(0,L"wglCreateContext failed",L"ERROR",MB_OK); if(!wglMakeCurrent(mDC,mRC)) MessageBox(0,L"wglMakeCurrent failed",L"ERROR",MB_OK); ShowWindow(winhandle,SW_SHOW); UpdateWindow(winhandle); //creating second window WNDCLASSEX wndclass1; wndclass.cbSize=sizeof(wndclass1); wndclass.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndclass.lpfnWndProc=wndproc2; wndclass.cbClsExtra=NULL; wndclass.cbWndExtra=NULL; wndclass.hInstance=NULL; wndclass.hIcon=0; wndclass.hCursor=0; wndclass.hbrBackground=(HBRUSH)13; wndclass.lpszMenuName=NULL; wndclass.lpszClassName=classname1; wndclass.hIconSm=NULL; RegisterClassEx(&wndclass1); HWND winhandle2=CreateWindowEx(NULL,classname1,L"SECOND",WS_OVERLAPPEDWINDOW|WS_MAXIMIZE, 0,0,790,550,NULL,NULL, NULL,NULL); mDC = GetDC(winhandle2); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cRedBits = 8; pfd.cRedShift = 16; pfd.cGreenBits = 8; pfd.cGreenShift = 8; pfd.cBlueBits = 8; pfd.cBlueShift = 0; pfd.cAlphaBits = 0; pfd.cAlphaShift = 0; pfd.cAccumBits = 64; pfd.cAccumRedBits = 16; pfd.cAccumGreenBits = 16; pfd.cAccumBlueBits = 16; pfd.cAccumAlphaBits = 0; pfd.cDepthBits = 32; pfd.cStencilBits = 8; pfd.cAuxBuffers = 0; pfd.iLayerType = PFD_MAIN_PLANE; pfd.bReserved = 0; pfd.dwLayerMask = 0; pfd.dwVisibleMask = 0; pfd.dwDamageMask = 0; PixelFormat = ChoosePixelFormat(mDC,&pfd); if(PixelFormat==0) DescribePixelFormat(mDC,1,sizeof(PIXELFORMATDESCRIPTOR),&pfd); else { if(!SetPixelFormat(mDC,PixelFormat,&pfd)) MessageBox(0,L"Error setting pixel format",L"Error",MB_OK); } mRC = wglCreateContext(mDC); if(mRC == 0) MessageBox(0,L"wglCreateContext failed",L"ERROR",MB_OK); if(!wglMakeCurrent(mDC,mRC)) MessageBox(0,L"wglMakeCurrent failed",L"ERROR",MB_OK); ShowWindow(winhandle2,SW_SHOW); UpdateWindow(winhandle2); After each window was created it's dc was initilized for OpenGL use like shown above.Each window has in it's WM_PAINT and WM_SIZE the following code: RECT rect; HDC clientdc = GetDC(hWnd); GetClientRect(hWnd,▭); int width = rect.right - rect.left; int height = rect.bottom - rect.top; glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-width/2,width/2,-height/2,height/2); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); //drawing zero line glBegin(GL_LINES); glColor3f(1,1,1); glVertex2d(width/2,0); glVertex2d(-width/2,100); glEnd(); glFlush(); SwapBuffers(clientdc); Everything is rendering, the problem is that the first window is repainted incorrectly.When i'm trying to change is's size the strange lines are shown.When i remove the OpenGL initilization for the second window the first is repaited well on resize.Where can be the problem?
Erik Rufelt
Erik Rufelt
Use [source]..code..[/source] tags, to allow for easier viewing of your code.
It would probably also be a good idea to make a minimal compilable example.

Quote:
Original post by Sh@dow
//creating second window
WNDCLASSEX wndclass1;
wndclass.cbSize=sizeof(wndclass1);
wndclass.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.lpfnWndProc=wndproc2;
wndclass.cbClsExtra=NULL;
wndclass.cbWndExtra=NULL;
wndclass.hInstance=NULL;
wndclass.hIcon=0;
wndclass.hCursor=0;
wndclass.hbrBackground=(HBRUSH)13;
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName=classname1;
wndclass.hIconSm=NULL;

RegisterClassEx(&wndclass1);


Seems very strange if this would work. You set the members of wndclass, but you should set the members of wndclass1.

There shouldn't be anything special to be done, if you create two windows and rendering contexts the same way, then you can draw to both of them, and resize the windows, independently. It's hard to say what could be the problem from incomplete code, especially when it shouldn't even work, since RegisterClassEx should most definitely fail if you are using the code above where wndclass1 is uninitialized.
Well actually it will fail but you use the same classname for you first windowclass, so both window 1 and window 2 will share the same window-class and therefore the same WndProc. Perhaps the problem is in there somewhere.
Sh@dow
Sh@dow
Thanks for reply.There are bugs in the code so i fixed them now.
The window is still not redrawing so i will post the whole code.
WNDCLASSEX wndclass1;	wndclass1.cbSize=sizeof(wndclass1);	wndclass1.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	wndclass1.lpfnWndProc=wndproc1;	wndclass1.cbClsExtra=NULL;	wndclass1.cbWndExtra=NULL;	wndclass1.hInstance=NULL;	wndclass1.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(668));;	wndclass1.hCursor=LoadCursor(NULL,IDC_ARROW);	wndclass1.hbrBackground=(HBRUSH)13;	wndclass1.lpszMenuName=NULL;	wndclass1.lpszClassName=classname1;	wndclass1.hIconSm=NULL;	RegisterClassEx(&wndclass1);	HWND winhandle1=CreateWindowEx(NULL,classname1,L"FIRST",WS_OVERLAPPEDWINDOW|WS_MAXIMIZE,						0,0,790,550,NULL,NULL,						NULL,NULL);		HDC mDC = GetDC(winhandle1);				PIXELFORMATDESCRIPTOR pfd;					pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 				pfd.nVersion = 1; 				pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 				pfd.iPixelType = PFD_TYPE_RGBA; 				pfd.cColorBits = 32; 				pfd.cRedBits = 8;				pfd.cRedShift = 16;				pfd.cGreenBits = 8;				pfd.cGreenShift = 8;				pfd.cBlueBits = 8;				pfd.cBlueShift = 0;				pfd.cAlphaBits  = 0;				pfd.cAlphaShift = 0;				pfd.cAccumBits = 64;				pfd.cAccumRedBits = 16;				pfd.cAccumGreenBits = 16;				pfd.cAccumBlueBits = 16;				pfd.cAccumAlphaBits = 0;				pfd.cDepthBits = 32;				pfd.cStencilBits = 8;				pfd.cAuxBuffers = 0;				pfd.iLayerType = PFD_MAIN_PLANE;				pfd.bReserved = 0;				pfd.dwLayerMask = 0;				pfd.dwVisibleMask = 0;				pfd.dwDamageMask = 0;				int PixelFormat = ChoosePixelFormat(mDC,&pfd);				if(PixelFormat==0)				DescribePixelFormat(mDC,1,sizeof(PIXELFORMATDESCRIPTOR),&pfd);				else				{					if(!SetPixelFormat(mDC,PixelFormat,&pfd))						MessageBox(0,L"Error setting pixel format",L"Error",MB_OK);				}					HGLRC mRC = wglCreateContext(mDC);				if(mRC == 0)				MessageBox(0,L"wglCreateContext failed",L"ERROR",MB_OK);				if(!wglMakeCurrent(mDC,mRC))				MessageBox(0,L"wglMakeCurrent failed",L"ERROR",MB_OK);		ShowWindow(winhandle1,SW_SHOW);	UpdateWindow(winhandle1);	//creating second window	WNDCLASSEX wndclass2;	wndclass2.cbSize=sizeof(wndclass2);	wndclass2.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	wndclass2.lpfnWndProc=wndproc2;	wndclass2.cbClsExtra=NULL;	wndclass2.cbWndExtra=NULL;	wndclass2.hInstance=NULL;	wndclass2.hIcon=0;	wndclass2.hCursor=0;	wndclass2.hbrBackground=(HBRUSH)13;	wndclass2.lpszMenuName=NULL;	wndclass2.lpszClassName=classname2;	wndclass2.hIconSm=NULL;	RegisterClassEx(&wndclass2);	HWND winhandle2=CreateWindowEx(NULL,classname2,L"SECOND",WS_OVERLAPPEDWINDOW|WS_MAXIMIZE,						0,0,790,550,NULL,NULL,						NULL,NULL);			 mDC = GetDC(winhandle2);				 					pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 				pfd.nVersion = 1; 				pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 				pfd.iPixelType = PFD_TYPE_RGBA; 				pfd.cColorBits = 32; 				pfd.cRedBits = 8;				pfd.cRedShift = 16;				pfd.cGreenBits = 8;				pfd.cGreenShift = 8;				pfd.cBlueBits = 8;				pfd.cBlueShift = 0;				pfd.cAlphaBits  = 0;				pfd.cAlphaShift = 0;				pfd.cAccumBits = 64;				pfd.cAccumRedBits = 16;				pfd.cAccumGreenBits = 16;				pfd.cAccumBlueBits = 16;				pfd.cAccumAlphaBits = 0;				pfd.cDepthBits = 32;				pfd.cStencilBits = 8;				pfd.cAuxBuffers = 0;				pfd.iLayerType = PFD_MAIN_PLANE;				pfd.bReserved = 0;				pfd.dwLayerMask = 0;				pfd.dwVisibleMask = 0;				pfd.dwDamageMask = 0;				 PixelFormat = ChoosePixelFormat(mDC,&pfd);				if(PixelFormat==0)				DescribePixelFormat(mDC,1,sizeof(PIXELFORMATDESCRIPTOR),&pfd);				else				{					if(!SetPixelFormat(mDC,PixelFormat,&pfd))						MessageBox(0,L"Error setting pixel format",L"Error",MB_OK);				}					mRC = wglCreateContext(mDC);				if(mRC == 0)				MessageBox(0,L"wglCreateContext failed",L"ERROR",MB_OK);				if(!wglMakeCurrent(mDC,mRC))				MessageBox(0,L"wglMakeCurrent failed",L"ERROR",MB_OK);				ShowWindow(winhandle2,SW_SHOW);				UpdateWindow(winhandle2);	MSG message;	while(GetMessage(&message,NULL,0,0))	{		TranslateMessage(&message);		DispatchMessage(&message);			}


The window procedure is the same for both windows i will post only one:
LRESULT CALLBACK wndproc1(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){	switch(uMsg)	{				case WM_PAINT:			{				RECT rect;				HDC clientdc = GetDC(hWnd);				GetClientRect(hWnd,▭);				int width = rect.right - rect.left;				int height = rect.bottom - rect.top;				glViewport(0,0,width,height);					glMatrixMode(GL_PROJECTION);				glLoadIdentity();					gluOrtho2D(-width/2,width/2,-height/2,height/2);					glClearColor(0,0,0,0);				glClear(GL_COLOR_BUFFER_BIT);				//drawing zero line				glBegin(GL_LINES);				glColor3f(1,1,1);				glVertex2d(width/2,0);				glVertex2d(-width/2,100);				glEnd();				glFlush();				SwapBuffers(clientdc);											}			break;			case WM_SIZE:			{				RECT rect;				HDC clientdc = GetDC(hWnd);				GetClientRect(hWnd,▭);				int width = rect.right - rect.left;				int height = rect.bottom - rect.top;				glViewport(0,0,width,height);					glMatrixMode(GL_PROJECTION);				glLoadIdentity();					gluOrtho2D(-width/2,width/2,-height/2,height/2);					glClearColor(0,0,0,0);				glClear(GL_COLOR_BUFFER_BIT);				//drawing zero line				glBegin(GL_LINES);				glColor3f(1,1,1);				glVertex2d(width/2,0);				glVertex2d(-width/2,100);				glEnd();				glFlush();				SwapBuffers(clientdc);							}			break;		case WM_CLOSE:			{				ExitProcess(0);			}			break;		default:			return DefWindowProc(hWnd,uMsg,wParam,lParam);	}	return DefWindowProc(hWnd,uMsg,wParam,lParam);}


The second window is resized well, the first on resize has strange lines.I had the same bug in MFC writing MDI and SDI applications.
Erik Rufelt
Erik Rufelt
For one you don't seem to use wglMakeCurrent() in you draw functions, which means you will only draw to one window.. since they have different RCs you must set the correct current RC when drawing to each. As of now you will draw to the same RC twice. This might lead to problems, especially since you use glOrtho with what seems to be the window dimensions. When one window is larger, you will draw to the same RC twice, once with a smaller size and once with a larger size. Since you clear the buffer it shouldn't be noticeable though..
I assume one of your windows is only black, without anything drawing in it?

What exactly are you trying to accomplish, and why are you only drawing in WM_PAINT and WM_SIZE?
Usually one want animated scenes, and should draw constantly in the main-loop, whenever no window messages are waiting to be handled.
Sh@dow
Sh@dow
>>I assume one of your windows is only black, without anything drawing in it?
In both two windowses i draw a line.So in both windowses there is a line but when i resize first in additional space of the first a line from second window appear.

Now I call the wglMakeCurrent before paiting and everything works fine.I thought that when i call wglMakeCurrent in initialization(setting pixel format) the windows dc is constantly associated with rendering context which was created with wglCreateContext ant there is no need to call wglMakeCurrent anymore.I thought OS remembers that rendering context is constantly associated with windows.

I'm drawing in WM_PAINT and in WM_SIZE because i want to draw some graphics in several windowses so i don't need animation.The graphics are redrawed only when window is resized or other windows are running on my window.

So now everything is working fine.Thanks a lot for help.
Erik Rufelt
Erik Rufelt
Quote:
Original post by Sh@dow
call the wglMakeCurrent before paiting and everything works fine.I thought that when i call wglMakeCurrent in initialization(setting pixel format) the windows dc is constantly associated with rendering context which was created with wglCreateContext ant there is no need to call wglMakeCurrent anymore.I thought OS remembers that rendering context is constantly associated with windows.


It does, but doesn't know which one you are drawing to. When you call SwapBuffer it swaps the correct buffer, but when you call glClear() for example, it has no way of knowing which of your two RCs you want cleared. wglMakeCurrent tells OpenGL which RC to draw into.
owiley
owiley
not sure but you only have one rendering context in any give moment that context should be reference to a window so that it knows who is who not sure tho. i always render with one window never did multiple
Bring more Pain

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.