Jump to content

  • Log In with Google      Sign In   
  • Create Account


dramatic fps drop when using transparent texture


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
39 replies to this topic

#1 fip   Members   -  Reputation: 147

Like
0Likes
Like

Posted 10 December 2012 - 11:27 AM

Hi all,
it's my first post here and i plan to be more participative from now on.
Ill start with a problem i have in one application i did in visual C+GLUT+OpenGL.
As the title states, i have a dramatic drop in frames per second when using a single BMP texture with transparency and i think maybe the problem is that im not using the texture mapping correctly.

Without the displaying of transparent texture i get 50 frames per second which for me is okay. You can notice that the grass has a texture and also the sharks have dotted texture as skin.
fps 50.jpg

In the following picture i draw the water walls i want without transparency i get 30 frames per second (20 fps drop) i dont understand why but anyway 30 fps seems to me a good framerate.
fps 30.jpg

Now in this third image i add transparency for the water walls you can see the drop to 9 fps!!! And this i can't understand as i know dealing with transparency is one of the hardest things for GPUs but common, im using only one texture in 4 quads!!!!!
fps 9.jpg

Here is the code i use:

[source lang="cpp"]void PintarCortinillasAgua(TcajaHueca *recinto, Tcontrol * control){ glMatrixMode(GL_MODELVIEW); glPushMatrix(); if(control->texturas == VERDADERO) { glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, tex_agua.tex_Id); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glBegin(GL_POLYGON);//plano Zmax glColor4f(1,1,1,0.4f); glTexCoord2f( 0, 0 + offset_agua); glVertex3f(recinto->min[X], recinto->min[Y], recinto->max[Z]); glTexCoord2f( 5, 0 + offset_agua); glVertex3f(recinto->max[X], recinto->min[Y], recinto->max[Z]); glTexCoord2f( 5, 2 + offset_agua); glVertex3f(recinto->max[X], recinto->max[Y], recinto->max[Z]); glTexCoord2f( 0, 2 + offset_agua); glVertex3f(recinto->min[X], recinto->max[Y], recinto->max[Z]); glEnd(); glBegin(GL_POLYGON); //plano Xmax glColor4f(1,1,1,0.4f); glTexCoord2f( 0, 0 + offset_agua); glVertex3f(recinto->max[X], recinto->min[Y], recinto->min[Z]); glTexCoord2f( 5, 0 + offset_agua); glVertex3f(recinto->max[X], recinto->min[Y], recinto->max[Z]); glTexCoord2f( 5, 2 + offset_agua); glVertex3f(recinto->max[X], recinto->max[Y], recinto->max[Z]); glTexCoord2f( 0, 2 + offset_agua); glVertex3f(recinto->max[X], recinto->max[Y], recinto->min[Z]); glEnd(); glBegin(GL_POLYGON); //plano Zmin glColor4f(1,1,1,0.4f); glTexCoord2f( 0, 0 + offset_agua); glVertex3f(recinto->min[X], recinto->min[Y], recinto->min[Z]); glTexCoord2f( 5, 0 + offset_agua); glVertex3f(recinto->max[X], recinto->min[Y], recinto->min[Z]); glTexCoord2f( 5, 2 + offset_agua); glVertex3f(recinto->max[X], recinto->max[Y], recinto->min[Z]); glTexCoord2f( 0, 2 + offset_agua); glVertex3f(recinto->min[X], recinto->max[Y], recinto->min[Z]); glEnd(); glBegin(GL_POLYGON); //plano Xmin glColor4f(1,1,1,0.4f); glTexCoord2f( 0, 0 + offset_agua); glVertex3f(recinto->min[X], recinto->min[Y], recinto->min[Z]); glTexCoord2f( 5, 0 + offset_agua); glVertex3f(recinto->min[X], recinto->min[Y], recinto->max[Z]); glTexCoord2f( 5, 2 + offset_agua); glVertex3f(recinto->min[X], recinto->max[Y], recinto->max[Z]); glTexCoord2f( 0, 2 + offset_agua); glVertex3f(recinto->min[X], recinto->max[Y], recinto->min[Z]); glEnd(); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); } glPopMatrix();}[/source]
The texture is a BMP image in REPEAT mode with blending set with glColor4f(1,1,1,0.4f).
Also i animate the texture mapping with an offset in the y direction to simulate falling water but this does not affect the fps drop.

What am i doing wrong??

Sponsor:

#2 fip   Members   -  Reputation: 147

Like
0Likes
Like

Posted 10 December 2012 - 12:28 PM

Okay i can say that i forgot to disable the GL_DEPTH_TEST and enable it at the end
[source lang="java"]glEnable(GL_BLEND)glDisable(GL_DEPTH_TEST);(draw stuff)glEnable(GL_DEPTH_TEST);glDisable(GL_BLEND);[/source]

I have ordered the drawing of the walls, first the 2 walls from the back and at last the 2 walls from the front, and apparently it works.....
fps 26 front.jpg

... if it wasnt by the fact that i can rotate around Y axis and this is what happens:
fps 25 rotation problem.jpg

now my back walls when i rotate around vertical Y axis the grass appears because it is rendered AFTER the back walls.


1. - What can i do to solve this problem? I can't find the correct draw order.
2. - If i dont disable GL_DEPTH_TESTING i get the correct behaviour but i get 9 fps!!!!
3. - I dont have anymore 9 fps but 25fps, why is this if i had at the beginning without the walls 55 fps? Why such difference in performance?

Edited by fip, 10 December 2012 - 12:39 PM.


#3 C0lumbo   Crossbones+   -  Reputation: 2120

Like
1Likes
Like

Posted 10 December 2012 - 01:15 PM

What sort of graphics card are you using, and what sort of resolution and anti-aliasing setup is there?

The only explanation I can think of is that you're woefully fill rate bound, but I can't see how this scene could possibly cause that situation on a desktop graphics card (maybe an iPad1, but not anything else).

Plus a quick stupid question - you're not accidentally rendering the transparent quads multiple times are you?

#4 Kaze   Members   -  Reputation: 948

Like
0Likes
Like

Posted 10 December 2012 - 01:22 PM

Your fps will always be garbage in intermediate mode, try using a draw list or vbo.

#5 Servant of the Lord   Crossbones+   -  Reputation: 17144

Like
2Likes
Like

Posted 10 December 2012 - 01:45 PM

In addition to the above, you shouldn't measure performance in FPS - measure in milliseconds or microseconds. FPS measurements can be deceptive; an increase from 55 FPS to 60 FPS (a gain of 1.5 ms a frame) is not the same increase as from 60 FPS to 65 FPS (a gain of 1.2 ms a frame).

It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.

[Fly with me on Twitter] [Google+] [My broken website]

All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.                                                                                                                                                       [Need free cloud storage? I personally like DropBox]

Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal


#6 Ohforf sake   Members   -  Reputation: 1445

Like
0Likes
Like

Posted 10 December 2012 - 03:26 PM

Can you post the output of glGetString(GL_VENDOR) ? If it is Microsoft, then you are running on some kind of emulation and need to install the drivers for your graphics card.

#7 ic0de   Members   -  Reputation: 808

Like
1Likes
Like

Posted 10 December 2012 - 10:22 PM

Why are you using GL_POLYGON? you seem to be using just quads replacing GL_POLYGON with GL_QUADS should be faster. Also get rid of those extra glbegin/glend's in between each face.

you know you program too much when you start ending sentences with semicolons;


#8 fip   Members   -  Reputation: 147

Like
0Likes
Like

Posted 11 December 2012 - 06:33 AM

Can you post the output of glGetString(GL_VENDOR) ? If it is Microsoft, then you are running on some kind of emulation and need to install the drivers for your graphics card.


Ahh that's it!! i got "microsoft corporation" for GL_VENDOR and "GDI generic" for GL_RENDERER query!!.

Now, im running the app in a laptop Dell XPS17 with integrated graphics card and an Nvidia GT555m card, maybe the problem is im not choosing the right graphics card for running the app.

Now how the heck i do that?

Why are you using GL_POLYGON? you seem to be using just quads replacing GL_POLYGON with GL_QUADS should be faster. Also get rid of those extra glbegin/glend's in between each face.


Yeah you re right ill change it, thanks.

Your fps will always be garbage in intermediate mode, try using a draw list or vbo.


Display lists seem interesting ill dig into that. This was my first attempt messing with OpenGL

#9 mhagain   Crossbones+   -  Reputation: 7436

Like
1Likes
Like

Posted 11 December 2012 - 08:01 AM

Your fps will always be garbage in intermediate mode, try using a draw list or vbo.


No no no no no.

Immediate mode is slower than the other methods for sure, but it's not that much slower. You don't get such dramatic framerate drops from it, particularly with such a simple scene (as polycounts really ramp up it's expected, but with basic scenes it's performance is roughly equivalent to the others). Remember - Quake used immediate mode and didn't suffer overly much from it.

Please don't recommend VBOs (or display lists) as a "solution" every time you see immediate mode code - the real cause of the problem may very well be elsewhere (as, indeed, it was in this case).

I'm not advising that it's OK to use immediate mode here, by the way; I am recommending that you should properly diagnose the problem before recommending a solution, rather than jump to conclusions.

Now how the heck i do that?


You should have an option to select the GPU to use in your NVIDIA control panel. It's also worthwhile downloading updated drivers for your machine as the absence of a proper OpenGL driver for the integrated card suggests that you're on an OEM driver; visit http://www.nvidia.com/Download/index.aspx?lang=en-us to get a proper updated driver.

Edited by mhagain, 11 December 2012 - 08:12 AM.

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.


#10 Kaze   Members   -  Reputation: 948

Like
0Likes
Like

Posted 11 December 2012 - 11:14 AM


Your fps will always be garbage in intermediate mode, try using a draw list or vbo.


No no no no no.

Immediate mode is slower than the other methods for sure, but it's not that much slower. You don't get such dramatic framerate drops from it, particularly with such a simple scene (as polycounts really ramp up it's expected, but with basic scenes it's performance is roughly equivalent to the others). Remember - Quake used immediate mode and didn't suffer overly much from it.

Please don't recommend VBOs (or display lists) as a "solution" every time you see immediate mode code - the real cause of the problem may very well be elsewhere (as, indeed, it was in this case).

I'm not advising that it's OK to use immediate mode here, by the way; I am recommending that you should properly diagnose the problem before recommending a solution, rather than jump to conclusions.


Graphics card makers only optimize their hardware for vbo's these days so its not unreasonable to assume legacy functions can cause all sorts of performance problems.

Edited by Kaze, 11 December 2012 - 11:15 AM.


#11 fastcall22   Crossbones+   -  Reputation: 3969

Like
0Likes
Like

Posted 11 December 2012 - 11:17 AM

Ahh that's it!! i got "microsoft corporation" for GL_VENDOR and "GDI generic" for GL_RENDERER query!!.

Now, im running the app in a laptop Dell XPS17 with integrated graphics card and an Nvidia GT555m card, maybe the problem is im not choosing the right graphics card for running the app.<br /><br />Now how the heck i do that?

It's also worthwhile downloading updated drivers for your machine

^ This.

I encountered the same problem when I moved to Windows 8. Apparently Windows 8 thinks its half-baked display driver is better than the drivers provided by my graphic card's manufacturer...

WW91J3ZlIGdvdCBhIHNlY3JldCBib251cyBwb2ludCE=


#12 fip   Members   -  Reputation: 147

Like
0Likes
Like

Posted 11 December 2012 - 11:26 AM

Hi, i have the nvidia control panel where i can select the .exe file related to whichever game i want to play and select which of the two video cards runs the game.

For game and other applications like adobe creative suite it works and it's the nvidia graphics card taking charge of.

But ive tried setting my application *.exe file in the list, and still wont run in the nvidia gt555m!! my Nvidia notifier says there are no programs running with the nvidia gpu plus the console spits out again GDI GENERIC plus no changes in fps of the app so it's definitely not working for me this way.

I've searched the internet but all i have found is people not knowing how to put the *.exe from a game in the list of the nvidia control panel, nothing about any programmer trying to run his own exe file in the nvidia gpu.......

Any ideas?

Edited by fip, 11 December 2012 - 11:28 AM.


#13 mhagain   Crossbones+   -  Reputation: 7436

Like
1Likes
Like

Posted 11 December 2012 - 11:57 AM

Graphics card makers only optimize their hardware for vbo's these days so its not unreasonable to assume legacy functions can cause all sorts of performance problems.


Quake still runs well on a modern GPU (which is likely to be emulating immediate mode in the driver by filling a dynamic VBO behind the scenes) - certainly much faster than the single-digit framerates that the OP is reporting, and with much more complex geometry, translucency, etc. Yes, you're right that it's not unreasonable to make that assumption, but when actual hard data invalidates the assumption (for this class of simple scene) then you do need to reconsider.

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 fip   Members   -  Reputation: 147

Like
0Likes
Like

Posted 11 December 2012 - 12:05 PM

Ive downloaded lesson01 from nehe.gamedev.net opengl tutorials, the one that simply creates a window with rendering context and have noticed that the exe is being run by the nvidia gpu!!!

So, i guess it has to do either with the way glut manages window either with any initialization parameter im not setting properly..........

What do you guys think?

#15 mhagain   Crossbones+   -  Reputation: 7436

Like
0Likes
Like

Posted 11 December 2012 - 12:55 PM

So, i guess it has to do either with the way glut manages window either with any initialization parameter im not setting properly..........


Definitely possible. One unfortunate thing that many GLUT examples I've seen do is create a single-buffered context, and it may be the case that your NVIDIA GPU/driver is unable to give you a hardware accelerated one. If that sounds like something you may have in your code then switching it to double-buffered (using GLUT_DOUBLE during startup and adding a call to glutSwapBuffers at the end of each frame) may be all that you need. Also worth checking the bit depth you request for your colour and depth buffers (not sure if you can control this via GLUT though).

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.


#16 fip   Members   -  Reputation: 147

Like
0Likes
Like

Posted 12 December 2012 - 03:39 PM

I have double buffer specified in glut.

Ive spent some time porting my application to use SDL + OPENGL for window managing and input, and again i dont know why my gpu is not the GL_RENDERER i have again "GDI generic" !!!!

I have missed to try just creating a window in SDL and see if it renders on the gpu, ill try this tomorrow.

Maybe im using some opengl command that causes the software rendering?

#17 slicer4ever   Crossbones+   -  Reputation: 3205

Like
1Likes
Like

Posted 12 December 2012 - 05:54 PM

is it possible to post your window creation code, pretty much all the code upto when you check the vendor, and hopefully we can point out the problem.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#18 fip   Members   -  Reputation: 147

Like
0Likes
Like

Posted 13 December 2012 - 03:47 AM

Hi,
Ive tested this SDL simple example and it doesnt run in my gpu neither.... although it initializes the video mode with SDL_OPENGL

example from http://lazyfoo.net/SDL_tutorials/lesson36/index.php

This is driving me nuts.............

I'll post my glut+Opengl window creation & initialization code soon, now i have to leave.

[source lang="cpp"]/*This source code copyrighted by Lazy Foo' Productions (2004-2012)and may not be redistributed without written permission.*///The headers#include "SDL.h"#include "SDL_opengl.h"//Screen attributesconst int SCREEN_WIDTH = 640;const int SCREEN_HEIGHT = 480;const int SCREEN_BPP = 32;//The frame rateconst int FRAMES_PER_SECOND = 60;//Event handlerSDL_Event event;//Rendering flagbool renderQuad = true;//The timerclass Timer{ private: //The clock time when the timer started int startTicks; //The ticks stored when the timer was paused int pausedTicks; //The timer status bool paused; bool started; public: //Initializes variables Timer(); //The various clock actions void start(); void stop(); void pause(); void unpause(); //Gets the timer's time int get_ticks(); //Checks the status of the timer bool is_started(); bool is_paused();};bool initGL(){ //Initialize Projection Matrix glMatrixMode( GL_PROJECTION ); glLoadIdentity(); //Initialize Modelview Matrix glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); //Initialize clear color glClearColor( 0.f, 0.f, 0.f, 1.f ); //Check for error GLenum error = glGetError(); if( error != GL_NO_ERROR ) { printf( "Error initializing OpenGL! %s\n", gluErrorString( error ) ); return false; } return true;}bool init(){ //Initialize SDL if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) { return false; } //Create Window if( SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL ) == NULL ) { return false; } //Enable unicode SDL_EnableUNICODE( SDL_TRUE ); //Initialize OpenGL if( initGL() == false ) { return false; } //Set caption SDL_WM_SetCaption( "OpenGL Test", NULL ); return true;}void handleKeys( unsigned char key, int x, int y ){ //Toggle quad if( key == 'q' ) { renderQuad = !renderQuad; }}void update(){}void render(){ //Clear color buffer glClear( GL_COLOR_BUFFER_BIT ); //Render quad if( renderQuad == true ) { glBegin( GL_QUADS ); glVertex2f( -0.5f, -0.5f ); glVertex2f( 0.5f, -0.5f ); glVertex2f( 0.5f, 0.5f ); glVertex2f( -0.5f, 0.5f ); glEnd(); } //Update screen SDL_GL_SwapBuffers();}void clean_up(){ //Quit SDL SDL_Quit();}Timer::Timer(){ //Initialize the variables startTicks = 0; pausedTicks = 0; paused = false; started = false;}void Timer::start(){ //Start the timer started = true; //Unpause the timer paused = false; //Get the current clock time startTicks = SDL_GetTicks();}void Timer::stop(){ //Stop the timer started = false; //Unpause the timer paused = false;}void Timer::pause(){ //If the timer is running and isn't already paused if( ( started == true ) &amp;&amp; ( paused == false ) ) { //Pause the timer paused = true; //Calculate the paused ticks pausedTicks = SDL_GetTicks() - startTicks; }}void Timer::unpause(){ //If the timer is paused if( paused == true ) { //Unpause the timer paused = false; //Reset the starting ticks startTicks = SDL_GetTicks() - pausedTicks; //Reset the paused ticks pausedTicks = 0; }}int Timer::get_ticks(){ //If the timer is running if( started == true ) { //If the timer is paused if( paused == true ) { //Return the number of ticks when the timer was paused return pausedTicks; } else { //Return the current time minus the start time return SDL_GetTicks() - startTicks; } } //If the timer isn't running return 0;}bool Timer::is_started(){ return started;}bool Timer::is_paused(){ return paused;}int main( int argc, char *argv[] ){ //Quit flag bool quit = false; //Initialize if( init() == false ) { return 1; } //The frame rate regulator Timer fps; //Wait for user exit while( quit == false ) { //Start the frame timer fps.start(); //While there are events to handle while( SDL_PollEvent( &amp;event ) ) { if( event.type == SDL_QUIT ) { quit = true; } else if( event.type == SDL_KEYDOWN ) { //Handle keypress with current mouse position int x = 0, y = 0; SDL_GetMouseState( &amp;x, &amp;y ); handleKeys( event.key.keysym.unicode, x, y ); } } //Run frame update update(); //Render frame render(); //Cap the frame rate if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND ) { SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() ); } } //Clean up clean_up(); return 0;}[/source]

Edited by fip, 13 December 2012 - 04:01 AM.


#19 mhagain   Crossbones+   -  Reputation: 7436

Like
0Likes
Like

Posted 13 December 2012 - 04:43 AM

OK, one problem here is that you're using SDL_Delay to control framerate. That's internally implemented as a Sleep call and Sleep is not a good way of controlling framerate (it only specifies a minimum time to sleep for; actual time may be longer, and this will be true even if using a high resolution timer).

That's not going to fix your specific problem with not getting a hardware accelerated GL context, but it is some cleaning up you need to do.

For your GL context problem, I'll have a look over your code later on today and see if I can spot anything (assuming someone else doesn't come up with the solution before then).

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.


#20 kunos   Crossbones+   -  Reputation: 2185

Like
1Likes
Like

Posted 13 December 2012 - 05:47 AM

Of course there is a driver problem there because with a scene light that you should run into the 300fps ballpark easily.
Having said that, blending operations will always have a big impact on the scene because simply, they do more work, they have to read the current pixel color, apply the blending function and then write back the colour.
Stefano Casillo
Lead Programmer
TWITTER: @KunosStefano
AssettoCorsa - netKar PRO - Kunos Simulazioni




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