3

コードを投稿する前に、次のことを説明します。現在、iPhoneプラットフォームでOpenGL ES 2.0を学習しており、プログラムを毎回コンパイルできますが、正しく実行される場合があります。これは、頂点シェーダーとフラグメントシェーダー、および単一の三角形を備えた非常にシンプルなプログラムです。

何らかの理由で、頂点シェーダーの特定の属性名のみが機能します。たとえばattribute vec4 v_Color、プログラムを使用すると問題なく実行されますが、大文字の「C」なしで使用すると、名前パラメータを属性と完全に一致attribute vec4 v_colorさせても、位置属性が色属性に再割り当てされ、その逆も同様です。名前。動作しないもう1つの方法は、何らかの理由で正常に動作することです。「バー」のようなランダムな単語を使ってみましたが、うまくいきませんでした。頂点シェーダーの名前をで指定した名前と一致させていることに注意してください。glBindAttribLocation()vColora_colorglBindAttribLocation()

特定の名前だけが機能する可能性は低いようです。(プログラマーに柔軟性を与えるためのジェネリック属性の要点ではありませんか?)名前を変更するだけなので、頂点シェーダーをプログラムに読み込む方法に何か問題があるのではないかと思います。そもそも; 間違ったタイプのエンコーディングを使用している可能性があります。多分それはそれを読み間違え、それ自身でそれを理解しようとします、それで私がそれを持っている明示的な名前を無視してそれらを再割り当てします。

頂点シェーダーを読み取るために使用しているコードは次のとおりです。

NSError *error;
NSString *vertPath = [[NSBundle mainBundle] pathForResource:@"Simple" ofType:@"vert"];
NSString *vertShaderString = [NSString stringWithContentsOfFile:vertPath encoding:NSUTF8StringEncoding error:&error];
const GLchar *vertShaderText = [vertShaderString UTF8String];

if (!vertShaderString) {
    NSLog(@"%@", [error localizedDescription]);
}

vertShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertShader, 1, &vertShaderText, NULL);

glCompileShader(vertShader);
glGetShaderiv(vertShader, GL_COMPILE_STATUS, &vertCompiled);
if (!vertCompiled) {

    NSLog(@"Vert shader not compiled.");
}

glAttachShader(prog, vertShader);

次に、描画呼び出しを行うために実際に使用しているコード:

GLfloat vertices[] = { 0.0, 0.0, 0.0, 0.5, 0.5, 0.5 };
GLubyte indices[3] = { 0, 1, 2 };

// Position vertex attribute data
glEnableVertexAttribArray(0);
glBindAttribLocation(prog, 0, "a_position");
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);


// Color vertex attribute data
GLfloat vColors[] = {
    1.0, 0.0, 0.0, 1.0,
    0.0, 1.0, 0.0, 1.0,
    0.0, 0.0, 1.0, 1.0 };

glEnableVertexAttribArray(1);
glBindAttribLocation(prog, 1, "a_color");
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, vColors);


glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(GLubyte), GL_UNSIGNED_BYTE, indices);

最後に、かなり些細な頂点シェーダー(非常に基本的なため、フラグメントシェーダーを含める必要はありません):

attribute vec4 a_position;
attribute vec4 a_color;

varying vec4 varColor;

void main() {

gl_Position = a_position;
varColor = a_color;
}

上記のコードは実際には問題なく機能しますが、に変更a_colorするv_colorと、位置データと色データが突然切り替わるため、三角形の形状が変化し、色がすべて間違っています。これはもちろん望ましくありません。それは非常に奇妙な問題です。これが私のObjective-C実装または私のOpenGLES2.0実装の問題だと思いますか?

御時間ありがとうございます!

4

1 に答える 1

4

呼び出しglBindAttribLocationは、次にプログラムがにリンクされたときにのみ有効になりglLinkProgramます。ここで行うように呼び出しても何も起こらないため、コンパイラが思いついた乱数に変数が割り当てられます。

リンクする前に呼び出したくない場合は、glGetAttribLocation代わりにここを使用して、OpenGLが各属性に割り当てた値を照会する別のオプション。getただし、すべてのフレームで呼び出さないように、値をキャッシュしてみてください。

于 2012-09-23T14:46:12.433 に答える