OpenGL的状态需要在新的共享上下文上重置

What OpenGL state needs to be reset upon a new shared context?

本文关键字:上下文 共享 状态 OpenGL      更新时间:2023-10-16

我有以下类来表示网格;

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,在那里你可以创建一个新窗口,并使用与上一个窗口相同的上下文(链接),但据我所知,即使缓冲区对象及其内容仍然保存,你仍然需要重置OpenGL状态-对吗?

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

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

不完全是。GLFW将创建一个新的上下文,该上下文共享一些其他上下文的对象。也就是说,任何保存一些数据的对象(纹理、缓冲区对象、着色器和程序等)都将被共享,即可以从两个上下文访问。引用其他对象的容器对象是不共享的(帧缓冲区对象、顶点数组对象)。

然而,据我所知,你仍然需要重置OpenGL状态

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

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