0

私のiOS4アプリは、OpenGL ES 2.0を使用し、単一のテクスチャで要素をレンダリングします。複数の異なるテクスチャを使用して要素を描画したいのですが、動作させるのに問題があります。

適用するテクスチャを示すために、頂点シェーダーに変数を追加しました。

...
attribute float TextureIn;
varying float TextureOut;

void main(void)
{ 
    ...
    TextureOut = TextureIn;
}

フラグメントシェーダーでその値を使用して、テクスチャを選択します。

...
varying lowp float TextureOut;

uniform sampler2D Texture0;
uniform sampler2D Texture1;

void main(void)
{   
    if (TextureOut == 1.0) 
    {
        gl_FragColor = texture2D(Texture1, TexCoordOut);
    }
    else // 0
    {
        gl_FragColor = texture2D(Texture0, TexCoordOut);
    }
}

シェーダーをコンパイルします。

...
_texture = glGetAttribLocation(programHandle, "TextureIn");
glEnableVertexAttribArray(_texture);
_textureUniform0 = glGetUniformLocation(programHandle, "Texture0");
_textureUniform1 = glGetUniformLocation(programHandle, "Texture1");

初期化/セットアップ:

...
GLuint _texture;
GLuint _textureUniform0;
GLuint _textureUniform1;

...
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D); // ?
glBindTexture(GL_TEXTURE_2D, _textureUniform0);
glUniform1i(_textureUniform0, 0);

glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D); // ?
glBindTexture(GL_TEXTURE_2D, _textureUniform1);
glUniform1i(_textureUniform1, 1);

glActiveTexture(GL_TEXTURE0);

与える:

...
glVertexAttribPointer(_texture, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 13));    

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _textureUniform0);
glUniform1i(_textureUniform0, 0);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _textureUniform1);
glUniform1i(_textureUniform1, 1);

glActiveTexture(GL_TEXTURE0);

glDrawElements(GL_TRIANGLES, indicesCountA, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * 0));
glDrawElements(GL_TRIANGLES, indicesCountB, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * indicesCountA));
glDrawElements(GL_TRIANGLES, indicesCountC, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * (indicesCountA + indicesCountB)));

私の望みは、頂点に関連付けられたテクスチャを動的に適用することでしたが、GL_TEXTURE0しか認識しないようです。

テクスチャを変更できる唯一の方法は、各テクスチャをGL_TEXTURE0に関連付けてから、次のように描画することです。

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _textureUniformX);
glUniform1i(_textureUniformX, 0);
glDrawElements(GL_TRIANGLES, indicesCountA, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * 0));
...

すべてのテクスチャをレンダリングするには、テクスチャごとに個別のglDrawElements()呼び出しが必要です。また、glDrawElements()呼び出しはパフォーマンスに大きな影響を与え、呼び出しの数を最小限に抑える必要があることを読みました。そのため、各頂点に使用するテクスチャを動的に指定しようとしました。

私の理解が間違っているか、重要な何かを見逃している可能性があります。私はまだOpenGLに慣れていないので、学べば学ぶほど、学ぶべきことがたくさんあると感じます。

GL_TEXTURE0以外のテクスチャも使用できるはずですが、その方法はまだわかりません。

任意のガイダンスまたは指示をいただければ幸いです。

4

1 に答える 1

2

浮動小数点の丸めの問題が発生しているだけでしょうか?存在するべきではありませんが(単一のprivimitveが異なるテクスチャの頂点を共有する場合を除く)、これTextureOut == 1.0をaTextureOut > 0.5などに置き換えてください。

一般的なアドバイスとして、ドローコールの数を可能な限り減らす必要があるという点で正しいですが、あなたのアプローチはかなり奇妙です。フラグメントシェーダーブランチを使用したドローコールリダクションを購入しています。また、すべてのテクスチャを別々のテクスチャユニットで常に必要とするため、このアプローチはテクスチャの総数に合わせて適切にスケーリングすることはできません。

テクスチャスイッチを減らす通常のアプローチは、すべてのテクスチャを単一の大きなテクスチャ、いわゆるテクスチャアトラスに配置し、テクスチャ座標を使用してこのテクスチャの適切なサブ領域を選択することです。これにもいくつかの落とし穴がありますが(これはまったく別の質問です)、無料で提供されるものはありません。

編集:ああ待って、私はあなたが実際に間違っていることを見る

glBindTexture(GL_TEXTURE_2D, _textureUniform0);

テクスチャを現在のテクスチャユニットにバインドしていますが、テクスチャオブジェクトの代わりに、この関数に均一な場所を指定します。これは完全なゴミです(ただし、均一な場所とテクスチャオブジェクトの両方がそれ自体であるため、奇妙な状況でも機能する可能性があります)整数)。もちろん、実際のテクスチャをバインドする必要があります。

于 2012-09-18T08:28:41.900 に答える