繁体   English   中英

OpenGL隐藏屏幕的一部分

[英]Opengl hide parts of the screen

(代码段。我知道它很丑,但是我想在使其变得更好之前使它工作,所以请不要过多地关注结构)

我稍微修改了文档中的glfw示例,使其具有一个三角形,该三角形在按向右箭头键时会旋转,并绘制一个由其顶点之一(在此情况下为蓝色)的位置描述的圆。 我仅在初始化窗口时才清除GL_COLOR_BUFFER_BIT ,以避免必须存储绘制线所需的所有坐标(在最终程序中它们将成千上万),这意味着每次我按向右屏幕时箭头将三角形的“副本”绘制旋转12度,并绘制一条将旧的蓝色角度位置连接到新的角度的线。

现在的问题是,我希望能够按GLFW_KEY_ESCAPEGLFW_KEY_ESCAPE并“删除”三角形,同时保持绘制的线条。

我尝试使用z缓冲区将三角形隐藏在黑色矩形后面,但是仅可视化最后绘制的线(我认为这是因为opengl不知道前一行的z,因为我不存储它们)。

有没有一种方法可以执行我想要的操作,而不必存储所有点坐标,然后清除整个屏幕并仅重绘线条? 如果是这样,最好的存储方式是什么?

这是我到目前为止的部分代码。

bool check = 0;

Vertex blue = {0.f, 0.6f, 0.5f};
Vertex green = {0.6f,-0.4f, 0.5f};
Vertex red = {-0.6f, -0.4f, 0.5f};
Vertex line = {0.f, 0.6f, 0.f};
Vertex line2 = {0.f, 0.6f, 0.f};

static void
key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        check = !check;
    if (key == GLFW_KEY_RIGHT && action == GLFW_PRESS) {
        line.x = line2.x;
        line.y = line2.y;
        rotation -= 12;
        rad = DegToRad(-12);
        double x = line.x*cos(rad) - line.y * sin(rad);
        double y = line.y * cos(rad) + line.x * sin(rad);
        line2.x = x;
        line2.y = y;
}

int main(void) {
    GLFWwindow *window;
    glfwSetErrorCallback(error_callback);
    if (!glfwInit())
        exit(EXIT_FAILURE);
    window = glfwCreateWindow(1280, 720, "Example", NULL, NULL);
    if (!window) {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
    glfwMakeContextCurrent(window);
    glfwSetKeyCallback(window, key_callback);
    glClear(GL_COLOR_BUFFER_BIT);
    while (!glfwWindowShouldClose(window)) {

        glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
        float ratio;
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float) height;
        glViewport(0, 0, width, height);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
        glMatrixMode(GL_MODELVIEW);

        glLoadIdentity();
        glRotatef(rotation, 0.f, 0.f, 1.f);
        glBegin(GL_TRIANGLES);
        glColor3f(1.f, 0.f, 0.f);
        glVertex3f(red.x, red.y, red.z);
        glColor3f(0.f, 1.f, 0.f);
        glVertex3f(green.x, green.y, green.z);
        glColor3f(0.f, 0.f, 1.f);
        glVertex3f(blue.x, blue.y, blue.z);
        glEnd();

        glLoadIdentity();
        glLineWidth(1.0);
        glColor3f(1.0, 0.0, 0.0);
        glBegin(GL_LINES);
        glVertex3f(line.x, line.y, line.z);
        glVertex3f(line2.x, line2.y, line2.z);
        glEnd();

        if (check){
            //hide the triangles but not the lines
         }

        glEnd();


        glfwSwapBuffers(window);
        glfwPollEvents();

    }

    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

我仅在初始化窗口时清除GL_COLOR_BUFFER_BIT

那就是你的问题。 在OpenGL中,习惯用法总是始终对主帧缓冲区颜色位进行清晰的操作。 也就是说,因为当操作系统要求重画时,您不知道窗口主帧缓冲区的状态。 就您所知,在您的程序不知道的情况下,它可能已全部替换为背景中的猫图片。 严重的是:如果正在运行猫视频,并且操作系统感觉到需要重新布置窗口的主帧缓冲内存,那么最终可能会发生这种情况。

有没有一种方法可以执行我想要的操作,而不必存储所有点坐标,然后清除整个屏幕并仅重绘线条?

出于所有意图和目的:不可以。理论上,可以通过一系列复杂的模版缓冲操作来实现这一目的,但这将是一棵非常错误的树。

您可以尝试以下操作:像您一样绘制一堆三角形,然后缩小窗口的大小,以至于没有任何余物,然后将其重新设置为原始大小……您发现问题出在哪里? 有一种解决这个特定问题的方法,但这不是您应该在此处执行的操作。

正确的做法是重新绘制所有内容。 如果您觉得这样很慢,则必须优化绘图过程。 在当前的硬件上,每秒可能加工出1亿个三角形。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM