Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Sluggish OpenGL performance using Win32


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 BinaryPhysics   Members   -  Reputation: 294

Like
0Likes
Like

Posted 08 July 2012 - 04:57 PM

Just to simplify everything here is a copy of the source file in question:
[source lang="cpp"]/*** main.cpp*/# include <stdlib.h># include <time.h># include <windows.h># if defined(_WINDOWS_)# include <gl\gl.h># endif /* defined(_WINDOWS_) */LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);HDC hdc;PIXELFORMATDESCRIPTOR pfd;int format;HGLRC hglrc;/*** entry point*/int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){ WNDCLASS WndClass; HWND hWnd; MSG msg; WndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = hInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = NULL; WndClass.lpszMenuName = NULL; WndClass.lpszClassName = "greyscale"; if(RegisterClass(&WndClass) == 0) { MessageBox(NULL, "Unable to register the window's class.", "", MB_OK | MB_ICONERROR); return 0; } hWnd = CreateWindow("greyscale", "greyscale", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 800, 600, NULL, NULL, hInstance, NULL); if(!hWnd) { MessageBox(NULL, "Failed to create window.", "", MB_OK | MB_ICONERROR); return 0; } hdc = GetDC(hWnd); ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; format = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, format, &pfd); hglrc = wglCreateContext(hdc); if(!hglrc) { MessageBox(NULL, "Failed to create context for OpenGL.", "", MB_OK | MB_ICONERROR); return 0; } if(wglMakeCurrent(hdc, hglrc) == FALSE) { MessageBox(NULL, "Unable to change the current context.", "", MB_OK | MB_ICONERROR); return 0; } ReleaseDC(hWnd, hdc); ShowWindow(hWnd, nShowCmd); UpdateWindow(hWnd); glClearColor(0.0f, 1.0f, 0.0f, 0.0f); for(;;) { if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } glClear(GL_COLOR_BUFFER_BIT); glFlush(); } wglMakeCurrent(NULL, NULL); wglDeleteContext(hglrc); return msg.wParam;}/*** message handler*/LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg) { case WM_NULL: { return 0; } case WM_DESTROY: { PostQuitMessage(0); return 0; } case WM_CLOSE: { if(MessageBox(hWnd, "Are you sure you want to exit?", "", MB_YESNO | MB_ICONQUESTION) == IDYES) DestroyWindow(hWnd); return 0; } } return DefWindowProc(hWnd, msg, wParam, lParam);}[/source]

This has been bugging me for a while so I thought I might as well see if it's happened to anyone else or see if someone can tell me how badly I'm going wrong.

I've finally managed to get OpenGL rendering within Win32 (and not through the other third party libraries like GLUT).

My issue though is that when I actually include rendering commands in the main loop the window appears to become unresponsive. I say appears because I can drag it around occasionally and it takes ages to respond.

The issue disappears with I remove the Clear and Flush commands in the loop.

I've added a timer (not shown above) to limit the speed at when the rendering runs and the issue then goes away. The only conclusion I can come to is that the OpenGL commands take to long and cause PeekMessage to miss messages in the queue (that was all I had, I only started Win32 yesterday so I'm probably wrong).

The code compiles correctly and produces no errors in Visual Studio. What exactly is causing this behaviour?

Edited by BinaryPhysics, 08 July 2012 - 05:34 PM.


Sponsor:

#2 phantom   Moderators   -  Reputation: 7592

Like
2Likes
Like

Posted 08 July 2012 - 05:15 PM

Well, you don't want to use 'glFlush', that's for certain. While that can flush commands to be executed you are basically telling the driver 'clear the same bit of memory over and over' - you need to call the 'swapbuffers' function (I can't recall the Win32 function for it) to make anything really happen.

The other consideration is do you even get a hardware context? If this is executing in software you are basically running a tight loop clearly memory over and over again and the OpenGL1.1 Software implementation is basically a bit load of rubbish so might explain things.

In short;
- check you aren't in software
- don't call glFlush EVER (until you know when you should call it in the future of course)
- even if in hardware your test case is broken so drawing conclusions from it aren't valid - GL calls don't take a long time to execute as most just push commands into a command queue and do work 'later' (generally a few frames later)

#3 BinaryPhysics   Members   -  Reputation: 294

Like
0Likes
Like

Posted 08 July 2012 - 05:25 PM

Well, you don't want to use 'glFlush', that's for certain.


But this is a single buffered program. What exactly would I end up swapping too?

The other consideration is do you even get a hardware context? [...] the OpenGL1.1 Software implementation is basically a bit load of rubbish so might explain things.


Is that not anything to do with the CreateContext command? I found a copy of the OpenGL Programming Guide (Release 1) so everything I've learnt is from there.

even if in hardware your test case is broken so drawing conclusions from it aren't valid - GL calls don't take a long time to execute as most just push commands into a command queue and do work 'later' (generally a few frames later)


I figured I was probably wrong (otherwise you wouldn't have the 'remove' choice when calling PeekMessage) but I'm honestly confused why it seems to crawl to a standstill when it isn't regulated.

Edited by BinaryPhysics, 08 July 2012 - 05:33 PM.


#4 phantom   Moderators   -  Reputation: 7592

Like
0Likes
Like

Posted 08 July 2012 - 05:50 PM

Oh, i missed the single buffered bit.... chances are between that, the 24bit color restriction and just grabbing the first context you might well be running on a slow software path.

Any reason you DONT want double buffering anyway?

#5 SimonForsman   Crossbones+   -  Reputation: 6323

Like
2Likes
Like

Posted 08 July 2012 - 06:10 PM

Just to simplify everything here is a copy of the source file in question:
[source lang="cpp"]/*** main.cpp*/# include <stdlib.h># include <time.h># include <windows.h># if defined(_WINDOWS_)# include <gl\gl.h># endif /* defined(_WINDOWS_) */LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);HDC hdc;PIXELFORMATDESCRIPTOR pfd;int format;HGLRC hglrc;/*** entry point*/int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){ WNDCLASS WndClass; HWND hWnd; MSG msg; WndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = hInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = NULL; WndClass.lpszMenuName = NULL; WndClass.lpszClassName = "greyscale"; if(RegisterClass(&WndClass) == 0) { MessageBox(NULL, "Unable to register the window's class.", "", MB_OK | MB_ICONERROR); return 0; } hWnd = CreateWindow("greyscale", "greyscale", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 800, 600, NULL, NULL, hInstance, NULL); if(!hWnd) { MessageBox(NULL, "Failed to create window.", "", MB_OK | MB_ICONERROR); return 0; } hdc = GetDC(hWnd); ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; format = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, format, &pfd); hglrc = wglCreateContext(hdc); if(!hglrc) { MessageBox(NULL, "Failed to create context for OpenGL.", "", MB_OK | MB_ICONERROR); return 0; } if(wglMakeCurrent(hdc, hglrc) == FALSE) { MessageBox(NULL, "Unable to change the current context.", "", MB_OK | MB_ICONERROR); return 0; } ReleaseDC(hWnd, hdc); ShowWindow(hWnd, nShowCmd); UpdateWindow(hWnd); glClearColor(0.0f, 1.0f, 0.0f, 0.0f); for(;;) { if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } glClear(GL_COLOR_BUFFER_BIT); glFlush(); } wglMakeCurrent(NULL, NULL); wglDeleteContext(hglrc); return msg.wParam;}/*** message handler*/LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg) { case WM_NULL: { return 0; } case WM_DESTROY: { PostQuitMessage(0); return 0; } case WM_CLOSE: { if(MessageBox(hWnd, "Are you sure you want to exit?", "", MB_YESNO | MB_ICONQUESTION) == IDYES) DestroyWindow(hWnd); return 0; } } return DefWindowProc(hWnd, msg, wParam, lParam);}[/source]

This has been bugging me for a while so I thought I might as well see if it's happened to anyone else or see if someone can tell me how badly I'm going wrong.

I've finally managed to get OpenGL rendering within Win32 (and not through the other third party libraries like GLUT).

My issue though is that when I actually include rendering commands in the main loop the window appears to become unresponsive. I say appears because I can drag it around occasionally and it takes ages to respond.

The issue disappears with I remove the Clear and Flush commands in the loop.

I've added a timer (not shown above) to limit the speed at when the rendering runs and the issue then goes away. The only conclusion I can come to is that the OpenGL commands take to long and cause PeekMessage to miss messages in the queue (that was all I had, I only started Win32 yesterday so I'm probably wrong).

The code compiles correctly and produces no errors in Visual Studio. What exactly is causing this behaviour?


The big killer is this:

if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
				{
						if(msg.message == WM_QUIT)
								break;

						TranslateMessage(&msg);
						DispatchMessage(&msg);
				}

				glClear(GL_COLOR_BUFFER_BIT);
				glFlush();

change that if to a while, otherwise you only process 1 window message per frame and the message queue will get flooded if you do anything that generates alot of messages (such as moving the window)
I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

#6 BinaryPhysics   Members   -  Reputation: 294

Like
0Likes
Like

Posted 08 July 2012 - 06:55 PM

Any reason you DONT want double buffering anyway?


Not in the slightest. When learning stuff in the past, I've had a tendency to move far to fast and begin stumbling over further topics that I lack any grounding in. I've got the first copy of OpenGL 1.0 and I've done the first 6 chapters (I need to go back over lighting though). The only reason I'm ignore any use of buffers is that I simply haven't learnt it yet.

[...] change that if to a while, otherwise you only process 1 window message per frame...


When I read this I actually wanted to slap myself. I can't believe I missed something so theoretically simple. Thank-you so much.

Although that didn't actually solve the problem... Now I'm running with a while loop to process all the built up messages and I removed call to Flush. The program now slows down my entire laptop.

#7 mark ds   Members   -  Reputation: 1486

Like
0Likes
Like

Posted 08 July 2012 - 07:10 PM

Post the code...

and add this.

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.cDepthBits = 24;
pfd.cStencilBits = 0;

Edited by mark ds, 08 July 2012 - 07:14 PM.


#8 SimonForsman   Crossbones+   -  Reputation: 6323

Like
2Likes
Like

Posted 08 July 2012 - 07:12 PM

Any reason you DONT want double buffering anyway?


Not in the slightest. When learning stuff in the past, I've had a tendency to move far to fast and begin stumbling over further topics that I lack any grounding in. I've got the first copy of OpenGL 1.0 and I've done the first 6 chapters (I need to go back over lighting though). The only reason I'm ignore any use of buffers is that I simply haven't learnt it yet.

[...] change that if to a while, otherwise you only process 1 window message per frame...


When I read this I actually wanted to slap myself. I can't believe I missed something so theoretically simple. Thank-you so much.

Although that didn't actually solve the problem... Now I'm running with a while loop to process all the built up messages and I removed call to Flush. The program now slows down my entire laptop.


That seems to be as expected aswell, without the flush and no double buffering your application should do its best to occupy a full core on your cpu. (If you only got one then the rest of the system will slow down considerably (Which is fine if its a fullscreen game), you could post your modified code again so we can see if you're doing something else thats wierd.

Since you're only using one buffer i'd highly recommend using glFinish instead of glFlush aswell, Flush only tells the driver to send any buffered commands to the GPU (the opengl driver is free to buffer and batch the commands you give it), glFinish will actually wait for the GPU to finish its job (just like a buffer swap would)
I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

#9 BinaryPhysics   Members   -  Reputation: 294

Like
0Likes
Like

Posted 08 July 2012 - 07:16 PM

[source lang=cpp"]/*** main.cpp*/# include <stdlib.h># include <time.h># include <windows.h># if defined(_WINDOWS_)# include <gl\gl.h># endif /* defined(_WINDOWS_) */LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);HDC hdc;PIXELFORMATDESCRIPTOR pfd;int format;HGLRC hglrc;/*** entry point*/int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){ WNDCLASS WndClass; HWND hWnd; MSG msg; WndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = hInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = NULL; WndClass.lpszMenuName = NULL; WndClass.lpszClassName = "greyscale"; if(RegisterClass(&WndClass) == 0) { MessageBox(NULL, "Unable to register the window's class.", "", MB_OK | MB_ICONERROR); return 0; } hWnd = CreateWindow("greyscale", "greyscale", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 800, 600, NULL, NULL, hInstance, NULL); if(!hWnd) { MessageBox(NULL, "Failed to create window.", "", MB_OK | MB_ICONERROR); return 0; } hdc = GetDC(hWnd); ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); 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.cDepthBits = 24; pfd.cStencilBits = 0; format = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, format, &pfd); hglrc = wglCreateContext(hdc); if(!hglrc) { MessageBox(NULL, "Failed to create context for OpenGL.", "", MB_OK | MB_ICONERROR); return 0; } if(wglMakeCurrent(hdc, hglrc) == FALSE) { MessageBox(NULL, "Unable to change the current context.", "", MB_OK | MB_ICONERROR); return 0; } ShowWindow(hWnd, nShowCmd); UpdateWindow(hWnd); glClearColor(0.0f, 1.0f, 0.0f, 0.0f); for(;;) { while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_TRIANGLES); glVertex2f( 0.5f, 0.5f ); glVertex2f(-0.5f, 0.75f); glVertex2f(-0.35f, -0.4f); glEnd(); glViewport(0, 0, 800, 600); SwapBuffers(hdc); } wglMakeCurrent(NULL, NULL); wglDeleteContext(hglrc); ReleaseDC(hWnd, hdc); return msg.wParam;}/*** message handler*/LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg) { case WM_NULL: { return 0; } case WM_DESTROY: { PostQuitMessage(0); return 0; } case WM_CLOSE: { if(MessageBox(hWnd, "Are you sure you want to exit?", "", MB_YESNO | MB_ICONQUESTION) == IDYES) DestroyWindow(hWnd); return 0; } } return DefWindowProc(hWnd, msg, wParam, lParam);}[/source]


and add this.


See that addition makes the program run. I think I'm missing something about Window's behaviour and a single OpenGL buffer?

Since you're only using one buffer i'd highly recommend using glFinish instead of glFlush aswell


I had been using that but I thought it might have been the cause so I took it out.

Edited by BinaryPhysics, 08 July 2012 - 07:21 PM.


#10 BinaryPhysics   Members   -  Reputation: 294

Like
0Likes
Like

Posted 08 July 2012 - 07:30 PM

Just out of curiosity I did two things:
  • Leave the call to ReleaseDC at the bottom of WinMain after it had been moved; and
  • Took the program back to a single buffer with no information about the stencil or depth buffer (I left the increased colour bits).
[source lang="cpp"]/*** main.cpp*/# include <stdlib.h># include <time.h># include <windows.h># if defined(_WINDOWS_)# include <gl\gl.h># endif /* defined(_WINDOWS_) */LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);HDC hdc;PIXELFORMATDESCRIPTOR pfd;int format;HGLRC hglrc;/*** entry point*/int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){ WNDCLASS WndClass; HWND hWnd; MSG msg; WndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = hInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = NULL; WndClass.lpszMenuName = NULL; WndClass.lpszClassName = "greyscale"; if(RegisterClass(&WndClass) == 0) { MessageBox(NULL, "Unable to register the window's class.", "", MB_OK | MB_ICONERROR); return 0; } hWnd = CreateWindow("greyscale", "greyscale", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 800, 600, NULL, NULL, hInstance, NULL); if(!hWnd) { MessageBox(NULL, "Failed to create window.", "", MB_OK | MB_ICONERROR); return 0; } hdc = GetDC(hWnd); ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; format = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, format, &pfd); hglrc = wglCreateContext(hdc); if(!hglrc) { MessageBox(NULL, "Failed to create context for OpenGL.", "", MB_OK | MB_ICONERROR); return 0; } if(wglMakeCurrent(hdc, hglrc) == FALSE) { MessageBox(NULL, "Unable to change the current context.", "", MB_OK | MB_ICONERROR); return 0; } ShowWindow(hWnd, nShowCmd); UpdateWindow(hWnd); glClearColor(0.0f, 1.0f, 0.0f, 0.0f); for(;;) { while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_TRIANGLES); glVertex2f( 0.5f, 0.5f ); glVertex2f(-0.5f, 0.75f); glVertex2f(-0.35f, -0.4f ); glEnd(); glViewport(0, 0, 800, 600); glFinish(); } wglMakeCurrent(NULL, NULL); wglDeleteContext(hglrc); ReleaseDC(hWnd, hdc); return msg.wParam;}/*** message handler*/LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg) { case WM_NULL: { return 0; } case WM_DESTROY: { PostQuitMessage(0); return 0; } case WM_CLOSE: { if(MessageBox(hWnd, "Are you sure you want to exit?", "", MB_YESNO | MB_ICONQUESTION) == IDYES) DestroyWindow(hWnd); return 0; } } return DefWindowProc(hWnd, msg, wParam, lParam);}[/source]

The program now runs smoothly; but only if the Finish command is used (instead of Flush).

I think the issue was identified in these places:

[...] the 24bit color restriction...

[source lang="cpp"]pfd.cColorBits = 32;[/source]


It doesn't quit properly; but that's a separate issue I can work on.

Thanks a lot for your help.

Edited by BinaryPhysics, 08 July 2012 - 07:36 PM.


#11 mark ds   Members   -  Reputation: 1486

Like
0Likes
Like

Posted 08 July 2012 - 07:38 PM

easy fix for the exit problem...

	    for(;;)
	    {
			    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
			    {
					    if(msg.message == WM_QUIT)
							    break;

					    TranslateMessage(&msg);
					    DispatchMessage(&msg);
			    }
else
{

			    glClear(GL_COLOR_BUFFER_BIT);

			    glColor3f(0.0f, 0.0f, 0.0f);
			    glBegin(GL_TRIANGLES);
					    glVertex2f( 0.5f,   0.5f );
					    glVertex2f(-0.5f,   0.75f);
					    glVertex2f(-0.35f, -0.4f );
			    glEnd();

			    glViewport(0, 0, 800, 600);

			    glFinish();
}
	    }


#12 mark ds   Members   -  Reputation: 1486

Like
0Likes
Like

Posted 08 July 2012 - 07:45 PM

Just to add... you won't get a lot of help with single buffering or glFinish, simply because nobody ever uses it!

#13 mhagain   Crossbones+   -  Reputation: 8284

Like
1Likes
Like

Posted 09 July 2012 - 05:11 AM

Any reason you DONT want double buffering anyway?


Not in the slightest. When learning stuff in the past, I've had a tendency to move far to fast and begin stumbling over further topics that I lack any grounding in. I've got the first copy of OpenGL 1.0 and I've done the first 6 chapters (I need to go back over lighting though). The only reason I'm ignore any use of buffers is that I simply haven't learnt it yet.


I have to comment on this because there's actually nothing to learn with double-buffering. Just make sure that you set PFD_DOUBLEBUFFER and call SwapBuffers at the end of the frame - that's it. OpenGL tutorials that create single buffered contexts may give you the misguided impression that a double-buffered context is somehow more complex or needs more work; it's not.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#14 L. Spiro   Crossbones+   -  Reputation: 14411

Like
0Likes
Like

Posted 09 July 2012 - 05:32 AM

Just to add... you won't get a lot of help with single buffering or glFinish, simply because nobody ever uses it!

Not exactly. It is used quite often in multi-threaded rendering setups to signal that resources are no longer being used by the GPU (among other things).


L. Spiro

Edited by L. Spiro, 09 July 2012 - 05:32 AM.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#15 BinaryPhysics   Members   -  Reputation: 294

Like
0Likes
Like

Posted 10 July 2012 - 05:37 PM

easy fix for the exit problem...


Yeah, it occurred to me that the break statement suddenly becomes an exit from the message loop by not the containing loop.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS