SDL程序中的颜色已关闭

时间:2011-06-09 04:56:56

标签: c opengl sdl

我目前正在开发一个非常简单的游戏,使用纯C方法和SDL(及其官方额外的库,如SDL_image)和OpenGL。现在虽然我遇到了一些绊脚石,我不知道为什么会这样做:颜色在绘制时都是关闭的。我目前正在Mac上运行该程序,但如果我在Windows中运行它时正确记得颜色更接近正确,但仍然会发生一些奇怪的事情(例如纯白色多边形绘图为黄色)。 / p>

目前在我的Mac上,作为png文件加载的所有图像都将其颜色绘制得有点偏离,而纯白色多边形则绘制为深绿色。还有一些图像是纯白色的。如果我在Windows上记得正确的话,图像会正确绘制,但白色多边形是黄色的,如前所述。现在我将发布相关的初始化和加载代码等等。

int main( int argc, char *argv[] ) {
//initializing various OpenGL attributes with SDL utilities
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); //needs for 3D
    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 ); //only needed for systems other than mac osx
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );

    /* Set 640x480 video mode */
    screen=SDL_SetVideoMode(screen_width,screen_height, 8, videoflags );
        if (screen == NULL) {
        fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
                        screen_width, screen_height,
                        video_info->vfmt->BitsPerPixel, SDL_GetError());
        exit(2);
    }

    glShadeModel( GL_SMOOTH );

    glClearColor( 0.3f, 0.3f, 0.3f, 0 );

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

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    gluOrtho2D( 0.0f, screen->w, 0.0f, screen->h );

    /*glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );*/
    glEnable( GL_ALPHA_TEST );
    glAlphaFunc( GL_GREATER, 0.1f );

// Some basic initialization stuff goes here
// Assume infinite while loop goes here, except when esc is pressed

        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();

        glEnable( GL_TEXTURE_2D );
        draw_gui();

        // Things get drawn here

        glDisable( GL_TEXTURE_2D );

        SDL_GL_SwapBuffers();
        SDL_Delay( 10 );

// End of while loop, clean up, etc.
}

现在我将展示实际将图像加载到内存中的代码:

Sprite *gen_sprite( char *file ) {
    SDL_Surface *buffer = IMG_Load( file );
    if( buffer == NULL ) {
        fprintf( stderr, "Could not load image '%s'\n for reason: %s\n",
                file, IMG_GetError() );
        exit( 3 );
    } 
    return gen_sprite_from( buffer );
}

Sprite *gen_sprite_from( SDL_Surface *buffer ) {
    Sprite *sprite;
    GLuint texture;

    if( buffer == NULL ) {
        fprintf( stderr, "NULL surface passed to gen_sprite_from." );
        exit( 3 );
    }    
    texture = gen_Gl_texture_from( buffer );
    if( ( sprite = malloc( sizeof( Sprite ) ) ) == NULL ) {
        fprintf( stderr, "Malloc failed to allocate space for a Sprite.\n" );
        exit( 1 );
    }
    if( ( sprite->tex = malloc( sizeof( GLuint ) ) ) == NULL ) {
        fprintf( stderr, "Malloc failed to allocate space for a GLuint.\n" );
        exit( 1 );
    }
    sprite->tex[ 0 ] = texture;
    sprite->original = buffer;
    sprite->is_animation = 0;
    sprite->cur_frame = 0;
    sprite->cur_time = 0;
    sprite->num_frames = 1;
    sprite->frame_time = NULL;

    return sprite;
}

Uint32 gen_Gl_texture_from( SDL_Surface *buffer ) {
    GLuint texture;
    SDL_Surface *temp;

    glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
    glGenTextures( 1, &texture );
    temp = SDL_CreateRGBSurface( SDL_SWSURFACE, buffer->w, buffer->h, 32,

        0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 );
    SDL_SetAlpha( buffer, 0, SDL_ALPHA_OPAQUE );
    SDL_BlitSurface( buffer, NULL, temp, NULL );
    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 );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
    gluBuild2DMipmaps( GL_TEXTURE_2D, 4,
                      temp->w, temp->h,
                      GL_RGBA, GL_UNSIGNED_BYTE,
                      temp->pixels );
    SDL_FreeSurface( temp );

    // This just creates white blocks instead of actually loading textures
    //glPixelStorei( GL_UNPACK_ALIGNMENT, buffer->format->BytesPerPixel );
    //glGenTextures( 1, &texture );
    //glBindTexture( GL_TEXTURE_2D, texture );
    //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    //glTexImage2D( GL_TEXTURE_2D, 0, mask_order, buffer->w, buffer->h, 0,
    //  mask_order, GL_UNSIGNED_BYTE, buffer->pixels );

    return texture;
}

此时,我相信所有与颜色倾斜相关的代码都已发布。绘图代码非常简单,只涉及诸如平移或旋转,绑定纹理,然后是带有texcoords和顶点的简单开始/结束块。如果有人能告诉我为什么颜色会关闭,让我知道一个很好的方法来确保颜色总是以跨平台的方式正确(我打算在所有平台上构建,这是我正在使用的部分原因) SDL)我真的很感激。

1 个答案:

答案 0 :(得分:4)

您的频道正在混乱。

问题在以下几行中很明显:

temp = SDL_CreateRGBSurface( SDL_SWSURFACE, buffer->w, buffer->h, 32,
    0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 );

gluBuild2DMipmaps( GL_TEXTURE_2D, 4,
                  temp->w, temp->h,
                  GL_RGBA, GL_UNSIGNED_BYTE,
                  temp->pixels );

您正在指定由32位单元组成的SDL中的32位纹理,然后您将OpenGL纹理指定为4个8位组件。根据您的体系结构的字节序,这可能会给您正确或不正确的结果。解决方案是将OpenGL纹理指定为GL_UNSIGNED_BYTE而不是GL_UNSIGNED_INT,如下所示:

gluBuild2DMipmaps( GL_TEXTURE_2D, 4,
                  temp->w, temp->h,
                  GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
                  temp->pixels );

或者也许GL_UNSIGNED_INT_8_8_8_8_REV是正确的,我太懒了,无法弄清楚哪一个与你的SDL纹理规格相匹配。或者您可以更改SDL纹理规范。一个类似的格式(实际上GL_BGRA / GL_UNSIGNED_INT_8_8_8_8_REV,我认为,我可能错了)完全匹配一个普遍支持的内部格式,并且略微上传到你的显卡更快,但除非你上传了很多纹理,否则你不会注意到。

作为一种风格说明,通常更倾向于更准确地指定内部格式,如下所示:

gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8, ....