主要包含圆柱体(Cylinder)圆盘(Disk)球(Sphere) 圆锥(Cylinder)
作法:
1.创建几何体对象 GLUquadricObj *quadratic=gluNewQuadric();
2.设置几何体属性 gluQuadricNormals(法线)gluQuadricTexture(纹理)
gluQuadricOrientation(对齐方式)gluQuadricDrawStyle(绘画样式)
3.绘制二次几何体
gluQuadricNormals | 设置法线 | |
GLU_FLAT | 普通 | |
GLU_SMOOTH | 平滑 | |
GLU_NONE | ||
gluQuadricTexture | GL_TRUE|GL_FALSE | 是否绑定纹理 |
gluQuadricOrientation | GLU_OUTSIDE|GLU_INSIDE | 设置对其方式 |
gluQuadricDrawStyle | 绘画样式 | |
GLU_POINT | 以点方式绘制 | |
GLU_LINE | 以线方式绘制 | |
GLU_FILL 100010 #define GLU_LINE 100011 #define GLU_FILL 100012 #define GLU_SILHOUETTE 100013 |
以填充方式绘制 | |
GLU_SILHOUETTE | ||
gluCylinder | 绘制圆柱体|圆锥 | |
参数2 | 圆柱体的底面半径 | |
参数3 | 圆柱体的顶面半径(圆锥半径为0.0) | |
参数4 | 圆柱体的高度 | |
参数5 | 纬线(环绕Z轴有多少细分) | |
参数6 | 经线(沿着Z轴有多少细分)。细分越多该对象就越细致。 | |
gluDisk | ||
参数2 | 盘子的内圆半径,该参数可以为0,则表示在盘子中间没孔,内圆半径越大孔越大 | |
参数3 | 表示外圆半径,这个参数必须比内圆半径大 | |
参数4 | 组成该盘子的切片的数量,这个数量可以想象成披萨饼中的切片的数量。切片越多,外圆边缘就越平滑 | |
参数5 | 组成盘子的环的数量。环很像唱片上的轨迹,一环套一环。这些环从内圆半径细分到外圆半径。细分越多,速度越慢。 | |
gluSphere | 绘制球 | |
参数2 | 半径 | |
参数3 | 纬线 | |
参数4 | 经线 | |
gluPartialDisk | 参数2 | 绘制部分圆盘 |
参数3 | 盘子的内圆半径,该参数可以为0,则表示在盘子中间没孔,内圆半径越大孔越大 | |
参数4 | 表示外圆半径,这个参数必须比内圆半径大 | |
参数5 | 组成该盘子的切片的数量,这个数量可以想象成披萨饼中的切片的数量。切片越多,外圆边缘就越平滑 | |
参数6 | 组成盘子的环的数量。环很像唱片上的轨迹,一环套一环。这些环从内圆半径细分到外圆半径。细分越多,速度越慢。 | |
参数7 | 起始角度 | |
参数8 | 旋转角度 |
#include "header.h" int part1; int part2; int p1=0; int p2=1; GLfloat xrot; GLfloat yrot; GLfloat xspeed; GLfloat yspeed; GLfloat z=-5.0f; GLUquadricObj *quadratic; GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f }; GLuint filter; GLuint texture[3]; GLuint object=0; AUX_RGBImageRec *LoadBMP(char *Filename) { FILE *File=NULL; if (!Filename) { return NULL; } File=fopen(Filename,"r"); if (File) { fclose(File); return auxDIBImageLoad(Filename); } return NULL; } int LoadGLTextures() { int Status=FALSE; AUX_RGBImageRec *TextureImage[1]; memset(TextureImage,0,sizeof(void *)*1); if (TextureImage[0]=LoadBMP("Data/Wall.bmp")) { Status=TRUE; glGenTextures(3, &texture[0]); // Create Nearest Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // Create Linear Filtered Texture glBindTexture(GL_TEXTURE_2D, texture[1]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // Create MipMapped Texture glBindTexture(GL_TEXTURE_2D, texture[2]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); } if (TextureImage[0]) { if (TextureImage[0]->data) { free(TextureImage[0]->data); } free(TextureImage[0]); } return Status; } GLvoid ReSizeGLScene(GLsizei width, GLsizei height) { if (height==0) { height=1; } glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int InitGL(void) { if (!LoadGLTextures()) { return FALSE; } glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); glEnable(GL_LIGHT1); quadratic=gluNewQuadric(); gluQuadricNormals(quadratic, GLU_SMOOTH); gluQuadricTexture(quadratic, GL_TRUE); return TRUE; } void glDrawCube() { glBegin(GL_QUADS); // Front Face glNormal3f( 0.0f, 0.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); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Back Face glNormal3f( 0.0f, 0.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); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Face glNormal3f( 0.0f, 1.0f, 0.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); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Bottom Face glNormal3f( 0.0f,-1.0f, 0.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); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Right Face glNormal3f( 1.0f, 0.0f, 0.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); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Left Face glNormal3f(-1.0f, 0.0f, 0.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); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); } void DrawGLScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f,0.0f,z); glRotatef(xrot,1.0f,0.0f,0.0f); glRotatef(yrot,0.0f,1.0f,0.0f); glBindTexture(GL_TEXTURE_2D, texture[filter]); switch(object) { case 0: glDrawCube(); break; case 1: glTranslatef(0.0f,0.0f,-1.5f); gluCylinder(quadratic,1.0f,1.0f,3.0f,32,32); break; case 2: gluDisk(quadratic,0.5f,1.5f,32,32); break; case 3: gluSphere(quadratic,1.3f,32,32); break; case 4: glTranslatef(0.0f,0.0f,-1.5f); gluCylinder(quadratic,1.0f,0.0f,3.0f,32,32); break; case 5: part1+=p1; part2+=p2; if(part1>359) { p1=0; part1=0; p2=1; part2=0; } if(part2>359) { p1=1; p2=0; } gluPartialDisk(quadratic,0.5f,1.5f,32,32,part1,part2-part1); break; }; xrot+=xspeed; yrot+=yspeed; glFlush(); } void rotate() { glutPostRedisplay(); } void keyboard(unsigned char key,int x,int y) { switch (key) { case 'L': glEnable(GL_LIGHTING); glutPostRedisplay(); break; case 'l': glDisable(GL_LIGHTING); glutPostRedisplay(); break; case ' ': object++; if(object>5) object=0; glutPostRedisplay(); break; case 'F': filter+=1; if (filter>2) { filter=0; } glutPostRedisplay(); break; case 'W': yspeed+=0.01f; glutIdleFunc(rotate); break; case 'S': yspeed-=0.01f; glutIdleFunc(rotate); break; case 'A': xspeed+=0.01f; glutIdleFunc(rotate); break; case 'D': xspeed-=0.01f; glutIdleFunc(rotate); break; case 'Z': z-=0.01f; glutIdleFunc(rotate); break; case 'X': z+=0.01f; glutIdleFunc(rotate); break; case 'R': glutIdleFunc(NULL); break; } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH); glutInitWindowSize(800,600); glutInitWindowPosition(100,100); glutCreateWindow("二次几何体"); InitGL(); glutDisplayFunc(DrawGLScene); glutKeyboardFunc(keyboard); glutReshapeFunc(ReSizeGLScene); glutMainLoop(); }