简体   繁体   中英

SDL+OpenGL working in linux but not windows, NOT COMPILER/LINKER ISSUE

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:

  • View seems to be stuck in an orthographic projection(when it's set up to be perspective)
  • Shaders, Blending, Framebuffers/VBO's, Textures, are not working.
  • Extreme delay.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM