Jump to content

  • Log In with Google      Sign In   
  • Create Account


[SDL] Super slow framerate on Windows 7, GLEW shaders unavailable


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

#1 nitro glycerine   Members   -  Reputation: 103

Like
0Likes
Like

Posted 24 February 2012 - 10:38 PM

Hello!

I've been working on a project off and on in SDL for a number of months now, and I've had an issue from the start that I recently had some time to try and debug. I've been developing on Windows XP until this past week, so it was not really an issue until now.

Basically, my SDL bases game works perfectly fine on any Windows XP machine (ie. normal frame rate, shaders work no problem), but I initially noticed that if I ran the executable on Windows 7, the frame rate would only be 10-15 for no reason (on super high-end machines, ie. Phenom II X6 / 5970) but this was strictly a Windows 7 issue as indicated by testing on several different machines. Upon further investigation I realized that if I run the game from within Visual Studio 2008 on a Windows 7 machine it works perfectly (ie. 7000+ FPS w/o vsync), but as soon as I ran it from the executable instead, the frame rate would once again be between 10 and 15, and if shaders were being used via GLEW, the program would simply exit because GLEW 2.0 was unavailable.

tldr; SDL OpenGL game, works fine on XP, on Win7 works fine in VS2008 but EXE limited to 10 fps and shaders wont work

Honestly not sure what the issue could possibly be and has been baffling me for some time. If anyone has any suggestions or input, it would be greatly appreciated. It almost seems like SDL is somehow switching to software mode or some limited version of OpenGL. Also worth mentioning that the only things being rendered is some text (generated and rendered via lists) and a very simple skybox with 1024x1024 textures for each side.

My game is using SDLmain and a number of libraries, including:
SDL
SDL_ttf
GLEW
FreeImage
Qt
FMOD Ex
FBX SDK
Bullet Physics

Thanks for reading. Some code, if it helps any:

Main.cpp:
#include "Game.h"
int main(int argc, char * argv[]) {
	 Game * game = new Game();
	 if(!game->init()) { return -1; }
	 game->run();
	 delete game;
	 return 0;
}

OpenGL Setup:
bool Game::init() {
	 if(m_initialized) { return false; }
	 settings->load();
	 if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK) == -1) { return false; }
	 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, settings->verticalSync ? 1 : 0);
	 m_graphics = SDL_SetVideoMode(settings->windowWidth, settings->windowHeight, 0, SDL_OPENGL | (settings->fullScreen ?	 SDL_FULLSCREEN : 0));
	 SDL_WM_SetCaption("Game", NULL);
	 QString iconPath;
	 iconPath.append(QString("%1/Icons/Block.bmp").arg(settings->dataDirectoryName));
	 QByteArray iconPathBytes = iconPath.toLocal8Bit();
	 m_icon = SDL_LoadBMP(iconPathBytes.data());
	 SDL_WM_SetIcon(m_icon, NULL);
	 glShadeModel(GL_SMOOTH);
	 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	 glClearDepth(1.0f);
	 glEnable(GL_DEPTH_TEST);
	 glEnable(GL_TEXTURE_2D);
	 glEnable(GL_BLEND);
	 glDepthFunc(GL_LEQUAL);
	 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	 glMatrixMode(GL_MODELVIEW);
	 glViewport(0, 0, settings->windowWidth, settings->windowHeight);
	 if(glewInit() != GLEW_OK) { return false; }
	 if(!GLEW_VERSION_2_0) { return false; }

	 etc.

Game Loop:
void Game::run() {
if(!m_initialized) { return; }
m_running = true;
SDL_Event event;
static unsigned int lastTime = SDL_GetTicks();
unsigned int currentTime = SDL_GetTicks();
do {
  if(SDL_PollEvent(&event)) {
   switch(event.type) {
	case SDL_KEYDOWN:
	 if(!console->isActive()) {
	  menu->handleInput(event);
	 }
	 if(!menu->isActive()) {
	  console->handleInput(event);
	 }
	 break;
	case SDL_MOUSEMOTION:
	 if(!console->isActive() &&
		!menu->isActive() &&
		SDL_GetAppState() & SDL_APPMOUSEFOCUS &&
		SDL_GetAppState() & SDL_APPINPUTFOCUS &&
		SDL_GetAppState() & SDL_APPACTIVE) {
	  camera->handleInput(event);
	 }
	 break;
	case SDL_QUIT:
	 m_running = false;
	 break;
	default:
	 break;
   }
  }
  if(m_running) {
   currentTime = SDL_GetTicks();
   update(currentTime - lastTime);
   draw();
   lastTime = currentTime;
  }
} while(m_running);
}


Sponsor:

#2 fastcall22   Crossbones+   -  Reputation: 4149

Like
0Likes
Like

Posted 24 February 2012 - 11:13 PM

if(SDL_PollEvent(&event))

Should be:

while ( SDL_PollEvent( &event ) )

It's likely that your event queue accumulates more and and more windows events until your game slows down to a crawl -- you need to process all of the window messages between each frame, not just one per frame. (Not sure if this will fix your problem, but it will certainly help...)
c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#3 nitro glycerine   Members   -  Reputation: 103

Like
0Likes
Like

Posted 27 February 2012 - 03:42 AM

Oh dear, I feel ashamed for implementing that wrong. Thanks for the reply! Although this did not fix my previous issues (slow framerate, shaders unsupported), it did fix my input handling and bizarre behaviours I was experiencing with my camera which I had yet to solve, so thanks!

Still looking for a solution, though. I just can't figure what's so different with the execution of the game between being run from Visual Studio 2008 vs. from the compiled release executable.

#4 mhagain   Crossbones+   -  Reputation: 7595

Like
0Likes
Like

Posted 27 February 2012 - 08:47 AM

Are you mixing any regular SDL drawing (i.e. not OpenGL stuff) with your OpenGL drawing? That could be a possible cause on WDDM drivers.

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.


#5 nitro glycerine   Members   -  Reputation: 103

Like
0Likes
Like

Posted 27 February 2012 - 12:20 PM

Not as far as I know, I'm using glLists for my SkyBox, and standard OpenGL stuff for the rest, see code below. The only strange thing I'm doing is using SDL_ttf which uses SDL_Surface to blit text which I convert to an OpenGL texture. Irregardless, I don't think any of this should be an issue if it works perfectly fine from Visual Studio 2008, right?

Edit: Furthermore, there are no problems on Windows XP when running from either VS2008 or EXE. So why is it such a problem on Windows 7? I'm using platform independent libraries (ie. no STL), so I'm still completely baffled.

SkyBox Load:
bool SkyBox::load() {
	if(m_loaded) { return true; }

	for(int i=0;i<6;i++) {
		m_textures[i] = Game::resources->getTexture(m_textureNames[i]);
		if(m_textures[i] == NULL) { return false; }
		if(!m_textures[i]->load()) { return false; }
	}

	m_skyBoxList = glGenLists(6);

	float width = (float) (m_textures[0]->getWidth() - 1) / (float) m_textures[0]->getWidth();
	
	// left side
	glNewList(m_skyBoxList, GL_COMPILE);
		glBegin(GL_POLYGON);
			glTexCoord2d(1 - width, width);
			glVertex3d(-0.5, 0.5, 0.5);
			glTexCoord2d(1 - width, 1 - width);
			glVertex3d(-0.5, -0.5, 0.5);
			glTexCoord2d(width, 1 - width);
			glVertex3d(-0.5, -0.5, -0.5);
			glTexCoord2d(width, width);
			glVertex3d(-0.5, 0.5, -0.5);
		glEnd();
	glEndList();

	// right side
	glNewList(m_skyBoxList + 1, GL_COMPILE);
		glBegin(GL_POLYGON);
			glTexCoord2d(1 - width, width);
			glVertex3d(0.5, 0.5, -0.5);
			glTexCoord2d(1 - width, 1 - width);
			glVertex3d(0.5, -0.5, -0.5);
			glTexCoord2d(width, 1 - width);
			glVertex3d(0.5, -0.5, 0.5);
			glTexCoord2d(width, width);
			glVertex3d(0.5, 0.5, 0.5);
		glEnd();
	glEndList();

	// front side
	glNewList(m_skyBoxList + 2, GL_COMPILE);
		glBegin(GL_POLYGON);
			glTexCoord2d(1 - width, width);
			glVertex3d(-0.5, 0.5, -0.5);
			glTexCoord2d(1 - width, 1 - width);
			glVertex3d(-0.5, -0.5, -0.5);
			glTexCoord2d(width, 1 - width);
			glVertex3d(0.5, -0.5, -0.5);
			glTexCoord2d(width, width);
			glVertex3d(0.5, 0.5, -0.5);
		glEnd();
	glEndList();

	// back side
	glNewList(m_skyBoxList + 3, GL_COMPILE);
		glBegin(GL_POLYGON);
			glTexCoord2d(1 - width, width);
			glVertex3d(0.5, 0.5, 0.5);
			glTexCoord2d(1 - width, 1 - width);
			glVertex3d(0.5, -0.5, 0.5);
			glTexCoord2d(width, 1 - width);
			glVertex3d(-0.5, -0.5, 0.5);
			glTexCoord2d(width, width);
			glVertex3d(-0.5, 0.5, 0.5);
		glEnd();
	glEndList();

	// top side
	glNewList(m_skyBoxList + 4, GL_COMPILE);
		glBegin(GL_POLYGON);
			glTexCoord2d(width, 1 - width);
			glVertex3d(-0.5, 0.5, 0.5);
			glTexCoord2d(width, width);
			glVertex3d(-0.5, 0.5, -0.5);
			glTexCoord2d(1 - width, width);
			glVertex3d(0.5, 0.5, -0.5);
			glTexCoord2d(1 - width, 1 - width);
			glVertex3d(0.5, 0.5, 0.5);
		glEnd();
	glEndList();

	// bottom side
	glNewList(m_skyBoxList + 5, GL_COMPILE);
		glBegin(GL_POLYGON);
			glTexCoord2d(width, 1 - width);
			glVertex3d(-0.5, -0.5, -0.5);
			glTexCoord2d(width, width);
			glVertex3d(-0.5, -0.5, 0.5);
			glTexCoord2d(1 - width, width);
			glVertex3d(0.5, -0.5, 0.5);
			glTexCoord2d(1 - width, 1 - width);
			glVertex3d(0.5, -0.5, -0.5);
		glEnd();
	glEndList();

	m_loaded = true;

	return true;
}

SkyBox Draw:
void SkyBox::draw() {
	if(!m_loaded) { return; }

	glDisable(GL_DEPTH_TEST);
	
	glLoadIdentity();

	glRotated(Game::camera->getRotation().x, 1, 0, 0);
	glRotated(Game::camera->getRotation().y, 0, 1, 0);

	for(int i=0;i<6;i++) {
		m_textures[i]->activate();
		glCallList(m_skyBoxList + i);
	}

	glEnable(GL_DEPTH_TEST);
}

Game Draw:
void Game::draw() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// set up 3d rendering
	glEnable(GL_TEXTURE_2D);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(70.0f, (GLfloat) settings->windowWidth / (GLfloat) settings->windowHeight, 0.1f, 10000.0f);
	glMatrixMode(GL_MODELVIEW);
	
	// render skybox
	if(skyBox != NULL) {
		skyBox->draw();
	}

	// render world
	if(mainShader != NULL) { mainShader->activate(); }

	glPushMatrix();
		camera->setup();
		
		glScalef(100, 100, 100);

		glBegin(GL_POLYGON);

		// left
		glVertex3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(-1.0f, 0.0f, -1.0f);
		glVertex3f(-1.0f, -1.0f, -1.0f);
		glVertex3f(-1.0f, -1.0f, 0.0f);

		// right
		glVertex3f(0.0f, 0.0f, 0.0f);
		glVertex3f(0.0f, -1.0f, 0.0f);
		glVertex3f(0.0f, -1.0f, -1.0f);
		glVertex3f(0.0f, 0.0f, -1.0f);

		// front
		glVertex3f(0.0f, 0.0f, 0.0f);
		glVertex3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(-1.0f, -1.0f, 0.0f);
		glVertex3f(0.0f, -1.0f, 0.0f);

		// back
		glVertex3f(0.0f, 0.0f, 0.0f);
		glVertex3f(-1.0f, 0.0f, -1.0f);
		glVertex3f(-1.0f, -1.0f, -1.0f);
		glVertex3f(0.0f, -1.0f, -1.0f);

		// top
		glVertex3f(0.0f, 0.0f, 0.0f);
		glVertex3f(0.0f, 0.0f, -1.0f);
		glVertex3f(-1.0f, 0.0f, -1.0f);
		glVertex3f(-1.0f, 0.0f, 0.0f);

		// bottom
		glVertex3f(0.0f, 0.0f, 0.0f);
		glVertex3f(0.0f, -1.0f, -1.0f);
		glVertex3f(-1.0f, -1.0f, -1.0f);
		glVertex3f(-1.0f, -1.0f, 0.0f);

		glEnd();
	glPopMatrix();

	if(mainShader != NULL) { mainShader->deactivate(); }

	// set up 2d rendering
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, settings->windowWidth, settings->windowHeight, 0);

	// render hud / gui elements
	displayFPS();
	menu->draw();
	console->draw();

	SDL_GL_SwapBuffers();
}

Font Draw / Load:
void Font::drawTextHelper(int x, int y, const char * text) const {
	if(!m_loaded) { return; }

	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE);

	glBindTexture(GL_TEXTURE_2D, m_texture);

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

		glLoadIdentity();

		glTranslated(x, y, 0);
		glListBase(m_font - 32);
		glCallLists(strlen(text), GL_BYTE, text);

	glPopMatrix();
}

bool Font::load() {
	if(m_loaded) { return true; }

	QString fontPath = QString("%1/Fonts/%2").arg(Game::settings->dataDirectoryName).arg(m_fileName);

	QFileInfo fontFile(fontPath);
	if(!fontFile.exists()) { return false; }

	QByteArray bytes = fontPath.toLocal8Bit();

	TTF_Font * fontData;
	if(!(fontData = TTF_OpenFont(bytes.data(), m_size))) {
		return false;
	}

	SDL_Color colour = {255, 255, 255, 255};

	SDL_Surface * character;
	QVector characters;
	int maxWidth = -1;
	int maxHeight = -1;
	char data[2];
	data[1] = '\0';
	for(int i=0;i<128;i++ ) {
		data[0] = (char) (i + 32);
		character = TTF_RenderText_Blended(fontData, data, colour);
		characters.push_back(character);
		if(maxWidth < 0 || maxWidth < character->w) { maxWidth = character->w; }
		if(maxHeight < 0 || maxHeight < character->h) { maxHeight = character->h; }
	}

	m_horizontalSpacing = maxWidth;
	m_verticalSpacing = maxHeight;

	int width = 1, tempWidth = maxWidth * 16;
	int height = 1, tempHeight = maxHeight * 8;
	while(width < tempWidth) { width *= 2; }
	while(height < tempHeight) { height *= 2; }

	SDL_Surface * temp = SDL_CreateRGBSurface(0, width, height, 32,
		#if SDL_BYTEORDER == SDL_BIG_ENDIAN
			0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
		#else
			0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
		#endif
	);

	SDL_Rect sourceArea, destArea;
	int x = 0;
	int y = 0;
	for(int i=0;i<128;i++) {
		sourceArea.x = 0;
		sourceArea.y = 0;
		sourceArea.w = characters[i]->w;
		sourceArea.h = characters[i]->h;

		destArea.x = maxWidth * x;
		destArea.y = maxHeight * y;
		destArea.w = characters[i]->w;
		destArea.h = characters[i]->h;

		SDL_SetAlpha(characters[i], 0, 0);
		SDL_BlitSurface(characters[i], &sourceArea, temp, &destArea);

		x++;
		if(x == 16) {
			x = 0;
			y++;
		}
	}

	glGenTextures(1, &m_texture);
	glBindTexture(GL_TEXTURE_2D, m_texture);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, temp->w, temp->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp->pixels);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE);

	m_font = glGenLists(128);

	x = 0;
	y = 0;
	float w = (float) maxWidth / (float) (temp->w);
	float h = (float) maxHeight / (float) (temp->h);
	for(int i=0;i<128;i++) {

		glNewList(m_font + i, GL_COMPILE);

			glBegin(GL_QUADS);
				glTexCoord2f((w * x),	 ((h * y)));	 glVertex2i(0,		0);
				glTexCoord2f((w * x) + w, ((h * y)));	 glVertex2i(maxWidth, 0);
				glTexCoord2f((w * x) + w, ((h * y) + h)); glVertex2i(maxWidth, maxHeight);
				glTexCoord2f((w * x),	 ((h * y) + h)); glVertex2i(0,		maxHeight);
			glEnd();

			glTranslated(maxWidth, 0, 0);

		glEndList();

		x++;
		if(x == 16) {
			x = 0;
			y++;
		}
	}

	for(int i=0;i<128;i++) {
		SDL_FreeSurface(characters[i]);
	}
	SDL_FreeSurface(temp);

	m_loaded = true;

	return true;
}


#6 nitro glycerine   Members   -  Reputation: 103

Like
1Likes
Like

Posted 24 March 2012 - 06:43 PM

Found the solution to all my issues finally, after consulting some friends. Turns out Visual Studio 2008 on Windows 7 would use the operating system's version of OpenGL, and when I ran it from the EXE it used the local OpenGL32.dll which was either out of date, or built for the wrong platform. So, removing this DLL fixed all framerate issues, and now runs no problem after defaulting to the operating system's OpenGL32.dll. Hopefully this helps anyone else who runs into this issue!




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