Okay so I have run into a very strange problem regarding a project I've been working on. This project is a 3D-engine(using SDL and openGL for input handling, and graphics respectively). I have been working on this project in linux(Ubuntu 10.10) for the past several months and recently decided to port the code over to a Windows 7 environment. One of the main reasons I chose SDL was because it handles window creation independent of operating system, meaning it should be rather simple to port from one OS to another. I am not having problems compiling or linking, it's the problem that the exact same code is running in two completely different ways for apparently no reason.
First off, a visual example of the differences:
http://i.stack.imgur.com/RNcCs.jpg
It's not supposed to look this way, first off the purple revtanglers in the lower left are supposed to be text, and if you look REALLLY closely you can see some points being rendered, I'm using geometry, vertex, and pixel shaders:
http://i.stack.imgur.com/1Y9km.jpg
It should look a lot more like this, as it does in linux. Those points I was talking about are the grass in these:
http://i.stack.imgur.com/Hzmuy.jpg
http://i.stack.imgur.com/HYCMh.jpg
It's also running at 600+ FPS in linux, shaders work fine, everything works flawlessly. I added some code to check the FPS in windows(sending current fps to log file when a button is pressed) and it was running at 20-30 FPS with shaders disabled.
I'm VERY confused by this because none of the code I'm using is actually DIFFERENT, the only differences are in how I use openGL: in windows I use GLEW to handle my extensions while in linux I use #define GL_GLEXT_PROTOTYPES. I've looked around and it would seem as though the code I'm using SHOULD work on both linux and windows, although I'm having these very strange effects whenever I run my program in windows.
The problems would be:
The only places I think I could be doing something wrong would be in Initializing SDL/OpenGL/GLEW .
I'm directly using GLEW, as the libraries I was originally linking to were giving me problems.
//SAE_GL.h
/**Header Guard**/
#ifndef __SAE_OPENGL__
#define __SAE_OPENGL__
/**Include**/
///gl extensions
#ifdef __WIN32
#define GLEW_STATIC
#include "GL/glew.h"
#else
#define GL_GLEXT_PROTOTYPES
#endif
///opengl
#include "GL/gl.h"
#include "GL/glu.h"
///SAE Dependencies
#include "SAE_Core.h"
Window manager(WM.h simply has declarations and includes SAE_GL.h, SAE_SDL.h, and SAE_Core.h)
#include "SAE_WM.h"
namespace SAE{
bool SDL_Application::SAE_QUIT_BOOL_DEFAULT = false;
bool SDL_Application::SAE_MENU_BOOL_DEFAULT = false;
bool SDL_Application::SAE_VERBOSE_FLAG = false;
///Constructor
SDL_Application::SDL_Application(){
///Video Info
screen = (SDL_Surface*)NULL;
videoInfo = (SDL_VideoInfo*)NULL;
VIEW_MODE = SAE_PERSPECTIVE;
VIEW_DIM = SAE_3D;
defaultScreenInfo = SAE_DEFAULT_SCREENINFO_HOLDER;
currentScreenInfo = SAE_DEFAULT_SCREENINFO_HOLDER;
numResolutions = 0;
///Set up our video flags
videoFlags = SDL_OPENGL; ///OpenGL
videoFlags |= SDL_GL_DOUBLEBUFFER; ///Double Buffering
videoFlags |= SDL_HWPALETTE; ///Harware Palette
videoFlags |= SDL_RESIZABLE; ///Window Resizing
///Callback setup
setResizeFunction ( SDL_DResize );
setRunFunction ( SDL_DRun );
setEventFunction ( SDL_DEvent );
setCleanupFunction ( SDL_DClean );
setMenuManagerFunction ( SDL_DMenu );
SAE_QUIT_FLAG = &SAE_QUIT_BOOL_DEFAULT;
SAE_MENU_FLAG = &SAE_MENU_BOOL_DEFAULT;
/////////////////////////////////////////////////
///FPS Handler setup
time = 0;
frames = 0;
/////////////////////////////////////////////////
/////////////////////////////////////////////////
/////////////////////////////////////////////////
/////////////////////////////////////////////////
}
void SDL_Application::init(int argc, char** argv){
///Redirect output to log
FILE* tempb;
tempb = freopen( "logfile.dat", "a+", stderr );
fprintf(stderr,"\n===================================================================================================\n");
fprintf(stderr,"\n***Initializing program essentials***\n");
bool create_fonts = false;
for(int i = 0; i < argc; i++){
if(strncmp(argv[i], "-v",10)==0) SAE_VERBOSE_FLAG = true;
if(strncmp(argv[i], "--genfonts",20)==0){
videoFlags |= SDL_NOFRAME;
create_fonts = true;
}
}
///Initialize Everything in SDL
if(be_verbose)fprintf(stderr,"----SDL : ");
if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ){
if(be_verbose){
fprintf( stderr, "Failed\n");
fprintf( stderr, "--------Critical Error: SDL init failed: %s\n", SDL_GetError( ) );
}
fprintf( stderr, "****The program encountered a critical error - exiting...****");
exit( 0 );
}else{
if(be_verbose)fprintf( stderr, "Success :)\n" );
}
///Get Video Info
videoInfo = ( SDL_VideoInfo* )SDL_GetVideoInfo( );
if(be_verbose)fprintf(stderr,"----Video Info : ");
if( !videoInfo ){
if(be_verbose){
fprintf( stderr, "Failed\n");
fprintf( stderr, "--------Critical Error: Can't query video info: %s\n", SDL_GetError() );
}
fprintf( stderr, "\n****The program encountered a critical error - exiting...****");
exit( 0 );
} else {
///Setup our default width and height
defaultScreenInfo.Width = videoInfo->current_w;
defaultScreenInfo.Height = videoInfo->current_h;
if(be_verbose)fprintf( stderr, "Success :)\n");
}
//////////////////////////////////////////////////////////////////////////////////////////////////
///Sets up what type of surface we're using
if(be_verbose) fprintf(stderr,"----FrameBuffer: ");
if( videoInfo -> hw_available ){
videoFlags |= SDL_HWSURFACE;
}
else{
videoFlags |= SDL_SWSURFACE;
}
/////////
///Sets up hardware blitting
if( videoInfo -> blit_hw ){
videoFlags |= SDL_HWACCEL;
}
/////////
///Enable Double Buffering
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);
///Startup the screen
if(create_fonts){
screen = SDL_SetVideoMode( SAE_DEFAULT_TEXTURE_WIDTH,
SAE_DEFAULT_TEXTURE_HEIGHT,
SAE_DEFAULT_SCREEN_BYTES_PER_PIXEL,
videoFlags );
}else{
screen = SDL_SetVideoMode( SAE_DEFAULT_SCREEN_WIDTH,
SAE_DEFAULT_SCREEN_HEIGHT,
SAE_DEFAULT_SCREEN_BYTES_PER_PIXEL,
videoFlags );
}
if ( !screen ){
if(be_verbose)fprintf( stderr, "Critical Error: Video mode not supported: %s\n", SDL_GetError());
fprintf( stderr, "\n****The program encountered a critical error - exiting...****");
exit(0);
} else {
if(be_verbose) fprintf( stderr, "Success :)\n");
}
//////////////////////////////////////////////////////////////////////////////////////////////////
SDL_PixelFormat format;
SAE_ScreenInfo max;
format.BitsPerPixel = SAE_COMPATABILITY_SCREEN_BYTES_PER_PIXEL;
////////
///Get supported screen resolutions
SDL_Rect** modes = SDL_ListModes(&format, videoFlags|SDL_FULLSCREEN);
if(be_verbose)fprintf(stderr,"----Resolutions: ");
if (modes == (SDL_Rect**)0) {
if(be_verbose)fprintf(stderr,"Critical Error: No resolutions available!\n");
fprintf( stderr, "\n****The program encountered a critical error - exiting...****");
exit(-1);
}else{
if(be_verbose)fprintf(stderr,"Success :)\n");
}
if (modes == (SDL_Rect**)-1) {
max.Width = videoInfo->current_w;
max.Height = videoInfo->current_h;
}else{
for (int i=0; modes[i]; ++i){
max.Width = modes[i]->w;
max.Height = modes[i]->h;
}
}
for(int i = 0; i < 23; i+=2){
if(SAE_SCREEN_RESOLUTIONS[i] <= max.Width && SAE_SCREEN_RESOLUTIONS[i+1] <= max.Height)
{
supportedResolutions[numResolutions].Width = SAE_SCREEN_RESOLUTIONS[i];
supportedResolutions[numResolutions].Height = SAE_SCREEN_RESOLUTIONS[i+1];
numResolutions++;
}
}
///Initialize openGL
if(be_verbose)fprintf(stderr,"----OpenGL : ");
if(!initializeOpenGL()){
if(be_verbose)fprintf(stderr,"Critical Error: openGL init failed, exiting\n");
fprintf( stderr, "\n****The program encountered a critical error - exiting...****");
exit(0);
} else {
if(be_verbose)fprintf(stderr,"Success :)\n\n");
}
/////////////////////////////////////////////////
fprintf(stderr,"***------------SUCCESS------------***\n");
////////////////////////////////////////////////
if(be_verbose){
fprintf(stderr,"\n***---Current Video Information---***\n");
fprintf( stderr, "----Software Surface: %s\n", (videoFlags&SDL_SWSURFACE )?"ENABLED":"DISABLED");
fprintf( stderr, "----Hardware Surface: %s\n", (videoFlags&SDL_HWSURFACE )?"ENABLED":"DISABLED");
fprintf( stderr, "----Hardware Palette: %s\n", (videoFlags&SDL_HWPALETTE )?"ENABLED":"DISABLED");
fprintf( stderr, "----Double Buffering: %s\n", (videoFlags&SDL_DOUBLEBUF )?"ENABLED":"DISABLED");
fprintf( stderr, "----openGL Doublebuf: %s\n", (videoFlags&SDL_GL_DOUBLEBUFFER )?"ENABLED":"DISABLED");
fprintf( stderr, "----Fullscreen : %s\n", (videoFlags&SDL_FULLSCREEN)?"ENABLED":"DISABLED");
fprintf( stderr, "----OpenGL : %s\n", (videoFlags&SDL_OPENGL )?"ENABLED":"DISABLED");
fprintf( stderr, "----Resizable : %s\n", (videoFlags&SDL_RESIZABLE )?"ENABLED":"DISABLED");
fprintf( stderr, "----No Frame : %s\n", (videoFlags&SDL_NOFRAME )?"ENABLED":"DISABLED");
}
SDL_EnableKeyRepeat(500,250);
time = SDL_GetTicks();
resizeWindow(SAE_DEFAULT_SCREEN_WIDTH, SAE_DEFAULT_SCREEN_HEIGHT);
time = SDL_GetTicks();
}
This is where I'm setting up openGL/GLEW for use.
///Initialize openGL
bool SDL_Application::initializeOpenGL(){
/////////////////////////////////////////////////
///Initialize GLEW and load extensions
#ifdef __WIN32
GLenum status = glewInit();
if( status != GLEW_OK ){
///Glew Initialization went wrong
fprintf(stderr, "Error: %s\n", glewGetErrorString( status ));
return false;
} else {
fprintf(stderr, "GLEW successfully initialized!\n");
}
#endif
/////////////////////////////////////////////////
///Sets clear color and clear depth
float clearColor[]={0.0f,0.0f,0.0f,0.0f};
glClearColor( clearColor[0], clearColor[1], clearColor[2], clearColor[3] );
glClearDepth( 1.0f );
/////////
///DEPTH FUNCTION NEEDS CHECKING
glDepthFunc ( GL_LEQUAL );
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glShadeModel( GL_SMOOTH );
/////////
glEnable( GL_DEPTH_TEST ); ///Depth Testting
glEnable( GL_CULL_FACE); ///Face Culling
/////////////////////////////////////////////////
return true;
/////////////////////////////////////////////////
}
I'm also including my window re-sizing functions seeing as it's relative.
void SDL_Application::resizeWindow(int width, int height){
/////////////////////////////////////////////////
SDL_Event myEvent;
myEvent.type = SDL_VIDEORESIZE;
myEvent.resize.type = SDL_VIDEORESIZE;
myEvent.resize.w = width;
myEvent.resize.h = height;
SDL_PushEvent(&myEvent);
}
void SDL_Application::ResizeWindow(int width, int height){
/////////////////////////////////////////////////
double v_min = (VIEW_DIM == SAE_2D)?1.0: 0.1 * SAE_UNIT_MEASURE;
double v_max = (VIEW_DIM == SAE_2D)?1.0: 1000.0 * SAE_UNIT_MEASURE;
///Prevents divide by zero
if( height <= 0 ) height = 1;
///Set aspect ratio
double ratio = (double)width/(double)height;
currentScreenInfo.Width = width;
currentScreenInfo.Height = height;
/////////
///Load and clear our projection matrix
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
///Set the entire window as our viewport
glViewport( 0, 0, currentScreenInfo.Width, currentScreenInfo.Height );
if(VIEW_MODE == SAE_PERSPECTIVE)
{
///Set up a perspective projection
gluPerspective( 70, ratio, v_min, v_max );
}else{
///Gives us an orthographic perspective
glOrtho( v_min, v_max, v_min, v_max, v_min, v_max);
}
/////////
///Set what we're looking at, into the screen
gluLookAt(0, 0, 0,
0, 0, -1,
0.0f, 1.0f, 0.0f);
/////////
///Do our user-set resize function and resize the screen
SAEResize( currentScreenInfo.Width, currentScreenInfo.Height);
screen = SDL_SetVideoMode( currentScreenInfo.Width, currentScreenInfo.Height, SAE_DEFAULT_SCREEN_BYTES_PER_PIXEL, videoFlags);
/////////////////////////////////////////////////
}
I figure I must be missing something, or I don't know something about how SDL/OpenGL/GLEW works on windows.
Edit: Looks like I'm probably not going to get a concrete answer to my question, I suppose I should just rewrite my code to use DirectX, ah well, no biggie.
I don't think this is the main reason for your problems, but: Why on earth are so many people, including OP setting the projection matrix in the window resizing handler? Why? Setting matrices goes all into the display function.
Also the projection matrix should only be used to set the "lens". One must not set the view position with the projection matrix. gluLookAt
on projection matrix mode: Big, fat NoGo !
You said you're using shaders. So why are you using fixed functio matrix operations at all? Pass the matrices as uniforms. This also immediately resolves the problem of doing stuff in the resize handler, where it doesn't belong.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.