【问题标题】:OpenGL: smudges drawn on image surfacesOpenGL:在图像表面上绘制的污点
【发布时间】:2011-11-11 19:19:25
【问题描述】:

我正在尝试编写一个魔方的接口。

但是,当我绘制它时,立方体的表面上有污迹:

这是注释良好的代码。有人可以帮助我,或许可以运行代码并告诉我哪里可能出错了?

#include <GL/glut.h>
#include <stdlib.h>

#include <stdio.h>

void init() {

  glClearColor(1.0f, 0.0f, 1.0f, 1.0f);

  glEnable(GL_DEPTH_TEST);

}

static float x_degs = 0.0f;
static float y_degs = 0.0f;

void keyboard(unsigned char key, int x, int y) {

  switch (key) {

    case 'q':

      exit(EXIT_SUCCESS);

    case 'h':

      y_degs -= 1.0f;

      glutPostRedisplay();

      glutSwapBuffers();

      break;

    case 'j':

      x_degs -= 1.0f;

      glutPostRedisplay();

      glutSwapBuffers();

      break;

    case 'k':

      x_degs += 1.0f;

      glutPostRedisplay();

      glutSwapBuffers();

      break;

    case 'l':

      y_degs += 1.0f;

      glutPostRedisplay();

      glutSwapBuffers();

      break;

  }

}

// half the length of one card

static const float card_half_size = 1.0f;

// half the space between cards

static const float space_half_size = 0.1f;

// number of cards per face

static const int NUM_CARDS_PER_FACE = 4;
/*
// start position of center of top left card 

const float start = - 3 * (card_half_size + space_half_size);

// increment between center of cards

const float incr = 2 * (card_half_size + space_half_size);

// half the size of a cube face

const float cube_half_size = 4 * (card_half_size + space_half_size);
*/
// draw a card centered at the origin

void draw_card() {

  glBegin(GL_QUADS);
    glVertex3f(- card_half_size, - card_half_size, 0.0f);
    glVertex3f(- card_half_size, card_half_size, 0.0f);
    glVertex3f(card_half_size, card_half_size, 0.0f);
    glVertex3f(card_half_size, - card_half_size, 0.0f);
  glEnd();

}

// draw a cube face made up of cards

void draw_card_face() {

  const float cube_half_size = 4 * (card_half_size + space_half_size);
  const float start = - 3 * (card_half_size + space_half_size);
  const float incr = 2 * (card_half_size + space_half_size);

  glColor3f(0.0f, 1.0f, 1.0f);

  glBegin(GL_QUADS);
    glVertex3f(- cube_half_size, - cube_half_size, -0.001f);
    glVertex3f(- cube_half_size, cube_half_size, -0.001f);
    glVertex3f(cube_half_size, cube_half_size, -0.001f);
    glVertex3f(cube_half_size, - cube_half_size, -0.001f);
  glEnd();

  glColor3f(1.0f, 1.0f, 1.0f);

  for (int i = 0; i < NUM_CARDS_PER_FACE; i++)

    for (int j = 0; j < NUM_CARDS_PER_FACE; j++) {

      glPushMatrix();
        glTranslatef(start + i * incr, start + j * incr, 0.0f);
        draw_card();
      glPopMatrix();

    }

}

// draw a cube made up of cards

void draw_card_cube() {

  const float cube_half_size = 4 * (card_half_size + space_half_size);

  // front face

  glPushMatrix();
    glTranslatef(0.0f, 0.0f, cube_half_size);
    draw_card_face();
  glPopMatrix();

  // back face

  glPushMatrix();
    glTranslatef(0.0f, 0.0f, - cube_half_size);
    glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
    draw_card_face();
  glPopMatrix();

  // right face

  glPushMatrix();
    glTranslatef(cube_half_size, 0.0f, 0.0f);
    glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
    draw_card_face();
  glPopMatrix();

  // left face

  glPushMatrix();
    glTranslatef(- cube_half_size, 0.0f, 0.0f);
    glRotatef(- 90.0f, 0.0f, 1.0f, 0.0f);
    draw_card_face();
  glPopMatrix();

  // top face

  glPushMatrix();
    glTranslatef(0.0f, cube_half_size, 0.0f);
    glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
    draw_card_face();
  glPopMatrix();

  // bottom face

  glPushMatrix();
    glTranslatef(0.0f, - cube_half_size, 0.0f);
    glRotatef(- 90.0f, 1.0f, 0.0f, 0.0f);
    draw_card_face();
  glPopMatrix();


}

void display() {

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  glRotatef(x_degs, 1.0f, 0.0f, 0.0f);
  glRotatef(y_degs, 0.0f, 1.0f, 0.0f);

  gluLookAt(-0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
  draw_card_cube();
  glutSwapBuffers();

}

void reshape(int w, int h) {

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-15.0f, 15.0f, -15.0f, 15.0f, -15.0f, 15.0f);
  glViewport(0, 0, w, h);
  glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char **argv) {

  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutCreateWindow(argv[0]);
  init();
  glutKeyboardFunc(keyboard);
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutMainLoop();
  return 0;

}

好的,我已经修改了代码,以便我在后面绘制青色矩形 0.01f 单位而不是 0.001f 单位,这似乎已经修复了 z-fighting。但是我本来想使用 glPolygonOffset(factor, units) 来解决这个问题,但我无法做到,因为以下 原因:

  1. 我不知道如何设置因子和单位(我都试过 1.0)。
  2. 我尝试了不同的值,但没有结果。

这是没有流血/缝合/z-fighting的代码:

#include <GL/glut.h>
#include <stdlib.h>

#include <stdio.h>

void init() {

  glClearColor(1.0f, 0.0f, 1.0f, 1.0f);

  glEnable(GL_DEPTH_TEST);

}

static float x_degs = 0.0f;
static float y_degs = 0.0f;

void keyboard(unsigned char key, int x, int y) {

  switch (key) {

    case 'q':

      exit(EXIT_SUCCESS);

    case 'h':

      y_degs -= 1.0f;

      glutPostRedisplay();

      glutSwapBuffers();

      break;

    case 'j':

      x_degs -= 1.0f;

      glutPostRedisplay();

      glutSwapBuffers();

      break;

    case 'k':

      x_degs += 1.0f;

      glutPostRedisplay();

      glutSwapBuffers();

      break;

    case 'l':

      y_degs += 1.0f;

      glutPostRedisplay();

      glutSwapBuffers();

      break;

  }

}

// half the length of one card

static const float card_half_size = 1.0f;

// half the space between cards

static const float space_half_size = 0.1f;

// number of cards per face

static const int NUM_CARDS_PER_FACE = 4;
/*
// start position of center of top left card 

const float start = - 3 * (card_half_size + space_half_size);

// increment between center of cards

const float incr = 2 * (card_half_size + space_half_size);

// half the size of a cube face

const float cube_half_size = 4 * (card_half_size + space_half_size);
*/
// draw a card centered at the origin

void draw_card() {

  glBegin(GL_QUADS);
    glVertex3f(- card_half_size, - card_half_size, 0.0f);
    glVertex3f(- card_half_size, card_half_size, 0.0f);
    glVertex3f(card_half_size, card_half_size, 0.0f);
    glVertex3f(card_half_size, - card_half_size, 0.0f);
  glEnd();

}

// draw a cube face made up of cards

void draw_card_face() {

  const float cube_half_size = 4 * (card_half_size + space_half_size);
  const float start = - 3 * (card_half_size + space_half_size);
  const float incr = 2 * (card_half_size + space_half_size);

  glColor3f(0.0f, 1.0f, 1.0f);

  glBegin(GL_QUADS);
    glVertex3f(- cube_half_size, - cube_half_size, -0.001f);
    glVertex3f(- cube_half_size, cube_half_size, -0.001f);
    glVertex3f(cube_half_size, cube_half_size, -0.001f);
    glVertex3f(cube_half_size, - cube_half_size, -0.001f);
  glEnd();

  glColor3f(1.0f, 1.0f, 1.0f);

  for (int i = 0; i < NUM_CARDS_PER_FACE; i++)

    for (int j = 0; j < NUM_CARDS_PER_FACE; j++) {

      glPushMatrix();
        glTranslatef(start + i * incr, start + j * incr, 0.0f);
        draw_card();
      glPopMatrix();

    }

}

// draw a cube made up of cards

void draw_card_cube() {

  const float cube_half_size = 4 * (card_half_size + space_half_size);

  // front face

  glPushMatrix();
    glTranslatef(0.0f, 0.0f, cube_half_size);
    draw_card_face();
  glPopMatrix();

  // back face

  glPushMatrix();
    glTranslatef(0.0f, 0.0f, - cube_half_size);
    glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
    draw_card_face();
  glPopMatrix();

  // right face

  glPushMatrix();
    glTranslatef(cube_half_size, 0.0f, 0.0f);
    glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
    draw_card_face();
  glPopMatrix();

  // left face

  glPushMatrix();
    glTranslatef(- cube_half_size, 0.0f, 0.0f);
    glRotatef(- 90.0f, 0.0f, 1.0f, 0.0f);
    draw_card_face();
  glPopMatrix();

  // top face

  glPushMatrix();
    glTranslatef(0.0f, cube_half_size, 0.0f);
    glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
    draw_card_face();
  glPopMatrix();

  // bottom face

  glPushMatrix();
    glTranslatef(0.0f, - cube_half_size, 0.0f);
    glRotatef(- 90.0f, 1.0f, 0.0f, 0.0f);
    draw_card_face();
  glPopMatrix();


}

void display() {

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  glRotatef(x_degs, 1.0f, 0.0f, 0.0f);
  glRotatef(y_degs, 0.0f, 1.0f, 0.0f);

  gluLookAt(-0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
  draw_card_cube();
  glutSwapBuffers();

}

void reshape(int w, int h) {

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-15.0f, 15.0f, -15.0f, 15.0f, -15.0f, 15.0f);
  glViewport(0, 0, w, h);
  glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char **argv) {

  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutCreateWindow(argv[0]);
  init();
  glutKeyboardFunc(keyboard);
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutMainLoop();
  return 0;

}

【问题讨论】:

  • “立方体表面的污迹”。有机会上图吗?
  • 我建议使用温和的清洁剂和软布。
  • 您好,我不知道如何在堆栈溢出时包含图片,所以我在 PicasaWeb 上分享了一张图片:!link
  • 您的键盘处理程序中不需要glutSwapBuffers(),只需glutPostRedisplay()s
  • 通过glGet()GL_DEPTH_BITS 再次检查您的深度缓冲区有多少位。有些人可能会“默认”获得 24 位或 32 位深度缓冲区,而如果您在 VM 中运行程序,您可能会获得 16 位深度缓冲区。

标签: c opengl rubiks-cube


【解决方案1】:

我认为您将棋子绘制为主立方体面的共面四边形;如果是这样的话,你遇到的问题就叫做“z打架”。

您可以查看点 12.040 深度缓冲似乎有效,但多边形似乎会通过它们前面的多边形流血。发生了什么事? 这里: http://www.opengl.org/resources/faq/technical/depthbuffer.htm

基本上,您的深度缓冲区没有足够的精度来解决为每个像素显示哪个四边形,从而导致问题。

您可以手动向棋盘四边形添加偏移量,以将它们从立方体上移开;或通过glPolygonOffset 使用深度偏差来解决问题。

【讨论】:

    【解决方案2】:

    我认为您正在尝试进行共面渲染。查看glPolygonOffset(),而不是像您那样使用小 Z 偏移。

    【讨论】:

    • 感谢您的回复。是的,我正在尝试进行共面渲染。 glPolygonOffset() 如何比使用小的 z 偏移更稳定,无论如何我如何在我的代码中使用它?如何选择 glPolygonOffset() 的两个参数以及在代码中放置 glPolygonOffset() 调用的位置。
    【解决方案3】:

    这是我从你的代码中得到的,用gcc -std=c99 -lGL -lGLU -lglut a.c 编译:没有污迹。可以发你的吗? (Ubuntu 11.10,英特尔 GPU)

    【讨论】:

    • 您好,谢谢您的回复,例如顶面全是蓝色而不是方格。现在尝试输入 j、k、h、l 来移动立方体。请参阅上面我发布图片的链接。有污迹(还有带有 gcc -std=c99 foo.c -lGL -lGLU -lglut 的 Ubuntu 11.10
    • 如果我旋转立方体,它是“稳定的”,至少在这里。根据您发布的内容,我猜一些顶点彼此非常接近,并且哪个三角形赢得表面在数值上是不稳定的。不过没有详细阅读代码。
    • 我在带有 Ubuntu 11.10 的 Oracle VirtualBox 中运行我的代码这一事实有什么不同吗?我的显卡是 NVIDIA GeForce 410M。
    • 似乎驱动程序是唯一的区别。其他答案似乎也证实了我建议的 z 坐标不稳定性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多