1

グラフィックに OpenGL を使用して C++ で簡単なゲームをプログラミングしようとしています。私のゲームでは、画面上に白い正方形としてレンダリングされるオブジェクトがあります。白い正方形の代わりに画面上に画像をレンダリングできるように、画像をテクスチャとしてこれらのオブジェクトにバインドできるようにしたいと考えています。テスト用に .png または .bmp を使用していますが、画像の形式に制限はありません。

私のオブジェクト クラスの 1 つである Character.h は、_texture という名前の GLuint* メンバー変数と _data という名前の unsigned char* メンバー変数を (それぞれイメージ ハンドルとピクセル データとして) 格納します。Character.h 内には、画像をテクスチャとして Character オブジェクトにバインドするための関数があります。

void loadTexture(const char* fileName)
    {
        /* read pixel data */
        FILE* file;
        file = fopen(fileName, "rb");
        if (file == NULL) {cout << "ERROR: Image file not found!" << endl;}
        _data = (unsigned char*)malloc(_dimension * _dimension * 3);
        fread(_data, _dimension * _dimension * 3, 1, file);
        fclose(file);
        /* bind texture */
        glGenTextures(1, &_texture); // _texture is a member variable of type GLuint
        glBindTexture(GL_TEXTURE_2D, _texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _dimension, _dimension, 0, GL_RGB, GL_UNSIGNED_BYTE, _data); // _dimension = 64.0f.
    }

画像がバインドされたら、この関数 (別のクラスにある静的関数) を使用して Character オブジェクトをレンダリングしようとします。

static void drawTexturedRectangle(float x, float y, float w, float h, GLuint texture, unsigned char* data)
    {
        /* fractions are calculated to determine the position onscreen that the object is drawn at */
        float xFraction = (x / GlobalConstants::SCREEN_WIDTH) * 2;
        float yFraction = (y / GlobalConstants::SCREEN_HEIGHT) * 2;
        float wFraction = (w / GlobalConstants::SCREEN_WIDTH) * 2;
        float hFraction = (h / GlobalConstants::SCREEN_HEIGHT) * 2;
        glEnable(GL_TEXTURE_2D);
        glClear(GL_COLOR_BUFFER_BIT);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glPushMatrix();
        glEnable(GL_BLEND);
        glBegin(GL_QUADS);
        glTexCoord2f(0.0f, 0.0f); glVertex2f(xFraction, yFraction); // bottom left corner
        glTexCoord2f(0.0f, 1.0f); glVertex2f(xFraction, yFraction + hFraction); // top left corner
        glTexCoord2f(1.0f, 1.0f); glVertex2f(xFraction + wFraction, yFraction + hFraction); // top right corner
        glTexCoord2f(1.0f, 0.0f); glVertex2f(xFraction + wFraction, yFraction); // bottom right corner
        glEnd();
        glDisable(GL_BLEND);
        glPopMatrix();
    }

これをどれだけいじっても、テクスチャのない真っ白な正方形をレンダリングする以外に、プログラムに何かをさせることはできないようです。変数ファイル、_texture、_dimension、_data のすべてに値が含まれていることを確認しました。誰かが私が間違っているかもしれないことを見つけることができますか?

4

1 に答える 1

1

生のファイルをglTexImage2Dに入力できるとは思いませんが、テクスチャファイルをその形式で保存する場合を除きます(おそらくそうではありません)。glTexImage2D は巨大な配列バイト (テクセルの色を表す) を想定していますが、通常、ファイル形式はそのような画像を保存しません。bmp にもいくつかのヘッダー情報が含まれています。

DevIL や SOIL などのサードパーティのイメージ ローダー ライブラリを使用して、テクスチャをロードしてください。これらのライブラリは、最も一般的な画像ファイル形式 (png、jpg、tga など) を、OpenGL に入力できるバイト ストリームに変換できます。

補足: glTexImage2D(..., data) を呼び出した後、データの内容が GPU メモリ (VRAM) にコピーされます。この時点から、テクスチャはすでに VRAM にあるため、id を使用してテクスチャをバインドするだけで済みます。各フレームで glTexImage2D() を呼び出すと、各フレームのテクスチャ全体が vram に再アップロードされ、パフォーマンスが大幅に低下します。

于 2015-06-15T09:19:14.853 に答える