2016-08-30 4 views
1

OpenGL、GLEW、およびGLFWを使用して同じメッシュの複数の画像を撮ります。メッシュ(三角形)は各ショットで変更されず、ModelViewMatrixのみが変更されます。重複した三角形の転送がない同じメッシュの複数の画像

はここに私のメインループの重要なコードです:あなたが見ることができるように

for (int i = 0; i < number_of_images; i++) { 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    /* set GL_MODELVIEW matrix depending on i */ 
    glBegin(GL_TRIANGLES); 
    for (Triangle &t : mesh) { 
     for (Point &p : t) { 
      glVertex3f(p.x, p.y, p.z); 
     } 
    } 
    glReadPixels(/*...*/) // get picture and store it somewhere 
    glfwSwapBuffers(); 
} 

、私は私が撮りたい各ショットの三角形の頂点を転送/設定します。一度だけ転送する必要があるソリューションはありますか?私のメッシュはかなり大きいので、この転送にかなりの時間がかかります。

+0

メッシュを頂点バッファオブジェクトにアップロードします。最終的には、固定機能パイプラインを使用しないでください(古くなってから古くなっています)、コアプロファイルに移行してください。ここでは、頂点バッファオブジェクトの使用が義務付けられています。 – BDL

+0

古いOpenGL APIを使用しています。最新のAPIを使用してみてください。私は古いOpenGLに関する多くの書籍があることを知っており、OpenGLを研究する正しい方法はどこにあるのかは分かりません。 – Unick

答えて

5

2016年にを使用しないでください。glBegin/glEndを使用してください。とんでもない。代わりにVertex Array Obejctsを使用してください。 vertexおよび/またはgeometryシェーダを使用して、頂点データの位置を変更して変更します。これらの手法を使用すると、GPUにデータを一度アップロードすると、さまざまな変換で同じメッシュを描画できます。

// 1. Initialization. 
// Object handles: 
GLuint vao; 
GLuint verticesVbo; 
// Generate and bind vertex array object. 
glGenVertexArrays(1, &vao); 
glBindVertexArray(vao); 
// Generate a buffer object. 
glGenBuffers(1, &verticesVbo); 
// Enable vertex attribute number 0, which 
// corresponds to vertex coordinates in older OpenGL versions. 
const GLuint ATTRIBINDEX_VERTEX = 0; 
glEnableVertexAttribArray(ATTRIBINDEX_VERTEX); 
// Bind buffer object. 
glBindBuffer(GL_ARRAY_BUFFER, verticesVbo); 
// Mesh geometry. In your actual code you probably will generate 
// or load these data instead of hard-coding. 
// This is an example of a single triangle. 
GLfloat vertices[] = { 
    0.0f, 0.0f, -9.0f, 
    0.0f, 0.1f, -9.0f, 
    1.0f, 1.0f, -9.0f 
}; 
// Determine vertex data format. 
glVertexAttribPointer(ATTRIBINDEX_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, 0); 
// Pass actual data to the GPU. 
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*3*3, vertices, GL_STATIC_DRAW); 
// Initialization complete - unbinding objects. 
glBindBuffer(GL_ARRAY_BUFFER, 0); 
glBindVertexArray(0); 

// 2. Draw calls. 
while(/* draw calls are needed */) { 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glBindVertexArray(vao); 
    // Set transformation matrix and/or other 
    // transformation parameters here using glUniform* calls. 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
    glBindVertexArray(0); // Unbinding just as an example in case if some other code will bind something else later. 
} 

と頂点シェーダは、このようになります:

layout(location=0) in vec3 vertex_pos; 
uniform mat4 viewProjectionMatrix; // Assuming you set this before glDrawArrays. 

void main(void) { 
    gl_Position = viewProjectionMatrix * vec4(vertex_pos, 1.0f); 
} 

も加速良い現代のためthis pageを見てみましょう。ここ

は、あなたのコードは次のように見えるかもしれ方法の概要でありますグラフィックスブック。

+0

ありがとうございました。私はかなり古いOpenGLを使っていたことを知っていました。あなたのポストは私にモダンなスタイルに切り替えるよう動機づけました。 – user38034

0

@BDLは、即時モード描画呼び出し(glBegin ... glEnd)を放棄して、頂点バッファオブジェクト(VBO)からデータをフェッチする頂点配列描画(glDrawElements、glDrawArrays)に切り替える必要があるとコメントしました。 @ Sergeyは彼の答えでVertex Array Objectsを述べましたが、実際はVBOの状態コンテナです。

OpenGLは "メッシュ"、 "シーン"などを扱わないことをあなたが理解していなければならないこと、 。 OpenGLは単なる描画APIです。それは点...線と三角形を一度に1つずつ描きます...それらの間には何の関係もありません。それでおしまい。したがって、同じものを複数表示する場合は、となる必要があります。を数回描く必要があります。これを回避する方法はありません。

最近のOpenGLのバージョンでは、複数のビューポートレンダリングがサポートされていますが、ジオメトリシェーダを使用してジオメトリに複数のピースを描画して描画します。

関連する問題