【问题标题】:OpenGL Only Works on Second FrameOpenGL 仅适用于第二帧
【发布时间】:2013-07-27 08:13:07
【问题描述】:

我正在使用 SFML、OpenGL 和 VC++ 编译器。当我渲染某些东西时,它只会在第二次运行时正确弹出(?)。这是我的代码:

void Renderer::initializeOpenGL() {
    glEnable(GL_DEPTH_TEST);
    glEnableClientState(GL_VERTEX_ARRAY);
    glOrtho(0, 1024, 0, 576, 0, 1024);
}

void Renderer::drawWorld(World* world) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1.F, 1.F, 1.F);
    std::vector<int> vertices;
    for(unsigned int x = 0; x < world->width; x++) {
        bool left = false, right = false;
        if(x == 0)
            left = true;
        else if(x == world->width -1)
            right = true;
        for(unsigned int z = 0; z < world->depth; z++) {
            bool front = false, back = false;
            if(z == 0)
                front = true;
            else if(z == world->depth -1)
                back = true;
            for(unsigned int y = 0; y < world->height; y++) {
                if(!world->blocks[x][z][y])
                    continue;
                if(left == true || !world->blocks[x-1][z][y]) {
                    vertices.push_back(x);
                    vertices.push_back(y);
                    vertices.push_back(z);

                    vertices.push_back(x);
                    vertices.push_back(y);
                    vertices.push_back(z+1);

                    vertices.push_back(x);
                    vertices.push_back(y+1);
                    vertices.push_back(z+1);

                    vertices.push_back(x);
                    vertices.push_back(y+1);
                    vertices.push_back(z);
                }
                if(right == true || !world->blocks[x+1][z][y]) {
                    vertices.push_back(x+1);
                    vertices.push_back(y);
                    vertices.push_back(z);

                    vertices.push_back(x+1);
                    vertices.push_back(y);
                    vertices.push_back(z+1);

                    vertices.push_back(x+1);
                    vertices.push_back(y+1);
                    vertices.push_back(z+1);

                    vertices.push_back(x+1);
                    vertices.push_back(y+1);
                    vertices.push_back(z);
                }

                if(front == true || !world->blocks[x][z-1][y]) {
                    vertices.push_back(x);
                    vertices.push_back(y);
                    vertices.push_back(z+1);

                    vertices.push_back(x+1);
                    vertices.push_back(y);
                    vertices.push_back(z+1);

                    vertices.push_back(x+1);
                    vertices.push_back(y+1);
                    vertices.push_back(z+1);

                    vertices.push_back(x);
                    vertices.push_back(y+1);
                    vertices.push_back(z+1);
                }
                if(back == true || !world->blocks[x][z+1][y]) {
                    vertices.push_back(x);
                    vertices.push_back(y);
                    vertices.push_back(z);

                    vertices.push_back(x+1);
                    vertices.push_back(y);
                    vertices.push_back(z);

                    vertices.push_back(x+1);
                    vertices.push_back(y+1);
                    vertices.push_back(z);

                    vertices.push_back(x);
                    vertices.push_back(y+1);
                    vertices.push_back(z);
                }

                if(y == 0 || !world->blocks[x][z][y-1]) {
                    vertices.push_back(x);
                    vertices.push_back(y);
                    vertices.push_back(z);

                    vertices.push_back(x+1);
                    vertices.push_back(y);
                    vertices.push_back(z);

                    vertices.push_back(x+1);
                    vertices.push_back(y);
                    vertices.push_back(z+1);

                    vertices.push_back(x);
                    vertices.push_back(y);
                    vertices.push_back(z+1);
                }
                if(y == world->height -1 || !world->blocks[x][z][y+1]) {
                    vertices.push_back(x);
                    vertices.push_back(y+1);
                    vertices.push_back(z);

                    vertices.push_back(x+1);
                    vertices.push_back(y+1);
                    vertices.push_back(z);

                    vertices.push_back(x+1);
                    vertices.push_back(y+1);
                    vertices.push_back(z+1);

                    vertices.push_back(x);
                    vertices.push_back(y+1);
                    vertices.push_back(z+1);
                }
            }
        }
    }

    glVertexPointer(3, GL_INT, 0, &vertices[0]);
    glDrawArrays(GL_QUADS, 0, vertices.size() /3);
    std::cout << "Vertices: " << vertices.size() << std::endl;
}

这是我的结果:
drawWorld 的第一次调用:http://i.imgur.com/yMchEG9.png
drawWorld 的第二次调用:http://i.imgur.com/d9swgao.png

很明显,在第一次调用之前,initializeOpenGL 只被调用了 1 次。在提供的代码之外没有 OpenGL 语句。

【问题讨论】:

    标签: c++ opengl render


    【解决方案1】:

    更新:

    显然,正如通过我的回答的 cmets 所讨论的那样,我的方法是错误的。正确的是用户 derhass 在 cmets 中指出的内容。引自derhass:

    没有。 GL 是一个状态机。状态如何设置并不重要 当它们不被使用时。对于顶点数组状态,重要的是 绘制调用。您必须确保您需要的所有阵列都已启用 并且在绘图调用时禁用所有您不需要的东西。 实际上,避免不必要的状态更改是一种很好的做法。

    导致此更新的错误假设:

    void Renderer::initializeOpenGL() {
        glEnable(GL_DEPTH_TEST);
        glEnableClientState(GL_VERTEX_ARRAY);
        glOrtho(0, 1024, 0, 576, 0, 1024);
    }
    

    glEnableClientState 并不是这样工作的。 您需要在绘制调用之前启用客户端状态并在之后禁用它。

    所以我看到你在抽奖电话后错过了glDisableClientState(GL_VERTEX_ARRAY);。 还要从您的 initializeOpenGL() 函数中删除 glEnableClientState(GL_VERTEX_ARRAY); 并将其放在您的 drawWorld 函数中(编辑:在您的顶点指针调用之前)。

    这可能会导致您的问题。

    【讨论】:

    • 启用该顶点数组并且从不禁用它绝对没有错。
    • 如果这是真的,那绝对是个好消息,但我想就“良好做法”而言应该这样使用,对吧?
    • 没有。 GL 是一个状态机。不使用状态时如何设置它们并不重要。对于顶点数组状态,重要的是绘制调用。您必须确保在绘制调用时启用了所有需要的数组,并且禁用了所有不需要的数组。实际上,避免不必要的状态更改是一种很好的做法。你在这里建议的是一个典型的货物崇拜编程示例,基于一些以这种方式工作的教程/示例。
    • 我同意@derhass。您应该将评论放入您的答案中。请稍后联系我,以便我删除我的反对票。
    • 这样做是公平的。我只是认为解决这个问题不在我的手中。认为mods会接管。我是第一个支持他的评论的人,他提供的信息很有用,而不是你在大多数教程/示例中可以找到的东西,因为它们似乎没有深入阐述。不过,他确实有点伤害了我的感情。只是一点点:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多