3

ゲームに画像をロードしようとしています。SDL と OpenGL、および SDL_Image フレームワークを使用して、C++ で記述されています。画像を取得し、必要に応じて回転/反転しましたが、主な問題が 2 つあります。

まず、画像の色が完全に反転しています。(つまり、青 -> 赤) ピクセルあたりのバイト数に応じて、「GL_RGB」または「GL_RGBA」のいずれかの形式があります。PNG、JPEG、および BMP を試してみましたが、すべて同じです。道に迷いました! -- 私のばかげた間違いを訂正してくれた datenwolf に感謝します!

次に、画像は 1 回描画されます。それだけです。他のバッファで再描画されることはありません。一度表示されるだけで、次のフレームが描画されるとすぐに消えます。

GLuint loadTexture()
{
SDL_Surface* image = IMG_Load( "/Users/<My name>/Pictures/pacman board.jpeg" );

SDL_DisplayFormatAlpha(image);

unsigned object(0);

glGenTextures(1, &object);

glBindTexture(GL_TEXTURE_2D, object);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


int Mode = NULL;

if(image->format->BytesPerPixel == 3) {Mode = GL_RGB;}
else if(image->format->BytesPerPixel == 4) {Mode = GL_RGBA;}

glTexImage2D(GL_TEXTURE_2D, 0, Mode, image->w, image->h, 0, Mode, GL_UNSIGNED_BYTE, image->pixels);

SDL_FreeSurface(image);
return object;
}

int main(int argc, char * argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

SDL_WM_SetCaption("HI", NULL);
SDL_SetVideoMode(600, 600, 32, SDL_OPENGL);

glClearColor(0,0,0,1);
glViewport(0, 0, 600, 600);

glShadeModel(GL_SMOOTH);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

unsigned int pad_texture = 0;
pad_texture = loadTexture();


//---MAIN LOOP---\\

bool isRunning = true;
SDL_Event event;
while (isRunning)
{
    while (SDL_PollEvent(&event))
    {
        if (event.type == SDL_QUIT) { isRunning = false; }
        if (event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE) {isRunning = false;}   
    }


    glClear(GL_COLOR_BUFFER_BIT);
    gluOrtho2D(0, 600, 0, 600); // For some reason, I prefer having '0,0' at the bottom left.

    glPushMatrix();

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D,pad_texture);

    glBegin(GL_QUADS);

    glTexCoord2d(0, 1); glVertex2f(0, 0);
    glTexCoord2d(1, 1); glVertex2f(600, 0);
    glTexCoord2d(1, 0); glVertex2f(600, 600);
    glTexCoord2d(0, 0); glVertex2f(0, 600);
    glEnd();

    glDisable(GL_TEXTURE_2D);

    glPopMatrix(); //Stop drawing

    SDL_GL_SwapBuffers();   
}
SDL_Quit();    
return 0;
}
4

1 に答える 1

2

ほとんどの画像ファイル形式には、ピクセル データが BGR または BGRA の順序で含まれています。RGB 順序付けを使用してこのような画像データをロードすると、もちろん、青と赤のチャンネルが入れ替わります。

バージョン 1.4 以降、OpenGL はこれらのピクセル形式も提供しています。glext.h新しい形式のトークンにアクセスするには、GLEW などの拡張ラッパーを使用するか、最新のものを取得してインストールする必要があります。OpenGL-3 コア以降でサポートされている形式の完全なリストについては、http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xmlを参照してください。古い OpenGL、つまり OpenGL-1.4 から OpenGL-2.1 については、http: //www.opengl.org/sdk/docs/man2/xhtml/glTexImage2D.xml を参照してください。

アップデート

画像が 1 回しか表示されないのは、次の理由によるものです。

while (isRunning)
{
    /*...*/

    glClear(GL_COLOR_BUFFER_BIT);
    gluOrtho2D(0, 600, 0, 600); // For some reason, I prefer having '0,0' at the bottom left.

gluOrtho2Dすでにマトリックス上にあるものの上に掛けます。これはgluOrtho2D、前の反復で行ったことです。また、マトリックス モードを「ダングリング」状態のままにしました。原則として、各描画反復の開始時に、OpenGL 描画状態全体 (ビューポート、クリア カラー、クリア深度、すべてのマトリックス) を常に新たに設定する必要があります。あなたの場合

while (isRunning)
{
    /*...*/

    glViewport(0, 0, win_width, win_height);

    glClearColor(0,0,0,1);
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, win_width, 0, win_height, -1, 1); // gluOrtho2D is the most useless wrapper ever..., just put a -1, 1 as additional parameters to glOrtho

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glShadeModel(GL_SMOOTH);
于 2013-04-06T16:17:51.393 に答える