2014-11-19 2 views
1

Я пытаюсь реализовать отложенное затенение с OpenGL 4.4 на NVIDIA GTX 970 с установленными последними установленными драйверами.
Мой код работал с рендерингом непосредственно на экран. Чтобы добавить второй проход, я создаю FBO, в котором я создаю свою сцену и квадрат, на котором я делаю окончательное изображение. Когда я пытаюсь ничего не сделать в первом проходе и нарисую квад после второго прохода, квадрат виден. Когда я пытаюсь сделать сетку (например, куб) во время первого прохода, квадрат исчезает. Также я получаю следующее сообщение об ошибке:
enter image description here
glVertexAttribPointer GL_INVALID_OPERATION Недопустимое использование указателя vao vbo

Сетка была нагруженные AssImp.
Я использую следующий код для создания VBO/ВАО:

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); 
} 
+0

gDEBugger отлично работает с GL4. Вероятно, вы используете старую версию gRemedy, прежде чем AMD купила ее. Он поддерживает современный отладочный вывод GL, и вы можете использовать его для получения тех же ошибок, которые вы указали в своей трассировке отладки. Я думаю, что ваша фактическая проблема здесь просто в том, что у вас нет ненулевой привязки объектов массива вершин. –

+0

call glGetError несколько раз и найдите там, где была сгенерирована ошибка –

ответ

3

ошибка с кодом, вероятно, потому что вы никогда генерируется VertexArrayObject, вызов glGenVertexArray (1, ваш указатель vao); если у вас его нет, современный opengl будет отмечать его как ошибку, что, вероятно, происходит с вами. Создайте массив вершин, затем привяжите его с помощью glBindVertexArray (ваш vao);

Во-вторых, вы не должны буферизировать свои данные в каждом цикле рендеринга. Это невероятно неэффективно. Вы должны создать несколько VAO, привязать к ним данные вершин, а затем отвязать vao при рендеринге соответствующей сетки, просто переустановите VAO и glDrawElements.

Так пример был бы это,

, если у вас есть STRUCT Vertex как так

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); 
} 

Если у вас есть какие-либо вопросы, не стесняйтесь спрашивать.

+0

Большое вам спасибо! Ошибки действительно исчезают. Но квадрат также не отображается, когда я делаю куб в первом проходе. Я постараюсь сделать еще немного отладки нового кода завтра, очень поздно, когда я живу;) –

+0

Сцена делает хорошее без пропусков. С проходом он не работает:/Question: Что это за предупреждение использования состояния Texture? Могла ли это быть причиной моей беды? –

+1

@MarcoAlka Предупреждение означает, что вы не привязывали действительную текстуру перед выполнением функций текстуры. Убедитесь, что glBindTexture вызвал текстуру, созданную вами перед использованием любых glTextureFunctions. – user3427457

Смежные вопросы