【问题标题】:How do I make cube faces opaque on OpenGL?如何在 OpenGL 上使立方体面不透明?
【发布时间】:2020-03-15 03:27:38
【问题描述】:

我正在编写一个程序来在 OpenGL 上绘制一个立方体并在鼠标点击时连续旋转它。在特定的角度,我能够看穿立方体(透明)。我启用了深度测试,所以我不知道为什么会这样。我不确定我是否正确启用它。

#include <math.h>
#include <vector>
#include <Windows.h>
#include <gl\glut.h>

using namespace std;


void myInit() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0, 0, 0, 1);
    glOrtho(-2, 2, -2, 2, 2, -2);
    glMatrixMode(GL_MODELVIEW);
}

float Cube[][3] = { {-1, -1, -1}, {1, -1, -1}, {1, 1, -1}, {-1, 1, -1}, {-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1} };
float Colors[][3] = { {0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 1, 0}, {0, 1, 1}, {1, 0, 1}, {1, 1, 1} };

int axis = 0, theta[3] = {0, 0, 0};

void draw_face (int a, int b, int c, int d) {
    glBegin(GL_QUADS);
        glColor3fv(Colors[a]);
        glVertex3fv(Cube[a]);
        glColor3fv(Colors[b]);
        glVertex3fv(Cube[b]);
        glColor3fv(Colors[c]);
        glVertex3fv(Cube[c]);
        glColor3fv(Colors[d]);
        glVertex3fv(Cube[d]);
    glEnd();
}

void draw_cube () {
    draw_face(0, 3, 2, 1);
    draw_face(2, 3, 7, 6);
    draw_face(0, 4, 7, 3);
    draw_face(1, 2, 6, 5);
    draw_face(4, 5, 6, 7);
    draw_face(0, 1, 5, 4);
}

void spin_cube() {
    theta[axis] += 2;
    if (theta[axis] > 360)
        theta[axis] = -360;
    glutPostRedisplay();
}

void idle_func() {
    Sleep(10);
    spin_cube();
}

void mouse_func(int button, int state, int x, int y) {
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
        axis = 0;
    else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
        axis = 1;
    else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
        axis = 2;
}

void myDrawing() {
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
    glRotatef(theta[0], 1, 0, 0);
    glRotatef(theta[1], 0, 1, 0);
    glRotatef(theta[2], 0, 0, 1);
    draw_cube();
    glPopMatrix();
    glFlush();
    glutSwapBuffers();
}

int main(int argc, char *argv[]) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glEnable(GL_DEPTH_TEST);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("sample");
    glutDisplayFunc(myDrawing);
    glutIdleFunc(idle_func);
    glutMouseFunc(mouse_func);
    myInit();
    glutMainLoop();
}

【问题讨论】:

  • 您似乎没有启用深度测试。尝试在myInit() 中添加glEnable(GL_DEPTH_TEST);
  • myDrawing() 中,您可以使用glClear(GL_COLOR_BUFFER_BIT);。这应该是glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);。 (另一个 Q 也提醒我要寻找这个:SO: glEnable(GL_DEPTH_TEST) - nothing rendered。);-)
  • 对于透明度,请参阅OpenGL - How to create Order Independent transparency? ...但如果您想要完全相反的情况,您需要启用GL_DEPTH_TEST...但是如果您启用了GL_CULL_FACE ,那么面的缠绕必须与glFrontFace 设置 GL_CW/GL_CCW 如果不是,那么你会从某些方面看到立方体从里到外,我认为这是你的情况......你可以从这里提取正确的立方体 complete GL+GLSL+VAO/VBO C++ example 寻找 vao_pos[] QUADs 表跨度>

标签: c++ opengl glut depth-testing


【解决方案1】:

多个问题:

  1. 您不是从 GLUT 请求深度缓冲区:

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    

    解决方案:或在GLUT_DEPTH 中确保 GLUT 在 GL 上下文创建期间向操作系统请求一些深度缓冲区位:

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    
  2. 您在 GLUT 创建 GL 上下文之前调用 glEnable(GL_DEPTH_TEST)

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    // no GL context yet
    glEnable(GL_DEPTH_TEST);
    

    解决方案:将glEnable() 移动到glutCreateWindow() 之后,这样它就有一个可以使用的当前GL 上下文:

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("sample");
    glEnable(GL_DEPTH_TEST);
    ...
    
  3. 你永远不会清除深度缓冲区:

    void myDrawing() {
        // where's GL_DEPTH_BUFFER_BIT?
        glClear(GL_COLOR_BUFFER_BIT);
        ...
    

    解决方案:或在 GL_DEPTH_BUFFER_BIT 到您的 glClear() 参数:

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    

所有修复一起:

#include <cmath>
#include <vector>
#include <GL/glut.h>

using namespace std;

void myInit() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0, 0, 0, 1);
    glOrtho(-2, 2, -2, 2, 2, -2);
    glMatrixMode(GL_MODELVIEW);
}

float Cube[][3] = { {-1, -1, -1}, {1, -1, -1}, {1, 1, -1}, {-1, 1, -1}, {-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1} };
float Colors[][3] = { {0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 1, 0}, {0, 1, 1}, {1, 0, 1}, {1, 1, 1} };

int axis = 0, theta[3] = {0, 0, 0};

void draw_face (int a, int b, int c, int d) {
    glBegin(GL_QUADS);
        glColor3fv(Colors[a]);
        glVertex3fv(Cube[a]);
        glColor3fv(Colors[b]);
        glVertex3fv(Cube[b]);
        glColor3fv(Colors[c]);
        glVertex3fv(Cube[c]);
        glColor3fv(Colors[d]);
        glVertex3fv(Cube[d]);
    glEnd();
}

void draw_cube () {
    draw_face(0, 3, 2, 1);
    draw_face(2, 3, 7, 6);
    draw_face(0, 4, 7, 3);
    draw_face(1, 2, 6, 5);
    draw_face(4, 5, 6, 7);
    draw_face(0, 1, 5, 4);
}

void spin_cube() {
    theta[axis] += 2;
    if (theta[axis] > 360)
        theta[axis] = -360;
    glutPostRedisplay();
}

void idle_func() {
    Sleep(10);
    spin_cube();
}

void mouse_func(int button, int state, int x, int y) {
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
        axis = 0;
    else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
        axis = 1;
    else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
        axis = 2;
}

void myDrawing() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
    glRotatef(theta[0], 1, 0, 0);
    glRotatef(theta[1], 0, 1, 0);
    glRotatef(theta[2], 0, 0, 1);
    draw_cube();
    glPopMatrix();
    glFlush();
    glutSwapBuffers();
}

int main(int argc, char *argv[]) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("sample");
    glEnable(GL_DEPTH_TEST);
    glutDisplayFunc(myDrawing);
    glutIdleFunc(idle_func);
    glutMouseFunc(mouse_func);
    myInit();
    glutMainLoop();
}

【讨论】:

  • 谢谢 genpfault。完美运行
  • @acr1997 如果此答案解决了您的问题,您应该通过单击投票柜台附近的检查器将其标记为解决方案
猜你喜欢
  • 2015-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-18
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
相关资源
最近更新 更多