lophyxp 发表于 2017-1-19 20:38:47

【OpenGL】【3D】一个OpenGL示例程序

本帖最后由 lophyxp 于 2017-1-19 20:38 编辑


[*]先上源代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "GL/glew.h"
#include "GL/glut.h"

#ifdef WIN32
       #define filename "d:\\tex03.bmp"
#elif LINUX
       #define filename "/home/lophyxp/tex03.bmp"
#endif

static GLint imagewidth;
static GLint imageheight;
static GLint pixellength;
static GLubyte* pixeldata;


void readBMP() {
      //打开文件
      FILE* pfile = fopen(filename, "rb");
      if (pfile == 0) {
                printf("%s is not a BMP file.\n", filename);
                exit(0);
      }

      //读取图像大小
      fseek(pfile, 0x0012, SEEK_SET);
      fread(&imagewidth, sizeof(imagewidth), 1, pfile);
      fread(&imageheight, sizeof(imageheight), 1, pfile);

      //计算像素数据长度,处理对齐
      pixellength = imagewidth * 3;
      while (pixellength % 4 != 0)pixellength++;
      pixellength *= imageheight;

      //读取像素数据
      pixeldata = (GLubyte*)malloc(pixellength);
      if (pixeldata == 0) exit(0);

      fseek(pfile, 54, SEEK_SET);
      fread(pixeldata, pixellength, 1, pfile);

      //关闭文件
      fclose(pfile);
}

typedef struct materialStruct {
      GLfloat ambient;
      GLfloat diffuse;
      GLfloat specular;
      GLfloat shininess;
}materialStruct;

materialStruct brassMaterials = {
      { 0.33, 0.22, 0.03, 1.0 },
      { 0.78, 0.57, 0.11, 1.0 },
      { 0.99, 0.91, 0.81, 1.0 },
      27.8
};

materialStruct redPlasticMaterials = {
      { 0.3, 0.0, 0.0, 1.0 },
      { 0.6, 0.0, 0.0, 1.0 },
      { 0.8, 0.6, 0.6, 1.0 },
      32.0
};

materialStruct whiteShinyMaterials = {
      { 1.0, 1.0, 1.0, 1.0 },
      { 1.0, 1.0, 1.0, 1.0 },
      { 1.0, 1.0, 1.0, 1.0 },
      100.0
};

void materials(materialStruct *materials) {
      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, materials->ambient);
      glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, materials->diffuse);
      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, materials->specular);
      glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, materials->shininess);
}

typedef struct lightingStruct {
      GLfloat ambient;
      GLfloat diffuse;
      GLfloat specular;
}lightingStruct;

lightingStruct whiteLighting = {
      { 0.0, 0.0, 0.0, 1.0 },
      { 1.0, 1.0, 1.0, 1.0 },
      { 1.0, 1.0, 1.0, 1.0 }
};

lightingStruct coloredLighting = {
      { 0.2, 0.0, 0.0, 1.0 },
      { 0.0, 1.0, 0.0, 1.0 },
      { 0.0, 0.0, 1.0, 1.0 }
};

void lighting(lightingStruct *lighting) {
      glLightfv(GL_LIGHT0, GL_AMBIENT, lighting->ambient);
      glLightfv(GL_LIGHT0, GL_DIFFUSE, lighting->diffuse);
      glLightfv(GL_LIGHT0, GL_SPECULAR, lighting->specular);
}

void init() {
      glViewport(0, 0, 500, 500);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(-2.0, 2.0, -2.0,
                2.0, -10.0, 10.0);

      // Texture_2d ================================
      glEnable(GL_DEPTH_TEST);
      glEnable(GL_TEXTURE_2D);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imagewidth, imageheight, 0, GL_BGR, GL_UNSIGNED_BYTE, pixeldata);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
      //glDisable(GL_TEXTURE_2D);

      // Blend ======================================
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      //glBlendFunc(GL_SRC_ALPHA, GL_ONE);

      // Lighting ================================
      //GLfloat light_pos[] = { 1.0,2.0,3.0,1.0 };
      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);
      /*glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      glLightfv(GL_LIGHT0, GL_POSITION, light_pos);*/
      lighting(&whiteLighting);
      materials(&brassMaterials);

      glShadeModel(GL_SMOOTH);

      // Fog ===================================
      GLuint filter = 2;
      GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINE };
      GLuint fogfilter = 0;
      GLfloat fogColor = { 0.5f, 0.5f, 0.5f, 1.0f };

      glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
      glFogi(GL_FOG_MODE, fogMode);
      glFogfv(GL_FOG_COLOR, fogColor);
      glFogf(GL_FOG_DENSITY, 0.35f);
      glHint(GL_FOG_HINT, GL_DONT_CARE);
      glFogf(GL_FOG_START, 1.0f);
      glFogf(GL_FOG_END, 5.0f);
      glEnable(GL_FOG);
}

GLfloat vertics[]={
      {-1.0, -1.0, 1.0},      {-1.0,1.0,1.0},                //0, 1
      {1.0,1.0,1.0},                {1.0,-1.0,1.0},                //2, 3
      {-1.0,-1.0,-1.0},      {-1.0,1.0,-1.0},      //4, 5
      {1.0,1.0,-1.0},                {1.0,-1.0,-1.0}                //6, 7
};
GLfloat colors[] = {
      {1.0,0.0,0.0,0.5},{0.0,1.0,1.0,0.5},
      {1.0,1.0,0.0,0.5},{0.0,1.0,0.0,0.5},
      {0.0,0.0,1.0,0.5},{1.0,0.0,1.0,0.5},
      {0.0,0.0,0.0,0.5},{1.0,1.0,1.0,0.5}
};
GLfloat normals[] = {
      {-1.0, 0.0, 0.0}, {1.0, 0.0, 0.0},
      {0.0, -1.0, 0.0}, {0.0, 1.0, 0.0},
      {0.0, 0.0, -1.0}, {0.0, 0.0, 1.0}
};

void polygon(int a, int b, int c, int d) {
      glBegin(GL_POLYGON);
                glColor3fv(colors);
                glTexCoord2f(0.0, 0.0);
                glVertex3fv(vertics);
                glColor3fv(colors);
                glTexCoord2f(0.0, 1.0);
                glVertex3fv(vertics);
                glColor3fv(colors);
                glTexCoord2f(1.0, 1.0);
                glVertex3fv(vertics);
                glColor3fv(colors);
                glTexCoord2f(1.0, 0.0);
                glVertex3fv(vertics);
      glEnd();
}

void cube() {
      glNormal3fv(normals);      //z
      polygon(0, 3, 2, 1);
      glNormal3fv(normals);      //x
      polygon(2, 3, 7, 6);
      glNormal3fv(normals);      //-y
      polygon(3, 0, 4, 7);
      glNormal3fv(normals);      //y
      polygon(1, 2, 6, 5);
      glNormal3fv(normals);      //-z
      polygon(4, 5, 6, 7);
      glNormal3fv(normals);      //-x
      polygon(5, 4, 0, 1);
}

GLUquadricObj* Quadric;

void quadric() {
      Quadric = gluNewQuadric();
      gluQuadricDrawStyle(Quadric, GLU_FILL);
      gluQuadricNormals(Quadric, GLU_SMOOTH);
      gluQuadricTexture(Quadric, GL_TRUE);
      gluSphere(Quadric, 1.5, 120, 120);
      //gluCylinder(Quadric, 0.5, 0.5, 2.0, 120, 120);
      //gluDisk(Quadric, 0.5, 1.0, 120, 120);
      //gluPartialDisk(Quadric, 0.5, 1.0, 120, 120, 90.0, 180.0);

      gluDeleteQuadric(Quadric);
}

static GLfloat theta[] = { 0.0, 0.0, 0.0 };
static GLint axis = 1;      //0:x, 1:y, 2:z
static GLfloat position0[] = { 10.0,20.0,30.0,1.0 };

void display(void)
{
      glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      //gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
      glPushMatrix();
      glRotatef(theta, 1.0, 0.0, 0.0);
      glRotatef(theta, 0.0, 1.0, 0.0);
      glRotatef(theta, 0.0, 0.0, 1.0);

      glLightfv(GL_LIGHT0, GL_POSITION, position0);

      
      //cube();
      //glutSolidTeapot(1.0);
      glRotatef(-90.0, 1.0, 0.0, 0.0);//quardic round axis-z to round axis-y
      quadric();
      glPopMatrix();

      //glDrawPixels(imagewidth, imageheight, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixeldata);

      glFlush();
      glutSwapBuffers();
}

void myMouse(int btn, int state, int x, int y) {
      if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
                axis = 0;
      if (btn == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
                axis = 1;
      if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
                axis = 2;
}

void myIdle() {
      theta += 0.1;
      if (theta > 360.0) theta -= 360.0;
      
      glutPostRedisplay();
}

void myKeyboard(unsigned char k, int x, int y) {
      static bool gp = true;
      switch (k) {
      case '1':
                glutIdleFunc(NULL);
                break;
      case '2':
                glutIdleFunc(&myIdle);
                break;
      case '3':
                glEnable(GL_TEXTURE_2D);
                break;
      case '4':
                glDisable(GL_TEXTURE_2D);
                break;
      case 'w':
                materials(&redPlasticMaterials);
                break;
      case 'e':
                materials(&brassMaterials);
                break;
      case 'r':
                materials(&whiteShinyMaterials);
                break;
      case 's':
                lighting(&whiteLighting);
                break;
      case 'd':
                lighting(&coloredLighting);
                break;
      case 'f':
                if (gp == true) {
                        glDisable(GL_FOG);
                        gp = false;
                }
                else {
                        glEnable(GL_FOG);
                        gp = true;
                }
                break;
      case 'q':
                exit(0);
                break;
      }
}

void myReshape(int w, int h) {
      glViewport(0, 0, w, h);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      if(w<=h)
                glOrtho(-2.0, 2.0, -2.0*(GLfloat)h / (GLfloat)w,
                        2.0*(GLfloat)h / (GLfloat)w, -10.0, 10.0);
      else
                glOrtho(-2.0*(GLfloat)w / (GLfloat)h,
                        2.0*(GLfloat)w / (GLfloat)h, -2.0, 2.0,-10.0, 10.0);
      glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char* argv[]) {
      readBMP();
      glutInit(&argc, argv);
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
      glutInitWindowPosition(10, 10);
      glutInitWindowSize(500, 500);
      glutCreateWindow(filename);
      init();
      glutDisplayFunc(&display);
      glutReshapeFunc(&myReshape);
      glutIdleFunc(&myIdle);
      glutMouseFunc(&myMouse);
      glutKeyboardFunc(&myKeyboard);
      glutMainLoop();
      //-------------------------------------
      free(pixeldata);
      return 0;
}

[*]下载纹理文件

Windows下,解压缩后得到tex.bmp文件,放到D盘根目录下;Linux下,解压缩以后放到/home/lophyxp/目录下。
[*]Windows下编译
下载oglEarth.rar五个文件,解压缩到
我的文档\Visual Studio 2015\Projects目录下,打开Visual Studio 2015,打开项目,选择oglEarth\oglEarth.sln,点“本地Windows调试器”前面的绿色箭头。
[*]Linux下编译
下载,执行tar xzvf oglEarth.tar.gz
make main
./main
[*]运行效果

页: [1]
查看完整版本: 【OpenGL】【3D】一个OpenGL示例程序