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<70>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();
|
||
}
|