• Advertisement
Sign in to follow this  

OpenGL dramatic fps drop when using transparent texture

This topic is 1859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.
[attachment=12710: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.
[attachment=12709: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!!!!!
[attachment=12708: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??

Share this post


Link to post
Share on other sites
Advertisement
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.....
[attachment=12717:fps 26 front.jpg]

... if it wasnt by the fact that i can rotate around Y axis and this is what happens:
[attachment=12716: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

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Your fps will always be garbage in intermediate mode, try using a draw list or vbo.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
[quote name='Ohforf sake' timestamp='1355174772' post='5009202']
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.
[/quote]

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?

[quote name='ic0de' timestamp='1355199754' post='5009310']
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.
[/quote]
Yeah you re right ill change it, thanks.[quote name='Kaze' timestamp='1355167357' post='5009164']
Your fps will always be garbage in intermediate mode, try using a draw list or vbo.
[/quote]

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

Share this post


Link to post
Share on other sites
[quote name='Kaze' timestamp='1355167357' post='5009164']
Your fps will always be garbage in intermediate mode, try using a draw list or vbo.
[/quote]

No no no no no.

Immediate mode is slower than the other methods for sure, but it's not [i]that[/i] much slower. You don't get such dramatic framerate drops from it, particularly with such a simple scene (as polycounts [i]really[/i] 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 [i]not[/i] advising that it's OK to use immediate mode here, by the way; I [i]am[/i] recommending that you should properly diagnose the problem before recommending a solution, rather than jump to conclusions.

[quote name='fip' timestamp='1355229220' post='5009392']
Now how the heck i do that?
[/quote]

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

Share this post


Link to post
Share on other sites
[quote name='mhagain' timestamp='1355234510' post='5009420']
[quote name='Kaze' timestamp='1355167357' post='5009164']
Your fps will always be garbage in intermediate mode, try using a draw list or vbo.
[/quote]

No no no no no.

Immediate mode is slower than the other methods for sure, but it's not [i]that[/i] much slower. You don't get such dramatic framerate drops from it, particularly with such a simple scene (as polycounts [i]really[/i] 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 [i]not[/i] advising that it's OK to use immediate mode here, by the way; I [i]am[/i] recommending that you should properly diagnose the problem before recommending a solution, rather than jump to conclusions.
[/quote]

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

Share this post


Link to post
Share on other sites
[quote name='fip' timestamp='1355229220' post='5009392']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?[/quote][quote name='mhagain' timestamp='1355234510' post='5009420']It's also worthwhile downloading updated drivers for your machine[/quote]
^ 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...

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
[quote name='Kaze' timestamp='1355246060' post='5009455']
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.
[/quote]

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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
[quote name='fip' timestamp='1355249103' post='5009478']
So, i guess it has to do either with the way glut manages window either with any initialization parameter im not setting properly..........
[/quote]

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).

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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 [url="http://lazyfoo.net/SDL_tutorials/lesson36/index.php"]http://lazyfoo.net/SDL_tutorials/lesson36/index.php[/url]

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 attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

//The frame rate
const int FRAMES_PER_SECOND = 60;

//Event handler
SDL_Event event;

//Rendering flag
bool renderQuad = true;

//The timer
class 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

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Hi again,

more testing:
- ive added
[source lang="cpp"]SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1);[/source]
does not have any effect. I think it should be enough with SDL_OPENGL but just in case.

- i ve run the executable on a notebook with only one GPU and i keep getting the "GDI generic" for GL_RENDERER.
So maybe it's not an issue of having dual gpus, furthermore in case it was using the intel HD integrated graphics card i should be getting "Intel" as the GL_VENDOR right?



[quote name='mhagain' timestamp='1355395381' post='5010151']
OK, one problem here is that you're using SDL_Delay to control framerate.
[/quote]

It's just some code i grabbed from the internet. I dont care right now about this.

[quote name='mhagain' timestamp='1355395381' post='5010151']
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).
[/quote]
Thanks for your time, this is the problem i want to fix!!

Share this post


Link to post
Share on other sites
I tested this other SDL+Opengl code and still get GDI generic for GL_RENDERER.

[source lang="cpp"]#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include "SDL.h"

#ifdef __MACOS__
#define HAVE_OPENGL
#endif

#define HAVE_OPENGL

#ifdef HAVE_OPENGL

#include "SDL_opengl.h"

/* Undefine this if you want a flat cube instead of a rainbow cube */
#define SHADED_CUBE

/* Define this to be the name of the logo image to use with -logo */
#define LOGO_FILE "icon.bmp"

/* The SDL_OPENGLBLIT interface is deprecated.
The code is still available for benchmark purposes though.
*/

static SDL_bool USE_DEPRECATED_OPENGLBLIT = SDL_FALSE;

static SDL_Surface *global_image = NULL;
static GLuint global_texture = 0;
static GLuint cursor_texture = 0;

/**********************************************************************/

void HotKey_ToggleFullScreen(void)
{
SDL_Surface *screen;

screen = SDL_GetVideoSurface();
if ( SDL_WM_ToggleFullScreen(screen) ) {
printf("Toggled fullscreen mode - now %s\n",
(screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed");
} else {
printf("Unable to toggle fullscreen mode\n");
}
}

void HotKey_ToggleGrab(void)
{
SDL_GrabMode mode;

printf("Ctrl-G: toggling input grab!\n");
mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
if ( mode == SDL_GRAB_ON ) {
printf("Grab was on\n");
} else {
printf("Grab was off\n");
}
mode = SDL_WM_GrabInput(!mode);
if ( mode == SDL_GRAB_ON ) {
printf("Grab is now on\n");
} else {
printf("Grab is now off\n");
}
}

void HotKey_Iconify(void)
{
printf("Ctrl-Z: iconifying window!\n");
SDL_WM_IconifyWindow();
}

int HandleEvent(SDL_Event *event)
{
int done;

done = 0;
switch( event->type ) {
case SDL_ACTIVEEVENT:
/* See what happened */
printf( "app %s ", event->active.gain ? "gained" : "lost" );
if ( event->active.state & SDL_APPACTIVE ) {
printf( "active " );
} else if ( event->active.state & SDL_APPMOUSEFOCUS ) {
printf( "mouse " );
} else if ( event->active.state & SDL_APPINPUTFOCUS ) {
printf( "input " );
}
printf( "focus\n" );
break;


case SDL_KEYDOWN:
if ( event->key.keysym.sym == SDLK_ESCAPE ) {
done = 1;
}
if ( (event->key.keysym.sym == SDLK_g) &&
(event->key.keysym.mod & KMOD_CTRL) ) {
HotKey_ToggleGrab();
}
if ( (event->key.keysym.sym == SDLK_z) &&
(event->key.keysym.mod & KMOD_CTRL) ) {
HotKey_Iconify();
}
if ( (event->key.keysym.sym == SDLK_RETURN) &&
(event->key.keysym.mod & KMOD_ALT) ) {
HotKey_ToggleFullScreen();
}
printf("key '%s' pressed\n",
SDL_GetKeyName(event->key.keysym.sym));
break;
case SDL_QUIT:
done = 1;
break;
}
return(done);
}

void SDL_GL_Enter2DMode()
{
SDL_Surface *screen = SDL_GetVideoSurface();

/* Note, there may be other things you need to change,
depending on how you have your OpenGL state set up.
*/
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);

/* This allows alpha blending of 2D textures with the scene */
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glViewport(0, 0, screen->w, screen->h);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
}

void SDL_GL_Leave2DMode()
{
glMatrixMode(GL_MODELVIEW);
glPopMatrix();

glMatrixMode(GL_PROJECTION);
glPopMatrix();

glPopAttrib();
}

/* Quick utility function for texture creation */
static int power_of_two(int input)
{
int value = 1;

while ( value < input ) {
value <<= 1;
}
return value;
}

GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
{
GLuint texture;
int w, h;
SDL_Surface *image;
SDL_Rect area;
Uint32 saved_flags;
Uint8 saved_alpha;

/* Use the surface width and height expanded to powers of 2 */
w = power_of_two(surface->w);
h = power_of_two(surface->h);
texcoord[0] = 0.0f; /* Min X */
texcoord[1] = 0.0f; /* Min Y */
texcoord[2] = (GLfloat)surface->w / w; /* Max X */
texcoord[3] = (GLfloat)surface->h / h; /* Max Y */

image = SDL_CreateRGBSurface(
SDL_SWSURFACE,
w, h,
32,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
0x000000FF,
0x0000FF00,
0x00FF0000,
0xFF000000
#else
0xFF000000,
0x00FF0000,
0x0000FF00,
0x000000FF
#endif
);
if ( image == NULL ) {
return 0;
}

/* Save the alpha blending attributes */
saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
saved_alpha = surface->format->alpha;
if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
SDL_SetAlpha(surface, 0, 0);
}

/* Copy the surface into the GL texture image */
area.x = 0;
area.y = 0;
area.w = surface->w;
area.h = surface->h;
SDL_BlitSurface(surface, &area, image, &area);

/* Restore the alpha blending attributes */
if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
SDL_SetAlpha(surface, saved_flags, saved_alpha);
}

/* Create an OpenGL texture for the image */
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
w, h,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
image->pixels);
SDL_FreeSurface(image); /* No longer needed */

return texture;
}

void DrawLogoCursor(void)
{
static GLfloat texMinX, texMinY;
static GLfloat texMaxX, texMaxY;
static int w, h;
int x, y;

if ( ! cursor_texture ) {
SDL_Surface *image;
GLfloat texcoord[4];

/* Load the image (could use SDL_image library here) */
image = SDL_LoadBMP(LOGO_FILE);
if ( image == NULL ) {
return;
}
w = image->w;
h = image->h;

/* Convert the image into an OpenGL texture */
cursor_texture = SDL_GL_LoadTexture(image, texcoord);

/* Make texture coordinates easy to understand */
texMinX = texcoord[0];
texMinY = texcoord[1];
texMaxX = texcoord[2];
texMaxY = texcoord[3];

/* We don't need the original image anymore */
SDL_FreeSurface(image);

/* Make sure that the texture conversion is okay */
if ( ! cursor_texture ) {
return;
}
}

/* Move the image around */
SDL_GetMouseState(&x, &y);
x -= w/2;
y -= h/2;

/* Show the image on the screen */
SDL_GL_Enter2DMode();
glBindTexture(GL_TEXTURE_2D, cursor_texture);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(texMinX, texMinY); glVertex2i(x, y );
glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y );
glTexCoord2f(texMinX, texMaxY); glVertex2i(x, y+h);
glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
glEnd();
SDL_GL_Leave2DMode();
}

void DrawLogoTexture(void)
{
static GLfloat texMinX, texMinY;
static GLfloat texMaxX, texMaxY;
static int x = 0;
static int y = 0;
static int w, h;
static int delta_x = 1;
static int delta_y = 1;

SDL_Surface *screen = SDL_GetVideoSurface();

if ( ! global_texture ) {
SDL_Surface *image;
GLfloat texcoord[4];

/* Load the image (could use SDL_image library here) */
image = SDL_LoadBMP(LOGO_FILE);
if ( image == NULL ) {
return;
}
w = image->w;
h = image->h;

/* Convert the image into an OpenGL texture */
global_texture = SDL_GL_LoadTexture(image, texcoord);

/* Make texture coordinates easy to understand */
texMinX = texcoord[0];
texMinY = texcoord[1];
texMaxX = texcoord[2];
texMaxY = texcoord[3];

/* We don't need the original image anymore */
SDL_FreeSurface(image);

/* Make sure that the texture conversion is okay */
if ( ! global_texture ) {
return;
}
}

/* Move the image around */
x += delta_x;
if ( x < 0 ) {
x = 0;
delta_x = -delta_x;
} else
if ( (x+w) > screen->w ) {
x = screen->w-w;
delta_x = -delta_x;
}
y += delta_y;
if ( y < 0 ) {
y = 0;
delta_y = -delta_y;
} else
if ( (y+h) > screen->h ) {
y = screen->h-h;
delta_y = -delta_y;
}

/* Show the image on the screen */
SDL_GL_Enter2DMode();
glBindTexture(GL_TEXTURE_2D, global_texture);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(texMinX, texMinY); glVertex2i(x, y );
glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y );
glTexCoord2f(texMinX, texMaxY); glVertex2i(x, y+h);
glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
glEnd();
SDL_GL_Leave2DMode();
}

/* This code is deprecated, but available for speed comparisons */
void DrawLogoBlit(void)
{
static int x = 0;
static int y = 0;
static int w, h;
static int delta_x = 1;
static int delta_y = 1;

SDL_Rect dst;
SDL_Surface *screen = SDL_GetVideoSurface();

if ( global_image == NULL ) {
SDL_Surface *temp;

/* Load the image (could use SDL_image library here) */
temp = SDL_LoadBMP(LOGO_FILE);
if ( temp == NULL ) {
return;
}
w = temp->w;
h = temp->h;

/* Convert the image into the screen format */
global_image = SDL_CreateRGBSurface(
SDL_SWSURFACE,
w, h,
screen->format->BitsPerPixel,
screen->format->Rmask,
screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask);
if ( global_image ) {
SDL_BlitSurface(temp, NULL, global_image, NULL);
}
SDL_FreeSurface(temp);

/* Make sure that the texture conversion is okay */
if ( ! global_image ) {
return;
}
}

/* Move the image around
Note that we do not clear the old position. This is because we
perform a glClear() which clears the framebuffer and then only
update the new area.
Note that you can also achieve interesting effects by modifying
the screen surface alpha channel. It's set to 255 by default..
*/
x += delta_x;
if ( x < 0 ) {
x = 0;
delta_x = -delta_x;
} else
if ( (x+w) > screen->w ) {
x = screen->w-w;
delta_x = -delta_x;
}
y += delta_y;
if ( y < 0 ) {
y = 0;
delta_y = -delta_y;
} else
if ( (y+h) > screen->h ) {
y = screen->h-h;
delta_y = -delta_y;
}
dst.x = x;
dst.y = y;
dst.w = w;
dst.h = h;
SDL_BlitSurface(global_image, NULL, screen, &dst);

/* Show the image on the screen */
SDL_UpdateRects(screen, 1, &dst);
}

int RunGLTest( int argc, char* argv[],
int logo, int logocursor, int slowly, int bpp, float gamma, int noframe, int fsaa, int sync, int accel )
{
int i;
int rgb_size[3];
int w = 640;
int h = 480;
int done = 0;
int frames;
Uint32 start_time, this_time;
float color[8][3]= {{ 1.0, 1.0, 0.0},
{ 1.0, 0.0, 0.0},
{ 0.0, 0.0, 0.0},
{ 0.0, 1.0, 0.0},
{ 0.0, 1.0, 1.0},
{ 1.0, 1.0, 1.0},
{ 1.0, 0.0, 1.0},
{ 0.0, 0.0, 1.0}};
float cube[8][3]= {{ 0.5, 0.5, -0.5},
{ 0.5, -0.5, -0.5},
{-0.5, -0.5, -0.5},
{-0.5, 0.5, -0.5},
{-0.5, 0.5, 0.5},
{ 0.5, 0.5, 0.5},
{ 0.5, -0.5, 0.5},
{-0.5, -0.5, 0.5}};
Uint32 video_flags;
int value;

if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError());
exit( 1 );
}

/* See if we should detect the display depth */
if ( bpp == 0 ) {
if ( SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8 ) {
bpp = 8;
} else {
bpp = 16; /* More doesn't seem to work */
}
}

/* Set the flags we want to use for setting the video mode */
if ( logo && USE_DEPRECATED_OPENGLBLIT ) {
video_flags = SDL_OPENGLBLIT;
} else {
video_flags = SDL_OPENGL;
}
for ( i=1; argv[i]; ++i ) {
if ( strcmp(argv[i], "-fullscreen") == 0 ) {
video_flags |= SDL_FULLSCREEN;
}
}

if (noframe) {
video_flags |= SDL_NOFRAME;
}

/* Initialize the display */
switch (bpp) {
case 8:
rgb_size[0] = 3;
rgb_size[1] = 3;
rgb_size[2] = 2;
break;
case 15:
case 16:
rgb_size[0] = 5;
rgb_size[1] = 5;
rgb_size[2] = 5;
break;
default:
rgb_size[0] = 8;
rgb_size[1] = 8;
rgb_size[2] = 8;
break;
}
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, rgb_size[0] );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, rgb_size[1] );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, rgb_size[2] );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
if ( fsaa ) {
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, fsaa );
}
if ( accel ) {
SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
}
if ( sync ) {
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1 );
} else {
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 );
}
if ( SDL_SetVideoMode( w, h, bpp, video_flags ) == NULL ) {
fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
SDL_Quit();
exit(1);
}

printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel);
printf("\n");
printf( "Vendor : %s\n", glGetString( GL_VENDOR ) );
printf( "Renderer : %s\n", glGetString( GL_RENDERER ) );
printf( "Version : %s\n", glGetString( GL_VERSION ) );
printf( "Extensions : %s\n", glGetString( GL_EXTENSIONS ) );
printf("\n");

SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &value );
printf( "SDL_GL_RED_SIZE: requested %d, got %d\n", rgb_size[0],value);
SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &value );
printf( "SDL_GL_GREEN_SIZE: requested %d, got %d\n", rgb_size[1],value);
SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &value );
printf( "SDL_GL_BLUE_SIZE: requested %d, got %d\n", rgb_size[2],value);
SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &value );
printf( "SDL_GL_DEPTH_SIZE: requested %d, got %d\n", bpp, value );
SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &value );
printf( "SDL_GL_DOUBLEBUFFER: requested 1, got %d\n", value );
if ( fsaa ) {
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &value );
printf("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value );
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &value );
printf("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, value );
}
if ( accel ) {
SDL_GL_GetAttribute( SDL_GL_ACCELERATED_VISUAL, &value );
printf( "SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value );
}
if ( sync ) {
SDL_GL_GetAttribute( SDL_GL_SWAP_CONTROL, &value );
printf( "SDL_GL_SWAP_CONTROL: requested 1, got %d\n", value );
}

/* Set the window manager title bar */
SDL_WM_SetCaption( "SDL GL test", "testgl" );

/* Set the gamma for the window */
if ( gamma != 0.0 ) {
SDL_SetGamma(gamma, gamma, gamma);
}

glViewport( 0, 0, w, h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );

glOrtho( -2.0, 2.0, -2.0, 2.0, -20.0, 20.0 );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );

glEnable(GL_DEPTH_TEST);

glDepthFunc(GL_LESS);

glShadeModel(GL_SMOOTH);

/* Loop until done. */
start_time = SDL_GetTicks();
frames = 0;
while( !done ) {
GLenum gl_error;
char* sdl_error;
SDL_Event event;

/* Do our drawing, too. */
glClearColor( 0.0, 0.0, 0.0, 1.0 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glBegin( GL_QUADS );

#ifdef SHADED_CUBE
glColor3fv(color[0]);
glVertex3fv(cube[0]);
glColor3fv(color[1]);
glVertex3fv(cube[1]);
glColor3fv(color[2]);
glVertex3fv(cube[2]);
glColor3fv(color[3]);
glVertex3fv(cube[3]);

glColor3fv(color[3]);
glVertex3fv(cube[3]);
glColor3fv(color[4]);
glVertex3fv(cube[4]);
glColor3fv(color[7]);
glVertex3fv(cube[7]);
glColor3fv(color[2]);
glVertex3fv(cube[2]);

glColor3fv(color[0]);
glVertex3fv(cube[0]);
glColor3fv(color[5]);
glVertex3fv(cube[5]);
glColor3fv(color[6]);
glVertex3fv(cube[6]);
glColor3fv(color[1]);
glVertex3fv(cube[1]);

glColor3fv(color[5]);
glVertex3fv(cube[5]);
glColor3fv(color[4]);
glVertex3fv(cube[4]);
glColor3fv(color[7]);
glVertex3fv(cube[7]);
glColor3fv(color[6]);
glVertex3fv(cube[6]);

glColor3fv(color[5]);
glVertex3fv(cube[5]);
glColor3fv(color[0]);
glVertex3fv(cube[0]);
glColor3fv(color[3]);
glVertex3fv(cube[3]);
glColor3fv(color[4]);
glVertex3fv(cube[4]);

glColor3fv(color[6]);
glVertex3fv(cube[6]);
glColor3fv(color[1]);
glVertex3fv(cube[1]);
glColor3fv(color[2]);
glVertex3fv(cube[2]);
glColor3fv(color[7]);
glVertex3fv(cube[7]);
#else /* flat cube */
glColor3f(1.0, 0.0, 0.0);
glVertex3fv(cube[0]);
glVertex3fv(cube[1]);
glVertex3fv(cube[2]);
glVertex3fv(cube[3]);

glColor3f(0.0, 1.0, 0.0);
glVertex3fv(cube[3]);
glVertex3fv(cube[4]);
glVertex3fv(cube[7]);
glVertex3fv(cube[2]);

glColor3f(0.0, 0.0, 1.0);
glVertex3fv(cube[0]);
glVertex3fv(cube[5]);
glVertex3fv(cube[6]);
glVertex3fv(cube[1]);

glColor3f(0.0, 1.0, 1.0);
glVertex3fv(cube[5]);
glVertex3fv(cube[4]);
glVertex3fv(cube[7]);
glVertex3fv(cube[6]);

glColor3f(1.0, 1.0, 0.0);
glVertex3fv(cube[5]);
glVertex3fv(cube[0]);
glVertex3fv(cube[3]);
glVertex3fv(cube[4]);

glColor3f(1.0, 0.0, 1.0);
glVertex3fv(cube[6]);
glVertex3fv(cube[1]);
glVertex3fv(cube[2]);
glVertex3fv(cube[7]);
#endif /* SHADED_CUBE */

glEnd( );

glMatrixMode(GL_MODELVIEW);
glRotatef(5.0, 1.0, 1.0, 1.0);

/* Draw 2D logo onto the 3D display */
if ( logo ) {
if ( USE_DEPRECATED_OPENGLBLIT ) {
DrawLogoBlit();
} else {
DrawLogoTexture();
}
}
if ( logocursor ) {
DrawLogoCursor();
}

SDL_GL_SwapBuffers( );

/* Check for error conditions. */
gl_error = glGetError( );

if( gl_error != GL_NO_ERROR ) {
fprintf( stderr, "testgl: OpenGL error: %d\n", gl_error );
}

sdl_error = SDL_GetError( );

if( sdl_error[0] != '\0' ) {
fprintf(stderr, "testgl: SDL error '%s'\n", sdl_error);
SDL_ClearError();
}

/* Allow the user to see what's happening */
if ( slowly ) {
SDL_Delay( 20 );
}

/* Check if there's a pending event. */
while( SDL_PollEvent( &event ) ) {
done = HandleEvent(&event);
}
++frames;
}

/* Print out the frames per second */
this_time = SDL_GetTicks();
if ( this_time != start_time ) {
printf("%2.2f FPS\n",
((float)frames/(this_time-start_time))*1000.0);
}

if ( global_image ) {
SDL_FreeSurface(global_image);
global_image = NULL;
}
if ( global_texture ) {
glDeleteTextures( 1, &global_texture );
global_texture = 0;
}
if ( cursor_texture ) {
glDeleteTextures( 1, &cursor_texture );
cursor_texture = 0;
}

/* Destroy our GL context, etc. */
SDL_Quit( );
return(0);
}

int main(int argc, char *argv[])
{
int i, logo, logocursor = 0;
int numtests;
int bpp = 0;
int slowly;
float gamma = 0.0;
int noframe = 0;
int fsaa = 0;
int accel = 0;
int sync = 0;

logo = 0;
slowly = 0;
numtests = 1;
for ( i=1; argv[i]; ++i ) {
if ( strcmp(argv[i], "-twice") == 0 ) {
++numtests;
}
if ( strcmp(argv[i], "-logo") == 0 ) {
logo = 1;
USE_DEPRECATED_OPENGLBLIT = SDL_FALSE;
}
if ( strcmp(argv[i], "-logoblit") == 0 ) {
logo = 1;
USE_DEPRECATED_OPENGLBLIT = SDL_TRUE;
}
if ( strcmp(argv[i], "-logocursor") == 0 ) {
logocursor = 1;
}
if ( strcmp(argv[i], "-slow") == 0 ) {
slowly = 1;
}
if ( strcmp(argv[i], "-bpp") == 0 ) {
bpp = atoi(argv[++i]);
}
if ( strcmp(argv[i], "-gamma") == 0 ) {
gamma = (float)atof(argv[++i]);
}
if ( strcmp(argv[i], "-noframe") == 0 ) {
noframe = 1;
}
if ( strcmp(argv[i], "-fsaa") == 0 ) {
++fsaa;
}
if ( strcmp(argv[i], "-accel") == 0 ) {
++accel;
}
if ( strcmp(argv[i], "-sync") == 0 ) {
++sync;
}
if ( strncmp(argv[i], "-h", 2) == 0 ) {
printf(
"Usage: %s [-twice] [-logo] [-logocursor] [-slow] [-bpp n] [-gamma n] [-noframe] [-fsaa] [-accel] [-sync] [-fullscreen]\n",
argv[0]);
exit(0);
}
}
for ( i=0; i<numtests; ++i ) {
RunGLTest(argc, argv, logo, logocursor, slowly, bpp, gamma, noframe, fsaa, sync, accel);
}
return 0;
}

#else /* HAVE_OPENGL */

int main(int argc, char *argv[])
{
printf("No OpenGL support on this system\n");
return 1;
}

#endif /* HAVE_OPENGL */[/source]

Can someone try to run this code and see what do you get for GL_RENDERER?

I want to know if the problem is in the code or it's in my laptop configuration somehow.

Share this post


Link to post
Share on other sites
Here's what I get on one machine:

[quote]Vendor : ATI Technologies Inc.
Renderer : AMD Radeon HD 6450
Version : 4.2.11931 Compatibility Profile Context
SDL_GL_RED_SIZE: requested 5, got 8
SDL_GL_GREEN_SIZE: requested 5, got 8
SDL_GL_BLUE_SIZE: requested 5, got 8
SDL_GL_DEPTH_SIZE: requested 16, got 24
SDL_GL_DOUBLEBUFFER: requested 1, got 1[/quote]

What looks possible here is that you're requesting default modes that may not be available in hardware-accelerated versions. 16-bit modes are really really old these days (the last video card that didn't support 32-bit colour was the Voodoo 3) and there should be no reason to go looking for one - try bumping RGB to 8/8/8 and see what that gets you.

Share this post


Link to post
Share on other sites
the most likely cause is that you don't have a driver from nvidia. Go on the nvidia website, download and install your driver and enjoy hardware accelerated OpenGL.

Share this post


Link to post
Share on other sites
Hi mhagain,
Here is what i get after increasing the depth size to 24:

[Quote]
Screen BPP: 24
Vendor : Microsoft Corporation
Renderer : GDI Generic
Version : 1.1.0
Extensions : GL_WIN_swap_hint GL_EXT_bgr
SDL_GL_RED_SIZE: requested 8, got 8
SDL_GL_GREEN_SIZE: requested 8, got 8
SDL_GL_BLUE_SIZE: requested 8, got 8
SDL_GL_DEPTH_SIZE: requested 24, got 32
SDL_GL_DOUBLEBUFFER: requested 1, got 1
[/Quote]

I think i have spotted the problem.
In the official opengl documentation site ive found this [url="http://www.opengl.org/archives/resources/faq/technical/mswindows.htm"]http://www.opengl.org/archives/resources/faq/technical/mswindows.htm[/url] specially the point "5.030 How do I enable and disable hardware rendering on a Wintel card?"
It says that hardware acceleration depends on choosing a right PIXEL FORMAT. Now is it possible to do this when you are using GLUT? Which config do i need when using SDL to get hardware acceleration?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Now

  • Advertisement
  • Similar Content

    • By Balma Alparisi
      i got error 1282 in my code.
      sf::ContextSettings settings; settings.majorVersion = 4; settings.minorVersion = 5; settings.attributeFlags = settings.Core; sf::Window window; window.create(sf::VideoMode(1600, 900), "Texture Unit Rectangle", sf::Style::Close, settings); window.setActive(true); window.setVerticalSyncEnabled(true); glewInit(); GLuint shaderProgram = createShaderProgram("FX/Rectangle.vss", "FX/Rectangle.fss"); float vertex[] = { -0.5f,0.5f,0.0f, 0.0f,0.0f, -0.5f,-0.5f,0.0f, 0.0f,1.0f, 0.5f,0.5f,0.0f, 1.0f,0.0f, 0.5,-0.5f,0.0f, 1.0f,1.0f, }; GLuint indices[] = { 0,1,2, 1,2,3, }; GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); GLuint ebo; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices,GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(float) * 5, (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(float) * 5, (void*)(sizeof(float) * 3)); glEnableVertexAttribArray(1); GLuint texture[2]; glGenTextures(2, texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); sf::Image* imageOne = new sf::Image; bool isImageOneLoaded = imageOne->loadFromFile("Texture/container.jpg"); if (isImageOneLoaded) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageOne->getSize().x, imageOne->getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageOne->getPixelsPtr()); glGenerateMipmap(GL_TEXTURE_2D); } delete imageOne; glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); sf::Image* imageTwo = new sf::Image; bool isImageTwoLoaded = imageTwo->loadFromFile("Texture/awesomeface.png"); if (isImageTwoLoaded) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageTwo->getSize().x, imageTwo->getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageTwo->getPixelsPtr()); glGenerateMipmap(GL_TEXTURE_2D); } delete imageTwo; glUniform1i(glGetUniformLocation(shaderProgram, "inTextureOne"), 0); glUniform1i(glGetUniformLocation(shaderProgram, "inTextureTwo"), 1); GLenum error = glGetError(); std::cout << error << std::endl; sf::Event event; bool isRunning = true; while (isRunning) { while (window.pollEvent(event)) { if (event.type == event.Closed) { isRunning = false; } } glClear(GL_COLOR_BUFFER_BIT); if (isImageOneLoaded && isImageTwoLoaded) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture[1]); glUseProgram(shaderProgram); } glBindVertexArray(vao); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); glBindVertexArray(0); window.display(); } glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ebo); glDeleteProgram(shaderProgram); glDeleteTextures(2,texture); return 0; } and this is the vertex shader
      #version 450 core layout(location=0) in vec3 inPos; layout(location=1) in vec2 inTexCoord; out vec2 TexCoord; void main() { gl_Position=vec4(inPos,1.0); TexCoord=inTexCoord; } and the fragment shader
      #version 450 core in vec2 TexCoord; uniform sampler2D inTextureOne; uniform sampler2D inTextureTwo; out vec4 FragmentColor; void main() { FragmentColor=mix(texture(inTextureOne,TexCoord),texture(inTextureTwo,TexCoord),0.2); } I was expecting awesomeface.png on top of container.jpg

    • By khawk
      We've just released all of the source code for the NeHe OpenGL lessons on our Github page at https://github.com/gamedev-net/nehe-opengl. code - 43 total platforms, configurations, and languages are included.
      Now operated by GameDev.net, NeHe is located at http://nehe.gamedev.net where it has been a valuable resource for developers wanting to learn OpenGL and graphics programming.

      View full story
    • By TheChubu
      The Khronos™ Group, an open consortium of leading hardware and software companies, announces from the SIGGRAPH 2017 Conference the immediate public availability of the OpenGL® 4.6 specification. OpenGL 4.6 integrates the functionality of numerous ARB and EXT extensions created by Khronos members AMD, Intel, and NVIDIA into core, including the capability to ingest SPIR-V™ shaders.
      SPIR-V is a Khronos-defined standard intermediate language for parallel compute and graphics, which enables content creators to simplify their shader authoring and management pipelines while providing significant source shading language flexibility. OpenGL 4.6 adds support for ingesting SPIR-V shaders to the core specification, guaranteeing that SPIR-V shaders will be widely supported by OpenGL implementations.
      OpenGL 4.6 adds the functionality of these ARB extensions to OpenGL’s core specification:
      GL_ARB_gl_spirv and GL_ARB_spirv_extensions to standardize SPIR-V support for OpenGL GL_ARB_indirect_parameters and GL_ARB_shader_draw_parameters for reducing the CPU overhead associated with rendering batches of geometry GL_ARB_pipeline_statistics_query and GL_ARB_transform_feedback_overflow_querystandardize OpenGL support for features available in Direct3D GL_ARB_texture_filter_anisotropic (based on GL_EXT_texture_filter_anisotropic) brings previously IP encumbered functionality into OpenGL to improve the visual quality of textured scenes GL_ARB_polygon_offset_clamp (based on GL_EXT_polygon_offset_clamp) suppresses a common visual artifact known as a “light leak” associated with rendering shadows GL_ARB_shader_atomic_counter_ops and GL_ARB_shader_group_vote add shader intrinsics supported by all desktop vendors to improve functionality and performance GL_KHR_no_error reduces driver overhead by allowing the application to indicate that it expects error-free operation so errors need not be generated In addition to the above features being added to OpenGL 4.6, the following are being released as extensions:
      GL_KHR_parallel_shader_compile allows applications to launch multiple shader compile threads to improve shader compile throughput WGL_ARB_create_context_no_error and GXL_ARB_create_context_no_error allow no error contexts to be created with WGL or GLX that support the GL_KHR_no_error extension “I’m proud to announce OpenGL 4.6 as the most feature-rich version of OpenGL yet. We've brought together the most popular, widely-supported extensions into a new core specification to give OpenGL developers and end users an improved baseline feature set. This includes resolving previous intellectual property roadblocks to bringing anisotropic texture filtering and polygon offset clamping into the core specification to enable widespread implementation and usage,” said Piers Daniell, chair of the OpenGL Working Group at Khronos. “The OpenGL working group will continue to respond to market needs and work with GPU vendors to ensure OpenGL remains a viable and evolving graphics API for all its customers and users across many vital industries.“
      The OpenGL 4.6 specification can be found at https://khronos.org/registry/OpenGL/index_gl.php. The GLSL to SPIR-V compiler glslang has been updated with GLSL 4.60 support, and can be found at https://github.com/KhronosGroup/glslang.
      Sophisticated graphics applications will also benefit from a set of newly released extensions for both OpenGL and OpenGL ES to enable interoperability with Vulkan and Direct3D. These extensions are named:
      GL_EXT_memory_object GL_EXT_memory_object_fd GL_EXT_memory_object_win32 GL_EXT_semaphore GL_EXT_semaphore_fd GL_EXT_semaphore_win32 GL_EXT_win32_keyed_mutex They can be found at: https://khronos.org/registry/OpenGL/index_gl.php
      Industry Support for OpenGL 4.6
      “With OpenGL 4.6 our customers have an improved set of core features available on our full range of OpenGL 4.x capable GPUs. These features provide improved rendering quality, performance and functionality. As the graphics industry’s most popular API, we fully support OpenGL and will continue to work closely with the Khronos Group on the development of new OpenGL specifications and extensions for our customers. NVIDIA has released beta OpenGL 4.6 drivers today at https://developer.nvidia.com/opengl-driver so developers can use these new features right away,” said Bob Pette, vice president, Professional Graphics at NVIDIA.
      "OpenGL 4.6 will be the first OpenGL release where conformant open source implementations based on the Mesa project will be deliverable in a reasonable timeframe after release. The open sourcing of the OpenGL conformance test suite and ongoing work between Khronos and X.org will also allow for non-vendor led open source implementations to achieve conformance in the near future," said David Airlie, senior principal engineer at Red Hat, and developer on Mesa/X.org projects.

      View full story
    • By _OskaR
      Hi,
      I have an OpenGL application but without possibility to wite own shaders.
      I need to perform small VS modification - is possible to do it in an alternative way? Do we have apps or driver modifictions which will catch the shader sent to GPU and override it?
    • By xhcao
      Does sync be needed to read texture content after access texture image in compute shader?
      My simple code is as below,
      glUseProgram(program.get());
      glBindImageTexture(0, texture[0], 0, GL_FALSE, 3, GL_READ_ONLY, GL_R32UI);
      glBindImageTexture(1, texture[1], 0, GL_FALSE, 4, GL_WRITE_ONLY, GL_R32UI);
      glDispatchCompute(1, 1, 1);
      // Does sync be needed here?
      glUseProgram(0);
      glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
      glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                     GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture[1], 0);
      glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
       
      Compute shader is very simple, imageLoad content from texture[0], and imageStore content to texture[1]. Does need to sync after dispatchCompute?
  • Advertisement