1

最新のドライバーがインストールされた NVIDIA GTX 970 で、OpenGL 4.4 を使用してディファード シェーディングを実装しようとしています。
私のコードは、画面に直接レンダリングして動作しました。2 番目のパスを追加するには、シーンをレンダリングする FBO と、最終イメージをレンダリングするクワッドを作成します。最初のパスで何もレンダリングせず、2 番目のパスの後にクワッドを描画しようとすると、クワッドが表示されます。最初のパスでメッシュ (立方体など) をレンダリングしようとすると、クワッドが消えます。また、次のエラー メッセージが表示されます。
ここに画像の説明を入力

メッシュは AssImp でロードされました。
次のコードを使用して VBO / VAO を作成します。

void Mesh::genGPUBuffers()
{
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vec3), &vertices[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glGenBuffers(1, &uvbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(vec2), &uvs[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glGenBuffers(1, &normalbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(vec3), &normals[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glGenBuffers(1, &indexbuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexbuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short), &indices[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}


そして、メッシュを次のようにレンダリングします。

void Mesh::render()
{
    if (shader != nullptr)
    {
        shader->use();
        shader->setModelMatrix(modelMatrix);
    }

    for (int i = 0x1; i <= 0xB; i++)
    {
        if (texture[i] != nullptr)
        {
            glBindMultiTextureEXT(GL_TEXTURE0 + i, GL_TEXTURE_2D, texture[i]->getTextureID());
        }
    }

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(
        0,                  // attribute
        3,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized?
        0,                  // stride
        (void*)0            // array buffer offset
    );

    // 2nd attribute buffer : UVs
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glVertexAttribPointer(
        1,                                // attribute
        2,                                // size
        GL_FLOAT,                         // type
        GL_FALSE,                         // normalized?
        0,                                // stride
        (void*)0                          // array buffer offset
    );

    // 3rd attribute buffer : normals
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glVertexAttribPointer(
        2,                                // attribute
        3,                                // size
        GL_FLOAT,                         // type
        GL_FALSE,                         // normalized?
        0,                                // stride
        (void*)0                          // array buffer offset
    );

    // Index buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexbuffer);

    // Draw the triangles
    glDrawElements(
        GL_TRIANGLES,      // mode
        (GLsizei)indexCount,    // count
        GL_UNSIGNED_SHORT,   // type
        (void*)0           // element array buffer offset
    );

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
}


gDEBugger を使用すると、エラー メッセージが glVertexAttribPointer から来ていることがわかりました。しかし、gDEBugger は OpenGL 4 をサポートしていないため、それ自体が多くのエラーをスローし、実際には機能しません。

FBO は次のように生成されます。

GLuint depthBuf;
Texture
    posTex(this),
    normTex(this),
    colorTex(this)
;

// Create and bind the FBO
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

// The depth buffer
glGenRenderbuffers(1, &depthBuf);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuf);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, static_cast<GLsizei>(resolution.x), static_cast<GLsizei>(resolution.y));

// Create the textures for position, normal and color
posTex.createGBuf(GL_TEXTURE0, GL_RGB32F, static_cast<int>(resolution.x), static_cast<int>(resolution.y));
normTex.createGBuf(GL_TEXTURE1, GL_RGB32F, static_cast<int>(resolution.x), static_cast<int>(resolution.y));
colorTex.createGBuf(GL_TEXTURE2, GL_RGB8, static_cast<int>(resolution.x), static_cast<int>(resolution.y));

// Attach the textures to the framebuffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuf);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, posTex.getTextureID(), 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normTex.getTextureID(), 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorTex.getTextureID(), 0);

glBindFramebuffer(GL_FRAMEBUFFER, 0);


createGBuf() 関数は次のようになります。

void C0::Texture::createGBuf(GLenum texUnit, GLenum format, int width, int height)
{
    this->width = width;
    this->height = height;
    glActiveTexture(texUnit);
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
4

1 に答える 1

4

コードのエラーは、おそらく VertexArrayObject を生成したことがないためです。glGenVertexArray(1、vao ポインター) を呼び出します。持っていない場合、最新のopenglはそれを間違いとしてマークします。これはおそらくあなたに起こっていることです。頂点配列を生成し、それを glBindVertexArray(your vao); にバインドします。

次に、レンダリング サイクルごとにデータをバッファリングするべきではありません。それは信じられないほど非効率的です。複数の VAO を作成し、それらに頂点データをバインドしてから vao をアンバインドする必要があります。対応するメッシュをレンダリングするときは、VAO と glDrawElements を再バインドするだけです。

たとえば、次のようになります。

そのような構造体の頂点がある場合

struct Vertex{
  vec3 position;
  vec2 uv;
  vec3 normal;
};
struct Mesh{
   std::vector<Vertex> vertices;
   std::vector<unsigned int> indices;

   GLuint VAO;

   void initializeVAO();
   void Render();
};

次に、そのように初期化します。

Mesh::initializeVAO(){
    GLuint vertexBuffer, indiceBuffer;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &vertexBuffer);
    glGenBuffers(1, &indiceBuffer);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)sizeof(vec3));

    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(:vec3) + sizeof(glm::vec2)));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indiceBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indiceBuffer);

    glBindVertexArray(0);
    glDeleteBuffers(1, &vertexBuffer);
    glDeleteBuffers(1, &indiceBuffer);
}

次に、レンダリングします

Mesh::Render()
{
     glBindVertexArray(VAO);
     glDrawElements(GL_TRIANGLES, indices.size(), 0);
     glBindVertexArray(0);
}

ご不明な点がございましたら、お気軽にお問い合わせください。

于 2014-11-19T22:54:20.910 に答える