我使用OpenGL實現了一個簡單的球形攝像機,並渲染了一個用於觀測的立方體。但立方體顯示不正確。就像這樣:OpenGL球形攝像機:立方體渲染不正確
立方體的一些表面是看不見的,有些則不是。有人能解決這個問題嗎?這裏是代碼:
#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;
}
左鍵單擊旋轉,然後右鍵單擊以更改半徑。
你確定你有頂點繞組是否正確? IME是OpenGL中最大的罪魁禍首,那就是當你沒有將頂點逆時針列在面向多邊形前面的攝像機上時。雖然我讀了太多的三維頂點座標,但是我的大腦開始溢出,所以我沒有自己驗證它。只是一個想法。 – LinearZoetrope
什麼是「球形相機」?你似乎只是在z和x/y旋轉中做翻譯。 –
@Jsor:繞組看起來對我很正確。 –