我目前正在开发一个非常简单的游戏,使用纯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)我真的很感激。
答案 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, ....