diff options
Diffstat (limited to 'src/net/java/games/jogl/impl')
-rwxr-xr-x | src/net/java/games/jogl/impl/GLUquadricImpl.java | 1049 | ||||
-rwxr-xr-x | src/net/java/games/jogl/impl/Project.java | 592 | ||||
-rwxr-xr-x | src/net/java/games/jogl/impl/Util.java | 242 |
3 files changed, 1883 insertions, 0 deletions
diff --git a/src/net/java/games/jogl/impl/GLUquadricImpl.java b/src/net/java/games/jogl/impl/GLUquadricImpl.java new file mode 100755 index 000000000..cca415cc4 --- /dev/null +++ b/src/net/java/games/jogl/impl/GLUquadricImpl.java @@ -0,0 +1,1049 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** $Date$ $Revision$ +** $Header$ +*/ + +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +package net.java.games.jogl.impl; + +import net.java.games.jogl.*; + +/** + * GLUquadricImpl.java + * + * + * Created 22-dec-2003 (originally Quadric.java) + * @author Erik Duijs + * @author Kenneth Russell + */ + +class GLUquadricImpl implements GLUquadric { + private int drawStyle; + private int orientation; + private boolean textureFlag; + private int normals; + + GLUquadricImpl() { + drawStyle = GLU.GLU_FILL; + orientation = GLU.GLU_OUTSIDE; + textureFlag = false; + normals = GLU.GLU_SMOOTH; + } + + /** + * 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 + */ + 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 + */ + 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 + */ + 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 + */ + void setTextureFlag(boolean textureFlag) { + this.textureFlag = textureFlag; + } + + /** + * Returns the drawStyle. + * @return int + */ + int getDrawStyle() { + return drawStyle; + } + + /** + * Returns the normals. + * @return int + */ + int getNormals() { + return normals; + } + + /** + * Returns the orientation. + * @return int + */ + int getOrientation() { + return orientation; + } + + /** + * Returns the textureFlag. + * @return boolean + */ + boolean getTextureFlag() { + return textureFlag; + } + + /** + * 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. + */ + void drawCylinder(GL gl, 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 (orientation == GLU.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 (drawStyle == GLU.GLU_POINT) { + gl.glBegin(GL.GL_POINTS); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(gl, 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 (drawStyle == GLU.GLU_LINE || drawStyle == GLU.GLU_SILHOUETTE) { + // Draw rings + if (drawStyle == GLU.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(gl, 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(gl, 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(gl, 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(gl, 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 (drawStyle == GLU.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(gl, (x * nsign), (y * nsign), (nz * nsign)); + TXTR_COORD(gl, s, t); + gl.glVertex3f((x * r), (y * r), z); + normal3f(gl, (x * nsign), (y * nsign), (nz * nsign)); + TXTR_COORD(gl, s, t + dt); + gl.glVertex3f((x * (r + dr)), (y * (r + dr)), (z + dz)); + } else { + normal3f(gl, x * nsign, y * nsign, nz * nsign); + TXTR_COORD(gl, s, t); + gl.glVertex3f((x * r), (y * r), z); + normal3f(gl, x * nsign, y * nsign, nz * nsign); + TXTR_COORD(gl, 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 + } + } + + /** + * 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 drawDisk(GL gl, float innerRadius, float outerRadius, int slices, int loops) + { + float da, dr; + + /* Normal vectors */ + if (normals != GLU.GLU_NONE) { + if (orientation == GLU.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 (drawStyle) { + case GLU.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 (orientation == GLU.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(gl, 0.5f + sa * r2 / dtc, 0.5f + ca * r2 / dtc); + gl.glVertex2f(r2 * sa, r2 * ca); + TXTR_COORD(gl, 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(gl, 0.5f - sa * r2 / dtc, 0.5f + ca * r2 / dtc); + gl.glVertex2f(r2 * sa, r2 * ca); + TXTR_COORD(gl, 0.5f - sa * r1 / dtc, 0.5f + ca * r1 / dtc); + gl.glVertex2f(r1 * sa, r1 * ca); + } + gl.glEnd(); + } + r1 = r2; + } + break; + } + case GLU.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.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.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; + } + } + + /** + * 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.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). + */ + public void drawPartialDisk(GL gl, + float innerRadius, + float outerRadius, + int slices, + int loops, + float startAngle, + float sweepAngle) { + int i, j, max; + float[] sinCache = new float[CACHE_SIZE]; + float[] cosCache = new float[CACHE_SIZE]; + float angle; + float x, y; + float sintemp, costemp; + float deltaRadius; + float radiusLow, radiusHigh; + float texLow = 0, texHigh = 0; + float angleOffset; + int slices2; + int finish; + + if (slices >= CACHE_SIZE) + slices = CACHE_SIZE - 1; + if (slices < 2 + || loops < 1 + || outerRadius <= 0.0f + || innerRadius < 0.0f + || innerRadius > outerRadius) { + //gluQuadricError(qobj, GLU.GLU_INVALID_VALUE); + System.err.println("PartialDisk: GLU_INVALID_VALUE"); + return; + } + + if (sweepAngle < -360.0f) + sweepAngle = 360.0f; + if (sweepAngle > 360.0f) + sweepAngle = 360.0f; + if (sweepAngle < 0) { + startAngle += sweepAngle; + sweepAngle = -sweepAngle; + } + + if (sweepAngle == 360.0f) { + slices2 = slices; + } else { + slices2 = slices + 1; + } + + /* Compute length (needed for normal calculations) */ + deltaRadius = outerRadius - innerRadius; + + /* Cache is the vertex locations cache */ + + angleOffset = startAngle / 180.0f * PI; + for (i = 0; i <= slices; i++) { + angle = angleOffset + ((PI * sweepAngle) / 180.0f) * i / slices; + sinCache[i] = sin(angle); + cosCache[i] = cos(angle); + } + + if (sweepAngle == 360.0f) { + sinCache[slices] = sinCache[0]; + cosCache[slices] = cosCache[0]; + } + + switch (normals) { + case GLU.GLU_FLAT : + case GLU.GLU_SMOOTH : + if (orientation == GLU.GLU_OUTSIDE) { + gl.glNormal3f(0.0f, 0.0f, 1.0f); + } else { + gl.glNormal3f(0.0f, 0.0f, -1.0f); + } + break; + default : + case GLU.GLU_NONE : + break; + } + + switch (drawStyle) { + case GLU.GLU_FILL : + if (innerRadius == .0f) { + finish = loops - 1; + /* Triangle strip for inner polygons */ + gl.glBegin(GL.GL_TRIANGLE_FAN); + if (textureFlag) { + gl.glTexCoord2f(0.5f, 0.5f); + } + gl.glVertex3f(0.0f, 0.0f, 0.0f); + radiusLow = outerRadius - deltaRadius * ((float) (loops - 1) / loops); + if (textureFlag) { + texLow = radiusLow / outerRadius / 2; + } + + if (orientation == GLU.GLU_OUTSIDE) { + for (i = slices; i >= 0; i--) { + if (textureFlag) { + gl.glTexCoord2f(texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + } + } else { + for (i = 0; i <= slices; i++) { + if (textureFlag) { + gl.glTexCoord2f(texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + } + } + gl.glEnd(); + } else { + finish = loops; + } + for (j = 0; j < finish; j++) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + radiusHigh = outerRadius - deltaRadius * ((float) (j + 1) / loops); + if (textureFlag) { + texLow = radiusLow / outerRadius / 2; + texHigh = radiusHigh / outerRadius / 2; + } + + gl.glBegin(GL.GL_QUAD_STRIP); + for (i = 0; i <= slices; i++) { + if (orientation == GLU.GLU_OUTSIDE) { + if (textureFlag) { + gl.glTexCoord2f(texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + + if (textureFlag) { + gl.glTexCoord2f(texHigh * sinCache[i] + 0.5f, + texHigh * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusHigh * sinCache[i], + radiusHigh * cosCache[i], + 0.0f); + } else { + if (textureFlag) { + gl.glTexCoord2f(texHigh * sinCache[i] + 0.5f, + texHigh * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusHigh * sinCache[i], + radiusHigh * cosCache[i], + 0.0f); + + if (textureFlag) { + gl.glTexCoord2f(texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + } + } + gl.glEnd(); + } + break; + case GLU.GLU_POINT : + gl.glBegin(GL.GL_POINTS); + for (i = 0; i < slices2; i++) { + sintemp = sinCache[i]; + costemp = cosCache[i]; + for (j = 0; j <= loops; j++) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + + if (textureFlag) { + texLow = radiusLow / outerRadius / 2; + + gl.glTexCoord2f(texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f); + } + } + gl.glEnd(); + break; + case GLU.GLU_LINE : + if (innerRadius == outerRadius) { + gl.glBegin(GL.GL_LINE_STRIP); + + for (i = 0; i <= slices; i++) { + if (textureFlag) { + gl.glTexCoord2f(sinCache[i] / 2 + 0.5f, cosCache[i] / 2 + 0.5f); + } + gl.glVertex3f(innerRadius * sinCache[i], innerRadius * cosCache[i], 0.0f); + } + gl.glEnd(); + break; + } + for (j = 0; j <= loops; j++) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + if (textureFlag) { + texLow = radiusLow / outerRadius / 2; + } + + gl.glBegin(GL.GL_LINE_STRIP); + for (i = 0; i <= slices; i++) { + if (textureFlag) { + gl.glTexCoord2f(texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + } + gl.glEnd(); + } + for (i = 0; i < slices2; i++) { + sintemp = sinCache[i]; + costemp = cosCache[i]; + gl.glBegin(GL.GL_LINE_STRIP); + for (j = 0; j <= loops; j++) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + if (textureFlag) { + texLow = radiusLow / outerRadius / 2; + } + + if (textureFlag) { + gl.glTexCoord2f(texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f); + } + gl.glEnd(); + } + break; + case GLU.GLU_SILHOUETTE : + if (sweepAngle < 360.0f) { + for (i = 0; i <= slices; i += slices) { + sintemp = sinCache[i]; + costemp = cosCache[i]; + gl.glBegin(GL.GL_LINE_STRIP); + for (j = 0; j <= loops; j++) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + + if (textureFlag) { + texLow = radiusLow / outerRadius / 2; + gl.glTexCoord2f(texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f); + } + gl.glEnd(); + } + } + for (j = 0; j <= loops; j += loops) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + if (textureFlag) { + texLow = radiusLow / outerRadius / 2; + } + + gl.glBegin(GL.GL_LINE_STRIP); + for (i = 0; i <= slices; i++) { + if (textureFlag) { + gl.glTexCoord2f(texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + gl.glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + } + gl.glEnd(); + if (innerRadius == outerRadius) + break; + } + break; + default : + break; + } + } + + /** + * 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 drawSphere(GL gl, 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; + + normals = (this.normals != GLU.GLU_NONE); + + if (orientation == GLU.GLU_INSIDE) { + nsign = -1.0f; + } else { + nsign = 1.0f; + } + + drho = PI / stacks; + dtheta = 2.0f * PI / slices; + + if (drawStyle == GLU.GLU_FILL) { + if (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 (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(gl, 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(gl, s, t - dt); + s += ds; + gl.glVertex3f(x * radius, y * radius, z * radius); + } + gl.glEnd(); + t -= dt; + } + + if (!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; + 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 ( + drawStyle == GLU.GLU_LINE + || drawStyle == GLU.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 (drawStyle == GLU.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(); + } + } + + + //---------------------------------------------------------------------- + // Internals only below this point + // + + private static final float PI = (float)Math.PI; + private static final int CACHE_SIZE = 240; + + /** + * Call glNormal3f after scaling normal to unit length. + * + * @param x + * @param y + * @param z + */ + private void normal3f(GL gl, 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); + } + + private void TXTR_COORD(GL gl, float x, float y) { + if (textureFlag) gl.glTexCoord2f(x,y); + } + + private float sin(float r) { + return (float)Math.sin(r); + } + + private float cos(float r) { + return (float)Math.cos(r); + } +} diff --git a/src/net/java/games/jogl/impl/Project.java b/src/net/java/games/jogl/impl/Project.java new file mode 100755 index 000000000..60e8d5dad --- /dev/null +++ b/src/net/java/games/jogl/impl/Project.java @@ -0,0 +1,592 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** $Date$ $Revision$ +** $Header$ +*/ + +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ +package net.java.games.jogl.impl; + +import net.java.games.jogl.*; +import net.java.games.jogl.util.*; + +import java.nio.DoubleBuffer; + +/** + * Project.java + * <p/> + * <p/> + * Created 11-jan-2004 + * + * @author Erik Duijs + * @author Kenneth Russell + */ +class Project { + private static final double[] IDENTITY_MATRIX = + new double[] { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 }; + + private final DoubleBuffer matrix = BufferUtils.newDoubleBuffer(16); + private final double[] finalMatrix = new double[16]; + + private final double[][] tempMatrix = new double[4][4]; + private final double[] in = new double[4]; + private final double[] out = new double[4]; + + private final double[] forward = new double[3]; + private final double[] side = new double[3]; + private final double[] up = new double[3]; + + /** + * Make matrix an identity matrix + */ + private void __gluMakeIdentityd(DoubleBuffer m) { + int oldPos = m.position(); + m.put(IDENTITY_MATRIX); + m.position(oldPos); + } + + private void __gluMakeIdentityd(double[] m) { + for (int i = 0; i < 16; i++) { + m[i] = IDENTITY_MATRIX[i]; + } + } + + /** + * Method __gluMultMatrixVecd + * + * @param matrix + * @param in + * @param out + */ + private void __gluMultMatrixVecd(double[] matrix, double[] in, double[] out) { + for (int i = 0; i < 4; i++) { + out[i] = + in[0] * matrix[0*4+i] + + in[1] * matrix[1*4+i] + + in[2] * matrix[2*4+i] + + in[3] * matrix[3*4+i]; + + } + } + + /** + * @param src + * @param inverse + * + * @return + */ + private boolean __gluInvertMatrixd(double[] src, double[] inverse) { + int i, j, k, swap; + double t; + double[][] temp = tempMatrix; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + temp[i][j] = src[i*4+j]; + } + } + __gluMakeIdentityd(inverse); + + for (i = 0; i < 4; i++) { + /* + * * Look for largest element in column + */ + swap = i; + for (j = i + 1; j < 4; j++) { + if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) { + swap = j; + } + } + + if (swap != i) { + /* + * * Swap rows. + */ + for (k = 0; k < 4; k++) { + t = temp[i][k]; + temp[i][k] = temp[swap][k]; + temp[swap][k] = t; + + t = inverse[i*4+k]; + inverse[i*4+k] = inverse[swap*4+k]; + inverse[swap*4+k] = t; + } + } + + if (temp[i][i] == 0) { + /* + * No non-zero pivot. The matrix is singular, which shouldn't + * happen. This means the user gave us a bad matrix. + */ + return false; + } + + t = temp[i][i]; + for (k = 0; k < 4; k++) { + temp[i][k] /= t; + inverse[i*4+k] /= t; + } + for (j = 0; j < 4; j++) { + if (j != i) { + t = temp[j][i]; + for (k = 0; k < 4; k++) { + temp[j][k] -= temp[i][k] * t; + inverse[j*4+k] -= inverse[i*4+k]*t; + } + } + } + } + return true; + } + + /** + * @param a + * @param b + * @param r + */ + private void __gluMultMatricesd(double[] a, double[] b, double[] r) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + r[i*4+j] = + a[i*4+0]*b[0*4+j] + + a[i*4+1]*b[1*4+j] + + a[i*4+2]*b[2*4+j] + + a[i*4+3]*b[3*4+j]; + } + } + } + + /** + * Normalize vector + * + * @param v + */ + private static void normalize(double[] v) { + double r; + + r = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + if ( r == 0.0 ) + return; + + r = 1.0 / r; + + v[0] *= r; + v[1] *= r; + v[2] *= r; + + return; + } + + /** + * Calculate cross-product + * + * @param v1 + * @param v2 + * @param result + */ + private static void cross(double[] v1, double[] v2, double[] 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 gluOrtho2D. + * + * @param left + * @param right + * @param bottom + * @param top + */ + public void gluOrtho2D(GL gl, double left, double right, double bottom, double top) { + gl.glOrtho(left, right, bottom, top, -1, 1); + } + + /** + * Method gluPerspective. + * + * @param fovy + * @param aspect + * @param zNear + * @param zFar + */ + public void gluPerspective(GL gl, double fovy, double aspect, double zNear, double zFar) { + double sine, cotangent, deltaZ; + double radians = fovy / 2 * Math.PI / 180; + + deltaZ = zFar - zNear; + sine = Math.sin(radians); + + if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { + return; + } + + cotangent = Math.cos(radians) / sine; + + __gluMakeIdentityd(matrix); + + 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.glMultMatrixd(matrix); + } + + /** + * Method gluLookAt + * + * @param eyex + * @param eyey + * @param eyez + * @param centerx + * @param centery + * @param centerz + * @param upx + * @param upy + * @param upz + */ + public void gluLookAt(GL gl, + double eyex, + double eyey, + double eyez, + double centerx, + double centery, + double centerz, + double upx, + double upy, + double upz) { + double[] forward = this.forward; + double[] side = this.side; + double[] up = this.up; + + 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); + + __gluMakeIdentityd(matrix); + 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.glMultMatrixd(matrix); + gl.glTranslated(-eyex, -eyey, -eyez); + } + + /** + * Method gluProject + * + * @param objx + * @param objy + * @param objz + * @param modelMatrix + * @param projMatrix + * @param viewport + * @param win_pos + * + * @return + */ + public boolean gluProject(double objx, + double objy, + double objz, + double[] modelMatrix, + double[] projMatrix, + int[] viewport, + double[] win_pos) { + + double[] in = this.in; + double[] out = this.out; + + in[0] = objx; + in[1] = objy; + in[2] = objz; + in[3] = 1.0; + + __gluMultMatrixVecd(modelMatrix, in, out); + __gluMultMatrixVecd(projMatrix, out, in); + + if (in[3] == 0.0) + return false; + + in[3] = (1.0 / in[3]) * 0.5; + + // Map x, y and z to range 0-1 + in[0] = in[0] * in[3] + 0.5f; + in[1] = in[1] * in[3] + 0.5f; + in[2] = in[2] * in[3] + 0.5f; + + // Map x,y to viewport + win_pos[0] = in[0] * viewport[2] + viewport[0]; + win_pos[1] = in[1] * viewport[3] + viewport[1]; + win_pos[2] = in[2]; + + return true; + } + + /** + * Method gluUnproject + * + * @param winx + * @param winy + * @param winz + * @param modelMatrix + * @param projMatrix + * @param viewport + * @param obj_pos + * + * @return + */ + public boolean gluUnProject(double winx, + double winy, + double winz, + double[] modelMatrix, + double[] projMatrix, + int[] viewport, + double[] obj_pos) { + double[] in = this.in; + double[] out = this.out; + + __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix); + + if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) + return false; + + in[0] = winx; + in[1] = winy; + in[2] = winz; + in[3] = 1.0; + + // Map x and y from window coordinates + in[0] = (in[0] - viewport[0]) / viewport[2]; + in[1] = (in[1] - viewport[1]) / viewport[3]; + + // Map to range -1 to 1 + in[0] = in[0] * 2 - 1; + in[1] = in[1] * 2 - 1; + in[2] = in[2] * 2 - 1; + + __gluMultMatrixVecd(finalMatrix, in, out); + + if (out[3] == 0.0) + return false; + + out[3] = 1.0 / out[3]; + + obj_pos[0] = out[0] * out[3]; + obj_pos[1] = out[1] * out[3]; + obj_pos[2] = out[2] * out[3]; + + return true; + } + + /** + * Method gluUnproject4 + * + * @param winx + * @param winy + * @param winz + * @param clipw + * @param modelMatrix + * @param projMatrix + * @param viewport + * @param near + * @param far + * @param obj_pos + * + * @return + */ + public boolean gluUnProject4(double winx, + double winy, + double winz, + double clipw, + double[] modelMatrix, + double[] projMatrix, + int[] viewport, + double near, + double far, + double[] obj_pos) { + double[] in = this.in; + double[] out = this.out; + + __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix); + + if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) + return false; + + in[0] = winx; + in[1] = winy; + in[2] = winz; + in[3] = clipw; + + // Map x and y from window coordinates + in[0] = (in[0] - viewport[0]) / viewport[2]; + in[1] = (in[1] - viewport[1]) / viewport[3]; + in[2] = (in[2] - near) / (far - near); + + // Map to range -1 to 1 + in[0] = in[0] * 2 - 1; + in[1] = in[1] * 2 - 1; + in[2] = in[2] * 2 - 1; + + __gluMultMatrixVecd(finalMatrix, in, out); + + if (out[3] == 0.0) + return false; + + obj_pos[0] = out[0]; + obj_pos[1] = out[1]; + obj_pos[2] = out[2]; + obj_pos[3] = out[3]; + return true; + } + + /** + * Method gluPickMatrix + * + * @param x + * @param y + * @param deltaX + * @param deltaY + * @param viewport + */ + public void gluPickMatrix(GL gl, + double x, + double y, + double deltaX, + double deltaY, + int[] viewport) { + if (deltaX <= 0 || deltaY <= 0) { + return; + } + + /* Translate and scale the picked region to the entire window */ + gl.glTranslated((viewport[2] - 2 * (x - viewport[0])) / deltaX, + (viewport[3] - 2 * (y - viewport[1])) / deltaY, + 0); + gl.glScaled(viewport[2] / deltaX, viewport[3] / deltaY, 1.0); + } +} diff --git a/src/net/java/games/jogl/impl/Util.java b/src/net/java/games/jogl/impl/Util.java new file mode 100755 index 000000000..80a5d1232 --- /dev/null +++ b/src/net/java/games/jogl/impl/Util.java @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +package net.java.games.jogl.impl; + +import java.nio.IntBuffer; +import net.java.games.jogl.*; + +/** + * Util.java + * <p/> + * <p/> + * Created 7-jan-2004 + * + * @author Erik Duijs + */ +class Util { + + /** + * temp int[] of one for getting an int from some GL functions + */ + private int[] scratch = new int[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); + } + + /** + * 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. + * <p/> + * Compute the nearest power of 2 number. This algorithm is a little strange, but it works quite well. + * + * @param value + * + * @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 << 2; + } + value >>= 1; + i <<= 1; + } + } + + /** + * 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; + } + + /** + * Convenience method for returning an int, rather than getting it out of a buffer yourself. + * + * @param what + * + * @return int + */ + protected int glGetIntegerv(GL gl, int what) { + gl.glGetIntegerv(what, scratch); + return scratch[0]; + } +} |