6

私はこのコードでOpenGLで飛行機を作成しました:

glBegin(GL_TRIANGLE_STRIP);
glColor4f(0.8, 0.8, 0.5, 1.0);
glVertex3f(startlen, height, startwid);    
glVertex3f(startlen, height, startwid + width);
glVertex3f(startlen + length, height, startwid);
glVertex3f(startlen + length, height, startwid + width);
glEnd();

次に、この平面にテクスチャを適用します。

ここでこのチュートリアルを読みましたが、UV座標がないため、「OpenGLでのテクスチャの使用」の部分にとどまりました。

テクスチャファイル(私の場合はビットマップファイル)をインポートする必要があることはわかっています。
ローダーは、textureIDであるGlintを返しますが、それはグローバルですか?たとえば、そのテクスチャをロードする必要がある場合は、指定されたIDを使用してbindtexture関数を呼び出す必要がありますか?

とにかく、どのようにテクスチャを平面に適用できますか?


編集#1: 投稿された蚊の例のテクスチャが機能するようになりました。
私が見つけたのは、テクスチャをクラスのコンストラクターにロードしていることでしたが、オブジェクトがパブリックであり、OpenGLの初期化の前に構築されたため、ロードすべきではありませんでした。
したがって、クワッドの例ではテクスチャが正常に読み込まれるようになりました:)

今の問題は、飛行機で使用しようとしたところ、歪んで見えることです。これに対する解決策は、おそらくテクスチャを数回ロードできるようにすることですが、元のサイズを維持します(これを行う方法はわかりませんが)

また、現在の飛行機の隣にクリーム色の別の飛行機を作成しましたが、テクスチャリング後は次のようになります。 ここに画像の説明を入力してください

したがって、現在2つの問題があります。

  • テクスチャは元の解像度を維持する必要がありますが、平面全体をカバーする回数だけ表示されます
  • その隣の平面は色を失いました(なぜこれが起こったのですか?それを修正する方法は?-この平面にもテクスチャを使用するかもしれません)

編集#2:

蚊のおかげで、2番目の問題が修正されました!しかし、タイリングはまだ機能しません。これが今の様子です: ここに画像の説明を入力してください

そして、これは私が使用したテクスチャです:
ここに画像の説明を入力してください
その寸法は256x256です(私はそれをトリミングするために画像エディタを使用しました)


編集#3:
これらは(内側のマージンの)一致する頂点を持つglTexCoord2f座標です:

glTexCoord2f(0.0f, 0.0f);   glVertex3f(startlen, height, startwid);
glTexCoord2f(0.0f, 1.0f);   glVertex3f(startlen, height, startwid - width/2);
glTexCoord2f(1.0f, 0.0f);   glVertex3f(startlen + length, height, startwid);
glTexCoord2f(1.0f, 1.0f);   glVertex3f(startlen + length, height, startwid - width/2);
4

2 に答える 2

11

textureIDを返すローダーがある場合は、画像データの読み込み、プロパティの設定、さらに使用するための実際のテクスチャとしての保存がすでに行われている可能性があります。それでは、テクスチャをテクスチャリングターゲットにバインドすることに移ります。

このIDをお持ちの場合は、基本的にglBindTexture()、三角ストリップを描画する前に関数を呼び出す必要があります。

glBindTexture(GL_TEXTURE_2D, id); // where id is GLuint returned by your loader

ここで、描画する頂点ごとに、それらの頂点のテクスチャの座標も指定する必要があります。そのためには、glTexCoord2f()関数を使用します。単純なクワッドの場合、次のようになります。

glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(0.0f, 1.0f);                   
    glVertex2i(0.0f, 10.0f);

    // Top left
    glTexCoord2f(0.0f, 0.0f);
    glVertex2i(0.0f, 0.0f);

    // Top right
    glTexCoord2f(1.0f, 0.0f);
    glVertex2i(10.0f, 0.0f);

    // Bottom right
    glTexCoord2f(1.0f, 1.0f);
    glVertex2i(10.0f, 10.0f);
glEnd();

ご覧のとおり、各頂点にはテクスチャ「ポイント」がアタッチされています。テクスチャの表示方法をOpenGLに指示します。

ここで、頂点の適切な座標を指定することにより、テクスチャを平面上にどのように分散させるかを選択するのはあなた次第です。

覚えておく必要があるのは、テクスチャ座標は0.0で始まり、1.0で終わるということです。この値を1.0以上に増やすと、テクスチャの設定(タイリングなど)に応じた動作になります。

チュートリアルでは、テクスチャ座標が0.0から1.0の範囲であり、特定の頂点にどのテクスチャ座標が設定されているかを示す非常に優れた画像があります。

ここに画像の説明を入力してください

PS。テクスチャを表示するには、最初に次のコマンドを呼び出してこの機能を有効にする必要があります。

glEnable(GL_TEXTURE_2D);

テクスチャを使用してオブジェクトを描画するたびに呼び出す必要はありません。絵を描く前に一度だけ呼ばれることもあります。


編集

  1. 次の問題によると、必要なのはタイリング効果を実現することです。これは、テクスチャの作成中に簡単に実行できます。ローダーで、この行の後:

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    次のテクスチャパラメータを次のように設定する必要があります。

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

    この場合GL_REPEAT、座標が1.0より大きい場合は常に、テクスチャを繰り返すために使用されます。たとえば、テクスチャ座標を2.0に指定した場合、1.0を指定した場合と同じになります。

  2. 2番目の問題は、テクスチャがまだバインドされていて、テクスチャリングが有効になっているために存在します(使用したことを思い出してください glEnable(GL_TEXTURE_2D);)。したがって、基本的に、現在描画するすべてのものがテクスチャで覆われます。

    ただし、テクスチャリングせずに何かを描画したい場合は、基本的に、2番目の平面を描画する前にテクスチャリングを無効にし、描画後に再度有効にする必要があります。

    glDisable(GL_TEXTURE_2D);
       // Draw your second plane here
    glEnable(GL_TEXTURE_2D);
    

EDIT2

さて、あなたは私を少し誤解したと思います。この場合、テクスチャの終わりである最大1.0までテクスチャ座標を指定するため、タイリングは機能しません。私が言っていることをあなたに示すことができる画像を用意しました:

ここに画像の説明を入力してください

真ん中の赤い色の写真では、テクスチャ座標との頂点座標をマークしました。

したがって、基本的に、現在のようにテクスチャ座標を設定すると(最大1.0)、テクスチャを平面の周りに引き伸ばすことができます。ここで、この平面が非常に大きいと想像してください。テクスチャの解像度が低い場合は、醜いストレッチ効果しか発生しません。

タイリング効果を得るには、私の例のように1.0より高い値を設定する必要があります。2.0ではテクスチャが2回繰り返されます。

テクスチャを平面上で「見栄えよく」見せるための魔法の方法はないため、それを実現するには数学を使用する必要があります。今、これはあなたに任せます。

于 2013-02-06T23:06:10.803 に答える
1

すべての頂点にUV座標を指定する必要があります。これはglTexCoord2f();
、関数が2つの引数を取る関数を使用して行います。最初の引数は、u、もう1つは、vです。描画コードは次のようになります。

glBegin(GL_TRIANGLE_STRIP);
glColor4f(0.8, 0.8, 0.5, 1.0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(startlen, height, startwid);
glTexCoord2f(0.0f, 1.0f); glVertex3f(startlen, height, startwid + width);
glTexCoord2f(1.0f, 1.0f); glVertex3f(startlen + length, height, startwid);
glTexCoord2f(1.0f, 0.0f); glVertex3f(startlen + length, height, startwid + width);
glEnd();

あなたはそれらを少し切り替えるかもしれません、私はあなたがあなたのテクスチャをそれにどのようにマッピングしたいかわかりません。0.0 =左、1.0 =右のテクスチャでは、uをxとして表示できます。また、0.0 =上、1.0 =下のテクスチャでは、vをyとして表示できます。
ここで、必要なものがさらにいくつかあります。まず、テクスチャリングを有効にする必要があります。

glEnable(GL_TEXTURE_2D); //call this once, during initialization

すでに述べたように、テクスチャをロードする必要があります。

glGenTextures(1, &MyTexture);
glBindTexture(GL_TEXTURE_2D, MyTexture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //data is a gluByte array of your image data

そして、クワッドを描画する前にバインドする必要があります。

glBindTexture(GL_TEXTURE_2D, MyTexture);

テクスチャの実際のロードはあなたに任せます。これはまったく別の質問であり、ここで議論するのは広範囲にわたるためです。

于 2013-02-06T23:12:24.060 に答える