OpenGL SkyBox没有显示

时间:2012-03-06 13:03:57

标签: c++ opengl draw

我正在使用openGL c ++创建一个天空盒,现在我按照天空盒上的一些教程,我已经设置了所有图像,但我的天空盒根本没有被绘制! (我只看到黑色的opengl背景)

所以这是我的代码,可能是什么问题?我正在看它几个小时,找不到东西,我是openGL的新手,所以如果你发现任何不好的代码请告诉我!谢谢!

 #include <iostream>
#include <stdlib.h>


#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include "imageloader.h"

using namespace std;

//angle of rotation
GLfloat xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0;
GLuint _textureId;           //The OpenGL id of the texture
GLuint _skybox[5];
float lastx, lasty;
bool leftMouseButton = false;
float PI = 3.141592654f;

//Makes the image into a texture, and returns the id of the texture
GLuint __loadTexture(Image* image) {
    GLuint textureId;
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glTexImage2D(GL_TEXTURE_2D,
        0,
        GL_RGB,
        image->width, image->height,
        0,
        GL_RGB,
        GL_UNSIGNED_BYTE,
        image->pixels);
    return textureId;
}


GLuint __loadMipmappedTexture(Image *image) {
    GLuint textureId;
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);
    gluBuild2DMipmaps(GL_TEXTURE_2D,
                      GL_RGB,
                      image->width, image->height,
                      GL_RGB,
                      GL_UNSIGNED_BYTE,
                      image->pixels);
    return textureId;
}
void initRendering() {
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_NORMALIZE);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_CULL_FACE);
    glShadeModel (GL_SMOOTH); //set the shader to smooth shader

    Image* image = loadBMP("artesis.bmp");
    _textureId = __loadMipmappedTexture(image);
    image = loadBMP("skybox/deep_ft.bmp");
    _skybox[0] = __loadMipmappedTexture(image);
    image = loadBMP("skybox/deep_lf.bmp");
    _skybox[1] = __loadMipmappedTexture(image);
    image = loadBMP("skybox/deep_bk.bmp");
    _skybox[2] = __loadMipmappedTexture(image);
    image = loadBMP("skybox/deep_rt.bmp");
    _skybox[3] = __loadMipmappedTexture(image);
    image = loadBMP("skybox/deep_up.bmp");
    _skybox[4] = __loadMipmappedTexture(image);
    image = loadBMP("skybox/deep_dn.bmp");
    _skybox[5] = __loadMipmappedTexture(image);
    delete image;

}

void handleResize(int w, int h) {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, (double)w / (double)h, 1.0, 100.0);
    glViewport (0, 0, w, h);
    glMatrixMode(GL_MODELVIEW);
    glutPostRedisplay();
}

void mouseMovement(int x, int y) {

    if (leftMouseButton == true)
    {
        GLfloat diffx = (x-lastx)/20; //check the difference between the current x and the last x position
        GLfloat diffy = (y-lasty)/20; //check the difference between the current y and the last y position
        lastx = x; //set lastx to the current x position
        lasty = y; //set lasty to the current y position

        xrot += (float) diffy; //set the xrot to xrot with the addition of the difference in the y position
        yrot += (float) diffx;    //set the xrot to yrot with the addition of the difference in the x position
    }
    else if( leftMouseButton == false)
    {
        GLfloat diffx = x-lastx; //check the difference between the current x and the last x position
        GLfloat diffy = y-lasty; //check the difference between the current y and the last y position
        lastx = x; //set lastx to the current x position
        lasty = y; //set lasty to the current y position
    }
}

void mouseButtons(int button, int state, int x, int y) {
    if ((state == GLUT_DOWN) && (button == GLUT_LEFT_BUTTON)) 
    {
        leftMouseButton = true;
    }

    else if ((state == GLUT_DOWN) && (button == GLUT_RIGHT_BUTTON)) 
    {
        leftMouseButton = false;
    }
}

void drawGrid(float size, float step)
{
    // disable lighting
    glDisable(GL_LIGHTING);

    glBegin(GL_LINES);

    glColor3f(0.3f, 0.3f, 0.3f);
    for(float i=step; i <= size; i+= step)
    {
        glVertex3f(-size, 0,  i);   // lines parallel to X-axis
        glVertex3f( size, 0,  i);
        glVertex3f(-size, 0, -i);   // lines parallel to X-axis
        glVertex3f( size, 0, -i);

        glVertex3f( i, 0, -size);   // lines parallel to Z-axis
        glVertex3f( i, 0,  size);
        glVertex3f(-i, 0, -size);   // lines parallel to Z-axis
        glVertex3f(-i, 0,  size);
    }

    // x-axis
    glColor3f(0.5f, 0, 0);
    glVertex3f(-size, 0, 0);
    glVertex3f( size, 0, 0);

    // z-axis
    glColor3f(0,0,0.5f);
    glVertex3f(0, 0, -size);
    glVertex3f(0, 0,  size);

    glEnd();

    // enable lighting back
    glEnable(GL_LIGHTING);
}

void keyboard (unsigned char key, int x, int y) {
    float xrotrad, yrotrad;
    switch(key) {
    case 'a':
        xrot += 1;
        if(xrot > 360) xrot -= 360;
        break;
    case 'w':
        xrot -= 1;
        if(xrot < -360) xrot += 360;
        break;
    case 'z':   
        yrotrad = (yrot / 180 * PI);
        xrotrad = (xrot / 180 * PI); 
        xpos += float(sin(yrotrad));
        zpos -= float(cos(yrotrad));
        ypos -= float(sin(xrotrad));
        break;
    case 's':   
        yrotrad = (yrot / 180 * PI);
        xrotrad = (xrot / 180 * PI); 
        xpos -= float(sin(yrotrad));
        zpos += float(cos(yrotrad));
        ypos += float(sin(xrotrad));
        break;
    case 'd':
        yrot += 1;
        if (yrot >360) yrot -= 360;
        break;
    case 'q':
        yrot -= 1;
        if (yrot < -360)yrot += 360;
        break;

    case 27:
        exit(0);
        break;
    }
}

void camera (void) {
    glRotatef(xrot,1.0,0.0,0.0);  //rotate our camera on teh x-axis (left and right)
    glRotatef(yrot,0.0,1.0,0.0);  //rotate our camera on the y-axis (up and down)
    glTranslated(-xpos,-ypos,-zpos); //translate the screen to the position of our camera
}

void drawScene() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    GLfloat lightKa[] = {.0f, .0f, .0f, 1.0f};      // ambient light
    GLfloat lightKd[] = {.9f, .9f, .9f, 1.0f};      // diffuse light
    GLfloat lightKs[] = {1, 1, 1, 1};               // specular light
    glLightfv(GL_LIGHT0, GL_AMBIENT, lightKa);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightKd);
    glLightfv(GL_LIGHT0, GL_SPECULAR, lightKs);

    // position the light
    float lightPos[4] = {0, 10, 10, 0};
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

    camera();

    //call the skybox
    // Store the current matrix
    glPushMatrix();

    // Reset and transform the matrix.
    glLoadIdentity();

    /* EDIT: I really dont know how to set gluLookAt, I guess it should be the camera positions??? */
    gluLookAt(
        0.0,0.0,0.0,
        0.1, 0.0, 0.1,
        0.0,1.0,0.0);

    // Enable/Disable features
    glPushAttrib(GL_ENABLE_BIT);
    glEnable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);
    glDepthMask(false);
    glDisable(GL_LIGHTING);
    glDisable(GL_BLEND);

    // Just in case we set all vertices to white.
    glColor4f(1,1,1,1);

    // Render the front quad
    glBindTexture(GL_TEXTURE_2D, _skybox[0]);
    glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex3f(  0.5f, -0.5f, -0.5f );
        glTexCoord2f(1, 0); glVertex3f( -0.5f, -0.5f, -0.5f );
        glTexCoord2f(1, 1); glVertex3f( -0.5f,  0.5f, -0.5f );
        glTexCoord2f(0, 1); glVertex3f(  0.5f,  0.5f, -0.5f );
    glEnd();

    // Render the left quad
    glBindTexture(GL_TEXTURE_2D, _skybox[1]);
    glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex3f(  0.5f, -0.5f,  0.5f );
        glTexCoord2f(1, 0); glVertex3f(  0.5f, -0.5f, -0.5f );
        glTexCoord2f(1, 1); glVertex3f(  0.5f,  0.5f, -0.5f );
        glTexCoord2f(0, 1); glVertex3f(  0.5f,  0.5f,  0.5f );
    glEnd();

    // Render the back quad
    glBindTexture(GL_TEXTURE_2D, _skybox[2]);
    glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex3f( -0.5f, -0.5f,  0.5f );
        glTexCoord2f(1, 0); glVertex3f(  0.5f, -0.5f,  0.5f );
        glTexCoord2f(1, 1); glVertex3f(  0.5f,  0.5f,  0.5f );
        glTexCoord2f(0, 1); glVertex3f( -0.5f,  0.5f,  0.5f );

    glEnd();

    // Render the right quad
    glBindTexture(GL_TEXTURE_2D, _skybox[3]);
    glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex3f( -0.5f, -0.5f, -0.5f );
        glTexCoord2f(1, 0); glVertex3f( -0.5f, -0.5f,  0.5f );
        glTexCoord2f(1, 1); glVertex3f( -0.5f,  0.5f,  0.5f );
        glTexCoord2f(0, 1); glVertex3f( -0.5f,  0.5f, -0.5f );
    glEnd();

    // Render the top quad
    glBindTexture(GL_TEXTURE_2D, _skybox[4]);
    glBegin(GL_QUADS);
        glTexCoord2f(0, 1); glVertex3f( -0.5f,  0.5f, -0.5f );
        glTexCoord2f(0, 0); glVertex3f( -0.5f,  0.5f,  0.5f );
        glTexCoord2f(1, 0); glVertex3f(  0.5f,  0.5f,  0.5f );
        glTexCoord2f(1, 1); glVertex3f(  0.5f,  0.5f, -0.5f );
    glEnd();

    // Render the bottom quad
    glBindTexture(GL_TEXTURE_2D, _skybox[5]);
    glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex3f( -0.5f, -0.5f, -0.5f );
        glTexCoord2f(0, 1); glVertex3f( -0.5f, -0.5f,  0.5f );
        glTexCoord2f(1, 1); glVertex3f(  0.5f, -0.5f,  0.5f );
        glTexCoord2f(1, 0); glVertex3f(  0.5f, -0.5f, -0.5f );
    glEnd();

    // Restore enable bits and matrix
    glPopAttrib();
    glPopMatrix();
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_BLEND);
    glDepthMask(true);
    glClear(GL_DEPTH_BUFFER_BIT);

    drawGrid(20, 1);

    glutSwapBuffers(); //swap the buffers

}

void update(int value) {
    angle++; //increase the angle
    glutPostRedisplay(); //Tell GLUT that the display has changed

    //Tell GLUT to call update again in 25 milliseconds
    glutTimerFunc(25, update, 0);
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(800, 800);

    glutCreateWindow("Block Position");
    initRendering();

    glutDisplayFunc(drawScene);
    glutKeyboardFunc(keyboard);
    glutIdleFunc(drawScene);

    glutReshapeFunc(handleResize);
    glutPassiveMotionFunc(mouseMovement); 
    glutTimerFunc(25, update, 0); //Add a timer
    glutMouseFunc(mouseButtons);
    glutMainLoop();
    return 0;
}

2 个答案:

答案 0 :(得分:2)

如果没有任何内容出现,可能是因为天空框不在场景中,因为它在屏幕上culled(或未呈现)。

在代码中,您为100.0指定了zFar

gluPerspective(45.0, (double)w / (double)h, 1.0, 100.0);

更改zFar值以适应天空盒的大小(比如500.0),它应该出现。

答案 1 :(得分:1)

你应该从最小的渲染开始,比如没有闪电,没有面部剔除,只有白色的三角形。因此,如果您看到白色,那么至少您的相机位置可能正常。然后你可以启用剔除,如果全部消失,那么这就是你的问题 - 法线方向错误。然后,如果一切正常,则启用照明,然后进行纹理处理 - 并始终检查更改内容。

所以不要太难看,但要消除复杂性 - 甚至检查一下简单的trianlge是否会出现在预期的位置。