在新的共享上下文中需要重置什么OpenGL状态?

时间:2013-08-07 14:59:45

标签: c++ opengl opengl-3 glfw

我有以下类来表示Mesh;

OpenGLMesh::OpenGLMesh(const std::vector<float>& vertexData, const std::vector<float>& normalData, const std::vector<float>& texCoords, const std::vector<uint32_t>& indexData) : mIndices(indexData.size())
     {
        glGenBuffers(1, &mVBO);
        glGenBuffers(1, &mIndexBuffer);
        glGenVertexArrays(1, &mVAO);

        // buffer vertex, normals and index data
        size_t vertexDataSize   = vertexData.size() * sizeof(float);
        size_t normalDataSize   = normalData.size() * sizeof(float);
        size_t texCoordDataSize = texCoords.size() * sizeof(float);
        size_t indexDataSize    = indexData.size() * sizeof(uint32_t);

        glBindVertexArray(mVAO);
        glBindBuffer(GL_ARRAY_BUFFER, mVBO);
        glBufferData(GL_ARRAY_BUFFER, vertexDataSize + normalDataSize + texCoordDataSize, NULL, GL_STATIC_DRAW);
        glBufferSubData(GL_ARRAY_BUFFER, NULL, vertexDataSize, &vertexData[0]);
        glBufferSubData(GL_ARRAY_BUFFER, vertexDataSize, normalDataSize, &normalData[0]);
        glBufferSubData(GL_ARRAY_BUFFER, vertexDataSize + normalDataSize, texCoordDataSize, &texCoords[0]);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexDataSize, &indexData[0], GL_STATIC_DRAW);

        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(vertexDataSize));
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(vertexDataSize + normalDataSize));

       // unbind array buffer and VAO
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
     }

然后绘制网格的方法;

void OpenGLMesh::Render()
{
    glBindVertexArray(mVAO);
    glDrawElements(GL_TRIANGLES, mIndices, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

我正在使用GLFW3,您可以在其中创建一个新窗口并使用与上一个窗口(link)相同的上下文,但据我了解,即使缓冲区对象和仍然需要重置OpenGL状态他们的内容仍然保存 - 对吗?

我尝试阅读手册,但我不知道我发布的代码的哪些部分被视为OpenGL状态的一部分,需要重置?

1 个答案:

答案 0 :(得分:3)

  

创建一个新窗口并使用相同的上下文

不完全。 GLFW将创建shares some of the other contexts' objects的新上下文。即,任何保持一些数据(纹理,缓冲对象,着色器和程序等)的对象都将被共享,即可从两个上下文访问。引用其他对象的容器对象不共享(帧缓冲对象,顶点数组对象)。

  

但据我了解,您仍需要重置OpenGL状态

从技术上讲,新创建的上下文以重置默认状态开始,某些对象已经预先分配并初始化。

然而,就像任何状态机一样,当你即将使用它时,你永远不应该假设OpenGL处于某种状态。始终确保在需要之前设置所有必需的状态需要时。归结起来,你应该在绘图代码的开头设置你需要的每一个状态。