背景纹理。切换到ortho然后切换回3d

时间:2013-03-29 05:19:36

标签: opengl

我正在处理背景纹理。我想要做的是我想要设置背景图像。为了在我的代码中我使用切换到ortho,绘制一个充满窗口大小的正方形,纹理它。然后切换回3d并绘制3D图像。它绘制背景纹理和雪人,但它们都会在一秒钟内消失。我不知道错误代码在哪里。我认为必须与推动和弹出矩阵有关。下面是我的InitGl,draw()和drawnowman(),main和reshape()的代码。我认为问题是在3D到2d之间的swithc期间的draw()函数。建议?

int main (int argc, char **argv) 
{
     glutInit (&argc, argv);
     glutInitDisplayMode (GLUT_DOUBLE);
     glutInitWindowSize (500, 500);
     glutInitWindowPosition (100, 100);
     glutCreateWindow ("A basic OpenGL Window");
     glutKeyboardFunc(key);

     if( !initGL() ) {                                                   // NEW (16)
        printf( "Unable to initialize graphics library!\n" );
        return 1;
    }

     glutDisplayFunc (display);
    // glutIdleFunc (display);
    glutIdleFunc(idle);
     glutReshapeFunc (reshape);

    //Load our texture
     texture = LoadTexture( "texture.bmp", 256, 256 );

    glutMainLoop ();

    //Free our texture
     FreeTexture( texture );

    return 0;
 }


void drawSnowMan(void)
{
    GLUquadricObj *pObj;
    //glDisable(GL_TEXTURE_2D);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

// save the world matrix
    glPushMatrix();

        glTranslatef(xpos, -0.5, -5.0);
        glRotated(rotX,1,0,0);                             // ******** NEW (11)
        glRotated(rotY,0,1,0);
        pObj = gluNewQuadric();
        gluQuadricNormals(pObj, GLU_SMOOTH);
    //glRotated(rotZ,0,0,1);

    glPushMatrix();
        //setting up light effect for base, mid and head spheres. all red!
        ambient[0] = 1.0; ambient[1] = 0.0; ambient[2] = 0.0;
        diffuse[0] = 1.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
        specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
        glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
        glMaterialfv(GL_FRONT, GL_SHININESS, shiness);

        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        //glTranslatef(0.0 ,0.75f, 0.0f);
        //bottom sphere. dont need to gltranslate again because it will use the previous gltranslate
        //which is declared outside
        glutSolidSphere(0.70f,20,20);

        //mid sphere
        glTranslatef(0.0f, 1.0f, 0.0f);
        glutSolidSphere(0.45f,20,20);

        //top sphere
        glTranslatef(0.0f, 0.6f, 0.0f);
        glutSolidSphere(0.30f,20,20);

        //eyes

    glDisable(GL_LIGHTING);
    glDisable(GL_LIGHT0);
    glPopMatrix();

    //drawing hat
    glPushMatrix();
            //black color. move it 1.85 in y position because thats where the head is
            //rotate the cylinder and draw cylinder
            glColor3f(0.0f, 0.0f, 0.0f);
            glTranslatef(0.0f, 1.85f, 0.0f);
            glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
            gluCylinder(pObj, 0.17f, 0.17f, 0.4f, 26, 13);

            //drawing brim. disable cull_face. draw disk, so front part. disabl
             glDisable(GL_CULL_FACE);
            gluDisk(pObj, 0.17f, 0.28f, 26, 13);
            glEnable(GL_CULL_FACE);


            glTranslatef(0.0f, 0.0f, 0.40f);
             gluDisk(pObj, 0.17f, 0.28f, 26, 13);
    glPopMatrix();

    glPushMatrix();

        glPushMatrix();
        glColor3f(1.0,1.0,1.0);
        glTranslatef(2.0f, 1.0f, 0.0f);
        glRotatef(90.0,0.0, 0.0,-5.0);
        glScalef (0.01, 0.2, 0.06);      /* modeling transformation */
        //glutSolidCone(0.1, 0.1, 10.0, 14.0);
        glutSolidCube(1.5);

        glPopMatrix();

        glPushMatrix();

        glTranslatef(2.0f, 0.8f, 0.0f);
        glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
        gluCylinder(pObj, 0.04f, 0.04f, 0.2f, 26, 13);

        glPopMatrix();

        //blade
        glPushMatrix();
            ambient[0] = 0.0; ambient[1] = 1.0; ambient[2] = 0.0;
            diffuse[0] = 1.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
            specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
            glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
            glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
            glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
            glMaterialfv(GL_FRONT, GL_SHININESS, shiness);

            glEnable(GL_LIGHTING);
            glEnable(GL_LIGHT1);

            glTranslatef(2.0f, 1.0f, 0.0f);
            glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
            gluCylinder(pObj, 0.03f, 0.03f, 1.1f, 26, 13);

            glDisable(GL_LIGHTING);
            glDisable(GL_LIGHT0);
        glPopMatrix();

    glPopMatrix();

    //big push matrix for eyes, and nose
    glPushMatrix();
        //eyes color = black light. set defuse all 0, ambient = black. turns the eyes black
        /*ambient[0] = 0.0; ambient[1] = 0.0; ambient[2] = 0.0;
        diffuse[0] = 0.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
        specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
        glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
        glMaterialfv(GL_FRONT, GL_SHININESS, shiness);*/

        glColor3f(0.0, 0.0, 0.0);

        //left eye
        glPushMatrix();
            glTranslatef(-0.17, 1.7, 0.25 );
            glutSolidSphere(0.05, 10.0, 10.0);
        glPopMatrix();

        //right eye
        glPushMatrix();
            glTranslatef(0.17, 1.7, 0.25 );
            glutSolidSphere(0.05, 10.0, 10.0);
        glPopMatrix();

        //drawing nose
        glPushMatrix();
            glTranslatef(0.0, 1.6, 0.25 );
            glutSolidCone(0.08f,0.5f,10,2);
        glPopMatrix();

    glPopMatrix(); // end big push matrix for eyes and nose


glPopMatrix();

} // end of drawsnowman()


void display (void) {
     glClearColor(0.25f, 0.25f, 0.50f, 1.0f ); // blueish color
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   // glLoadIdentity();

    // MODEL VIEW is set up in IniitGL
    //so save it
    glPushMatrix();
            //switch to projection matrix
            //swithc to ortho.
            //draw texture
         glMatrixMode(GL_PROJECTION);
         glLoadIdentity();
         glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, -1.0);
         glDisable(GL_DEPTH_TEST);
         glDisable(GL_LIGHTING);
         glDepthMask(GL_FALSE);
         glMatrixMode(GL_MODELVIEW);
         glLoadIdentity();

         glEnable(GL_TEXTURE_2D);
         glBindTexture(GL_TEXTURE_2D, texture);


// Draw a textured quad
        glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
        glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
        glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
        glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
        glEnd();


        glDepthMask(GL_TRUE);
        glEnable(GL_DEPTH_TEST);

    glPopMatrix();// pop the 3d model view
    glMatrixMode(GL_PROJECTION);
        glMatrixMode(GL_MODELVIEW);


// You can ignore this. just a different of way drawing texture and still does not work
   /* glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, -1.0);


    glDisable(GL_DEPTH_TEST);
 glDisable(GL_LIGHTING);
 glDepthMask(GL_FALSE);
    glMatrixMode(GL_MODELVIEW);


   glPushMatrix();

   glDepthMask( false );
    glLoadIdentity();


    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);


// Draw a textured quad
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
    glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
    glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
    glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
    glEnd();


    glDepthMask(GL_TRUE);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    /*glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective (60, 800 / 600, 1.0, 100.0);;
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(  0.0, 0.0, 0.0,  // Where would the camera be?
                0.0, 0.0,-1.0,  // Where would it be looking?
                0.0, 1.0, 0.0); // What would be the "up" vector?fa*/


   /* glDisable(GL_TEXTURE_2D);
    glPopMatrix();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    //gluPerspective (45, SCREEN_WIDTH / SCREEN_HEIGHT, 1.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();*/

      drawSnowMan(); // draw snow man


     glutSwapBuffers();
     angle ++;
 }

 void reshape (int w, int h) {
     glViewport (0, 0, (GLsizei)w, (GLsizei)h);
     glMatrixMode (GL_PROJECTION);
     glLoadIdentity ();
     gluPerspective (45, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
     glMatrixMode (GL_MODELVIEW);
 }

bool initGL (void) {

    glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    // Switch to the "camera" mode
    glMatrixMode(GL_PROJECTION);  // Camera
    glLoadIdentity();

    // Change the camera to a 3D view
    glFrustum( -1 * (float) SCREEN_WIDTH / SCREEN_HEIGHT,
                    (float) SCREEN_WIDTH / SCREEN_HEIGHT,
                    -1.0,
                     1.0,
                     1.5,
                     1000.0);

   glClearColor(0.25f, 0.25f, 0.50f, 1.0f );

    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);                         // NEW (5)
    glEnable(GL_LINE_SMOOTH);                                       // NEW (6)

    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);                      // NEW (7)
    glEnable(GL_POLYGON_SMOOTH);                                    // NEW (8)

    // this is a specular light
    GLfloat mat_specular[] = { 1.0 , 1.0 , 1.0 , 1.0 };    // Color of a "shiny material
    GLfloat mat_shininess[] = { 50.0 };                 // How shiny is it?
   // GLfloat mat_ambient_and_diffuse[] = { 0.0, 1.0, 0.0, 1.0 };

    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };  // Infinitely far away. Direction light
    GLfloat light_position1[] = {2.0,1.5,0.0,1.0}; // saber light


    // How to calculate the surface normal for pixels
    glShadeModel(GL_SMOOTH); // Try this as well GL_FLAT

    // Setup up some material reflective properties
   // glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   // glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
    //glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_and_diffuse);
    //glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_ambient_and_diffuse);

    // Finally actually make the light
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glLightfv(GL_LIGHT1, GL_POSITION, light_position1);

    //Check for error
    GLenum error = glGetError();                                    // NEW (9)
    if( error != GL_NO_ERROR ) {
        printf( "Error initializing OpenGL! %s\n", gluErrorString( error ) );
        return false;
    }

    return true;
}

void idle(void) {
    glutPostRedisplay();
}

2 个答案:

答案 0 :(得分:1)

重新认识新手误解:OpenGL“初始化”。

OpenGL 未初始化!您在 initGL 重塑中的所有代码都属于显示。

在调用 glLight ... 的情况下,在将模型视图矩阵设置到您希望灯光所在的空间中后,将必须放置在显示中。此外,OpenGL是不是;是的,最初OpenGL中的'L'确实意味着库,但我将它回溯到 Layer ,因为它就是大多数现代图形系统的原因:最终用户程序与GPU及其驱动程序之间的层

我认为一旦您将代码从 initGL 重塑移动到 display ,解决方案应该变得清晰:您可以更改,重置和随时修改投影和模型视图矩阵。要使显示中的窗口宽度和高度可以将它们存储在 reshape 中的全局变量中,或者首选解决方案,请使用glutGet(GLUT_WINDOW_WIDTH)glutGet(GLUT_WINDOW_HEIGHT)来查询窗口尺寸。显示功能。

你想在正投影中绘制东西吗?然后适当地设置投影和模型视图。切换到一个角度?就这么做。

答案 1 :(得分:0)

我想我有点弄清楚为什么我的背景纹理会不断消失。我有Cullface和深度的东西打开。我把它关掉了弹出最后一个矩阵然后就可以了。

然而,有一个问题。纹理图像是雪背景,但它变成全红色。所以首先我认为这是由于snowgirl照明的反射。我关掉了所有的灯,仍然是红色的。无法弄清楚为什么。可能是,纹理颜色与雪人的原始颜色融为一体吗?