1

面ごとに異なるテクスチャを持つ 1 つの立方体を描画しようとしています。display()を呼び出す前に、ルーチンですべてのテクスチャ ユニットを有効にする必要があると述べている多くのチュートリアルに出くわしましたglDrawElements()。私はこれを私の使命としています:

gl.glClientActiveTexture(GL.GL_TEXTURE0);
gl.glBindTexture(GL.GL_TEXTURE_2D, textureId);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject());
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);

gl.glClientActiveTexture(GL.GL_TEXTURE1);
gl.glBindTexture(GL.GL_TEXTURE_2D, textureId+1);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject());
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);

...

gl.glClientActiveTexture(GL.GL_TEXTURE5);
gl.glBindTexture(GL.GL_TEXTURE_2D, textureId+5);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject());
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);

これはすべて私にとって理にかなっています。ただし、バッファにデータを入力するとき (たとえば、モデル データをロードするとき) にどのテクスチャを参照しているかを判断する方法は異なります。ありがとうクリス

4

3 に答える 3

2

あなたが探しているのはキューブマップです。OpenGL では、一度に 6 つのテクスチャ (立方体の側面のサイズを表す) を定義し、一般的な 2D テクスチャ座標の代わりに 3D テクスチャ座標を使用してそれらをマッピングできます。単純な立方体の場合、テクスチャ座標は頂点のそれぞれの法線と同じになります。(この方法でプレーン キューブのみをテクスチャリングする場合は、頂点シェーダーで法線とテクスチャ座標を統合することもできます!) キューブ マップは、現在行っている方法で 6 つの異なるテクスチャを同時にバインドしようとするよりもはるかに簡単です。

GLuint mHandle;
glGenTextures(1, &mHandle); // create your texture normally

// Note the target being used instead of GL_TEXTURE_2D!
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glBindTexture(GL_TEXTURE_CUBE_MAP, mHandle);

// Now, load in your six distinct images. They need to be the same dimensions!
// Notice the targets being specified: the six sides of the cube map.
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data1);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data3);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data4);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data5);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, width, height, 0,
    format, GL_UNSIGNED_BYTE, data6);

glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

// And of course, after you are all done using the textures...
glDeleteTextures(1, &mHandle);

現在、シェーダーを実行するときは、頂点シェーダーが 2D 座標 (vec2) ではなく 3D 座標 (vec3) を受け入れたり渡したりする必要があります。

// old GLSL style
attribute vec3 inTextureCoordinate;
varying vec3 vTextureCoordinate;

// more recent GLSL
in vec3 inTextureCoordinate;
out vec3 vTextureCoordinate;

この例では、頂点シェーダーは単純に vTextureCoordinate = inTextureCoordinate を割り当てます。フラグメント シェーダーは、そのテクスチャ座標を受け入れ、キューブ マップを均一にサンプリングする必要があります。

uniform samplerCube cubeMap;
...
gl_FragColor = textureCube(cubeMap, vTextureCoordinate);

うわー!それはたくさんありました。私は何かを残しましたか?

于 2011-02-07T18:14:41.187 に答える
1

ただし、バッファにデータを入力するとき (たとえば、モデル データをロードするとき) にどのテクスチャを参照しているかを判断する方法は異なります。

最新の ActiveTexture 呼び出しで最後に指定したテクスチャを参照しています。その呼び出しは実際には何もしません。テクスチャで何かを行う後続のすべての呼び出しに影響する非表示の状態を設定するだけです。

于 2011-02-07T17:25:58.117 に答える
0

面ごとにテクスチャを選択することは、通常、openGL では困難です (たとえば、EXT_texture_array を使用して、テクスチャの配列にインデックスを付けることができる最近の一部のカードを除きます)。この問題は通常、こののようにすべてのテクスチャを 1 つにまとめることで回避されます。

ただし、非常に具体的なケースでは、キューブマップは完璧です-キューブだけがあり、他に何もないと本当に確信している場合。

于 2011-02-09T13:39:54.640 に答える