2014-04-22 44 views
1

我使用OpenGL實現了一個簡單的球形攝像機,並渲染了一個用於觀測的立方體。但立方體顯示不正確。就像這樣:OpenGL球形攝像機:立方體渲染不正確

enter image description here

立方體的一些表面是看不見的,有些則不是。有人能解決這個問題嗎?這裏是代碼:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <math.h> 

#include <gl/glut.h> 

#define MAX_EPSILON_ERROR 10.0f 
#define THRESHOLD   0.30f 
#define REFRESH_DELAY  10 //ms 
//////////////////////////////////////////////////////////////////////////////// 
// constants 
const unsigned int window_width = 512; 
const unsigned int window_height = 512; 

// mouse controls 
int mouse_old_x, mouse_old_y; 
int mouse_buttons = 0; 
float rotate_x = 0.0, rotate_y = 0.0; 
float translate_z = -3.0; 

// Auto-Verification Code 
int fpsCount = 0;  // FPS count for averaging 
int fpsLimit = 1;  // FPS limit for sampling 
int g_Index = 0; 
float avgFPS = 0.0f; 
unsigned int frameCount = 0; 
unsigned int g_TotalErrors = 0; 
bool g_bQAReadback = false; 

int *pArgc = NULL; 
char **pArgv = NULL; 

#define MAX(a,b) ((a > b) ? a : b) 

//////////////////////////////////////////////////////////////////////////////// 
// declaration, forward 
void cleanup(); 

// GL functionality 
bool initGL(int *argc, char **argv); 

// rendering callbacks 
void display(); 
void keyboard(unsigned char key, int x, int y); 
void mouse(int button, int state, int x, int y); 
void motion(int x, int y); 
void timerEvent(int value); 

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

    // First initialize OpenGL context 
    if (false == initGL(&argc, argv)) 
    { 
     return false; 
    } 

    // register callbacks 
    glutDisplayFunc(display); 
    glutKeyboardFunc(keyboard); 
    glutMouseFunc(mouse); 
    glutMotionFunc(motion); 

    // start rendering mainloop 
    glutMainLoop(); 
    atexit(cleanup); 
    return 0; 
} 


//////////////////////////////////////////////////////////////////////////////// 
//! Initialize GL 
//////////////////////////////////////////////////////////////////////////////// 
bool initGL(int *argc, char **argv) 
{ 
    glutInit(argc, argv); 
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 
    glutInitWindowSize(window_width, window_height); 
    glutCreateWindow("Cuda GL Interop (VBO)"); 
    glutDisplayFunc(display); 
    glutKeyboardFunc(keyboard); 
    glutMotionFunc(motion); 
    glutTimerFunc(REFRESH_DELAY, timerEvent,0); 

    //// initialize necessary OpenGL extensions 
    //glewInit(); 

    //if (! glewIsSupported("GL_VERSION_2_0 ")) 
    //{ 
    // fprintf(stderr, "ERROR: Support for necessary OpenGL extensions missing."); 
    // fflush(stderr); 
    // return false; 
    //} 

    // default initialization 
    glClearColor(0.0, 0.0, 0.0, 1.0); 
    glDisable(GL_DEPTH_TEST); 

    // viewport 
    glViewport(0, 0, window_width, window_height); 

    // projection 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(60.0, (GLfloat)window_width/(GLfloat) window_height, 2, 10.0); 

// SDK_CHECK_ERROR_GL(); 

    return true; 
} 

//////////////////////////////////////////////////////////////////////////////// 
//! Display callback 
//////////////////////////////////////////////////////////////////////////////// 
void display() 
{ 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // set view matrix 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glTranslatef(0.0, 0.0, translate_z); 
    glRotatef(rotate_x, 1.0, 0.0, 0.0); 
    glRotatef(rotate_y, 0.0, 1.0, 0.0); 


    glBegin(GL_QUADS); 
     glColor3f(0.0f, 1.0f, 0.0f);   // 顏色改成綠色 
     glVertex3f(1.0f, 1.0f,-1.0f);   // 四邊形的右上頂點 (頂面) 
     glVertex3f(-1.0f, 1.0f,-1.0f);   // 四邊形的左上頂點 (頂面) 
     glVertex3f(-1.0f, 1.0f, 1.0f);   // 四邊形的左下頂點 (頂面) 
     glVertex3f(1.0f, 1.0f, 1.0f);   // 四邊形的右下頂點 (頂面) 

     glColor3f(1.0f,0.5f,0.0f);    // 顏色改成橙色 
     glVertex3f(1.0f,-1.0f, 1.0f);   // 四邊形的右上頂點(底面) 
     glVertex3f(-1.0f,-1.0f, 1.0f);   // 四邊形的左上頂點(底面) 
     glVertex3f(-1.0f,-1.0f,-1.0f);   // 四邊形的左下頂點(底面) 
     glVertex3f(1.0f,-1.0f,-1.0f);   // 四邊形的右下頂點(底面) 

     glColor3f(1.0f,0.0f,0.0f);    // 顏色改成紅色 
     glVertex3f(1.0f, 1.0f, 1.0f);   // 四邊形的右上頂點(前面) 
     glVertex3f(-1.0f, 1.0f, 1.0f);   // 四邊形的左上頂點(前面) 
     glVertex3f(-1.0f,-1.0f, 1.0f);   // 四邊形的左下頂點(前面) 
     glVertex3f(1.0f,-1.0f, 1.0f);   // 四邊形的右下頂點(前面) 

     glColor3f(1.0f,1.0f,0.0f);    // 顏色改成黃色 
     glVertex3f(1.0f,-1.0f,-1.0f);   // 四邊形的右上頂點(後面) 
     glVertex3f(-1.0f,-1.0f,-1.0f);   // 四邊形的左上頂點(後面) 
     glVertex3f(-1.0f, 1.0f,-1.0f);   // 四邊形的左下頂點(後面) 
     glVertex3f(1.0f, 1.0f,-1.0f);   // 四邊形的右下頂點(後面) 

     glColor3f(0.0f,0.0f,1.0f);    // 顏色改成藍色 
     glVertex3f(-1.0f, 1.0f, 1.0f);   // 四邊形的右上頂點(左面) 
     glVertex3f(-1.0f, 1.0f,-1.0f);   // 四邊形的左上頂點(左面) 
     glVertex3f(-1.0f,-1.0f,-1.0f);   // 四邊形的左下頂點(左面) 
     glVertex3f(-1.0f,-1.0f, 1.0f);   // 四邊形的右下頂點(左面) 

     glColor3f(1.0f,0.0f,1.0f);    // 顏色改成紫羅蘭色 
     glVertex3f(1.0f, 1.0f,-1.0f);   // 四邊形的右上頂點(右面) 
     glVertex3f(1.0f, 1.0f, 1.0f);   // 四邊形的左上頂點(右面) 
     glVertex3f(1.0f,-1.0f, 1.0f);   // 四邊形的左下頂點(右面) 
     glVertex3f(1.0f,-1.0f,-1.0f);   // 四邊形的右下頂點(右面) 
    glEnd(); 

    glutSwapBuffers(); 
} 

void timerEvent(int value) 
{ 
    glutPostRedisplay(); 
    glutTimerFunc(REFRESH_DELAY, timerEvent,0); 
} 

void cleanup() 
{ 
    //sdkDeleteTimer(&timer); 
} 

//////////////////////////////////////////////////////////////////////////////// 
//! Keyboard events handler 
//////////////////////////////////////////////////////////////////////////////// 
void keyboard(unsigned char key, int /*x*/, int /*y*/) 
{ 
    switch (key) 
    { 
    case (27) : 
     exit(EXIT_SUCCESS); 
     break; 
    } 
} 

//////////////////////////////////////////////////////////////////////////////// 
//! Mouse event handlers 
//////////////////////////////////////////////////////////////////////////////// 
void mouse(int button, int state, int x, int y) 
{ 
    if (state == GLUT_DOWN) 
    { 
     mouse_buttons |= 1<<button; 
    } 
    else if (state == GLUT_UP) 
    { 
     mouse_buttons = 0; 
    } 

    mouse_old_x = x; 
    mouse_old_y = y; 
} 

void motion(int x, int y) 
{ 
    float dx, dy; 
    dx = (float)(x - mouse_old_x); 
    dy = (float)(y - mouse_old_y); 

    if (mouse_buttons & 1) 
    { 
     rotate_x += dy * 0.2f; 
     rotate_y += dx * 0.2f; 
    } 
    else if (mouse_buttons & 4) 
    { 
     translate_z += dy * 0.01f; 
    } 

    mouse_old_x = x; 
    mouse_old_y = y; 
} 

左鍵單擊旋轉,然後右鍵單擊以更改半徑。

+0

你確定你有頂點繞組是否正確? IME是OpenGL中最大的罪魁禍首,那就是當你沒有將頂點逆時針列在面向多邊形前面的攝像機上時。雖然我讀了太多的三維頂點座標,但是我的大腦開始溢出,所以我沒有自己驗證它。只是一個想法。 – LinearZoetrope

+0

什麼是「球形相機」?你似乎只是在z和x/y旋轉中做翻譯。 –

+0

@Jsor:繞組看起來對我很正確。 –

回答

3

請求深度緩衝:

glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE); 
        ^^^^^^^^^^ 

而且使深度測試:

glEnable(GL_DEPTH_TEST); 
+0

非常感謝!你能告訴我爲什麼添加深度緩衝後,它是正確的嗎? –

+0

在沒有深度緩衝區的情況下啓用深度測試不會執行任何操作。如果沒有進行深度測試,您的四邊形/三角形將按照您發送的順序繪製到幀緩衝區中,以便稍後幾何圖形有可能覆蓋較早的事物。 – genpfault