2011-11-11 69 views
2

我試圖編寫一個接口到rubik的多維數據集。OpenGL:在圖像表面上繪製的污跡

然而,當我畫它有立方體的臉上污跡:

Cube

這裏是很好的註釋代碼。有人可以幫助我,也許運行代碼並告訴我哪裏可能會出錯?

#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; 

} 

OK,我已經修改了代碼,這樣我畫個青色長方形0.01F部件的後面,而不是0.001f單位後面,這似乎有固定的z戰鬥。不過我也喜歡使用glPolygonOffset(係數,單位)來解決這個問題,但我無法做到這一點,有以下原因 :

  1. 我不知道如何設置facor和單元(I我已經試過1.0)。
  2. 我試過不同的值,沒有結果。

這裏是沒有出血/拼接/ Z-戰鬥代碼:

#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; 

} 
+2

「立方體表面有污跡」。任何形象的機會? – Bart

+1

我建議使用溫和的清潔劑和軟布。 – Throwback1986

+0

你好,我不確定如何在堆棧溢出中包含圖像,所以我在PicasaWeb上共享一個:![link](https://picasaweb.google.com/johngoche99/OpenGL#5673826643990873458) –

回答

1

這是我從你的代碼,以gcc -std=c99 -lGL -lGLU -lglut a.c編譯得到:不暈染。你可以發佈你的嗎? (Ubuntu的11.10,英特爾GPU)

local screenshot

+0

嗨,感謝您的回覆,如頂面是全藍色的,而不是現在嘗試輸入j,k,h,l來移動立方體,查看上面的鏈接,我已經發布了一個圖像,還有一些污跡(還有Ubuntu 11.10,gcc -std = c99 foo.c -lGL -lGLU -lglut –

+0

如果我旋轉它,這個立方體是「穩定的」,至少在這裏。從你發佈的內容來看,我猜想一些頂點彼此非常接近,哪個三角形贏得表面的數值不穩定。 – eudoxos

+0

是否我在Oracle VirtualBox中運行我的代碼與Ubuntu 11.10有所不同?我的顯卡是NVIDIA GeForce 410M。 –

2

我認爲你正在試圖做的共面的渲染。看看glPolygonOffset(),而不是像你一樣使用小Z偏移量。

+0

謝謝你的回覆。是的,我正在嘗試做共面渲染。 glPolygonOffset()如何比使用小的z偏移更穩定,以及如何在代碼中使用它?如何選擇glPolygonOffset()的兩個參數以及將glPolygonOffset()調用放在代碼中的位置。 –

5

我認爲你正在將你的棋子畫成你的主立方體面的共面四邊形;如果是這種情況,你遇到的問題就叫做「z戰鬥」。

你可以看看點12.040深度緩衝似乎可行,但多邊形似乎流過了面前的多邊形。這是怎麼回事?這裏: http://www.opengl.org/resources/faq/technical/depthbuffer.htm

基本上,你的深度緩衝沒有足夠的精度來解決,以顯示這四對每個像素,造成問題的原因。

您可以手動將偏移量添加到檢查器四邊形,以將它們從多維數據集移開;或通過glPolygonOffset使用深度偏差來解決問題。