diff --git a/src/java/org/lwjgl/opengl/glu/Cylinder.java b/src/java/org/lwjgl/opengl/glu/Cylinder.java new file mode 100644 index 00000000..3ff4d73f --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/Cylinder.java @@ -0,0 +1,169 @@ +package org.lwjgl.opengl.glu; + +import org.lwjgl.opengl.GL; + +/** + * Cylinder.java + * + * + * Created 23-dec-2003 + * @author Erik Duijs + */ +public class Cylinder extends Quadric implements GLUConstants { + + /** + * Constructor for Cylinder. + */ + public Cylinder() { + super(); + } + + /** + * draws a cylinder oriented along the z axis. The base of the + * cylinder is placed at z = 0, and the top at z=height. Like a sphere, a + * cylinder is subdivided around the z axis into slices, and along the z axis + * into stacks. + * + * Note that if topRadius is set to zero, then this routine will generate a + * cone. + * + * If the orientation is set to GLU.OUTSIDE (with glu.quadricOrientation), then + * any generated normals point away from the z axis. Otherwise, they point + * toward the z axis. + * + * If texturing is turned on (with glu.quadricTexture), then texture + * coordinates are generated so that t ranges linearly from 0.0 at z = 0 to + * 1.0 at z = height, and s ranges from 0.0 at the +y axis, to 0.25 at the +x + * axis, to 0.5 at the -y axis, to 0.75 at the -x axis, and back to 1.0 at the + * +y axis. + * + * @param baseRadius Specifies the radius of the cylinder at z = 0. + * @param topRadius Specifies the radius of the cylinder at z = height. + * @param height Specifies the height of the cylinder. + * @param slices Specifies the number of subdivisions around the z axis. + * @param stacks Specifies the number of subdivisions along the z axis. + */ + public void draw(float baseRadius, float topRadius, float height, int slices, int stacks) { + + float da, r, dr, dz; + float x, y, z, nz, nsign; + int i, j; + + if (super.orientation == GLU_INSIDE) { + nsign = -1.0f; + } else { + nsign = 1.0f; + } + + da = 2.0f * PI / slices; + dr = (topRadius - baseRadius) / stacks; + dz = height / stacks; + nz = (baseRadius - topRadius) / height; + // Z component of normal vectors + + if (super.drawStyle == GLU_POINT) { + GL.glBegin(GL.GL_POINTS); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(x * nsign, y * nsign, nz * nsign); + + z = 0.0f; + r = baseRadius; + for (j = 0; j <= stacks; j++) { + GL.glVertex3f((x * r), (y * r), z); + z += dz; + r += dr; + } + } + GL.glEnd(); + } else if (super.drawStyle == GLU_LINE || super.drawStyle == GLU_SILHOUETTE) { + // Draw rings + if (super.drawStyle == GLU_LINE) { + z = 0.0f; + r = baseRadius; + for (j = 0; j <= stacks; j++) { + GL.glBegin(GL.GL_LINE_LOOP); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(x * nsign, y * nsign, nz * nsign); + GL.glVertex3f((x * r), (y * r), z); + } + GL.glEnd(); + z += dz; + r += dr; + } + } else { + // draw one ring at each end + if (baseRadius != 0.0) { + GL.glBegin(GL.GL_LINE_LOOP); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(x * nsign, y * nsign, nz * nsign); + GL.glVertex3f((x * baseRadius), (y * baseRadius), 0.0f); + } + GL.glEnd(); + GL.glBegin(GL.GL_LINE_LOOP); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(x * nsign, y * nsign, nz * nsign); + GL.glVertex3f((x * topRadius), (y * topRadius), height); + } + GL.glEnd(); + } + } + // draw length lines + GL.glBegin(GL.GL_LINES); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(x * nsign, y * nsign, nz * nsign); + GL.glVertex3f((x * baseRadius), (y * baseRadius), 0.0f); + GL.glVertex3f((x * topRadius), (y * topRadius), (height)); + } + GL.glEnd(); + } else if (super.drawStyle == GLU_FILL) { + float ds = 1.0f / slices; + float dt = 1.0f / stacks; + float t = 0.0f; + z = 0.0f; + r = baseRadius; + for (j = 0; j < stacks; j++) { + float s = 0.0f; + GL.glBegin(GL.GL_QUAD_STRIP); + for (i = 0; i <= slices; i++) { + if (i == slices) { + x = sin(0.0f); + y = cos(0.0f); + } else { + x = sin((i * da)); + y = cos((i * da)); + } + if (nsign == 1.0f) { + normal3f((x * nsign), (y * nsign), (nz * nsign)); + TXTR_COORD(s, t); + GL.glVertex3f((x * r), (y * r), z); + normal3f((x * nsign), (y * nsign), (nz * nsign)); + TXTR_COORD(s, t + dt); + GL.glVertex3f((x * (r + dr)), (y * (r + dr)), (z + dz)); + } else { + normal3f(x * nsign, y * nsign, nz * nsign); + TXTR_COORD(s, t); + GL.glVertex3f((x * r), (y * r), z); + normal3f(x * nsign, y * nsign, nz * nsign); + TXTR_COORD(s, t + dt); + GL.glVertex3f((x * (r + dr)), (y * (r + dr)), (z + dz)); + } + s += ds; + } // for slices + GL.glEnd(); + r += dr; + t += dt; + z += dz; + } // for stacks + } + } +} diff --git a/src/java/org/lwjgl/opengl/glu/Disk.java b/src/java/org/lwjgl/opengl/glu/Disk.java new file mode 100644 index 00000000..b4787d76 --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/Disk.java @@ -0,0 +1,182 @@ +package org.lwjgl.opengl.glu; + +import org.lwjgl.opengl.GL; + +/** + * Disk.java + * + * + * Created 23-dec-2003 + * @author Erik Duijs + */ +public class Disk extends Quadric implements GLUConstants { + + /** + * Constructor for Disk. + */ + public Disk() { + super(); + } + + /** + * renders a disk on the z = 0 plane. The disk has a radius of + * outerRadius, and contains a concentric circular hole with a radius of + * innerRadius. If innerRadius is 0, then no hole is generated. The disk is + * subdivided around the z axis into slices (like pizza slices), and also + * about the z axis into rings (as specified by slices and loops, + * respectively). + * + * With respect to orientation, the +z side of the disk is considered to be + * "outside" (see glu.quadricOrientation). This means that if the orientation + * is set to GLU.OUTSIDE, then any normals generated point along the +z axis. + * Otherwise, they point along the -z axis. + * + * If texturing is turned on (with glu.quadricTexture), texture coordinates are + * generated linearly such that where r=outerRadius, the value at (r, 0, 0) is + * (1, 0.5), at (0, r, 0) it is (0.5, 1), at (-r, 0, 0) it is (0, 0.5), and at + * (0, -r, 0) it is (0.5, 0). + */ + public void draw(float innerRadius, float outerRadius, int slices, int loops) + { + float da, dr; + + /* Normal vectors */ + if (super.normals != GLU_NONE) { + if (super.orientation == GLU_OUTSIDE) { + GL.glNormal3f(0.0f, 0.0f, +1.0f); + } + else { + GL.glNormal3f(0.0f, 0.0f, -1.0f); + } + } + + da = 2.0f * PI / slices; + dr = (outerRadius - innerRadius) / loops; + + switch (super.drawStyle) { + case GLU_FILL: + { + /* 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) + */ + float dtc = 2.0f * outerRadius; + float sa, ca; + float r1 = innerRadius; + int l; + for (l = 0; l < loops; l++) { + float r2 = r1 + dr; + if (super.orientation == GLU_OUTSIDE) { + int s; + GL.glBegin(GL.GL_QUAD_STRIP); + for (s = 0; s <= slices; s++) { + float a; + if (s == slices) + a = 0.0f; + else + a = s * da; + sa = sin(a); + ca = cos(a); + TXTR_COORD(0.5f + sa * r2 / dtc, 0.5f + ca * r2 / dtc); + GL.glVertex2f(r2 * sa, r2 * ca); + TXTR_COORD(0.5f + sa * r1 / dtc, 0.5f + ca * r1 / dtc); + GL.glVertex2f(r1 * sa, r1 * ca); + } + GL.glEnd(); + } + else { + int s; + GL.glBegin(GL.GL_QUAD_STRIP); + for (s = slices; s >= 0; s--) { + float a; + if (s == slices) + a = 0.0f; + else + a = s * da; + sa = sin(a); + ca = cos(a); + TXTR_COORD(0.5f - sa * r2 / dtc, 0.5f + ca * r2 / dtc); + GL.glVertex2f(r2 * sa, r2 * ca); + TXTR_COORD(0.5f - sa * r1 / dtc, 0.5f + ca * r1 / dtc); + GL.glVertex2f(r1 * sa, r1 * ca); + } + GL.glEnd(); + } + r1 = r2; + } + break; + } + case GLU_LINE: + { + int l, s; + /* draw loops */ + for (l = 0; l <= loops; l++) { + float r = innerRadius + l * dr; + GL.glBegin(GL.GL_LINE_LOOP); + for (s = 0; s < slices; s++) { + float a = s * da; + GL.glVertex2f(r * sin(a), r * cos(a)); + } + GL.glEnd(); + } + /* draw spokes */ + for (s = 0; s < slices; s++) { + float a = s * da; + float x = sin(a); + float y = cos(a); + GL.glBegin(GL.GL_LINE_STRIP); + for (l = 0; l <= loops; l++) { + float r = innerRadius + l * dr; + GL.glVertex2f(r * x, r * y); + } + GL.glEnd(); + } + break; + } + case GLU_POINT: + { + int s; + GL.glBegin(GL.GL_POINTS); + for (s = 0; s < slices; s++) { + float a = s * da; + float x = sin(a); + float y = cos(a); + int l; + for (l = 0; l <= loops; l++) { + float r = innerRadius * l * dr; + GL.glVertex2f(r * x, r * y); + } + } + GL.glEnd(); + break; + } + case GLU_SILHOUETTE: + { + if (innerRadius != 0.0) { + float a; + GL.glBegin(GL.GL_LINE_LOOP); + for (a = 0.0f; a < 2.0 * PI; a += da) { + float x = innerRadius * sin(a); + float y = innerRadius * cos(a); + GL.glVertex2f(x, y); + } + GL.glEnd(); + } + { + float a; + GL.glBegin(GL.GL_LINE_LOOP); + for (a = 0; a < 2.0f * PI; a += da) { + float x = outerRadius * sin(a); + float y = outerRadius * cos(a); + GL.glVertex2f(x, y); + } + GL.glEnd(); + } + break; + } + default: + return; + } + } + +} diff --git a/src/java/org/lwjgl/opengl/glu/GLU.java b/src/java/org/lwjgl/opengl/glu/GLU.java new file mode 100644 index 00000000..310b3e7b --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/GLU.java @@ -0,0 +1,162 @@ +package org.lwjgl.opengl.glu; + +import java.nio.ByteBuffer; + +import org.lwjgl.opengl.GL; + +/** + * GLU.java + * + * + * Created 23-dec-2003 + * @author Erik Duijs + */ +public class GLU extends Util implements GLUConstants { + + /** + * Method gluLookAt + * @param eyex + * @param eyey + * @param eyez + * @param centerx + * @param centery + * @param centerz + * @param upx + * @param upy + * @param upz + */ + public static void gluLookAt( + float eyex, + float eyey, + float eyez, + float centerx, + float centery, + float centerz, + float upx, + float upy, + float upz) { + + Project.gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz); + } + + /** + * Method gluOrtho2D + * @param left + * @param right + * @param bottom + * @param top + */ + public static void gluOrtho2D( + float left, + float right, + float bottom, + float top) { + + GL.glOrtho(left, right, bottom, top, -1.0, 1.0); + } + + /** + * Method gluPerspective + * @param fovy + * @param aspect + * @param zNear + * @param zFar + */ + public static void gluPerspective( + float fovy, + float aspect, + float zNear, + float zFar) { + + Project.gluPerspective(fovy, aspect, zNear, zFar); + } + + + /** + * Method gluPickMatrix + * @param x + * @param y + * @param width + * @param height + * @param viewport + */ + public static void gluPickMatrix( + float x, + float y, + float width, + float height, + int viewport[]) { + + Project.gluPickMatrix(x, y, width, height, viewport); + } + + /** + * Method gluGetString. + * @param name + * @return String + */ + public static String gluGetString(int name) { + return Registry.gluGetString(name); + } + + /** + * Method gluCheckExtension. + * @param string + * @param string1 + * @return boolean + */ + public static boolean gluCheckExtension(String extName, String extString) { + return Registry.gluCheckExtension(extName, extString); + } + + /** + * Method gluBuild2DMipmaps + * @param target + * @param components + * @param width + * @param height + * @param format + * @param type + * @param data + * @return int + */ + public static int gluBuild2DMipmaps( + int target, + int components, + int width, + int height, + int format, + int type, + ByteBuffer data) { + + return MipMap.gluBuild2DMipmaps(target, components, width, height, format, type, data); + } + + /** + * Method gluScaleImage. + * @param format + * @param width + * @param height + * @param type + * @param data + * @param w + * @param h + * @param type1 + * @param image + * @return int + */ + public static int gluScaleImage( + int format, + int widthIn, + int heightIn, + int typeIn, + ByteBuffer dataIn, + int widthOut, + int heightOut, + int typeOut, + ByteBuffer dataOut) { + + return MipMap.gluScaleImage(format, widthIn, heightIn, typeIn, dataIn, widthOut, heightOut, typeOut, dataOut); + } + +} diff --git a/src/java/org/lwjgl/opengl/glu/GLUConstants.java b/src/java/org/lwjgl/opengl/glu/GLUConstants.java new file mode 100644 index 00000000..d1aa7f51 --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/GLUConstants.java @@ -0,0 +1,193 @@ +package org.lwjgl.opengl.glu; + +/** + * $Id$ + * + * GLU constants. + * + * NOTE: this was lifted from LWJGL 0.6 with some minor modifications. + * + * @author cix_foo + * @version $Revision$ + */ +public interface GLUConstants { + + public static final float PI = (float)Math.PI; + + /* Errors: (return value 0 = no error) */ + public static final int GLU_INVALID_ENUM = 100900; + public static final int GLU_INVALID_VALUE = 100901; + public static final int GLU_OUT_OF_MEMORY = 100902; + public static final int GLU_INCOMPATIBLE_GL_VERSION = 100903; + + /* StringName */ + public static final int GLU_VERSION = 100800; + public static final int GLU_EXTENSIONS = 100801; + + /* Boolean */ + public static final boolean GLU_TRUE = true; + public static final boolean GLU_FALSE = false; + + + /**** Quadric constants ****/ + + /* QuadricNormal */ + public static final int GLU_SMOOTH = 100000; + public static final int GLU_FLAT = 100001; + public static final int GLU_NONE = 100002; + + /* QuadricDrawStyle */ + public static final int GLU_POINT = 100010; + public static final int GLU_LINE = 100011; + public static final int GLU_FILL = 100012; + public static final int GLU_SILHOUETTE = 100013; + + /* QuadricOrientation */ + public static final int GLU_OUTSIDE = 100020; + public static final int GLU_INSIDE = 100021; + + /* Callback types: */ + /* ERROR = 100103 */ + + + /**** Tesselation constants ****/ + + public static final double TESS_MAX_COORD = 1.0e150; + + /* TessProperty */ + public static final int GLU_TESS_WINDING_RULE = 100140; + public static final int GLU_TESS_BOUNDARY_ONLY = 100141; + public static final int GLU_TESS_TOLERANCE = 100142; + + /* TessWinding */ + public static final int GLU_TESS_WINDING_ODD = 100130; + public static final int GLU_TESS_WINDING_NONZERO = 100131; + public static final int GLU_TESS_WINDING_POSITIVE = 100132; + public static final int GLU_TESS_WINDING_NEGATIVE = 100133; + public static final int GLU_TESS_WINDING_ABS_GEQ_TWO = 100134; + + /* TessCallback */ + public static final int GLU_TESS_BEGIN = 100100; /* void (CALLBACK*)(GLenum type) */ + public static final int GLU_TESS_VERTEX = 100101; /* void (CALLBACK*)(void *data) */ + public static final int GLU_TESS_END = 100102; /* void (CALLBACK*)(void) */ + public static final int GLU_TESS_ERROR = 100103; /* void (CALLBACK*)(GLenum errno) */ + public static final int GLU_TESS_EDGE_FLAG = 100104; /* void (CALLBACK*)(GLboolean boundaryEdge) */ + public static final int GLU_TESS_COMBINE = 100105; /* void (CALLBACK*)(GLdouble coords[3], + void *data[4], + GLfloat weight[4], + void **dataOut) */ + public static final int GLU_TESS_BEGIN_DATA = 100106; /* void (CALLBACK*)(GLenum type, + void *polygon_data) */ + public static final int GLU_TESS_VERTEX_DATA = 100107; /* void (CALLBACK*)(void *data, + void *polygon_data) */ + public static final int GLU_TESS_END_DATA = 100108; /* void (CALLBACK*)(void *polygon_data) */ + public static final int GLU_TESS_ERROR_DATA = 100109; /* void (CALLBACK*)(GLenum errno, + void *polygon_data) */ + public static final int GLU_TESS_EDGE_FLAG_DATA = 100110; /* void (CALLBACK*)(GLboolean boundaryEdge, + void *polygon_data) */ + public static final int GLU_TESS_COMBINE_DATA = 100111; /* void (CALLBACK*)(GLdouble coords[3], + void *data[4], + GLfloat weight[4], + void **dataOut, + void *polygon_data) */ + + /* TessError */ + public static final int GLU_TESS_ERROR1 = 100151; + public static final int GLU_TESS_ERROR2 = 100152; + public static final int GLU_TESS_ERROR3 = 100153; + public static final int GLU_TESS_ERROR4 = 100154; + public static final int GLU_TESS_ERROR5 = 100155; + public static final int GLU_TESS_ERROR6 = 100156; + public static final int GLU_TESS_ERROR7 = 100157; + public static final int GLU_TESS_ERROR8 = 100158; + + public static final int GLU_TESS_MISSING_BEGIN_POLYGON = GLU_TESS_ERROR1; + public static final int GLU_TESS_MISSING_BEGIN_CONTOUR = GLU_TESS_ERROR2; + public static final int GLU_TESS_MISSING_END_POLYGON = GLU_TESS_ERROR3; + public static final int GLU_TESS_MISSING_END_CONTOUR = GLU_TESS_ERROR4; + public static final int GLU_TESS_COORD_TOO_LARGE = GLU_TESS_ERROR5; + public static final int GLU_TESS_NEED_COMBINE_CALLBACK = GLU_TESS_ERROR6; + + /**** NURBS constants ****/ + + /* NurbsProperty */ + public static final int GLU_AUTO_LOAD_MATRIX = 100200; + public static final int GLU_CULLING = 100201; + public static final int GLU_SAMPLING_TOLERANCE = 100203; + public static final int GLU_DISPLAY_MODE = 100204; + public static final int GLU_PARAMETRIC_TOLERANCE = 100202; + public static final int GLU_SAMPLING_METHOD = 100205; + public static final int GLU_U_STEP = 100206; + public static final int GLU_V_STEP = 100207; + + /* NurbsSampling */ + public static final int GLU_PATH_LENGTH = 100215; + public static final int GLU_PARAMETRIC_ERROR = 100216; + public static final int GLU_DOMAIN_DISTANCE = 100217; + + + /* NurbsTrim */ + public static final int GLU_MAP1_TRIM_2 = 100210; + public static final int GLU_MAP1_TRIM_3 = 100211; + + /* NurbsDisplay */ + /* FILL = 100012 */ + public static final int GLU_OUTLINE_POLYGON = 100240; + public static final int GLU_OUTLINE_PATCH = 100241; + + /* NurbsCallback */ + /* ERROR = 100103 */ + + /* NurbsErrors */ + public static final int GLU_NURBS_ERROR1 = 100251; + public static final int GLU_NURBS_ERROR2 = 100252; + public static final int GLU_NURBS_ERROR3 = 100253; + public static final int GLU_NURBS_ERROR4 = 100254; + public static final int GLU_NURBS_ERROR5 = 100255; + public static final int GLU_NURBS_ERROR6 = 100256; + public static final int GLU_NURBS_ERROR7 = 100257; + public static final int GLU_NURBS_ERROR8 = 100258; + public static final int GLU_NURBS_ERROR9 = 100259; + public static final int GLU_NURBS_ERROR10 = 100260; + public static final int GLU_NURBS_ERROR11 = 100261; + public static final int GLU_NURBS_ERROR12 = 100262; + public static final int GLU_NURBS_ERROR13 = 100263; + public static final int GLU_NURBS_ERROR14 = 100264; + public static final int GLU_NURBS_ERROR15 = 100265; + public static final int GLU_NURBS_ERROR16 = 100266; + public static final int GLU_NURBS_ERROR17 = 100267; + public static final int GLU_NURBS_ERROR18 = 100268; + public static final int GLU_NURBS_ERROR19 = 100269; + public static final int GLU_NURBS_ERROR20 = 100270; + public static final int GLU_NURBS_ERROR21 = 100271; + public static final int GLU_NURBS_ERROR22 = 100272; + public static final int GLU_NURBS_ERROR23 = 100273; + public static final int GLU_NURBS_ERROR24 = 100274; + public static final int GLU_NURBS_ERROR25 = 100275; + public static final int GLU_NURBS_ERROR26 = 100276; + public static final int GLU_NURBS_ERROR27 = 100277; + public static final int GLU_NURBS_ERROR28 = 100278; + public static final int GLU_NURBS_ERROR29 = 100279; + public static final int GLU_NURBS_ERROR30 = 100280; + public static final int GLU_NURBS_ERROR31 = 100281; + public static final int GLU_NURBS_ERROR32 = 100282; + public static final int GLU_NURBS_ERROR33 = 100283; + public static final int GLU_NURBS_ERROR34 = 100284; + public static final int GLU_NURBS_ERROR35 = 100285; + public static final int GLU_NURBS_ERROR36 = 100286; + public static final int GLU_NURBS_ERROR37 = 100287; + + /* Contours types -- obsolete! */ + public static final int GLU_CW = 100120; + public static final int GLU_CCW = 100121; + public static final int GLU_INTERIOR = 100122; + public static final int GLU_EXTERIOR = 100123; + public static final int GLU_UNKNOWN = 100124; + + /* Names without "TESS_" prefix */ + public static final int GLU_BEGIN = GLU_TESS_BEGIN; + public static final int GLU_VERTEX = GLU_TESS_VERTEX; + public static final int GLU_END = GLU_TESS_END; + public static final int GLU_ERROR = GLU_TESS_ERROR; + public static final int GLU_EDGE_FLAG = GLU_TESS_EDGE_FLAG; +} diff --git a/src/java/org/lwjgl/opengl/glu/MipMap.java b/src/java/org/lwjgl/opengl/glu/MipMap.java new file mode 100644 index 00000000..835a0a64 --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/MipMap.java @@ -0,0 +1,287 @@ +package org.lwjgl.opengl.glu; + +import java.nio.ByteBuffer; + +import org.lwjgl.opengl.GL; + +/** + * MipMap.java + * + * + * Created 11-jan-2004 + * @author Erik Duijs + */ +public class MipMap extends Util implements GLUConstants { + + /** + * Method gluBuild2DMipmaps + * + * @param target + * @param components + * @param width + * @param height + * @param format + * @param type + * @param data + * @return int + */ + public static int gluBuild2DMipmaps( + int target, + int components, + int width, + int height, + int format, + int type, + ByteBuffer data) { + + int retVal = 0; + int error; + int w, h, maxSize; + ByteBuffer image, newimage; + int neww, newh, level, bpp; + boolean done; + + if (width < 1 || height < 1) return GLU_INVALID_VALUE; + + maxSize = glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE); + + w = nearestPower(width); + if (w > maxSize) { + w = maxSize; + } + h = nearestPower(height); + if (h > maxSize) { + h = maxSize; + } + + bpp = bytesPerPixel(format, type); + if (bpp == 0) { + return GLU_INVALID_ENUM; + } + + // Get current glPixelStore state + PixelStoreState pss = new PixelStoreState(); + + // set pixel packing + GL.glPixelStorei(GL.GL_PACK_ROW_LENGTH, 0); + GL.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1); + GL.glPixelStorei(GL.GL_PACK_SKIP_ROWS, 0); + GL.glPixelStorei(GL.GL_PACK_SKIP_PIXELS, 0); + + done = false; + + if (w != width || h != height) { + // must rescale image to get "top" mipmap texture image + image = ByteBuffer.allocateDirect((w + 4) * h * bpp); + error = gluScaleImage(format, width, height, type, data, w, h, type, image); + if (error != 0) { + retVal = error; + done = true; + } + } else { + image = data; + } + + level = 0; + while (!done) { + if (image != data) { + /* set pixel unpacking */ + GL.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0); + GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); + GL.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, 0); + GL.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, 0); + } + + GL.glTexImage2D(target, level, components, w, h, 0, format, type, image); + + if (w == 1 && h == 1) + break; + + neww = (w < 2) ? 1 : w / 2; + newh = (h < 2) ? 1 : h / 2; + newimage = ByteBuffer.allocateDirect((neww + 4) * newh * bpp); + + error = gluScaleImage(format, w, h, type, image, neww, newh, type, newimage); + if (error != 0) { + retVal = error; + done = true; + } + + image = newimage; + + w = neww; + h = newh; + level++; + } + + // Restore original glPixelStore state + pss.save(); + + return retVal; + } + + /** + * Method gluScaleImage. + * @param format + * @param width + * @param height + * @param type + * @param data + * @param w + * @param h + * @param type1 + * @param image + * @return int + */ + public static int gluScaleImage( + int format, + int widthIn, + int heightIn, + int typein, + ByteBuffer dataIn, + int widthOut, + int heightOut, + int typeOut, + ByteBuffer dataOut) { + + int components, i, j, k; + float[] tempin, tempout; + float sx, sy; + int sizein, sizeout; + int rowstride, rowlen; + + components = compPerPix(format); + if (components == -1) { + return GLU_INVALID_ENUM; + } + + // temp image data + tempin = new float[widthIn * heightIn * components]; + tempout = new float[widthOut * heightOut * components]; + + // Determine bytes per input type + switch (typein) { + case GL.GL_UNSIGNED_BYTE : + sizein = 1; + break; + default : + return GL.GL_INVALID_ENUM; + } + + // Determine bytes per output type + switch (typeOut) { + case GL.GL_UNSIGNED_BYTE : + sizeout = 1; + break; + + default : + return GL.GL_INVALID_ENUM; + } + + // Get glPixelStore state + PixelStoreState pss = new PixelStoreState(); + + //Unpack the pixel data and convert to floating point + if (pss.unpackRowLength > 0) { + rowlen = pss.unpackRowLength; + } else { + rowlen = widthIn; + } + if (sizein >= pss.unpackAlignment) { + rowstride = components * rowlen; + } else { + rowstride = pss.unpackAlignment / sizein * ceil(components * rowlen * sizein, pss.unpackAlignment); + } + + switch (typein) { + case GL.GL_UNSIGNED_BYTE : + k = 0; + dataIn.rewind(); + for (i = 0; i < heightIn; i++) { + int ubptr = i * rowstride + pss.unpackSkipRows * rowstride + pss.unpackSkipPixels * components; + for (j = 0; j < widthIn * components; j++) { + tempin[k++] = (float) ((int) dataIn.get(ubptr++) & 0xff); + } + } + break; + + default : + return GLU_INVALID_ENUM; + } + + // Do scaling + sx = (float) widthIn / (float) widthOut; + sy = (float) heightIn / (float) heightOut; + + float[] c = new float[components]; + int src, dst; + + for (int iy = 0; iy < heightOut; iy++) { + for (int ix = 0; ix < widthOut; ix++) { + int x0 = (int) (ix * sx); + int x1 = (int) ((ix + 1) * sx); + int y0 = (int) (iy * sy); + int y1 = (int) ((iy + 1) * sy); + + int readPix = 0; + + // reset weighted pixel + for (int ic = 0; ic < components; ic++) { + c[ic] = 0; + } + + // create weighted pixel + for (int ix0 = x0; ix0 < x1; ix0++) { + for (int iy0 = y0; iy0 < y1; iy0++) { + + src = (iy0 * widthIn + ix0) * components; + + for (int ic = 0; ic < components; ic++) { + c[ic] += tempin[src + ic]; + } + + readPix++; + } + } + + // store weighted pixel + dst = (iy * widthOut + ix) * components; + + for (k = 0; k < components; k++) { + tempout[dst++] = c[k] / readPix; + } + } + } + + + // Convert temp output + if (pss.packRowLength > 0) { + rowlen = pss.packRowLength; + } else { + rowlen = widthOut; + } + if (sizeout >= pss.packAlignment) { + rowstride = components * rowlen; + } else { + rowstride = pss.packAlignment / sizeout * ceil(components * rowlen * sizeout, pss.packAlignment); + } + + switch (typeOut) { + case GL.GL_UNSIGNED_BYTE : + k = 0; + for (i = 0; i < heightOut; i++) { + int ubptr = i * rowstride + pss.packSkipRows * rowstride + pss.packSkipPixels * components; + + for (j = 0; j < widthOut * components; j++) { + dataOut.put(ubptr++, (byte) tempout[k++]); + } + } + break; + + default : + return GLU_INVALID_ENUM; + } + + return 0; + } +} \ No newline at end of file diff --git a/src/java/org/lwjgl/opengl/glu/PartialDisk.java b/src/java/org/lwjgl/opengl/glu/PartialDisk.java new file mode 100644 index 00000000..0486be04 --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/PartialDisk.java @@ -0,0 +1,44 @@ + +package org.lwjgl.opengl.glu; + +/** + * PartialDisk.java + * + * + * Created 23-dec-2003 + * @author Erik Duijs + */ +public class PartialDisk extends Quadric implements GLUConstants { + + /** + * Constructor for PartialDisk. + */ + public PartialDisk() { + super(); + } + + /** + * renders a partial disk on the z=0 plane. A partial disk is + * similar to a full disk, except that only the subset of the disk from + * startAngle through startAngle + sweepAngle is included (where 0 degrees is + * along the +y axis, 90 degrees along the +x axis, 180 along the -y axis, and + * 270 along the -x axis). + * + * The partial disk has a radius of outerRadius, and contains a concentric + * circular hole with a radius of innerRadius. If innerRadius is zero, then + * no hole is generated. The partial disk is subdivided around the z axis + * into slices (like pizza slices), and also about the z axis into rings (as + * specified by slices and loops, respectively). + * + * With respect to orientation, the +z side of the partial disk is considered + * to be outside (see gluQuadricOrientation). This means that if the + * orientation is set to GLU_OUTSIDE, then any normals generated point along + * the +z axis. Otherwise, they point along the -z axis. + * + * If texturing is turned on (with gluQuadricTexture), texture coordinates are + * generated linearly such that where r=outerRadius, the value at (r, 0, 0) is + * (1, 0.5), at (0, r, 0) it is (0.5, 1), at (-r, 0, 0) it is (0, 0.5), and at + * (0, -r, 0) it is (0.5, 0). + */ + +} diff --git a/src/java/org/lwjgl/opengl/glu/PixelStoreState.java b/src/java/org/lwjgl/opengl/glu/PixelStoreState.java new file mode 100644 index 00000000..d9c1002a --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/PixelStoreState.java @@ -0,0 +1,53 @@ +package org.lwjgl.opengl.glu; + +import org.lwjgl.opengl.GL; + +/** + * PixelStoreState.java + * + * + * Created 11-jan-2004 + * @author Erik Duijs + */ +class PixelStoreState extends Util implements GLUConstants { + + public int unpackRowLength = glGetIntegerv(GL.GL_UNPACK_ROW_LENGTH); + public int unpackAlignment = glGetIntegerv(GL.GL_UNPACK_ALIGNMENT); + public int unpackSkipRows = glGetIntegerv(GL.GL_UNPACK_SKIP_ROWS); + public int unpackSkipPixels = glGetIntegerv(GL.GL_UNPACK_SKIP_PIXELS); + public int packRowLength = glGetIntegerv(GL.GL_PACK_ROW_LENGTH); + public int packAlignment = glGetIntegerv(GL.GL_PACK_ALIGNMENT); + public int packSkipRows = glGetIntegerv(GL.GL_PACK_SKIP_ROWS); + public int packSkipPixels = glGetIntegerv(GL.GL_PACK_SKIP_PIXELS); + + /** + * Constructor for PixelStoreState. + */ + public PixelStoreState() { + super(); + load(); + } + + public void load() { + unpackRowLength = glGetIntegerv(GL.GL_UNPACK_ROW_LENGTH); + unpackAlignment = glGetIntegerv(GL.GL_UNPACK_ALIGNMENT); + unpackSkipRows = glGetIntegerv(GL.GL_UNPACK_SKIP_ROWS); + unpackSkipPixels = glGetIntegerv(GL.GL_UNPACK_SKIP_PIXELS); + packRowLength = glGetIntegerv(GL.GL_PACK_ROW_LENGTH); + packAlignment = glGetIntegerv(GL.GL_PACK_ALIGNMENT); + packSkipRows = glGetIntegerv(GL.GL_PACK_SKIP_ROWS); + packSkipPixels = glGetIntegerv(GL.GL_PACK_SKIP_PIXELS); + } + + public void save() { + GL.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, unpackRowLength); + GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, unpackAlignment); + GL.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, unpackSkipRows); + GL.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, unpackSkipPixels); + GL.glPixelStorei(GL.GL_PACK_ROW_LENGTH, packRowLength); + GL.glPixelStorei(GL.GL_PACK_ALIGNMENT, packAlignment); + GL.glPixelStorei(GL.GL_PACK_SKIP_ROWS, packSkipRows); + GL.glPixelStorei(GL.GL_PACK_SKIP_PIXELS, packSkipPixels); + } + +} diff --git a/src/java/org/lwjgl/opengl/glu/Project.java b/src/java/org/lwjgl/opengl/glu/Project.java new file mode 100644 index 00000000..65c63ed8 --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/Project.java @@ -0,0 +1,157 @@ +package org.lwjgl.opengl.glu; + +import java.nio.FloatBuffer; + +import org.lwjgl.opengl.GL; + +/** + * Project.java + * + * + * Created 11-jan-2004 + * @author Erik Duijs + */ +public class Project extends Util implements GLUConstants { + + private static FloatBuffer matrix = createFloatBuffer(16); + + /** + * Make m an identity matrix + */ + private static void __gluMakeIdentityf() { + matrix.put(0 + 4 * 0, 1); + matrix.put(0 + 4 * 1, 0); + matrix.put(0 + 4 * 2, 0); + matrix.put(0 + 4 * 3, 0); + matrix.put(1 + 4 * 0, 0); + matrix.put(1 + 4 * 1, 1); + matrix.put(1 + 4 * 2, 0); + matrix.put(1 + 4 * 3, 0); + matrix.put(2 + 4 * 0, 0); + matrix.put(2 + 4 * 1, 0); + matrix.put(2 + 4 * 2, 1); + matrix.put(2 + 4 * 3, 0); + matrix.put(3 + 4 * 0, 0); + matrix.put(3 + 4 * 1, 0); + matrix.put(3 + 4 * 2, 0); + matrix.put(3 + 4 * 3, 1); + } + + /** + * Method gluPerspective. + * @param fovy + * @param aspect + * @param zNear + * @param zFar + */ + public static void gluPerspective(float fovy, float aspect, float zNear, float zFar) { + float sine, cotangent, deltaZ; + float radians = fovy / 2 * PI / 180; + + deltaZ = zFar - zNear; + sine = (float) Math.sin(radians); + if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { + return; + } + cotangent = (float) Math.cos(radians) / sine; + + __gluMakeIdentityf(); + + matrix.put(0 * 4 + 0, cotangent / aspect); + matrix.put(1 * 4 + 1, cotangent); + matrix.put(2 * 4 + 2, - (zFar + zNear) / deltaZ); + matrix.put(2 * 4 + 3, -1); + matrix.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ); + matrix.put(3 * 4 + 3, 0); + + GL.glMultMatrixf(matrix); + } + + /** + * Method gluLookAt + * @param eyex + * @param eyey + * @param eyez + * @param centerx + * @param centery + * @param centerz + * @param upx + * @param upy + * @param upz + */ + public static void gluLookAt( + float eyex, + float eyey, + float eyez, + float centerx, + float centery, + float centerz, + float upx, + float upy, + float upz) { + + int i; + float[] forward = new float[3]; + float[] side = new float[3]; + float[] up = new float[3]; + + forward[0] = centerx - eyex; + forward[1] = centery - eyey; + forward[2] = centerz - eyez; + + up[0] = upx; + up[1] = upy; + up[2] = upz; + + normalize(forward); + + /* Side = forward x up */ + cross(forward, up, side); + normalize(side); + + /* Recompute up as: up = side x forward */ + cross(side, forward, up); + + __gluMakeIdentityf(); + matrix.put(0 * 4 + 0, side[0]); + matrix.put(1 * 4 + 0, side[1]); + matrix.put(2 * 4 + 0, side[2]); + + matrix.put(0 * 4 + 1, up[0]); + matrix.put(1 * 4 + 1, up[1]); + matrix.put(2 * 4 + 1, up[2]); + + matrix.put(0 * 4 + 2, -forward[0]); + matrix.put(1 * 4 + 2, -forward[1]); + matrix.put(2 * 4 + 2, -forward[2]); + + GL.glMultMatrixf(matrix); + GL.glTranslatef(-eyex, -eyey, -eyez); + } + + /** + * Method gluPickMatrix + * @param x + * @param y + * @param deltax + * @param deltay + * @param viewport + */ + public static void gluPickMatrix( + float x, + float y, + float deltax, + float deltay, + int[] viewport) { + if (deltax <= 0 || deltay <= 0) { + return; + } + + /* Translate and scale the picked region to the entire window */ + GL.glTranslatef( + (viewport[2] - 2 * (x - viewport[0])) / deltax, + (viewport[3] - 2 * (y - viewport[1])) / deltay, + 0); + GL.glScalef(viewport[2] / deltax, viewport[3] / deltay, 1.0f); + } +} diff --git a/src/java/org/lwjgl/opengl/glu/Quadric.java b/src/java/org/lwjgl/opengl/glu/Quadric.java new file mode 100644 index 00000000..d2a18be3 --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/Quadric.java @@ -0,0 +1,167 @@ +package org.lwjgl.opengl.glu; + +import org.lwjgl.opengl.GL; + +/** + * Quadric.java + * + * + * Created 22-dec-2003 + * @author Erik Duijs + */ +public class Quadric implements GLUConstants { + + protected int drawStyle; + protected int orientation; + protected boolean textureFlag; + protected int normals; + + /** + * Constructor for Quadric. + */ + public Quadric() { + super(); + + drawStyle = this.GLU_FILL; + orientation = this.GLU_OUTSIDE; + textureFlag = false; + normals = this.GLU_SMOOTH; + } + + /** + * Call glNormal3f after scaling normal to unit length. + * + * @param x + * @param y + * @param z + */ + protected void normal3f(float x, float y, float z) { + float mag; + + mag = (float)Math.sqrt(x * x + y * y + z * z); + if (mag > 0.00001F) { + x /= mag; + y /= mag; + z /= mag; + } + GL.glNormal3f(x, y, z); + } + + /** + * specifies the draw style for quadrics. + * + * The legal values are as follows: + * + * GLU.FILL: Quadrics are rendered with polygon primitives. The polygons + * are drawn in a counterclockwise fashion with respect to + * their normals (as defined with glu.quadricOrientation). + * + * GLU.LINE: Quadrics are rendered as a set of lines. + * + * GLU.SILHOUETTE: Quadrics are rendered as a set of lines, except that edges + * separating coplanar faces will not be drawn. + * + * GLU.POINT: Quadrics are rendered as a set of points. + * + * @param drawStyle The drawStyle to set + */ + public void setDrawStyle(int drawStyle) { + this.drawStyle = drawStyle; + } + + /** + * specifies what kind of normals are desired for quadrics. + * The legal values are as follows: + * + * GLU.NONE: No normals are generated. + * + * GLU.FLAT: One normal is generated for every facet of a quadric. + * + * GLU.SMOOTH: One normal is generated for every vertex of a quadric. This + * is the default. + * + * @param normals The normals to set + */ + public void setNormals(int normals) { + this.normals = normals; + } + + /** + * specifies what kind of orientation is desired for. + * The orientation values are as follows: + * + * GLU.OUTSIDE: Quadrics are drawn with normals pointing outward. + * + * GLU.INSIDE: Normals point inward. The default is GLU.OUTSIDE. + * + * Note that the interpretation of outward and inward depends on the quadric + * being drawn. + * + * @param orientation The orientation to set + */ + public void setOrientation(int orientation) { + this.orientation = orientation; + } + + /** + * specifies if texture coordinates should be generated for + * quadrics rendered with qobj. If the value of textureCoords is true, + * then texture coordinates are generated, and if textureCoords is false, + * they are not.. The default is false. + * + * The manner in which texture coordinates are generated depends upon the + * specific quadric rendered. + * + * @param textureFlag The textureFlag to set + */ + public void setTextureFlag(boolean textureFlag) { + this.textureFlag = textureFlag; + } + + + /** + * Returns the drawStyle. + * @return int + */ + public int getDrawStyle() { + return drawStyle; + } + + /** + * Returns the normals. + * @return int + */ + public int getNormals() { + return normals; + } + + /** + * Returns the orientation. + * @return int + */ + public int getOrientation() { + return orientation; + } + + /** + * Returns the textureFlag. + * @return boolean + */ + public boolean getTextureFlag() { + return textureFlag; + } + + protected void TXTR_COORD(float x, float y) { + if (textureFlag) GL.glTexCoord2f(x,y); + } + + + protected float sin(float r) { + return (float)Math.sin(r); + } + + protected float cos(float r) { + return (float)Math.cos(r); + } + +} diff --git a/src/java/org/lwjgl/opengl/glu/Registry.java b/src/java/org/lwjgl/opengl/glu/Registry.java new file mode 100644 index 00000000..dcdcc7e2 --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/Registry.java @@ -0,0 +1,49 @@ +package org.lwjgl.opengl.glu; + +/** + * Registry.java + * + * + * Created 11-jan-2004 + * @author Erik Duijs + */ +public class Registry extends Util implements GLUConstants { + + private static final String versionString = "1.3"; + private static final String extensionString = + "GLU_EXT_nurbs_tessellator " + "GLU_EXT_object_space_tess "; + + /** + * Method gluGetString + * @param name + * @return String + */ + public static String gluGetString(int name) { + + if (name == GLU_VERSION) { + return versionString; + } else if (name == GLU_EXTENSIONS) { + return extensionString; + } + return null; + } + + /** + * Method gluCheckExtension + * + * @param extName is an extension name. + * @param extString is a string of extensions separated by blank(s). There may or + * may not be leading or trailing blank(s) in extString. + * This works in cases of extensions being prefixes of another like + * GL_EXT_texture and GL_EXT_texture3D. + * @return boolean true if extName is found otherwise it returns false. + */ + public static boolean gluCheckExtension(String extName, String extString) { + boolean flag = false; + + if (extString == null || extName == null) + return false; + + return extString.indexOf(extName) != -1; + } +} diff --git a/src/java/org/lwjgl/opengl/glu/Sphere.java b/src/java/org/lwjgl/opengl/glu/Sphere.java new file mode 100644 index 00000000..9427fbaa --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/Sphere.java @@ -0,0 +1,203 @@ +package org.lwjgl.opengl.glu; + + +import org.lwjgl.opengl.GL; + +/** + * Sphere.java + * + * + * Created 23-dec-2003 + * @author Erik Duijs + */ +public class Sphere extends Quadric implements GLUConstants { + + /** + * Constructor + */ + public Sphere() { + super(); + } + + /** + * draws a sphere of the given radius centered around the origin. + * The sphere is subdivided around the z axis into slices and along the z axis + * into stacks (similar to lines of longitude and latitude). + * + * If the orientation is set to GLU.OUTSIDE (with glu.quadricOrientation), then + * any normals generated point away from the center of the sphere. Otherwise, + * they point toward the center of the sphere. + + * If texturing is turned on (with glu.quadricTexture), then texture + * coordinates are generated so that t ranges from 0.0 at z=-radius to 1.0 at + * z=radius (t increases linearly along longitudinal lines), and s ranges from + * 0.0 at the +y axis, to 0.25 at the +x axis, to 0.5 at the -y axis, to 0.75 + * at the -x axis, and back to 1.0 at the +y axis. + */ + public void draw(float radius, int slices, int stacks) { + // TODO + + float rho, drho, theta, dtheta; + float x, y, z; + float s, t, ds, dt; + int i, j, imin, imax; + boolean normals; + float nsign; + + if (super.normals == GLU_NONE) { + normals = false; + } else { + normals = true; + } + + if (super.orientation == GLU_INSIDE) { + nsign = -1.0f; + } else { + nsign = 1.0f; + } + + drho = PI / stacks; + dtheta = 2.0f * PI / slices; + + if (super.drawStyle == GLU_FILL) { + if (super.textureFlag) { + // draw +Z end as a triangle fan + GL.glBegin(GL.GL_TRIANGLE_FAN); + GL.glNormal3f(0.0f, 0.0f, 1.0f); + GL.glVertex3f(0.0f, 0.0f, nsign * radius); + for (j = 0; j <= slices; j++) { + theta = (j == slices) ? 0.0f : j * dtheta; + x = -sin(theta) * sin(drho); + y = cos(theta) * sin(drho); + z = nsign * cos(drho); + if (normals) { + GL.glNormal3f(x * nsign, y * nsign, z * nsign); + } + GL.glVertex3f(x * radius, y * radius, z * radius); + } + GL.glEnd(); + } + + ds = 1.0f / slices; + dt = 1.0f / stacks; + t = 1.0f; // because loop now runs from 0 + if (super.textureFlag) { + 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; + GL.glBegin(GL.GL_QUAD_STRIP); + s = 0.0f; + for (j = 0; j <= slices; j++) { + theta = (j == slices) ? 0.0f : j * dtheta; + x = -sin(theta) * sin(rho); + y = cos(theta) * sin(rho); + z = nsign * cos(rho); + if (normals) { + GL.glNormal3f(x * nsign, y * nsign, z * nsign); + } + TXTR_COORD(s, t); + GL.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) { + GL.glNormal3f(x * nsign, y * nsign, z * nsign); + } + TXTR_COORD(s, t - dt); + s += ds; + GL.glVertex3f(x * radius, y * radius, z * radius); + } + GL.glEnd(); + t -= dt; + } + + if (!super.textureFlag) { + // draw -Z end as a triangle fan + GL.glBegin(GL.GL_TRIANGLE_FAN); + GL.glNormal3f(0.0f, 0.0f, -1.0f); + GL.glVertex3f(0.0f, 0.0f, -radius * nsign); + rho = PI - drho; + s = 1.0f; + t = dt; + for (j = slices; j >= 0; j--) { + theta = (j == slices) ? 0.0f : j * dtheta; + x = -sin(theta) * sin(rho); + y = cos(theta) * sin(rho); + z = nsign * cos(rho); + if (normals) + GL.glNormal3f(x * nsign, y * nsign, z * nsign); + s -= ds; + GL.glVertex3f(x * radius, y * radius, z * radius); + } + GL.glEnd(); + } + } else if ( + super.drawStyle == GLU_LINE + || super.drawStyle == GLU_SILHOUETTE) { + // draw stack lines + for (i = 1; + i < stacks; + i++) { // stack line at i==stacks-1 was missing here + rho = i * drho; + GL.glBegin(GL.GL_LINE_LOOP); + for (j = 0; j < slices; j++) { + theta = j * dtheta; + x = cos(theta) * sin(rho); + y = sin(theta) * sin(rho); + z = cos(rho); + if (normals) + GL.glNormal3f(x * nsign, y * nsign, z * nsign); + GL.glVertex3f(x * radius, y * radius, z * radius); + } + GL.glEnd(); + } + // draw slice lines + for (j = 0; j < slices; j++) { + theta = j * dtheta; + GL.glBegin(GL.GL_LINE_STRIP); + for (i = 0; i <= stacks; i++) { + rho = i * drho; + x = cos(theta) * sin(rho); + y = sin(theta) * sin(rho); + z = cos(rho); + if (normals) + GL.glNormal3f(x * nsign, y * nsign, z * nsign); + GL.glVertex3f(x * radius, y * radius, z * radius); + } + GL.glEnd(); + } + } else if (super.drawStyle == GLU_POINT) { + // top and bottom-most points + GL.glBegin(GL.GL_POINTS); + if (normals) + GL.glNormal3f(0.0f, 0.0f, nsign); + GL.glVertex3f(0.0f, 0.0f, radius); + if (normals) + GL.glNormal3f(0.0f, 0.0f, -nsign); + GL.glVertex3f(0.0f, 0.0f, -radius); + + // loop over stacks + for (i = 1; i < stacks - 1; i++) { + rho = i * drho; + for (j = 0; j < slices; j++) { + theta = j * dtheta; + x = cos(theta) * sin(rho); + y = sin(theta) * sin(rho); + z = cos(rho); + if (normals) + GL.glNormal3f(x * nsign, y * nsign, z * nsign); + GL.glVertex3f(x * radius, y * radius, z * radius); + } + } + GL.glEnd(); + } + } + +} \ No newline at end of file diff --git a/src/java/org/lwjgl/opengl/glu/Util.java b/src/java/org/lwjgl/opengl/glu/Util.java new file mode 100644 index 00000000..e14c672b --- /dev/null +++ b/src/java/org/lwjgl/opengl/glu/Util.java @@ -0,0 +1,226 @@ +package org.lwjgl.opengl.glu; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.opengl.GL; + +/** + * Util.java + * + * + * Created 7-jan-2004 + * @author Erik Duijs + */ +public class Util { + + /** temp IntBuffer of one for getting an int from some GL functions */ + private static IntBuffer scratch = createIntBuffer(1); + + /** + * Return ceiling of integer division + * @param a + * @param b + * @return int + */ + protected static int ceil(int a, int b) { + return (a % b == 0 ? a / b : a / b + 1); + } + + /** + * Normalize vector + * @param v + * @return float[] + */ + protected static float[] normalize(float[] v) { + float r; + + r = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + if (r == 0.0) + return v; + + v[0] /= r; + v[1] /= r; + v[2] /= r; + + return v; + } + + /** + * Calculate cross-product + * @param v1 + * @param v2 + * @param result + */ + protected static void cross(float[] v1, float[] v2, float[] result) { + result[0] = v1[1] * v2[2] - v1[2] * v2[1]; + result[1] = v1[2] * v2[0] - v1[0] * v2[2]; + result[2] = v1[0] * v2[1] - v1[1] * v2[0]; + } + + /** + * Method compPerPix. + * @param format + * @return int + */ + protected static int compPerPix(int format) { + /* Determine number of components per pixel */ + switch (format) { + case GL.GL_COLOR_INDEX : + case GL.GL_STENCIL_INDEX : + case GL.GL_DEPTH_COMPONENT : + case GL.GL_RED : + case GL.GL_GREEN : + case GL.GL_BLUE : + case GL.GL_ALPHA : + case GL.GL_LUMINANCE : + return 1; + case GL.GL_LUMINANCE_ALPHA : + return 2; + case GL.GL_RGB : + case GL.GL_BGR : + return 3; + case GL.GL_RGBA : + case GL.GL_BGRA : + return 4; + default : + return -1; + } + } + + /** + * Method nearestPower. + * + * Compute the nearest power of 2 number. This algorithm is a little + * strange, but it works quite well. + * + * @param width + * @return int + */ + protected static int nearestPower(int value) { + int i; + + i = 1; + + /* Error! */ + if (value == 0) + return -1; + + for (;;) { + if (value == 1) { + return i; + } else if (value == 3) { + return i * 4; + } + value = value >> 1; + i *= 2; + } + } + + /** + * Method bytesPerPixel. + * @param format + * @param type + * @return int + */ + protected static int bytesPerPixel(int format, int type) { + int n, m; + + switch (format) { + case GL.GL_COLOR_INDEX : + case GL.GL_STENCIL_INDEX : + case GL.GL_DEPTH_COMPONENT : + case GL.GL_RED : + case GL.GL_GREEN : + case GL.GL_BLUE : + case GL.GL_ALPHA : + case GL.GL_LUMINANCE : + n = 1; + break; + case GL.GL_LUMINANCE_ALPHA : + n = 2; + break; + case GL.GL_RGB : + case GL.GL_BGR : + n = 3; + break; + case GL.GL_RGBA : + case GL.GL_BGRA : + n = 4; + break; + default : + n = 0; + } + + switch (type) { + case GL.GL_UNSIGNED_BYTE : + m = 1; + break; + case GL.GL_BYTE : + m = 1; + break; + case GL.GL_BITMAP : + m = 1; + break; + case GL.GL_UNSIGNED_SHORT : + m = 2; + break; + case GL.GL_SHORT : + m = 2; + break; + case GL.GL_UNSIGNED_INT : + m = 4; + break; + case GL.GL_INT : + m = 4; + break; + case GL.GL_FLOAT : + m = 4; + break; + default : + m = 0; + } + + return n * m; + } + + /** + * Create a FloatBuffer of specified size. + * @param size + * @return FloatBuffer + */ + protected static FloatBuffer createFloatBuffer(int size) { + ByteBuffer temp = ByteBuffer.allocateDirect(4 * size); + temp.order(ByteOrder.nativeOrder()); + + return temp.asFloatBuffer(); + } + + /** + * Create IntBuffer of specified size. + * @param size + * @return IntBuffer + */ + protected static IntBuffer createIntBuffer(int size) { + ByteBuffer temp = ByteBuffer.allocateDirect(4 * size); + temp.order(ByteOrder.nativeOrder()); + + return temp.asIntBuffer(); + } + + /** + * Convenience method for returning an int, + * rather than getting it out of a buffer yourself. + * + * @param what + * @return int + */ + protected static int glGetIntegerv(int what) { + scratch.rewind(); + GL.glGetInteger(what, scratch); + return scratch.get(); + } + +}