📄 shapes.c
字号:
/* * freeglut_geometry.c * * Freeglut geometry rendering methods. * * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. * Written by Pawel W. Olszta, <olszta@sourceforge.net> * Creation date: Fri Dec 3 1999 * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */#include <math.h>#include "internal.h"/* * TODO BEFORE THE STABLE RELEASE: * * Following functions have been contributed by Andreas Umbach. * * glutWireCube() -- looks OK * glutSolidCube() -- OK * * Those functions have been implemented by John Fay. * * glutWireTorus() -- looks OK * glutSolidTorus() -- looks OK * glutWireDodecahedron() -- looks OK * glutSolidDodecahedron() -- looks OK * glutWireOctahedron() -- looks OK * glutSolidOctahedron() -- looks OK * glutWireTetrahedron() -- looks OK * glutSolidTetrahedron() -- looks OK * glutWireIcosahedron() -- looks OK * glutSolidIcosahedron() -- looks OK * * The Following functions have been updated by Nigel Stewart, based * on FreeGLUT 2.0.0 implementations: * * glutWireSphere() -- looks OK * glutSolidSphere() -- looks OK * glutWireCone() -- looks OK * glutSolidCone() -- looks OK *//* -- INTERFACE FUNCTIONS -------------------------------------------------- *//* * Draws a wireframed cube. Code contributed by Andreas Umbach <marvin@dataway.ch> */void GLUTAPIENTRY glutWireCube( GLdouble dSize ){ double size = dSize * 0.5;# define V(a,b,c) glVertex3d( a size, b size, c size );# define N(a,b,c) glNormal3d( a, b, c ); /* * PWO: I dared to convert the code to use macros... */ glBegin( GL_LINE_LOOP ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); glEnd(); glBegin( GL_LINE_LOOP ); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); glEnd(); glBegin( GL_LINE_LOOP ); N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); glEnd(); glBegin( GL_LINE_LOOP ); N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); glEnd(); glBegin( GL_LINE_LOOP ); N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); glEnd(); glBegin( GL_LINE_LOOP ); N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); glEnd();# undef V# undef N}/* * Draws a solid cube. Code contributed by Andreas Umbach <marvin@dataway.ch> */void GLUTAPIENTRY glutSolidCube( GLdouble dSize ){ double size = dSize * 0.5;# define V(a,b,c) glVertex3d( a size, b size, c size );# define N(a,b,c) glNormal3d( a, b, c ); /* * PWO: Again, I dared to convert the code to use macros... */ glBegin( GL_QUADS ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); glEnd();# undef V# undef N}/* * Compute lookup table of cos and sin values forming a cirle * * Notes: * It is the responsibility of the caller to free these tables * The size of the table is (n+1) to form a connected loop * The last entry is exactly the same as the first * The sign of n can be flipped to get the reverse loop */static void circleTable(double **sint,double **cost,const int n){ int i; /* Table size, the sign of n flips the circle direction */ const int size = abs(n); /* Determine the angle between samples */ const double angle = 2*M_PI/(double)n; /* Allocate memory for n samples, plus duplicate of first entry at the end */ *sint = (double *) calloc(sizeof(double), size+1); *cost = (double *) calloc(sizeof(double), size+1); /* Bail out if memory allocation fails, fgError never returns */ if (!(*sint) || !(*cost)) { free(*sint); free(*cost); _glut_fatal("Failed to allocate memory in circleTable"); } /* Compute cos and sin around the circle */ for (i=0; i<size; i++) { (*sint)[i] = sin(angle*i); (*cost)[i] = cos(angle*i); } /* Last sample is duplicate of the first */ (*sint)[size] = (*sint)[0]; (*cost)[size] = (*cost)[0];}/* * Draws a solid sphere */void GLUTAPIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks){ int i,j; /* Adjust z and radius as stacks are drawn. */ double z0,z1; double r0,r1; /* Pre-computed circle */ double *sint1,*cost1; double *sint2,*cost2; circleTable(&sint1,&cost1,-slices); circleTable(&sint2,&cost2,stacks*2); /* The top stack is covered with a triangle fan */ z0 = 1.0; z1 = cost2[1]; r0 = 0.0; r1 = sint2[1]; glBegin(GL_TRIANGLE_FAN); glNormal3d(0,0,1); glVertex3d(0,0,radius); for (j=slices; j>=0; j--) { glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 ); glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius); } glEnd(); /* Cover each stack with a quad strip, except the top and bottom stacks */ for( i=1; i<stacks-1; i++ ) { z0 = z1; z1 = cost2[i+1]; r0 = r1; r1 = sint2[i+1]; glBegin(GL_QUAD_STRIP); for(j=0; j<=slices; j++) { glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 ); glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius); glNormal3d(cost1[j]*r0, sint1[j]*r0, z0 ); glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius); } glEnd(); } /* The bottom stack is covered with a triangle fan */ z0 = z1; r0 = r1; glBegin(GL_TRIANGLE_FAN); glNormal3d(0,0,-1); glVertex3d(0,0,-radius); for (j=0; j<=slices; j++) { glNormal3d(cost1[j]*r0, sint1[j]*r0, z0 ); glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius); } glEnd(); /* Release sin and cos tables */ free(sint1); free(cost1); free(sint2); free(cost2);}/* * Draws a solid sphere */void GLUTAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks){ int i,j; /* Adjust z and radius as stacks and slices are drawn. */ double r; double x,y,z; /* Pre-computed circle */ double *sint1,*cost1; double *sint2,*cost2; circleTable(&sint1,&cost1,-slices ); circleTable(&sint2,&cost2, stacks*2); /* Draw a line loop for each stack */ for (i=1; i<stacks; i++) { z = cost2[i]; r = sint2[i]; glBegin(GL_LINE_LOOP); for(j=0; j<=slices; j++) { x = cost1[j]; y = sint1[j]; glNormal3d(x,y,z); glVertex3d(x*r*radius,y*r*radius,z*radius); } glEnd(); } /* Draw a line loop for each slice */ for (i=0; i<slices; i++) { glBegin(GL_LINE_STRIP); for(j=0; j<=stacks; j++) { x = cost1[i]*sint2[j]; y = sint1[i]*sint2[j]; z = cost2[j]; glNormal3d(x,y,z); glVertex3d(x*radius,y*radius,z*radius); } glEnd(); } /* Release sin and cos tables */ free(sint1); free(cost1); free(sint2); free(cost2);}/* * Draws a solid cone */void GLUTAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks ){ int i,j; /* Step in z and radius as stacks are drawn. */ double z0,z1; double r0,r1; const double zStep = height/stacks; const double rStep = base/stacks; /* Scaling factors for vertex normals */ const double cosn = ( height / sqrt ( height * height + base * base )); const double sinn = ( base / sqrt ( height * height + base * base )); /* Pre-computed circle */ double *sint,*cost; circleTable(&sint,&cost,-slices); /* Cover the circular base with a triangle fan... */ z0 = 0.0; z1 = zStep; r0 = base; r1 = r0 - rStep; glBegin(GL_TRIANGLE_FAN); glNormal3d(0.0,0.0,-1.0); glVertex3d(0.0,0.0, z0 ); for (j=0; j<=slices; j++) glVertex3d(cost[j]*r0, sint[j]*r0, z0); glEnd(); /* Cover each stack with a quad strip, except the top stack */ for( i=0; i<stacks-1; i++ ) { glBegin(GL_QUAD_STRIP); for(j=0; j<=slices; j++) { glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn); glVertex3d(cost[j]*r0, sint[j]*r0, z0 ); glVertex3d(cost[j]*r1, sint[j]*r1, z1 ); } z0 = z1; z1 += zStep; r0 = r1; r1 -= rStep; glEnd(); } /* The top stack is covered with individual triangles */ glBegin(GL_TRIANGLES); glNormal3d(cost[0]*sinn, sint[0]*sinn, cosn);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -