[英]Opengl hide parts of the screen
(代码段。我知道它很丑,但是我想在使其变得更好之前使它工作,所以请不要过多地关注结构)
我稍微修改了文档中的glfw示例,使其具有一个三角形,该三角形在按向右箭头键时会旋转,并绘制一个由其顶点之一(在此情况下为蓝色)的位置描述的圆。 我仅在初始化窗口时才清除GL_COLOR_BUFFER_BIT
,以避免必须存储绘制线所需的所有坐标(在最终程序中它们将成千上万),这意味着每次我按向右屏幕时箭头将三角形的“副本”绘制旋转12度,并绘制一条将旧的蓝色角度位置连接到新的角度的线。
现在的问题是,我希望能够按GLFW_KEY_ESCAPE
键GLFW_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.