opengGL + glut 实现画几个简单的图元

功能: when press "c" ------   circle

                           "s" ------   cube with color

                           "t" ------    triaggle

                           "m" -----   cube with texture

 

         when press  "r"   -----  above primitive will rotate around y axis

 

代码 :

 

#include <GL/glut.h>
#include <stdlib.h>
#include "FreeImage.h"
#include <math.h>
#include <stdio.h>
#include <string.h>


#define PI 3.14159265358979323846

static float rotAngle = 0.0;
static int iFlag=1;
static GLuint    texture[1];            // Storage For One Texture ( NEW )

 GLuint Texture;


void output(int x, int y, float r, float g, float b, int font, char *string)
{
  glColor3f( r, g, b );
  glRasterPos2f(x, y);
  int len, i;
  len = (int)strlen(string);
  for (i = 0; i < len; i++) {
    glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, string[i]);
  }
}



GLuint loadBMP_custom(const char * imagepath){

    printf("Reading image %s\n", imagepath);

    // Data read from the header of the BMP file
    unsigned char header[54];
    unsigned int dataPos;
    unsigned int imageSize;
    unsigned int width, height;
    // Actual RGB data
    unsigned char * data;
    unsigned char tempRGB;

    // Open the file
    FILE * file = fopen(imagepath,"rb");
    if (!file)                                {printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); getchar(); return 0;}

    // Read the header, i.e. the 54 first bytes

    // If less than 54 bytes are read, problem
    if ( fread(header, 1, 54, file)!=54 ){ 
        printf("Not a correct BMP file\n");
        return 0;
    }
    // A BMP files always begins with "BM"
    if ( header[0]!='B' || header[1]!='M' ){
        printf("Not a correct BMP file\n");
        return 0;
    }
    // Make sure this is a 24bpp file
    if ( *(int*)&(header[0x1E])!=0  )         {printf("Not a correct BMP file\n");    return 0;}
    if ( *(int*)&(header[0x1C])!=24 )         {printf("Not a correct BMP file\n");    return 0;}

    // Read the information about the image
    dataPos    = *(int*)&(header[0x0A]);
    imageSize  = *(int*)&(header[0x22]);
    width      = *(int*)&(header[0x12]);
    height     = *(int*)&(header[0x16]);

    // Some BMP files are misformatted, guess missing information
    if (imageSize==0)    imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component
    if (dataPos==0)      dataPos=54; // The BMP header is done that way

    // Create a buffer
    data = new unsigned char [imageSize];

    // Read the actual data from the file into the buffer
    fread(data,1,imageSize,file);


    //swap R and B
    for(int imageIdx=0;imageIdx<imageSize;imageIdx+=3)
    {
        tempRGB = data[imageIdx];
        data[imageIdx] = data[imageIdx + 2];
        data[imageIdx + 2] = tempRGB;

    }


    // Everything is in memory now, the file wan be closed
    fclose (file);

    // Create one OpenGL texture        &texture[0]

    GLuint textureID;
    glGenTextures(1, &textureID);
    
    // "Bind" the newly created texture : all future texture functions will modify this texture
    glBindTexture(GL_TEXTURE_2D, textureID);

    // Give the image to OpenGL
    glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

    // OpenGL has now copied the data. Free our own version
    delete [] data;

    // Poor filtering, or ...
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

    // ... nice trilinear filtering.


    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
    
    
    //glGenerateMipmap(GL_TEXTURE_2D);


    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    // Return the ID of the texture we just created
    return textureID;
}


int LoadGLTextures()                                    // Load Bitmaps And Convert To Textures
{
    int Status=FALSE;                                    // Status Indicator

    //image format
    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
    //pointer to the image, once loaded
    FIBITMAP *dib=NULL;
    //pointer to the image data
    BYTE* bits=NULL;
    //image width and height
    unsigned int width, height;

    FreeImage_Initialise(FALSE);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    //musu003.png
    //xiaoai0004.bmp
    //489.png


    fif = FreeImage_GetFileType("./48901.png", 0);
    //if still unknown, try to guess the file format from the file extension
    if(fif == FIF_UNKNOWN) 
        fif = FreeImage_GetFIFFromFilename("./48901.png");
    //if still unkown, return failure
    if(fif == FIF_UNKNOWN)
        return Status;

    //check that the plugin has reading capabilities and load the file
    if(FreeImage_FIFSupportsReading(fif))
        dib = FreeImage_Load(fif, "./48901.png",0);
    //if the image failed to load, return failure
    if(!dib)
    {
        //output(10,10,1.0,1.0,1.0,5,"read file error.");
        printf("read file error.");
        return Status;
    }
    printf("reach here. \n");
    //retrieve the image data
    bits = FreeImage_GetBits(dib);
    //get the image width and height
    width = FreeImage_GetWidth(dib);
    height = FreeImage_GetHeight(dib);

    unsigned bpp = FreeImage_GetBPP(dib);
    //if this somehow one of these failed (they shouldn't), return failure
    if((bits == 0) || (width == 0) || (height == 0))
        return Status;

    printf("already get width and height. \n");
    unsigned int bytePerPixel=bpp/8;   //每像素占多少字节

    printf("bytePerPixel is %d , width is %d , height is %d  \n" ,bytePerPixel,width,height);

    //bit的数据格式是BGR,B和R应该交换过来
    //for(int imageIdx=0;imageIdx<(width*height*bytePerPixel);imageIdx+=bytePerPixel)    
    //{
    //    unsigned char tempRGB=bits[imageIdx];
    //    bits[imageIdx]=bits[imageIdx+2];
    //    bits[imageIdx+2]=tempRGB;
    //}

    Status=TRUE;

    glGenTextures(1, &texture[0]);                    // Create The Texture

    // Typical Texture Generation Using Data From The Bitmap
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    //倒数第三个参数是GL_RGBA,因为这里用的png图,bpp=32,如果用的jpg图,bpp=24,则此参数应为GL_RGB
    //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits);

    //original is GL_UNSIGNED_BYTE
    //change to GLubyte 

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    return Status;                                        // Return The Status
}


void init(void) 
{

    //if (!LoadGLTextures())                                // Jump To Texture Loading Routine ( NEW )
    //{
    //    return ;                                    // If Texture Didn't Load Return FALSE
    //}



   glClearColor (0.0, 0.0, 0.0, 0.0);

       Texture = loadBMP_custom("48901.bmp");

    //glEnable(GL_TEXTURE_2D);    

   //glShadeModel (GL_FLAT);
       glShadeModel(GL_SMOOTH);

    glClearDepth(1.0f);                                    // Depth Buffer Setup
    glEnable(GL_DEPTH_TEST);                            // Enables Depth Testing
    glDepthFunc(GL_LEQUAL);                                // The Type Of Depth Testing To Do
}



void draw_triangle(void)
{
    glDisable(GL_TEXTURE_2D);

    glClearColor(0.0,0.0,0.0,0.0);

   glBegin (GL_LINE_LOOP);
   glVertex2f(0.0, 1.0);
   glVertex2f(1.0, -1.0);
   glVertex2f(-1.0, -1.0);
   glEnd();
}

void draw_circle(void)
{
    glDisable(GL_TEXTURE_2D);

    glBegin(GL_LINE_LOOP);
    for(int i =0; i <= 300; i++)
    {
        double angle = 2 * PI * i / 300;
        double x = cos(angle);
        double y = sin(angle);
        glVertex2d(x,y);
    }
    glEnd(); 

}

void draw_TextureCube(void)
{
    glEnable(GL_TEXTURE_2D);    

    glBindTexture(GL_TEXTURE_2D,Texture);

    glBegin(GL_QUADS);
        // Front Face
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
        // Back Face
        glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
        // Top Face
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
        // Bottom Face
        glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
        // Right face
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
        // Left Face
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
    glEnd();

}


void draw_cube(void)
{
    glDisable(GL_TEXTURE_2D);

        glBegin(GL_QUADS);                                    // Draw A Quad
        glColor3f(0.0f,1.0f,0.0f);                        // Set The Color To Green
        glVertex3f( 1.0f, 1.0f,-1.0f);                    // Top Right Of The Quad (Top)
        glVertex3f(-1.0f, 1.0f,-1.0f);                    // Top Left Of The Quad (Top)
        glVertex3f(-1.0f, 1.0f, 1.0f);                    // Bottom Left Of The Quad (Top)
        glVertex3f( 1.0f, 1.0f, 1.0f);                    // Bottom Right Of The Quad (Top)
        glColor3f(1.0f,0.5f,0.0f);                        // Set The Color To Orange
        glVertex3f( 1.0f,-1.0f, 1.0f);                    // Top Right Of The Quad (Bottom)
        glVertex3f(-1.0f,-1.0f, 1.0f);                    // Top Left Of The Quad (Bottom)
        glVertex3f(-1.0f,-1.0f,-1.0f);                    // Bottom Left Of The Quad (Bottom)
        glVertex3f( 1.0f,-1.0f,-1.0f);                    // Bottom Right Of The Quad (Bottom)
        glColor3f(1.0f,0.0f,0.0f);                        // Set The Color To Red
        glVertex3f( 1.0f, 1.0f, 1.0f);                    // Top Right Of The Quad (Front)
        glVertex3f(-1.0f, 1.0f, 1.0f);                    // Top Left Of The Quad (Front)
        glVertex3f(-1.0f,-1.0f, 1.0f);                    // Bottom Left Of The Quad (Front)
        glVertex3f( 1.0f,-1.0f, 1.0f);                    // Bottom Right Of The Quad (Front)
        glColor3f(1.0f,1.0f,0.0f);                        // Set The Color To Yellow
        glVertex3f( 1.0f,-1.0f,-1.0f);                    // Top Right Of The Quad (Back)
        glVertex3f(-1.0f,-1.0f,-1.0f);                    // Top Left Of The Quad (Back)
        glVertex3f(-1.0f, 1.0f,-1.0f);                    // Bottom Left Of The Quad (Back)
        glVertex3f( 1.0f, 1.0f,-1.0f);                    // Bottom Right Of The Quad (Back)
        glColor3f(0.0f,0.0f,1.0f);                        // Set The Color To Blue
        glVertex3f(-1.0f, 1.0f, 1.0f);                    // Top Right Of The Quad (Left)
        glVertex3f(-1.0f, 1.0f,-1.0f);                    // Top Left Of The Quad (Left)
        glVertex3f(-1.0f,-1.0f,-1.0f);                    // Bottom Left Of The Quad (Left)
        glVertex3f(-1.0f,-1.0f, 1.0f);                    // Bottom Right Of The Quad (Left)
        glColor3f(1.0f,0.0f,1.0f);                        // Set The Color To Violet
        glVertex3f( 1.0f, 1.0f,-1.0f);                    // Top Right Of The Quad (Right)
        glVertex3f( 1.0f, 1.0f, 1.0f);                    // Top Left Of The Quad (Right)
        glVertex3f( 1.0f,-1.0f, 1.0f);                    // Bottom Left Of The Quad (Right)
        glVertex3f( 1.0f,-1.0f,-1.0f);                    // Bottom Right Of The Quad (Right)
    glEnd();                                            // Done Drawing The Quad


}


void display(void)
{
   //glClear (GL_COLOR_BUFFER_BIT);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //glClearColor(0.0,0.0,0.0,0.0);

   //glLoadIdentity ();
   glColor3f (1.0, 1.0, 1.0);


   glPushMatrix();
   glRotatef(-rotAngle, 0.0, 0.1, 0.0);


    switch (iFlag) {
      case 1:
         draw_triangle();
         break;
      case 2:
         //glutSolidSphere(1.0,20,16);
         draw_circle();
         break;
      case 3:
         //glScalef (2.0, 2.0, 2.0); 
         //glutWireCube (1.0);
         draw_cube();
         break;
      case 4:
         //glScalef (2.0, 2.0, 2.0); 
         //glutWireCube (1.0);
         draw_TextureCube();
         break;
      default:
         break;
    }


   glPopMatrix();

    glFlush ();
}

void reshape (int w, int h)
{
   //glViewport (0, 0, (GLsizei) w, (GLsizei) h);
   //glMatrixMode (GL_PROJECTION);
   //glLoadIdentity ();
   //if (w <= h)
   //   glOrtho (-50.0, 50.0, -50.0*(GLfloat)h/(GLfloat)w,
   //      50.0*(GLfloat)h/(GLfloat)w, -1.0, 1.0);
   //else
   //   glOrtho (-50.0*(GLfloat)w/(GLfloat)h,
   //      50.0*(GLfloat)w/(GLfloat)h, -50.0, 50.0, -1.0, 1.0);
   //glMatrixMode(GL_MODELVIEW);

   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
   //gluPerspective(60.0,1.0,1.5,20.0);
   glMatrixMode (GL_MODELVIEW);

     glLoadIdentity ();            
          
   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

}

void keyboard(unsigned char key, int x, int y)
{
    switch (key) {
      case 'r':
      case 'R':
         rotAngle += 20.;
         glutPostRedisplay();    
         break;
      case 't':
      case 'T':
         rotAngle =0.0;
         iFlag=1;   
         glutPostRedisplay();    
         break;
      case 's':
      case 'S':
         rotAngle =0.0;
         iFlag=3;   
         glutPostRedisplay();    
         break;
      case 'c':
      case 'C':
         rotAngle =0.0;
         iFlag=2;   
         glutPostRedisplay();    
         break;
      case 'm':
      case 'M':
         rotAngle =0.0;
         iFlag=4;   
         glutPostRedisplay();    
         break;
      case 27:  /*  Escape Key */
         exit(0);
         break;
      default:
         break;
    }

}

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (500, 500); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape);
   glutKeyboardFunc (keyboard);
   glutMainLoop();
   return 0;
}

 

转载于:https://www.cnblogs.com/lthxk-yl/p/3553680.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值