1

私は現在 OpenGL 2.0 を学習しており、基本的な iPhone アプリを作成しています。Blender でモデルを作成し、それを .obj ファイルにエクスポートして、座標を取り込むパーサーを作成しました。形状は正常に表示されますが、色はありません (黒)。これは、法線に問題があることを意味します。しかし、法線をチェックしたところ、それらに問題があることがわかりました。私のコードに欠けているものはありますか?

これを手伝ってくれてとても感謝しています!

スクリーンショット

ここに画像の説明を入力

ここに私のOpenGLコードがあります

glEnable(GL_DEPTH_TEST);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);


glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, loader.currentCountOfVerticies * sizeof(GLfloat) * 3, arrayOfVerticies, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 12, BUFFER_OFFSET(0));

glGenVertexArraysOES(1, &_normalArray);
glBindVertexArrayOES(_normalArray);

glGenBuffers(1, &_normalBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _normalBuffer);
glBufferData(GLKVertexAttribNormal, loader.currentCountOfNormals  * sizeof(GLfloat) * 3,loader.arrayOfNormals , GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 12, BUFFER_OFFSET(0));

glGenVertexArraysOES(1, &_textureArray);
glBindVertexArrayOES(_textureArray);

glGenBuffers(1, &_textureBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _textureBuffer);
glBufferData(GL_ARRAY_BUFFER, loader.currentCountOfTextureCoordinates * sizeof(GLfloat) * 2, loader.arrayOftextureCoOrdinates, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 8, BUFFER_OFFSET(0));


glBindVertexArrayOES(0);

そして私のDrawRect方法

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArrayOES(_vertexArray); 

    glUseProgram(_program);

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

    #ifdef DEBUG_VERTEX_DATA_LOOP
    NSLog(@"size of c array * type %ld", loader.currentCountOfVerticies *sizeof(GLfloat));
    #endif

    //Takes in the ammout of indicies not triangels!
    glDrawArrays(GL_TRIANGLES, 0, loader.currentCountOfVerticies);
}

ロード シェーダー メソッドからのコード

glBindAttribLocation(_program, GLKVertexAttribPosition, "position");  
glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
glBindAttribLocation(_program, GLKVertexAttribTexCoord0, "TextCo");

頂点シェーダー

//  Created by Jake Cunningham on 13/10/2012.
//  Copyright (c) 2012 Jake Cunningham. All rights reserved.
//

attribute vec4 position;
attribute vec3 normal;

varying lowp vec4 colorVarying;

uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;

attribute vec2 TextCo;
varying vec2 textCoOut;

void main()
{
    vec3 eyeNormal = normalize(normalMatrix * normal);
    vec3 lightPosition = vec3(0.0, 0.0, 1.0);
    vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0);

    float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));

    colorVarying = diffuseColor * nDotVP;

    gl_Position = modelViewProjectionMatrix * position;
    textCoOut = TextCo;
}

フラグメントシェーダー

//
//  Created by Jake Cunningham on 13/10/2012.
//  Copyright (c) 2012 Jake Cunningham. All rights reserved.
//

varying lowp vec4 colorVarying;

varying lowp vec2 textCoOut;
uniform sampler2D texture;

void main()
{
    gl_FragColor = colorVarying * texture2D(texture, textCoOut);
}
4

3 に答える 3

2

テクスチャリングとは別にライティングを最初にテストすることをお勧めします。フラグメント シェーダーの乗算は、テクセルが黒の場合 (テクスチャの読み込みに失敗した場合やその他のテクスチャリングの問題がある場合に発生する可能性が高い)、照明コードの出力が表示されないことを意味します。

于 2013-01-01T20:18:37.300 に答える
0

私は問題を解決しましたが、私はまだ何が問題だったのか確信が持てないことを告白しなければなりません. コードを上記から次のように変更しました

glEnable(GL_DEPTH_TEST);

glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, total * sizeof(GLfloat), mergedArray, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

glBindVertexArrayOES(0);

頂点と法線の両方の配列を単一のバッファにマージすると、問題が解決しました。照明が付くようになりました。なぜ 2 つのバッファーを使用できなかったのか わかりません 誰かが私ができない何かを見つけることができれば、フィードバックをいただければ幸いです。

GCの皆様ありがとうございました

于 2013-01-02T12:30:53.203 に答える
0

問題は、複数の頂点配列オブジェクトの使用です。頂点配列オブジェクト (VAO) は軽量オブジェクト (実際の頂点属性データを含まないことを意味します) であり、1 回の描画呼び出しで多数の頂点配列をレンダリングするために必要なすべての状態をカプセル化します。特に:

  • glVertexAttribPointer各属性インデックスの設定
  • 有効な属性配列
  • バインドされた要素配列バッファー

したがって、これは個々の頂点属性配列よりも 1 レベル高く、単一の (概念的な) シーン オブジェクト、またはより正確には単一の描画呼び出しのすべての頂点属性配列設定を構成します。

ただし、コードでは、個々の属性ごとに新しい頂点配列オブジェクトを作成します。次にレンダリングするときは_vertexArray、属性を設定して有効にするだけのバインドのみを行うGLKVertexAttribPositionため、法線や texCoords などはありません。

したがって、元のコードを次のように置き換える必要があります。

glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, loader.currentCountOfVerticies * sizeof(GLfloat) * 3, arrayOfVerticies, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 12, BUFFER_OFFSET(0));

//forget this
//glGenVertexArraysOES(1, &_normalArray);
//glBindVertexArrayOES(_normalArray);

glGenBuffers(1, &_normalBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _normalBuffer);
glBufferData(GLKVertexAttribNormal, loader.currentCountOfNormals  * sizeof(GLfloat) * 3,loader.arrayOfNormals , GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 12, BUFFER_OFFSET(0));

//and this, too
//glGenVertexArraysOES(1, &_textureArray);
//glBindVertexArrayOES(_textureArray);

glGenBuffers(1, &_textureBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _textureBuffer);
glBufferData(GL_ARRAY_BUFFER, loader.currentCountOfTextureCoordinates * sizeof(GLfloat) * 2, loader.arrayOftextureCoOrdinates, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 8, BUFFER_OFFSET(0));

glBindVertexArrayOES(0);
于 2013-01-02T13:15:34.233 に答える