262 lines
6 KiB
C
262 lines
6 KiB
C
|
#include <stdlib.h>
|
|||
|
#include <math.h>
|
|||
|
#include <GL/gl.h>
|
|||
|
#include "glu.h"
|
|||
|
|
|||
|
|
|||
|
void drawTorus(float rc, int numc, float rt, int numt)
|
|||
|
{
|
|||
|
int i, j, k;
|
|||
|
double s, t;
|
|||
|
double x, y, z;
|
|||
|
double pi, twopi;
|
|||
|
|
|||
|
pi = 3.14159265358979323846;
|
|||
|
twopi = 2 * pi;
|
|||
|
|
|||
|
for (i = 0; i < numc; i++) {
|
|||
|
glBegin(GL_QUAD_STRIP);
|
|||
|
for (j = 0; j <= numt; j++) {
|
|||
|
for (k = 1; k >= 0; k--) {
|
|||
|
s = (i + k) % numc + 0.5;
|
|||
|
t = j % numt;
|
|||
|
|
|||
|
x = cos(t*twopi/numt) * cos(s*twopi/numc);
|
|||
|
y = sin(t*twopi/numt) * cos(s*twopi/numc);
|
|||
|
z = sin(s*twopi/numc);
|
|||
|
glNormal3f(x, y, z);
|
|||
|
|
|||
|
x = (rt + rc * cos(s*twopi/numc)) * cos(t*twopi/numt);
|
|||
|
y = (rt + rc * cos(s*twopi/numc)) * sin(t*twopi/numt);
|
|||
|
z = rc * sin(s*twopi/numc);
|
|||
|
glVertex3f(x, y, z);
|
|||
|
}
|
|||
|
}
|
|||
|
glEnd();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void normal3f( GLfloat x, GLfloat y, GLfloat z )
|
|||
|
{
|
|||
|
GLdouble mag;
|
|||
|
|
|||
|
mag = sqrt( x*x + y*y + z*z );
|
|||
|
if (mag>0.00001F) {
|
|||
|
x /= mag;
|
|||
|
y /= mag;
|
|||
|
z /= mag;
|
|||
|
}
|
|||
|
glNormal3f( x, y, z );
|
|||
|
}
|
|||
|
|
|||
|
void gluPerspective( GLdouble fovy, GLdouble aspect,
|
|||
|
GLdouble zNear, GLdouble zFar )
|
|||
|
{
|
|||
|
GLdouble xmin, xmax, ymin, ymax;
|
|||
|
|
|||
|
ymax = zNear * tan( fovy * M_PI / 360.0 );
|
|||
|
ymin = -ymax;
|
|||
|
|
|||
|
xmin = ymin * aspect;
|
|||
|
xmax = ymax * aspect;
|
|||
|
|
|||
|
glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
|
|||
|
}
|
|||
|
|
|||
|
GLUquadricObj *gluNewQuadric(void)
|
|||
|
{
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
void gluQuadricDrawStyle(GLUquadricObj *obj, int style)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void gluCylinder( GLUquadricObj *qobj,
|
|||
|
GLdouble baseRadius, GLdouble topRadius, GLdouble height,
|
|||
|
GLint slices, GLint stacks )
|
|||
|
{
|
|||
|
GLdouble da, r, dr, dz;
|
|||
|
GLfloat z, nz, nsign;
|
|||
|
GLint i, j;
|
|||
|
GLfloat du = 1.0 / slices;
|
|||
|
GLfloat dv = 1.0 / stacks;
|
|||
|
GLfloat tcx = 0.0, tcy = 0.0;
|
|||
|
|
|||
|
nsign = 1.0;
|
|||
|
|
|||
|
da = 2.0*M_PI / slices;
|
|||
|
dr = (topRadius-baseRadius) / stacks;
|
|||
|
dz = height / stacks;
|
|||
|
nz = (baseRadius-topRadius) / height; /* Z component of normal vectors */
|
|||
|
|
|||
|
for (i=0;i<slices;i++) {
|
|||
|
GLfloat x1 = -sin(i*da);
|
|||
|
GLfloat y1 = cos(i*da);
|
|||
|
GLfloat x2 = -sin((i+1)*da);
|
|||
|
GLfloat y2 = cos((i+1)*da);
|
|||
|
z = 0.0;
|
|||
|
r = baseRadius;
|
|||
|
tcy = 0.0;
|
|||
|
glBegin( GL_QUAD_STRIP );
|
|||
|
for (j=0;j<=stacks;j++) {
|
|||
|
if (nsign==1.0) {
|
|||
|
normal3f( x1*nsign, y1*nsign, nz*nsign );
|
|||
|
glTexCoord2f(tcx, tcy);
|
|||
|
glVertex3f( x1*r, y1*r, z );
|
|||
|
normal3f( x2*nsign, y2*nsign, nz*nsign );
|
|||
|
glTexCoord2f(tcx+du, tcy);
|
|||
|
glVertex3f( x2*r, y2*r, z );
|
|||
|
}
|
|||
|
else {
|
|||
|
normal3f( x2*nsign, y2*nsign, nz*nsign );
|
|||
|
glTexCoord2f(tcx, tcy);
|
|||
|
glVertex3f( x2*r, y2*r, z );
|
|||
|
normal3f( x1*nsign, y1*nsign, nz*nsign );
|
|||
|
glTexCoord2f(tcx+du, tcy);
|
|||
|
glVertex3f( x1*r, y1*r, z );
|
|||
|
}
|
|||
|
z += dz;
|
|||
|
r += dr;
|
|||
|
tcy += dv;
|
|||
|
}
|
|||
|
glEnd();
|
|||
|
tcx += du;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Disk (adapted from Mesa) */
|
|||
|
|
|||
|
void gluDisk( GLUquadricObj *qobj,
|
|||
|
GLdouble innerRadius, GLdouble outerRadius,
|
|||
|
GLint slices, GLint loops )
|
|||
|
{
|
|||
|
GLdouble a, da;
|
|||
|
GLfloat dr;
|
|||
|
GLfloat r1, r2, dtc;
|
|||
|
GLint s, l;
|
|||
|
GLfloat sa,ca;
|
|||
|
|
|||
|
/* Normal vectors */
|
|||
|
glNormal3f( 0.0, 0.0, +1.0 );
|
|||
|
|
|||
|
da = 2.0*M_PI / slices;
|
|||
|
dr = (outerRadius-innerRadius) / (GLfloat) loops;
|
|||
|
|
|||
|
/* texture of a gluDisk is a cut out of the texture unit square */
|
|||
|
/* x, y in [-outerRadius, +outerRadius]; s, t in [0, 1] (linear mapping) */
|
|||
|
dtc = 2.0f * outerRadius;
|
|||
|
|
|||
|
r1 = innerRadius;
|
|||
|
for (l=0;l<loops;l++) {
|
|||
|
r2 = r1 + dr;
|
|||
|
glBegin( GL_QUAD_STRIP );
|
|||
|
for (s=0;s<=slices;s++) {
|
|||
|
if (s==slices) a = 0.0;
|
|||
|
else a = s * da;
|
|||
|
sa = sin(a); ca = cos(a);
|
|||
|
glTexCoord2f(0.5+sa*r2/dtc,0.5+ca*r2/dtc);
|
|||
|
glVertex2f( r2*sa, r2*ca );
|
|||
|
glTexCoord2f(0.5+sa*r1/dtc,0.5+ca*r1/dtc);
|
|||
|
glVertex2f( r1*sa, r1*ca );
|
|||
|
}
|
|||
|
glEnd();
|
|||
|
r1 = r2;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Sph<EFBFBD>re (adapted from Mesa)
|
|||
|
*/
|
|||
|
|
|||
|
void gluSphere(GLUquadricObj *qobj,
|
|||
|
float radius,int slices,int stacks)
|
|||
|
{
|
|||
|
float rho, drho, theta, dtheta;
|
|||
|
float x, y, z;
|
|||
|
float s, t, ds, dt;
|
|||
|
int i, j, imin, imax;
|
|||
|
int normals;
|
|||
|
float nsign;
|
|||
|
|
|||
|
normals=1;
|
|||
|
nsign=1;
|
|||
|
|
|||
|
drho = M_PI / (float) stacks;
|
|||
|
dtheta = 2.0 * M_PI / (float) slices;
|
|||
|
|
|||
|
/* draw +Z end as a triangle fan */
|
|||
|
glBegin( GL_TRIANGLE_FAN );
|
|||
|
glNormal3f( 0.0, 0.0, 1.0 );
|
|||
|
glTexCoord2f(0.5,0.0);
|
|||
|
glVertex3f( 0.0, 0.0, nsign * radius );
|
|||
|
for (j=0;j<=slices;j++) {
|
|||
|
theta = (j==slices) ? 0.0 : j * dtheta;
|
|||
|
x = -sin(theta) * sin(drho);
|
|||
|
y = cos(theta) * sin(drho);
|
|||
|
z = nsign * cos(drho);
|
|||
|
if (normals) glNormal3f( x*nsign, y*nsign, z*nsign );
|
|||
|
glVertex3f( x*radius, y*radius, z*radius );
|
|||
|
}
|
|||
|
glEnd();
|
|||
|
|
|||
|
|
|||
|
ds = 1.0 / slices;
|
|||
|
dt = 1.0 / stacks;
|
|||
|
t = 1.0; /* because loop now runs from 0 */
|
|||
|
if (1) {
|
|||
|
imin = 0;
|
|||
|
imax = stacks;
|
|||
|
}
|
|||
|
else {
|
|||
|
imin = 1;
|
|||
|
imax = stacks-1;
|
|||
|
}
|
|||
|
|
|||
|
/* draw intermediate stacks as quad strips */
|
|||
|
for (i=imin;i<imax;i++) {
|
|||
|
rho = i * drho;
|
|||
|
glBegin( GL_QUAD_STRIP );
|
|||
|
s = 0.0;
|
|||
|
for (j=0;j<=slices;j++) {
|
|||
|
theta = (j==slices) ? 0.0 : j * dtheta;
|
|||
|
x = -sin(theta) * sin(rho);
|
|||
|
y = cos(theta) * sin(rho);
|
|||
|
z = nsign * cos(rho);
|
|||
|
if (normals) glNormal3f( x*nsign, y*nsign, z*nsign );
|
|||
|
glTexCoord2f(s,1-t);
|
|||
|
glVertex3f( x*radius, y*radius, z*radius );
|
|||
|
x = -sin(theta) * sin(rho+drho);
|
|||
|
y = cos(theta) * sin(rho+drho);
|
|||
|
z = nsign * cos(rho+drho);
|
|||
|
if (normals) glNormal3f( x*nsign, y*nsign, z*nsign );
|
|||
|
glTexCoord2f(s,1-(t-dt));
|
|||
|
s += ds;
|
|||
|
glVertex3f( x*radius, y*radius, z*radius );
|
|||
|
}
|
|||
|
glEnd();
|
|||
|
t -= dt;
|
|||
|
}
|
|||
|
|
|||
|
/* draw -Z end as a triangle fan */
|
|||
|
glBegin( GL_TRIANGLE_FAN );
|
|||
|
glNormal3f( 0.0, 0.0, -1.0 );
|
|||
|
glTexCoord2f(0.5,1.0);
|
|||
|
glVertex3f( 0.0, 0.0, -radius*nsign );
|
|||
|
rho = M_PI - drho;
|
|||
|
s = 1.0;
|
|||
|
t = dt;
|
|||
|
for (j=slices;j>=0;j--) {
|
|||
|
theta = (j==slices) ? 0.0 : j * dtheta;
|
|||
|
x = -sin(theta) * sin(rho);
|
|||
|
y = cos(theta) * sin(rho);
|
|||
|
z = nsign * cos(rho);
|
|||
|
if (normals) glNormal3f( x*nsign, y*nsign, z*nsign );
|
|||
|
glTexCoord2f(s,1-t);
|
|||
|
s -= ds;
|
|||
|
glVertex3f( x*radius, y*radius, z*radius );
|
|||
|
}
|
|||
|
glEnd();
|
|||
|
}
|