OpenGL球面照相机:立方体渲染不正确

时间:2021-07-20 18:16:30

I implement a simple sphere camera by using OpenGL and I render a cube for observasion. But the cube is not displayed correctly. Like this:

我使用OpenGL实现了一个简单的球面相机,我渲染了一个立方体来观察。但是立方体没有正确显示。是这样的:

OpenGL球面照相机:立方体渲染不正确

Some surfaces of the cube are invisible, some are not. Can someone solve the problem? Here is the code:

有些立方体的表面是看不见的,有些则不是。有人能解决这个问题吗?这是代码:

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

Left click for rotation, and right click to change the radius.

左击旋转,右击改变半径。

1 个解决方案

#1


3  

Request a depth buffer:

请求一个深度缓冲:

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

And enable depth testing:

并启用深度测试:

glEnable(GL_DEPTH_TEST);

#1


3  

Request a depth buffer:

请求一个深度缓冲:

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

And enable depth testing:

并启用深度测试:

glEnable(GL_DEPTH_TEST);