問題は、別のオブジェクトが描画されていないため、2つのオブジェクトを適切に描画する方法を理解できないことです。
ここにメインコードがあります:
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
GLuint VertexArrayID2;
glGenVertexArrays(1, &VertexArrayID2);
glBindVertexArray(VertexArrayID2);
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
GLuint MatrixID2 = glGetUniformLocation(programID, "MVP2");
glm::mat4 Projection = glm::perspective(45.0f, 5.0f / 4.0f, 0.1f, 100.0f);
glm::mat4 View = glm::lookAt(
glm::vec3(4*2,3*2,8*2),
glm::vec3(0,0,0),
glm::vec3(0,1,0)
);
glm::mat4 Model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
glm::mat4 MVP = Projection * View * Model;
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glm::mat4 Model2 = glm::translate(glm::mat4(1.0f), glm::vec3(-5.0f, 0.0f, 0.0f));
glm::mat4 MVP2 = Projection * View * Model2;
glUniformMatrix4fv(MatrixID2, 1, GL_FALSE, &MVP2[0][0]);
static const GLfloat g_vertex_buffer_data[] = {
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f, 1.0f,
(plenty of floats)
1.0f,-1.0f, 1.0f
};
static const GLfloat g_vertex_buffer_data2[] = {
-1.0f, -1.0f, 3.0f,
(plenty of floats)
0.0f, 1.0f, 2.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint vertexbuffer2;
glGenBuffers(1, &vertexbuffer2);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data2), g_vertex_buffer_data2, GL_STATIC_DRAW);
do{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(MatrixID2, 1, GL_FALSE, &MVP2[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES, 0, 12*3);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES, 0, 4*3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(2);
glfwSwapBuffers(window);
glfwPollEvents();
}
そしてシェーダー:
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 2) in vec3 vertexPosition_modelspace2;
uniform mat4 MVP;
uniform mat4 MVP2;
void main(){
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
gl_Position = MVP2 * vec4(vertexPosition_modelspace2,1);
}
最後のオブジェクトのみが描画されていることに気付いたので、問題は「gl_Position」がその値を上書きすることですが、どのようにそれを理解する必要がありますか?
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
gl_Position = MVP2 * vec4(vertexPosition_modelspace2,1);
それはグラフィックスパイプラインの動作方法ではありません。 できない同時に2つのオブジェクトを描画します。 gl_Position
への最後の書き込みだけが有効になり、最初のオブジェクトは完全に無視されます。最も基本的なバリアントでは、2つの完全に独立したオブジェクトを描画する必要があり、コードで行うように、2つの描画呼び出しが必要になります。
ただし、その場合、2つの異なる頂点属性は必要ありません。シェーダーは頂点を処理するだけです。頂点には、verexPosition_modelspace
属性しかありません。したがって、描画するすべてのオブジェクトにその属性を使用できます。属性が同じことを意味する場合は、オブジェクトごとに異なる属性を使用しても意味がありません。
描画コードを見てみましょう:
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
ここでは、最初のバッファーの頂点データを指すように頂点属性0を設定し、属性配列を有効にします。したがって、データはvertexPosition_modelspace
のソースとして使用されません。
glDrawArrays(GL_TRIANGLES, 0, 12*3);
次に、オブジェクトを描画します。ただし、すでに説明したように、実際のシェーダーは実際にvertexPosition_modelspace2
のみを使用します。これは、ポインターを設定していないか、配列を有効にしていないためです。配列が無効になっているため、GLはすべての頂点に対して属性2の現在の値を使用します。したがって、三角形の場合、すべての点が同じである三角形を作成します-表面積が0であり、属性2の現在の実際の値に関係なく、とにかく見えません。
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
ここで奇妙なことを行います。属性2の配列を有効にしますが、そのためのポインターを設定しないでください。 2番目のモデルを指すように、属性0のポインターを再指定する必要があります。
glDrawArrays(GL_TRIANGLES, 0, 4*3);
次に、属性0と2の両方を有効にして描画します。属性0には必要なデータが含まれますが、シェーダーでは無視されます。属性2はどこかを指しているだけであり、定義されていない動作が発生します-クラッシュするだけかもしれませんが、奇妙なものを表示したり、まったく表示しないこともあります。
これを機能させるには、シェーダーからvertexPosition_modelspace2
を完全に削除します。 MVP
行列も1つだけ使用します。オブジェクトを描画するときは、次のことを行う必要があります。
MVP
均一行列を設定しますこれは、必要な数のオブジェクトで実行できます。