• ### Announcements

#### Archived

This topic is now archived and is closed to further replies.

# SwapBuffer trouble

## Recommended Posts

Greg K    122
In my program, swapbuffers() takes 100 milliseconds. I know that openGL queues up commands and does them all in one go but I am only rendering at most 140 quads per frame! And not only that but they are 2D quads! Does anyone have an explanation/tip on how to speed this up? -Greg Reverie Entertainment

##### Share on other sites
OpenGL doesn''t queue up commands. swapbuffers just waits till all the commands are complete. Post your code.

PS: What do you mean 2D quads?!

"C lets you shoot yourself in the foot rather easily. C++ allows you to reuse the bullet!"

##### Share on other sites
exa_einstein    122
somebody told me anything about glFlush() or glFinish() and that they should be called before glSwapBuffers().

If it won''t help, try to check whether you really have TWO buffers, not one(can''t swap->copying->slow) or three (need special accelerated functions->copying->slow).

##### Share on other sites
Greg K    122
static	PIXELFORMATDESCRIPTOR pfd=				// pfd Tells Windows How We Want Things To Be	{		sizeof(PIXELFORMATDESCRIPTOR),				// Size Of This Pixel Format Descriptor		1,											// Version Number		PFD_DRAW_TO_WINDOW |						// Format Must Support Window		PFD_SUPPORT_OPENGL |						// Format Must Support OpenGL		PFD_DOUBLEBUFFER,							// Must Support Double Buffering		PFD_TYPE_RGBA,								// Request An RGBA Format		16, 										// Select Our Color Depth		0, 0, 0, 0, 0, 0,							// Color Bits Ignored		0,											// No Alpha Buffer		0,											// Shift Bit Ignored		0,											// No Accumulation Buffer		0, 0, 0, 0,									// Accumulation Bits Ignored		16,											// 16Bit Z-Buffer (Depth Buffer)  		0,											// No Stencil Buffer		0,											// No Auxiliary Buffer		PFD_MAIN_PLANE,								// Main Drawing Layer		0,											// Reserved		0, 0, 0										// Layer Masks Ignored	};		ShowWindow(hWnd,SW_SHOW);	SetForegroundWindow(hWnd);			glClearColor(0.0f, 0.0f, 0.0f, 1.0f);	glDisable(GL_DEPTH_TEST);	glEnable(GL_TEXTURE_2D);

glViewport(0, 0, width, height);	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	glOrtho(0, 800, 600, 0,-1.0f,1.0f);	glMatrixMode(GL_MODELVIEW);	glLoadIdentity();

	glBindTexture(GL_TEXTURE_2D, nTexID);		glBegin(GL_QUADS);		glTexCoord2s( 0, 0 );glVertex2s(nX		 , nY		 ); 		glTexCoord2s( 1, 0 );glVertex2s(nX+nWidth, nY		 ); 		glTexCoord2s( 1, 1 );glVertex2s(nX+nWidth, nY-nHeight); 		glTexCoord2s( 0, 1 );glVertex2s(nX		 , nY-nHeight); 	glEnd();

SwapBuffers(hDC);

Here are some code tidbits. Hope this helps...

[edited by - Greg K on August 12, 2003 9:25:04 AM]

##### Share on other sites
exa_einstein    122
huh no idea...

ma brain almost dead now, but try not to send type _short_ arguments, opengl computes only with floats.

Yes, i understand. this hasn't any chance to survive...

--edit

AND TRY TO RUN WITH MORE COLORS, 16-bit is nearly palletized.
nothing? again?

--edit2

have you sent your pfd to windows? i don't see that

[edited by - exa_einstein on August 12, 2003 9:35:43 AM]

##### Share on other sites
Greg K    122
of course I sent it to windows. It wouldn't run otherwise would it? Those are just snippets. I don't see why I shouldn't use shorts, there is an ogl function that accepts them and maybe they can do some compression on them when sending them to vid hardware? Also, how would 32 bits speed anything up? I would think it would slow it down.
-Greg

[edited by - Greg K on August 12, 2003 9:44:22 AM]

##### Share on other sites
exa_einstein    122
...it was only idea. You never know what windows want...

##### Share on other sites
Greg K    122
yeah, I am at the point where I will try anything.
-Greg

##### Share on other sites
exa_einstein    122
glFlush(); //forces ogl computing
glSwapBuffers(hDC);
//or
glFinish(); //waits for finishing ogl comkputing
glSwapBuffers(hDC);
//or
//...or
//shit...
//yeah:
try to check your videocard (if you are using some tweaker, check it too) and look for some threads/processes/viruses, they can slow it down. and then...RESET WINDO.S

...i hate smiles.
but my favourite smile is...

##### Share on other sites
Sander    1332
Check your profiler again (or do it from memory). Exactly WHAT is takin 100 milliseconds? Just the SwapBuffers() function or the entire renderloop?

My best guess anyway is that you are running in software mode. Query for GL_VENDOR. If it sais your driver, then something fishy is going on somewhere. If it says Windows, then you are in software mode and that''s why you are slow.

Sander Maréchal

GSACP: GameDev Society Against Crap Posting
To join: Put these lines in your signature and don''t post crap!

##### Share on other sites
Greg K    122
Just swapbuffers, and it is in hardware mode (NVIDIA Corporation)
-Greg

##### Share on other sites
Greg K    122
I now have it down to around 50 milliseconds. Yes, it is just that one line of code.

DWORD x = timeGetTime();
SwapBuffers(hDC);
x = timeGetTime() - x;

x = around 30-50, why?

##### Share on other sites
quote:
Original post by exa_einstein
glFinish(); //waits for finishing ogl comkputing
glSwapBuffers(hDC);

WTF NO! Don''t use glFinish with double buffering as it is useless. Use glFlush(). glFinish waits until everything is drawn so no need to swap buffers.
Because gl commands are being proccesed after being called it is good to have the rendering loop that:
firstly does CPU calculations,
then calls swapbuffers(),
then draws everything.
so while everything is being drawn your program can pump messages, do the calculations and then swapbuffers when everything is already drawn. Much more effective.

"C lets you shoot yourself in the foot rather easily. C++ allows you to reuse the bullet!"

##### Share on other sites
Greg K    122
I still don''t understand how 100-200 quads could take this long. Depth testing isn''t even on.
-Greg

##### Share on other sites
exa_einstein    122
quote:
Original post by Greg K
I now have it down to around 50 milliseconds. Yes, it is just that one line of code.

DWORD x = timeGetTime();
SwapBuffers(hDC);
x = timeGetTime() - x;

x = around 30-50, why?

Do you REALLY measure your time in miliseconds? if you get the time with QueryPerfurmanceTimer(), one cpu cycle (returned value) will be equal to a millisecond only if you have 1kHZ CPU.
-->You must divide that value by QueryPerformanceFrequency()

##### Share on other sites
Greg K    122
guh, I posted code! Yes, I really do measure my time in milliseconds just as the code shows! Unless I am mistaken and timeGetTime() actually returns something else...

-Greg

##### Share on other sites
exa_einstein    122
ALLAH SAVE ALL SWAPPING BUFFERS...

no idea... don''t you have you videocard onboard or aren''t you using shared ram memory or haven''t you S3Trio3D like me

...::why don''t we have assembler forum?::...

##### Share on other sites
Trienco    2555
how long does it take when you dont draw anything or disable texturing?

##### Share on other sites
reaptide    226
Try to avoid using glFlush() and glFinish(). It is not necessary to use them with double buffering. They will cause your program to wait until all rendering commands are finished before continuing. SwapBuffers() already does this, so its a bit redundant.

Assuming that you are using a videocard that is rather recent (Any newer than a TNT or some such) use 32-bit floats, not shorts. The vast majority of videocards prefer to get their data in 32-bit chunks. Any 32-bit system is like this really. I suspect you won''t benifit from any sort of compression since your system will just pad the remaining 16-bits with zeros.

I see you got everything running in hardware mode which is good to say the least.

Looking at your code I notice that you are binding a texture every frame. If you are only using one texture than this is not necessary. OpenGL is a state machine and it remembers the last thing you did until you tell it to do something else. So if you are indeed only using one texture, then bind it once in your initialization function (Right under the glEnable(GL_TEXTURE_2D) should do) and leave it at that. The texture bind doesn''t change until you want it to. As well I hope you aren''t loading and building the texture anew each frame. Once you got the texture object created it sticks around until you call glDeleteTextures().

Well that''s about all I have to say. Hope some of that helps.

##### Share on other sites
Greg K    122
Okay, I will switch over to 32 bit floats. Thanks for the advice. Unfortunatly I do need to bind the texture every draw because almost 100% of the time it will be a diff texture. I think I found out why it is going so slow though. I am rendering about 340 triangles per frame but these triangles cover the whole screen twice over (lots of overlapping). There is no way to get around the overlapping but I was thinking maybe I could get ogl to ignore the pixels that overlap? Will that speed it up? For instance will color keying out all the pixels I don''t need to be drawn speed it up?
-Greg

##### Share on other sites
Ilici    862
Check for driver settings -> i found something on my ATI card - swap buffers mode option with to modes: block transfer and smth else i dont remember.

look for this though i dont think it will do much

rendering 100 screen size quads is acceptable (for 800x600: 192 000 000 = 192mtexels/s)

##### Share on other sites
exa_einstein    122
Ilici is right. Try to check drivers and make sure you aren''t really moving buffers, but you are only redirecting "pointers" to them (i don''t know how is called a pointer to memory on graphics card)

2) why you have lots of textures? what are you exactly doing? If you aren''t generating them every frame, it may be better to create some bigger ones.

..and try to post all the code, we''ll check it too. I think (hope...) you won''t need copyrights or such things for 200 triangles.

...::why don''t we have assembler forum?::...

##### Share on other sites
GameCat    292
1. Don''t do a glFlush unless you know what you''re doing (that means don''t do it) and *don''t* do a glFinish unless you know what you''re doing. You''ll wreck performance.
2. If vsync is on, swapbuffer will eventually block. You can turn off vsync either in your video drivers control panel or in your program with the WGL_EXT_swap_control extension.
3. To devrease latency windows mandates a certain maximum number of frames for which drivers can buffer a buffer swap something like 2 frames or so.
4. In general, all timing measurements are useless when vsync is on.

##### Share on other sites
Sorry to bust in here, but the last poster said something which I am very interested about.

4. In general, all timing measurements are useless when vsync is on.

So how do you do timing if vsync is on? I mean, you need to do something with time, else how do you assure your game/program runs at the same speed on a slower/faster computer?

##### Share on other sites
quote:
Original post by GameCat
1. Don''t do a glFlush unless you know what you''re doing (that means don''t do it) and *don''t* do a glFinish unless you know what you''re doing. You''ll wreck performance.
2. If vsync is on, swapbuffer will eventually block. You can turn off vsync either in your video drivers control panel or in your program with the WGL_EXT_swap_control extension.
3. To devrease latency windows mandates a certain maximum number of frames for which drivers can buffer a buffer swap something like 2 frames or so.
4. In general, all timing measurements are useless when vsync is on.

1. glFlush waits till all the gl commands get proccessed, glFinish waits till everything is DRAWN. You should use glFlush if you doublebuffer.
2. Even with vsync swapbuffer won''t wait more than 60/100 ms.
4. Only if he gets more than 60 fps, and he doesn''t.

"C lets you shoot yourself in the foot rather easily. C++ allows you to reuse the bullet!"