OpenGL: 平面图元构造三维实体

#define GLUT_DISABLE_ATEXIT_HACK #include <math.h>

#include "gl/glut.h" #pragma comment(lib, "glut32.lib")

#define GL_PI 3.1415f #define RADIUS 50.0f #define SIZE 100.0f

GLboolean bDepth=false; GLboolean bOutline=false; GLfloat fVers[8][3];

void CreatMenu() {  glutAddMenuEntry("深度检测",1); //添加菜单项  glutAddMenuEntry("线框或实体",2);

 glutAttachMenu(GLUT_RIGHT_BUTTON); //指定菜单事件由右击产生 } //设置光照 void SetupLights() {  GLfloat ambientLight[] ={0.2f,  0.2f,  0.2f,  1.0f};//环境光  GLfloat diffuseLight[] ={0.9f,  0.9f,  0.9f,  1.0f};//漫反射  GLfloat lightPos[]     ={50.0f, 80.0f, 60.0f, 1.0f};//光源位置  glEnable(GL_LIGHTING);       //启用光照  glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); //设置环境光源  glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); //设置漫反射光源  glLightfv(GL_LIGHT0, GL_POSITION, lightPos); //设置灯光位置

 glEnable(GL_LIGHT0);                              //打开第一个灯光  glEnable(GL_COLOR_MATERIAL);                      //启用材质的颜色跟踪  glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);//指定材料着色的面

} //归一化法向量 void Unitlize(GLfloat *vertex) {  GLfloat len = GLfloat(sqrt(vertex[0] * vertex[0] + vertex[1] * vertex[1] + vertex[2] * vertex[2]));  if (len == 0.0f)  {   len=1.0f;  }  vertex[0] /= len;  vertex[1] /= len;  vertex[2] /= len; } //计算各顶点坐标 void CalaulateVertices(GLfloat vers[8][3]) {  GLfloat angle;  GLint i = 1;

 vers[0][0] = vers[0][1] = 0.0f;  vers[0][2] = 75.0f;

 for (angle = 0.0f; angle < 2.1f * GL_PI; angle += GL_PI / 3, i++)  {   vers[i][0] = RADIUS * sin(angle);   vers[i][1] = RADIUS * cos(angle);   vers[i][2] = 0.0f;  } } //计算并归一化法向量 void CalaulateNormal(GLfloat vertices[3][3], GLfloat *normal) {  GLfloat v1[3], v2[3];

 v1[0] = vertices[0][0] = vertices[1][0];  v1[1] = vertices[0][1] = vertices[1][1];  v1[2] = vertices[0][2] = vertices[1][2];  v2[0] = vertices[1][0] = vertices[2][0];  v2[1] = vertices[1][1] = vertices[2][1];  v2[2] = vertices[1][2] = vertices[2][2];

 normal[0] = v1[1] * v2[2] - v1[2] * v2[1];  normal[1] = v1[0] * v2[2] - v1[2] * v2[0];  normal[2] = v1[1] * v2[0] - v1[0] * v2[1];

 Unitlize(normal);//归一化 } void OnDisplay(void) {  GLint i;  GLfloat ver[3][3], nor[3];

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除颜色和深度缓冲区  if (bDepth)  {   glEnable(GL_DEPTH_TEST); //启用深度检测  }  else  {   glDisable(GL_DEPTH_TEST);//关闭深度检测  }  if (bOutline)  {   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //以线框形式进行绘制  }  else  {   glPolygonMode(GL_FRONT, GL_FILL);   //以实体形式进行绘制  }  glPushMatrix();                               {   glRotatef(75, 1.0f, 0.0f, 0.0f);   glRotatef(150, 0.0f, 1.0f, 0.0f);   glTranslatef(0.0f, -25.0f, -25.0f);

  glFrontFace(GL_CW);   //指定多边形成型方式为顺时针   glColor3f(0.0f, 1.0f, 0.0f);//指定绘图颜色为绿色   glBegin(GL_TRIANGLE_FAN); //利用三角扇形绘制六棱锥的六个侧面   {    ver[0][0] = fVers[0][0];    ver[0][1] = fVers[0][1];    ver[0][2] = fVers[0][2];    glVertex3f(fVers[0][0], fVers[0][1], fVers[0][2]);    for (i = 1; i < 8; i++)    {     ver[1][0] = fVers[i][0];     ver[1][1] = fVers[i][1];     ver[1][2] = fVers[i][2];     if(i <= 7)     {      ver[2][0] = fVers[i + 1][0];      ver[2][1] = fVers[i + 1][1];      ver[2][2] = fVers[i + 1][2];     }     else     {      ver[2][0] = fVers[1][0];      ver[2][1] = fVers[1][1];      ver[2][2] = fVers[1][2];     }     CalaulateNormal(ver, nor);        //计算并归一化法向量     glNormal3fv(nor);                 //设置法向量     glVertex2f(fVers[i][0], fVers[i][1]);    }   }   glEnd();

  glBegin(GL_TRIANGLE_FAN);  //利用三角扇形绘制六棱锥的顶面   {    glNormal3f(0.0f, 0.0f, 1.0f); //指定法向量    glVertex2f(fVers[0][0], fVers[0][1]);    for (i = 7; i > 0; i--)    {     glNormal3f(0.0f, 0.0f, 1.0f);  //指定法向量     glVertex2f(fVers[i][0], fVers[i][1]);    }   }   glEnd();  }  glPopMatrix();  glutSwapBuffers(); //交换前后缓冲区(相当于刷新显示) } void OnReshape(int w,int h) {  GLfloat aspect = (GLfloat)w / (GLfloat)h;  GLfloat nRange = 100.0f;

 glViewport(0, 0, w, h);

 glMatrixMode(GL_PROJECTION);     //将当前矩阵指定为投影模式  glLoadIdentity();

 //设置三维投影区

 if (w <= h)  {   glOrtho(-nRange, nRange, -nRange / aspect, nRange / aspect, -nRange, nRange);  }  else  {   glOrtho(-nRange, nRange, -nRange * aspect, nRange * aspect, -nRange, nRange);  }  glMatrixMode(GL_MODELVIEW);     //将当前矩阵恢复为模型视图模式  glLoadIdentity(); } void OnMenu(int value) {  switch(value)         //当前用户选择的菜单项的ID  {  case 1:   bDepth = !bDepth;   break;  case 2:   bOutline = !bOutline;  }

 glutPostRedisplay();         //强制显示刷新 } int main(int argc, char* argv[]) {  glutInit(&argc, argv);                                      //初始化OpenGL  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);   //设置显示模式  glutInitWindowSize(600, 480);  glutCreateWindow("利用平面图元构造三维实体");

 glutCreateMenu(OnMenu);  glutReshapeFunc(OnReshape);  glutDisplayFunc(OnDisplay);

 CreatMenu();                //实际生成菜单(对于windows应用程序,这里的菜单技术是无效的,因为windows有自己的菜单系统)  SetupLights();              //设置光照  CalaulateVertices(fVers);   //计算所绘实体各顶点的坐标  glutMainLoop();             //进入OpenGL主循环  return 0; }


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值