OpenGL 前后渲染

Tom*_*mas 1 c++ opengl rendering

我对 OpenGL 渲染的理解是,如果没有深度测试,对象将按顺序绘制,因此您调用的最后一个渲染函数将在已绘制的任何内容之上绘制其形状。我发现情况似乎并非如此:

glDisable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);


glColor3f(1.0, 0.0, 0.0);
glBegin(GL_QUADS);
{
    glVertex2f(50, 50);
    glVertex2f(100, 50);
    glVertex2f(100, 100);
    glVertex2f(50, 100);
}
glEnd();


glColor3f(0.0, 0.0, 1.0);
glBegin(GL_QUADS);
{
    glVertex2f(30, 60);
    glVertex2f(110, 60);
    glVertex2f(110, 90);
    glVertex2f(30, 90);
}
glEnd();
Run Code Online (Sandbox Code Playgroud)

而不是我所期望的蓝色方块下方的红色方块,这些调用会给我一个蓝色方块上的红色方块!

我不明白 OpenGL 渲染是如何工作的吗?或者我只是缺少某种不会让蓝色方块渲染的选项或配置?我正在使用自定义(但非常简单)着色器,这会改变什么吗?

这个问题的未被接受的答案似乎暗示顺序渲染实际上并没有发生并且是特定于实现的,但其接受的答案暗示事实确实如此。

在顶部进行第二次调用的最佳方法是什么?我真的不想拥有某种在整个程序中不断增加的全局 z 值。

Sig*_*erm 5

您调用的渲染函数将在已绘制的任何内容之上绘制其形状。

这是正确的。

我发现情况似乎并非如此:

这对我有用:

#include <SDL/SDL.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>

static int scrWidth = 640;
static int scrHeight = 480;

int main(int argc, char** argv){
    SDL_Init(SDL_INIT_VIDEO);

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);

    if (SDL_SetVideoMode(scrWidth, scrHeight, 32, SDL_OPENGL) == 0){
        fprintf(stderr, "couldn't set mode %dx%d!\n", 640, 480);
        SDL_Quit();
        return -1;
    }
    glewInit();

    SDL_ShowCursor(SDL_DISABLE);

    glClearColor(0.2, 0.2, 0.2, 0.2);
    glClearDepth(1.0);

    glEnable(GL_DEPTH_TEST);

    bool running = true;
    while (running){
        SDL_Event event;
        if (SDL_PollEvent(&event)){
            switch(event.type){
                case SDL_QUIT:
                    running = false;
                    break;
            };
        }
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(0, scrWidth, scrHeight, 0);

        glColor3f(1.0f, 0.0f, 0.0f);
        glBegin(GL_QUADS);
        glVertex2f(50, 50);
        glVertex2f(100, 50);
        glVertex2f(100, 100);
        glVertex2f(50, 100);
        glEnd();


        glColor3f(0.0, 0.0, 1.0);
        glBegin(GL_QUADS);
        glVertex2f(30, 60);
        glVertex2f(110, 60);
        glVertex2f(110, 90);
        glVertex2f(30, 90);
        glEnd();

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glFlush();
        SDL_GL_SwapBuffers();       
    }   

    SDL_Quit();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

与您的代码进行比较,看看是否有区别。也许您并没有真正禁用深度测试。如果您在代码中使用模板缓冲区以及模板缓冲区参数的某些组合(类似于glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff); glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);),您也可能遇到同样的问题。如果您忘记使用 glClear 并在第一个和第二个多边形之间插入“交换缓冲区”调用,您也可以获得相同的效果。

正在使用自定义(但非常简单)着色器,这会改变什么吗?

是的,它可以改变一切。然而,在这种情况下,它意味着你没有提供足够的信息来帮助与你的问题。当您需要代码方面的帮助时,您应该发布完整功能齐全但能说明您的问题的最小示例。“忘记”发布这个例子是一个坏主意。