0

我有以下类来表示网格;

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 状态的一部分并且需要重置?

4

1 回答 1

3

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

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

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

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

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

于 2013-08-07T23:43:56.313 回答