使用openGL向元素添加纹理

时间:2014-01-02 20:57:42

标签: c++ opengl texture2d

我试图用openGL建立长颈鹿。我已经做了身体和走路,但我想添加我找到的纹理。我正在添加我的代码供您查看。

#define _CRT_SECURE_NO_DEPRECATE

#include <stdlib.h>
#include <glut.h>
#include <stdio.h>
#include <math.h>
#include <windows.h>
#include <iostream>
#include <conio.h>

GLUquadricObj *p; /* pointer to quadric object */ 
GLuint GIRAFFE;
GLuint BODY;
GLuint LEGUP;
GLuint LEGDOWN;
GLuint HEAD;
GLuint CORN;
GLuint EYES;
GLuint TAIL;
GLuint LIST_NAME;
GLuint BODY_PAINT;

float MAX=10.0, MIN=-10.0;
int flagLeft = 0, flagRight = 0;    //flags that indicates if the giraffe can move to the left or the right. if 0 - it can, if 1 - it can't
float XPlace=0.0,YPlace=0.0,ZPlace=0.0, rotation = 0.0; //indicators where the giraffe is at a current time
int position = 0;   //index for setting the legs of the girrafe. 0 - all four legs standing. 1 - forward right and backwards left are in the air, forward left and backward right are on the ground. 2 - forward right and backwards left are on the ground, forward left and backward right are in the air

GLuint LoadTexture(char *filename) // load a textures //
{
    GLuint texture;
    BITMAPFILEHEADER fileheader; 
    BITMAPINFOHEADER infoheader;
    RGBTRIPLE pixel;  

    FILE *pFile = fopen( filename, "rb");          // Open the file for reading to buffer
    if( pFile == NULL) return (-1); 

    fread( &fileheader, sizeof(fileheader), 1, pFile); // Read the file_header
    fread( &infoheader, sizeof(infoheader), 1, pFile); // and read the info_header

   //----------------
    int w,h, nSize;

    w=(int)(infoheader.biWidth);
    h=(int)(infoheader.biHeight);

    nSize = w * h * 4; //in memory: 4 bytes for every readed pixel

    // Allocation memory for our image (width * height * bytesPerPixel)
    unsigned char *pImage = (unsigned char *)new char[nSize];

    //------------

    // Read w*h times data about every pixel from BMP file and locate them to memory
    // if our file is 24-bit Bitmap type, so for every pixel we have 24/8=3 Bytes
    // in this program size of memory for Image bigger of size of file 
    // (in memory: 4 bytes for every pixel)

    int j = 0; //index for Image
    for( int i=0; i < w * h; i ++ )  //index for BMP file
    {            
            // We load an RGB value from the file
            fread( &pixel, sizeof(pixel), 1, pFile); 

            // And store data in right places( additional here every rgb pixel = 4 bytes)
            pImage[j+0] = pixel.rgbtRed;      // Red component
            pImage[j+1] = pixel.rgbtGreen;  // Green component
            pImage[j+2] = pixel.rgbtBlue;     // Blue component
            pImage[j+3] = 255;   // Alpha value - is used in the process 
                                 //of combining texture with background 
                                 //to create a partial transparency
            j += 4; // Go to the next 4 bytes in memory
    }

    fclose( pFile ); // Close the file stream

    glEnable(GL_TEXTURE_2D);

    glGenTextures( 1, &texture );
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

    // the texture wraps over at the edges (repeat)
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    // Make Texture(2D MIPmaps format image) from our Image in memory 
    //in this program for texture we define 4 bytes for 1 pixel 
    gluBuild2DMipmaps(GL_TEXTURE_2D, 4, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pImage);

    free(pImage);

    return texture; 
}

#pragma region Body Parts

void HoofDown() //the hoof of the giraffe when it's down
{
    glPushMatrix();
    glTranslatef(-3,-7.5,1.8);
    glColor3f(0.4, 0.75, 0.13);
    glRotatef(245.0, 0.2, 0.2, 0.2);
    gluDisk(p, 0.,1.,25,5);
    glPopMatrix();
}

void HoofUp()   //the hoof of the giraffe when it's up
{
    glPushMatrix();
    glTranslatef(-7,-6,1.8);
    glColor3f(0.4, 0.75, 0.13);
    glRotatef(220.0, 0.2, 0.2, 0.2);
    gluDisk(p, 0.,1.,25,5);
    glPopMatrix();
}

void Chest() //CHEST
{
    glPushMatrix();
    glTranslatef(-2,2.,0.);
    glRotatef(90,1.,1.,0.);
    gluCylinder(p,2.5,1.5,4.5,15,10);
    glPopMatrix();
}

void Neck() 
{
    glPushMatrix();
    glTranslatef(-5,14,0);
    glRotatef(90,1,0.2,0);
    gluCylinder(p,0.5,1.3,11,15,10);
    glPopMatrix();
}

void ThighDown()    //the thigh of the giraffe when it's down
{
    glPushMatrix();
    glTranslatef(-3,0.5,1.5);
    glColor3f(0.4, 0.75, 0.13);
    glRotatef(90,1.,0.,0.);
    gluCylinder(p,0.5,0.5,4,15,10);
    glPopMatrix();
}

void ThighUp()  //the thigh of the giraffe when it's up
{
    glPushMatrix();
    glTranslatef(-3,0.5,1.5);
    glColor3f(0.4, 0.75, 0.13);
    glRotatef(90,3.,-3.,0.);
    gluCylinder(p,0.5,0.5,4,15,10);
    glPopMatrix();
}

void LegDown()  //the leg of the giraffe when it's down
{
    glPushMatrix();
    glTranslatef(-3,-3.5,1.5);
    glColor3f(0.4, 0.75, 0.13);
    glRotatef(90,0.5,0.,0.);
    gluCylinder(p,0.5,0.5,4,15,10);

    glPopMatrix();
}

void LegUp()    //the leg of the giraffe when it's up
{
    glPushMatrix();
    glTranslatef(-5.7,-2.2,1.5);
    glColor3f(0.4, 0.75, 0.13);
    glRotatef(90,1.5,-0.5,0.);
    gluCylinder(p,0.5,0.5,4,15,10);

    glPopMatrix();
}

void FootDown() //the lower leg of the giraffe when it's down
{
    glPushMatrix();
    glTranslatef(-3,-3.5,1.5);
    glColor3f(0.4, 0.75, 0.13);
    glRotatef(86,1.,0.,0.);
    gluCylinder(p,0.3,0.7,4,15,10);

    glPopMatrix();
}

void FootUp()   //the lower leg of the giraffe when it's up
{
    glPushMatrix();
    glTranslatef(-5.7,-2.2,1.5);
    glColor3f(0.4, 0.75, 0.13);
    glRotatef(90,1.5,-0.5,0.);
    gluCylinder(p,0.3,0.7,4,15,10);

    glPopMatrix();
}

void Head1() //head part1
{
    glPushMatrix();
    glTranslatef(-5.3,14.3,0);
    glRotatef(90,1.,-0.9,0.);
    gluCylinder(p,0.7,0.3,3,15,10);
    glPopMatrix();
}

void Cornp1() //corn part1
{
    glPushMatrix();
    glTranslatef(-8.8,14.3,0);
    glColor3f(0.5, 0.35, 0.05);
    glRotatef(90,1.,0.3,0.);
    gluCylinder(p,0,0.2,1,15,10);
    glPopMatrix();
}

void Cornp2() //corn part2
{
    glPushMatrix();
    glTranslatef(-8.6,13.3,0);
    glRotatef(90,1.,0.9,0.);
    gluCylinder(p,0.2,0.4,1,15,10);
    glPopMatrix();
}

void Sphere()
{
    glPushMatrix();
    glTranslatef(-1.92,2,0.);
    glRotatef(0.,0.,0.,1.);
    gluSphere(p,2.5,15,21);
    glPopMatrix();
}

void Sphere2()
{
    glPushMatrix();
    glTranslatef(1.5,-1.5,0.);
    gluSphere(p,1.5,15,21);
    glPopMatrix();
}

void Headp2() //head part2
{
    glPushMatrix();
    glTranslatef(-5.2,14.5,0.);
    gluSphere(p,0.8,15,21);
    glPopMatrix();
}

void Headp3() //head part3
{
    glPushMatrix();
    glTranslatef(-7.4,11.8,0.);
    gluSphere(p,0.5,15,21);
    glPopMatrix();
}

void HeadMiddle() //head middle part4
{
    glPushMatrix();
    glTranslatef(-6,12.8,0.);
    gluSphere(p,0.5,15,21);
    glPopMatrix();
}

void Eyes() //EYES
{
    glPushMatrix();
    glTranslatef(-11,12.9,0.2);
    glColor3f(0.4, 0.75, 0.13);
    gluSphere(p,0.2,15,21);
    glPopMatrix();
}

void Tail() 
{
    glPushMatrix();
    glTranslatef(-2.4,-0.3,-0.5);
    glRotatef(90,1,0.5,0);
    gluCylinder(p,0.2,0.1,4,15,10);
    glPopMatrix();
}

#pragma endregion

#pragma region Leg Positions

void stand()    //all four legs of the giraffe are on the ground
{
    glCallList (LEGDOWN);   //leg forward right
    glPopMatrix();
    glTranslatef (0, 0,-2.5); 
    glCallList (LEGDOWN);   //leg forward left
    glPopMatrix();
    glScalef(1,1,1);
    glTranslatef (5.4, -1.6, 0.3); 
    glScalef(1,0.8,1);
    glCallList (LEGDOWN); //leg backward left
    glPopMatrix();
    glTranslatef (0, 0 ,1.5); 
    glCallList (LEGDOWN);   //leg backward right
    glPopMatrix();
}

void rightUp()  //forward right and backwards left are in the air, forward left and backward right are on the ground
{
    glCallList (LEGUP); //leg forward right
    glPopMatrix();
    glTranslatef (0, 0,-2.5); 
    glCallList (LEGDOWN);   //leg forward left
    glPopMatrix();
    glScalef(1,1,1);
    glTranslatef (5.4, -1.6, 0.3); 
    glScalef(1,0.8,1);
    glCallList (LEGUP); //leg backward left
    glPopMatrix();
    glTranslatef (0, 0 ,1.5); 
    glCallList (LEGDOWN);   //leg backward right
    glPopMatrix();
}

void leftUp()   //forward right and backwards left are on the ground, forward left and backward right are in the air
{
    glCallList (LEGDOWN);   //leg forward right
    glPopMatrix();
    glTranslatef (0, 0,-2.5); 
    glCallList (LEGUP); //leg forward left
    glPopMatrix();
    glScalef(1,1,1);
    glTranslatef (5.4, -1.6, 0.3); 
    glScalef(1,0.8,1);
    glCallList (LEGDOWN); //leg backward left
    glPopMatrix();
    glTranslatef (0, 0 ,1.5); 
    glCallList (LEGUP); //leg backward right
    glPopMatrix();
}

#pragma endregion

void display(void) 
{
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    glRotatef(0+rotation,0.,2.,0.);
    glTranslatef(XPlace,YPlace,ZPlace);

    glCallList (BODY);      
    glCallList (HEAD);  
    glTranslatef (2, 2, 0.6); 
    glCallList (CORN);  
    glTranslatef (0, 0, -0.7); 
    glCallList (CORN);  
    glTranslatef (-2.3, -1.3, 0); 
    glScalef(1,1.5,1);
    switch (position)
    {
        case 0:
            stand();
            break;
        case 1:
            rightUp();
            break;
        default:
            leftUp();
            break;
    }
    glCallList (EYES);
    glTranslatef (0, 0 ,1.2); 
    glCallList (EYES);
    glCallList (TAIL);


    glFlush();
    glutSwapBuffers(); 
}

void rotate(int direction)
{
    if(direction == 1)
        rotation += 0.5;
    if(direction == 2)
        rotation -= 0.5;
}

void myReshape(int w,int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-20.,20.,-20.,20.,-20.,20.);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void changePosition()   //changing the position for setting the legs
{
    position++;
    if(position == 3)
        position = 0;
}

void myinit()
{
    LIST_NAME= glGenLists (9);
    BodyPaint = LoadTexture("giraffeSkin.bmp");
    p=gluNewQuadric(); /* allocate quadric object */
    gluQuadricDrawStyle(p, GLU_LINE); /* render it as wireframe */
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glColor3f(0.4, 0.75, 0.13);

    BODY=LIST_NAME;
    glNewList (BODY, GL_COMPILE);
    Chest();
    Neck();
    Sphere();
    Sphere2();
    glEndList();

    LEGUP=LIST_NAME+1;
    glNewList(LEGUP ,GL_COMPILE);
    ThighUp();
    LegUp();
    FootUp();
    HoofUp();
    glEndList();

    LEGDOWN=LIST_NAME+2;
    glNewList(LEGDOWN ,GL_COMPILE);
    ThighDown();
    LegDown();
    FootDown();
    HoofDown();
    glEndList();

    HEAD=LIST_NAME+3;
    glNewList(HEAD,GL_COMPILE);
    Head1();
    Headp2();
    Headp3();
    glEndList();

    CORN=LIST_NAME+4;
    glNewList(CORN,GL_COMPILE);
    Cornp1();
    Cornp2();
    glEndList();

    EYES=LIST_NAME+5;
    glNewList(EYES,GL_COMPILE);
    Eyes();
    glEndList();

    TAIL=LIST_NAME+6;
    glNewList(TAIL,GL_COMPILE);
    Tail();
    glEndList();

    GIRAFFE=LIST_NAME+7;
}

void keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
        case '2'://up
            rotate(1);
            glutPostRedisplay();
            break;

        case '4'://left
            if(flagLeft==0)
            {
                flagRight = 0;
                XPlace=XPlace-0.05;
                if(XPlace<=MIN)
                    flagLeft=1;
                changePosition();
            }
            glutPostRedisplay();
            break;

       case '6'://right
           if(flagRight==0)
           {
               flagLeft = 0;
               XPlace=XPlace+0.05;
               if(XPlace>=MAX)
                   flagRight=1;
               changePosition();
           }
           glutPostRedisplay();
           break;

        case '8'://down
            rotate(2);
            glutPostRedisplay();
            break;

      case 27:  // ESC: exit the program
          exit(0); break;
      default:
          break;
   }
}

void main(int argc, char **argv) 
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(1000, 1000);
    glutCreateWindow("Quadric Objects");
    myinit(); 

    glutKeyboardFunc(keyboard);  // Register handler for key event
    glutReshapeFunc(myReshape);

    glutDisplayFunc(display);
    glutMainLoop();
}

我发现的纹理名为giraffeSkin.bmp

我知道我应该使用glBindTexture功能,但我不知道在哪里。有人可以帮我一把吗?

1 个答案:

答案 0 :(得分:1)

看起来你正在使用二次曲面(例如“gluCylinder”)库。他们有自己的纹理映射方式。看看函数gluQuadricTexture。你会看到有关二次曲面的映射有点过了。

http://www.opengl.org/sdk/docs/man2/xhtml/gluQuadricTexture.xml

同时,在纹理映射时,记得调用glEnable(GL_TEXTURE_2D)