2
\$\begingroup\$

I'm learning C++, and I'm writing my first OpenGL program. Unfortunately, it seems to be defaulting to Software Rendering (CPU uses bounces, GPU uses stays at 1%). I'm using SDL as the Windowing system. I've got no idea why, but when there is significant scaling, the program grinds to a halt. My PC should be able to handle it - I'm using an 8800GTX. My texture is 1024x1024, 32 bit RGBA and loaded with DevIL, and glGetString(GL_VENDOR) is returning "NVidia Corporation". Any ideas?

I'm sorry to be dumping all the code, but I've got absolutely no idea at all what is doing it. I'm very new to OpenGL.

#pragma once
#include "SDL.h"
#include "SDL_opengl.h"7
#include "IL/il.h"
#include "IL/ilut.h"
#include <math.h>    

const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 768;
const int SCREEN_BPP = 32;
const int FPS = 60;
const int XSIZE = 1024; 
const int YSIZE = 768;

int main( int argc, char *argv[] )
{
    bool quit = false;

    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);

    SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_HWSURFACE |  SDL_OPENGL);     

    glEnable(GL_TEXTURE_2D);

    const GLubyte * Vendor = glGetString(GL_VENDOR);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to red      
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho(0, XSIZE, YSIZE, 0, 0, 1);
    glMatrixMode (GL_MODELVIEW);

    glDisable(GL_DEPTH_TEST);

    GLuint image;

    ilInit();
    ilutRenderer(ILUT_OPENGL);  

    ILuint texid;
    ILboolean success;
    ilGenImages(1, &texid);
    ilBindImage(texid);

    success = ilLoadImage("Textures.png");
    if (success)
    {
        success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
        if (!success)
        {
            SDL_Quit();
            return -1;
        }
        glGenTextures(1, &image);
        glBindTexture(GL_TEXTURE_2D, image);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        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, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH),
          ilGetInteger(IL_IMAGE_HEIGHT), 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE,
          ilGetData());
        ilDeleteImages(1, &texid);
    }
    else
    {
        SDL_Quit();
        return -2;
    }


    SDL_Event event;

    float x = 0.0f;

    while (!quit) 
    {
        while ( SDL_PollEvent(&event) )
        {
            switch (event.type)
            {
                case SDL_QUIT:
                    quit = true;
                    break;
            }
        }

        glClear(GL_COLOR_BUFFER_BIT);

        glLoadIdentity();
        glTranslatef(200.0f, 200.0f, 0.0f);
        glRotatef(x,0.0f,0.0f, 1.0f);       
        glScalef(1.0f+x, 1.0f+x, 1.0f+x);
        glBegin(GL_QUADS);      
        glTexCoord2f(0.0f, 0.0f);
        glVertex2f(-100, -100); 
        glTexCoord2f(0.0f, 0.119140f);      
        glVertex2f(-100, 100); 
        glTexCoord2f(0.091797f, 0.119140f);
        glVertex2f(100, 100); 
        glTexCoord2f(0.091797f, 0.0f);
        glVertex2f(100, -100);
        glEnd();

        x += 0.1f;

        SDL_GL_SwapBuffers();
        glFlush;        
    }

    return 0;
}

Edit : (24/04/2011 9.22 PM AEST) When run on an ancient card, on an ancient computer, it maintains ~60FPS.

\$\endgroup\$
10
  • \$\begingroup\$ Query glGetString(GL_VERSION); from OpenGL and make sure it is not something like 1.0 (that would mean no proper drivers installed). It happens on built-in GPUs mostly, but give it a try! ;) \$\endgroup\$
    – Kromster
    Apr 23, 2011 at 15:52
  • \$\begingroup\$ It returns 3.3.0. I've got almost latest NVidia drivers installed... hmmmmm \$\endgroup\$
    – lochok
    Apr 23, 2011 at 15:54
  • \$\begingroup\$ Have you tried using a profiler such as gDEBugger to see if any of the OpenGL calls are taking a silly amount of time? \$\endgroup\$
    – Ray Dey
    Apr 24, 2011 at 0:46
  • \$\begingroup\$ I just did. I've never used it so I don't know what to look for - but I did note that it says 78% of my calls are depreciated - mostly because of 'Fixed Pipeline Vertex Processing' being depreciated. These include my calls to glTexCoord2f, glVertex2f, glLoadIdentity, glBegin, glEnd, glRotatef, glScalef, glTranslatef, glMatrixMode and glOtho! That's almost every OpenGL call! Will this alone dump me down to super slow speed? \$\endgroup\$
    – lochok
    Apr 24, 2011 at 2:54
  • \$\begingroup\$ @lochok: It may well do. Those calls simply don't exist anymore, and your OGL implementation may be being forced to emulate them in software. \$\endgroup\$
    – DeadMG
    Apr 24, 2011 at 6:26

5 Answers 5

4
\$\begingroup\$

What do you mean by insanely slow? You have no timing in your code. How many frames per second?

Your drawing very little, it's normal for the GPU to be mostly unused. You can't determine if it's software rendering just by looking at CPU/GPU usage.

\$\endgroup\$
5
  • \$\begingroup\$ I'd estimate it slows down to about 3-5fps. My reasoning was, if it had to slow that much, then either CPU or GPU usage should be going through the roof. All four cores on my CPU jumped to 30+% - which I figured was the NVidea OpenGL fallback. It only really slowed once the quad took up a really large part of the screen. \$\endgroup\$
    – lochok
    Apr 23, 2011 at 15:14
  • \$\begingroup\$ Just pushed it a reasonable amount longer, CPU usage grew to about 60% for each core \$\endgroup\$
    – lochok
    Apr 23, 2011 at 15:24
  • \$\begingroup\$ Try removing the SDL_PollEvent while loop \$\endgroup\$
    – Meh
    Apr 23, 2011 at 15:30
  • \$\begingroup\$ No improvement at all \$\endgroup\$
    – lochok
    Apr 23, 2011 at 15:37
  • \$\begingroup\$ What your drawing it's so simple, that even with software rendering you shouldn't have a problem. \$\endgroup\$
    – Meh
    Apr 23, 2011 at 23:03
3
\$\begingroup\$

You should not need to use glFlush(). Also it's advisable to use vertex arrays or VBOs instead of immediate mode, though it probably won't make a difference in a program as small as this.

\$\endgroup\$
1
  • \$\begingroup\$ glFlush made no difference - but thank you for the idea \$\endgroup\$
    – lochok
    Apr 23, 2011 at 23:45
1
\$\begingroup\$

Try to disable texturing before rendering (before while loop): glDisable(GL_TEXTURE_2D); - if it helps, there is problem with texturing. But I don't think it should help.

You can also try to comment everything from glBegin(GL_QUADS); to glEnd(); - but you will not see if it helps. You would need some FPS counter.

Also try to sleep while loop at the end for some time (let's say for 20 ms). But I don't think it will help anyway.

And also try to change glOrtho(0, XSIZE, YSIZE, 0, 0, 1); to glOrtho(0, XSIZE, 0, YSIZE, 0, 1); Is your code rendering something?

\$\endgroup\$
4
  • \$\begingroup\$ FPS Log is: 29 26 23 21 16 16 15 14 13 12 11 11 11 10 10 9 9 9 7 7 7 7 7 7 7 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 4 4 3 - it slows down as the one quad stretches. I'm (intending on) making a 2D game - hence why I had glOrtho set what it was. It made no real change to the FPS. Disabling texturing (after the textures were supposedly bound and loaded) increased substantially - 55 47 45 43 40 40 37 35 33 32 30 29 ... 9 10 9 9 9 9 9 9 9 9 9 9 9 8 9 - but 9FPS is still ridiculously slow for one quad taking up much of the screen. Removing glBegin bounced it up to averaging 100+ \$\endgroup\$
    – lochok
    Apr 23, 2011 at 23:57
  • 3
    \$\begingroup\$ Maybe you can try something else then SDL. It's really weird :) \$\endgroup\$
    – zacharmarz
    Apr 24, 2011 at 9:40
  • \$\begingroup\$ So you isolated the problem code to the glBegin()? Are you actually seeing that image? Maybe your SDL isn't flushing your context. Try the latest repository of SDL (1.3?) \$\endgroup\$ Apr 24, 2011 at 13:03
  • \$\begingroup\$ The glBegin segment was if I commented out the entire section - so, there is no image to speak of. A very fast render of a plain black screen \$\endgroup\$
    – lochok
    Apr 24, 2011 at 13:35
1
\$\begingroup\$

Are your textures a power of 2 size? (4x4, 64x64 etc.) I think that could definitely slow things way down if they are not.

\$\endgroup\$
1
  • \$\begingroup\$ I thought so too - my texture is 1024x1024. I also tried lowering it to 256x256 with no effect \$\endgroup\$
    – lochok
    Apr 23, 2011 at 23:09
1
\$\begingroup\$

I've got no idea why, but it seems to have repaired itself. I even put a NPOT texture to test and I'm still getting very, very reasonable FPS rates. I don't think I've changed anything, and I've really got not idea at all why it is fixed. I'm sorry that this doesn't seem to be really answering the question. If anybody else can decipher why - you're doing better then me.

My final source is below:

#pragma once
#include "SDL.h"
#include "SDL_opengl.h"
#include "IL/il.h"
#include "IL/ilut.h"
#include <math.h>    
#include <fstream>

const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 768;
const int SCREEN_BPP = 32;
const int FPS = 60;
const int XSIZE = 1024; 
const int YSIZE = 768;

using namespace std;

int main( int argc, char *argv[] )
{
bool quit = false;

SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);

SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_HWSURFACE |  SDL_OPENGL);     

glEnable(GL_TEXTURE_2D);

const GLubyte * Vendor = glGetString(GL_VENDOR);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to red      
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho(0, XSIZE, YSIZE, 0, 0, 1);
glMatrixMode (GL_MODELVIEW);

glDisable(GL_DEPTH_TEST);

GLuint image;

ilInit();
ilutRenderer(ILUT_OPENGL);  

ILuint texid;
ILboolean success;
ilGenImages(1, &texid);
ilBindImage(texid);

success = ilLoadImage("Textures.png");

    Uint32 startclock = 0;
Uint32 deltaclock = 0;
Uint32 currentFPS = 0;      
startclock = SDL_GetTicks();
deltaclock = SDL_GetTicks();

fstream Log;
Log.open("log.txt", ios::out | ios::trunc);
Log.clear();    

if (success)
{
    success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
    if (!success)
    {
        SDL_Quit();
        return -1;
    }
    glGenTextures(1, &image);
    glBindTexture(GL_TEXTURE_2D, image);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    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, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH),
      ilGetInteger(IL_IMAGE_HEIGHT), 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE,
      ilGetData());
    ilDeleteImages(1, &texid);
}
else
{
    SDL_Quit();
    return -2;
}


SDL_Event event;

float x = 0.0f;

while (!quit) 
{
    while ( SDL_PollEvent(&event) )
    {
        switch (event.type)
        {
            case SDL_QUIT:
                quit = true;
                break;
        }
    }

    glClear(GL_COLOR_BUFFER_BIT);

    glLoadIdentity();
    glTranslatef(200.0f, 200.0f, 0.0f);
    glRotatef(x,0.0f,0.0f, 1.0f);       
    glScalef(1.0f+x, 1.0f+x, 1.0f+x);
    glBegin(GL_QUADS);      
    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(-100, -100); 
    glTexCoord2f(0.0f, 0.119140f);      
    glVertex2f(-100, 100); 
    glTexCoord2f(0.091797f, 0.119140f);
    glVertex2f(100, 100); 
    glTexCoord2f(0.091797f, 0.0f);
    glVertex2f(100, -100);
    glEnd();

    x += 0.1f;

    SDL_GL_SwapBuffers();

    deltaclock = SDL_GetTicks() - startclock;
    startclock = SDL_GetTicks();
    if ( deltaclock != 0 )  currentFPS = 1000 / deltaclock; 
    static char buffer[20] = {0}; 
    sprintf( buffer, "%d ", currentFPS ); 
    SDL_WM_SetCaption( buffer,0 ); 

    if (currentFPS < 4) { quit = true ;}

    Log << buffer;

}
Log.close();
return 0;
}
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Setting window captions and writing to files are both very expensive. \$\endgroup\$
    – user744
    Apr 24, 2011 at 15:45
  • \$\begingroup\$ Same Code, and it's slowing to a crawl again. Grrrrrr \$\endgroup\$
    – lochok
    May 2, 2011 at 6:55
  • \$\begingroup\$ OK - there seems to be something about how long it has been since the program was last run. Queerer, and queerer. After a little while, runs fast. Straight away, it (mostly) runs slow \$\endgroup\$
    – lochok
    May 2, 2011 at 7:34
  • \$\begingroup\$ And finally, there are no issues at all if I run in Fullscreen \$\endgroup\$
    – lochok
    May 2, 2011 at 7:47
  • \$\begingroup\$ I just had a similar issue myself on an old 7600. I suspect there's some kind of bug with newer NVIDIA driver versions on older cards. The problem clears up after a reboot. \$\endgroup\$
    – Jimmy
    Sep 17, 2012 at 2:48

Not the answer you're looking for? Browse other questions tagged .