2

Qtを使用してOpenGLの頂点バッファオブジェクトを使用して四角形を描画しようとしています。これが私のジオメトリです:

numVertices = 4;
vertices = new float[3*numVertices];
int i = 0;
vertices[i++] = 0.0f; vertices[i++] = 0.0f; vertices[i++] = 0.0f; // (0,0,0)
vertices[i++] = 1.0f; vertices[i++] = 0.0f; vertices[i++] = 0.0f; // (1,0,0)
vertices[i++] = 1.0f; vertices[i++] = 1.0f; vertices[i++] = 0.0f; // (1,1,0)
vertices[i++] = 0.0f; vertices[i++] = 1.0f; vertices[i++] = 0.0f; // (0,1,0)
i = 0;
// spilt quad into two triangles:
numTriangles = 2;
indices = new unsigned int[numTriangles*3];
indices[i++] = 0; indices[i++] = 1; indices[i++] = 2; 
indices[i++] = 0; indices[i++] = 2; indices[i++] = 3;

次のinitializeGLメソッド:

QGLBuffer vertexBuffer;
vertexBuffer.create();
vertexBuffer.bind();
vertexBuffer.allocate(vertices, numVertices*sizeof(float));

QGLShaderProgram* shaderProgram_ = new QGLShaderProgram;
shaderProgram_->addShaderFromSourceFile(QGLShader::Vertex,"C:/src/light.vert.glsl") ) {
shaderProgram_->addShaderFromSourceFile(QGLShader::Fragment, "C:/src/light.frag.glsl");
bool ok = shaderProgram_->link();
ok = shaderProgram_->bind();

VBOの部分は、頂点をGPUにコピーすることだけだと思いますか?(なぜそんなに多くの行?)

シェーダー部分は、古いスタイルのglBegin(GL_QUADS);で正常に機能しました。

次の私のpaintGLメソッドで:

shaderProgram_->setAttributeBuffer("vertex", GL_FLOAT, 0, 3, 0);
shaderProgram_->enableAttributeArray("vertex");
glDrawElements(GL_TRIANGLES, numTriangles, GL_UNSIGNED_INT, indices);

最初の2行は何をしていますか?タイプGL_FLOATの「vertex」という名前の頂点バッファがあることをシェーダーに伝えているのではないでしょうか。しかし、VBOを作成するときに名前を指定しませんでした!?OpenGLは、これが「頂点」であることをどのように認識しますか?

とにかく私は何も縫っていません!?足りないステップはありますか?私のシェーダーは単純なパストラフです。

# version 120  
varying vec4 color;
void main() {
    vec4 vertex = gl_Vertex;
    // pass trough:
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vertex; 
    color = gl_Color; 
}

# version 120 
varying vec4 color;
void main (void) 
{   
    // pass-trough:    
 gl_FragColor = color;
 }
4

1 に答える 1

2

私はあなたがここで3を失ったと思います:

vertexBuffer.allocate(vertices, numVertices*sizeof(float));

->

vertexBuffer.allocate(vertices, numVertices*sizeof(float)*3);

VBOの部分は頂点をGPUにコピーするだけだと思いますか? (なんでこんなに行列?)

はい。それがOpenGLの仕組みです。VBO に何かを保存するには、それを作成し、バインドして、データをコピーする必要があります。

最初の 2 行は何をしているのですか? GL_FLOAT 型の「頂点」という名前の頂点バッファーがあることをシェーダーに伝えているのでしょうか。しかし、VBO を作成するときに名前を指定しませんでした!? OpenGLはこれが「頂点」であることをどのように認識していますか?

最初の行:

QGLShaderProgram::setAttributeBuffer()「現在バインドされている頂点バッファーの特定のオフセットから始まる、このシェーダー プログラムの name と呼ばれる属性に頂点値の配列を設定します。」- マニュアルから。繰り返しますが、これが OpenGL の仕組みです。ステートマシンです。特定のバッファを GL_ARRAY_BUFFER バインディング ポイントにバインドし、次にこれが「頂点」属性データが格納されるバッファであることを OpenGL に伝えます。「頂点」は、シェーダー プログラムにある属性名です。(「gl_Vertex」に変更する必要があるかもしれません)推測すると、QtはglVertexAttribLocation()属性の場所を見つけて、次の呼び出しを呼び出しますglVertexAttribPointer()

二行目:

OpenGL は、シェーダー プログラムがデータを見つけられる特別な場所に、あるバッファーからデータをコピーする必要があることを認識している必要があります。これは、特定の場所の属性配列を有効にすることによって行われます。推測すると、Qt はここで呼び出しglVertexAttribLocation()ますglEnableAttribArray()

ところで:コードでモデルビューと射影行列を指定していますか? デフォルトで設定されているかどうかはわかりません。テスト目的で、これらの値をシェーダーから削除してみてください。

追加した:

glDrawElements(GL_TRIANGLES, numTriangles, GL_UNSIGNED_INT, indices);

2 番目のパラメーターは三角形の数ではなく、インデックス配列から読み取られるインデックスの数です。ここにあるはずですnumTriangles*3

于 2012-12-15T16:49:48.680 に答える