0001: /*
0002: * $RCSfile: JoglPipeline.java,v $
0003: *
0004: * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0006: *
0007: * This code is free software; you can redistribute it and/or modify it
0008: * under the terms of the GNU General Public License version 2 only, as
0009: * published by the Free Software Foundation. Sun designates this
0010: * particular file as subject to the "Classpath" exception as provided
0011: * by Sun in the LICENSE file that accompanied this code.
0012: *
0013: * This code is distributed in the hope that it will be useful, but WITHOUT
0014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0016: * version 2 for more details (a copy is included in the LICENSE file that
0017: * accompanied this code).
0018: *
0019: * You should have received a copy of the GNU General Public License version
0020: * 2 along with this work; if not, write to the Free Software Foundation,
0021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0022: *
0023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0024: * CA 95054 USA or visit www.sun.com if you need additional information or
0025: * have any questions.
0026: *
0027: * $Revision: 1.23 $
0028: * $Date: 2008/02/28 20:17:18 $
0029: * $State: Exp $
0030: */
0031:
0032: package javax.media.j3d;
0033:
0034: import com.sun.j3d.internal.ByteBufferWrapper;
0035: import java.awt.*;
0036: import java.io.*;
0037: import java.lang.reflect.*;
0038: import java.nio.*;
0039: import java.security.*;
0040: import java.util.*;
0041: import java.util.regex.*;
0042: import javax.media.opengl.*;
0043: import javax.media.opengl.glu.*;
0044: import com.sun.opengl.cg.*;
0045: import com.sun.opengl.util.*;
0046:
0047: /**
0048: * Concrete implementation of Pipeline class for the JOGL rendering
0049: * pipeline.
0050: */
0051: class JoglPipeline extends Pipeline {
0052:
0053: // Flags indicating whether the Cg or GLSL libraries are available.
0054: private boolean cgLibraryAvailable = false;
0055:
0056: // Currently prints for entry points not yet implemented
0057: private static final boolean DEBUG = true;
0058: // Currently prints for entry points already implemented
0059: private static final boolean VERBOSE = false;
0060: // Debugging output for graphics configuration selection
0061: private static final boolean DEBUG_CONFIG = false;
0062: // Prints extra debugging information
0063: private static final boolean EXTRA_DEBUGGING = false;
0064: // Number of milliseconds to wait for windows to pop up on screen
0065: private static final int WAIT_TIME = 1000;
0066: // Configurable constant just in case we want to change this later
0067: private static final int MIN_FRAME_SIZE = 1;
0068:
0069: /**
0070: * Constructor for singleton JoglPipeline instance
0071: */
0072: protected JoglPipeline() {
0073: }
0074:
0075: /**
0076: * Initialize the pipeline
0077: */
0078: void initialize(Pipeline.Type pipelineType) {
0079: super .initialize(pipelineType);
0080:
0081: assert pipelineType == Pipeline.Type.JOGL;
0082:
0083: // Java3D maintains strict control over which threads perform OpenGL work
0084: Threading.disableSingleThreading();
0085:
0086: // TODO: finish this with any other needed initialization
0087: }
0088:
0089: /**
0090: * Load all of the required libraries
0091: */
0092: void loadLibraries(int globalShadingLanguage) {
0093: if (globalShadingLanguage == Shader.SHADING_LANGUAGE_CG) {
0094: // Try to load the jogl_cg library and set the
0095: // cgLibraryAvailable flag to true if loads successfully; note
0096: // that successfully performing initialization of this class
0097: // will cause the Cg native library to be loaded on our behalf
0098: try {
0099: Class.forName("com.sun.opengl.cg.CgGL");
0100: cgLibraryAvailable = true;
0101: } catch (Exception ex) {
0102: System.err.println(ex);
0103: } catch (Error ex) {
0104: System.err.println(ex);
0105: }
0106: }
0107: }
0108:
0109: /**
0110: * Returns true if the Cg library is loaded and available. Note that this
0111: * does not necessarily mean that Cg is supported by the graphics card.
0112: */
0113: boolean isCgLibraryAvailable() {
0114: return cgLibraryAvailable;
0115: }
0116:
0117: /**
0118: * Returns true if the GLSL library is loaded and available. Note that this
0119: * does not necessarily mean that GLSL is supported by the graphics card.
0120: */
0121: boolean isGLSLLibraryAvailable() {
0122: return true;
0123: }
0124:
0125: // ---------------------------------------------------------------------
0126:
0127: //
0128: // GeometryArrayRetained methods
0129: //
0130:
0131: // Used by D3D to free vertex buffer
0132: void freeD3DArray(GeometryArrayRetained geo, boolean deleteVB) {
0133: // Nothing to do
0134: }
0135:
0136: // used for GeometryArrays by Copy or interleaved
0137: void execute(Context ctx, GeometryArrayRetained geo, int geo_type,
0138: boolean isNonUniformScale, boolean useAlpha,
0139: boolean ignoreVertexColors, int startVIndex, int vcount,
0140: int vformat, int texCoordSetCount, int[] texCoordSetMap,
0141: int texCoordSetMapLen, int[] texUnitOffset,
0142: int numActiveTexUnitState, int vertexAttrCount,
0143: int[] vertexAttrSizes, float[] varray, float[] carray,
0144: int cDirty) {
0145: if (VERBOSE)
0146: System.err.println("JoglPipeline.execute()");
0147:
0148: executeGeometryArray(ctx, geo, geo_type, isNonUniformScale,
0149: useAlpha, ignoreVertexColors, startVIndex, vcount,
0150: vformat, texCoordSetCount, texCoordSetMap,
0151: texCoordSetMapLen, texUnitOffset,
0152: numActiveTexUnitState, vertexAttrCount,
0153: vertexAttrSizes, varray, null, carray, cDirty);
0154: }
0155:
0156: // used by GeometryArray by Reference with java arrays
0157: void executeVA(Context ctx, GeometryArrayRetained geo,
0158: int geo_type, boolean isNonUniformScale,
0159: boolean ignoreVertexColors, int vcount, int vformat,
0160: int vdefined, int initialCoordIndex, float[] vfcoords,
0161: double[] vdcoords, int initialColorIndex, float[] cfdata,
0162: byte[] cbdata, int initialNormalIndex, float[] ndata,
0163: int vertexAttrCount, int[] vertexAttrSizes,
0164: int[] vertexAttrIndices, float[][] vertexAttrData,
0165: int texCoordMapLength, int[] texcoordoffset,
0166: int numActiveTexUnitState, int[] texIndex, int texstride,
0167: Object[] texCoords, int cdirty) {
0168: if (VERBOSE)
0169: System.err.println("JoglPipeline.executeVA()");
0170:
0171: boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
0172: boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
0173: boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
0174: boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
0175: boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
0176: boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
0177: boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
0178:
0179: FloatBuffer fverts = null;
0180: DoubleBuffer dverts = null;
0181: FloatBuffer fclrs = null;
0182: ByteBuffer bclrs = null;
0183: FloatBuffer[] texCoordBufs = null;
0184: FloatBuffer norms = null;
0185: FloatBuffer[] vertexAttrBufs = null;
0186:
0187: // Get vertex attribute arrays
0188: if (vattrDefined) {
0189: vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData);
0190: }
0191:
0192: // get texture arrays
0193: if (textureDefined) {
0194: texCoordBufs = getTexCoordSetBuffer(texCoords);
0195: }
0196:
0197: // get coordinate array
0198: if (floatCoordDefined) {
0199: fverts = getVertexArrayBuffer(vfcoords);
0200: } else if (doubleCoordDefined) {
0201: dverts = getVertexArrayBuffer(vdcoords);
0202: }
0203:
0204: // get color array
0205: if (floatColorsDefined) {
0206: fclrs = getColorArrayBuffer(cfdata);
0207: } else if (byteColorsDefined) {
0208: bclrs = getColorArrayBuffer(cbdata);
0209: }
0210:
0211: // get normal array
0212: if (normalsDefined) {
0213: norms = getNormalArrayBuffer(ndata);
0214: }
0215:
0216: int[] sarray = null;
0217: int[] start_array = null;
0218: int strip_len = 0;
0219: if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET
0220: || geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET
0221: || geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
0222: sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts;
0223: strip_len = sarray.length;
0224: start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices;
0225: }
0226:
0227: executeGeometryArrayVA(ctx, geo, geo_type, isNonUniformScale,
0228: ignoreVertexColors, vcount, vformat, vdefined,
0229: initialCoordIndex, fverts, dverts, initialColorIndex,
0230: fclrs, bclrs, initialNormalIndex, norms,
0231: vertexAttrCount, vertexAttrSizes, vertexAttrIndices,
0232: vertexAttrBufs, texCoordMapLength, texcoordoffset,
0233: numActiveTexUnitState, texIndex, texstride,
0234: texCoordBufs, cdirty, sarray, strip_len, start_array);
0235: }
0236:
0237: // used by GeometryArray by Reference with NIO buffer
0238: void executeVABuffer(Context ctx, GeometryArrayRetained geo,
0239: int geo_type, boolean isNonUniformScale,
0240: boolean ignoreVertexColors, int vcount, int vformat,
0241: int vdefined, int initialCoordIndex, Object vcoords,
0242: int initialColorIndex, Object cdataBuffer, float[] cfdata,
0243: byte[] cbdata, int initialNormalIndex, Object ndata,
0244: int vertexAttrCount, int[] vertexAttrSizes,
0245: int[] vertexAttrIndices, Object[] vertexAttrData,
0246: int texCoordMapLength, int[] texcoordoffset,
0247: int numActiveTexUnitState, int[] texIndex, int texstride,
0248: Object[] texCoords, int cdirty) {
0249: if (VERBOSE)
0250: System.err.println("JoglPipeline.executeVABuffer()");
0251:
0252: boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
0253: boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
0254: boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
0255: boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
0256: boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
0257: boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
0258: boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
0259:
0260: FloatBuffer fverts = null;
0261: DoubleBuffer dverts = null;
0262: FloatBuffer fclrs = null;
0263: ByteBuffer bclrs = null;
0264: FloatBuffer[] texCoordBufs = null;
0265: FloatBuffer norms = null;
0266: FloatBuffer[] vertexAttrBufs = null;
0267:
0268: // Get vertex attribute arrays
0269: if (vattrDefined) {
0270: vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData);
0271: }
0272:
0273: // get texture arrays
0274: if (textureDefined) {
0275: texCoordBufs = new FloatBuffer[texCoords.length];
0276: for (int i = 0; i < texCoords.length; i++) {
0277: texCoordBufs[i] = (FloatBuffer) texCoords[i];
0278: }
0279: }
0280:
0281: // get coordinate array
0282: if (floatCoordDefined) {
0283: fverts = (FloatBuffer) vcoords;
0284: } else if (doubleCoordDefined) {
0285: dverts = (DoubleBuffer) vcoords;
0286: }
0287:
0288: if (fverts == null && dverts == null) {
0289: return;
0290: }
0291:
0292: // get color array
0293: if (floatColorsDefined) {
0294: if (cfdata != null)
0295: fclrs = getColorArrayBuffer(cfdata);
0296: else
0297: fclrs = (FloatBuffer) cdataBuffer;
0298: } else if (byteColorsDefined) {
0299: if (cbdata != null)
0300: bclrs = getColorArrayBuffer(cbdata);
0301: else
0302: bclrs = (ByteBuffer) cdataBuffer;
0303: }
0304:
0305: // get normal array
0306: if (normalsDefined) {
0307: norms = (FloatBuffer) ndata;
0308: }
0309:
0310: int[] sarray = null;
0311: int[] start_array = null;
0312: int strip_len = 0;
0313: if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET
0314: || geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET
0315: || geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
0316: sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts;
0317: strip_len = sarray.length;
0318: start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices;
0319: }
0320:
0321: executeGeometryArrayVA(ctx, geo, geo_type, isNonUniformScale,
0322: ignoreVertexColors, vcount, vformat, vdefined,
0323: initialCoordIndex, fverts, dverts, initialColorIndex,
0324: fclrs, bclrs, initialNormalIndex, norms,
0325: vertexAttrCount, vertexAttrSizes, vertexAttrIndices,
0326: vertexAttrBufs, texCoordMapLength, texcoordoffset,
0327: numActiveTexUnitState, texIndex, texstride,
0328: texCoordBufs, cdirty, sarray, strip_len, start_array);
0329: }
0330:
0331: // used by GeometryArray by Reference in interleaved format with NIO buffer
0332: void executeInterleavedBuffer(Context ctx,
0333: GeometryArrayRetained geo, int geo_type,
0334: boolean isNonUniformScale, boolean useAlpha,
0335: boolean ignoreVertexColors, int startVIndex, int vcount,
0336: int vformat, int texCoordSetCount, int[] texCoordSetMap,
0337: int texCoordSetMapLen, int[] texUnitOffset,
0338: int numActiveTexUnit, Object varray, float[] cdata,
0339: int cdirty) {
0340: if (VERBOSE)
0341: System.err
0342: .println("JoglPipeline.executeInterleavedBuffer()");
0343:
0344: executeGeometryArray(ctx, geo, geo_type, isNonUniformScale,
0345: useAlpha, ignoreVertexColors, startVIndex, vcount,
0346: vformat, texCoordSetCount, texCoordSetMap,
0347: texCoordSetMapLen, texUnitOffset, numActiveTexUnit, 0,
0348: null, null, (Buffer) varray, cdata, cdirty);
0349: }
0350:
0351: void setVertexFormat(Context ctx, GeometryArrayRetained geo,
0352: int vformat, boolean useAlpha, boolean ignoreVertexColors) {
0353: if (VERBOSE)
0354: System.err.println("JoglPipeline.setVertexFormat()");
0355:
0356: GL gl = context(ctx).getGL();
0357:
0358: // Enable and disable the appropriate pointers
0359: if ((vformat & GeometryArray.NORMALS) != 0) {
0360: gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
0361: } else {
0362: gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
0363: }
0364: if (!ignoreVertexColors
0365: && ((vformat & GeometryArray.COLOR) != 0)) {
0366: gl.glEnableClientState(GL.GL_COLOR_ARRAY);
0367: } else {
0368: gl.glDisableClientState(GL.GL_COLOR_ARRAY);
0369: }
0370:
0371: if (gl.isExtensionAvailable("GL_SUN_global_alpha")) {
0372: if (useAlpha) {
0373: gl.glEnable(GL.GL_GLOBAL_ALPHA_SUN);
0374: } else {
0375: gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN);
0376: }
0377: }
0378:
0379: if ((vformat & GeometryArray.COORDINATES) != 0) {
0380: gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
0381: } else {
0382: gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
0383: }
0384: }
0385:
0386: void disableGlobalAlpha(Context ctx, GeometryArrayRetained geo,
0387: int vformat, boolean useAlpha, boolean ignoreVertexColors) {
0388: if (VERBOSE)
0389: System.err.println("JoglPipeline.disableGlobalAlpha()");
0390:
0391: GL gl = context(ctx).getGL();
0392:
0393: if (gl.isExtensionAvailable("GL_SUN_global_alpha")) {
0394: if (!ignoreVertexColors
0395: && ((vformat & GeometryArray.COLOR) != 0)) {
0396: if (useAlpha) {
0397: gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN);
0398: }
0399: }
0400: }
0401: }
0402:
0403: // used for GeometryArrays
0404: void buildGA(Context ctx, GeometryArrayRetained geo, int geo_type,
0405: boolean isNonUniformScale, boolean updateAlpha,
0406: float alpha, boolean ignoreVertexColors, int startVIndex,
0407: int vcount, int vformat, int texCoordSetCount,
0408: int[] texCoordSetMap, int texCoordSetMapLen,
0409: int[] texCoordSetMapOffset, int vertexAttrCount,
0410: int[] vertexAttrSizes, double[] xform, double[] nxform,
0411: float[] varray) {
0412: if (VERBOSE)
0413: System.err.println("JoglPipeline.buildGA()");
0414: JoglContext jctx = (JoglContext) ctx;
0415: GL gl = context(ctx).getGL();
0416: FloatBuffer verts = null;
0417: int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0;
0418: int texStride = 0;
0419: int vAttrOff = 0;
0420: if ((vformat & GeometryArray.COORDINATES) != 0) {
0421: stride += 3;
0422: }
0423: if ((vformat & GeometryArray.NORMALS) != 0) {
0424: stride += 3;
0425: coordoff += 3;
0426: }
0427:
0428: if ((vformat & GeometryArray.COLOR) != 0) {
0429: if ((vformat & GeometryArray.BY_REFERENCE) != 0) {
0430: if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
0431: stride += 4;
0432: normoff += 4;
0433: coordoff += 4;
0434: } else {
0435: stride += 3;
0436: normoff += 3;
0437: coordoff += 3;
0438: }
0439: } else {
0440: stride += 4;
0441: normoff += 4;
0442: coordoff += 4;
0443: }
0444: }
0445:
0446: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
0447: if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
0448: texStride = 2 * texCoordSetCount;
0449: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
0450: texStride = 3 * texCoordSetCount;
0451: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) {
0452: texStride = 4 * texCoordSetCount;
0453: }
0454: stride += texStride;
0455: normoff += texStride;
0456: coloroff += texStride;
0457: coordoff += texStride;
0458: }
0459:
0460: int vAttrStride = 0;
0461: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
0462: for (int i = 0; i < vertexAttrCount; i++) {
0463: vAttrStride += vertexAttrSizes[i];
0464: }
0465: stride += vAttrStride;
0466: normoff += vAttrStride;
0467: coloroff += vAttrStride;
0468: coordoff += vAttrStride;
0469: texCoordoff += vAttrStride;
0470: }
0471:
0472: int bstride = stride * BufferUtil.SIZEOF_FLOAT;
0473: // Start sending down from the startVIndex
0474: int initialOffset = startVIndex * stride;
0475: normoff += initialOffset;
0476: coloroff += initialOffset;
0477: coordoff += initialOffset;
0478: texCoordoff += initialOffset;
0479: vAttrOff += initialOffset;
0480:
0481: // process alpha for geometryArray without alpha
0482: boolean useAlpha = false;
0483: if (updateAlpha && !ignoreVertexColors) {
0484: useAlpha = true;
0485: }
0486:
0487: if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET
0488: || geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET
0489: || geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
0490: int[] sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts;
0491:
0492: int primType = 0;
0493: switch (geo_type) {
0494: case GeometryRetained.GEO_TYPE_TRI_STRIP_SET:
0495: primType = GL.GL_TRIANGLE_STRIP;
0496: break;
0497: case GeometryRetained.GEO_TYPE_TRI_FAN_SET:
0498: primType = GL.GL_TRIANGLE_FAN;
0499: break;
0500: case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
0501: primType = GL.GL_LINE_STRIP;
0502: break;
0503: }
0504:
0505: if (ignoreVertexColors) {
0506: vformat &= ~GeometryArray.COLOR;
0507: }
0508:
0509: for (int i = 0; i < sarray.length; i++) {
0510: gl.glBegin(primType);
0511: for (int j = 0; j < sarray[i]; j++) {
0512: if ((vformat & GeometryArray.NORMALS) != 0) {
0513: if (nxform != null) {
0514: float nx = (float) (nxform[0]
0515: * varray[normoff] + nxform[1]
0516: * varray[normoff + 1] + nxform[2]
0517: * varray[normoff + 2]);
0518: float ny = (float) (nxform[4]
0519: * varray[normoff] + nxform[5]
0520: * varray[normoff + 1] + nxform[6]
0521: * varray[normoff + 2]);
0522: float nz = (float) (nxform[8]
0523: * varray[normoff] + nxform[9]
0524: * varray[normoff + 1] + nxform[10]
0525: * varray[normoff + 2]);
0526: gl.glNormal3f(nx, ny, nz);
0527: } else {
0528: gl.glNormal3f(varray[normoff],
0529: varray[normoff + 1],
0530: varray[normoff + 2]);
0531: }
0532: }
0533: if ((vformat & GeometryArray.COLOR) != 0) {
0534: if (useAlpha) {
0535: gl.glColor4f(varray[coloroff],
0536: varray[coloroff + 1],
0537: varray[coloroff + 2],
0538: varray[coloroff + 3] * alpha);
0539: } else {
0540: if ((vformat & GeometryArray.WITH_ALPHA) != 0) { // alpha is present
0541: gl.glColor4f(varray[coloroff],
0542: varray[coloroff + 1],
0543: varray[coloroff + 2],
0544: varray[coloroff + 3]);
0545: } else {
0546: gl.glColor3f(varray[coloroff],
0547: varray[coloroff + 1],
0548: varray[coloroff + 2]);
0549: }
0550: }
0551: }
0552:
0553: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
0554: int vaOff = vAttrOff;
0555: if (verts == null) {
0556: verts = FloatBuffer.wrap(varray);
0557: }
0558: for (int vaIdx = 0; vaIdx < vertexAttrCount; vaIdx++) {
0559: switch (vertexAttrSizes[vaIdx]) {
0560: case 1:
0561: verts.position(vaOff);
0562: jctx.vertexAttr1fv(gl, vaIdx, verts);
0563: break;
0564: case 2:
0565: verts.position(vaOff);
0566: jctx.vertexAttr2fv(gl, vaIdx, verts);
0567: break;
0568: case 3:
0569: verts.position(vaOff);
0570: jctx.vertexAttr3fv(gl, vaIdx, verts);
0571: break;
0572: case 4:
0573: verts.position(vaOff);
0574: jctx.vertexAttr4fv(gl, vaIdx, verts);
0575: break;
0576: }
0577:
0578: vaOff += vertexAttrSizes[vaIdx];
0579: }
0580: }
0581:
0582: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
0583: if (texCoordSetMapLen > 0) {
0584: if (gl
0585: .isExtensionAvailable("GL_VERSION_1_3")) {
0586: if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
0587: for (int k = 0; k < texCoordSetMapLen; k++) {
0588: if (texCoordSetMapOffset[k] != -1) {
0589: int off = texCoordoff
0590: + texCoordSetMapOffset[k];
0591: gl.glMultiTexCoord2f(
0592: GL.GL_TEXTURE0 + k,
0593: varray[off],
0594: varray[off + 1]);
0595: }
0596: }
0597: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
0598: for (int k = 0; k < texCoordSetMapLen; k++) {
0599: if (texCoordSetMapOffset[k] != -1) {
0600: int off = texCoordoff
0601: + texCoordSetMapOffset[k];
0602: gl.glMultiTexCoord3f(
0603: GL.GL_TEXTURE0 + k,
0604: varray[off],
0605: varray[off + 1],
0606: varray[off + 2]);
0607: }
0608: }
0609: } else {
0610: for (int k = 0; k < texCoordSetMapLen; k++) {
0611: if (texCoordSetMapOffset[k] != -1) {
0612: int off = texCoordoff
0613: + texCoordSetMapOffset[k];
0614: gl.glMultiTexCoord4f(
0615: GL.GL_TEXTURE0 + k,
0616: varray[off],
0617: varray[off + 1],
0618: varray[off + 2],
0619: varray[off + 3]);
0620: }
0621: }
0622: }
0623: } else { // no multitexture
0624: if (texCoordSetMapOffset[0] != -1) {
0625: int off = texCoordoff
0626: + texCoordSetMapOffset[0];
0627: if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
0628: gl.glTexCoord2f(varray[off],
0629: varray[off + 1]);
0630: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
0631: gl.glTexCoord3f(varray[off],
0632: varray[off + 1],
0633: varray[off + 2]);
0634: } else {
0635: gl.glTexCoord4f(varray[off],
0636: varray[off + 1],
0637: varray[off + 2],
0638: varray[off + 3]);
0639: }
0640: }
0641: } // no multitexture
0642: }
0643: // texCoordSetMapLen can't be 0 if texture coordinates
0644: // is to be specified
0645: }
0646:
0647: if ((vformat & GeometryArray.COORDINATES) != 0) {
0648: if (xform != null) {
0649: // transform the vertex data with the static transform
0650: float w = (float) (xform[12]
0651: * varray[coordoff] + xform[13]
0652: * varray[coordoff + 1] + xform[14]
0653: * varray[coordoff + 2] + xform[15]);
0654: float winv = 1.0f / w;
0655: float vx = (float) (xform[0]
0656: * varray[coordoff] + xform[1]
0657: * varray[coordoff + 1] + xform[2]
0658: * varray[coordoff + 2] + xform[3])
0659: * winv;
0660: float vy = (float) (xform[4]
0661: * varray[coordoff] + xform[5]
0662: * varray[coordoff + 1] + xform[6]
0663: * varray[coordoff + 2] + xform[7])
0664: * winv;
0665: float vz = (float) (xform[8]
0666: * varray[coordoff] + xform[9]
0667: * varray[coordoff + 1] + xform[10]
0668: * varray[coordoff + 2] + xform[11])
0669: * winv;
0670: gl.glVertex3f(vx, vy, vz);
0671: } else {
0672: gl.glVertex3f(varray[coordoff],
0673: varray[coordoff + 1],
0674: varray[coordoff + 2]);
0675: }
0676: }
0677: normoff += stride;
0678: coloroff += stride;
0679: coordoff += stride;
0680: texCoordoff += stride;
0681: vAttrOff += stride;
0682: }
0683: gl.glEnd();
0684: }
0685: } else if ((geo_type == GeometryRetained.GEO_TYPE_QUAD_SET)
0686: || (geo_type == GeometryRetained.GEO_TYPE_TRI_SET)
0687: || (geo_type == GeometryRetained.GEO_TYPE_POINT_SET)
0688: || (geo_type == GeometryRetained.GEO_TYPE_LINE_SET)) {
0689: int primType = 0;
0690: switch (geo_type) {
0691: case GeometryRetained.GEO_TYPE_QUAD_SET:
0692: primType = GL.GL_QUADS;
0693: break;
0694: case GeometryRetained.GEO_TYPE_TRI_SET:
0695: primType = GL.GL_TRIANGLES;
0696: break;
0697: case GeometryRetained.GEO_TYPE_POINT_SET:
0698: primType = GL.GL_POINTS;
0699: break;
0700: case GeometryRetained.GEO_TYPE_LINE_SET:
0701: primType = GL.GL_LINES;
0702: break;
0703: }
0704:
0705: if (ignoreVertexColors) {
0706: vformat &= ~GeometryArray.COLOR;
0707: }
0708:
0709: gl.glBegin(primType);
0710: for (int j = 0; j < vcount; j++) {
0711: if ((vformat & GeometryArray.NORMALS) != 0) {
0712: if (nxform != null) {
0713: float nx = (float) (nxform[0] * varray[normoff]
0714: + nxform[1] * varray[normoff + 1] + nxform[2]
0715: * varray[normoff + 2]);
0716: float ny = (float) (nxform[4] * varray[normoff]
0717: + nxform[5] * varray[normoff + 1] + nxform[6]
0718: * varray[normoff + 2]);
0719: float nz = (float) (nxform[8] * varray[normoff]
0720: + nxform[9] * varray[normoff + 1] + nxform[10]
0721: * varray[normoff + 2]);
0722: gl.glNormal3f(nx, ny, nz);
0723: } else {
0724: gl.glNormal3f(varray[normoff],
0725: varray[normoff + 1],
0726: varray[normoff + 2]);
0727: }
0728: }
0729: if ((vformat & GeometryArray.COLOR) != 0) {
0730: if (useAlpha) {
0731: float cr, cg, cb, ca;
0732: if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
0733: cr = varray[coloroff];
0734: cg = varray[coloroff + 1];
0735: cb = varray[coloroff + 2];
0736: ca = varray[coloroff + 3] * alpha;
0737: } else {
0738: cr = varray[coloroff];
0739: cg = varray[coloroff + 1];
0740: cb = varray[coloroff + 2];
0741: ca = alpha;
0742: }
0743: gl.glColor4f(cr, cg, cb, ca);
0744: } else {
0745: if ((vformat & GeometryArray.WITH_ALPHA) != 0) { // alpha is present
0746: gl.glColor4f(varray[coloroff],
0747: varray[coloroff + 1],
0748: varray[coloroff + 2],
0749: varray[coloroff + 3]);
0750: } else {
0751: gl.glColor3f(varray[coloroff],
0752: varray[coloroff + 1],
0753: varray[coloroff + 2]);
0754: }
0755: }
0756: }
0757:
0758: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
0759: int vaOff = vAttrOff;
0760: if (verts == null) {
0761: verts = FloatBuffer.wrap(varray);
0762: }
0763: for (int vaIdx = 0; vaIdx < vertexAttrCount; vaIdx++) {
0764: switch (vertexAttrSizes[vaIdx]) {
0765: case 1:
0766: verts.position(vaOff);
0767: jctx.vertexAttr1fv(gl, vaIdx, verts);
0768: break;
0769: case 2:
0770: verts.position(vaOff);
0771: jctx.vertexAttr2fv(gl, vaIdx, verts);
0772: break;
0773: case 3:
0774: verts.position(vaOff);
0775: jctx.vertexAttr3fv(gl, vaIdx, verts);
0776: break;
0777: case 4:
0778: verts.position(vaOff);
0779: jctx.vertexAttr4fv(gl, vaIdx, verts);
0780: break;
0781: }
0782:
0783: vaOff += vertexAttrSizes[vaIdx];
0784: }
0785: }
0786:
0787: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
0788: if (texCoordSetMapLen > 0) {
0789: if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
0790: if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
0791: for (int k = 0; k < texCoordSetMapLen; k++) {
0792: if (texCoordSetMapOffset[k] != -1) {
0793: int off = texCoordoff
0794: + texCoordSetMapOffset[k];
0795: gl.glMultiTexCoord2f(
0796: GL.GL_TEXTURE0 + k,
0797: varray[off],
0798: varray[off + 1]);
0799: }
0800: }
0801: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
0802: for (int k = 0; k < texCoordSetMapLen; k++) {
0803: if (texCoordSetMapOffset[k] != -1) {
0804: int off = texCoordoff
0805: + texCoordSetMapOffset[k];
0806: gl.glMultiTexCoord3f(
0807: GL.GL_TEXTURE0 + k,
0808: varray[off],
0809: varray[off + 1],
0810: varray[off + 2]);
0811: }
0812: }
0813: } else {
0814: for (int k = 0; k < texCoordSetMapLen; k++) {
0815: if (texCoordSetMapOffset[k] != -1) {
0816: int off = texCoordoff
0817: + texCoordSetMapOffset[k];
0818: gl.glMultiTexCoord4f(
0819: GL.GL_TEXTURE0 + k,
0820: varray[off],
0821: varray[off + 1],
0822: varray[off + 2],
0823: varray[off + 3]);
0824: }
0825: }
0826: }
0827: } else { // no multitexture
0828: if (texCoordSetMapOffset[0] != -1) {
0829: int off = texCoordoff
0830: + texCoordSetMapOffset[0];
0831: if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
0832: gl.glTexCoord2f(varray[off],
0833: varray[off + 1]);
0834: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
0835: gl.glTexCoord3f(varray[off],
0836: varray[off + 1],
0837: varray[off + 2]);
0838: } else {
0839: gl.glTexCoord4f(varray[off],
0840: varray[off + 1],
0841: varray[off + 2],
0842: varray[off + 3]);
0843: }
0844: }
0845: } // no multitexture
0846: }
0847: // texCoordSetMapLen can't be 0 if texture coordinates is
0848: // to be specified
0849: }
0850:
0851: if ((vformat & GeometryArray.COORDINATES) != 0) {
0852: if (xform != null) {
0853: // transform the vertex data with the static transform
0854: float w = (float) (xform[12] * varray[coordoff]
0855: + xform[13] * varray[coordoff + 1]
0856: + xform[14] * varray[coordoff + 2] + xform[15]);
0857: float winv = 1.0f / w;
0858: float vx = (float) (xform[0] * varray[coordoff]
0859: + xform[1] * varray[coordoff + 1]
0860: + xform[2] * varray[coordoff + 2] + xform[3])
0861: * winv;
0862: float vy = (float) (xform[4] * varray[coordoff]
0863: + xform[5] * varray[coordoff + 1]
0864: + xform[6] * varray[coordoff + 2] + xform[7])
0865: * winv;
0866: float vz = (float) (xform[8] * varray[coordoff]
0867: + xform[9] * varray[coordoff + 1]
0868: + xform[10] * varray[coordoff + 2] + xform[11])
0869: * winv;
0870: gl.glVertex3f(vx, vy, vz);
0871: } else {
0872: gl.glVertex3f(varray[coordoff],
0873: varray[coordoff + 1],
0874: varray[coordoff + 2]);
0875: }
0876: }
0877: normoff += stride;
0878: coloroff += stride;
0879: coordoff += stride;
0880: texCoordoff += stride;
0881: vAttrOff += stride;
0882: }
0883: gl.glEnd();
0884: }
0885: }
0886:
0887: // used to Build Dlist GeometryArray by Reference with java arrays
0888: void buildGAForByRef(Context ctx, GeometryArrayRetained geo,
0889: int geo_type, boolean isNonUniformScale,
0890: boolean updateAlpha, float alpha,
0891: boolean ignoreVertexColors, int vcount, int vformat,
0892: int vdefined, int initialCoordIndex, float[] vfcoords,
0893: double[] vdcoords, int initialColorIndex, float[] cfdata,
0894: byte[] cbdata, int initialNormalIndex, float[] ndata,
0895: int vertexAttrCount, int[] vertexAttrSizes,
0896: int[] vertexAttrIndices, float[][] vertexAttrData,
0897: int texCoordMapLength, int[] tcoordsetmap,
0898: int[] texIndices, int texStride, Object[] texCoords,
0899: double[] xform, double[] nxform) {
0900: if (VERBOSE)
0901: System.err.println("JoglPipeline.buildGAForByRef()");
0902:
0903: GL gl = context(ctx).getGL();
0904:
0905: boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
0906: boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
0907: boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
0908: boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
0909: boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
0910: boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
0911: boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
0912:
0913: FloatBuffer fverts = null;
0914: DoubleBuffer dverts = null;
0915: FloatBuffer fclrs = null;
0916: ByteBuffer bclrs = null;
0917: FloatBuffer[] texCoordBufs = null;
0918: FloatBuffer norms = null;
0919: FloatBuffer[] vertexAttrBufs = null;
0920:
0921: // Get vertex attribute arrays
0922: if (vattrDefined) {
0923: vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData);
0924: }
0925:
0926: // get texture arrays
0927: if (textureDefined) {
0928: texCoordBufs = getTexCoordSetBuffer(texCoords);
0929: }
0930:
0931: // process alpha for geometryArray without alpha
0932: boolean useAlpha = false;
0933: if (updateAlpha && !ignoreVertexColors) {
0934: useAlpha = true;
0935: }
0936:
0937: int[] sarray = null;
0938: int[] start_array = null;
0939: int strip_len = 0;
0940: if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET
0941: || geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET
0942: || geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
0943: sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts;
0944: strip_len = sarray.length;
0945: start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices;
0946: }
0947:
0948: if (ignoreVertexColors) {
0949: vformat &= ~GeometryArray.COLOR;
0950: floatColorsDefined = false;
0951: byteColorsDefined = false;
0952: }
0953:
0954: // get coordinate array
0955: if (floatCoordDefined) {
0956: gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
0957: fverts = getVertexArrayBuffer(vfcoords, (xform == null));
0958: if (xform != null) {
0959: // Must copy in and transform data
0960: for (int i = initialCoordIndex; i < vcount * 3; i += 3) {
0961: fverts.put(i, (float) (xform[0] * vfcoords[i]
0962: + xform[1] * vfcoords[i + 1] + xform[2]
0963: * vfcoords[i + 2]));
0964: fverts.put(i + 1, (float) (xform[4] * vfcoords[i]
0965: + xform[5] * vfcoords[i + 1] + xform[6]
0966: * vfcoords[i + 2]));
0967: fverts.put(i + 2, (float) (xform[8] * vfcoords[i]
0968: + xform[9] * vfcoords[i + 1] + xform[10]
0969: * vfcoords[i + 2]));
0970: }
0971: }
0972: } else if (doubleCoordDefined) {
0973: gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
0974: dverts = getVertexArrayBuffer(vdcoords, (xform == null));
0975: if (xform != null) {
0976: // Must copy in and transform data
0977: for (int i = initialCoordIndex; i < vcount * 3; i += 3) {
0978: dverts.put(i, (xform[0] * vdcoords[i] + xform[1]
0979: * vdcoords[i + 1] + xform[2]
0980: * vdcoords[i + 2]));
0981: dverts.put(i + 1, (xform[4] * vdcoords[i]
0982: + xform[5] * vdcoords[i + 1] + xform[6]
0983: * vdcoords[i + 2]));
0984: dverts.put(i + 2, (xform[8] * vdcoords[i]
0985: + xform[9] * vdcoords[i + 1] + xform[10]
0986: * vdcoords[i + 2]));
0987: }
0988: }
0989: } else {
0990: gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
0991: }
0992:
0993: // get color array
0994: if (floatColorsDefined) {
0995: gl.glEnableClientState(GL.GL_COLOR_ARRAY);
0996: fclrs = getColorArrayBuffer(cfdata, !useAlpha);
0997: if (useAlpha) {
0998: // Must copy in and modify color data
0999: if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
1000: for (int i = initialColorIndex; i < vcount * 4; i += 4) {
1001: fclrs.put(i, cfdata[i]);
1002: fclrs.put(i + 1, cfdata[i + 1]);
1003: fclrs.put(i + 2, cfdata[i + 2]);
1004: fclrs.put(i + 3, alpha * cfdata[i + 3]);
1005: }
1006: } else {
1007: int k = 0;
1008: for (int i = initialColorIndex; i < vcount * 4; i += 4) {
1009: fclrs.put(i, cfdata[k++]);
1010: fclrs.put(i + 1, cfdata[k++]);
1011: fclrs.put(i + 2, cfdata[k++]);
1012: fclrs.put(i + 3, alpha);
1013: }
1014: }
1015: vformat |= GeometryArray.WITH_ALPHA;
1016: }
1017: } else if (byteColorsDefined) {
1018: gl.glEnableClientState(GL.GL_COLOR_ARRAY);
1019: bclrs = getColorArrayBuffer(cbdata, !useAlpha);
1020: if (useAlpha) {
1021: // Must copy in and modify color data
1022: if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
1023: for (int i = initialColorIndex; i < vcount * 4; i += 4) {
1024: bclrs.put(i, cbdata[i]);
1025: bclrs.put(i + 1, cbdata[i + 1]);
1026: bclrs.put(i + 2, cbdata[i + 2]);
1027: bclrs
1028: .put(
1029: i + 3,
1030: (byte) (alpha * (int) (cbdata[i + 3] & 0xFF)));
1031: }
1032: } else {
1033: int k = 0;
1034: for (int i = initialColorIndex; i < vcount * 4; i += 4) {
1035: bclrs.put(i, cbdata[k++]);
1036: bclrs.put(i + 1, cbdata[k++]);
1037: bclrs.put(i + 2, cbdata[k++]);
1038: bclrs.put(i + 3, (byte) (alpha * 255.0f));
1039: }
1040: }
1041: vformat |= GeometryArray.WITH_ALPHA;
1042: }
1043: } else {
1044: gl.glDisableClientState(GL.GL_COLOR_ARRAY);
1045: }
1046:
1047: // get normal array
1048: if (normalsDefined) {
1049: gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
1050: norms = getNormalArrayBuffer(ndata, (nxform == null));
1051: if (nxform != null) {
1052: // Must copy in and transform data
1053: for (int i = initialNormalIndex; i < vcount * 3; i += 3) {
1054: norms.put(i, (float) (nxform[0] * ndata[i]
1055: + nxform[1] * ndata[i + 1] + nxform[2]
1056: * ndata[i + 2]));
1057: norms.put(i + 1, (float) (nxform[4] * ndata[i]
1058: + nxform[5] * ndata[i + 1] + nxform[6]
1059: * ndata[i + 2]));
1060: norms.put(i + 2, (float) (nxform[8] * ndata[i]
1061: + nxform[9] * ndata[i + 1] + nxform[10]
1062: * ndata[i + 2]));
1063: }
1064: }
1065: } else {
1066: gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
1067: }
1068:
1069: executeGeometryArrayVA(ctx, geo, geo_type, isNonUniformScale,
1070: ignoreVertexColors, vcount, vformat, vdefined,
1071: initialCoordIndex, fverts, dverts, initialColorIndex,
1072: fclrs, bclrs, initialNormalIndex, norms,
1073: vertexAttrCount, vertexAttrSizes, vertexAttrIndices,
1074: vertexAttrBufs, texCoordMapLength, tcoordsetmap,
1075: texCoordMapLength, texIndices, texStride, texCoordBufs,
1076: 0, sarray, strip_len, start_array);
1077: }
1078:
1079: //----------------------------------------------------------------------
1080: // Private helper methods for GeometryArrayRetained
1081: //
1082:
1083: private void testForInterleavedArrays(int vformat,
1084: boolean[] useInterleavedArrays, int[] iaFormat) {
1085: if (VERBOSE)
1086: System.err
1087: .println("JoglPipeline.testForInterleavedArrays()");
1088: useInterleavedArrays[0] = true;
1089: switch (vformat) {
1090: case GeometryArray.COORDINATES:
1091: iaFormat[0] = GL.GL_V3F;
1092: break;
1093: case (GeometryArray.COORDINATES | GeometryArray.NORMALS):
1094: iaFormat[0] = GL.GL_N3F_V3F;
1095: break;
1096: case (GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2):
1097: iaFormat[0] = GL.GL_T2F_V3F;
1098: break;
1099: case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR):
1100: case (GeometryArray.COORDINATES | GeometryArray.NORMALS
1101: | GeometryArray.COLOR | GeometryArray.WITH_ALPHA):
1102: iaFormat[0] = GL.GL_C4F_N3F_V3F;
1103: break;
1104: case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.TEXTURE_COORDINATE_2):
1105: iaFormat[0] = GL.GL_T2F_N3F_V3F;
1106: break;
1107: case (GeometryArray.COORDINATES | GeometryArray.NORMALS
1108: | GeometryArray.COLOR | GeometryArray.TEXTURE_COORDINATE_2):
1109: case (GeometryArray.COORDINATES | GeometryArray.NORMALS
1110: | GeometryArray.COLOR | GeometryArray.WITH_ALPHA | GeometryArray.TEXTURE_COORDINATE_2):
1111: iaFormat[0] = GL.GL_T2F_C4F_N3F_V3F;
1112: break;
1113: default:
1114: useInterleavedArrays[0] = false;
1115: break;
1116: }
1117: }
1118:
1119: private void enableTexCoordPointer(GL gl, int texUnit, int texSize,
1120: int texDataType, int stride, Buffer pointer) {
1121: if (VERBOSE)
1122: System.err.println("JoglPipeline.enableTexCoordPointer()");
1123: clientActiveTextureUnit(gl, texUnit);
1124: gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
1125: gl.glTexCoordPointer(texSize, texDataType, stride, pointer);
1126: }
1127:
1128: private void disableTexCoordPointer(GL gl, int texUnit) {
1129: if (VERBOSE)
1130: System.err.println("JoglPipeline.disableTexCoordPointer()");
1131: clientActiveTextureUnit(gl, texUnit);
1132: gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
1133: }
1134:
1135: private void clientActiveTextureUnit(GL gl, int texUnit) {
1136: if (VERBOSE)
1137: System.err
1138: .println("JoglPipeline.clientActiveTextureUnit()");
1139: if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
1140: gl.glClientActiveTexture(texUnit + GL.GL_TEXTURE0);
1141: }
1142: }
1143:
1144: private void executeTexture(int texCoordSetMapLen, int texSize,
1145: int bstride, int texCoordoff, int[] texCoordSetMapOffset,
1146: int numActiveTexUnit, FloatBuffer verts, GL gl) {
1147: if (VERBOSE)
1148: System.err.println("JoglPipeline.executeTexture()");
1149: int tus = 0; /* texture unit state index */
1150:
1151: for (int i = 0; i < numActiveTexUnit; i++) {
1152:
1153: tus = i;
1154:
1155: /*
1156: * it's possible thattexture unit state index (tus)
1157: * is greater than the texCoordSetMapOffsetLen, in this
1158: * case, just disable TexCoordPointer.
1159: */
1160: if ((tus < texCoordSetMapLen)
1161: && (texCoordSetMapOffset[tus] != -1)) {
1162: if (EXTRA_DEBUGGING) {
1163: System.err
1164: .println(" texCoord position "
1165: + i
1166: + ": "
1167: + (texCoordoff + texCoordSetMapOffset[tus]));
1168: }
1169: verts.position(texCoordoff + texCoordSetMapOffset[tus]);
1170: enableTexCoordPointer(gl, i, texSize, GL.GL_FLOAT,
1171: bstride, verts);
1172: } else {
1173: disableTexCoordPointer(gl, i);
1174: }
1175: }
1176: }
1177:
1178: private void resetTexture(GL gl, JoglContext ctx) {
1179: if (VERBOSE)
1180: System.err.println("JoglPipeline.resetTexture()");
1181: /* Disable texture coordinate arrays for all texture units */
1182: for (int i = 0; i < ctx.getMaxTexCoordSets(); i++) {
1183: disableTexCoordPointer(gl, i);
1184: }
1185: /* Reset client active texture unit to 0 */
1186: clientActiveTextureUnit(gl, 0);
1187: }
1188:
1189: private void executeGeometryArray(Context absCtx,
1190: GeometryArrayRetained geo, int geo_type,
1191: boolean isNonUniformScale, boolean useAlpha,
1192: boolean ignoreVertexColors, int startVIndex, int vcount,
1193: int vformat, int texCoordSetCount, int[] texCoordSetMap,
1194: int texCoordSetMapLen, int[] texCoordSetMapOffset,
1195: int numActiveTexUnitState, int vertexAttrCount,
1196: int[] vertexAttrSizes, float[] varray, Buffer varrayBuffer,
1197: float[] carray, int cDirty) {
1198: if (VERBOSE)
1199: System.err.println("JoglPipeline.executeGeometryArray()");
1200: JoglContext ctx = (JoglContext) absCtx;
1201: GLContext context = context(ctx);
1202: GL gl = context.getGL();
1203:
1204: boolean useInterleavedArrays;
1205: int iaFormat = 0;
1206: int primType = 0;
1207: int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0;
1208: int texSize = 0, texStride = 0;
1209: int vAttrOff = 0;
1210: int vAttrStride = 0;
1211: int bstride = 0, cbstride = 0;
1212: FloatBuffer verts = null;
1213: FloatBuffer clrs = null;
1214: int[] sarray = null;
1215: int[] start_array = null;
1216:
1217: if (EXTRA_DEBUGGING) {
1218: System.err.println("Vertex format: "
1219: + getVertexDescription(vformat));
1220: System.err.println("Geometry type: "
1221: + getGeometryDescription(geo_type));
1222: if (carray != null) {
1223: System.err.println(" Separate color array");
1224: } else {
1225: System.err.println(" Colors (if any) interleaved");
1226: }
1227: }
1228:
1229: if ((vformat & GeometryArray.COORDINATES) != 0) {
1230: stride += 3;
1231: }
1232: if ((vformat & GeometryArray.NORMALS) != 0) {
1233: stride += 3;
1234: coordoff += 3;
1235: }
1236: if ((vformat & GeometryArray.COLOR) != 0) {
1237: if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
1238: stride += 4;
1239: normoff += 4;
1240: coordoff += 4;
1241: } else { /* Handle the case of executeInterleaved 3f */
1242: stride += 3;
1243: normoff += 3;
1244: coordoff += 3;
1245: }
1246: }
1247: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
1248: if (EXTRA_DEBUGGING) {
1249: System.err.println(" Number of tex coord sets: "
1250: + texCoordSetCount);
1251: }
1252: if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
1253: texSize = 2;
1254: texStride = 2 * texCoordSetCount;
1255: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
1256: texSize = 3;
1257: texStride = 3 * texCoordSetCount;
1258: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) {
1259: texSize = 4;
1260: texStride = 4 * texCoordSetCount;
1261: }
1262: stride += texStride;
1263: normoff += texStride;
1264: coloroff += texStride;
1265: coordoff += texStride;
1266: }
1267: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
1268: for (int i = 0; i < vertexAttrCount; i++) {
1269: vAttrStride += vertexAttrSizes[i];
1270: }
1271: stride += vAttrStride;
1272: normoff += vAttrStride;
1273: coloroff += vAttrStride;
1274: coordoff += vAttrStride;
1275: texCoordoff += vAttrStride;
1276: }
1277:
1278: bstride = stride * BufferUtil.SIZEOF_FLOAT;
1279:
1280: if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET
1281: || geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET
1282: || geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
1283: sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts;
1284: start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices;
1285: }
1286:
1287: // We have to copy if the data isn't specified using NIO
1288: if (varray != null) {
1289: verts = getVertexArrayBuffer(varray);
1290: } else if (varrayBuffer != null) {
1291: verts = (FloatBuffer) varrayBuffer;
1292: } else {
1293: // This should never happen
1294: throw new AssertionError("Unable to get vertex pointer");
1295: }
1296:
1297: // using byRef interleaved array and has a separate pointer, then ..
1298: int cstride = stride;
1299: if (carray != null) {
1300: clrs = getColorArrayBuffer(carray);
1301: cstride = 4;
1302: } else {
1303: // FIXME: need to "auto-slice" this buffer later
1304: clrs = verts;
1305: }
1306:
1307: cbstride = cstride * BufferUtil.SIZEOF_FLOAT;
1308:
1309: // Enable normalize for non-uniform scale (which rescale can't handle)
1310: if (isNonUniformScale) {
1311: gl.glEnable(GL.GL_NORMALIZE);
1312: }
1313:
1314: int startVertex = stride * startVIndex;
1315: int startClrs = cstride * startVIndex;
1316: if (clrs == verts) {
1317: startClrs += coloroff;
1318: }
1319:
1320: /*** Handle non-indexed strip GeometryArray first *******/
1321: if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET
1322: || geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET
1323: || geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
1324: if (ignoreVertexColors
1325: || (carray != null)
1326: || ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || (texCoordSetCount > 1)))) {
1327: useInterleavedArrays = false;
1328: } else {
1329: boolean[] tmp = new boolean[1];
1330: int[] tmp2 = new int[1];
1331: testForInterleavedArrays(vformat, tmp, tmp2);
1332: useInterleavedArrays = tmp[0];
1333: iaFormat = tmp2[0];
1334: }
1335: if (useInterleavedArrays) {
1336: verts.position(startVertex);
1337: gl.glInterleavedArrays(iaFormat, bstride, verts);
1338: } else {
1339: if ((vformat & GeometryArray.NORMALS) != 0) {
1340: verts.position(startVertex + normoff);
1341: gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
1342: }
1343: if (!ignoreVertexColors
1344: && (vformat & GeometryArray.COLOR) != 0) {
1345: if (EXTRA_DEBUGGING) {
1346: System.err.println(" Doing colors");
1347: }
1348: clrs.position(startClrs);
1349: if ((vformat & GeometryArray.WITH_ALPHA) != 0
1350: || useAlpha) {
1351: gl.glColorPointer(4, GL.GL_FLOAT, cbstride,
1352: clrs);
1353: } else {
1354: gl.glColorPointer(3, GL.GL_FLOAT, cbstride,
1355: clrs);
1356: }
1357: }
1358: if ((vformat & GeometryArray.COORDINATES) != 0) {
1359: verts.position(startVertex + coordoff);
1360: gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
1361: }
1362:
1363: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
1364: executeTexture(texCoordSetMapLen, texSize, bstride,
1365: texCoordoff, texCoordSetMapOffset,
1366: numActiveTexUnitState, verts, gl);
1367: }
1368:
1369: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
1370: int vAttrOffset = startVertex + vAttrOff;
1371: for (int i = 0; i < vertexAttrCount; i++) {
1372: ctx.enableVertexAttrArray(gl, i);
1373: verts.position(vAttrOffset);
1374: ctx.vertexAttrPointer(gl, i,
1375: vertexAttrSizes[i], GL.GL_FLOAT,
1376: bstride, verts);
1377: vAttrOffset += vertexAttrSizes[i];
1378: }
1379: }
1380: }
1381:
1382: switch (geo_type) {
1383: case GeometryRetained.GEO_TYPE_TRI_STRIP_SET:
1384: primType = GL.GL_TRIANGLE_STRIP;
1385: break;
1386: case GeometryRetained.GEO_TYPE_TRI_FAN_SET:
1387: primType = GL.GL_TRIANGLE_FAN;
1388: break;
1389: case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
1390: primType = GL.GL_LINE_STRIP;
1391: break;
1392: }
1393:
1394: if (gl.isExtensionAvailable("GL_EXT_multi_draw_arrays")) {
1395: gl.glMultiDrawArraysEXT(primType, start_array, 0,
1396: sarray, 0, sarray.length);
1397: } else {
1398: for (int i = 0; i < sarray.length; i++) {
1399: gl
1400: .glDrawArrays(primType, start_array[i],
1401: sarray[i]);
1402: }
1403: }
1404: } else if ((geo_type == GeometryRetained.GEO_TYPE_QUAD_SET)
1405: || (geo_type == GeometryRetained.GEO_TYPE_TRI_SET)
1406: || (geo_type == GeometryRetained.GEO_TYPE_POINT_SET)
1407: || (geo_type == GeometryRetained.GEO_TYPE_LINE_SET)) {
1408: /******* Handle non-indexed non-striped GeometryArray now *****/
1409: if (ignoreVertexColors
1410: || (carray != null)
1411: || ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || (texCoordSetCount > 1)))) {
1412: useInterleavedArrays = false;
1413: } else {
1414: boolean[] tmp = new boolean[1];
1415: int[] tmp2 = new int[1];
1416: testForInterleavedArrays(vformat, tmp, tmp2);
1417: useInterleavedArrays = tmp[0];
1418: iaFormat = tmp2[0];
1419: }
1420:
1421: if (useInterleavedArrays) {
1422: verts.position(startVertex);
1423: gl.glInterleavedArrays(iaFormat, bstride, verts);
1424: } else {
1425: if (EXTRA_DEBUGGING) {
1426: System.err.println(" startVertex: " + startVertex);
1427: System.err.println(" stride: " + stride);
1428: System.err.println(" bstride: " + bstride);
1429: System.err.println(" normoff: " + normoff);
1430: System.err.println(" coloroff: " + coloroff);
1431: System.err.println(" coordoff: " + coordoff);
1432: System.err.println(" texCoordoff: " + texCoordoff);
1433: }
1434: if ((vformat & GeometryArray.NORMALS) != 0) {
1435: verts.position(startVertex + normoff);
1436: gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
1437: }
1438: if (!ignoreVertexColors
1439: && (vformat & GeometryArray.COLOR) != 0) {
1440: clrs.position(startClrs);
1441: if ((vformat & GeometryArray.WITH_ALPHA) != 0
1442: || useAlpha) {
1443: gl.glColorPointer(4, GL.GL_FLOAT, cbstride,
1444: clrs);
1445: } else {
1446: gl.glColorPointer(3, GL.GL_FLOAT, cbstride,
1447: clrs);
1448: }
1449: }
1450: if ((vformat & GeometryArray.COORDINATES) != 0) {
1451: verts.position(startVertex + coordoff);
1452: gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
1453: }
1454:
1455: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
1456: executeTexture(texCoordSetMapLen, texSize, bstride,
1457: texCoordoff, texCoordSetMapOffset,
1458: numActiveTexUnitState, verts, gl);
1459: }
1460:
1461: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
1462: int vAttrOffset = startVertex + vAttrOff;
1463: for (int i = 0; i < vertexAttrCount; i++) {
1464: ctx.enableVertexAttrArray(gl, i);
1465: verts.position(vAttrOffset);
1466: ctx.vertexAttrPointer(gl, i,
1467: vertexAttrSizes[i], GL.GL_FLOAT,
1468: bstride, verts);
1469: vAttrOffset += vertexAttrSizes[i];
1470: }
1471: }
1472: }
1473: switch (geo_type) {
1474: case GeometryRetained.GEO_TYPE_QUAD_SET:
1475: gl.glDrawArrays(GL.GL_QUADS, 0, vcount);
1476: break;
1477: case GeometryRetained.GEO_TYPE_TRI_SET:
1478: gl.glDrawArrays(GL.GL_TRIANGLES, 0, vcount);
1479: break;
1480: case GeometryRetained.GEO_TYPE_POINT_SET:
1481: gl.glDrawArrays(GL.GL_POINTS, 0, vcount);
1482: break;
1483: case GeometryRetained.GEO_TYPE_LINE_SET:
1484: gl.glDrawArrays(GL.GL_LINES, 0, vcount);
1485: break;
1486: }
1487: }
1488:
1489: /* clean up if we turned on normalize */
1490: if (isNonUniformScale) {
1491: gl.glDisable(GL.GL_NORMALIZE);
1492: }
1493:
1494: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
1495: resetVertexAttrs(gl, ctx, vertexAttrCount);
1496: }
1497:
1498: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
1499: resetTexture(gl, ctx);
1500: }
1501: }
1502:
1503: // glLockArrays() is invoked only for indexed geometry, and the
1504: // vertexCount is guarenteed to be >= 0.
1505: private void lockArray(GL gl, int vertexCount) {
1506: if (gl.isExtensionAvailable("GL_EXT_compiled_vertex_array")) {
1507: gl.glLockArraysEXT(0, vertexCount);
1508: }
1509: }
1510:
1511: private void unlockArray(GL gl) {
1512: if (gl.isExtensionAvailable("GL_EXT_compiled_vertex_array")) {
1513: gl.glUnlockArraysEXT();
1514: }
1515: }
1516:
1517: private void executeGeometryArrayVA(Context absCtx,
1518: GeometryArrayRetained geo, int geo_type,
1519: boolean isNonUniformScale, boolean ignoreVertexColors,
1520: int vcount, int vformat, int vdefined,
1521: int initialCoordIndex, FloatBuffer fverts,
1522: DoubleBuffer dverts, int initialColorIndex,
1523: FloatBuffer fclrs, ByteBuffer bclrs,
1524: int initialNormalIndex, FloatBuffer norms,
1525: int vertexAttrCount, int[] vertexAttrSizes,
1526: int[] vertexAttrIndices, FloatBuffer[] vertexAttrData,
1527: int texCoordMapLength, int[] texCoordSetMap,
1528: int numActiveTexUnit, int[] texindices, int texStride,
1529: FloatBuffer[] texCoords, int cdirty, int[] sarray,
1530: int strip_len, int[] start_array) {
1531: JoglContext ctx = (JoglContext) absCtx;
1532: GLContext context = context(ctx);
1533: GL gl = context.getGL();
1534:
1535: boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
1536: boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
1537: boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
1538: boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
1539: boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
1540: boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
1541: boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
1542:
1543: // Enable normalize for non-uniform scale (which rescale can't handle)
1544: if (isNonUniformScale) {
1545: gl.glEnable(GL.GL_NORMALIZE);
1546: }
1547:
1548: int coordoff = 3 * initialCoordIndex;
1549: // Define the data pointers
1550: if (floatCoordDefined) {
1551: fverts.position(coordoff);
1552: gl.glVertexPointer(3, GL.GL_FLOAT, 0, fverts);
1553: } else if (doubleCoordDefined) {
1554: dverts.position(coordoff);
1555: gl.glVertexPointer(3, GL.GL_DOUBLE, 0, dverts);
1556: }
1557:
1558: if (floatColorsDefined) {
1559: int coloroff;
1560: int sz;
1561: if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
1562: coloroff = 4 * initialColorIndex;
1563: sz = 4;
1564: } else {
1565: coloroff = 3 * initialColorIndex;
1566: sz = 3;
1567: }
1568: fclrs.position(coloroff);
1569: gl.glColorPointer(sz, GL.GL_FLOAT, 0, fclrs);
1570: } else if (byteColorsDefined) {
1571: int coloroff;
1572: int sz;
1573: if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
1574: coloroff = 4 * initialColorIndex;
1575: sz = 4;
1576: } else {
1577: coloroff = 3 * initialColorIndex;
1578: sz = 3;
1579: }
1580: bclrs.position(coloroff);
1581: gl.glColorPointer(sz, GL.GL_UNSIGNED_BYTE, 0, bclrs);
1582: }
1583: if (normalsDefined) {
1584: int normoff = 3 * initialNormalIndex;
1585: norms.position(normoff);
1586: gl.glNormalPointer(GL.GL_FLOAT, 0, norms);
1587: }
1588:
1589: if (vattrDefined) {
1590: for (int i = 0; i < vertexAttrCount; i++) {
1591: FloatBuffer vertexAttrs = vertexAttrData[i];
1592: int sz = vertexAttrSizes[i];
1593: int initIdx = vertexAttrIndices[i];
1594: ctx.enableVertexAttrArray(gl, i);
1595: vertexAttrs.position(initIdx * sz);
1596: ctx.vertexAttrPointer(gl, i, sz, GL.GL_FLOAT, 0,
1597: vertexAttrs);
1598: }
1599: }
1600:
1601: if (textureDefined) {
1602: int texSet = 0;
1603: for (int i = 0; i < numActiveTexUnit; i++) {
1604: if ((i < texCoordMapLength)
1605: && ((texSet = texCoordSetMap[i]) != -1)) {
1606: FloatBuffer buf = texCoords[texSet];
1607: buf.position(texStride * texindices[texSet]);
1608: enableTexCoordPointer(gl, i, texStride,
1609: GL.GL_FLOAT, 0, buf);
1610: } else {
1611: disableTexCoordPointer(gl, i);
1612: }
1613: }
1614:
1615: // Reset client active texture unit to 0
1616: clientActiveTextureUnit(gl, 0);
1617: }
1618:
1619: if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET
1620: || geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET
1621: || geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
1622: int primType = 0;
1623: switch (geo_type) {
1624: case GeometryRetained.GEO_TYPE_TRI_STRIP_SET:
1625: primType = GL.GL_TRIANGLE_STRIP;
1626: break;
1627: case GeometryRetained.GEO_TYPE_TRI_FAN_SET:
1628: primType = GL.GL_TRIANGLE_FAN;
1629: break;
1630: case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
1631: primType = GL.GL_LINE_STRIP;
1632: break;
1633: }
1634: if (gl.isExtensionAvailable("GL_EXT_multi_draw_arrays")) {
1635: gl.glMultiDrawArraysEXT(primType, start_array, 0,
1636: sarray, 0, strip_len);
1637: } else if (gl.isExtensionAvailable("GL_VERSION_1_4")) {
1638: gl.glMultiDrawArrays(primType, start_array, 0, sarray,
1639: 0, strip_len);
1640: } else {
1641: for (int i = 0; i < strip_len; i++) {
1642: gl
1643: .glDrawArrays(primType, start_array[i],
1644: sarray[i]);
1645: }
1646: }
1647: } else {
1648: switch (geo_type) {
1649: case GeometryRetained.GEO_TYPE_QUAD_SET:
1650: gl.glDrawArrays(GL.GL_QUADS, 0, vcount);
1651: break;
1652: case GeometryRetained.GEO_TYPE_TRI_SET:
1653: gl.glDrawArrays(GL.GL_TRIANGLES, 0, vcount);
1654: break;
1655: case GeometryRetained.GEO_TYPE_POINT_SET:
1656: gl.glDrawArrays(GL.GL_POINTS, 0, vcount);
1657: break;
1658: case GeometryRetained.GEO_TYPE_LINE_SET:
1659: gl.glDrawArrays(GL.GL_LINES, 0, vcount);
1660: break;
1661: }
1662: }
1663:
1664: // clean up if we turned on normalize
1665: if (isNonUniformScale) {
1666: gl.glDisable(GL.GL_NORMALIZE);
1667: }
1668:
1669: if (vattrDefined) {
1670: resetVertexAttrs(gl, ctx, vertexAttrCount);
1671: }
1672:
1673: if (textureDefined) {
1674: resetTexture(gl, ctx);
1675: }
1676: }
1677:
1678: private String getVertexDescription(int vformat) {
1679: String res = "";
1680: if ((vformat & GeometryArray.COORDINATES) != 0)
1681: res += "COORDINATES ";
1682: if ((vformat & GeometryArray.NORMALS) != 0)
1683: res += "NORMALS ";
1684: if ((vformat & GeometryArray.COLOR) != 0)
1685: res += "COLOR ";
1686: if ((vformat & GeometryArray.WITH_ALPHA) != 0)
1687: res += "(WITH_ALPHA) ";
1688: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0)
1689: res += "TEXTURE_COORDINATE ";
1690: if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0)
1691: res += "(2) ";
1692: if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0)
1693: res += "(3) ";
1694: if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0)
1695: res += "(4) ";
1696: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0)
1697: res += "VERTEX_ATTRIBUTES ";
1698: return res;
1699: }
1700:
1701: private String getGeometryDescription(int geo_type) {
1702: switch (geo_type) {
1703: case GeometryRetained.GEO_TYPE_TRI_STRIP_SET:
1704: return "GEO_TYPE_TRI_STRIP_SET";
1705: case GeometryRetained.GEO_TYPE_TRI_FAN_SET:
1706: return "GEO_TYPE_TRI_FAN_SET";
1707: case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
1708: return "GEO_TYPE_LINE_STRIP_SET";
1709: case GeometryRetained.GEO_TYPE_QUAD_SET:
1710: return "GEO_TYPE_QUAD_SET";
1711: case GeometryRetained.GEO_TYPE_TRI_SET:
1712: return "GEO_TYPE_TRI_SET";
1713: case GeometryRetained.GEO_TYPE_POINT_SET:
1714: return "GEO_TYPE_POINT_SET";
1715: case GeometryRetained.GEO_TYPE_LINE_SET:
1716: return "GEO_TYPE_LINE_SET";
1717: default:
1718: return "(unknown " + geo_type + ")";
1719: }
1720: }
1721:
1722: private void resetVertexAttrs(GL gl, JoglContext ctx,
1723: int vertexAttrCount) {
1724: // Disable specified vertex attr arrays
1725: for (int i = 0; i < vertexAttrCount; i++) {
1726: ctx.disableVertexAttrArray(gl, i);
1727: }
1728: }
1729:
1730: // ---------------------------------------------------------------------
1731:
1732: //
1733: // IndexedGeometryArrayRetained methods
1734: //
1735:
1736: // by-copy or interleaved, by reference, Java arrays
1737: void executeIndexedGeometry(Context ctx, GeometryArrayRetained geo,
1738: int geo_type, boolean isNonUniformScale, boolean useAlpha,
1739: boolean ignoreVertexColors, int initialIndexIndex,
1740: int indexCount, int vertexCount, int vformat,
1741: int vertexAttrCount, int[] vertexAttrSizes,
1742: int texCoordSetCount, int[] texCoordSetMap,
1743: int texCoordSetMapLen, int[] texCoordSetOffset,
1744: int numActiveTexUnitState, float[] varray, float[] carray,
1745: int cdirty, int[] indexCoord) {
1746: if (VERBOSE)
1747: System.err.println("JoglPipeline.executeIndexedGeometry()");
1748:
1749: executeIndexedGeometryArray(ctx, geo, geo_type,
1750: isNonUniformScale, useAlpha, ignoreVertexColors,
1751: initialIndexIndex, indexCount, vertexCount, vformat,
1752: vertexAttrCount, vertexAttrSizes, texCoordSetCount,
1753: texCoordSetMap, texCoordSetMapLen, texCoordSetOffset,
1754: numActiveTexUnitState, varray, null, carray, cdirty,
1755: indexCoord);
1756: }
1757:
1758: // interleaved, by reference, nio buffer
1759: void executeIndexedGeometryBuffer(Context ctx,
1760: GeometryArrayRetained geo, int geo_type,
1761: boolean isNonUniformScale, boolean useAlpha,
1762: boolean ignoreVertexColors, int initialIndexIndex,
1763: int indexCount, int vertexCount, int vformat,
1764: int texCoordSetCount, int[] texCoordSetMap,
1765: int texCoordSetMapLen, int[] texCoordSetOffset,
1766: int numActiveTexUnitState, Object vdata, float[] carray,
1767: int cDirty, int[] indexCoord) {
1768: if (VERBOSE)
1769: System.err
1770: .println("JoglPipeline.executeIndexedGeometryBuffer()");
1771:
1772: executeIndexedGeometryArray(ctx, geo, geo_type,
1773: isNonUniformScale, useAlpha, ignoreVertexColors,
1774: initialIndexIndex, indexCount, vertexCount, vformat, 0,
1775: null, texCoordSetCount, texCoordSetMap,
1776: texCoordSetMapLen, texCoordSetOffset,
1777: numActiveTexUnitState, null, (FloatBuffer) vdata,
1778: carray, cDirty, indexCoord);
1779: }
1780:
1781: // non interleaved, by reference, Java arrays
1782: void executeIndexedGeometryVA(Context ctx,
1783: GeometryArrayRetained geo, int geo_type,
1784: boolean isNonUniformScale, boolean ignoreVertexColors,
1785: int initialIndexIndex, int validIndexCount,
1786: int vertexCount, int vformat, int vdefined,
1787: float[] vfcoords, double[] vdcoords, float[] cfdata,
1788: byte[] cbdata, float[] ndata, int vertexAttrCount,
1789: int[] vertexAttrSizes, float[][] vertexAttrData,
1790: int texCoordMapLength, int[] texcoordoffset,
1791: int numActiveTexUnitState, int texStride,
1792: Object[] texCoords, int cdirty, int[] indexCoord) {
1793: if (VERBOSE)
1794: System.err
1795: .println("JoglPipeline.executeIndexedGeometryVA()");
1796:
1797: boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
1798: boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
1799: boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
1800: boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
1801: boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
1802: boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
1803: boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
1804:
1805: FloatBuffer fverts = null;
1806: DoubleBuffer dverts = null;
1807: FloatBuffer fclrs = null;
1808: ByteBuffer bclrs = null;
1809: FloatBuffer[] texCoordBufs = null;
1810: FloatBuffer norms = null;
1811: FloatBuffer[] vertexAttrBufs = null;
1812:
1813: // Get vertex attribute arrays
1814: if (vattrDefined) {
1815: vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData);
1816: }
1817:
1818: // get texture arrays
1819: if (textureDefined) {
1820: texCoordBufs = getTexCoordSetBuffer(texCoords);
1821: }
1822:
1823: int[] sarray = null;
1824: int strip_len = 0;
1825: if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET
1826: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET
1827: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
1828: sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts;
1829: strip_len = sarray.length;
1830: }
1831:
1832: // get coordinate array
1833: if (floatCoordDefined) {
1834: fverts = getVertexArrayBuffer(vfcoords);
1835: } else if (doubleCoordDefined) {
1836: dverts = getVertexArrayBuffer(vdcoords);
1837: }
1838:
1839: // get color array
1840: if (floatColorsDefined) {
1841: fclrs = getColorArrayBuffer(cfdata);
1842: } else if (byteColorsDefined) {
1843: bclrs = getColorArrayBuffer(cbdata);
1844: }
1845:
1846: // get normal array
1847: if (normalsDefined) {
1848: norms = getNormalArrayBuffer(ndata);
1849: }
1850:
1851: executeIndexedGeometryArrayVA(ctx, geo, geo_type,
1852: isNonUniformScale, ignoreVertexColors,
1853: initialIndexIndex, validIndexCount, vertexCount,
1854: vformat, vdefined, fverts, dverts, fclrs, bclrs, norms,
1855: vertexAttrCount, vertexAttrSizes, vertexAttrBufs,
1856: texCoordMapLength, texcoordoffset,
1857: numActiveTexUnitState, texStride, texCoordBufs, cdirty,
1858: indexCoord, sarray, strip_len);
1859: }
1860:
1861: // non interleaved, by reference, nio buffer
1862: void executeIndexedGeometryVABuffer(Context ctx,
1863: GeometryArrayRetained geo, int geo_type,
1864: boolean isNonUniformScale, boolean ignoreVertexColors,
1865: int initialIndexIndex, int validIndexCount,
1866: int vertexCount, int vformat, int vdefined, Object vcoords,
1867: Object cdataBuffer, float[] cfdata, byte[] cbdata,
1868: Object ndata, int vertexAttrCount, int[] vertexAttrSizes,
1869: Object[] vertexAttrData, int texCoordMapLength,
1870: int[] texcoordoffset, int numActiveTexUnitState,
1871: int texStride, Object[] texCoords, int cdirty,
1872: int[] indexCoord) {
1873: if (VERBOSE)
1874: System.err
1875: .println("JoglPipeline.executeIndexedGeometryVABuffer()");
1876:
1877: boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
1878: boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
1879: boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
1880: boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
1881: boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
1882: boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
1883: boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
1884:
1885: FloatBuffer fverts = null;
1886: DoubleBuffer dverts = null;
1887: FloatBuffer fclrs = null;
1888: ByteBuffer bclrs = null;
1889: FloatBuffer[] texCoordBufs = null;
1890: FloatBuffer norms = null;
1891: FloatBuffer[] vertexAttrBufs = null;
1892:
1893: // Get vertex attribute arrays
1894: if (vattrDefined) {
1895: vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData);
1896: }
1897:
1898: // get texture arrays
1899: if (textureDefined) {
1900: texCoordBufs = new FloatBuffer[texCoords.length];
1901: for (int i = 0; i < texCoords.length; i++) {
1902: texCoordBufs[i] = (FloatBuffer) texCoords[i];
1903: }
1904: }
1905:
1906: // get coordinate array
1907: if (floatCoordDefined) {
1908: fverts = (FloatBuffer) vcoords;
1909: } else if (doubleCoordDefined) {
1910: dverts = (DoubleBuffer) vcoords;
1911: }
1912:
1913: if (fverts == null && dverts == null) {
1914: return;
1915: }
1916:
1917: int[] sarray = null;
1918: int strip_len = 0;
1919: if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET
1920: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET
1921: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
1922: sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts;
1923: strip_len = sarray.length;
1924: }
1925:
1926: // get color array
1927: if (floatColorsDefined) {
1928: if (cfdata != null)
1929: fclrs = getColorArrayBuffer(cfdata);
1930: else
1931: fclrs = (FloatBuffer) cdataBuffer;
1932: } else if (byteColorsDefined) {
1933: if (cbdata != null)
1934: bclrs = getColorArrayBuffer(cbdata);
1935: else
1936: bclrs = (ByteBuffer) cdataBuffer;
1937: }
1938:
1939: // get normal array
1940: if (normalsDefined) {
1941: norms = (FloatBuffer) ndata;
1942: }
1943:
1944: executeIndexedGeometryArrayVA(ctx, geo, geo_type,
1945: isNonUniformScale, ignoreVertexColors,
1946: initialIndexIndex, validIndexCount, vertexCount,
1947: vformat, vdefined, fverts, dverts, fclrs, bclrs, norms,
1948: vertexAttrCount, vertexAttrSizes, vertexAttrBufs,
1949: texCoordMapLength, texcoordoffset,
1950: numActiveTexUnitState, texStride, texCoordBufs, cdirty,
1951: indexCoord, sarray, strip_len);
1952: }
1953:
1954: // by-copy geometry
1955: void buildIndexedGeometry(Context absCtx,
1956: GeometryArrayRetained geo, int geo_type,
1957: boolean isNonUniformScale, boolean updateAlpha,
1958: float alpha, boolean ignoreVertexColors,
1959: int initialIndexIndex, int validIndexCount,
1960: int vertexCount, int vformat, int vertexAttrCount,
1961: int[] vertexAttrSizes, int texCoordSetCount,
1962: int[] texCoordSetMap, int texCoordSetMapLen,
1963: int[] texCoordSetMapOffset, double[] xform,
1964: double[] nxform, float[] varray, int[] indexCoord) {
1965: if (VERBOSE)
1966: System.err.println("JoglPipeline.buildIndexedGeometry()");
1967:
1968: JoglContext ctx = (JoglContext) absCtx;
1969: GL gl = context(ctx).getGL();
1970:
1971: boolean useInterleavedArrays;
1972: int iaFormat = 0;
1973: int primType = 0;
1974: int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0;
1975: int texSize = 0, texStride = 0;
1976: int vAttrOff = 0;
1977: int vAttrStride = 0;
1978: int bstride = 0, cbstride = 0;
1979: FloatBuffer verts = null;
1980: FloatBuffer clrs = null;
1981: int[] sarray = null;
1982: int strip_len = 0;
1983: boolean useAlpha = false;
1984:
1985: if ((vformat & GeometryArray.COORDINATES) != 0) {
1986: gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
1987: stride += 3;
1988: } else {
1989: gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
1990: }
1991:
1992: if ((vformat & GeometryArray.NORMALS) != 0) {
1993: gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
1994: stride += 3;
1995: coordoff += 3;
1996: } else {
1997: gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
1998: }
1999:
2000: if ((vformat & GeometryArray.COLOR) != 0) {
2001: gl.glEnableClientState(GL.GL_COLOR_ARRAY);
2002: stride += 4;
2003: normoff += 4;
2004: coordoff += 4;
2005: } else {
2006: gl.glDisableClientState(GL.GL_COLOR_ARRAY);
2007: }
2008:
2009: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
2010: if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
2011: texSize = 2;
2012: texStride = 2 * texCoordSetCount;
2013: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
2014: texSize = 3;
2015: texStride = 3 * texCoordSetCount;
2016: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) {
2017: texSize = 4;
2018: texStride = 4 * texCoordSetCount;
2019: }
2020: stride += texStride;
2021: normoff += texStride;
2022: coloroff += texStride;
2023: coordoff += texStride;
2024: }
2025:
2026: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
2027: for (int i = 0; i < vertexAttrCount; i++) {
2028: vAttrStride += vertexAttrSizes[i];
2029: }
2030: stride += vAttrStride;
2031: normoff += vAttrStride;
2032: coloroff += vAttrStride;
2033: coordoff += vAttrStride;
2034: texCoordoff += vAttrStride;
2035: }
2036:
2037: bstride = stride * BufferUtil.SIZEOF_FLOAT;
2038:
2039: // process alpha for geometryArray without alpha
2040: if (updateAlpha && !ignoreVertexColors) {
2041: useAlpha = true;
2042: }
2043:
2044: if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET
2045: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET
2046: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
2047: sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts;
2048: strip_len = sarray.length;
2049: }
2050:
2051: // Copy data into NIO array
2052: verts = getVertexArrayBuffer(varray);
2053:
2054: // Apply normal transform if necessary
2055: if ((vformat & GeometryArray.NORMALS) != 0 && nxform != null) {
2056: int off = normoff;
2057: for (int i = 0; i < vertexCount * 3; i += 3) {
2058: verts.put(off, (float) (nxform[0] * varray[off]
2059: + nxform[1] * varray[off + 1] + nxform[2]
2060: * varray[off + 2]));
2061: verts.put(off + 1, (float) (nxform[4] * varray[off]
2062: + nxform[5] * varray[off + 1] + nxform[6]
2063: * varray[off + 2]));
2064: verts.put(off + 2, (float) (nxform[8] * varray[off]
2065: + nxform[9] * varray[off + 1] + nxform[10]
2066: * varray[off + 2]));
2067: off += stride;
2068: }
2069: }
2070:
2071: // Apply coordinate transform if necessary
2072: if ((vformat & GeometryArray.COORDINATES) != 0 && xform != null) {
2073: int off = coordoff;
2074: for (int i = 0; i < vertexCount * 3; i += 3) {
2075: verts.put(off, (float) (xform[0] * varray[off]
2076: + xform[1] * varray[off + 1] + xform[2]
2077: * varray[off + 2]));
2078: verts.put(off + 1, (float) (xform[4] * varray[off]
2079: + xform[5] * varray[off + 1] + xform[6]
2080: * varray[off + 2]));
2081: verts.put(off + 2, (float) (xform[8] * varray[off]
2082: + xform[9] * varray[off + 1] + xform[10]
2083: * varray[off + 2]));
2084: off += stride;
2085: }
2086: }
2087:
2088: if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET
2089: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET
2090: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
2091: // Note we can use interleaved arrays even if we have a
2092: // non-null xform since we use the same data layout unlike the
2093: // C code
2094: if (ignoreVertexColors
2095: || (((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) && ((texCoordSetMapLen > 1) || (texCoordSetCount > 1)))) {
2096: useInterleavedArrays = false;
2097: } else {
2098: boolean[] tmp = new boolean[1];
2099: int[] tmp2 = new int[1];
2100: testForInterleavedArrays(vformat, tmp, tmp2);
2101: useInterleavedArrays = tmp[0];
2102: iaFormat = tmp2[0];
2103: }
2104:
2105: if (useInterleavedArrays) {
2106: verts.position(0);
2107: gl.glInterleavedArrays(iaFormat, bstride, verts);
2108: } else {
2109: if ((vformat & GeometryArray.NORMALS) != 0) {
2110: verts.position(normoff);
2111: gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
2112: }
2113: if (!ignoreVertexColors
2114: && ((vformat & GeometryArray.COLOR) != 0)) {
2115: verts.position(coloroff);
2116: if (((vformat & GeometryArray.WITH_ALPHA) != 0)
2117: || useAlpha) {
2118: gl.glColorPointer(4, GL.GL_FLOAT, bstride,
2119: verts);
2120: } else {
2121: gl.glColorPointer(3, GL.GL_FLOAT, bstride,
2122: verts);
2123: }
2124: }
2125: if ((vformat & GeometryArray.COORDINATES) != 0) {
2126: verts.position(coordoff);
2127: gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
2128: }
2129: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
2130: executeTexture(texCoordSetMapLen, texSize, bstride,
2131: texCoordoff, texCoordSetMapOffset,
2132: texCoordSetMapLen, verts, gl);
2133: }
2134: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
2135: int vAttrOffset = vAttrOff;
2136: for (int i = 0; i < vertexAttrCount; i++) {
2137: ctx.enableVertexAttrArray(gl, i);
2138: verts.position(vAttrOffset);
2139: ctx.vertexAttrPointer(gl, i,
2140: vertexAttrSizes[i], GL.GL_FLOAT,
2141: bstride, verts);
2142: vAttrOffset += vertexAttrSizes[i];
2143: }
2144: }
2145: }
2146:
2147: switch (geo_type) {
2148: case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET:
2149: primType = GL.GL_TRIANGLE_STRIP;
2150: break;
2151: case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET:
2152: primType = GL.GL_TRIANGLE_FAN;
2153: break;
2154: case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
2155: primType = GL.GL_LINE_STRIP;
2156: break;
2157: }
2158:
2159: lockArray(gl, vertexCount);
2160:
2161: // Note: using MultiDrawElements is probably more expensive than
2162: // not in this case due to the need to allocate more temporary
2163: // direct buffers and slice up the incoming indices array
2164: int offset = initialIndexIndex;
2165: IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord);
2166: for (int i = 0; i < strip_len; i++) {
2167: indicesBuffer.position(offset);
2168: int count = sarray[i];
2169: gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT,
2170: indicesBuffer);
2171: offset += count;
2172: }
2173: } else if ((geo_type == GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET)
2174: || (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_SET)
2175: || (geo_type == GeometryRetained.GEO_TYPE_INDEXED_POINT_SET)
2176: || (geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_SET)) {
2177: // Note we can use interleaved arrays even if we have a
2178: // non-null xform since we use the same data layout unlike the
2179: // C code
2180: if (ignoreVertexColors
2181: || (((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) && ((texCoordSetMapLen > 1) || (texCoordSetCount > 1)))) {
2182: useInterleavedArrays = false;
2183: } else {
2184: boolean[] tmp = new boolean[1];
2185: int[] tmp2 = new int[1];
2186: testForInterleavedArrays(vformat, tmp, tmp2);
2187: useInterleavedArrays = tmp[0];
2188: iaFormat = tmp2[0];
2189: }
2190:
2191: if (useInterleavedArrays) {
2192: verts.position(0);
2193: gl.glInterleavedArrays(iaFormat, bstride, verts);
2194: } else {
2195: if ((vformat & GeometryArray.NORMALS) != 0) {
2196: verts.position(normoff);
2197: gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
2198: }
2199:
2200: if (!ignoreVertexColors
2201: && ((vformat & GeometryArray.COLOR) != 0)) {
2202: verts.position(coloroff);
2203: if (((vformat & GeometryArray.WITH_ALPHA) != 0)
2204: || useAlpha) {
2205: gl.glColorPointer(4, GL.GL_FLOAT, bstride,
2206: verts);
2207: } else {
2208: gl.glColorPointer(3, GL.GL_FLOAT, bstride,
2209: verts);
2210: }
2211: }
2212: if ((vformat & GeometryArray.COORDINATES) != 0) {
2213: verts.position(coordoff);
2214: gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
2215: }
2216: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
2217: executeTexture(texCoordSetMapLen, texSize, bstride,
2218: texCoordoff, texCoordSetMapOffset,
2219: texCoordSetMapLen, verts, gl);
2220: }
2221: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
2222: int vAttrOffset = vAttrOff;
2223: for (int i = 0; i < vertexAttrCount; i++) {
2224: ctx.enableVertexAttrArray(gl, i);
2225: verts.position(vAttrOffset);
2226: ctx.vertexAttrPointer(gl, i,
2227: vertexAttrSizes[i], GL.GL_FLOAT,
2228: bstride, verts);
2229: vAttrOffset += vertexAttrSizes[i];
2230: }
2231: }
2232:
2233: switch (geo_type) {
2234: case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET:
2235: primType = GL.GL_QUADS;
2236: break;
2237: case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET:
2238: primType = GL.GL_TRIANGLES;
2239: break;
2240: case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET:
2241: primType = GL.GL_POINTS;
2242: break;
2243: case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET:
2244: primType = GL.GL_LINES;
2245: break;
2246: }
2247:
2248: lockArray(gl, vertexCount);
2249:
2250: IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord);
2251: indicesBuffer.position(initialIndexIndex);
2252: gl.glDrawElements(primType, validIndexCount,
2253: GL.GL_UNSIGNED_INT, indicesBuffer);
2254: }
2255: }
2256:
2257: unlockArray(gl);
2258:
2259: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
2260: resetVertexAttrs(gl, ctx, vertexAttrCount);
2261: }
2262:
2263: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
2264: resetTexture(gl, ctx);
2265: }
2266: }
2267:
2268: //----------------------------------------------------------------------
2269: //
2270: // Helper routines for IndexedGeometryArrayRetained
2271: //
2272:
2273: private void executeIndexedGeometryArray(Context absCtx,
2274: GeometryArrayRetained geo, int geo_type,
2275: boolean isNonUniformScale, boolean useAlpha,
2276: boolean ignoreVertexColors, int initialIndexIndex,
2277: int indexCount, int vertexCount, int vformat,
2278: int vertexAttrCount, int[] vertexAttrSizes,
2279: int texCoordSetCount, int[] texCoordSetMap,
2280: int texCoordSetMapLen, int[] texCoordSetOffset,
2281: int numActiveTexUnitState, float[] varray,
2282: FloatBuffer vdata, float[] carray, int cDirty,
2283: int[] indexCoord) {
2284: JoglContext ctx = (JoglContext) absCtx;
2285: GL gl = context(ctx).getGL();
2286:
2287: boolean useInterleavedArrays;
2288: int iaFormat = 0;
2289: int primType = 0;
2290: int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0;
2291: int texSize = 0, texStride = 0;
2292: int vAttrOff = 0;
2293: int vAttrStride = 0;
2294: int bstride = 0, cbstride = 0;
2295: FloatBuffer verts = null;
2296: FloatBuffer clrs = null;
2297: int[] sarray = null;
2298: int strip_len = 0;
2299:
2300: if ((vformat & GeometryArray.COORDINATES) != 0) {
2301: stride += 3;
2302: }
2303: if ((vformat & GeometryArray.NORMALS) != 0) {
2304: stride += 3;
2305: coordoff += 3;
2306: }
2307:
2308: if ((vformat & GeometryArray.COLOR) != 0) {
2309: if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
2310: stride += 4;
2311: normoff += 4;
2312: coordoff += 4;
2313: } else { // Handle the case of executeInterleaved 3f
2314: stride += 3;
2315: normoff += 3;
2316: coordoff += 3;
2317: }
2318: }
2319:
2320: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
2321: if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
2322: texSize = 2;
2323: texStride = 2 * texCoordSetCount;
2324: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
2325: texSize = 3;
2326: texStride = 3 * texCoordSetCount;
2327: } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) {
2328: texSize = 4;
2329: texStride = 4 * texCoordSetCount;
2330: }
2331: stride += texStride;
2332: normoff += texStride;
2333: coloroff += texStride;
2334: coordoff += texStride;
2335: }
2336:
2337: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
2338: for (int i = 0; i < vertexAttrCount; i++) {
2339: vAttrStride += vertexAttrSizes[i];
2340: }
2341: stride += vAttrStride;
2342: normoff += vAttrStride;
2343: coloroff += vAttrStride;
2344: coordoff += vAttrStride;
2345: texCoordoff += vAttrStride;
2346: }
2347:
2348: bstride = stride * BufferUtil.SIZEOF_FLOAT;
2349:
2350: if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET
2351: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET
2352: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
2353: sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts;
2354: strip_len = sarray.length;
2355: }
2356:
2357: // We have to copy if the data isn't specified using NIO
2358: if (varray != null) {
2359: verts = getVertexArrayBuffer(varray);
2360: } else if (vdata != null) {
2361: verts = vdata;
2362: } else {
2363: // This should never happen
2364: throw new AssertionError("Unable to get vertex pointer");
2365: }
2366:
2367: // using byRef interleaved array and has a separate pointer, then ..
2368: int cstride = stride;
2369: if (carray != null) {
2370: clrs = getColorArrayBuffer(carray);
2371: cstride = 4;
2372: } else {
2373: // FIXME: need to "auto-slice" this buffer later
2374: clrs = verts;
2375: }
2376:
2377: cbstride = cstride * BufferUtil.SIZEOF_FLOAT;
2378:
2379: // Enable normalize for non-uniform scale (which rescale can't handle)
2380: if (isNonUniformScale) {
2381: gl.glEnable(GL.GL_NORMALIZE);
2382: }
2383:
2384: /*** Handle non-indexed strip GeometryArray first *******/
2385: if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET
2386: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET
2387: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
2388: if (ignoreVertexColors
2389: || (carray != null)
2390: || ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || (texCoordSetCount > 1)))) {
2391: useInterleavedArrays = false;
2392: } else {
2393: boolean[] tmp = new boolean[1];
2394: int[] tmp2 = new int[1];
2395: testForInterleavedArrays(vformat, tmp, tmp2);
2396: useInterleavedArrays = tmp[0];
2397: iaFormat = tmp2[0];
2398: }
2399: if (useInterleavedArrays) {
2400: verts.position(0);
2401: gl.glInterleavedArrays(iaFormat, bstride, verts);
2402: } else {
2403: if ((vformat & GeometryArray.NORMALS) != 0) {
2404: verts.position(normoff);
2405: gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
2406: }
2407: if (!ignoreVertexColors
2408: && (vformat & GeometryArray.COLOR) != 0) {
2409: if (clrs == verts) {
2410: clrs.position(coloroff);
2411: }
2412: if ((vformat & GeometryArray.WITH_ALPHA) != 0
2413: || useAlpha) {
2414: gl.glColorPointer(4, GL.GL_FLOAT, cbstride,
2415: clrs);
2416: } else {
2417: gl.glColorPointer(3, GL.GL_FLOAT, cbstride,
2418: clrs);
2419: }
2420: }
2421: if ((vformat & GeometryArray.COORDINATES) != 0) {
2422: verts.position(coordoff);
2423: gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
2424: }
2425:
2426: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
2427: /* XXXX: texCoordoff == 0 ???*/
2428: executeTexture(texCoordSetMapLen, texSize, bstride,
2429: texCoordoff, texCoordSetOffset,
2430: numActiveTexUnitState, verts, gl);
2431: }
2432:
2433: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
2434: int vAttrOffset = vAttrOff;
2435: for (int i = 0; i < vertexAttrCount; i++) {
2436: ctx.enableVertexAttrArray(gl, i);
2437: verts.position(vAttrOffset);
2438: ctx.vertexAttrPointer(gl, i,
2439: vertexAttrSizes[i], GL.GL_FLOAT,
2440: bstride, verts);
2441: vAttrOffset += vertexAttrSizes[i];
2442: }
2443: }
2444: }
2445:
2446: switch (geo_type) {
2447: case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET:
2448: primType = GL.GL_TRIANGLE_STRIP;
2449: break;
2450: case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET:
2451: primType = GL.GL_TRIANGLE_FAN;
2452: break;
2453: case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
2454: primType = GL.GL_LINE_STRIP;
2455: break;
2456: }
2457:
2458: lockArray(gl, vertexCount);
2459:
2460: // Note: using MultiDrawElements is probably more expensive than
2461: // not in this case due to the need to allocate more temporary
2462: // direct buffers and slice up the incoming indices array
2463: int offset = initialIndexIndex;
2464: IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord);
2465: for (int i = 0; i < strip_len; i++) {
2466: indicesBuffer.position(offset);
2467: int count = sarray[i];
2468: gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT,
2469: indicesBuffer);
2470: offset += count;
2471: }
2472: } else if ((geo_type == GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET)
2473: || (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_SET)
2474: || (geo_type == GeometryRetained.GEO_TYPE_INDEXED_POINT_SET)
2475: || (geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_SET)) {
2476: /******* Handle non-indexed non-striped GeometryArray now *****/
2477: if (ignoreVertexColors
2478: || (carray != null)
2479: || ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || (texCoordSetCount > 1)))) {
2480: useInterleavedArrays = false;
2481: } else {
2482: boolean[] tmp = new boolean[1];
2483: int[] tmp2 = new int[1];
2484: testForInterleavedArrays(vformat, tmp, tmp2);
2485: useInterleavedArrays = tmp[0];
2486: iaFormat = tmp2[0];
2487: }
2488:
2489: if (useInterleavedArrays) {
2490: verts.position(0);
2491: gl.glInterleavedArrays(iaFormat, bstride, verts);
2492: } else {
2493: if ((vformat & GeometryArray.NORMALS) != 0) {
2494: verts.position(normoff);
2495: gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
2496: }
2497:
2498: if (!ignoreVertexColors
2499: && (vformat & GeometryArray.COLOR) != 0) {
2500: if (clrs == verts) {
2501: clrs.position(coloroff);
2502: }
2503: if ((vformat & GeometryArray.WITH_ALPHA) != 0
2504: || useAlpha) {
2505: gl.glColorPointer(4, GL.GL_FLOAT, cbstride,
2506: clrs);
2507: } else {
2508: gl.glColorPointer(3, GL.GL_FLOAT, cbstride,
2509: clrs);
2510: }
2511: }
2512: if ((vformat & GeometryArray.COORDINATES) != 0) {
2513: verts.position(coordoff);
2514: gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
2515: }
2516:
2517: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
2518: /* XXXX: texCoordoff == 0 ???*/
2519: executeTexture(texCoordSetMapLen, texSize, bstride,
2520: texCoordoff, texCoordSetOffset,
2521: numActiveTexUnitState, verts, gl);
2522: }
2523:
2524: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
2525: int vAttrOffset = vAttrOff;
2526: for (int i = 0; i < vertexAttrCount; i++) {
2527: ctx.enableVertexAttrArray(gl, i);
2528: verts.position(vAttrOffset);
2529: ctx.vertexAttrPointer(gl, i,
2530: vertexAttrSizes[i], GL.GL_FLOAT,
2531: bstride, verts);
2532: vAttrOffset += vertexAttrSizes[i];
2533: }
2534: }
2535: }
2536:
2537: lockArray(gl, vertexCount);
2538: IntBuffer buf = IntBuffer.wrap(indexCoord);
2539: buf.position(initialIndexIndex);
2540: switch (geo_type) {
2541: case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET:
2542: gl.glDrawElements(GL.GL_QUADS, indexCount,
2543: GL.GL_UNSIGNED_INT, buf);
2544: break;
2545: case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET:
2546: gl.glDrawElements(GL.GL_TRIANGLES, indexCount,
2547: GL.GL_UNSIGNED_INT, buf);
2548: break;
2549: case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET:
2550: gl.glDrawElements(GL.GL_POINTS, indexCount,
2551: GL.GL_UNSIGNED_INT, buf);
2552: break;
2553: case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET:
2554: gl.glDrawElements(GL.GL_LINES, indexCount,
2555: GL.GL_UNSIGNED_INT, buf);
2556: break;
2557: }
2558: }
2559:
2560: unlockArray(gl);
2561:
2562: if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
2563: resetVertexAttrs(gl, ctx, vertexAttrCount);
2564: }
2565:
2566: if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
2567: resetTexture(gl, ctx);
2568: }
2569:
2570: // clean up if we turned on normalize
2571: if (isNonUniformScale) {
2572: gl.glDisable(GL.GL_NORMALIZE);
2573: }
2574: }
2575:
2576: private void executeIndexedGeometryArrayVA(Context absCtx,
2577: GeometryArrayRetained geo, int geo_type,
2578: boolean isNonUniformScale, boolean ignoreVertexColors,
2579: int initialIndexIndex, int validIndexCount,
2580: int vertexCount, int vformat, int vdefined,
2581: FloatBuffer fverts, DoubleBuffer dverts, FloatBuffer fclrs,
2582: ByteBuffer bclrs, FloatBuffer norms, int vertexAttrCount,
2583: int[] vertexAttrSizes, FloatBuffer[] vertexAttrBufs,
2584: int texCoordSetCount, int[] texCoordSetMap,
2585: int numActiveTexUnitState, int texStride,
2586: FloatBuffer[] texCoords, int cDirty, int[] indexCoord,
2587: int[] sarray, int strip_len) {
2588: JoglContext ctx = (JoglContext) absCtx;
2589: GL gl = context(ctx).getGL();
2590:
2591: boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
2592: boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
2593: boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
2594: boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
2595: boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
2596: boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
2597: boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
2598:
2599: // Enable normalize for non-uniform scale (which rescale can't handle)
2600: if (isNonUniformScale) {
2601: gl.glEnable(GL.GL_NORMALIZE);
2602: }
2603:
2604: // Define the data pointers
2605: if (floatCoordDefined) {
2606: fverts.position(0);
2607: gl.glVertexPointer(3, GL.GL_FLOAT, 0, fverts);
2608: } else if (doubleCoordDefined) {
2609: dverts.position(0);
2610: gl.glVertexPointer(3, GL.GL_DOUBLE, 0, dverts);
2611: }
2612: if (floatColorsDefined) {
2613: fclrs.position(0);
2614: if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
2615: gl.glColorPointer(4, GL.GL_FLOAT, 0, fclrs);
2616: } else {
2617: gl.glColorPointer(3, GL.GL_FLOAT, 0, fclrs);
2618: }
2619: } else if (byteColorsDefined) {
2620: bclrs.position(0);
2621: if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
2622: gl.glColorPointer(4, GL.GL_UNSIGNED_BYTE, 0, bclrs);
2623: } else {
2624: gl.glColorPointer(3, GL.GL_UNSIGNED_BYTE, 0, bclrs);
2625: }
2626: }
2627: if (normalsDefined) {
2628: norms.position(0);
2629: gl.glNormalPointer(GL.GL_FLOAT, 0, norms);
2630: }
2631:
2632: if (vattrDefined) {
2633: for (int i = 0; i < vertexAttrCount; i++) {
2634: FloatBuffer vertexAttrs = vertexAttrBufs[i];
2635: int sz = vertexAttrSizes[i];
2636: ctx.enableVertexAttrArray(gl, i);
2637: vertexAttrs.position(0);
2638: ctx.vertexAttrPointer(gl, i, sz, GL.GL_FLOAT, 0,
2639: vertexAttrs);
2640: }
2641: }
2642:
2643: if (textureDefined) {
2644: int texSet = 0;
2645: for (int i = 0; i < numActiveTexUnitState; i++) {
2646: if ((i < texCoordSetCount)
2647: && ((texSet = texCoordSetMap[i]) != -1)) {
2648: FloatBuffer buf = texCoords[texSet];
2649: buf.position(0);
2650: enableTexCoordPointer(gl, i, texStride,
2651: GL.GL_FLOAT, 0, buf);
2652: } else {
2653: disableTexCoordPointer(gl, i);
2654: }
2655: }
2656:
2657: // Reset client active texture unit to 0
2658: clientActiveTextureUnit(gl, 0);
2659: }
2660:
2661: lockArray(gl, vertexCount);
2662:
2663: if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET
2664: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET
2665: || geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
2666: int primType = 0;
2667: switch (geo_type) {
2668: case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET:
2669: primType = GL.GL_TRIANGLE_STRIP;
2670: break;
2671: case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET:
2672: primType = GL.GL_TRIANGLE_FAN;
2673: break;
2674: case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
2675: primType = GL.GL_LINE_STRIP;
2676: break;
2677: }
2678:
2679: // Note: using MultiDrawElements is probably more expensive than
2680: // not in this case due to the need to allocate more temporary
2681: // direct buffers and slice up the incoming indices array
2682: int offset = initialIndexIndex;
2683: IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord);
2684: for (int i = 0; i < strip_len; i++) {
2685: indicesBuffer.position(offset);
2686: int count = sarray[i];
2687: gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT,
2688: indicesBuffer);
2689: offset += count;
2690: }
2691: } else {
2692: IntBuffer buf = IntBuffer.wrap(indexCoord);
2693: buf.position(initialIndexIndex);
2694: switch (geo_type) {
2695: case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET:
2696: gl.glDrawElements(GL.GL_QUADS, validIndexCount,
2697: GL.GL_UNSIGNED_INT, buf);
2698: break;
2699: case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET:
2700: gl.glDrawElements(GL.GL_TRIANGLES, validIndexCount,
2701: GL.GL_UNSIGNED_INT, buf);
2702: break;
2703: case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET:
2704: gl.glDrawElements(GL.GL_POINTS, validIndexCount,
2705: GL.GL_UNSIGNED_INT, buf);
2706: break;
2707: case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET:
2708: gl.glDrawElements(GL.GL_LINES, validIndexCount,
2709: GL.GL_UNSIGNED_INT, buf);
2710: break;
2711: }
2712: }
2713:
2714: unlockArray(gl);
2715:
2716: // clean up if we turned on normalize
2717: if (isNonUniformScale) {
2718: gl.glDisable(GL.GL_NORMALIZE);
2719: }
2720:
2721: if (vattrDefined) {
2722: resetVertexAttrs(gl, ctx, vertexAttrCount);
2723: }
2724:
2725: if (textureDefined) {
2726: resetTexture(gl, ctx);
2727: }
2728: }
2729:
2730: // ---------------------------------------------------------------------
2731:
2732: //
2733: // GraphicsContext3D methods
2734: //
2735:
2736: // Native method for readRaster
2737: void readRaster(Context ctx, int type, int xSrcOffset,
2738: int ySrcOffset, int width, int height, int hCanvas,
2739: int imageDataType, int imageFormat, Object imageBuffer,
2740: int depthFormat, Object depthBuffer) {
2741:
2742: GL gl = context(ctx).getGL();
2743: gl.glPixelStorei(GL.GL_PACK_ROW_LENGTH, width);
2744: gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
2745: int yAdjusted = hCanvas - height - ySrcOffset;
2746:
2747: if ((type & Raster.RASTER_COLOR) != 0) {
2748: int oglFormat = 0;
2749: if (imageDataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) {
2750:
2751: switch (imageFormat) {
2752: case ImageComponentRetained.TYPE_BYTE_BGR:
2753: oglFormat = GL.GL_BGR;
2754: break;
2755: case ImageComponentRetained.TYPE_BYTE_RGB:
2756: oglFormat = GL.GL_RGB;
2757: break;
2758: case ImageComponentRetained.TYPE_BYTE_ABGR:
2759: if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here!
2760: oglFormat = GL.GL_ABGR_EXT;
2761: } else {
2762: assert false;
2763: return;
2764: }
2765: break;
2766: case ImageComponentRetained.TYPE_BYTE_RGBA:
2767: // all RGB types are stored as RGBA
2768: oglFormat = GL.GL_RGBA;
2769: break;
2770: case ImageComponentRetained.TYPE_BYTE_LA:
2771: // all LA types are stored as LA8
2772: oglFormat = GL.GL_LUMINANCE_ALPHA;
2773: break;
2774: case ImageComponentRetained.TYPE_BYTE_GRAY:
2775: case ImageComponentRetained.TYPE_USHORT_GRAY:
2776: case ImageComponentRetained.TYPE_INT_BGR:
2777: case ImageComponentRetained.TYPE_INT_RGB:
2778: case ImageComponentRetained.TYPE_INT_ARGB:
2779: default:
2780: assert false;
2781: return;
2782: }
2783:
2784: gl.glReadPixels(xSrcOffset, yAdjusted, width, height,
2785: oglFormat, GL.GL_UNSIGNED_BYTE, ByteBuffer
2786: .wrap((byte[]) imageBuffer));
2787:
2788: } else if (imageDataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) {
2789: int intType = GL.GL_UNSIGNED_INT_8_8_8_8;
2790: boolean forceAlphaToOne = false;
2791:
2792: switch (imageFormat) {
2793: /* GL_BGR */
2794: case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
2795: oglFormat = GL.GL_RGBA;
2796: intType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
2797: forceAlphaToOne = true;
2798: break;
2799: case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
2800: forceAlphaToOne = true;
2801: /* Fall through to next case */
2802: case ImageComponentRetained.TYPE_INT_ARGB:
2803: oglFormat = GL.GL_BGRA;
2804: intType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
2805: break;
2806: /* This method only supports 3 and 4 components formats and INT types. */
2807: case ImageComponentRetained.TYPE_BYTE_LA:
2808: case ImageComponentRetained.TYPE_BYTE_GRAY:
2809: case ImageComponentRetained.TYPE_USHORT_GRAY:
2810: case ImageComponentRetained.TYPE_BYTE_BGR:
2811: case ImageComponentRetained.TYPE_BYTE_RGB:
2812: case ImageComponentRetained.TYPE_BYTE_RGBA:
2813: case ImageComponentRetained.TYPE_BYTE_ABGR:
2814: default:
2815: assert false;
2816: return;
2817: }
2818:
2819: /* Force Alpha to 1.0 if needed */
2820: if (forceAlphaToOne) {
2821: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
2822: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
2823: }
2824:
2825: gl.glReadPixels(xSrcOffset, yAdjusted, width, height,
2826: oglFormat, intType, IntBuffer
2827: .wrap((int[]) imageBuffer));
2828:
2829: /* Restore Alpha scale and bias */
2830: if (forceAlphaToOne) {
2831: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
2832: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
2833: }
2834:
2835: } else {
2836: assert false;
2837: }
2838: }
2839:
2840: if ((type & Raster.RASTER_DEPTH) != 0) {
2841:
2842: if (depthFormat == DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT) {
2843: // yOffset is adjusted for OpenGL - Y upward
2844: gl.glReadPixels(xSrcOffset, yAdjusted, width, height,
2845: GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT,
2846: IntBuffer.wrap((int[]) depthBuffer));
2847: } else {
2848: // DEPTH_COMPONENT_TYPE_FLOAT
2849: // yOffset is adjusted for OpenGL - Y upward
2850: gl.glReadPixels(xSrcOffset, yAdjusted, width, height,
2851: GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, FloatBuffer
2852: .wrap((float[]) depthBuffer));
2853: }
2854: }
2855:
2856: }
2857:
2858: // ---------------------------------------------------------------------
2859:
2860: //
2861: // CgShaderProgramRetained methods
2862: //
2863:
2864: // ShaderAttributeValue methods
2865:
2866: ShaderError setCgUniform1i(Context ctx,
2867: ShaderProgramId shaderProgramId,
2868: ShaderAttrLoc uniformLocation, int value) {
2869: if (VERBOSE)
2870: System.err.println("JoglPipeline.setCgUniform1i()");
2871:
2872: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
2873: if (param.vParam() != null) {
2874: CgGL.cgSetParameter1i(param.vParam(), value);
2875: }
2876:
2877: if (param.fParam() != null) {
2878: CgGL.cgSetParameter1i(param.fParam(), value);
2879: }
2880:
2881: return null;
2882: }
2883:
2884: ShaderError setCgUniform1f(Context ctx,
2885: ShaderProgramId shaderProgramId,
2886: ShaderAttrLoc uniformLocation, float value) {
2887: if (VERBOSE)
2888: System.err.println("JoglPipeline.setCgUniform1f()");
2889:
2890: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
2891: if (param.vParam() != null) {
2892: CgGL.cgSetParameter1f(param.vParam(), value);
2893: }
2894:
2895: if (param.fParam() != null) {
2896: CgGL.cgSetParameter1f(param.fParam(), value);
2897: }
2898:
2899: return null;
2900: }
2901:
2902: ShaderError setCgUniform2i(Context ctx,
2903: ShaderProgramId shaderProgramId,
2904: ShaderAttrLoc uniformLocation, int[] value) {
2905: if (VERBOSE)
2906: System.err.println("JoglPipeline.setCgUniform2i()");
2907:
2908: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
2909: if (param.vParam() != null) {
2910: CgGL.cgSetParameter2i(param.vParam(), value[0], value[1]);
2911: }
2912:
2913: if (param.fParam() != null) {
2914: CgGL.cgSetParameter2i(param.fParam(), value[0], value[1]);
2915: }
2916:
2917: return null;
2918: }
2919:
2920: ShaderError setCgUniform2f(Context ctx,
2921: ShaderProgramId shaderProgramId,
2922: ShaderAttrLoc uniformLocation, float[] value) {
2923: if (VERBOSE)
2924: System.err.println("JoglPipeline.setCgUniform2f()");
2925:
2926: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
2927: if (param.vParam() != null) {
2928: CgGL.cgSetParameter2f(param.vParam(), value[0], value[1]);
2929: }
2930:
2931: if (param.fParam() != null) {
2932: CgGL.cgSetParameter2f(param.fParam(), value[0], value[1]);
2933: }
2934:
2935: return null;
2936: }
2937:
2938: ShaderError setCgUniform3i(Context ctx,
2939: ShaderProgramId shaderProgramId,
2940: ShaderAttrLoc uniformLocation, int[] value) {
2941: if (VERBOSE)
2942: System.err.println("JoglPipeline.setCgUniform3i()");
2943:
2944: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
2945: if (param.vParam() != null) {
2946: CgGL.cgSetParameter3i(param.vParam(), value[0], value[1],
2947: value[2]);
2948: }
2949:
2950: if (param.fParam() != null) {
2951: CgGL.cgSetParameter3i(param.fParam(), value[0], value[1],
2952: value[2]);
2953: }
2954:
2955: return null;
2956: }
2957:
2958: ShaderError setCgUniform3f(Context ctx,
2959: ShaderProgramId shaderProgramId,
2960: ShaderAttrLoc uniformLocation, float[] value) {
2961: if (VERBOSE)
2962: System.err.println("JoglPipeline.setCgUniform3f()");
2963:
2964: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
2965: if (param.vParam() != null) {
2966: CgGL.cgSetParameter3f(param.vParam(), value[0], value[1],
2967: value[2]);
2968: }
2969:
2970: if (param.fParam() != null) {
2971: CgGL.cgSetParameter3f(param.fParam(), value[0], value[1],
2972: value[2]);
2973: }
2974:
2975: return null;
2976: }
2977:
2978: ShaderError setCgUniform4i(Context ctx,
2979: ShaderProgramId shaderProgramId,
2980: ShaderAttrLoc uniformLocation, int[] value) {
2981: if (VERBOSE)
2982: System.err.println("JoglPipeline.setCgUniform4i()");
2983:
2984: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
2985: if (param.vParam() != null) {
2986: CgGL.cgSetParameter4i(param.vParam(), value[0], value[1],
2987: value[2], value[3]);
2988: }
2989:
2990: if (param.fParam() != null) {
2991: CgGL.cgSetParameter4i(param.fParam(), value[0], value[1],
2992: value[2], value[3]);
2993: }
2994:
2995: return null;
2996: }
2997:
2998: ShaderError setCgUniform4f(Context ctx,
2999: ShaderProgramId shaderProgramId,
3000: ShaderAttrLoc uniformLocation, float[] value) {
3001: if (VERBOSE)
3002: System.err.println("JoglPipeline.setCgUniform4f()");
3003:
3004: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3005: if (param.vParam() != null) {
3006: CgGL.cgSetParameter4f(param.vParam(), value[0], value[1],
3007: value[2], value[3]);
3008: }
3009:
3010: if (param.fParam() != null) {
3011: CgGL.cgSetParameter4f(param.fParam(), value[0], value[1],
3012: value[2], value[3]);
3013: }
3014:
3015: return null;
3016: }
3017:
3018: ShaderError setCgUniformMatrix3f(Context ctx,
3019: ShaderProgramId shaderProgramId,
3020: ShaderAttrLoc uniformLocation, float[] value) {
3021: if (VERBOSE)
3022: System.err.println("JoglPipeline.setCgUniformMatrix3f()");
3023:
3024: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3025: if (param.vParam() != null) {
3026: CgGL.cgGLSetMatrixParameterfr(param.vParam(), value, 0);
3027: }
3028:
3029: if (param.fParam() != null) {
3030: CgGL.cgGLSetMatrixParameterfr(param.fParam(), value, 0);
3031: }
3032:
3033: return null;
3034: }
3035:
3036: ShaderError setCgUniformMatrix4f(Context ctx,
3037: ShaderProgramId shaderProgramId,
3038: ShaderAttrLoc uniformLocation, float[] value) {
3039: if (VERBOSE)
3040: System.err.println("JoglPipeline.setCgUniformMatrix4f()");
3041:
3042: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3043: if (param.vParam() != null) {
3044: CgGL.cgGLSetMatrixParameterfr(param.vParam(), value, 0);
3045: }
3046:
3047: if (param.fParam() != null) {
3048: CgGL.cgGLSetMatrixParameterfr(param.fParam(), value, 0);
3049: }
3050:
3051: return null;
3052: }
3053:
3054: // ShaderAttributeArray methods
3055:
3056: ShaderError setCgUniform1iArray(Context ctx,
3057: ShaderProgramId shaderProgramId,
3058: ShaderAttrLoc uniformLocation, int numElements, int[] value) {
3059: if (VERBOSE)
3060: System.err.println("JoglPipeline.setCgUniform1iArray()");
3061:
3062: float[] fval = new float[value.length];
3063: for (int i = 0; i < value.length; i++) {
3064: fval[i] = value[i];
3065: }
3066:
3067: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3068: if (param.vParam() != null) {
3069: CgGL.cgGLSetParameterArray1f(param.vParam(), 0,
3070: numElements, fval, 0);
3071: }
3072:
3073: if (param.fParam() != null) {
3074: CgGL.cgGLSetParameterArray1f(param.fParam(), 0,
3075: numElements, fval, 0);
3076: }
3077:
3078: return null;
3079: }
3080:
3081: ShaderError setCgUniform1fArray(Context ctx,
3082: ShaderProgramId shaderProgramId,
3083: ShaderAttrLoc uniformLocation, int numElements,
3084: float[] value) {
3085: if (VERBOSE)
3086: System.err.println("JoglPipeline.setCgUniform1fArray()");
3087:
3088: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3089: if (param.vParam() != null) {
3090: CgGL.cgGLSetParameterArray1f(param.vParam(), 0,
3091: numElements, value, 0);
3092: }
3093:
3094: if (param.fParam() != null) {
3095: CgGL.cgGLSetParameterArray1f(param.fParam(), 0,
3096: numElements, value, 0);
3097: }
3098:
3099: return null;
3100: }
3101:
3102: ShaderError setCgUniform2iArray(Context ctx,
3103: ShaderProgramId shaderProgramId,
3104: ShaderAttrLoc uniformLocation, int numElements, int[] value) {
3105: if (VERBOSE)
3106: System.err.println("JoglPipeline.setCgUniform2iArray()");
3107:
3108: float[] fval = new float[value.length];
3109: for (int i = 0; i < value.length; i++) {
3110: fval[i] = value[i];
3111: }
3112:
3113: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3114: if (param.vParam() != null) {
3115: CgGL.cgGLSetParameterArray2f(param.vParam(), 0,
3116: numElements, fval, 0);
3117: }
3118:
3119: if (param.fParam() != null) {
3120: CgGL.cgGLSetParameterArray2f(param.fParam(), 0,
3121: numElements, fval, 0);
3122: }
3123:
3124: return null;
3125: }
3126:
3127: ShaderError setCgUniform2fArray(Context ctx,
3128: ShaderProgramId shaderProgramId,
3129: ShaderAttrLoc uniformLocation, int numElements,
3130: float[] value) {
3131: if (VERBOSE)
3132: System.err.println("JoglPipeline.setCgUniform2fArray()");
3133:
3134: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3135: if (param.vParam() != null) {
3136: CgGL.cgGLSetParameterArray2f(param.vParam(), 0,
3137: numElements, value, 0);
3138: }
3139:
3140: if (param.fParam() != null) {
3141: CgGL.cgGLSetParameterArray2f(param.fParam(), 0,
3142: numElements, value, 0);
3143: }
3144:
3145: return null;
3146: }
3147:
3148: ShaderError setCgUniform3iArray(Context ctx,
3149: ShaderProgramId shaderProgramId,
3150: ShaderAttrLoc uniformLocation, int numElements, int[] value) {
3151: if (VERBOSE)
3152: System.err.println("JoglPipeline.setCgUniform3iArray()");
3153:
3154: float[] fval = new float[value.length];
3155: for (int i = 0; i < value.length; i++) {
3156: fval[i] = value[i];
3157: }
3158:
3159: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3160: if (param.vParam() != null) {
3161: CgGL.cgGLSetParameterArray3f(param.vParam(), 0,
3162: numElements, fval, 0);
3163: }
3164:
3165: if (param.fParam() != null) {
3166: CgGL.cgGLSetParameterArray3f(param.fParam(), 0,
3167: numElements, fval, 0);
3168: }
3169:
3170: return null;
3171: }
3172:
3173: ShaderError setCgUniform3fArray(Context ctx,
3174: ShaderProgramId shaderProgramId,
3175: ShaderAttrLoc uniformLocation, int numElements,
3176: float[] value) {
3177: if (VERBOSE)
3178: System.err.println("JoglPipeline.setCgUniform3fArray()");
3179:
3180: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3181: if (param.vParam() != null) {
3182: CgGL.cgGLSetParameterArray2f(param.vParam(), 0,
3183: numElements, value, 0);
3184: }
3185:
3186: if (param.fParam() != null) {
3187: CgGL.cgGLSetParameterArray2f(param.fParam(), 0,
3188: numElements, value, 0);
3189: }
3190:
3191: return null;
3192: }
3193:
3194: ShaderError setCgUniform4iArray(Context ctx,
3195: ShaderProgramId shaderProgramId,
3196: ShaderAttrLoc uniformLocation, int numElements, int[] value) {
3197: if (VERBOSE)
3198: System.err.println("JoglPipeline.setCgUniform4iArray()");
3199:
3200: float[] fval = new float[value.length];
3201: for (int i = 0; i < value.length; i++) {
3202: fval[i] = value[i];
3203: }
3204:
3205: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3206: if (param.vParam() != null) {
3207: CgGL.cgGLSetParameterArray4f(param.vParam(), 0,
3208: numElements, fval, 0);
3209: }
3210:
3211: if (param.fParam() != null) {
3212: CgGL.cgGLSetParameterArray4f(param.fParam(), 0,
3213: numElements, fval, 0);
3214: }
3215:
3216: return null;
3217: }
3218:
3219: ShaderError setCgUniform4fArray(Context ctx,
3220: ShaderProgramId shaderProgramId,
3221: ShaderAttrLoc uniformLocation, int numElements,
3222: float[] value) {
3223: if (VERBOSE)
3224: System.err.println("JoglPipeline.setCgUniform4fArray()");
3225:
3226: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3227: if (param.vParam() != null) {
3228: CgGL.cgGLSetParameterArray2f(param.vParam(), 0,
3229: numElements, value, 0);
3230: }
3231:
3232: if (param.fParam() != null) {
3233: CgGL.cgGLSetParameterArray2f(param.fParam(), 0,
3234: numElements, value, 0);
3235: }
3236:
3237: return null;
3238: }
3239:
3240: ShaderError setCgUniformMatrix3fArray(Context ctx,
3241: ShaderProgramId shaderProgramId,
3242: ShaderAttrLoc uniformLocation, int numElements,
3243: float[] value) {
3244: if (VERBOSE)
3245: System.err
3246: .println("JoglPipeline.setCgUniformMatrix3fArray()");
3247:
3248: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3249: if (param.vParam() != null) {
3250: CgGL.cgGLSetMatrixParameterArrayfr(param.vParam(), 0,
3251: numElements, value, 0);
3252: }
3253:
3254: if (param.fParam() != null) {
3255: CgGL.cgGLSetMatrixParameterArrayfr(param.fParam(), 0,
3256: numElements, value, 0);
3257: }
3258:
3259: return null;
3260: }
3261:
3262: ShaderError setCgUniformMatrix4fArray(Context ctx,
3263: ShaderProgramId shaderProgramId,
3264: ShaderAttrLoc uniformLocation, int numElements,
3265: float[] value) {
3266: if (VERBOSE)
3267: System.err
3268: .println("JoglPipeline.setCgUniformMatrix4fArray()");
3269:
3270: JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
3271: if (param.vParam() != null) {
3272: CgGL.cgGLSetMatrixParameterArrayfr(param.vParam(), 0,
3273: numElements, value, 0);
3274: }
3275:
3276: if (param.fParam() != null) {
3277: CgGL.cgGLSetMatrixParameterArrayfr(param.fParam(), 0,
3278: numElements, value, 0);
3279: }
3280:
3281: return null;
3282: }
3283:
3284: // interfaces for shader compilation, etc.
3285: ShaderError createCgShader(Context ctx, int shaderType,
3286: ShaderId[] shaderId) {
3287: if (VERBOSE)
3288: System.err.println("JoglPipeline.createCgShader()");
3289:
3290: JoglContext jctx = (JoglContext) ctx;
3291: JoglCgShaderInfo info = new JoglCgShaderInfo();
3292: info.setJ3DShaderType(shaderType);
3293: if (shaderType == Shader.SHADER_TYPE_VERTEX) {
3294: info.setShaderProfile(jctx.getCgVertexProfile());
3295: } else if (shaderType == Shader.SHADER_TYPE_FRAGMENT) {
3296: info.setShaderProfile(jctx.getCgFragmentProfile());
3297: } else {
3298: throw new AssertionError("unrecognized shaderType "
3299: + shaderType);
3300: }
3301: shaderId[0] = info;
3302: return null;
3303: }
3304:
3305: ShaderError destroyCgShader(Context ctx, ShaderId shaderId) {
3306: if (VERBOSE)
3307: System.err.println("JoglPipeline.destroyCgShader()");
3308:
3309: JoglCgShaderInfo info = (JoglCgShaderInfo) shaderId;
3310: CGprogram program = info.getCgShader();
3311: if (program != null) {
3312: CgGL.cgDestroyProgram(program);
3313: }
3314: return null;
3315: }
3316:
3317: ShaderError compileCgShader(Context ctx, ShaderId shaderId,
3318: String programString) {
3319: if (VERBOSE)
3320: System.err.println("JoglPipeline.compileCgShader()");
3321:
3322: if (programString == null)
3323: throw new AssertionError("shader program string is null");
3324: JoglCgShaderInfo info = (JoglCgShaderInfo) shaderId;
3325: JoglContext jctx = (JoglContext) ctx;
3326: CGprogram program = CgGL.cgCreateProgram(jctx.getCgContext(),
3327: CgGL.CG_SOURCE, programString, info.getShaderProfile(),
3328: null, null);
3329: int lastError = 0;
3330: if ((lastError = CgGL.cgGetError()) != 0) {
3331: ShaderError err = new ShaderError(
3332: ShaderError.COMPILE_ERROR,
3333: "Cg shader compile error");
3334: err.setDetailMessage(getCgErrorLog(jctx, lastError));
3335: return err;
3336: }
3337: info.setCgShader(program);
3338: return null;
3339: }
3340:
3341: ShaderError createCgShaderProgram(Context ctx,
3342: ShaderProgramId[] shaderProgramId) {
3343: if (VERBOSE)
3344: System.err.println("JoglPipeline.createCgShaderProgram()");
3345:
3346: JoglCgShaderProgramInfo info = new JoglCgShaderProgramInfo();
3347: shaderProgramId[0] = info;
3348: return null;
3349: }
3350:
3351: ShaderError destroyCgShaderProgram(Context ctx,
3352: ShaderProgramId shaderProgramId) {
3353: if (VERBOSE)
3354: System.err.println("JoglPipeline.destroyCgShaderProgram()");
3355: // Nothing to do in pure Java port
3356: return null;
3357: }
3358:
3359: ShaderError linkCgShaderProgram(Context ctx,
3360: ShaderProgramId shaderProgramId, ShaderId[] shaderIds) {
3361: if (VERBOSE)
3362: System.err.println("JoglPipeline.linkCgShaderProgram()");
3363:
3364: JoglCgShaderProgramInfo shaderProgramInfo = (JoglCgShaderProgramInfo) shaderProgramId;
3365: // NOTE: we assume that the caller has already verified that there
3366: // is at most one vertex program and one fragment program
3367: shaderProgramInfo.setVertexShader(null);
3368: shaderProgramInfo.setFragmentShader(null);
3369: for (int i = 0; i < shaderIds.length; i++) {
3370: JoglCgShaderInfo shader = (JoglCgShaderInfo) shaderIds[i];
3371: if (shader.getJ3DShaderType() == Shader.SHADER_TYPE_VERTEX) {
3372: shaderProgramInfo.setVertexShader(shader);
3373: } else {
3374: shaderProgramInfo.setFragmentShader(shader);
3375: }
3376:
3377: CgGL.cgGLLoadProgram(shader.getCgShader());
3378: int lastError = 0;
3379: if ((lastError = CgGL.cgGetError()) != 0) {
3380: ShaderError err = new ShaderError(
3381: ShaderError.LINK_ERROR,
3382: "Cg shader link/load error");
3383: err.setDetailMessage(getCgErrorLog((JoglContext) ctx,
3384: lastError));
3385: return err;
3386: }
3387:
3388: CgGL.cgGLBindProgram(shader.getCgShader());
3389: if ((lastError = CgGL.cgGetError()) != 0) {
3390: ShaderError err = new ShaderError(
3391: ShaderError.LINK_ERROR,
3392: "Cg shader link/bind error");
3393: err.setDetailMessage(getCgErrorLog((JoglContext) ctx,
3394: lastError));
3395: return err;
3396: }
3397: }
3398:
3399: return null;
3400: }
3401:
3402: void lookupCgVertexAttrNames(Context ctx,
3403: ShaderProgramId shaderProgramId, int numAttrNames,
3404: String[] attrNames, boolean[] errArr) {
3405: if (VERBOSE)
3406: System.err
3407: .println("JoglPipeline.lookupCgVertexAttrNames()");
3408:
3409: JoglCgShaderProgramInfo shaderProgramInfo = (JoglCgShaderProgramInfo) shaderProgramId;
3410: if (shaderProgramInfo.getVertexShader() == null) {
3411: // If there if no vertex shader, no attributes can be looked up, so all fail
3412: for (int i = 0; i < errArr.length; i++) {
3413: errArr[i] = false;
3414: }
3415: return;
3416: }
3417:
3418: shaderProgramInfo
3419: .setVertexAttributes(new CGparameter[numAttrNames]);
3420: for (int i = 0; i < numAttrNames; i++) {
3421: String attrName = attrNames[i];
3422: shaderProgramInfo.getVertexAttributes()[i] = CgGL
3423: .cgGetNamedParameter(shaderProgramInfo
3424: .getVertexShader().getCgShader(), attrName);
3425: if (shaderProgramInfo.getVertexAttributes()[i] == null) {
3426: errArr[i] = true;
3427: }
3428: }
3429: }
3430:
3431: void lookupCgShaderAttrNames(Context ctx,
3432: ShaderProgramId shaderProgramId, int numAttrNames,
3433: String[] attrNames, ShaderAttrLoc[] locArr, int[] typeArr,
3434: int[] sizeArr, boolean[] isArrayArr) {
3435: if (VERBOSE)
3436: System.err
3437: .println("JoglPipeline.lookupCgShaderAttrNames()");
3438:
3439: JoglCgShaderProgramInfo shaderProgramInfo = (JoglCgShaderProgramInfo) shaderProgramId;
3440:
3441: // Set the loc, type, and size arrays to out-of-bounds values
3442: for (int i = 0; i < numAttrNames; i++) {
3443: locArr[i] = null;
3444: typeArr[i] = -1;
3445: sizeArr[i] = -1;
3446: }
3447:
3448: int[] vType = new int[1];
3449: int[] vSize = new int[1];
3450: boolean[] vIsArray = new boolean[1];
3451: int[] fType = new int[1];
3452: int[] fSize = new int[1];
3453: boolean[] fIsArray = new boolean[1];
3454:
3455: boolean err = false;
3456:
3457: // Now lookup the location of each name in the attrNames array
3458: for (int i = 0; i < numAttrNames; i++) {
3459: String attrName = attrNames[i];
3460: // Get uniform attribute location -- note that we need to
3461: // lookup the name in both the vertex and fragment shader
3462: // (although we will generalize it to look at the list of "N"
3463: // shaders). If all parameter locations are NULL, then no
3464: // struct will be allocated and -1 will be stored for this
3465: // attribute. If there is more than one non-NULL parameter,
3466: // then all must be of the same type and dimensionality,
3467: // otherwise an error will be generated and -1 will be stored
3468: // for this attribute. If all non-NULL parameters are of the
3469: // same type and dimensionality, then a struct is allocated
3470: // containing the list of parameters.
3471: //
3472: // When any of the setCgUniform methods are called, the
3473: // attribute will be set for each parameter in the list.
3474: CGparameter vLoc = null;
3475: if (shaderProgramInfo.getVertexShader() != null) {
3476: vLoc = lookupCgParams(shaderProgramInfo
3477: .getVertexShader(), attrName, vType, vSize,
3478: vIsArray);
3479: if (vLoc != null) {
3480: sizeArr[i] = vSize[0];
3481: isArrayArr[i] = vIsArray[0];
3482: typeArr[i] = cgToJ3dType(vType[0]);
3483: }
3484: }
3485:
3486: CGparameter fLoc = null;
3487: if (shaderProgramInfo.getVertexShader() != null) {
3488: fLoc = lookupCgParams(shaderProgramInfo
3489: .getFragmentShader(), attrName, fType, fSize,
3490: fIsArray);
3491: if (fLoc != null) {
3492: sizeArr[i] = fSize[0];
3493: isArrayArr[i] = fIsArray[0];
3494: typeArr[i] = cgToJ3dType(fType[0]);
3495: }
3496: }
3497:
3498: // If the name lookup found an entry in both vertex and
3499: // fragment program, verify that the type and size are the
3500: // same.
3501: if (vLoc != null && fLoc != null) {
3502: if (vType != fType || vSize != fSize
3503: || vIsArray != fIsArray) {
3504: // TODO: the following needs to be propagated to ShaderError
3505: System.err
3506: .println("JAVA 3D : error shader attribute type mismatch: "
3507: + attrName);
3508: System.err.println(" 1 : type = " + vType[0]
3509: + ", size = " + vSize[0] + ", isArray = "
3510: + vIsArray[0]);
3511: System.err.println(" 0 : type = " + fType[0]
3512: + ", size = " + fSize[0] + ", isArray = "
3513: + fIsArray[0]);
3514: err = true;
3515: }
3516: }
3517:
3518: // Report an error if we got a mismatch or if the attribute
3519: // was not found in either the vertex or the fragment program
3520: if (err || (vLoc == null && fLoc == null)) {
3521: // TODO: distinguish between (err) and (vParam and fParam both NULL)
3522: // so we can report a more helpful error message
3523: // locPtr[i] = (jlong)-1;
3524: } else {
3525: // TODO: need to store the cgParamInfo pointers in the
3526: // shader program so we can free them later.
3527: //
3528: // NOTE: WE CURRENTLY HAVE A MEMORY LEAK.
3529: locArr[i] = new JoglCgShaderParameter(vLoc, fLoc);
3530: }
3531: }
3532: }
3533:
3534: ShaderError useCgShaderProgram(Context ctx,
3535: ShaderProgramId shaderProgramId) {
3536: if (VERBOSE)
3537: System.err.println("JoglPipeline.useCgShaderProgram()");
3538:
3539: JoglCgShaderProgramInfo shaderProgramInfo = (JoglCgShaderProgramInfo) shaderProgramId;
3540: JoglContext jctx = (JoglContext) ctx;
3541:
3542: // Disable shader profiles
3543: CgGL.cgGLDisableProfile(jctx.getCgVertexProfile());
3544: CgGL.cgGLDisableProfile(jctx.getCgFragmentProfile());
3545: if (shaderProgramInfo != null) {
3546: if (shaderProgramInfo.getVertexShader() != null) {
3547: CgGL.cgGLBindProgram(shaderProgramInfo
3548: .getVertexShader().getCgShader());
3549: CgGL.cgGLEnableProfile(shaderProgramInfo
3550: .getVertexShader().getShaderProfile());
3551: } else {
3552: CgGL.cgGLUnbindProgram(jctx.getCgVertexProfile());
3553: }
3554:
3555: if (shaderProgramInfo.getFragmentShader() != null) {
3556: CgGL.cgGLBindProgram(shaderProgramInfo
3557: .getFragmentShader().getCgShader());
3558: CgGL.cgGLEnableProfile(shaderProgramInfo
3559: .getFragmentShader().getShaderProfile());
3560: } else {
3561: CgGL.cgGLUnbindProgram(jctx.getCgFragmentProfile());
3562: }
3563: } else {
3564: CgGL.cgGLUnbindProgram(jctx.getCgVertexProfile());
3565: CgGL.cgGLUnbindProgram(jctx.getCgFragmentProfile());
3566: }
3567:
3568: jctx.setShaderProgram(shaderProgramInfo);
3569: return null;
3570: }
3571:
3572: //
3573: // Helper methods for above
3574: //
3575: private String getCgErrorLog(JoglContext ctx, int lastError) {
3576: if (lastError == 0)
3577: throw new AssertionError("lastError == 0");
3578: String errString = CgGL.cgGetErrorString(lastError);
3579: String listing = CgGL.cgGetLastListing(ctx.getCgContext());
3580: return (errString + System.getProperty("line.separator") + listing);
3581: }
3582:
3583: private int cgToJ3dType(int type) {
3584: switch (type) {
3585: case CgGL.CG_BOOL:
3586: case CgGL.CG_BOOL1:
3587: case CgGL.CG_FIXED:
3588: case CgGL.CG_FIXED1:
3589: case CgGL.CG_HALF:
3590: case CgGL.CG_HALF1:
3591: case CgGL.CG_INT:
3592: case CgGL.CG_INT1:
3593: return ShaderAttributeObjectRetained.TYPE_INTEGER;
3594:
3595: // XXXX: add ShaderAttribute support for setting samplers. In the
3596: // mean time, the binding between sampler and texture unit will
3597: // need to be specified in the shader itself (which it already is
3598: // in most example shaders).
3599: //
3600: // case CgGL.CG_SAMPLER2D:
3601: // case CgGL.CG_SAMPLER3D:
3602: // case CgGL.CG_SAMPLERCUBE:
3603:
3604: case CgGL.CG_BOOL2:
3605: case CgGL.CG_FIXED2:
3606: case CgGL.CG_HALF2:
3607: case CgGL.CG_INT2:
3608: return ShaderAttributeObjectRetained.TYPE_TUPLE2I;
3609:
3610: case CgGL.CG_BOOL3:
3611: case CgGL.CG_FIXED3:
3612: case CgGL.CG_HALF3:
3613: case CgGL.CG_INT3:
3614: return ShaderAttributeObjectRetained.TYPE_TUPLE3I;
3615:
3616: case CgGL.CG_BOOL4:
3617: case CgGL.CG_FIXED4:
3618: case CgGL.CG_HALF4:
3619: case CgGL.CG_INT4:
3620: return ShaderAttributeObjectRetained.TYPE_TUPLE4I;
3621:
3622: case CgGL.CG_FLOAT:
3623: case CgGL.CG_FLOAT1:
3624: return ShaderAttributeObjectRetained.TYPE_FLOAT;
3625:
3626: case CgGL.CG_FLOAT2:
3627: return ShaderAttributeObjectRetained.TYPE_TUPLE2F;
3628:
3629: case CgGL.CG_FLOAT3:
3630: return ShaderAttributeObjectRetained.TYPE_TUPLE3F;
3631:
3632: case CgGL.CG_FLOAT4:
3633: return ShaderAttributeObjectRetained.TYPE_TUPLE4F;
3634:
3635: case CgGL.CG_FLOAT3x3:
3636: return ShaderAttributeObjectRetained.TYPE_MATRIX3F;
3637:
3638: case CgGL.CG_FLOAT4x4:
3639: return ShaderAttributeObjectRetained.TYPE_MATRIX4F;
3640:
3641: // Java 3D does not support the following sampler types:
3642: //
3643: // case CgGL.CG_SAMPLER1D:
3644: // case CgGL.CG_SAMPLERRECT:
3645: }
3646:
3647: return -1;
3648: }
3649:
3650: private CGparameter lookupCgParams(JoglCgShaderInfo shader,
3651: String attrNameString, int[] type, int[] size,
3652: boolean[] isArray) {
3653: CGparameter loc = CgGL.cgGetNamedParameter(
3654: shader.getCgShader(), attrNameString);
3655: if (loc != null) {
3656: type[0] = CgGL.cgGetParameterType(loc);
3657: if (type[0] == CgGL.CG_ARRAY) {
3658: isArray[0] = true;
3659: size[0] = CgGL.cgGetArraySize(loc, 0);
3660: CGparameter firstElem = CgGL
3661: .cgGetArrayParameter(loc, 0);
3662: type[0] = CgGL.cgGetParameterType(firstElem);
3663: } else {
3664: isArray[0] = false;
3665: size[0] = 1;
3666: }
3667: }
3668: return loc;
3669: }
3670:
3671: // ---------------------------------------------------------------------
3672:
3673: //
3674: // GLSLShaderProgramRetained methods
3675: //
3676:
3677: // ShaderAttributeValue methods
3678:
3679: ShaderError setGLSLUniform1i(Context ctx,
3680: ShaderProgramId shaderProgramId,
3681: ShaderAttrLoc uniformLocation, int value) {
3682: if (VERBOSE)
3683: System.err.println("JoglPipeline.setGLSLUniform1i()");
3684:
3685: context(ctx).getGL().glUniform1iARB(unbox(uniformLocation),
3686: value);
3687: return null;
3688: }
3689:
3690: ShaderError setGLSLUniform1f(Context ctx,
3691: ShaderProgramId shaderProgramId,
3692: ShaderAttrLoc uniformLocation, float value) {
3693: if (VERBOSE)
3694: System.err.println("JoglPipeline.setGLSLUniform1f()");
3695:
3696: context(ctx).getGL().glUniform1fARB(unbox(uniformLocation),
3697: value);
3698: return null;
3699: }
3700:
3701: ShaderError setGLSLUniform2i(Context ctx,
3702: ShaderProgramId shaderProgramId,
3703: ShaderAttrLoc uniformLocation, int[] value) {
3704: if (VERBOSE)
3705: System.err.println("JoglPipeline.setGLSLUniform2i()");
3706:
3707: context(ctx).getGL().glUniform2iARB(unbox(uniformLocation),
3708: value[0], value[1]);
3709: return null;
3710: }
3711:
3712: ShaderError setGLSLUniform2f(Context ctx,
3713: ShaderProgramId shaderProgramId,
3714: ShaderAttrLoc uniformLocation, float[] value) {
3715: if (VERBOSE)
3716: System.err.println("JoglPipeline.setGLSLUniform2f()");
3717:
3718: context(ctx).getGL().glUniform2fARB(unbox(uniformLocation),
3719: value[0], value[1]);
3720: return null;
3721: }
3722:
3723: ShaderError setGLSLUniform3i(Context ctx,
3724: ShaderProgramId shaderProgramId,
3725: ShaderAttrLoc uniformLocation, int[] value) {
3726: if (VERBOSE)
3727: System.err.println("JoglPipeline.setGLSLUniform3i()");
3728:
3729: context(ctx).getGL().glUniform3iARB(unbox(uniformLocation),
3730: value[0], value[1], value[2]);
3731: return null;
3732: }
3733:
3734: ShaderError setGLSLUniform3f(Context ctx,
3735: ShaderProgramId shaderProgramId,
3736: ShaderAttrLoc uniformLocation, float[] value) {
3737: if (VERBOSE)
3738: System.err.println("JoglPipeline.setGLSLUniform3f()");
3739:
3740: context(ctx).getGL().glUniform3fARB(unbox(uniformLocation),
3741: value[0], value[1], value[2]);
3742: return null;
3743: }
3744:
3745: ShaderError setGLSLUniform4i(Context ctx,
3746: ShaderProgramId shaderProgramId,
3747: ShaderAttrLoc uniformLocation, int[] value) {
3748: if (VERBOSE)
3749: System.err.println("JoglPipeline.setGLSLUniform4i()");
3750:
3751: context(ctx).getGL().glUniform4iARB(unbox(uniformLocation),
3752: value[0], value[1], value[2], value[3]);
3753: return null;
3754: }
3755:
3756: ShaderError setGLSLUniform4f(Context ctx,
3757: ShaderProgramId shaderProgramId,
3758: ShaderAttrLoc uniformLocation, float[] value) {
3759: if (VERBOSE)
3760: System.err.println("JoglPipeline.setGLSLUniform4f()");
3761:
3762: context(ctx).getGL().glUniform4fARB(unbox(uniformLocation),
3763: value[0], value[1], value[2], value[3]);
3764: return null;
3765: }
3766:
3767: ShaderError setGLSLUniformMatrix3f(Context ctx,
3768: ShaderProgramId shaderProgramId,
3769: ShaderAttrLoc uniformLocation, float[] value) {
3770: if (VERBOSE)
3771: System.err.println("JoglPipeline.setGLSLUniformMatrix3f()");
3772:
3773: // Load attribute
3774: // transpose is true : each matrix is supplied in row major order
3775: context(ctx).getGL().glUniformMatrix3fvARB(
3776: unbox(uniformLocation), 1, true, value, 0);
3777: return null;
3778: }
3779:
3780: ShaderError setGLSLUniformMatrix4f(Context ctx,
3781: ShaderProgramId shaderProgramId,
3782: ShaderAttrLoc uniformLocation, float[] value) {
3783: if (VERBOSE)
3784: System.err.println("JoglPipeline.setGLSLUniformMatrix4f()");
3785:
3786: // Load attribute
3787: // transpose is true : each matrix is supplied in row major order
3788: context(ctx).getGL().glUniformMatrix4fvARB(
3789: unbox(uniformLocation), 1, true, value, 0);
3790: return null;
3791: }
3792:
3793: // ShaderAttributeArray methods
3794:
3795: ShaderError setGLSLUniform1iArray(Context ctx,
3796: ShaderProgramId shaderProgramId,
3797: ShaderAttrLoc uniformLocation, int numElements, int[] value) {
3798: if (VERBOSE)
3799: System.err.println("JoglPipeline.setGLSLUniform1iArray()");
3800:
3801: context(ctx).getGL().glUniform1ivARB(unbox(uniformLocation),
3802: numElements, value, 0);
3803: return null;
3804: }
3805:
3806: ShaderError setGLSLUniform1fArray(Context ctx,
3807: ShaderProgramId shaderProgramId,
3808: ShaderAttrLoc uniformLocation, int numElements,
3809: float[] value) {
3810: if (VERBOSE)
3811: System.err.println("JoglPipeline.setGLSLUniform1fArray()");
3812:
3813: context(ctx).getGL().glUniform1fvARB(unbox(uniformLocation),
3814: numElements, value, 0);
3815: return null;
3816: }
3817:
3818: ShaderError setGLSLUniform2iArray(Context ctx,
3819: ShaderProgramId shaderProgramId,
3820: ShaderAttrLoc uniformLocation, int numElements, int[] value) {
3821: if (VERBOSE)
3822: System.err.println("JoglPipeline.setGLSLUniform2iArray()");
3823:
3824: context(ctx).getGL().glUniform2ivARB(unbox(uniformLocation),
3825: numElements, value, 0);
3826: return null;
3827: }
3828:
3829: ShaderError setGLSLUniform2fArray(Context ctx,
3830: ShaderProgramId shaderProgramId,
3831: ShaderAttrLoc uniformLocation, int numElements,
3832: float[] value) {
3833: if (VERBOSE)
3834: System.err.println("JoglPipeline.setGLSLUniform2fArray()");
3835:
3836: context(ctx).getGL().glUniform2fvARB(unbox(uniformLocation),
3837: numElements, value, 0);
3838: return null;
3839: }
3840:
3841: ShaderError setGLSLUniform3iArray(Context ctx,
3842: ShaderProgramId shaderProgramId,
3843: ShaderAttrLoc uniformLocation, int numElements, int[] value) {
3844: if (VERBOSE)
3845: System.err.println("JoglPipeline.setGLSLUniform3iArray()");
3846:
3847: context(ctx).getGL().glUniform3ivARB(unbox(uniformLocation),
3848: numElements, value, 0);
3849: return null;
3850: }
3851:
3852: ShaderError setGLSLUniform3fArray(Context ctx,
3853: ShaderProgramId shaderProgramId,
3854: ShaderAttrLoc uniformLocation, int numElements,
3855: float[] value) {
3856: if (VERBOSE)
3857: System.err.println("JoglPipeline.setGLSLUniform3fArray()");
3858:
3859: context(ctx).getGL().glUniform3fvARB(unbox(uniformLocation),
3860: numElements, value, 0);
3861: return null;
3862: }
3863:
3864: ShaderError setGLSLUniform4iArray(Context ctx,
3865: ShaderProgramId shaderProgramId,
3866: ShaderAttrLoc uniformLocation, int numElements, int[] value) {
3867: if (VERBOSE)
3868: System.err.println("JoglPipeline.setGLSLUniform4iArray()");
3869:
3870: context(ctx).getGL().glUniform4ivARB(unbox(uniformLocation),
3871: numElements, value, 0);
3872: return null;
3873: }
3874:
3875: ShaderError setGLSLUniform4fArray(Context ctx,
3876: ShaderProgramId shaderProgramId,
3877: ShaderAttrLoc uniformLocation, int numElements,
3878: float[] value) {
3879: if (VERBOSE)
3880: System.err.println("JoglPipeline.setGLSLUniform4fArray()");
3881:
3882: context(ctx).getGL().glUniform4fvARB(unbox(uniformLocation),
3883: numElements, value, 0);
3884: return null;
3885: }
3886:
3887: ShaderError setGLSLUniformMatrix3fArray(Context ctx,
3888: ShaderProgramId shaderProgramId,
3889: ShaderAttrLoc uniformLocation, int numElements,
3890: float[] value) {
3891: if (VERBOSE)
3892: System.err
3893: .println("JoglPipeline.setGLSLUniformMatrix3fArray()");
3894:
3895: // Load attribute
3896: // transpose is true : each matrix is supplied in row major order
3897: context(ctx).getGL().glUniformMatrix3fvARB(
3898: unbox(uniformLocation), numElements, true, value, 0);
3899: return null;
3900: }
3901:
3902: ShaderError setGLSLUniformMatrix4fArray(Context ctx,
3903: ShaderProgramId shaderProgramId,
3904: ShaderAttrLoc uniformLocation, int numElements,
3905: float[] value) {
3906: if (VERBOSE)
3907: System.err
3908: .println("JoglPipeline.setGLSLUniformMatrix4fArray()");
3909:
3910: // Load attribute
3911: // transpose is true : each matrix is supplied in row major order
3912: context(ctx).getGL().glUniformMatrix4fvARB(
3913: unbox(uniformLocation), numElements, true, value, 0);
3914: return null;
3915: }
3916:
3917: // interfaces for shader compilation, etc.
3918: ShaderError createGLSLShader(Context ctx, int shaderType,
3919: ShaderId[] shaderId) {
3920: if (VERBOSE)
3921: System.err.println("JoglPipeline.createGLSLShader()");
3922:
3923: GL gl = context(ctx).getGL();
3924:
3925: int shaderHandle = 0;
3926: if (shaderType == Shader.SHADER_TYPE_VERTEX) {
3927: shaderHandle = gl
3928: .glCreateShaderObjectARB(GL.GL_VERTEX_SHADER_ARB);
3929: } else if (shaderType == Shader.SHADER_TYPE_FRAGMENT) {
3930: shaderHandle = gl
3931: .glCreateShaderObjectARB(GL.GL_FRAGMENT_SHADER_ARB);
3932: }
3933:
3934: if (shaderHandle == 0) {
3935: return new ShaderError(ShaderError.COMPILE_ERROR,
3936: "Unable to create native shader object");
3937: }
3938:
3939: shaderId[0] = new JoglShaderObject(shaderHandle);
3940: return null;
3941: }
3942:
3943: ShaderError destroyGLSLShader(Context ctx, ShaderId shaderId) {
3944: if (VERBOSE)
3945: System.err.println("JoglPipeline.destroyGLSLShader()");
3946:
3947: GL gl = context(ctx).getGL();
3948: gl.glDeleteObjectARB(unbox(shaderId));
3949: return null;
3950: }
3951:
3952: ShaderError compileGLSLShader(Context ctx, ShaderId shaderId,
3953: String program) {
3954: if (VERBOSE)
3955: System.err.println("JoglPipeline.compileGLSLShader()");
3956:
3957: int id = unbox(shaderId);
3958: if (id == 0) {
3959: throw new AssertionError("shaderId == 0");
3960: }
3961:
3962: if (program == null) {
3963: throw new AssertionError("shader program string is null");
3964: }
3965:
3966: GL gl = context(ctx).getGL();
3967: gl.glShaderSourceARB(id, 1, new String[] { program }, null, 0);
3968: gl.glCompileShaderARB(id);
3969: int[] status = new int[1];
3970: gl.glGetObjectParameterivARB(id,
3971: GL.GL_OBJECT_COMPILE_STATUS_ARB, status, 0);
3972: if (status[0] == 0) {
3973: String detailMsg = getInfoLog(gl, id);
3974: ShaderError res = new ShaderError(
3975: ShaderError.COMPILE_ERROR,
3976: "GLSL shader compile error");
3977: res.setDetailMessage(detailMsg);
3978: return res;
3979: }
3980: return null;
3981: }
3982:
3983: ShaderError createGLSLShaderProgram(Context ctx,
3984: ShaderProgramId[] shaderProgramId) {
3985: if (VERBOSE)
3986: System.err
3987: .println("JoglPipeline.createGLSLShaderProgram()");
3988:
3989: GL gl = context(ctx).getGL();
3990:
3991: int shaderProgramHandle = gl.glCreateProgramObjectARB();
3992: if (shaderProgramHandle == 0) {
3993: return new ShaderError(ShaderError.LINK_ERROR,
3994: "Unable to create native shader program object");
3995: }
3996: shaderProgramId[0] = new JoglShaderObject(shaderProgramHandle);
3997: return null;
3998: }
3999:
4000: ShaderError destroyGLSLShaderProgram(Context ctx,
4001: ShaderProgramId shaderProgramId) {
4002: if (VERBOSE)
4003: System.err
4004: .println("JoglPipeline.destroyGLSLShaderProgram()");
4005: context(ctx).getGL().glDeleteObjectARB(unbox(shaderProgramId));
4006: return null;
4007: }
4008:
4009: ShaderError linkGLSLShaderProgram(Context ctx,
4010: ShaderProgramId shaderProgramId, ShaderId[] shaderIds) {
4011: if (VERBOSE)
4012: System.err.println("JoglPipeline.linkGLSLShaderProgram()");
4013:
4014: GL gl = context(ctx).getGL();
4015: int id = unbox(shaderProgramId);
4016: for (int i = 0; i < shaderIds.length; i++) {
4017: gl.glAttachObjectARB(id, unbox(shaderIds[i]));
4018: }
4019: gl.glLinkProgramARB(id);
4020: int[] status = new int[1];
4021: gl.glGetObjectParameterivARB(id, GL.GL_OBJECT_LINK_STATUS_ARB,
4022: status, 0);
4023: if (status[0] == 0) {
4024: String detailMsg = getInfoLog(gl, id);
4025: ShaderError res = new ShaderError(ShaderError.LINK_ERROR,
4026: "GLSL shader program link error");
4027: res.setDetailMessage(detailMsg);
4028: return res;
4029: }
4030: return null;
4031: }
4032:
4033: ShaderError bindGLSLVertexAttrName(Context ctx,
4034: ShaderProgramId shaderProgramId, String attrName,
4035: int attrIndex) {
4036: if (VERBOSE)
4037: System.err.println("JoglPipeline.bindGLSLVertexAttrName()");
4038:
4039: JoglContext jctx = (JoglContext) ctx;
4040: context(ctx).getGL().glBindAttribLocationARB(
4041: unbox(shaderProgramId),
4042: attrIndex + VirtualUniverse.mc.glslVertexAttrOffset,
4043: attrName);
4044: return null;
4045: }
4046:
4047: void lookupGLSLShaderAttrNames(Context ctx,
4048: ShaderProgramId shaderProgramId, int numAttrNames,
4049: String[] attrNames, ShaderAttrLoc[] locArr, int[] typeArr,
4050: int[] sizeArr, boolean[] isArrayArr) {
4051: if (VERBOSE)
4052: System.err
4053: .println("JoglPipeline.lookupGLSLShaderAttrNames()");
4054:
4055: // set the loc, type, and size arrays to out-of-bound values
4056: for (int i = 0; i < attrNames.length; i++) {
4057: locArr[i] = null;
4058: typeArr[i] = -1;
4059: sizeArr[i] = -1;
4060: }
4061:
4062: // Loop through the list of active uniform variables, one at a
4063: // time, searching for a match in the attrNames array.
4064: //
4065: // NOTE: Since attrNames isn't sorted, and we don't have a
4066: // hashtable of names to index locations, we will do a
4067: // brute-force, linear search of the array. This leads to an
4068: // O(n^2) algorithm (actually O(n*m) where n is attrNames.length
4069: // and m is the number of uniform variables), but since we expect
4070: // N to be small, we will not optimize this at this time.
4071: int id = unbox(shaderProgramId);
4072: int[] tmp = new int[1];
4073: int[] tmp2 = new int[1];
4074: int[] tmp3 = new int[1];
4075: GL gl = context(ctx).getGL();
4076: gl.glGetObjectParameterivARB(id,
4077: GL.GL_OBJECT_ACTIVE_UNIFORMS_ARB, tmp, 0);
4078: int numActiveUniforms = tmp[0];
4079: gl.glGetObjectParameterivARB(id,
4080: GL.GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, tmp, 0);
4081: int maxStrLen = tmp[0];
4082: byte[] nameBuf = new byte[maxStrLen];
4083:
4084: for (int i = 0; i < numActiveUniforms; i++) {
4085: gl.glGetActiveUniformARB(id, i, maxStrLen, tmp3, 0, tmp, 0,
4086: tmp2, 0, nameBuf, 0);
4087: int size = tmp[0];
4088: int type = tmp2[0];
4089: String name = null;
4090: try {
4091: // TODO KCR : Shouldn't this use the default locale?
4092: name = new String(nameBuf, 0, tmp3[0], "US-ASCII");
4093: } catch (UnsupportedEncodingException e) {
4094: throw new RuntimeException(e);
4095: }
4096:
4097: // Issue 247 - we need to workaround an ATI bug where they erroneously
4098: // report individual elements of arrays rather than the array itself
4099: if (name.length() >= 3 && name.endsWith("]")) {
4100: if (name.endsWith("[0]")) {
4101: name = name.substring(0, name.length() - 3);
4102: } else {
4103: // Ignore this name
4104: continue;
4105: }
4106: }
4107:
4108: // Now try to find the name
4109: for (int j = 0; j < numAttrNames; j++) {
4110: if (name.equals(attrNames[j])) {
4111: sizeArr[j] = size;
4112: isArrayArr[j] = (size > 1);
4113: typeArr[j] = glslToJ3dType(type);
4114: break;
4115: }
4116: }
4117: }
4118:
4119: // Now lookup the location of each name in the attrNames array
4120: for (int i = 0; i < numAttrNames; i++) {
4121: // Get uniform attribute location
4122: int loc = gl.glGetUniformLocationARB(id, attrNames[i]);
4123: locArr[i] = new JoglShaderObject(loc);
4124: }
4125: }
4126:
4127: ShaderError useGLSLShaderProgram(Context ctx,
4128: ShaderProgramId shaderProgramId) {
4129: if (VERBOSE)
4130: System.err.println("JoglPipeline.useGLSLShaderProgram()");
4131:
4132: context(ctx).getGL().glUseProgramObjectARB(
4133: unbox(shaderProgramId));
4134: ((JoglContext) ctx)
4135: .setShaderProgram((JoglShaderObject) shaderProgramId);
4136: return null;
4137: }
4138:
4139: //----------------------------------------------------------------------
4140: // Helper methods for above shader routines
4141: //
4142: private int unbox(ShaderAttrLoc loc) {
4143: if (loc == null)
4144: return 0;
4145: return ((JoglShaderObject) loc).getValue();
4146: }
4147:
4148: private int unbox(ShaderProgramId id) {
4149: if (id == null)
4150: return 0;
4151: return ((JoglShaderObject) id).getValue();
4152: }
4153:
4154: private int unbox(ShaderId id) {
4155: if (id == null)
4156: return 0;
4157: return ((JoglShaderObject) id).getValue();
4158: }
4159:
4160: private String getInfoLog(GL gl, int id) {
4161: int[] infoLogLength = new int[1];
4162: gl.glGetObjectParameterivARB(id,
4163: GL.GL_OBJECT_INFO_LOG_LENGTH_ARB, infoLogLength, 0);
4164: if (infoLogLength[0] > 0) {
4165: byte[] storage = new byte[infoLogLength[0]];
4166: int[] len = new int[1];
4167: gl
4168: .glGetInfoLogARB(id, infoLogLength[0], len, 0,
4169: storage, 0);
4170: try {
4171: // TODO KCR : Shouldn't this use the default locale?
4172: return new String(storage, 0, len[0], "US-ASCII");
4173: } catch (UnsupportedEncodingException e) {
4174: throw new RuntimeException(e);
4175: }
4176: }
4177: return null;
4178: }
4179:
4180: private int glslToJ3dType(int type) {
4181: switch (type) {
4182: case GL.GL_BOOL_ARB:
4183: case GL.GL_INT:
4184: case GL.GL_SAMPLER_2D_ARB:
4185: case GL.GL_SAMPLER_3D_ARB:
4186: case GL.GL_SAMPLER_CUBE_ARB:
4187: return ShaderAttributeObjectRetained.TYPE_INTEGER;
4188:
4189: case GL.GL_FLOAT:
4190: return ShaderAttributeObjectRetained.TYPE_FLOAT;
4191:
4192: case GL.GL_INT_VEC2_ARB:
4193: case GL.GL_BOOL_VEC2_ARB:
4194: return ShaderAttributeObjectRetained.TYPE_TUPLE2I;
4195:
4196: case GL.GL_FLOAT_VEC2_ARB:
4197: return ShaderAttributeObjectRetained.TYPE_TUPLE2F;
4198:
4199: case GL.GL_INT_VEC3_ARB:
4200: case GL.GL_BOOL_VEC3_ARB:
4201: return ShaderAttributeObjectRetained.TYPE_TUPLE3I;
4202:
4203: case GL.GL_FLOAT_VEC3_ARB:
4204: return ShaderAttributeObjectRetained.TYPE_TUPLE3F;
4205:
4206: case GL.GL_INT_VEC4_ARB:
4207: case GL.GL_BOOL_VEC4_ARB:
4208: return ShaderAttributeObjectRetained.TYPE_TUPLE4I;
4209:
4210: case GL.GL_FLOAT_VEC4_ARB:
4211: return ShaderAttributeObjectRetained.TYPE_TUPLE4F;
4212:
4213: // case GL.GL_FLOAT_MAT2_ARB:
4214:
4215: case GL.GL_FLOAT_MAT3_ARB:
4216: return ShaderAttributeObjectRetained.TYPE_MATRIX3F;
4217:
4218: case GL.GL_FLOAT_MAT4_ARB:
4219: return ShaderAttributeObjectRetained.TYPE_MATRIX4F;
4220:
4221: // Java 3D does not support the following sampler types:
4222: //
4223: // case GL.GL_SAMPLER_1D_ARB:
4224: // case GL.GL_SAMPLER_1D_SHADOW_ARB:
4225: // case GL.GL_SAMPLER_2D_SHADOW_ARB:
4226: // case GL.GL_SAMPLER_2D_RECT_ARB:
4227: // case GL.GL_SAMPLER_2D_RECT_SHADOW_ARB:
4228: }
4229:
4230: return -1;
4231: }
4232:
4233: // ---------------------------------------------------------------------
4234:
4235: //
4236: // Renderer methods
4237: //
4238:
4239: void cleanupRenderer() {
4240: // Nothing to do
4241: }
4242:
4243: // ---------------------------------------------------------------------
4244:
4245: //
4246: // ColoringAttributesRetained methods
4247: //
4248:
4249: void updateColoringAttributes(Context ctx, float dRed,
4250: float dGreen, float dBlue, float red, float green,
4251: float blue, float alpha, boolean lightEnable, int shadeModel) {
4252: if (VERBOSE)
4253: System.err
4254: .println("JoglPipeline.updateColoringAttributes()");
4255:
4256: GL gl = context(ctx).getGL();
4257:
4258: float cr, cg, cb;
4259:
4260: if (lightEnable) {
4261: cr = dRed;
4262: cg = dGreen;
4263: cb = dBlue;
4264: } else {
4265: cr = red;
4266: cg = green;
4267: cb = blue;
4268: }
4269: gl.glColor4f(cr, cg, cb, alpha);
4270: if (shadeModel == ColoringAttributes.SHADE_FLAT) {
4271: gl.glShadeModel(GL.GL_FLAT);
4272: } else {
4273: gl.glShadeModel(GL.GL_SMOOTH);
4274: }
4275: }
4276:
4277: // ---------------------------------------------------------------------
4278:
4279: //
4280: // DirectionalLightRetained methods
4281: //
4282:
4283: private static final float[] black = new float[4];
4284:
4285: void updateDirectionalLight(Context ctx, int lightSlot, float red,
4286: float green, float blue, float dirx, float diry, float dirz) {
4287: if (VERBOSE)
4288: System.err.println("JoglPipeline.updateDirectionalLight()");
4289:
4290: GL gl = context(ctx).getGL();
4291:
4292: int lightNum = GL.GL_LIGHT0 + lightSlot;
4293: float[] values = new float[4];
4294:
4295: values[0] = red;
4296: values[1] = green;
4297: values[2] = blue;
4298: values[3] = 1.0f;
4299: gl.glLightfv(lightNum, GL.GL_DIFFUSE, values, 0);
4300: gl.glLightfv(lightNum, GL.GL_SPECULAR, values, 0);
4301: values[0] = -dirx;
4302: values[1] = -diry;
4303: values[2] = -dirz;
4304: values[3] = 0.0f;
4305: gl.glLightfv(lightNum, GL.GL_POSITION, values, 0);
4306: gl.glLightfv(lightNum, GL.GL_AMBIENT, black, 0);
4307: gl.glLightf(lightNum, GL.GL_CONSTANT_ATTENUATION, 1.0f);
4308: gl.glLightf(lightNum, GL.GL_LINEAR_ATTENUATION, 0.0f);
4309: gl.glLightf(lightNum, GL.GL_QUADRATIC_ATTENUATION, 0.0f);
4310: gl.glLightf(lightNum, GL.GL_SPOT_EXPONENT, 0.0f);
4311: gl.glLightf(lightNum, GL.GL_SPOT_CUTOFF, 180.0f);
4312: }
4313:
4314: // ---------------------------------------------------------------------
4315:
4316: //
4317: // PointLightRetained methods
4318: //
4319:
4320: void updatePointLight(Context ctx, int lightSlot, float red,
4321: float green, float blue, float attenx, float atteny,
4322: float attenz, float posx, float posy, float posz) {
4323: if (VERBOSE)
4324: System.err.println("JoglPipeline.updatePointLight()");
4325:
4326: GL gl = context(ctx).getGL();
4327:
4328: int lightNum = GL.GL_LIGHT0 + lightSlot;
4329: float[] values = new float[4];
4330:
4331: values[0] = red;
4332: values[1] = green;
4333: values[2] = blue;
4334: values[3] = 1.0f;
4335: gl.glLightfv(lightNum, GL.GL_DIFFUSE, values, 0);
4336: gl.glLightfv(lightNum, GL.GL_SPECULAR, values, 0);
4337: gl.glLightfv(lightNum, GL.GL_AMBIENT, black, 0);
4338: values[0] = posx;
4339: values[1] = posy;
4340: values[2] = posz;
4341: gl.glLightfv(lightNum, GL.GL_POSITION, values, 0);
4342: gl.glLightf(lightNum, GL.GL_CONSTANT_ATTENUATION, attenx);
4343: gl.glLightf(lightNum, GL.GL_LINEAR_ATTENUATION, atteny);
4344: gl.glLightf(lightNum, GL.GL_QUADRATIC_ATTENUATION, attenz);
4345: gl.glLightf(lightNum, GL.GL_SPOT_EXPONENT, 0.0f);
4346: gl.glLightf(lightNum, GL.GL_SPOT_CUTOFF, 180.0f);
4347: }
4348:
4349: // ---------------------------------------------------------------------
4350:
4351: //
4352: // SpotLightRetained methods
4353: //
4354:
4355: void updateSpotLight(Context ctx, int lightSlot, float red,
4356: float green, float blue, float attenx, float atteny,
4357: float attenz, float posx, float posy, float posz,
4358: float spreadAngle, float concentration, float dirx,
4359: float diry, float dirz) {
4360: if (VERBOSE)
4361: System.err.println("JoglPipeline.updateSpotLight()");
4362:
4363: GL gl = context(ctx).getGL();
4364:
4365: int lightNum = GL.GL_LIGHT0 + lightSlot;
4366: float[] values = new float[4];
4367:
4368: values[0] = red;
4369: values[1] = green;
4370: values[2] = blue;
4371: values[3] = 1.0f;
4372: gl.glLightfv(lightNum, GL.GL_DIFFUSE, values, 0);
4373: gl.glLightfv(lightNum, GL.GL_SPECULAR, values, 0);
4374: gl.glLightfv(lightNum, GL.GL_AMBIENT, black, 0);
4375: values[0] = posx;
4376: values[1] = posy;
4377: values[2] = posz;
4378: gl.glLightfv(lightNum, GL.GL_POSITION, values, 0);
4379: gl.glLightf(lightNum, GL.GL_CONSTANT_ATTENUATION, attenx);
4380: gl.glLightf(lightNum, GL.GL_LINEAR_ATTENUATION, atteny);
4381: gl.glLightf(lightNum, GL.GL_QUADRATIC_ATTENUATION, attenz);
4382: values[0] = dirx;
4383: values[1] = diry;
4384: values[2] = dirz;
4385: gl.glLightfv(lightNum, GL.GL_SPOT_DIRECTION, values, 0);
4386: gl.glLightf(lightNum, GL.GL_SPOT_EXPONENT, concentration);
4387: gl.glLightf(lightNum, GL.GL_SPOT_CUTOFF,
4388: (float) (spreadAngle * 180.0f / Math.PI));
4389: }
4390:
4391: // ---------------------------------------------------------------------
4392:
4393: //
4394: // ExponentialFogRetained methods
4395: //
4396:
4397: void updateExponentialFog(Context ctx, float red, float green,
4398: float blue, float density) {
4399: if (VERBOSE)
4400: System.err.println("JoglPipeline.updateExponentialFog()");
4401:
4402: GL gl = context(ctx).getGL();
4403:
4404: float[] color = new float[3];
4405: color[0] = red;
4406: color[1] = green;
4407: color[2] = blue;
4408: gl.glFogi(GL.GL_FOG_MODE, GL.GL_EXP);
4409: gl.glFogfv(GL.GL_FOG_COLOR, color, 0);
4410: gl.glFogf(GL.GL_FOG_DENSITY, density);
4411: gl.glEnable(GL.GL_FOG);
4412: }
4413:
4414: // ---------------------------------------------------------------------
4415:
4416: //
4417: // LinearFogRetained methods
4418: //
4419:
4420: void updateLinearFog(Context ctx, float red, float green,
4421: float blue, double fdist, double bdist) {
4422: if (VERBOSE)
4423: System.err.println("JoglPipeline.updateLinearFog()");
4424:
4425: GL gl = context(ctx).getGL();
4426:
4427: float[] color = new float[3];
4428: color[0] = red;
4429: color[1] = green;
4430: color[2] = blue;
4431: gl.glFogi(GL.GL_FOG_MODE, GL.GL_LINEAR);
4432: gl.glFogfv(GL.GL_FOG_COLOR, color, 0);
4433: gl.glFogf(GL.GL_FOG_START, (float) fdist);
4434: gl.glFogf(GL.GL_FOG_END, (float) bdist);
4435: gl.glEnable(GL.GL_FOG);
4436: }
4437:
4438: // ---------------------------------------------------------------------
4439:
4440: //
4441: // LineAttributesRetained methods
4442: //
4443:
4444: void updateLineAttributes(Context ctx, float lineWidth,
4445: int linePattern, int linePatternMask,
4446: int linePatternScaleFactor, boolean lineAntialiasing) {
4447: if (VERBOSE)
4448: System.err.println("JoglPipeline.updateLineAttributes()");
4449:
4450: GL gl = context(ctx).getGL();
4451: gl.glLineWidth(lineWidth);
4452:
4453: if (linePattern == LineAttributes.PATTERN_SOLID) {
4454: gl.glDisable(GL.GL_LINE_STIPPLE);
4455: } else {
4456: if (linePattern == LineAttributes.PATTERN_DASH) { // dashed lines
4457: gl.glLineStipple(1, (short) 0x00ff);
4458: } else if (linePattern == LineAttributes.PATTERN_DOT) { // dotted lines
4459: gl.glLineStipple(1, (short) 0x0101);
4460: } else if (linePattern == LineAttributes.PATTERN_DASH_DOT) { // dash-dotted lines
4461: gl.glLineStipple(1, (short) 0x087f);
4462: } else if (linePattern == LineAttributes.PATTERN_USER_DEFINED) { // user-defined mask
4463: gl.glLineStipple(linePatternScaleFactor,
4464: (short) linePatternMask);
4465: }
4466: gl.glEnable(GL.GL_LINE_STIPPLE);
4467: }
4468:
4469: /* XXXX: Polygon Mode check, blend enable */
4470: if (lineAntialiasing) {
4471: gl.glEnable(GL.GL_LINE_SMOOTH);
4472: } else {
4473: gl.glDisable(GL.GL_LINE_SMOOTH);
4474: }
4475: }
4476:
4477: // ---------------------------------------------------------------------
4478:
4479: //
4480: // MaterialRetained methods
4481: //
4482:
4483: void updateMaterial(Context ctx, float red, float green,
4484: float blue, float alpha, float aRed, float aGreen,
4485: float aBlue, float eRed, float eGreen, float eBlue,
4486: float dRed, float dGreen, float dBlue, float sRed,
4487: float sGreen, float sBlue, float shininess,
4488: int colorTarget, boolean lightEnable) {
4489: if (VERBOSE)
4490: System.err.println("JoglPipeline.updateMaterial()");
4491:
4492: float[] color = new float[4];
4493:
4494: GL gl = context(ctx).getGL();
4495:
4496: gl
4497: .glMaterialf(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS,
4498: shininess);
4499: switch (colorTarget) {
4500: case Material.DIFFUSE:
4501: gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE);
4502: break;
4503: case Material.AMBIENT:
4504: gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT);
4505: break;
4506: case Material.EMISSIVE:
4507: gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_EMISSION);
4508: break;
4509: case Material.SPECULAR:
4510: gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR);
4511: break;
4512: case Material.AMBIENT_AND_DIFFUSE:
4513: gl.glColorMaterial(GL.GL_FRONT_AND_BACK,
4514: GL.GL_AMBIENT_AND_DIFFUSE);
4515: break;
4516: }
4517:
4518: color[0] = eRed;
4519: color[1] = eGreen;
4520: color[2] = eBlue;
4521: gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_EMISSION, color, 0);
4522:
4523: color[0] = aRed;
4524: color[1] = aGreen;
4525: color[2] = aBlue;
4526: gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, color, 0);
4527:
4528: color[0] = sRed;
4529: color[1] = sGreen;
4530: color[2] = sBlue;
4531: gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, color, 0);
4532:
4533: float cr, cg, cb;
4534:
4535: if (lightEnable) {
4536: color[0] = dRed;
4537: color[1] = dGreen;
4538: color[2] = dBlue;
4539: } else {
4540: color[0] = red;
4541: color[1] = green;
4542: color[2] = blue;
4543: }
4544: color[3] = alpha;
4545: gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, color, 0);
4546: gl.glColor4f(color[0], color[1], color[2], color[3]);
4547:
4548: if (lightEnable) {
4549: gl.glEnable(GL.GL_LIGHTING);
4550: } else {
4551: gl.glDisable(GL.GL_LIGHTING);
4552: }
4553: }
4554:
4555: // ---------------------------------------------------------------------
4556:
4557: //
4558: // ModelClipRetained methods
4559: //
4560:
4561: void updateModelClip(Context ctx, int planeNum, boolean enableFlag,
4562: double A, double B, double C, double D) {
4563: if (VERBOSE)
4564: System.err.println("JoglPipeline.updateModelClip()");
4565:
4566: GL gl = context(ctx).getGL();
4567:
4568: double[] equation = new double[4];
4569: int pl = GL.GL_CLIP_PLANE0 + planeNum;
4570:
4571: // OpenGL clip planes are opposite to J3d clip planes
4572: if (enableFlag) {
4573: equation[0] = -A;
4574: equation[1] = -B;
4575: equation[2] = -C;
4576: equation[3] = -D;
4577: gl.glClipPlane(pl, DoubleBuffer.wrap(equation));
4578: gl.glEnable(pl);
4579: } else {
4580: gl.glDisable(pl);
4581: }
4582: }
4583:
4584: // ---------------------------------------------------------------------
4585:
4586: //
4587: // PointAttributesRetained methods
4588: //
4589:
4590: void updatePointAttributes(Context ctx, float pointSize,
4591: boolean pointAntialiasing) {
4592: if (VERBOSE)
4593: System.err.println("JoglPipeline.updatePointAttributes()");
4594:
4595: GL gl = context(ctx).getGL();
4596: gl.glPointSize(pointSize);
4597:
4598: // XXXX: Polygon Mode check, blend enable
4599: if (pointAntialiasing) {
4600: gl.glEnable(GL.GL_POINT_SMOOTH);
4601: } else {
4602: gl.glDisable(GL.GL_POINT_SMOOTH);
4603: }
4604: }
4605:
4606: // ---------------------------------------------------------------------
4607:
4608: //
4609: // PolygonAttributesRetained methods
4610: //
4611:
4612: void updatePolygonAttributes(Context ctx, int polygonMode,
4613: int cullFace, boolean backFaceNormalFlip,
4614: float polygonOffset, float polygonOffsetFactor) {
4615: if (VERBOSE)
4616: System.err
4617: .println("JoglPipeline.updatePolygonAttributes()");
4618:
4619: GL gl = context(ctx).getGL();
4620:
4621: if (cullFace == PolygonAttributes.CULL_NONE) {
4622: gl.glDisable(GL.GL_CULL_FACE);
4623: } else {
4624: if (cullFace == PolygonAttributes.CULL_BACK) {
4625: gl.glCullFace(GL.GL_BACK);
4626: } else {
4627: gl.glCullFace(GL.GL_FRONT);
4628: }
4629: gl.glEnable(GL.GL_CULL_FACE);
4630: }
4631:
4632: if (backFaceNormalFlip
4633: && (cullFace != PolygonAttributes.CULL_BACK)) {
4634: gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_TRUE);
4635: } else {
4636: gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_FALSE);
4637: }
4638:
4639: if (polygonMode == PolygonAttributes.POLYGON_POINT) {
4640: gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_POINT);
4641: } else if (polygonMode == PolygonAttributes.POLYGON_LINE) {
4642: gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
4643: } else {
4644: gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
4645: }
4646:
4647: gl.glPolygonOffset(polygonOffsetFactor, polygonOffset);
4648:
4649: if ((polygonOffsetFactor != 0.0) || (polygonOffset != 0.0)) {
4650: switch (polygonMode) {
4651: case PolygonAttributes.POLYGON_POINT:
4652: gl.glEnable(GL.GL_POLYGON_OFFSET_POINT);
4653: gl.glDisable(GL.GL_POLYGON_OFFSET_LINE);
4654: gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
4655: break;
4656: case PolygonAttributes.POLYGON_LINE:
4657: gl.glEnable(GL.GL_POLYGON_OFFSET_LINE);
4658: gl.glDisable(GL.GL_POLYGON_OFFSET_POINT);
4659: gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
4660: break;
4661: case PolygonAttributes.POLYGON_FILL:
4662: gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
4663: gl.glDisable(GL.GL_POLYGON_OFFSET_POINT);
4664: gl.glDisable(GL.GL_POLYGON_OFFSET_LINE);
4665: break;
4666: }
4667: } else {
4668: gl.glDisable(GL.GL_POLYGON_OFFSET_POINT);
4669: gl.glDisable(GL.GL_POLYGON_OFFSET_LINE);
4670: gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
4671: }
4672: }
4673:
4674: // ---------------------------------------------------------------------
4675:
4676: //
4677: // RenderingAttributesRetained methods
4678: //
4679:
4680: void updateRenderingAttributes(Context ctx,
4681: boolean depthBufferWriteEnableOverride,
4682: boolean depthBufferEnableOverride,
4683: boolean depthBufferEnable, boolean depthBufferWriteEnable,
4684: int depthTestFunction, float alphaTestValue,
4685: int alphaTestFunction, boolean ignoreVertexColors,
4686: boolean rasterOpEnable, int rasterOp,
4687: boolean userStencilAvailable, boolean stencilEnable,
4688: int stencilFailOp, int stencilZFailOp, int stencilZPassOp,
4689: int stencilFunction, int stencilReferenceValue,
4690: int stencilCompareMask, int stencilWriteMask) {
4691: if (VERBOSE)
4692: System.err
4693: .println("JoglPipeline.updateRenderingAttributes()");
4694:
4695: GL gl = context(ctx).getGL();
4696:
4697: if (!depthBufferEnableOverride) {
4698: if (depthBufferEnable) {
4699: gl.glEnable(GL.GL_DEPTH_TEST);
4700: gl.glDepthFunc(getFunctionValue(depthTestFunction));
4701: } else {
4702: gl.glDisable(GL.GL_DEPTH_TEST);
4703: }
4704: }
4705:
4706: if (!depthBufferWriteEnableOverride) {
4707: if (depthBufferWriteEnable) {
4708: gl.glDepthMask(true);
4709: } else {
4710: gl.glDepthMask(false);
4711: }
4712: }
4713:
4714: if (alphaTestFunction == RenderingAttributes.ALWAYS) {
4715: gl.glDisable(GL.GL_ALPHA_TEST);
4716: } else {
4717: gl.glEnable(GL.GL_ALPHA_TEST);
4718: gl.glAlphaFunc(getFunctionValue(alphaTestFunction),
4719: alphaTestValue);
4720: }
4721:
4722: if (ignoreVertexColors) {
4723: gl.glDisable(GL.GL_COLOR_MATERIAL);
4724: } else {
4725: gl.glEnable(GL.GL_COLOR_MATERIAL);
4726: }
4727:
4728: if (rasterOpEnable) {
4729: gl.glEnable(GL.GL_COLOR_LOGIC_OP);
4730: switch (rasterOp) {
4731: case RenderingAttributes.ROP_CLEAR:
4732: gl.glLogicOp(GL.GL_CLEAR);
4733: break;
4734: case RenderingAttributes.ROP_AND:
4735: gl.glLogicOp(GL.GL_AND);
4736: break;
4737: case RenderingAttributes.ROP_AND_REVERSE:
4738: gl.glLogicOp(GL.GL_AND_REVERSE);
4739: break;
4740: case RenderingAttributes.ROP_COPY:
4741: gl.glLogicOp(GL.GL_COPY);
4742: break;
4743: case RenderingAttributes.ROP_AND_INVERTED:
4744: gl.glLogicOp(GL.GL_AND_INVERTED);
4745: break;
4746: case RenderingAttributes.ROP_NOOP:
4747: gl.glLogicOp(GL.GL_NOOP);
4748: break;
4749: case RenderingAttributes.ROP_XOR:
4750: gl.glLogicOp(GL.GL_XOR);
4751: break;
4752: case RenderingAttributes.ROP_OR:
4753: gl.glLogicOp(GL.GL_OR);
4754: break;
4755: case RenderingAttributes.ROP_NOR:
4756: gl.glLogicOp(GL.GL_NOR);
4757: break;
4758: case RenderingAttributes.ROP_EQUIV:
4759: gl.glLogicOp(GL.GL_EQUIV);
4760: break;
4761: case RenderingAttributes.ROP_INVERT:
4762: gl.glLogicOp(GL.GL_INVERT);
4763: break;
4764: case RenderingAttributes.ROP_OR_REVERSE:
4765: gl.glLogicOp(GL.GL_OR_REVERSE);
4766: break;
4767: case RenderingAttributes.ROP_COPY_INVERTED:
4768: gl.glLogicOp(GL.GL_COPY_INVERTED);
4769: break;
4770: case RenderingAttributes.ROP_OR_INVERTED:
4771: gl.glLogicOp(GL.GL_OR_INVERTED);
4772: break;
4773: case RenderingAttributes.ROP_NAND:
4774: gl.glLogicOp(GL.GL_NAND);
4775: break;
4776: case RenderingAttributes.ROP_SET:
4777: gl.glLogicOp(GL.GL_SET);
4778: break;
4779: }
4780: } else {
4781: gl.glDisable(GL.GL_COLOR_LOGIC_OP);
4782: }
4783:
4784: if (userStencilAvailable) {
4785: if (stencilEnable) {
4786: gl.glEnable(GL.GL_STENCIL_TEST);
4787:
4788: gl.glStencilOp(getStencilOpValue(stencilFailOp),
4789: getStencilOpValue(stencilZFailOp),
4790: getStencilOpValue(stencilZPassOp));
4791:
4792: gl.glStencilFunc(getFunctionValue(stencilFunction),
4793: stencilReferenceValue, stencilCompareMask);
4794:
4795: gl.glStencilMask(stencilWriteMask);
4796:
4797: } else {
4798: gl.glDisable(GL.GL_STENCIL_TEST);
4799: }
4800: }
4801: }
4802:
4803: private int getFunctionValue(int func) {
4804: switch (func) {
4805: case RenderingAttributes.ALWAYS:
4806: func = GL.GL_ALWAYS;
4807: break;
4808: case RenderingAttributes.NEVER:
4809: func = GL.GL_NEVER;
4810: break;
4811: case RenderingAttributes.EQUAL:
4812: func = GL.GL_EQUAL;
4813: break;
4814: case RenderingAttributes.NOT_EQUAL:
4815: func = GL.GL_NOTEQUAL;
4816: break;
4817: case RenderingAttributes.LESS:
4818: func = GL.GL_LESS;
4819: break;
4820: case RenderingAttributes.LESS_OR_EQUAL:
4821: func = GL.GL_LEQUAL;
4822: break;
4823: case RenderingAttributes.GREATER:
4824: func = GL.GL_GREATER;
4825: break;
4826: case RenderingAttributes.GREATER_OR_EQUAL:
4827: func = GL.GL_GEQUAL;
4828: break;
4829: }
4830:
4831: return func;
4832: }
4833:
4834: private int getStencilOpValue(int op) {
4835: switch (op) {
4836: case RenderingAttributes.STENCIL_KEEP:
4837: op = GL.GL_KEEP;
4838: break;
4839: case RenderingAttributes.STENCIL_ZERO:
4840: op = GL.GL_ZERO;
4841: break;
4842: case RenderingAttributes.STENCIL_REPLACE:
4843: op = GL.GL_REPLACE;
4844: break;
4845: case RenderingAttributes.STENCIL_INCR:
4846: op = GL.GL_INCR;
4847: break;
4848: case RenderingAttributes.STENCIL_DECR:
4849: op = GL.GL_DECR;
4850: break;
4851: case RenderingAttributes.STENCIL_INVERT:
4852: op = GL.GL_INVERT;
4853: break;
4854: }
4855:
4856: return op;
4857: }
4858:
4859: // ---------------------------------------------------------------------
4860:
4861: //
4862: // TexCoordGenerationRetained methods
4863: //
4864:
4865: /**
4866: * This method updates the native context:
4867: * trans contains eyeTovworld transform in d3d
4868: * trans contains vworldToEye transform in ogl
4869: */
4870: void updateTexCoordGeneration(Context ctx, boolean enable,
4871: int genMode, int format, float planeSx, float planeSy,
4872: float planeSz, float planeSw, float planeTx, float planeTy,
4873: float planeTz, float planeTw, float planeRx, float planeRy,
4874: float planeRz, float planeRw, float planeQx, float planeQy,
4875: float planeQz, float planeQw, double[] vworldToEc) {
4876: if (VERBOSE)
4877: System.err
4878: .println("JoglPipeline.updateTexCoordGeneration()");
4879:
4880: GL gl = context(ctx).getGL();
4881:
4882: float[] planeS = new float[4];
4883: float[] planeT = new float[4];
4884: float[] planeR = new float[4];
4885: float[] planeQ = new float[4];
4886:
4887: if (enable) {
4888: gl.glEnable(GL.GL_TEXTURE_GEN_S);
4889: gl.glEnable(GL.GL_TEXTURE_GEN_T);
4890: if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
4891: gl.glEnable(GL.GL_TEXTURE_GEN_R);
4892: gl.glDisable(GL.GL_TEXTURE_GEN_Q);
4893: } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
4894: gl.glEnable(GL.GL_TEXTURE_GEN_R);
4895: gl.glEnable(GL.GL_TEXTURE_GEN_Q);
4896: } else {
4897: gl.glDisable(GL.GL_TEXTURE_GEN_R);
4898: gl.glDisable(GL.GL_TEXTURE_GEN_Q);
4899: }
4900:
4901: if (genMode != TexCoordGeneration.SPHERE_MAP) {
4902: planeS[0] = planeSx;
4903: planeS[1] = planeSy;
4904: planeS[2] = planeSz;
4905: planeS[3] = planeSw;
4906: planeT[0] = planeTx;
4907: planeT[1] = planeTy;
4908: planeT[2] = planeTz;
4909: planeT[3] = planeTw;
4910: if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
4911: planeR[0] = planeRx;
4912: planeR[1] = planeRy;
4913: planeR[2] = planeRz;
4914: planeR[3] = planeRw;
4915: } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
4916: planeR[0] = planeRx;
4917: planeR[1] = planeRy;
4918: planeR[2] = planeRz;
4919: planeR[3] = planeRw;
4920: planeQ[0] = planeQx;
4921: planeQ[1] = planeQy;
4922: planeQ[2] = planeQz;
4923: planeQ[3] = planeQw;
4924: }
4925: }
4926:
4927: switch (genMode) {
4928: case TexCoordGeneration.OBJECT_LINEAR:
4929: gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE,
4930: GL.GL_OBJECT_LINEAR);
4931: gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE,
4932: GL.GL_OBJECT_LINEAR);
4933: gl.glTexGenfv(GL.GL_S, GL.GL_OBJECT_PLANE, planeS, 0);
4934: gl.glTexGenfv(GL.GL_T, GL.GL_OBJECT_PLANE, planeT, 0);
4935:
4936: if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
4937: gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE,
4938: GL.GL_OBJECT_LINEAR);
4939: gl.glTexGenfv(GL.GL_R, GL.GL_OBJECT_PLANE, planeR,
4940: 0);
4941: } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
4942: gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE,
4943: GL.GL_OBJECT_LINEAR);
4944: gl.glTexGenfv(GL.GL_R, GL.GL_OBJECT_PLANE, planeR,
4945: 0);
4946: gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE,
4947: GL.GL_OBJECT_LINEAR);
4948: gl.glTexGenfv(GL.GL_Q, GL.GL_OBJECT_PLANE, planeQ,
4949: 0);
4950: }
4951: break;
4952: case TexCoordGeneration.EYE_LINEAR:
4953:
4954: gl.glMatrixMode(GL.GL_MODELVIEW);
4955: gl.glPushMatrix();
4956:
4957: if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
4958: gl.glLoadTransposeMatrixd(vworldToEc, 0);
4959: } else {
4960: double[] v = new double[16];
4961: copyTranspose(vworldToEc, v);
4962: gl.glLoadMatrixd(v, 0);
4963: }
4964:
4965: gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE,
4966: GL.GL_EYE_LINEAR);
4967: gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE,
4968: GL.GL_EYE_LINEAR);
4969: gl.glTexGenfv(GL.GL_S, GL.GL_EYE_PLANE, planeS, 0);
4970: gl.glTexGenfv(GL.GL_T, GL.GL_EYE_PLANE, planeT, 0);
4971:
4972: if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
4973: gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE,
4974: GL.GL_EYE_LINEAR);
4975: gl.glTexGenfv(GL.GL_R, GL.GL_EYE_PLANE, planeR, 0);
4976: } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
4977: gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE,
4978: GL.GL_EYE_LINEAR);
4979: gl.glTexGenfv(GL.GL_R, GL.GL_EYE_PLANE, planeR, 0);
4980: gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE,
4981: GL.GL_EYE_LINEAR);
4982: gl.glTexGenfv(GL.GL_Q, GL.GL_EYE_PLANE, planeQ, 0);
4983: }
4984: gl.glPopMatrix();
4985: break;
4986: case TexCoordGeneration.SPHERE_MAP:
4987: gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE,
4988: GL.GL_SPHERE_MAP);
4989: gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE,
4990: GL.GL_SPHERE_MAP);
4991: if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
4992: gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE,
4993: GL.GL_SPHERE_MAP);
4994: } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
4995: gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE,
4996: GL.GL_SPHERE_MAP);
4997: gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE,
4998: GL.GL_SPHERE_MAP);
4999: }
5000:
5001: break;
5002: case TexCoordGeneration.NORMAL_MAP:
5003: gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE,
5004: GL.GL_NORMAL_MAP);
5005: gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE,
5006: GL.GL_NORMAL_MAP);
5007: if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
5008: gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE,
5009: GL.GL_NORMAL_MAP);
5010: } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
5011: gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE,
5012: GL.GL_NORMAL_MAP);
5013: gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE,
5014: GL.GL_NORMAL_MAP);
5015: }
5016: break;
5017: case TexCoordGeneration.REFLECTION_MAP:
5018: gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE,
5019: GL.GL_REFLECTION_MAP);
5020: gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE,
5021: GL.GL_REFLECTION_MAP);
5022: if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
5023: gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE,
5024: GL.GL_REFLECTION_MAP);
5025: } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
5026: gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE,
5027: GL.GL_REFLECTION_MAP);
5028: gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE,
5029: GL.GL_REFLECTION_MAP);
5030: }
5031: break;
5032: }
5033: } else {
5034: gl.glDisable(GL.GL_TEXTURE_GEN_S);
5035: gl.glDisable(GL.GL_TEXTURE_GEN_T);
5036: gl.glDisable(GL.GL_TEXTURE_GEN_R);
5037: gl.glDisable(GL.GL_TEXTURE_GEN_Q);
5038: }
5039: }
5040:
5041: // ---------------------------------------------------------------------
5042:
5043: //
5044: // TransparencyAttributesRetained methods
5045: //
5046:
5047: private static final int screen_door[][] = {
5048: /* 0 / 16 */
5049: { 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5050: 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5051: 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5052: 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5053: 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5054: 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5055: 0x00000000, 0x00000000, 0x00000000, 0x00000000,
5056: 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
5057: /* 1 / 16 */
5058: { 0x00000000, 0x22222222, 0x00000000, 0x00000000,
5059: 0x00000000, 0x22222222, 0x00000000, 0x00000000,
5060: 0x00000000, 0x22222222, 0x00000000, 0x00000000,
5061: 0x00000000, 0x22222222, 0x00000000, 0x00000000,
5062: 0x00000000, 0x22222222, 0x00000000, 0x00000000,
5063: 0x00000000, 0x22222222, 0x00000000, 0x00000000,
5064: 0x00000000, 0x22222222, 0x00000000, 0x00000000,
5065: 0x00000000, 0x22222222, 0x00000000, 0x00000000, },
5066: /* 2 / 16 */
5067: { 0x00000000, 0x22222222, 0x00000000, 0x88888888,
5068: 0x00000000, 0x22222222, 0x00000000, 0x88888888,
5069: 0x00000000, 0x22222222, 0x00000000, 0x88888888,
5070: 0x00000000, 0x22222222, 0x00000000, 0x88888888,
5071: 0x00000000, 0x22222222, 0x00000000, 0x88888888,
5072: 0x00000000, 0x22222222, 0x00000000, 0x88888888,
5073: 0x00000000, 0x22222222, 0x00000000, 0x88888888,
5074: 0x00000000, 0x22222222, 0x00000000, 0x88888888, },
5075: /* 3 / 16 */
5076: { 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
5077: 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
5078: 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
5079: 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
5080: 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
5081: 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
5082: 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
5083: 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, },
5084: /* 4 / 16 */
5085: { 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5086: 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5087: 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5088: 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5089: 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5090: 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5091: 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5092: 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, },
5093: /* 5 / 16 */
5094: { 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5095: 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5096: 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5097: 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5098: 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5099: 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5100: 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
5101: 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, },
5102: /* 6 / 16 */
5103: { 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5104: 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5105: 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5106: 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5107: 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5108: 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5109: 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5110: 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, },
5111: /* 7 / 16 */
5112: { 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5113: 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5114: 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5115: 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5116: 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5117: 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5118: 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
5119: 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, },
5120: /* 8 / 16 */
5121: { 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5122: 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5123: 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5124: 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5125: 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5126: 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5127: 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5128: 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, },
5129: /* 9 / 16 */
5130: { 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5131: 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5132: 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5133: 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5134: 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5135: 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5136: 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
5137: 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, },
5138: /* 10 / 16 */
5139: { 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5140: 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5141: 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5142: 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5143: 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5144: 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5145: 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5146: 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, },
5147: /* 11 / 16 */
5148: { 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5149: 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5150: 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5151: 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5152: 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5153: 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5154: 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
5155: 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, },
5156: /* 12 / 16 */
5157: { 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
5158: 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
5159: 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
5160: 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
5161: 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
5162: 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
5163: 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
5164: 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, },
5165: /* 13 / 16 */
5166: { 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
5167: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
5168: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
5169: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
5170: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
5171: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
5172: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
5173: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, },
5174: /* 14 / 16 */
5175: { 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
5176: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
5177: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
5178: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
5179: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
5180: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
5181: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
5182: 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, },
5183: /* 15 / 16 */
5184: { 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
5185: 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
5186: 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
5187: 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
5188: 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
5189: 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
5190: 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
5191: 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, },
5192: /* 16 / 16 */
5193: { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
5194: 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
5195: 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
5196: 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
5197: 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
5198: 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
5199: 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
5200: 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, }, };
5201: private static final ByteBuffer[] screen_door_table = new ByteBuffer[screen_door.length];
5202: static {
5203: int eachLen = screen_door[0].length * BufferUtil.SIZEOF_INT;
5204: ByteBuffer buf = BufferUtil.newByteBuffer(screen_door.length
5205: * eachLen);
5206: IntBuffer intBuf = buf.asIntBuffer();
5207: for (int i = 0; i < screen_door.length; i++) {
5208: intBuf.put(screen_door[i]);
5209: }
5210: buf.rewind();
5211: for (int i = 0; i < screen_door.length; i++) {
5212: buf.position(i * eachLen);
5213: buf.limit((i + 1) * eachLen);
5214: screen_door_table[i] = buf.slice();
5215: }
5216: }
5217:
5218: private static final int[] blendFunctionTable = new int[TransparencyAttributes.MAX_BLEND_FUNC_TABLE_SIZE];
5219: static {
5220: blendFunctionTable[TransparencyAttributes.BLEND_ZERO] = GL.GL_ZERO;
5221: blendFunctionTable[TransparencyAttributes.BLEND_ONE] = GL.GL_ONE;
5222: blendFunctionTable[TransparencyAttributes.BLEND_SRC_ALPHA] = GL.GL_SRC_ALPHA;
5223: blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_SRC_ALPHA] = GL.GL_ONE_MINUS_SRC_ALPHA;
5224: blendFunctionTable[TransparencyAttributes.BLEND_DST_COLOR] = GL.GL_DST_COLOR;
5225: blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_DST_COLOR] = GL.GL_ONE_MINUS_DST_COLOR;
5226: blendFunctionTable[TransparencyAttributes.BLEND_SRC_COLOR] = GL.GL_SRC_COLOR;
5227: blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_SRC_COLOR] = GL.GL_ONE_MINUS_SRC_COLOR;
5228: blendFunctionTable[TransparencyAttributes.BLEND_CONSTANT_COLOR] = GL.GL_CONSTANT_COLOR;
5229: }
5230:
5231: void updateTransparencyAttributes(Context ctx, float alpha,
5232: int geometryType, int polygonMode, boolean lineAA,
5233: boolean pointAA, int transparencyMode,
5234: int srcBlendFunction, int dstBlendFunction) {
5235: if (VERBOSE)
5236: System.err
5237: .println("JoglPipeline.updateTransparencyAttributes()");
5238:
5239: GL gl = context(ctx).getGL();
5240:
5241: if (transparencyMode != TransparencyAttributes.SCREEN_DOOR) {
5242: gl.glDisable(GL.GL_POLYGON_STIPPLE);
5243: } else {
5244: gl.glEnable(GL.GL_POLYGON_STIPPLE);
5245: gl.glPolygonStipple(screen_door_table[(int) (alpha * 16)]);
5246: }
5247:
5248: if ((transparencyMode < TransparencyAttributes.SCREEN_DOOR)
5249: || ((((geometryType & RenderMolecule.LINE) != 0) || (polygonMode == PolygonAttributes.POLYGON_LINE)) && lineAA)
5250: || ((((geometryType & RenderMolecule.POINT) != 0) || (polygonMode == PolygonAttributes.POLYGON_POINT)) && pointAA)) {
5251: gl.glEnable(GL.GL_BLEND);
5252: // valid range of blendFunction 0..3 is already verified in shared code.
5253: gl.glBlendFunc(blendFunctionTable[srcBlendFunction],
5254: blendFunctionTable[dstBlendFunction]);
5255: } else {
5256: gl.glDisable(GL.GL_BLEND);
5257: }
5258: }
5259:
5260: // ---------------------------------------------------------------------
5261:
5262: //
5263: // TextureAttributesRetained methods
5264: //
5265:
5266: void updateTextureAttributes(Context ctx, double[] transform,
5267: boolean isIdentity, int textureMode,
5268: int perspCorrectionMode, float textureBlendColorRed,
5269: float textureBlendColorGreen, float textureBlendColorBlue,
5270: float textureBlendColorAlpha, int textureFormat) {
5271: if (VERBOSE)
5272: System.err
5273: .println("JoglPipeline.updateTextureAttributes()");
5274:
5275: GL gl = context(ctx).getGL();
5276: gl
5277: .glHint(
5278: GL.GL_PERSPECTIVE_CORRECTION_HINT,
5279: (perspCorrectionMode == TextureAttributes.NICEST) ? GL.GL_NICEST
5280: : GL.GL_FASTEST);
5281:
5282: // set OGL texture matrix
5283: gl.glPushAttrib(GL.GL_TRANSFORM_BIT);
5284: gl.glMatrixMode(GL.GL_TEXTURE);
5285:
5286: if (isIdentity) {
5287: gl.glLoadIdentity();
5288: } else if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
5289: gl.glLoadTransposeMatrixd(transform, 0);
5290: } else {
5291: double[] mx = new double[16];
5292: copyTranspose(transform, mx);
5293: gl.glLoadMatrixd(mx, 0);
5294: }
5295:
5296: gl.glPopAttrib();
5297:
5298: // set texture color
5299: float[] color = new float[4];
5300: color[0] = textureBlendColorRed;
5301: color[1] = textureBlendColorGreen;
5302: color[2] = textureBlendColorBlue;
5303: color[3] = textureBlendColorAlpha;
5304: gl.glTexEnvfv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_COLOR,
5305: color, 0);
5306:
5307: // set texture environment mode
5308:
5309: switch (textureMode) {
5310: case TextureAttributes.MODULATE:
5311: gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE,
5312: GL.GL_MODULATE);
5313: break;
5314: case TextureAttributes.DECAL:
5315: gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE,
5316: GL.GL_DECAL);
5317: break;
5318: case TextureAttributes.BLEND:
5319: gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE,
5320: GL.GL_BLEND);
5321: break;
5322: case TextureAttributes.REPLACE:
5323: gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE,
5324: GL.GL_REPLACE);
5325: break;
5326: case TextureAttributes.COMBINE:
5327: gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE,
5328: GL.GL_COMBINE);
5329: break;
5330: }
5331:
5332: if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) {
5333: gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI);
5334: }
5335: }
5336:
5337: void updateRegisterCombiners(Context absCtx, double[] transform,
5338: boolean isIdentity, int textureMode,
5339: int perspCorrectionMode, float textureBlendColorRed,
5340: float textureBlendColorGreen, float textureBlendColorBlue,
5341: float textureBlendColorAlpha, int textureFormat,
5342: int combineRgbMode, int combineAlphaMode,
5343: int[] combineRgbSrc, int[] combineAlphaSrc,
5344: int[] combineRgbFcn, int[] combineAlphaFcn,
5345: int combineRgbScale, int combineAlphaScale) {
5346: if (VERBOSE)
5347: System.err
5348: .println("JoglPipeline.updateRegisterCombiners()");
5349:
5350: JoglContext ctx = (JoglContext) absCtx;
5351: GL gl = context(ctx).getGL();
5352:
5353: if (perspCorrectionMode == TextureAttributes.NICEST) {
5354: gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
5355: } else {
5356: gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_FASTEST);
5357: }
5358:
5359: // set OGL texture matrix
5360: gl.glPushAttrib(GL.GL_TRANSFORM_BIT);
5361: gl.glMatrixMode(GL.GL_TEXTURE);
5362:
5363: if (isIdentity) {
5364: gl.glLoadIdentity();
5365: } else if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
5366: gl.glLoadTransposeMatrixd(transform, 0);
5367: } else {
5368: double[] mx = new double[16];
5369: copyTranspose(transform, mx);
5370: gl.glLoadMatrixd(mx, 0);
5371: }
5372:
5373: gl.glPopAttrib();
5374:
5375: // set texture color
5376: float[] color = new float[4];
5377: color[0] = textureBlendColorRed;
5378: color[1] = textureBlendColorGreen;
5379: color[2] = textureBlendColorBlue;
5380: color[3] = textureBlendColorAlpha;
5381: gl.glTexEnvfv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_COLOR,
5382: color, 0);
5383:
5384: // set texture environment mode
5385: gl.glEnable(GL.GL_REGISTER_COMBINERS_NV);
5386: int textureUnit = ctx.getCurrentTextureUnit();
5387: int combinerUnit = ctx.getCurrentCombinerUnit();
5388: int fragment;
5389: if (combinerUnit == GL.GL_COMBINER0_NV) {
5390: fragment = GL.GL_PRIMARY_COLOR_NV;
5391: } else {
5392: fragment = GL.GL_SPARE0_NV;
5393: }
5394:
5395: switch (textureMode) {
5396: case TextureAttributes.MODULATE:
5397: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5398: GL.GL_VARIABLE_A_NV, fragment,
5399: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5400: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5401: GL.GL_VARIABLE_B_NV, textureUnit,
5402: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5403: gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
5404: GL.GL_VARIABLE_A_NV, fragment,
5405: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
5406: gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
5407: GL.GL_VARIABLE_B_NV, textureUnit,
5408: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
5409:
5410: gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB,
5411: GL.GL_SPARE0_NV, GL.GL_DISCARD_NV,
5412: GL.GL_DISCARD_NV, GL.GL_NONE, GL.GL_NONE, false,
5413: false, false);
5414: gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA,
5415: GL.GL_SPARE0_NV, GL.GL_DISCARD_NV,
5416: GL.GL_DISCARD_NV, GL.GL_NONE, GL.GL_NONE, false,
5417: false, false);
5418: break;
5419:
5420: case TextureAttributes.DECAL:
5421: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5422: GL.GL_VARIABLE_A_NV, fragment,
5423: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5424: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5425: GL.GL_VARIABLE_B_NV, textureUnit,
5426: GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA);
5427: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5428: GL.GL_VARIABLE_C_NV, textureUnit,
5429: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5430: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5431: GL.GL_VARIABLE_D_NV, textureUnit,
5432: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
5433:
5434: gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
5435: GL.GL_VARIABLE_A_NV, fragment,
5436: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
5437: gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
5438: GL.GL_VARIABLE_B_NV, GL.GL_ZERO,
5439: GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA);
5440:
5441: gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB,
5442: GL.GL_DISCARD_NV, GL.GL_DISCARD_NV,
5443: GL.GL_SPARE0_NV, GL.GL_NONE, GL.GL_NONE, false,
5444: false, false);
5445: gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA,
5446: GL.GL_SPARE0_NV, GL.GL_DISCARD_NV,
5447: GL.GL_DISCARD_NV, GL.GL_NONE, GL.GL_NONE, false,
5448: false, false);
5449: break;
5450:
5451: case TextureAttributes.BLEND:
5452: gl.glCombinerParameterfvNV(GL.GL_CONSTANT_COLOR0_NV, color,
5453: 0);
5454:
5455: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5456: GL.GL_VARIABLE_A_NV, fragment,
5457: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5458: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5459: GL.GL_VARIABLE_B_NV, textureUnit,
5460: GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB);
5461: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5462: GL.GL_VARIABLE_C_NV, GL.GL_CONSTANT_COLOR0_NV,
5463: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5464: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5465: GL.GL_VARIABLE_D_NV, textureUnit,
5466: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5467:
5468: gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
5469: GL.GL_VARIABLE_A_NV, fragment,
5470: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
5471: gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
5472: GL.GL_VARIABLE_B_NV, textureUnit,
5473: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
5474:
5475: gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB,
5476: GL.GL_DISCARD_NV, GL.GL_DISCARD_NV,
5477: GL.GL_SPARE0_NV, GL.GL_NONE, GL.GL_NONE, false,
5478: false, false);
5479: gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA,
5480: GL.GL_SPARE0_NV, GL.GL_DISCARD_NV,
5481: GL.GL_DISCARD_NV, GL.GL_NONE, GL.GL_NONE, false,
5482: false, false);
5483: break;
5484:
5485: case TextureAttributes.REPLACE:
5486: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5487: GL.GL_VARIABLE_A_NV, textureUnit,
5488: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5489: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5490: GL.GL_VARIABLE_B_NV, GL.GL_ZERO,
5491: GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB);
5492: gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
5493: GL.GL_VARIABLE_A_NV, textureUnit,
5494: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
5495: gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
5496: GL.GL_VARIABLE_B_NV, GL.GL_ZERO,
5497: GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA);
5498:
5499: gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB,
5500: GL.GL_SPARE0_NV, GL.GL_DISCARD_NV,
5501: GL.GL_DISCARD_NV, GL.GL_NONE, GL.GL_NONE, false,
5502: false, false);
5503: gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA,
5504: GL.GL_SPARE0_NV, GL.GL_DISCARD_NV,
5505: GL.GL_DISCARD_NV, GL.GL_NONE, GL.GL_NONE, false,
5506: false, false);
5507: break;
5508:
5509: case TextureAttributes.COMBINE:
5510: if (combineRgbMode == TextureAttributes.COMBINE_DOT3) {
5511: int color1 = getCombinerArg(gl, combineRgbSrc[0],
5512: textureUnit, combinerUnit);
5513: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5514: GL.GL_VARIABLE_A_NV, color1,
5515: GL.GL_EXPAND_NORMAL_NV, GL.GL_RGB);
5516: int color2 = getCombinerArg(gl, combineRgbSrc[1],
5517: textureUnit, combinerUnit);
5518: gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
5519: GL.GL_VARIABLE_B_NV, color2,
5520: GL.GL_EXPAND_NORMAL_NV, GL.GL_RGB);
5521: gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
5522: GL.GL_VARIABLE_A_NV, GL.GL_ZERO,
5523: GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA);
5524: gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
5525: GL.GL_VARIABLE_B_NV, GL.GL_ZERO,
5526: GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA);
5527:
5528: gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB,
5529: GL.GL_SPARE0_NV, GL.GL_DISCARD_NV,
5530: GL.GL_DISCARD_NV,
5531: GL.GL_NONE/*SCALE_BY_FOUR_NV*/, GL.GL_NONE,
5532: true, false, false);
5533: gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA,
5534: GL.GL_SPARE0_NV, GL.GL_DISCARD_NV,
5535: GL.GL_DISCARD_NV, GL.GL_NONE, GL.GL_NONE,
5536: false, false, false);
5537: }
5538: break;
5539: }
5540:
5541: gl.glFinalCombinerInputNV(GL.GL_VARIABLE_A_NV, GL.GL_SPARE0_NV,
5542: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5543: gl.glFinalCombinerInputNV(GL.GL_VARIABLE_B_NV, GL.GL_ZERO,
5544: GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB);
5545: gl.glFinalCombinerInputNV(GL.GL_VARIABLE_C_NV, GL.GL_ZERO,
5546: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5547: gl.glFinalCombinerInputNV(GL.GL_VARIABLE_D_NV, GL.GL_ZERO,
5548: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5549: gl.glFinalCombinerInputNV(GL.GL_VARIABLE_E_NV, GL.GL_ZERO,
5550: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5551: gl.glFinalCombinerInputNV(GL.GL_VARIABLE_F_NV, GL.GL_ZERO,
5552: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
5553: gl.glFinalCombinerInputNV(GL.GL_VARIABLE_G_NV, GL.GL_SPARE0_NV,
5554: GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
5555:
5556: if (gl.isExtensionAvailable("GL_SGI_texture_color_table"))
5557: gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI);
5558: // GL_SGI_texture_color_table
5559: }
5560:
5561: void updateTextureColorTable(Context ctx, int numComponents,
5562: int colorTableSize, int[] textureColorTable) {
5563: if (VERBOSE)
5564: System.err
5565: .println("JoglPipeline.updateTextureColorTable()");
5566:
5567: GL gl = context(ctx).getGL();
5568: if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) {
5569: if (numComponents == 3) {
5570: gl.glColorTable(GL.GL_TEXTURE_COLOR_TABLE_SGI,
5571: GL.GL_RGB, colorTableSize, GL.GL_RGB,
5572: GL.GL_INT, IntBuffer.wrap(textureColorTable));
5573: } else {
5574: gl.glColorTable(GL.GL_TEXTURE_COLOR_TABLE_SGI,
5575: GL.GL_RGBA, colorTableSize, GL.GL_RGBA,
5576: GL.GL_INT, IntBuffer.wrap(textureColorTable));
5577: }
5578: gl.glEnable(GL.GL_TEXTURE_COLOR_TABLE_SGI);
5579: }
5580: }
5581:
5582: void updateCombiner(Context ctx, int combineRgbMode,
5583: int combineAlphaMode, int[] combineRgbSrc,
5584: int[] combineAlphaSrc, int[] combineRgbFcn,
5585: int[] combineAlphaFcn, int combineRgbScale,
5586: int combineAlphaScale) {
5587: if (VERBOSE)
5588: System.err.println("JoglPipeline.updateCombiner()");
5589:
5590: GL gl = context(ctx).getGL();
5591: int[] GLrgbMode = new int[1];
5592: int[] GLalphaMode = new int[1];
5593: getGLCombineMode(gl, combineRgbMode, combineAlphaMode,
5594: GLrgbMode, GLalphaMode);
5595: gl
5596: .glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB,
5597: GLrgbMode[0]);
5598: gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_ALPHA,
5599: GLalphaMode[0]);
5600:
5601: int nargs;
5602: if (combineRgbMode == TextureAttributes.COMBINE_REPLACE) {
5603: nargs = 1;
5604: } else if (combineRgbMode == TextureAttributes.COMBINE_INTERPOLATE) {
5605: nargs = 3;
5606: } else {
5607: nargs = 2;
5608: }
5609:
5610: for (int i = 0; i < nargs; i++) {
5611: gl.glTexEnvi(GL.GL_TEXTURE_ENV, _gl_combineRgbSrcIndex[i],
5612: _gl_combineSrc[combineRgbSrc[i]]);
5613: gl.glTexEnvi(GL.GL_TEXTURE_ENV, _gl_combineRgbOpIndex[i],
5614: _gl_combineFcn[combineRgbFcn[i]]);
5615: }
5616:
5617: if (combineAlphaMode == TextureAttributes.COMBINE_REPLACE) {
5618: nargs = 1;
5619: } else if (combineAlphaMode == TextureAttributes.COMBINE_INTERPOLATE) {
5620: nargs = 3;
5621: } else {
5622: nargs = 2;
5623: }
5624:
5625: for (int i = 0; i < nargs; i++) {
5626: gl.glTexEnvi(GL.GL_TEXTURE_ENV,
5627: _gl_combineAlphaSrcIndex[i],
5628: _gl_combineSrc[combineAlphaSrc[i]]);
5629: gl.glTexEnvi(GL.GL_TEXTURE_ENV, _gl_combineAlphaOpIndex[i],
5630: _gl_combineFcn[combineAlphaFcn[i]]);
5631: }
5632:
5633: gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_RGB_SCALE,
5634: combineRgbScale);
5635: gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_ALPHA_SCALE,
5636: combineAlphaScale);
5637: }
5638:
5639: // Helper routines for above
5640:
5641: private void getGLCombineMode(GL gl, int combineRgbMode,
5642: int combineAlphaMode, int[] GLrgbMode, int[] GLalphaMode) {
5643: switch (combineRgbMode) {
5644: case TextureAttributes.COMBINE_REPLACE:
5645: GLrgbMode[0] = GL.GL_REPLACE;
5646: break;
5647: case TextureAttributes.COMBINE_MODULATE:
5648: GLrgbMode[0] = GL.GL_MODULATE;
5649: break;
5650: case TextureAttributes.COMBINE_ADD:
5651: GLrgbMode[0] = GL.GL_ADD;
5652: break;
5653: case TextureAttributes.COMBINE_ADD_SIGNED:
5654: GLrgbMode[0] = GL.GL_ADD_SIGNED;
5655: break;
5656: case TextureAttributes.COMBINE_SUBTRACT:
5657: GLrgbMode[0] = GL.GL_SUBTRACT;
5658: break;
5659: case TextureAttributes.COMBINE_INTERPOLATE:
5660: GLrgbMode[0] = GL.GL_INTERPOLATE;
5661: break;
5662: case TextureAttributes.COMBINE_DOT3:
5663: GLrgbMode[0] = GL.GL_DOT3_RGB;
5664: break;
5665: default:
5666: break;
5667: }
5668:
5669: switch (combineAlphaMode) {
5670: case TextureAttributes.COMBINE_REPLACE:
5671: GLalphaMode[0] = GL.GL_REPLACE;
5672: break;
5673: case TextureAttributes.COMBINE_MODULATE:
5674: GLalphaMode[0] = GL.GL_MODULATE;
5675: break;
5676: case TextureAttributes.COMBINE_ADD:
5677: GLalphaMode[0] = GL.GL_ADD;
5678: break;
5679: case TextureAttributes.COMBINE_ADD_SIGNED:
5680: GLalphaMode[0] = GL.GL_ADD_SIGNED;
5681: break;
5682: case TextureAttributes.COMBINE_SUBTRACT:
5683: GLalphaMode[0] = GL.GL_SUBTRACT;
5684: break;
5685: case TextureAttributes.COMBINE_INTERPOLATE:
5686: GLalphaMode[0] = GL.GL_INTERPOLATE;
5687: break;
5688: case TextureAttributes.COMBINE_DOT3:
5689: // dot3 will only make sense for alpha if rgb is also
5690: // doing dot3. So if rgb is not doing dot3, fallback to replace
5691: if (combineRgbMode == TextureAttributes.COMBINE_DOT3) {
5692: GLrgbMode[0] = GL.GL_DOT3_RGBA;
5693: } else {
5694: GLalphaMode[0] = GL.GL_REPLACE;
5695: }
5696: break;
5697: default:
5698: break;
5699: }
5700: }
5701:
5702: // mapping from java enum to gl enum
5703: private static final int[] _gl_combineRgbSrcIndex = {
5704: GL.GL_SOURCE0_RGB, GL.GL_SOURCE1_RGB, GL.GL_SOURCE2_RGB, };
5705:
5706: private static final int[] _gl_combineAlphaSrcIndex = {
5707: GL.GL_SOURCE0_ALPHA, GL.GL_SOURCE1_ALPHA,
5708: GL.GL_SOURCE2_ALPHA, };
5709:
5710: private static final int[] _gl_combineRgbOpIndex = {
5711: GL.GL_OPERAND0_RGB, GL.GL_OPERAND1_RGB, GL.GL_OPERAND2_RGB, };
5712:
5713: private static final int[] _gl_combineAlphaOpIndex = {
5714: GL.GL_OPERAND0_ALPHA, GL.GL_OPERAND1_ALPHA,
5715: GL.GL_OPERAND2_ALPHA, };
5716:
5717: private static final int[] _gl_combineSrc = { GL.GL_PRIMARY_COLOR, // TextureAttributes.COMBINE_OBJECT_COLOR
5718: GL.GL_TEXTURE, // TextureAttributes.COMBINE_TEXTURE
5719: GL.GL_CONSTANT, // TextureAttributes.COMBINE_CONSTANT_COLOR
5720: GL.GL_PREVIOUS, // TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE
5721: };
5722:
5723: private static final int[] _gl_combineFcn = { GL.GL_SRC_COLOR, // TextureAttributes.COMBINE_SRC_COLOR
5724: GL.GL_ONE_MINUS_SRC_COLOR, // TextureAttributes.COMBINE_ONE_MINUS_SRC_COLOR
5725: GL.GL_SRC_ALPHA, // TextureAttributes.COMBINE_SRC_ALPHA
5726: GL.GL_ONE_MINUS_SRC_ALPHA, // TextureAttributes.COMBINE_ONE_MINUS_SRC_ALPHA
5727: };
5728:
5729: private int getCombinerArg(GL gl, int arg, int textureUnit,
5730: int combUnit) {
5731: int comb = 0;
5732:
5733: switch (arg) {
5734: case TextureAttributes.COMBINE_OBJECT_COLOR:
5735: if (combUnit == GL.GL_COMBINER0_NV) {
5736: comb = GL.GL_PRIMARY_COLOR_NV;
5737: } else {
5738: comb = GL.GL_SPARE0_NV;
5739: }
5740: break;
5741: case TextureAttributes.COMBINE_TEXTURE_COLOR:
5742: comb = textureUnit;
5743: break;
5744: case TextureAttributes.COMBINE_CONSTANT_COLOR:
5745: comb = GL.GL_CONSTANT_COLOR0_NV;
5746: break;
5747: case TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE:
5748: comb = textureUnit - 1;
5749: break;
5750: }
5751:
5752: return comb;
5753: }
5754:
5755: // ---------------------------------------------------------------------
5756:
5757: //
5758: // TextureUnitStateRetained methods
5759: //
5760:
5761: void updateTextureUnitState(Context ctx, int index, boolean enable) {
5762: if (VERBOSE)
5763: System.err.println("JoglPipeline.updateTextureUnitState()");
5764:
5765: GL gl = context(ctx).getGL();
5766: JoglContext jctx = (JoglContext) ctx;
5767:
5768: if (index >= 0 && gl.isExtensionAvailable("GL_VERSION_1_3")) {
5769: gl.glActiveTexture(index + GL.GL_TEXTURE0);
5770: gl.glClientActiveTexture(GL.GL_TEXTURE0 + index);
5771: if (gl.isExtensionAvailable("GL_NV_register_combiners")) {
5772: jctx.setCurrentTextureUnit(index + GL.GL_TEXTURE0);
5773: jctx.setCurrentCombinerUnit(index + GL.GL_COMBINER0_NV);
5774: gl.glCombinerParameteriNV(
5775: GL.GL_NUM_GENERAL_COMBINERS_NV, index + 1);
5776: }
5777: }
5778:
5779: if (!enable) {
5780: // if not enabled, then don't enable any tex mapping
5781: gl.glDisable(GL.GL_TEXTURE_1D);
5782: gl.glDisable(GL.GL_TEXTURE_2D);
5783: gl.glDisable(GL.GL_TEXTURE_3D);
5784: gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
5785: }
5786:
5787: // if it is enabled, the enable flag will be taken care of
5788: // in the bindTexture call
5789: }
5790:
5791: // ---------------------------------------------------------------------
5792:
5793: //
5794: // TextureRetained methods
5795: // Texture2DRetained methods
5796: //
5797:
5798: void bindTexture2D(Context ctx, int objectId, boolean enable) {
5799: if (VERBOSE)
5800: System.err.println("JoglPipeline.bindTexture2D(objectId="
5801: + objectId + ",enable=" + enable + ")");
5802:
5803: GL gl = context(ctx).getGL();
5804: gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
5805: gl.glDisable(GL.GL_TEXTURE_3D);
5806:
5807: if (!enable) {
5808: gl.glDisable(GL.GL_TEXTURE_2D);
5809: } else {
5810: gl.glBindTexture(GL.GL_TEXTURE_2D, objectId);
5811: gl.glEnable(GL.GL_TEXTURE_2D);
5812: }
5813: }
5814:
5815: void updateTexture2DImage(Context ctx, int numLevels, int level,
5816: int textureFormat, int imageFormat, int width, int height,
5817: int boundaryWidth, int dataType, Object data,
5818: boolean useAutoMipMap) {
5819: if (VERBOSE)
5820: System.err
5821: .println("JoglPipeline.updateTexture2DImage(width="
5822: + width + ",height=" + height + ",level="
5823: + level + ")");
5824:
5825: updateTexture2DImage(ctx, GL.GL_TEXTURE_2D, numLevels, level,
5826: textureFormat, imageFormat, width, height,
5827: boundaryWidth, dataType, data, useAutoMipMap);
5828: }
5829:
5830: void updateTexture2DSubImage(Context ctx, int level, int xoffset,
5831: int yoffset, int textureFormat, int imageFormat,
5832: int imgXOffset, int imgYOffset, int tilew, int width,
5833: int height, int dataType, Object data, boolean useAutoMipMap) {
5834:
5835: /* Note: useAutoMipMap is not use for SubImage in the jogl pipe */
5836:
5837: if (VERBOSE)
5838: System.err
5839: .println("JoglPipeline.updateTexture2DSubImage()");
5840:
5841: updateTexture2DSubImage(ctx, GL.GL_TEXTURE_2D, level, xoffset,
5842: yoffset, textureFormat, imageFormat, imgXOffset,
5843: imgYOffset, tilew, width, height, dataType, data);
5844: }
5845:
5846: void updateTexture2DLodRange(Context ctx, int baseLevel,
5847: int maximumLevel, float minimumLOD, float maximumLOD) {
5848: if (VERBOSE)
5849: System.err
5850: .println("JoglPipeline.updateTexture2DLodRange()");
5851:
5852: updateTextureLodRange(ctx, GL.GL_TEXTURE_2D, baseLevel,
5853: maximumLevel, minimumLOD, maximumLOD);
5854: }
5855:
5856: void updateTexture2DLodOffset(Context ctx, float lodOffsetS,
5857: float lodOffsetT, float lodOffsetR) {
5858: if (VERBOSE)
5859: System.err
5860: .println("JoglPipeline.updateTexture2DLodOffset()");
5861:
5862: updateTextureLodOffset(ctx, GL.GL_TEXTURE_2D, lodOffsetS,
5863: lodOffsetT, lodOffsetR);
5864: }
5865:
5866: void updateTexture2DBoundary(Context ctx, int boundaryModeS,
5867: int boundaryModeT, float boundaryRed, float boundaryGreen,
5868: float boundaryBlue, float boundaryAlpha) {
5869: if (VERBOSE)
5870: System.err
5871: .println("JoglPipeline.updateTexture2DBoundary()");
5872:
5873: updateTextureBoundary(ctx, GL.GL_TEXTURE_2D, boundaryModeS,
5874: boundaryModeT, -1, boundaryRed, boundaryGreen,
5875: boundaryBlue, boundaryAlpha);
5876: }
5877:
5878: void updateTexture2DFilterModes(Context ctx, int minFilter,
5879: int magFilter) {
5880: if (VERBOSE)
5881: System.err
5882: .println("JoglPipeline.updateTexture2DFilterModes()");
5883:
5884: updateTextureFilterModes(ctx, GL.GL_TEXTURE_2D, minFilter,
5885: magFilter);
5886: }
5887:
5888: void updateTexture2DSharpenFunc(Context ctx,
5889: int numSharpenTextureFuncPts, float[] sharpenTextureFuncPts) {
5890: if (VERBOSE)
5891: System.err
5892: .println("JoglPipeline.updateTexture2DSharpenFunc()");
5893:
5894: updateTextureSharpenFunc(ctx, GL.GL_TEXTURE_2D,
5895: numSharpenTextureFuncPts, sharpenTextureFuncPts);
5896: }
5897:
5898: void updateTexture2DFilter4Func(Context ctx, int numFilter4FuncPts,
5899: float[] filter4FuncPts) {
5900: if (VERBOSE)
5901: System.err
5902: .println("JoglPipeline.updateTexture2DFilter4Func()");
5903:
5904: updateTextureFilter4Func(ctx, GL.GL_TEXTURE_2D,
5905: numFilter4FuncPts, filter4FuncPts);
5906: }
5907:
5908: void updateTexture2DAnisotropicFilter(Context ctx, float degree) {
5909: if (VERBOSE)
5910: System.err
5911: .println("JoglPipeline.updateTexture2DAnisotropicFilter()");
5912:
5913: updateTextureAnisotropicFilter(ctx, GL.GL_TEXTURE_2D, degree);
5914: }
5915:
5916: private void updateTextureLodRange(Context ctx, int target,
5917: int baseLevel, int maximumLevel, float minimumLOD,
5918: float maximumLOD) {
5919: GL gl = context(ctx).getGL();
5920: // checking of the availability of the extension is already done
5921: // in the shared code
5922: gl.glTexParameteri(target, GL.GL_TEXTURE_BASE_LEVEL, baseLevel);
5923: gl.glTexParameteri(target, GL.GL_TEXTURE_MAX_LEVEL,
5924: maximumLevel);
5925: gl.glTexParameterf(target, GL.GL_TEXTURE_MIN_LOD, minimumLOD);
5926: gl.glTexParameterf(target, GL.GL_TEXTURE_MAX_LOD, maximumLOD);
5927: }
5928:
5929: private void updateTextureLodOffset(Context ctx, int target,
5930: float lodOffsetS, float lodOffsetT, float lodOffsetR) {
5931: GL gl = context(ctx).getGL();
5932: // checking of the availability of the extension is already done
5933: // in the shared code
5934: gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_S_SGIX,
5935: lodOffsetS);
5936: gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_T_SGIX,
5937: lodOffsetT);
5938: gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_R_SGIX,
5939: lodOffsetR);
5940: }
5941:
5942: private void updateTextureAnisotropicFilter(Context ctx,
5943: int target, float degree) {
5944: GL gl = context(ctx).getGL();
5945: // checking of the availability of anisotropic filter functionality
5946: // is already done in the shared code
5947: gl.glTexParameterf(target, GL.GL_TEXTURE_MAX_ANISOTROPY_EXT,
5948: degree);
5949: }
5950:
5951: // ---------------------------------------------------------------------
5952:
5953: //
5954: // Texture3DRetained methods
5955: //
5956:
5957: void bindTexture3D(Context ctx, int objectId, boolean enable) {
5958: if (VERBOSE)
5959: System.err.println("JoglPipeline.bindTexture3D()");
5960:
5961: GL gl = context(ctx).getGL();
5962: // textureCubeMap will take precedure over 3D Texture
5963: gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
5964:
5965: if (!enable) {
5966: gl.glDisable(GL.GL_TEXTURE_3D);
5967: } else {
5968: gl.glBindTexture(GL.GL_TEXTURE_3D, objectId);
5969: gl.glEnable(GL.GL_TEXTURE_3D);
5970: }
5971: }
5972:
5973: void updateTexture3DImage(Context ctx, int numLevels, int level,
5974: int textureFormat, int imageFormat, int width, int height,
5975: int depth, int boundaryWidth, int dataType, Object data,
5976: boolean useAutoMipMap) {
5977:
5978: if (VERBOSE)
5979: System.err.println("JoglPipeline.updateTexture3DImage()");
5980:
5981: GL gl = context(ctx).getGL();
5982:
5983: int format = 0;
5984: int internalFormat = 0;
5985: int type = GL.GL_UNSIGNED_INT_8_8_8_8;
5986: boolean forceAlphaToOne = false;
5987:
5988: switch (textureFormat) {
5989: case Texture.INTENSITY:
5990: internalFormat = GL.GL_INTENSITY;
5991: break;
5992: case Texture.LUMINANCE:
5993: internalFormat = GL.GL_LUMINANCE;
5994: break;
5995: case Texture.ALPHA:
5996: internalFormat = GL.GL_ALPHA;
5997: break;
5998: case Texture.LUMINANCE_ALPHA:
5999: internalFormat = GL.GL_LUMINANCE_ALPHA;
6000: break;
6001: case Texture.RGB:
6002: internalFormat = GL.GL_RGB;
6003: break;
6004: case Texture.RGBA:
6005: internalFormat = GL.GL_RGBA;
6006: break;
6007: default:
6008: assert false;
6009: return;
6010: }
6011:
6012: if (useAutoMipMap) {
6013: gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_GENERATE_MIPMAP,
6014: GL.GL_TRUE);
6015: } else {
6016: gl.glTexParameteri(GL.GL_TEXTURE_3D, GL.GL_GENERATE_MIPMAP,
6017: GL.GL_FALSE);
6018: }
6019:
6020: if ((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY)
6021: || (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) {
6022:
6023: switch (imageFormat) {
6024: case ImageComponentRetained.TYPE_BYTE_BGR:
6025: format = GL.GL_BGR;
6026: break;
6027: case ImageComponentRetained.TYPE_BYTE_RGB:
6028: format = GL.GL_RGB;
6029: break;
6030: case ImageComponentRetained.TYPE_BYTE_ABGR:
6031: if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here!
6032: format = GL.GL_ABGR_EXT;
6033: } else {
6034: assert false;
6035: return;
6036: }
6037: break;
6038: case ImageComponentRetained.TYPE_BYTE_RGBA:
6039: // all RGB types are stored as RGBA
6040: format = GL.GL_RGBA;
6041: break;
6042: case ImageComponentRetained.TYPE_BYTE_LA:
6043: // all LA types are stored as LA8
6044: format = GL.GL_LUMINANCE_ALPHA;
6045: break;
6046: case ImageComponentRetained.TYPE_BYTE_GRAY:
6047: if (internalFormat == GL.GL_ALPHA) {
6048: format = GL.GL_ALPHA;
6049: } else {
6050: format = GL.GL_LUMINANCE;
6051: }
6052: break;
6053: case ImageComponentRetained.TYPE_USHORT_GRAY:
6054: case ImageComponentRetained.TYPE_INT_BGR:
6055: case ImageComponentRetained.TYPE_INT_RGB:
6056: case ImageComponentRetained.TYPE_INT_ARGB:
6057: default:
6058: assert false;
6059: return;
6060: }
6061:
6062: if (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) {
6063:
6064: gl.glTexImage3D(GL.GL_TEXTURE_3D, level,
6065: internalFormat, width, height, depth,
6066: boundaryWidth, format, GL.GL_UNSIGNED_BYTE,
6067: ByteBuffer.wrap((byte[]) data));
6068: } else {
6069: gl.glTexImage3D(GL.GL_TEXTURE_3D, level,
6070: internalFormat, width, height, depth,
6071: boundaryWidth, format, GL.GL_UNSIGNED_BYTE,
6072: (ByteBuffer) data);
6073: }
6074:
6075: } else if ((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY)
6076: || (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) {
6077:
6078: switch (imageFormat) {
6079: /* GL_BGR */
6080: case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
6081: format = GL.GL_RGBA;
6082: type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
6083: forceAlphaToOne = true;
6084: break;
6085: case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
6086: forceAlphaToOne = true;
6087: /* Fall through to next case */
6088: case ImageComponentRetained.TYPE_INT_ARGB:
6089: format = GL.GL_BGRA;
6090: type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
6091: break;
6092: /* This method only supports 3 and 4 components formats and INT types. */
6093: case ImageComponentRetained.TYPE_BYTE_LA:
6094: case ImageComponentRetained.TYPE_BYTE_GRAY:
6095: case ImageComponentRetained.TYPE_USHORT_GRAY:
6096: case ImageComponentRetained.TYPE_BYTE_BGR:
6097: case ImageComponentRetained.TYPE_BYTE_RGB:
6098: case ImageComponentRetained.TYPE_BYTE_RGBA:
6099: case ImageComponentRetained.TYPE_BYTE_ABGR:
6100: default:
6101: assert false;
6102: return;
6103: }
6104:
6105: /* Force Alpha to 1.0 if needed */
6106: if (forceAlphaToOne) {
6107: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
6108: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
6109: }
6110:
6111: if (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) {
6112: gl.glTexImage3D(GL.GL_TEXTURE_3D, level,
6113: internalFormat, width, height, depth,
6114: boundaryWidth, format, type, IntBuffer
6115: .wrap((int[]) data));
6116: } else {
6117: gl.glTexImage3D(GL.GL_TEXTURE_3D, level,
6118: internalFormat, width, height, depth,
6119: boundaryWidth, format, type, (Buffer) data);
6120: }
6121:
6122: /* Restore Alpha scale and bias */
6123: if (forceAlphaToOne) {
6124: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
6125: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
6126: }
6127: } else {
6128: assert false;
6129: }
6130: }
6131:
6132: void updateTexture3DSubImage(Context ctx, int level, int xoffset,
6133: int yoffset, int zoffset, int textureFormat,
6134: int imageFormat, int imgXOffset, int imgYOffset,
6135: int imgZOffset, int tilew, int tileh, int width,
6136: int height, int depth, int dataType, Object data,
6137: boolean useAutoMipMap) {
6138:
6139: /* Note: useAutoMipMap is not use for SubImage in the jogl pipe */
6140:
6141: if (VERBOSE)
6142: System.err
6143: .println("JoglPipeline.updateTexture3DSubImage()");
6144:
6145: GL gl = context(ctx).getGL();
6146:
6147: int format = 0;
6148: int internalFormat = 0;
6149: int type = GL.GL_UNSIGNED_INT_8_8_8_8;
6150: int numBytes = 0;
6151: boolean forceAlphaToOne = false;
6152: boolean pixelStore = false;
6153:
6154: if (imgXOffset > 0 || (width < tilew)) {
6155: pixelStore = true;
6156: gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, tilew);
6157: }
6158:
6159: switch (textureFormat) {
6160: case Texture.INTENSITY:
6161: internalFormat = GL.GL_INTENSITY;
6162: break;
6163: case Texture.LUMINANCE:
6164: internalFormat = GL.GL_LUMINANCE;
6165: break;
6166: case Texture.ALPHA:
6167: internalFormat = GL.GL_ALPHA;
6168: break;
6169: case Texture.LUMINANCE_ALPHA:
6170: internalFormat = GL.GL_LUMINANCE_ALPHA;
6171: break;
6172: case Texture.RGB:
6173: internalFormat = GL.GL_RGB;
6174: break;
6175: case Texture.RGBA:
6176: internalFormat = GL.GL_RGBA;
6177: break;
6178: default:
6179: assert false;
6180: }
6181:
6182: if ((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY)
6183: || (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) {
6184:
6185: switch (imageFormat) {
6186: case ImageComponentRetained.TYPE_BYTE_BGR:
6187: format = GL.GL_BGR;
6188: numBytes = 3;
6189: break;
6190: case ImageComponentRetained.TYPE_BYTE_RGB:
6191: format = GL.GL_RGB;
6192: numBytes = 3;
6193: break;
6194: case ImageComponentRetained.TYPE_BYTE_ABGR:
6195: if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here!
6196: format = GL.GL_ABGR_EXT;
6197: numBytes = 4;
6198: } else {
6199: assert false;
6200: return;
6201: }
6202: break;
6203: case ImageComponentRetained.TYPE_BYTE_RGBA:
6204: // all RGB types are stored as RGBA
6205: format = GL.GL_RGBA;
6206: numBytes = 4;
6207: break;
6208: case ImageComponentRetained.TYPE_BYTE_LA:
6209: // all LA types are stored as LA8
6210: format = GL.GL_LUMINANCE_ALPHA;
6211: numBytes = 2;
6212: break;
6213: case ImageComponentRetained.TYPE_BYTE_GRAY:
6214: if (internalFormat == GL.GL_ALPHA) {
6215: format = GL.GL_ALPHA;
6216: numBytes = 1;
6217: } else {
6218: format = GL.GL_LUMINANCE;
6219: numBytes = 1;
6220: }
6221: break;
6222: case ImageComponentRetained.TYPE_USHORT_GRAY:
6223: case ImageComponentRetained.TYPE_INT_BGR:
6224: case ImageComponentRetained.TYPE_INT_RGB:
6225: case ImageComponentRetained.TYPE_INT_ARGB:
6226: default:
6227: assert false;
6228: return;
6229: }
6230:
6231: ByteBuffer buf = null;
6232: if (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) {
6233: buf = ByteBuffer.wrap((byte[]) data);
6234: } else {
6235: buf = (ByteBuffer) data;
6236: }
6237:
6238: int offset = (tilew * tileh * imgZOffset + tilew
6239: * imgYOffset + imgXOffset)
6240: * numBytes;
6241: buf.position(offset);
6242: gl.glTexSubImage3D(GL.GL_TEXTURE_3D, level, xoffset,
6243: yoffset, zoffset, width, height, depth, format,
6244: GL.GL_UNSIGNED_BYTE, buf);
6245:
6246: } else if ((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY)
6247: || (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) {
6248:
6249: switch (imageFormat) {
6250: /* GL_BGR */
6251: case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
6252: format = GL.GL_RGBA;
6253: type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
6254: forceAlphaToOne = true;
6255: break;
6256: case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
6257: forceAlphaToOne = true;
6258: /* Fall through to next case */
6259: case ImageComponentRetained.TYPE_INT_ARGB:
6260: format = GL.GL_BGRA;
6261: type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
6262: break;
6263: /* This method only supports 3 and 4 components formats and INT types. */
6264: case ImageComponentRetained.TYPE_BYTE_LA:
6265: case ImageComponentRetained.TYPE_BYTE_GRAY:
6266: case ImageComponentRetained.TYPE_USHORT_GRAY:
6267: case ImageComponentRetained.TYPE_BYTE_BGR:
6268: case ImageComponentRetained.TYPE_BYTE_RGB:
6269: case ImageComponentRetained.TYPE_BYTE_RGBA:
6270: case ImageComponentRetained.TYPE_BYTE_ABGR:
6271: default:
6272: assert false;
6273: return;
6274: }
6275:
6276: /* Force Alpha to 1.0 if needed */
6277: if (forceAlphaToOne) {
6278: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
6279: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
6280: }
6281:
6282: IntBuffer buf = null;
6283: if (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) {
6284: buf = IntBuffer.wrap((int[]) data);
6285: } else {
6286: buf = (IntBuffer) data;
6287: }
6288:
6289: int offset = tilew * tileh * imgZOffset + tilew
6290: * imgYOffset + imgXOffset;
6291: buf.position(offset);
6292: gl.glTexSubImage3D(GL.GL_TEXTURE_3D, level, xoffset,
6293: yoffset, zoffset, width, height, depth, format,
6294: type, buf);
6295:
6296: /* Restore Alpha scale and bias */
6297: if (forceAlphaToOne) {
6298: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
6299: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
6300: }
6301: } else {
6302: assert false;
6303: return;
6304: }
6305:
6306: if (pixelStore) {
6307: gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
6308: }
6309:
6310: }
6311:
6312: void updateTexture3DLodRange(Context ctx, int baseLevel,
6313: int maximumLevel, float minimumLod, float maximumLod) {
6314: if (VERBOSE)
6315: System.err
6316: .println("JoglPipeline.updateTexture3DLodRange()");
6317:
6318: updateTextureLodRange(ctx, GL.GL_TEXTURE_3D, baseLevel,
6319: maximumLevel, minimumLod, maximumLod);
6320: }
6321:
6322: void updateTexture3DLodOffset(Context ctx, float lodOffsetS,
6323: float lodOffsetT, float lodOffsetR) {
6324: if (VERBOSE)
6325: System.err
6326: .println("JoglPipeline.updateTexture3DLodOffset()");
6327:
6328: updateTextureLodOffset(ctx, GL.GL_TEXTURE_3D, lodOffsetS,
6329: lodOffsetT, lodOffsetR);
6330: }
6331:
6332: void updateTexture3DBoundary(Context ctx, int boundaryModeS,
6333: int boundaryModeT, int boundaryModeR, float boundaryRed,
6334: float boundaryGreen, float boundaryBlue, float boundaryAlpha) {
6335: if (VERBOSE)
6336: System.err
6337: .println("JoglPipeline.updateTexture3DBoundary()");
6338:
6339: updateTextureBoundary(ctx, GL.GL_TEXTURE_2D, boundaryModeS,
6340: boundaryModeT, boundaryModeR, boundaryRed,
6341: boundaryGreen, boundaryBlue, boundaryAlpha);
6342: }
6343:
6344: void updateTexture3DFilterModes(Context ctx, int minFilter,
6345: int magFilter) {
6346: if (VERBOSE)
6347: System.err
6348: .println("JoglPipeline.updateTexture3DFilterModes()");
6349:
6350: updateTextureFilterModes(ctx, GL.GL_TEXTURE_3D, minFilter,
6351: magFilter);
6352: }
6353:
6354: void updateTexture3DSharpenFunc(Context ctx,
6355: int numSharpenTextureFuncPts, float[] sharpenTextureFuncPts) {
6356: if (VERBOSE)
6357: System.err
6358: .println("JoglPipeline.updateTexture3DSharpenFunc()");
6359:
6360: updateTextureSharpenFunc(ctx, GL.GL_TEXTURE_3D,
6361: numSharpenTextureFuncPts, sharpenTextureFuncPts);
6362: }
6363:
6364: void updateTexture3DFilter4Func(Context ctx, int numFilter4FuncPts,
6365: float[] filter4FuncPts) {
6366: if (VERBOSE)
6367: System.err
6368: .println("JoglPipeline.updateTexture3DFilter4Func()");
6369:
6370: updateTextureFilter4Func(ctx, GL.GL_TEXTURE_3D,
6371: numFilter4FuncPts, filter4FuncPts);
6372: }
6373:
6374: void updateTexture3DAnisotropicFilter(Context ctx, float degree) {
6375: if (VERBOSE)
6376: System.err
6377: .println("JoglPipeline.updateTexture3DAnisotropicFilter()");
6378:
6379: updateTextureAnisotropicFilter(ctx, GL.GL_TEXTURE_3D, degree);
6380: }
6381:
6382: // ---------------------------------------------------------------------
6383:
6384: //
6385: // TextureCubeMapRetained methods
6386: //
6387:
6388: void bindTextureCubeMap(Context ctx, int objectId, boolean enable) {
6389: if (VERBOSE)
6390: System.err.println("JoglPipeline.bindTextureCubeMap()");
6391:
6392: GL gl = context(ctx).getGL();
6393: // TextureCubeMap will take precedure over 3D Texture so
6394: // there is no need to disable 3D Texture here.
6395: if (!enable) {
6396: gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
6397: } else {
6398: gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, objectId);
6399: gl.glEnable(GL.GL_TEXTURE_CUBE_MAP);
6400: }
6401: }
6402:
6403: void updateTextureCubeMapImage(Context ctx, int face,
6404: int numLevels, int level, int textureFormat,
6405: int imageFormat, int width, int height, int boundaryWidth,
6406: int dataType, Object data, boolean useAutoMipMap) {
6407: if (VERBOSE)
6408: System.err
6409: .println("JoglPipeline.updateTextureCubeMapImage()");
6410:
6411: updateTexture2DImage(ctx, _gl_textureCubeMapFace[face],
6412: numLevels, level, textureFormat, imageFormat, width,
6413: height, boundaryWidth, dataType, data, useAutoMipMap);
6414: }
6415:
6416: void updateTextureCubeMapSubImage(Context ctx, int face, int level,
6417: int xoffset, int yoffset, int textureFormat,
6418: int imageFormat, int imgXOffset, int imgYOffset, int tilew,
6419: int width, int height, int dataType, Object data,
6420: boolean useAutoMipMap) {
6421:
6422: /* Note: useAutoMipMap is not use for SubImage in the jogl pipe */
6423:
6424: if (VERBOSE)
6425: System.err
6426: .println("JoglPipeline.updateTextureCubeMapSubImage()");
6427:
6428: updateTexture2DSubImage(ctx, _gl_textureCubeMapFace[face],
6429: level, xoffset, yoffset, textureFormat, imageFormat,
6430: imgXOffset, imgYOffset, tilew, width, height, dataType,
6431: data);
6432: }
6433:
6434: void updateTextureCubeMapLodRange(Context ctx, int baseLevel,
6435: int maximumLevel, float minimumLod, float maximumLod) {
6436: if (VERBOSE)
6437: System.err
6438: .println("JoglPipeline.updateTextureCubeMapLodRange()");
6439:
6440: updateTextureLodRange(ctx, GL.GL_TEXTURE_CUBE_MAP, baseLevel,
6441: maximumLevel, minimumLod, maximumLod);
6442: }
6443:
6444: void updateTextureCubeMapLodOffset(Context ctx, float lodOffsetS,
6445: float lodOffsetT, float lodOffsetR) {
6446: if (VERBOSE)
6447: System.err
6448: .println("JoglPipeline.updateTextureCubeMapLodOffset()");
6449:
6450: updateTextureLodOffset(ctx, GL.GL_TEXTURE_CUBE_MAP, lodOffsetS,
6451: lodOffsetT, lodOffsetR);
6452: }
6453:
6454: void updateTextureCubeMapBoundary(Context ctx, int boundaryModeS,
6455: int boundaryModeT, float boundaryRed, float boundaryGreen,
6456: float boundaryBlue, float boundaryAlpha) {
6457: if (VERBOSE)
6458: System.err
6459: .println("JoglPipeline.updateTextureCubeMapBoundary()");
6460:
6461: updateTextureBoundary(ctx, GL.GL_TEXTURE_CUBE_MAP,
6462: boundaryModeS, boundaryModeT, -1, boundaryRed,
6463: boundaryGreen, boundaryBlue, boundaryAlpha);
6464: }
6465:
6466: void updateTextureCubeMapFilterModes(Context ctx, int minFilter,
6467: int magFilter) {
6468: if (VERBOSE)
6469: System.err
6470: .println("JoglPipeline.updateTextureCubeMapFilterModes()");
6471:
6472: updateTextureFilterModes(ctx, GL.GL_TEXTURE_CUBE_MAP,
6473: minFilter, magFilter);
6474: }
6475:
6476: void updateTextureCubeMapSharpenFunc(Context ctx,
6477: int numSharpenTextureFuncPts, float[] sharpenTextureFuncPts) {
6478: if (VERBOSE)
6479: System.err
6480: .println("JoglPipeline.updateTextureCubeMapSharpenFunc()");
6481:
6482: updateTextureSharpenFunc(ctx, GL.GL_TEXTURE_CUBE_MAP,
6483: numSharpenTextureFuncPts, sharpenTextureFuncPts);
6484: }
6485:
6486: void updateTextureCubeMapFilter4Func(Context ctx,
6487: int numFilter4FuncPts, float[] filter4FuncPts) {
6488: if (VERBOSE)
6489: System.err
6490: .println("JoglPipeline.updateTextureCubeMapFilter4Func()");
6491:
6492: updateTextureFilter4Func(ctx, GL.GL_TEXTURE_CUBE_MAP,
6493: numFilter4FuncPts, filter4FuncPts);
6494: }
6495:
6496: void updateTextureCubeMapAnisotropicFilter(Context ctx, float degree) {
6497: if (VERBOSE)
6498: System.err
6499: .println("JoglPipeline.updateTextureCubeMapAnisotropicFilter()");
6500:
6501: updateTextureAnisotropicFilter(ctx, GL.GL_TEXTURE_CUBE_MAP,
6502: degree);
6503: }
6504:
6505: //----------------------------------------------------------------------
6506: //
6507: // Helper routines for above texture methods
6508: //
6509:
6510: private void updateTexture2DImage(Context ctx, int target,
6511: int numLevels, int level, int textureFormat,
6512: int imageFormat, int width, int height, int boundaryWidth,
6513: int dataType, Object data, boolean useAutoMipMap) {
6514: GL gl = context(ctx).getGL();
6515:
6516: int format = 0, internalFormat = 0;
6517: int type = GL.GL_UNSIGNED_INT_8_8_8_8;
6518: boolean forceAlphaToOne = false;
6519:
6520: switch (textureFormat) {
6521: case Texture.INTENSITY:
6522: internalFormat = GL.GL_INTENSITY;
6523: break;
6524: case Texture.LUMINANCE:
6525: internalFormat = GL.GL_LUMINANCE;
6526: break;
6527: case Texture.ALPHA:
6528: internalFormat = GL.GL_ALPHA;
6529: break;
6530: case Texture.LUMINANCE_ALPHA:
6531: internalFormat = GL.GL_LUMINANCE_ALPHA;
6532: break;
6533: case Texture.RGB:
6534: internalFormat = GL.GL_RGB;
6535: break;
6536: case Texture.RGBA:
6537: internalFormat = GL.GL_RGBA;
6538: break;
6539: default:
6540: assert false;
6541: }
6542:
6543: if (useAutoMipMap) {
6544: gl.glTexParameteri(target, GL.GL_GENERATE_MIPMAP,
6545: GL.GL_TRUE);
6546: } else {
6547: gl.glTexParameteri(target, GL.GL_GENERATE_MIPMAP,
6548: GL.GL_FALSE);
6549: }
6550:
6551: if ((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY)
6552: || (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) {
6553:
6554: switch (imageFormat) {
6555: case ImageComponentRetained.TYPE_BYTE_BGR:
6556: format = GL.GL_BGR;
6557: break;
6558: case ImageComponentRetained.TYPE_BYTE_RGB:
6559: format = GL.GL_RGB;
6560: break;
6561: case ImageComponentRetained.TYPE_BYTE_ABGR:
6562: if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here!
6563: format = GL.GL_ABGR_EXT;
6564: } else {
6565: assert false;
6566: return;
6567: }
6568: break;
6569: case ImageComponentRetained.TYPE_BYTE_RGBA:
6570: // all RGB types are stored as RGBA
6571: format = GL.GL_RGBA;
6572: break;
6573: case ImageComponentRetained.TYPE_BYTE_LA:
6574: // all LA types are stored as LA8
6575: format = GL.GL_LUMINANCE_ALPHA;
6576: break;
6577: case ImageComponentRetained.TYPE_BYTE_GRAY:
6578: if (internalFormat == GL.GL_ALPHA) {
6579: format = GL.GL_ALPHA;
6580: } else {
6581: format = GL.GL_LUMINANCE;
6582: }
6583: break;
6584: case ImageComponentRetained.TYPE_USHORT_GRAY:
6585: case ImageComponentRetained.TYPE_INT_BGR:
6586: case ImageComponentRetained.TYPE_INT_RGB:
6587: case ImageComponentRetained.TYPE_INT_ARGB:
6588: default:
6589: assert false;
6590: return;
6591: }
6592:
6593: if (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) {
6594:
6595: gl.glTexImage2D(target, level, internalFormat, width,
6596: height, boundaryWidth, format,
6597: GL.GL_UNSIGNED_BYTE, ByteBuffer
6598: .wrap((byte[]) data));
6599: } else {
6600: gl.glTexImage2D(target, level, internalFormat, width,
6601: height, boundaryWidth, format,
6602: GL.GL_UNSIGNED_BYTE, (Buffer) data);
6603: }
6604:
6605: } else if ((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY)
6606: || (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) {
6607:
6608: switch (imageFormat) {
6609: /* GL_BGR */
6610: case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
6611: format = GL.GL_RGBA;
6612: type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
6613: forceAlphaToOne = true;
6614: break;
6615: case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
6616: forceAlphaToOne = true;
6617: /* Fall through to next case */
6618: case ImageComponentRetained.TYPE_INT_ARGB:
6619: format = GL.GL_BGRA;
6620: type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
6621: break;
6622: /* This method only supports 3 and 4 components formats and INT types. */
6623: case ImageComponentRetained.TYPE_BYTE_LA:
6624: case ImageComponentRetained.TYPE_BYTE_GRAY:
6625: case ImageComponentRetained.TYPE_USHORT_GRAY:
6626: case ImageComponentRetained.TYPE_BYTE_BGR:
6627: case ImageComponentRetained.TYPE_BYTE_RGB:
6628: case ImageComponentRetained.TYPE_BYTE_RGBA:
6629: case ImageComponentRetained.TYPE_BYTE_ABGR:
6630: default:
6631: assert false;
6632: return;
6633: }
6634:
6635: /* Force Alpha to 1.0 if needed */
6636: if (forceAlphaToOne) {
6637: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
6638: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
6639: }
6640:
6641: if (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) {
6642: gl.glTexImage2D(target, level, internalFormat, width,
6643: height, boundaryWidth, format, type, IntBuffer
6644: .wrap((int[]) data));
6645: } else {
6646: gl.glTexImage2D(target, level, internalFormat, width,
6647: height, boundaryWidth, format, type,
6648: (Buffer) data);
6649: }
6650:
6651: /* Restore Alpha scale and bias */
6652: if (forceAlphaToOne) {
6653: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
6654: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
6655: }
6656: } else {
6657: assert false;
6658: }
6659: }
6660:
6661: private void updateTexture2DSubImage(Context ctx, int target,
6662: int level, int xoffset, int yoffset, int textureFormat,
6663: int imageFormat, int imgXOffset, int imgYOffset, int tilew,
6664: int width, int height, int dataType, Object data) {
6665: GL gl = context(ctx).getGL();
6666:
6667: int format = 0, internalFormat = 0;
6668: int numBytes = 0;
6669: int type = GL.GL_UNSIGNED_INT_8_8_8_8;
6670: boolean forceAlphaToOne = false;
6671: boolean pixelStore = false;
6672:
6673: if (imgXOffset > 0 || (width < tilew)) {
6674: pixelStore = true;
6675: gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, tilew);
6676: }
6677:
6678: switch (textureFormat) {
6679: case Texture.INTENSITY:
6680: internalFormat = GL.GL_INTENSITY;
6681: break;
6682: case Texture.LUMINANCE:
6683: internalFormat = GL.GL_LUMINANCE;
6684: break;
6685: case Texture.ALPHA:
6686: internalFormat = GL.GL_ALPHA;
6687: break;
6688: case Texture.LUMINANCE_ALPHA:
6689: internalFormat = GL.GL_LUMINANCE_ALPHA;
6690: break;
6691: case Texture.RGB:
6692: internalFormat = GL.GL_RGB;
6693: break;
6694: case Texture.RGBA:
6695: internalFormat = GL.GL_RGBA;
6696: break;
6697: default:
6698: assert false;
6699: }
6700:
6701: if ((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY)
6702: || (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) {
6703:
6704: switch (imageFormat) {
6705: case ImageComponentRetained.TYPE_BYTE_BGR:
6706: format = GL.GL_BGR;
6707: numBytes = 3;
6708: break;
6709: case ImageComponentRetained.TYPE_BYTE_RGB:
6710: format = GL.GL_RGB;
6711: numBytes = 3;
6712: break;
6713: case ImageComponentRetained.TYPE_BYTE_ABGR:
6714: if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here!
6715: format = GL.GL_ABGR_EXT;
6716: numBytes = 4;
6717: } else {
6718: assert false;
6719: return;
6720: }
6721: break;
6722: case ImageComponentRetained.TYPE_BYTE_RGBA:
6723: // all RGB types are stored as RGBA
6724: format = GL.GL_RGBA;
6725: numBytes = 4;
6726: break;
6727: case ImageComponentRetained.TYPE_BYTE_LA:
6728: // all LA types are stored as LA8
6729: format = GL.GL_LUMINANCE_ALPHA;
6730: numBytes = 2;
6731: break;
6732: case ImageComponentRetained.TYPE_BYTE_GRAY:
6733: if (internalFormat == GL.GL_ALPHA) {
6734: format = GL.GL_ALPHA;
6735: numBytes = 1;
6736: } else {
6737: format = GL.GL_LUMINANCE;
6738: numBytes = 1;
6739: }
6740: break;
6741: case ImageComponentRetained.TYPE_USHORT_GRAY:
6742: case ImageComponentRetained.TYPE_INT_BGR:
6743: case ImageComponentRetained.TYPE_INT_RGB:
6744: case ImageComponentRetained.TYPE_INT_ARGB:
6745: default:
6746: assert false;
6747: return;
6748: }
6749:
6750: ByteBuffer buf = null;
6751: if (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) {
6752: buf = ByteBuffer.wrap((byte[]) data);
6753: } else {
6754: buf = (ByteBuffer) data;
6755: }
6756:
6757: // offset by the imageOffset
6758: buf.position((tilew * imgYOffset + imgXOffset) * numBytes);
6759: gl.glTexSubImage2D(target, level, xoffset, yoffset, width,
6760: height, format, GL.GL_UNSIGNED_BYTE, buf);
6761:
6762: } else if ((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY)
6763: || (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) {
6764:
6765: switch (imageFormat) {
6766: /* GL_BGR */
6767: case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
6768: format = GL.GL_RGBA;
6769: type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
6770: forceAlphaToOne = true;
6771: break;
6772: case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
6773: forceAlphaToOne = true;
6774: /* Fall through to next case */
6775: case ImageComponentRetained.TYPE_INT_ARGB:
6776: format = GL.GL_BGRA;
6777: type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
6778: break;
6779: /* This method only supports 3 and 4 components formats and INT types. */
6780: case ImageComponentRetained.TYPE_BYTE_LA:
6781: case ImageComponentRetained.TYPE_BYTE_GRAY:
6782: case ImageComponentRetained.TYPE_USHORT_GRAY:
6783: case ImageComponentRetained.TYPE_BYTE_BGR:
6784: case ImageComponentRetained.TYPE_BYTE_RGB:
6785: case ImageComponentRetained.TYPE_BYTE_RGBA:
6786: case ImageComponentRetained.TYPE_BYTE_ABGR:
6787: default:
6788: assert false;
6789: return;
6790: }
6791: /* Force Alpha to 1.0 if needed */
6792: if (forceAlphaToOne) {
6793: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
6794: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
6795: }
6796:
6797: IntBuffer buf = null;
6798: if (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) {
6799: buf = IntBuffer.wrap((int[]) data);
6800: } else {
6801: buf = (IntBuffer) data;
6802: }
6803:
6804: // offset by the imageOffset
6805: buf.position(tilew * imgYOffset + imgXOffset);
6806: gl.glTexSubImage2D(target, level, xoffset, yoffset, width,
6807: height, format, type, buf);
6808:
6809: /* Restore Alpha scale and bias */
6810: if (forceAlphaToOne) {
6811: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
6812: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
6813: }
6814: } else {
6815: assert false;
6816: return;
6817: }
6818:
6819: if (pixelStore) {
6820: gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
6821: }
6822:
6823: }
6824:
6825: void updateTextureFilterModes(Context ctx, int target,
6826: int minFilter, int magFilter) {
6827: GL gl = context(ctx).getGL();
6828:
6829: if (EXTRA_DEBUGGING) {
6830: System.err.println("minFilter: " + getFilterName(minFilter)
6831: + " magFilter: " + getFilterName(magFilter));
6832: }
6833:
6834: // FIXME: unclear whether we really need to set up the enum values
6835: // in the JoglContext as is done in the native code depending on
6836: // extension availability; maybe this is the defined fallback
6837: // behavior of the various Java3D modes
6838:
6839: // set texture min filter
6840: switch (minFilter) {
6841: case Texture.FASTEST:
6842: case Texture.BASE_LEVEL_POINT:
6843: gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER,
6844: GL.GL_NEAREST);
6845: break;
6846: case Texture.BASE_LEVEL_LINEAR:
6847: gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER,
6848: GL.GL_LINEAR);
6849: break;
6850: case Texture.MULTI_LEVEL_POINT:
6851: gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER,
6852: GL.GL_NEAREST_MIPMAP_NEAREST);
6853: break;
6854: case Texture.NICEST:
6855: case Texture.MULTI_LEVEL_LINEAR:
6856: gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER,
6857: GL.GL_LINEAR_MIPMAP_LINEAR);
6858: break;
6859: case Texture.FILTER4:
6860: gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER,
6861: GL.GL_FILTER4_SGIS);
6862: break;
6863: }
6864:
6865: // set texture mag filter
6866: switch (magFilter) {
6867: case Texture.FASTEST:
6868: case Texture.BASE_LEVEL_POINT:
6869: gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
6870: GL.GL_NEAREST);
6871: break;
6872: case Texture.NICEST:
6873: case Texture.BASE_LEVEL_LINEAR:
6874: gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
6875: GL.GL_LINEAR);
6876: break;
6877: case Texture.LINEAR_SHARPEN:
6878: gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
6879: GL.GL_LINEAR_SHARPEN_SGIS);
6880: break;
6881: case Texture.LINEAR_SHARPEN_RGB:
6882: gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
6883: GL.GL_LINEAR_SHARPEN_COLOR_SGIS);
6884: break;
6885: case Texture.LINEAR_SHARPEN_ALPHA:
6886: gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
6887: GL.GL_LINEAR_SHARPEN_ALPHA_SGIS);
6888: break;
6889: case Texture2D.LINEAR_DETAIL:
6890: gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
6891: GL.GL_LINEAR_DETAIL_SGIS);
6892: break;
6893: case Texture2D.LINEAR_DETAIL_RGB:
6894: gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
6895: GL.GL_LINEAR_DETAIL_COLOR_SGIS);
6896: break;
6897: case Texture2D.LINEAR_DETAIL_ALPHA:
6898: gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
6899: GL.GL_LINEAR_DETAIL_ALPHA_SGIS);
6900: break;
6901: case Texture.FILTER4:
6902: gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
6903: GL.GL_FILTER4_SGIS);
6904: break;
6905: }
6906: }
6907:
6908: void updateTextureBoundary(Context ctx, int target,
6909: int boundaryModeS, int boundaryModeT, int boundaryModeR,
6910: float boundaryRed, float boundaryGreen, float boundaryBlue,
6911: float boundaryAlpha) {
6912: GL gl = context(ctx).getGL();
6913:
6914: // set texture wrap parameter
6915: switch (boundaryModeS) {
6916: case Texture.WRAP:
6917: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S,
6918: GL.GL_REPEAT);
6919: break;
6920: case Texture.CLAMP:
6921: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S,
6922: GL.GL_CLAMP);
6923: break;
6924: case Texture.CLAMP_TO_EDGE:
6925: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S,
6926: GL.GL_CLAMP_TO_EDGE);
6927: break;
6928: case Texture.CLAMP_TO_BOUNDARY:
6929: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S,
6930: GL.GL_CLAMP_TO_BORDER);
6931: break;
6932: }
6933:
6934: switch (boundaryModeT) {
6935: case Texture.WRAP:
6936: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T,
6937: GL.GL_REPEAT);
6938: break;
6939: case Texture.CLAMP:
6940: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T,
6941: GL.GL_CLAMP);
6942: break;
6943: case Texture.CLAMP_TO_EDGE:
6944: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T,
6945: GL.GL_CLAMP_TO_EDGE);
6946: break;
6947: case Texture.CLAMP_TO_BOUNDARY:
6948: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T,
6949: GL.GL_CLAMP_TO_BORDER);
6950: break;
6951: }
6952:
6953: // applies to Texture3D only
6954: if (boundaryModeR != -1) {
6955: switch (boundaryModeR) {
6956: case Texture.WRAP:
6957: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_R,
6958: GL.GL_REPEAT);
6959: break;
6960:
6961: case Texture.CLAMP:
6962: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_R,
6963: GL.GL_CLAMP);
6964: break;
6965: case Texture.CLAMP_TO_EDGE:
6966: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_R,
6967: GL.GL_CLAMP_TO_EDGE);
6968: break;
6969: case Texture.CLAMP_TO_BOUNDARY:
6970: gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_R,
6971: GL.GL_CLAMP_TO_BORDER);
6972: break;
6973: }
6974: }
6975:
6976: if (boundaryModeS == Texture.CLAMP
6977: || boundaryModeT == Texture.CLAMP
6978: || boundaryModeR == Texture.CLAMP) {
6979: // set texture border color
6980: float[] color = new float[4];
6981: color[0] = boundaryRed;
6982: color[1] = boundaryGreen;
6983: color[2] = boundaryBlue;
6984: color[3] = boundaryAlpha;
6985: gl.glTexParameterfv(target, GL.GL_TEXTURE_BORDER_COLOR,
6986: color, 0);
6987: }
6988: }
6989:
6990: private static final String getFilterName(int filter) {
6991: switch (filter) {
6992: case Texture.FASTEST:
6993: return "Texture.FASTEST";
6994: case Texture.NICEST:
6995: return "Texture.NICEST";
6996: case Texture.BASE_LEVEL_POINT:
6997: return "Texture.BASE_LEVEL_POINT";
6998: case Texture.BASE_LEVEL_LINEAR:
6999: return "Texture.BASE_LEVEL_LINEAR";
7000: case Texture.MULTI_LEVEL_POINT:
7001: return "Texture.MULTI_LEVEL_POINT";
7002: case Texture.MULTI_LEVEL_LINEAR:
7003: return "Texture.MULTI_LEVEL_LINEAR";
7004: case Texture.FILTER4:
7005: return "Texture.FILTER4";
7006: case Texture.LINEAR_SHARPEN:
7007: return "Texture.LINEAR_SHARPEN";
7008: case Texture.LINEAR_SHARPEN_RGB:
7009: return "Texture.LINEAR_SHARPEN_RGB";
7010: case Texture.LINEAR_SHARPEN_ALPHA:
7011: return "Texture.LINEAR_SHARPEN_ALPHA";
7012: case Texture2D.LINEAR_DETAIL:
7013: return "Texture.LINEAR_DETAIL";
7014: case Texture2D.LINEAR_DETAIL_RGB:
7015: return "Texture.LINEAR_DETAIL_RGB";
7016: case Texture2D.LINEAR_DETAIL_ALPHA:
7017: return "Texture.LINEAR_DETAIL_ALPHA";
7018: default:
7019: return "(unknown)";
7020: }
7021: }
7022:
7023: private void updateTextureSharpenFunc(Context ctx, int target,
7024: int numPts, float[] pts) {
7025: // checking of the availability of sharpen texture functionality
7026: // is already done in shared code
7027: GL gl = context(ctx).getGL();
7028: gl.glSharpenTexFuncSGIS(target, numPts, pts, 0);
7029: }
7030:
7031: private void updateTextureFilter4Func(Context ctx, int target,
7032: int numPts, float[] pts) {
7033: // checking of the availability of filter4 functionality
7034: // is already done in shared code
7035: GL gl = context(ctx).getGL();
7036: gl.glTexFilterFuncSGIS(target, GL.GL_FILTER4_SGIS, numPts, pts,
7037: 0);
7038: }
7039:
7040: // mapping from java enum to gl enum
7041: private static final int[] _gl_textureCubeMapFace = {
7042: GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X,
7043: GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
7044: GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
7045: GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
7046: GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
7047: GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, };
7048:
7049: // ---------------------------------------------------------------------
7050:
7051: //
7052: // MasterControl methods
7053: //
7054:
7055: // Method to return the AWT object
7056: long getAWT() {
7057: if (VERBOSE)
7058: System.err.println("JoglPipeline.getAWT()");
7059:
7060: // FIXME: probably completely unneeded in this implementation,
7061: // but should probably remove this dependence in the shared code
7062: return 0;
7063: }
7064:
7065: // Method to initialize the native J3D library
7066: boolean initializeJ3D(boolean disableXinerama) {
7067: // Dummy method in JOGL pipeline
7068: return true;
7069: }
7070:
7071: // Maximum lights supported by the native API
7072: int getMaximumLights() {
7073: if (VERBOSE)
7074: System.err.println("JoglPipeline.getMaximumLights()");
7075:
7076: // FIXME: this isn't quite what the NativePipeline returns but
7077: // is probably close enough
7078: return 8;
7079: }
7080:
7081: // ---------------------------------------------------------------------
7082:
7083: //
7084: // Canvas3D methods - native wrappers
7085: //
7086:
7087: // This is the native method for creating the underlying graphics context.
7088: Context createNewContext(Canvas3D cv, long display,
7089: Drawable drawable, long fbConfig, Context shareCtx,
7090: boolean isSharedCtx, boolean offScreen,
7091: boolean glslLibraryAvailable, boolean cgLibraryAvailable) {
7092: if (VERBOSE)
7093: System.err.println("JoglPipeline.createNewContext()");
7094: GLDrawable draw = null;
7095: GLCapabilitiesChooser indexChooser = null;
7096: JoglGraphicsConfiguration config = (JoglGraphicsConfiguration) cv.graphicsConfiguration;
7097: if (config.getChosenIndex() >= 0) {
7098: indexChooser = new IndexCapabilitiesChooser(config
7099: .getChosenIndex());
7100: }
7101: if (cv.drawable == null) {
7102: draw = GLDrawableFactory.getFactory().getGLDrawable(cv,
7103: config.getGLCapabilities(), indexChooser);
7104: cv.drawable = new JoglDrawable(draw);
7105: } else {
7106: draw = drawable(cv.drawable);
7107: }
7108:
7109: // FIXME: assuming that this only gets called after addNotify has been called
7110: draw.setRealized(true);
7111: GLContext context = draw.createContext(context(shareCtx));
7112:
7113: // Apparently we are supposed to make the context current at
7114: // this point and set up a bunch of properties
7115:
7116: // Work around for some low end graphics driver bug, such as Intel Chipset.
7117: // Issue 324 : Lockup Java3D program and throw exception using JOGL renderer
7118: boolean failed = false;
7119: int failCount = 0;
7120: int MAX_FAIL_COUNT = 5;
7121: do {
7122: failed = false;
7123: int res = context.makeCurrent();
7124: if (res == GLContext.CONTEXT_NOT_CURRENT) {
7125: // System.err.println("makeCurrent fail : " + failCount);
7126: failed = true;
7127: ++failCount;
7128: try {
7129: Thread.sleep(100);
7130: } catch (InterruptedException e) {
7131: }
7132: }
7133: } while (failed && (failCount < MAX_FAIL_COUNT));
7134: if (failCount == MAX_FAIL_COUNT) {
7135: throw new IllegalRenderingStateException(
7136: "Unable to make new context current after "
7137: + failCount + "tries");
7138: }
7139:
7140: GL gl = context.getGL();
7141: JoglContext ctx = new JoglContext(context);
7142:
7143: try {
7144: if (!getPropertiesFromCurrentContext(ctx)) {
7145: throw new IllegalRenderingStateException(
7146: "Unable to fetch properties from current OpenGL context");
7147: }
7148:
7149: if (!isSharedCtx) {
7150: // Set up fields in Canvas3D
7151: setupCanvasProperties(cv, ctx, gl,
7152: glslLibraryAvailable, cgLibraryAvailable);
7153: }
7154:
7155: // Enable rescale normal
7156: gl.glEnable(GL.GL_RESCALE_NORMAL);
7157:
7158: gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE);
7159: gl.glDepthFunc(GL.GL_LEQUAL);
7160: gl.glEnable(GL.GL_COLOR_MATERIAL);
7161: gl.glReadBuffer(GL.GL_FRONT);
7162:
7163: // Issue 417: JOGL: Mip-mapped NPOT textures rendered incorrectly
7164: // Java 3D images are aligned to 1 byte
7165: gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
7166:
7167: // Workaround for issue 400: Enable separate specular by default
7168: gl.glLightModeli(GL.GL_LIGHT_MODEL_COLOR_CONTROL,
7169: GL.GL_SEPARATE_SPECULAR_COLOR);
7170: } finally {
7171: context.release();
7172: }
7173:
7174: return ctx;
7175: }
7176:
7177: void createQueryContext(Canvas3D cv, long display,
7178: Drawable drawable, long fbConfig, boolean offScreen,
7179: int width, int height, boolean glslLibraryAvailable,
7180: boolean cgLibraryAvailable) {
7181: if (VERBOSE)
7182: System.err.println("JoglPipeline.createQueryContext()");
7183:
7184: // FIXME: for now, ignoring the "offscreen" flag -- unclear how
7185: // to create an offscreen buffer at this point -- very likely
7186: // need Canvas3D.offScreenBufferInfo promoted to an Object --
7187: // this logic will need to be revisited to make sure we capture
7188: // all of the functionality of the NativePipeline
7189:
7190: Frame f = new Frame();
7191: f.setUndecorated(true);
7192: f.setLayout(new BorderLayout());
7193: GLCapabilities caps = new GLCapabilities();
7194: ContextQuerier querier = new ContextQuerier(cv,
7195: glslLibraryAvailable, cgLibraryAvailable);
7196: // FIXME: should know what GraphicsDevice on which to create
7197: // this Canvas / Frame, and this should probably be known from
7198: // the incoming "display" parameter
7199: QueryCanvas canvas = new QueryCanvas(caps, querier, null);
7200: f.add(canvas, BorderLayout.CENTER);
7201: f.setSize(MIN_FRAME_SIZE, MIN_FRAME_SIZE);
7202: f.setVisible(true);
7203: canvas.doQuery();
7204: // Attempt to wait for the frame to become visible, but don't block the EDT
7205: if (!EventQueue.isDispatchThread()) {
7206: synchronized (querier) {
7207: if (!querier.done()) {
7208: try {
7209: querier.wait(WAIT_TIME);
7210: } catch (InterruptedException e) {
7211: }
7212: }
7213: }
7214: }
7215:
7216: disposeOnEDT(f);
7217: }
7218:
7219: // This is the native for creating an offscreen buffer
7220: Drawable createOffScreenBuffer(Canvas3D cv, Context ctx,
7221: long display, long fbConfig, int width, int height) {
7222: if (VERBOSE)
7223: System.err.println("JoglPipeline.createOffScreenBuffer()");
7224:
7225: // Note 1: when this is called, the incoming Context argument is
7226: // null because (obviously) no drawable or context has been
7227: // created for the Canvas3D yet.
7228:
7229: // Note 2: we ignore the global j3d.usePbuffer flag; JOGL
7230: // doesn't expose pixmap/bitmap surfaces in its public API.
7231:
7232: // First pick up the JoglGraphicsConfiguration and from there
7233: // the GLCapabilities from the Canvas3D
7234: JoglGraphicsConfiguration jcfg = (JoglGraphicsConfiguration) cv.graphicsConfiguration;
7235: // Note that we ignore any chosen index from a prior call to getBestConfiguration();
7236: // those only enumerate the on-screen visuals, and we need to find one which is
7237: // pbuffer capable
7238: GLCapabilities caps = jcfg.getGLCapabilities();
7239: if (!GLDrawableFactory.getFactory().canCreateGLPbuffer()) {
7240: // FIXME: do anything else here? Throw exception?
7241: return null;
7242: }
7243:
7244: GLPbuffer pbuffer = GLDrawableFactory.getFactory()
7245: .createGLPbuffer(caps, null, width, height, null);
7246: return new JoglDrawable(pbuffer);
7247: }
7248:
7249: void destroyOffScreenBuffer(Canvas3D cv, Context ctx, long display,
7250: long fbConfig, Drawable drawable) {
7251: if (VERBOSE)
7252: System.err.println("JoglPipeline.destroyOffScreenBuffer()");
7253:
7254: JoglDrawable jdraw = (JoglDrawable) drawable;
7255: GLPbuffer pbuffer = (GLPbuffer) jdraw.getGLDrawable();
7256: pbuffer.destroy();
7257: }
7258:
7259: // This is the native for reading the image from the offscreen buffer
7260: void readOffScreenBuffer(Canvas3D cv, Context ctx, int format,
7261: int dataType, Object data, int width, int height) {
7262: if (VERBOSE)
7263: System.err.println("JoglPipeline.readOffScreenBuffer()");
7264:
7265: GL gl = context(ctx).getGL();
7266: gl.glPixelStorei(GL.GL_PACK_ROW_LENGTH, width);
7267: gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
7268:
7269: int type = 0;
7270: if ((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY)
7271: || (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) {
7272:
7273: switch (format) {
7274: // GL_BGR
7275: case ImageComponentRetained.TYPE_BYTE_BGR:
7276: type = GL.GL_BGR;
7277: break;
7278: case ImageComponentRetained.TYPE_BYTE_RGB:
7279: type = GL.GL_RGB;
7280: break;
7281: // GL_ABGR_EXT
7282: case ImageComponentRetained.TYPE_BYTE_ABGR:
7283: if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If false, should never come here!
7284: type = GL.GL_ABGR_EXT;
7285: } else {
7286: assert false;
7287: return;
7288: }
7289: break;
7290: case ImageComponentRetained.TYPE_BYTE_RGBA:
7291: type = GL.GL_RGBA;
7292: break;
7293:
7294: /* This method only supports 3 and 4 components formats and BYTE types. */
7295: case ImageComponentRetained.TYPE_BYTE_LA:
7296: case ImageComponentRetained.TYPE_BYTE_GRAY:
7297: case ImageComponentRetained.TYPE_USHORT_GRAY:
7298: case ImageComponentRetained.TYPE_INT_BGR:
7299: case ImageComponentRetained.TYPE_INT_RGB:
7300: case ImageComponentRetained.TYPE_INT_ARGB:
7301: default:
7302: throw new AssertionError("illegal format " + format);
7303: }
7304:
7305: gl
7306: .glReadPixels(0, 0, width, height, type,
7307: GL.GL_UNSIGNED_BYTE, ByteBuffer
7308: .wrap((byte[]) data));
7309:
7310: } else if ((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY)
7311: || (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) {
7312:
7313: int intType = GL.GL_UNSIGNED_INT_8_8_8_8;
7314: boolean forceAlphaToOne = false;
7315:
7316: switch (format) {
7317: /* GL_BGR */
7318: case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
7319: type = GL.GL_RGBA;
7320: intType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
7321: forceAlphaToOne = true;
7322: break;
7323: case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
7324: forceAlphaToOne = true;
7325: /* Fall through to next case */
7326: case ImageComponentRetained.TYPE_INT_ARGB:
7327: type = GL.GL_BGRA;
7328: intType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
7329: break;
7330: /* This method only supports 3 and 4 components formats and BYTE types. */
7331: case ImageComponentRetained.TYPE_BYTE_LA:
7332: case ImageComponentRetained.TYPE_BYTE_GRAY:
7333: case ImageComponentRetained.TYPE_USHORT_GRAY:
7334: case ImageComponentRetained.TYPE_BYTE_BGR:
7335: case ImageComponentRetained.TYPE_BYTE_RGB:
7336: case ImageComponentRetained.TYPE_BYTE_RGBA:
7337: case ImageComponentRetained.TYPE_BYTE_ABGR:
7338: default:
7339: throw new AssertionError("illegal format " + format);
7340: }
7341:
7342: /* Force Alpha to 1.0 if needed */
7343: if (forceAlphaToOne) {
7344: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
7345: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
7346: }
7347:
7348: gl.glReadPixels(0, 0, width, height, type, intType,
7349: IntBuffer.wrap((int[]) data));
7350:
7351: /* Restore Alpha scale and bias */
7352: if (forceAlphaToOne) {
7353: gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
7354: gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
7355: }
7356:
7357: } else {
7358: throw new AssertionError("illegal image data type "
7359: + dataType);
7360:
7361: }
7362: }
7363:
7364: // The native method for swapBuffers
7365: int swapBuffers(Canvas3D cv, Context ctx, long dpy,
7366: Drawable drawable) {
7367: if (VERBOSE)
7368: System.err.println("JoglPipeline.swapBuffers()");
7369: GLDrawable draw = drawable(drawable);
7370: draw.swapBuffers();
7371: return 0;
7372: }
7373:
7374: // notify D3D that Canvas is resize
7375: int resizeD3DCanvas(Canvas3D cv, Context ctx) {
7376: // Dummy method in JOGL pipeline
7377: return 0;
7378: }
7379:
7380: // notify D3D to toggle between FullScreen and window mode
7381: int toggleFullScreenMode(Canvas3D cv, Context ctx) {
7382: // Dummy method in JOGL pipeline
7383: return 0;
7384: }
7385:
7386: // native method for setting Material when no material is present
7387: void updateMaterialColor(Context ctx, float r, float g, float b,
7388: float a) {
7389: if (VERBOSE)
7390: System.err.println("JoglPipeline.updateMaterialColor()");
7391:
7392: GL gl = context(ctx).getGL();
7393: gl.glColor4f(r, g, b, a);
7394: gl.glDisable(GL.GL_LIGHTING);
7395: }
7396:
7397: void destroyContext(long display, Drawable drawable, Context ctx) {
7398: if (VERBOSE)
7399: System.err.println("JoglPipeline.destroyContext()");
7400: GLDrawable draw = drawable(drawable);
7401: GLContext context = context(ctx);
7402: if (GLContext.getCurrent() == context) {
7403: context.release();
7404: }
7405: context.destroy();
7406: // FIXME: assuming this is the right point at which to make this call
7407: draw.setRealized(false);
7408: }
7409:
7410: // This is the native method for doing accumulation.
7411: void accum(Context ctx, float value) {
7412: if (VERBOSE)
7413: System.err.println("JoglPipeline.accum()");
7414:
7415: GL gl = context(ctx).getGL();
7416: gl.glReadBuffer(GL.GL_BACK);
7417: gl.glAccum(GL.GL_ACCUM, value);
7418: gl.glReadBuffer(GL.GL_FRONT);
7419: }
7420:
7421: // This is the native method for doing accumulation return.
7422: void accumReturn(Context ctx) {
7423: if (VERBOSE)
7424: System.err.println("JoglPipeline.accumReturn()");
7425:
7426: GL gl = context(ctx).getGL();
7427: gl.glAccum(GL.GL_RETURN, 1.0f);
7428: }
7429:
7430: // This is the native method for clearing the accumulation buffer.
7431: void clearAccum(Context ctx) {
7432: if (VERBOSE)
7433: System.err.println("JoglPipeline.clearAccum()");
7434:
7435: GL gl = context(ctx).getGL();
7436: gl.glClear(GL.GL_ACCUM_BUFFER_BIT);
7437: }
7438:
7439: // This is the native method for getting the number of lights the underlying
7440: // native library can support.
7441: int getNumCtxLights(Context ctx) {
7442: if (VERBOSE)
7443: System.err.println("JoglPipeline.getNumCtxLights()");
7444:
7445: GL gl = context(ctx).getGL();
7446: int[] res = new int[1];
7447: gl.glGetIntegerv(GL.GL_MAX_LIGHTS, res, 0);
7448: return res[0];
7449: }
7450:
7451: // Native method for decal 1st child setup
7452: boolean decal1stChildSetup(Context ctx) {
7453: if (VERBOSE)
7454: System.err.println("JoglPipeline.decal1stChildSetup()");
7455:
7456: GL gl = context(ctx).getGL();
7457: gl.glEnable(GL.GL_STENCIL_TEST);
7458: gl.glClearStencil(0x0);
7459: gl.glClear(GL.GL_STENCIL_BUFFER_BIT);
7460: gl.glStencilFunc(GL.GL_ALWAYS, 0x1, 0x1);
7461: gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_REPLACE);
7462: if (gl.glIsEnabled(GL.GL_DEPTH_TEST))
7463: return true;
7464: else
7465: return false;
7466: }
7467:
7468: // Native method for decal nth child setup
7469: void decalNthChildSetup(Context ctx) {
7470: if (VERBOSE)
7471: System.err.println("JoglPipeline.decalNthChildSetup()");
7472:
7473: GL gl = context(ctx).getGL();
7474: gl.glDisable(GL.GL_DEPTH_TEST);
7475: gl.glStencilFunc(GL.GL_EQUAL, 0x1, 0x1);
7476: gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP);
7477: }
7478:
7479: // Native method for decal reset
7480: void decalReset(Context ctx, boolean depthBufferEnable) {
7481: if (VERBOSE)
7482: System.err.println("JoglPipeline.decalReset()");
7483:
7484: GL gl = context(ctx).getGL();
7485: gl.glDisable(GL.GL_STENCIL_TEST);
7486: if (depthBufferEnable)
7487: gl.glEnable(GL.GL_DEPTH_TEST);
7488: }
7489:
7490: // Native method for eye lighting
7491: void ctxUpdateEyeLightingEnable(Context ctx,
7492: boolean localEyeLightingEnable) {
7493: if (VERBOSE)
7494: System.err
7495: .println("JoglPipeline.ctxUpdateEyeLightingEnable()");
7496:
7497: GL gl = context(ctx).getGL();
7498:
7499: if (localEyeLightingEnable) {
7500: gl
7501: .glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER,
7502: GL.GL_TRUE);
7503: } else {
7504: gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER,
7505: GL.GL_FALSE);
7506: }
7507: }
7508:
7509: // The following three methods are used in multi-pass case
7510:
7511: // native method for setting blend color
7512: void setBlendColor(Context ctx, float red, float green, float blue,
7513: float alpha) {
7514: if (VERBOSE)
7515: System.err.println("JoglPipeline.setBlendColor()");
7516:
7517: GL gl = context(ctx).getGL();
7518: if (gl.isExtensionAvailable("GL_ARB_imaging")) {
7519: gl.glBlendColor(red, green, blue, alpha);
7520: }
7521: }
7522:
7523: // native method for setting blend func
7524: void setBlendFunc(Context ctx, int srcBlendFunction,
7525: int dstBlendFunction) {
7526: if (VERBOSE)
7527: System.err.println("JoglPipeline.setBlendFunc()");
7528:
7529: GL gl = context(ctx).getGL();
7530: gl.glEnable(GL.GL_BLEND);
7531: gl.glBlendFunc(blendFunctionTable[srcBlendFunction],
7532: blendFunctionTable[dstBlendFunction]);
7533: }
7534:
7535: // native method for setting fog enable flag
7536: void setFogEnableFlag(Context ctx, boolean enable) {
7537: if (VERBOSE)
7538: System.err.println("JoglPipeline.setFogEnableFlag()");
7539:
7540: GL gl = context(ctx).getGL();
7541:
7542: if (enable)
7543: gl.glEnable(GL.GL_FOG);
7544: else
7545: gl.glDisable(GL.GL_FOG);
7546: }
7547:
7548: // Setup the full scene antialising in D3D and ogl when GL_ARB_multisamle supported
7549: void setFullSceneAntialiasing(Context absCtx, boolean enable) {
7550: if (VERBOSE)
7551: System.err
7552: .println("JoglPipeline.setFullSceneAntialiasing()");
7553:
7554: JoglContext ctx = (JoglContext) absCtx;
7555: GL gl = context(ctx).getGL();
7556: if (ctx.getHasMultisample()
7557: && !VirtualUniverse.mc.implicitAntialiasing) {
7558: if (enable) {
7559: gl.glEnable(GL.GL_MULTISAMPLE);
7560: } else {
7561: gl.glDisable(GL.GL_MULTISAMPLE);
7562: }
7563: }
7564: }
7565:
7566: void setGlobalAlpha(Context ctx, float alpha) {
7567: if (VERBOSE)
7568: System.err.println("JoglPipeline.setGlobalAlpha()");
7569:
7570: GL gl = context(ctx).getGL();
7571: if (gl.isExtensionAvailable("GL_SUN_global_alpha")) {
7572: gl.glEnable(GL.GL_GLOBAL_ALPHA_SUN);
7573: gl.glGlobalAlphaFactorfSUN(alpha);
7574: }
7575: }
7576:
7577: // Native method to update separate specular color control
7578: void updateSeparateSpecularColorEnable(Context ctx, boolean enable) {
7579: if (VERBOSE)
7580: System.err
7581: .println("JoglPipeline.updateSeparateSpecularColorEnable()");
7582:
7583: GL gl = context(ctx).getGL();
7584:
7585: if (enable) {
7586: gl.glLightModeli(GL.GL_LIGHT_MODEL_COLOR_CONTROL,
7587: GL.GL_SEPARATE_SPECULAR_COLOR);
7588: } else {
7589: gl.glLightModeli(GL.GL_LIGHT_MODEL_COLOR_CONTROL,
7590: GL.GL_SINGLE_COLOR);
7591: }
7592: }
7593:
7594: // Initialization for D3D when scene begins and ends
7595: void beginScene(Context ctx) {
7596: }
7597:
7598: void endScene(Context ctx) {
7599: }
7600:
7601: // True under Solaris,
7602: // False under windows when display mode <= 8 bit
7603: boolean validGraphicsMode() {
7604: if (VERBOSE)
7605: System.err.println("JoglPipeline.validGraphicsMode()");
7606:
7607: // FIXME: believe this should do exactly what the native code
7608: // used to, but not 100% sure (also in theory should only run
7609: // this code on the Windows platform? What about Mac OS X?)
7610: DisplayMode currentMode = GraphicsEnvironment
7611: .getLocalGraphicsEnvironment().getDefaultScreenDevice()
7612: .getDisplayMode();
7613: // Note: on X11 platforms, a bit depth < 0 simply indicates that
7614: // multiple visuals are supported on the current display mode
7615:
7616: if (VERBOSE)
7617: System.err.println(" Returning "
7618: + (currentMode.getBitDepth() < 0 || currentMode
7619: .getBitDepth() > 8));
7620:
7621: return (currentMode.getBitDepth() < 0 || currentMode
7622: .getBitDepth() > 8);
7623: }
7624:
7625: // native method for setting light enables
7626: void setLightEnables(Context ctx, long enableMask, int maxLights) {
7627: if (VERBOSE)
7628: System.err.println("JoglPipeline.setLightEnables()");
7629:
7630: GL gl = context(ctx).getGL();
7631:
7632: for (int i = 0; i < maxLights; i++) {
7633: if ((enableMask & (1 << i)) != 0) {
7634: gl.glEnable(GL.GL_LIGHT0 + i);
7635: } else {
7636: gl.glDisable(GL.GL_LIGHT0 + i);
7637: }
7638: }
7639: }
7640:
7641: // native method for setting scene ambient
7642: void setSceneAmbient(Context ctx, float red, float green, float blue) {
7643: if (VERBOSE)
7644: System.err.println("JoglPipeline.setSceneAmbient()");
7645:
7646: GL gl = context(ctx).getGL();
7647:
7648: float[] color = new float[4];
7649: color[0] = red;
7650: color[1] = green;
7651: color[2] = blue;
7652: color[3] = 1.0f;
7653: gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, color, 0);
7654: }
7655:
7656: // native method for disabling fog
7657: void disableFog(Context ctx) {
7658: if (VERBOSE)
7659: System.err.println("JoglPipeline.disableFog()");
7660:
7661: GL gl = context(ctx).getGL();
7662: gl.glDisable(GL.GL_FOG);
7663: }
7664:
7665: // native method for disabling modelClip
7666: void disableModelClip(Context ctx) {
7667: if (VERBOSE)
7668: System.err.println("JoglPipeline.disableModelClip()");
7669:
7670: GL gl = context(ctx).getGL();
7671:
7672: gl.glDisable(GL.GL_CLIP_PLANE0);
7673: gl.glDisable(GL.GL_CLIP_PLANE1);
7674: gl.glDisable(GL.GL_CLIP_PLANE2);
7675: gl.glDisable(GL.GL_CLIP_PLANE3);
7676: gl.glDisable(GL.GL_CLIP_PLANE4);
7677: gl.glDisable(GL.GL_CLIP_PLANE5);
7678: }
7679:
7680: // native method for setting default RenderingAttributes
7681: void resetRenderingAttributes(Context ctx,
7682: boolean depthBufferWriteEnableOverride,
7683: boolean depthBufferEnableOverride) {
7684: if (VERBOSE)
7685: System.err
7686: .println("JoglPipeline.resetRenderingAttributes()");
7687:
7688: GL gl = context(ctx).getGL();
7689:
7690: if (!depthBufferWriteEnableOverride) {
7691: gl.glDepthMask(true);
7692: }
7693: if (!depthBufferEnableOverride) {
7694: gl.glEnable(GL.GL_DEPTH_TEST);
7695: }
7696: gl.glAlphaFunc(GL.GL_ALWAYS, 0.0f);
7697: gl.glDepthFunc(GL.GL_LEQUAL);
7698: gl.glEnable(GL.GL_COLOR_MATERIAL);
7699: gl.glDisable(GL.GL_COLOR_LOGIC_OP);
7700: }
7701:
7702: // native method for setting default texture
7703: void resetTextureNative(Context ctx, int texUnitIndex) {
7704: if (VERBOSE)
7705: System.err.println("JoglPipeline.resetTextureNative()");
7706:
7707: GL gl = context(ctx).getGL();
7708: if (texUnitIndex >= 0
7709: && gl.isExtensionAvailable("GL_VERSION_1_3")) {
7710: gl.glActiveTexture(texUnitIndex + GL.GL_TEXTURE0);
7711: gl.glClientActiveTexture(texUnitIndex + GL.GL_TEXTURE0);
7712: }
7713:
7714: gl.glDisable(GL.GL_TEXTURE_1D);
7715: gl.glDisable(GL.GL_TEXTURE_2D);
7716: gl.glDisable(GL.GL_TEXTURE_3D);
7717: gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
7718: }
7719:
7720: // native method for activating a particular texture unit
7721: void activeTextureUnit(Context ctx, int texUnitIndex) {
7722: if (VERBOSE)
7723: System.err.println("JoglPipeline.activeTextureUnit()");
7724:
7725: GL gl = context(ctx).getGL();
7726: if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
7727: gl.glActiveTexture(texUnitIndex + GL.GL_TEXTURE0);
7728: gl.glClientActiveTexture(texUnitIndex + GL.GL_TEXTURE0);
7729: }
7730: }
7731:
7732: // native method for setting default TexCoordGeneration
7733: void resetTexCoordGeneration(Context ctx) {
7734: if (VERBOSE)
7735: System.err
7736: .println("JoglPipeline.resetTexCoordGeneration()");
7737:
7738: GL gl = context(ctx).getGL();
7739: gl.glDisable(GL.GL_TEXTURE_GEN_S);
7740: gl.glDisable(GL.GL_TEXTURE_GEN_T);
7741: gl.glDisable(GL.GL_TEXTURE_GEN_R);
7742: gl.glDisable(GL.GL_TEXTURE_GEN_Q);
7743: }
7744:
7745: // native method for setting default TextureAttributes
7746: void resetTextureAttributes(Context ctx) {
7747: if (VERBOSE)
7748: System.err.println("JoglPipeline.resetTextureAttributes()");
7749:
7750: GL gl = context(ctx).getGL();
7751:
7752: float[] color = new float[4];
7753:
7754: gl.glPushAttrib(GL.GL_TRANSFORM_BIT);
7755: gl.glMatrixMode(GL.GL_TEXTURE);
7756: gl.glLoadIdentity();
7757: gl.glPopAttrib();
7758: gl.glTexEnvfv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_COLOR,
7759: color, 0);
7760: gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE,
7761: GL.GL_REPLACE);
7762: gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
7763:
7764: if (gl.isExtensionAvailable("GL_NV_register_combiners")) {
7765: gl.glDisable(GL.GL_REGISTER_COMBINERS_NV);
7766: }
7767:
7768: if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) {
7769: gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI);
7770: }
7771: }
7772:
7773: // native method for setting default PolygonAttributes
7774: void resetPolygonAttributes(Context ctx) {
7775: if (VERBOSE)
7776: System.err.println("JoglPipeline.resetPolygonAttributes()");
7777:
7778: GL gl = context(ctx).getGL();
7779:
7780: gl.glCullFace(GL.GL_BACK);
7781: gl.glEnable(GL.GL_CULL_FACE);
7782:
7783: gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_FALSE);
7784:
7785: gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
7786:
7787: gl.glPolygonOffset(0.0f, 0.0f);
7788: gl.glDisable(GL.GL_POLYGON_OFFSET_POINT);
7789: gl.glDisable(GL.GL_POLYGON_OFFSET_LINE);
7790: gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
7791: }
7792:
7793: // native method for setting default LineAttributes
7794: void resetLineAttributes(Context ctx) {
7795: if (VERBOSE)
7796: System.err.println("JoglPipeline.resetLineAttributes()");
7797:
7798: GL gl = context(ctx).getGL();
7799: gl.glLineWidth(1.0f);
7800: gl.glDisable(GL.GL_LINE_STIPPLE);
7801:
7802: // XXXX: Polygon Mode check, blend enable
7803: gl.glDisable(GL.GL_LINE_SMOOTH);
7804: }
7805:
7806: // native method for setting default PointAttributes
7807: void resetPointAttributes(Context ctx) {
7808: if (VERBOSE)
7809: System.err.println("JoglPipeline.resetPointAttributes()");
7810:
7811: GL gl = context(ctx).getGL();
7812: gl.glPointSize(1.0f);
7813:
7814: // XXXX: Polygon Mode check, blend enable
7815: gl.glDisable(GL.GL_POINT_SMOOTH);
7816: }
7817:
7818: // native method for setting default TransparencyAttributes
7819: void resetTransparency(Context ctx, int geometryType,
7820: int polygonMode, boolean lineAA, boolean pointAA) {
7821: if (VERBOSE)
7822: System.err.println("JoglPipeline.resetTransparency()");
7823:
7824: GL gl = context(ctx).getGL();
7825:
7826: if (((((geometryType & RenderMolecule.LINE) != 0) || (polygonMode == PolygonAttributes.POLYGON_LINE)) && lineAA)
7827: || ((((geometryType & RenderMolecule.POINT) != 0) || (polygonMode == PolygonAttributes.POLYGON_POINT)) && pointAA)) {
7828: gl.glEnable(GL.GL_BLEND);
7829: gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
7830: } else {
7831: gl.glDisable(GL.GL_BLEND);
7832: }
7833: gl.glDisable(GL.GL_POLYGON_STIPPLE);
7834: }
7835:
7836: // native method for setting default ColoringAttributes
7837: void resetColoringAttributes(Context ctx, float r, float g,
7838: float b, float a, boolean enableLight) {
7839: if (VERBOSE)
7840: System.err
7841: .println("JoglPipeline.resetColoringAttributes()");
7842:
7843: GL gl = context(ctx).getGL();
7844:
7845: if (!enableLight) {
7846: gl.glColor4f(r, g, b, a);
7847: }
7848: gl.glShadeModel(GL.GL_SMOOTH);
7849: }
7850:
7851: /**
7852: * This native method makes sure that the rendering for this canvas
7853: * gets done now.
7854: */
7855: void syncRender(Context ctx, boolean wait) {
7856: if (VERBOSE)
7857: System.err.println("JoglPipeline.syncRender()");
7858:
7859: GL gl = context(ctx).getGL();
7860:
7861: if (wait)
7862: gl.glFinish();
7863: else
7864: gl.glFlush();
7865: }
7866:
7867: // The native method that sets this ctx to be the current one
7868: boolean useCtx(Context ctx, long display, Drawable drawable) {
7869: if (VERBOSE)
7870: System.err.println("JoglPipeline.useCtx()");
7871: GLContext context = context(ctx);
7872: int res = context.makeCurrent();
7873: return (res != GLContext.CONTEXT_NOT_CURRENT);
7874: }
7875:
7876: // Optionally release the context. Returns true if the context was released.
7877: boolean releaseCtx(Context ctx, long dpy) {
7878: if (VERBOSE)
7879: System.err.println("JoglPipeline.releaseCtx()");
7880: GLContext context = context(ctx);
7881: context.release();
7882: return true;
7883: }
7884:
7885: void clear(Context ctx, float r, float g, float b,
7886: boolean clearStencil) {
7887: if (VERBOSE)
7888: System.err.println("JoglPipeline.clear()");
7889:
7890: JoglContext jctx = (JoglContext) ctx;
7891: GLContext context = context(ctx);
7892: GL gl = context.getGL();
7893:
7894: // OBSOLETE CLEAR CODE
7895: /*
7896: gl.glClearColor(r, g, b, jctx.getAlphaClearValue());
7897: gl.glClear(GL.GL_COLOR_BUFFER_BIT);
7898:
7899: // Java 3D always clears the Z-buffer
7900: gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT);
7901: gl.glDepthMask(true);
7902: gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
7903: gl.glPopAttrib();
7904:
7905: // Issue 239 - clear stencil if specified
7906: if (clearStencil) {
7907: gl.glPushAttrib(GL.GL_STENCIL_BUFFER_BIT);
7908: gl.glClearStencil(0);
7909: gl.glStencilMask(~0);
7910: gl.glClear(GL.GL_STENCIL_BUFFER_BIT);
7911: gl.glPopAttrib();
7912: }
7913: */
7914:
7915: // Mask of which buffers to clear, this always includes color & depth
7916: int clearMask = GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT;
7917:
7918: // Issue 239 - clear stencil if specified
7919: if (clearStencil) {
7920: gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT
7921: | GL.GL_STENCIL_BUFFER_BIT);
7922:
7923: gl.glClearStencil(0);
7924: gl.glStencilMask(~0);
7925: clearMask |= GL.GL_STENCIL_BUFFER_BIT;
7926: } else {
7927: gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT);
7928: }
7929:
7930: gl.glDepthMask(true);
7931: gl.glClearColor(r, g, b, jctx.getAlphaClearValue());
7932: gl.glClear(clearMask);
7933: gl.glPopAttrib();
7934:
7935: }
7936:
7937: void textureFillBackground(Context ctx, float texMinU,
7938: float texMaxU, float texMinV, float texMaxV, float mapMinX,
7939: float mapMaxX, float mapMinY, float mapMaxY,
7940: boolean useBilinearFilter) {
7941: if (VERBOSE)
7942: System.err.println("JoglPipeline.textureFillBackground()");
7943:
7944: GLContext context = context(ctx);
7945: GL gl = context.getGL();
7946:
7947: // Temporarily disable fragment and most 3D operations
7948: gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_TEXTURE_BIT
7949: | GL.GL_POLYGON_BIT);
7950:
7951: disableAttribFor2D(gl);
7952: gl.glDepthMask(false);
7953: gl.glEnable(GL.GL_TEXTURE_2D);
7954:
7955: /* Setup filter mode if needed */
7956: if (useBilinearFilter) {
7957: // System.err.println("JoglPipeline - Background : use bilinear filter\n");
7958: gl.glTexParameteri(GL.GL_TEXTURE_2D,
7959: GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
7960: gl.glTexParameteri(GL.GL_TEXTURE_2D,
7961: GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
7962: }
7963:
7964: // reset the polygon mode
7965: gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
7966:
7967: gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
7968:
7969: // load identity modelview and projection matrix
7970: gl.glMatrixMode(GL.GL_PROJECTION);
7971: gl.glLoadIdentity();
7972: gl.glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
7973: gl.glMatrixMode(GL.GL_MODELVIEW);
7974: gl.glLoadIdentity();
7975: gl.glMatrixMode(GL.GL_TEXTURE);
7976: gl.glPushMatrix();
7977: gl.glLoadIdentity();
7978:
7979: gl.glBegin(GL.GL_QUADS);
7980: gl.glTexCoord2f(texMinU, texMinV);
7981: gl.glVertex2f(mapMinX, mapMinY);
7982: gl.glTexCoord2f(texMaxU, texMinV);
7983: gl.glVertex2f(mapMaxX, mapMinY);
7984: gl.glTexCoord2f(texMaxU, texMaxV);
7985: gl.glVertex2f(mapMaxX, mapMaxY);
7986: gl.glTexCoord2f(texMinU, texMaxV);
7987: gl.glVertex2f(mapMinX, mapMaxY);
7988: gl.glEnd();
7989:
7990: // Restore texture Matrix transform
7991: gl.glPopMatrix();
7992:
7993: gl.glMatrixMode(GL.GL_MODELVIEW);
7994: // Restore attributes
7995: gl.glPopAttrib();
7996:
7997: }
7998:
7999: void textureFillRaster(Context ctx, float texMinU, float texMaxU,
8000: float texMinV, float texMaxV, float mapMinX, float mapMaxX,
8001: float mapMinY, float mapMaxY, float mapZ, float alpha,
8002: boolean useBilinearFilter) {
8003:
8004: if (VERBOSE)
8005: System.err.println("JoglPipeline.textureFillRaster()");
8006:
8007: GLContext context = context(ctx);
8008: GL gl = context.getGL();
8009:
8010: // Temporarily disable fragment and most 3D operations
8011: gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_TEXTURE_BIT
8012: | GL.GL_POLYGON_BIT | GL.GL_CURRENT_BIT);
8013:
8014: disableAttribForRaster(gl);
8015:
8016: /* Setup filter mode if needed */
8017: if (useBilinearFilter) {
8018: // System.err.println("JoglPipeline - Raster : use bilinear filter\n");
8019: gl.glTexParameteri(GL.GL_TEXTURE_2D,
8020: GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
8021: gl.glTexParameteri(GL.GL_TEXTURE_2D,
8022: GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
8023: }
8024:
8025: gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE,
8026: GL.GL_MODULATE);
8027: gl.glColor4f(1.0f, 1.0f, 1.0f, alpha);
8028:
8029: // reset the polygon mode
8030: gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
8031:
8032: gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
8033:
8034: // load identity modelview and projection matrix
8035: gl.glMatrixMode(GL.GL_MODELVIEW);
8036: gl.glPushMatrix();
8037: gl.glLoadIdentity();
8038: gl.glMatrixMode(GL.GL_PROJECTION);
8039: gl.glPushMatrix();
8040: gl.glLoadIdentity();
8041: gl.glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
8042:
8043: gl.glBegin(GL.GL_QUADS);
8044: gl.glTexCoord2f(texMinU, texMinV);
8045: gl.glVertex3f(mapMinX, mapMinY, mapZ);
8046: gl.glTexCoord2f(texMaxU, texMinV);
8047: gl.glVertex3f(mapMaxX, mapMinY, mapZ);
8048: gl.glTexCoord2f(texMaxU, texMaxV);
8049: gl.glVertex3f(mapMaxX, mapMaxY, mapZ);
8050: gl.glTexCoord2f(texMinU, texMaxV);
8051: gl.glVertex3f(mapMinX, mapMaxY, mapZ);
8052: gl.glEnd();
8053:
8054: // Restore matrices
8055: gl.glPopMatrix();
8056: gl.glMatrixMode(GL.GL_MODELVIEW);
8057: gl.glPopMatrix();
8058: // Restore attributes
8059: gl.glPopAttrib();
8060:
8061: }
8062:
8063: void executeRasterDepth(Context ctx, float posX, float posY,
8064: float posZ, int srcOffsetX, int srcOffsetY,
8065: int rasterWidth, int rasterHeight, int depthWidth,
8066: int depthHeight, int depthFormat, Object depthData) {
8067: if (VERBOSE)
8068: System.err.println("JoglPipeline.executeRasterDepth()");
8069: GLContext context = context(ctx);
8070: GL gl = context.getGL();
8071:
8072: gl.glRasterPos3f(posX, posY, posZ);
8073:
8074: int[] drawBuf = new int[1];
8075: gl.glGetIntegerv(GL.GL_DRAW_BUFFER, drawBuf, 0);
8076: /* disable draw buffer */
8077: gl.glDrawBuffer(GL.GL_NONE);
8078:
8079: /*
8080: * raster position is upper left corner, default for Java3D
8081: * ImageComponent currently has the data reverse in Y
8082: */
8083: gl.glPixelZoom(1.0f, -1.0f);
8084: gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, depthWidth);
8085: if (srcOffsetX >= 0) {
8086: gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, srcOffsetX);
8087: if (srcOffsetX + rasterWidth > depthWidth) {
8088: rasterWidth = depthWidth - srcOffsetX;
8089: }
8090: } else {
8091: rasterWidth += srcOffsetX;
8092: if (rasterWidth > depthWidth) {
8093: rasterWidth = depthWidth;
8094: }
8095: }
8096: if (srcOffsetY >= 0) {
8097: gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, srcOffsetY);
8098: if (srcOffsetY + rasterHeight > rasterHeight) {
8099: rasterHeight = rasterHeight - srcOffsetY;
8100: }
8101: } else {
8102: rasterHeight += srcOffsetY;
8103: if (rasterHeight > rasterHeight) {
8104: rasterHeight = rasterHeight;
8105: }
8106: }
8107:
8108: if (depthFormat == DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT) {
8109: gl.glDrawPixels(rasterWidth, rasterHeight,
8110: GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT,
8111: IntBuffer.wrap((int[]) depthData));
8112: } else { /* DepthComponentRetained.DEPTH_COMPONENT_TYPE_FLOAT */
8113: gl.glDrawPixels(rasterWidth, rasterHeight,
8114: GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, FloatBuffer
8115: .wrap((float[]) depthData));
8116: }
8117:
8118: /* re-enable draw buffer */
8119: gl.glDrawBuffer(drawBuf[0]);
8120:
8121: gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
8122: gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, 0);
8123: gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, 0);
8124:
8125: }
8126:
8127: // The native method for setting the ModelView matrix.
8128: void setModelViewMatrix(Context ctx, double[] viewMatrix,
8129: double[] modelMatrix) {
8130: if (VERBOSE)
8131: System.err.println("JoglPipeline.setModelViewMatrix()");
8132: GLContext context = context(ctx);
8133: GL gl = context.getGL();
8134:
8135: gl.glMatrixMode(GL.GL_MODELVIEW);
8136:
8137: if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
8138: gl.glLoadTransposeMatrixd(viewMatrix, 0);
8139: gl.glMultTransposeMatrixd(modelMatrix, 0);
8140: } else {
8141: double[] v = new double[16];
8142: double[] m = new double[16];
8143: copyTranspose(viewMatrix, v);
8144: copyTranspose(modelMatrix, m);
8145: gl.glLoadMatrixd(v, 0);
8146: gl.glMultMatrixd(m, 0);
8147: }
8148: }
8149:
8150: // The native method for setting the Projection matrix.
8151: void setProjectionMatrix(Context ctx, double[] projMatrix) {
8152: if (VERBOSE)
8153: System.err.println("JoglPipeline.setProjectionMatrix()");
8154: GLContext context = context(ctx);
8155: GL gl = context.getGL();
8156:
8157: gl.glMatrixMode(GL.GL_PROJECTION);
8158:
8159: if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
8160: // Invert the Z value in clipping coordinates because OpenGL uses
8161: // left-handed clipping coordinates, while Java3D defines right-handed
8162: // coordinates everywhere.
8163: projMatrix[8] *= -1.0;
8164: projMatrix[9] *= -1.0;
8165: projMatrix[10] *= -1.0;
8166: projMatrix[11] *= -1.0;
8167: gl.glLoadTransposeMatrixd(projMatrix, 0);
8168: projMatrix[8] *= -1.0;
8169: projMatrix[9] *= -1.0;
8170: projMatrix[10] *= -1.0;
8171: projMatrix[11] *= -1.0;
8172: } else {
8173: double[] p = new double[16];
8174: copyTranspose(projMatrix, p);
8175: // Invert the Z value in clipping coordinates because OpenGL uses
8176: // left-handed clipping coordinates, while Java3D defines right-handed
8177: // coordinates everywhere.
8178: p[2] *= -1.0;
8179: p[6] *= -1.0;
8180: p[10] *= -1.0;
8181: p[14] *= -1.0;
8182: gl.glLoadMatrixd(p, 0);
8183: }
8184: }
8185:
8186: // The native method for setting the Viewport.
8187: void setViewport(Context ctx, int x, int y, int width, int height) {
8188: if (VERBOSE)
8189: System.err.println("JoglPipeline.setViewport()");
8190: GL gl = context(ctx).getGL();
8191: gl.glViewport(x, y, width, height);
8192: }
8193:
8194: // used for display Lists
8195: void newDisplayList(Context ctx, int displayListId) {
8196: if (VERBOSE)
8197: System.err.println("JoglPipeline.newDisplayList()");
8198: if (displayListId <= 0) {
8199: System.err.println("JAVA 3D ERROR : glNewList("
8200: + displayListId + ") -- IGNORED");
8201: }
8202:
8203: GL gl = context(ctx).getGL();
8204: gl.glNewList(displayListId, GL.GL_COMPILE);
8205: }
8206:
8207: void endDisplayList(Context ctx) {
8208: if (VERBOSE)
8209: System.err.println("JoglPipeline.endDisplayList()");
8210: GL gl = context(ctx).getGL();
8211: gl.glEndList();
8212: }
8213:
8214: int numInvalidLists = 0;
8215:
8216: void callDisplayList(Context ctx, int id, boolean isNonUniformScale) {
8217: if (VERBOSE)
8218: System.err.println("JoglPipeline.callDisplayList()");
8219: if (id <= 0) {
8220: if (numInvalidLists < 3) {
8221: ++numInvalidLists;
8222: System.err.println("JAVA 3D ERROR : glCallList(" + id
8223: + ") -- IGNORED");
8224: } else if (numInvalidLists == 3) {
8225: ++numInvalidLists;
8226: System.err
8227: .println("JAVA 3D : further glCallList error messages discarded");
8228: }
8229: return;
8230: }
8231:
8232: GL gl = context(ctx).getGL();
8233: // Set normalization if non-uniform scale
8234: if (isNonUniformScale) {
8235: gl.glEnable(GL.GL_NORMALIZE);
8236: }
8237:
8238: gl.glCallList(id);
8239:
8240: // Turn normalization back off
8241: if (isNonUniformScale) {
8242: gl.glDisable(GL.GL_NORMALIZE);
8243: }
8244: }
8245:
8246: void freeDisplayList(Context ctx, int id) {
8247: if (VERBOSE)
8248: System.err.println("JoglPipeline.freeDisplayList()");
8249: if (id <= 0) {
8250: System.err.println("JAVA 3D ERROR : glDeleteLists(" + id
8251: + ",1) -- IGNORED");
8252: }
8253:
8254: GL gl = context(ctx).getGL();
8255: gl.glDeleteLists(id, 1);
8256: }
8257:
8258: void freeTexture(Context ctx, int id) {
8259: if (VERBOSE)
8260: System.err.println("JoglPipeline.freeTexture()");
8261:
8262: GL gl = context(ctx).getGL();
8263:
8264: if (id > 0) {
8265: int[] tmp = new int[1];
8266: tmp[0] = id;
8267: gl.glDeleteTextures(1, tmp, 0);
8268: } else {
8269: System.err.println("tried to delete tex with texid <= 0");
8270: }
8271: }
8272:
8273: void texturemapping(Context ctx, int px, int py, int minX,
8274: int minY, int maxX, int maxY, int texWidth, int texHeight,
8275: int rasWidth, int format, int objectId, byte[] imageYdown,
8276: int winWidth, int winHeight) {
8277: if (VERBOSE)
8278: System.err.println("JoglPipeline.texturemapping()");
8279:
8280: GL gl = context(ctx).getGL();
8281:
8282: int glType = GL.GL_RGBA;
8283:
8284: // Temporarily disable fragment and most 3D operations
8285: gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_TEXTURE_BIT
8286: | GL.GL_DEPTH_BUFFER_BIT | GL.GL_POLYGON_BIT);
8287: disableAttribFor2D(gl);
8288:
8289: // Reset the polygon mode
8290: gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
8291:
8292: gl.glDepthMask(false);
8293: gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
8294: gl.glBindTexture(GL.GL_TEXTURE_2D, objectId);
8295: // set up texture parameter
8296: gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
8297: GL.GL_NEAREST);
8298: gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
8299: GL.GL_NEAREST);
8300: gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S,
8301: GL.GL_REPEAT);
8302: gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T,
8303: GL.GL_REPEAT);
8304:
8305: gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE,
8306: GL.GL_REPLACE);
8307: gl.glEnable(GL.GL_BLEND);
8308: gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
8309:
8310: gl.glEnable(GL.GL_TEXTURE_2D);
8311:
8312: // loaded identity modelview and projection matrix
8313: gl.glMatrixMode(GL.GL_PROJECTION);
8314: gl.glLoadIdentity();
8315:
8316: gl.glOrtho(0.0, winWidth, 0.0, winHeight, 0.0, 0.0);
8317:
8318: gl.glMatrixMode(GL.GL_MODELVIEW);
8319: gl.glLoadIdentity();
8320:
8321: if (gl.isExtensionAvailable("GL_EXT_abgr")) {
8322: glType = GL.GL_ABGR_EXT;
8323: } else {
8324: switch (format) {
8325: case ImageComponentRetained.TYPE_BYTE_RGBA:
8326: glType = GL.GL_RGBA;
8327: break;
8328: case ImageComponentRetained.TYPE_BYTE_RGB:
8329: glType = GL.GL_RGB;
8330: break;
8331: }
8332: }
8333: gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, rasWidth);
8334: gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, minX);
8335: gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, minY);
8336: gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, minX, minY,
8337: maxX - minX, maxY - minY, glType, GL.GL_UNSIGNED_BYTE,
8338: ByteBuffer.wrap(imageYdown));
8339: gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
8340: gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, 0);
8341: gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, 0);
8342:
8343: float texMinU = (float) minX / (float) texWidth;
8344: float texMinV = (float) minY / (float) texHeight;
8345: float texMaxU = (float) maxX / (float) texWidth;
8346: float texMaxV = (float) maxY / (float) texHeight;
8347: float halfWidth = (float) winWidth / 2.0f;
8348: float halfHeight = (float) winHeight / 2.0f;
8349:
8350: float mapMinX = (float) (((px + minX) - halfWidth) / halfWidth);
8351: float mapMinY = (float) ((halfHeight - (py + maxY)) / halfHeight);
8352: float mapMaxX = (float) ((px + maxX - halfWidth) / halfWidth);
8353: float mapMaxY = (float) ((halfHeight - (py + minY)) / halfHeight);
8354:
8355: gl.glBegin(GL.GL_QUADS);
8356:
8357: gl.glTexCoord2f(texMinU, texMaxV);
8358: gl.glVertex2f(mapMinX, mapMinY);
8359: gl.glTexCoord2f(texMaxU, texMaxV);
8360: gl.glVertex2f(mapMaxX, mapMinY);
8361: gl.glTexCoord2f(texMaxU, texMinV);
8362: gl.glVertex2f(mapMaxX, mapMaxY);
8363: gl.glTexCoord2f(texMinU, texMinV);
8364: gl.glVertex2f(mapMinX, mapMaxY);
8365: gl.glEnd();
8366:
8367: // Java 3D always clears the Z-buffer
8368: gl.glDepthMask(true);
8369: gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
8370: gl.glPopAttrib();
8371: }
8372:
8373: boolean initTexturemapping(Context ctx, int texWidth,
8374: int texHeight, int objectId) {
8375: if (VERBOSE)
8376: System.err.println("JoglPipeline.initTexturemapping()");
8377:
8378: GL gl = context(ctx).getGL();
8379:
8380: int glType = (gl.isExtensionAvailable("GL_EXT_abgr") ? GL.GL_ABGR_EXT
8381: : GL.GL_RGBA);
8382:
8383: gl.glBindTexture(GL.GL_TEXTURE_2D, objectId);
8384:
8385: gl.glTexImage2D(GL.GL_PROXY_TEXTURE_2D, 0, GL.GL_RGBA,
8386: texWidth, texHeight, 0, glType, GL.GL_UNSIGNED_BYTE,
8387: null);
8388:
8389: int[] width = new int[1];
8390: gl.glGetTexLevelParameteriv(GL.GL_PROXY_TEXTURE_2D, 0,
8391: GL.GL_TEXTURE_WIDTH, width, 0);
8392:
8393: if (width[0] <= 0) {
8394: return false;
8395: }
8396:
8397: // init texture size only without filling the pixels
8398: gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, texWidth,
8399: texHeight, 0, glType, GL.GL_UNSIGNED_BYTE, null);
8400:
8401: return true;
8402: }
8403:
8404: // Set internal render mode to one of FIELD_ALL, FIELD_LEFT or
8405: // FIELD_RIGHT. Note that it is up to the caller to ensure that
8406: // stereo is available before setting the mode to FIELD_LEFT or
8407: // FIELD_RIGHT. The boolean isTRUE for double buffered mode, FALSE
8408: // foe single buffering.
8409: void setRenderMode(Context ctx, int mode, boolean doubleBuffer) {
8410: if (VERBOSE)
8411: System.err.println("JoglPipeline.setRenderMode()");
8412:
8413: GL gl = context(ctx).getGL();
8414: int drawBuf = 0;
8415: if (doubleBuffer) {
8416: drawBuf = GL.GL_BACK;
8417: switch (mode) {
8418: case Canvas3D.FIELD_LEFT:
8419: drawBuf = GL.GL_BACK_LEFT;
8420: break;
8421: case Canvas3D.FIELD_RIGHT:
8422: drawBuf = GL.GL_BACK_RIGHT;
8423: break;
8424: case Canvas3D.FIELD_ALL:
8425: drawBuf = GL.GL_BACK;
8426: break;
8427: }
8428: } else {
8429: drawBuf = GL.GL_FRONT;
8430: switch (mode) {
8431: case Canvas3D.FIELD_LEFT:
8432: drawBuf = GL.GL_FRONT_LEFT;
8433: break;
8434: case Canvas3D.FIELD_RIGHT:
8435: drawBuf = GL.GL_FRONT_RIGHT;
8436: break;
8437: case Canvas3D.FIELD_ALL:
8438: drawBuf = GL.GL_FRONT;
8439: break;
8440: }
8441: }
8442:
8443: gl.glDrawBuffer(drawBuf);
8444: }
8445:
8446: // Set glDepthMask.
8447: void setDepthBufferWriteEnable(Context ctx, boolean mode) {
8448: if (VERBOSE)
8449: System.err
8450: .println("JoglPipeline.setDepthBufferWriteEnable()");
8451:
8452: GL gl = context(ctx).getGL();
8453: if (mode) {
8454: gl.glDepthMask(true);
8455: } else {
8456: gl.glDepthMask(false);
8457: }
8458: }
8459:
8460: //----------------------------------------------------------------------
8461: // Helper private functions for Canvas3D
8462: //
8463:
8464: private boolean getPropertiesFromCurrentContext(JoglContext ctx) {
8465: GL gl = GLU.getCurrentGL();
8466: // FIXME: this is a heavily abridged set of the stuff in Canvas3D.c;
8467: // probably need to pull much more in
8468: int[] tmp = new int[1];
8469: gl.glGetIntegerv(GL.GL_MAX_TEXTURE_UNITS, tmp, 0);
8470: ctx.setMaxTexCoordSets(tmp[0]);
8471: if (VirtualUniverse.mc.transparentOffScreen) {
8472: ctx.setAlphaClearValue(0.0f);
8473: } else {
8474: ctx.setAlphaClearValue(1.0f);
8475: }
8476: if (gl.isExtensionAvailable("GL_ARB_vertex_shader")) {
8477: gl.glGetIntegerv(GL.GL_MAX_TEXTURE_COORDS_ARB, tmp, 0);
8478: ctx.setMaxTexCoordSets(tmp[0]);
8479: }
8480: return true;
8481: }
8482:
8483: private int[] extractVersionInfo(String versionString) {
8484: StringTokenizer tok = new StringTokenizer(versionString, ". ");
8485: int major = Integer.valueOf(tok.nextToken()).intValue();
8486: int minor = Integer.valueOf(tok.nextToken()).intValue();
8487:
8488: // See if there's vendor-specific information which might
8489: // imply a more recent OpenGL version
8490: tok = new StringTokenizer(versionString, " ");
8491: if (tok.hasMoreTokens()) {
8492: tok.nextToken();
8493: if (tok.hasMoreTokens()) {
8494: Pattern p = Pattern
8495: .compile("\\D*(\\d+)\\.(\\d+)\\.?(\\d*).*");
8496: Matcher m = p.matcher(tok.nextToken());
8497: if (m.matches()) {
8498: int altMajor = Integer.valueOf(m.group(1))
8499: .intValue();
8500: int altMinor = Integer.valueOf(m.group(2))
8501: .intValue();
8502: // Avoid possibly confusing situations by requiring
8503: // major version to match
8504: if (altMajor == major && altMinor > minor) {
8505: minor = altMinor;
8506: }
8507: }
8508: }
8509: }
8510: return new int[] { major, minor };
8511: }
8512:
8513: private int getTextureColorTableSize(GL gl) {
8514: if (!gl.isExtensionAvailable("GL_ARB_imaging")) {
8515: return 0;
8516: }
8517:
8518: gl.glColorTable(GL.GL_PROXY_TEXTURE_COLOR_TABLE_SGI,
8519: GL.GL_RGBA, 256, GL.GL_RGB, GL.GL_INT, null);
8520: int[] tmp = new int[1];
8521: gl.glGetColorTableParameteriv(
8522: GL.GL_PROXY_TEXTURE_COLOR_TABLE_SGI,
8523: GL.GL_COLOR_TABLE_WIDTH, tmp, 0);
8524: return tmp[0];
8525: }
8526:
8527: private void checkTextureExtensions(Canvas3D cv, JoglContext ctx,
8528: GL gl, boolean gl13) {
8529: if (gl13) {
8530: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_MULTI_TEXTURE;
8531: cv.multiTexAccelerated = true;
8532: int[] tmp = new int[1];
8533: gl.glGetIntegerv(GL.GL_MAX_TEXTURE_UNITS, tmp, 0);
8534: cv.maxTextureUnits = tmp[0];
8535: cv.maxTexCoordSets = cv.maxTextureUnits;
8536: if (gl.isExtensionAvailable("GL_ARB_vertex_shader")) {
8537: gl.glGetIntegerv(GL.GL_MAX_TEXTURE_COORDS_ARB, tmp, 0);
8538: cv.maxTexCoordSets = tmp[0];
8539: }
8540: }
8541:
8542: if (gl.isExtensionAvailable("GL_SGI_texture_color_table")
8543: || gl.isExtensionAvailable("GL_ARB_imaging")) {
8544: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COLOR_TABLE;
8545:
8546: // get texture color table size
8547: // need to check later
8548: cv.textureColorTableSize = getTextureColorTableSize(gl);
8549: if (cv.textureColorTableSize <= 0) {
8550: cv.textureExtendedFeatures &= ~Canvas3D.TEXTURE_COLOR_TABLE;
8551: }
8552: if (cv.textureColorTableSize > 256) {
8553: cv.textureColorTableSize = 256;
8554: }
8555: }
8556:
8557: if (gl.isExtensionAvailable("GL_ARB_texture_env_combine")) {
8558: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE;
8559: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE_SUBTRACT;
8560: } else if (gl
8561: .isExtensionAvailable("GL_EXT_texture_env_combine")) {
8562: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE;
8563: }
8564:
8565: if (gl.isExtensionAvailable("GL_NV_register_combiners")) {
8566: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_REGISTER_COMBINERS;
8567: }
8568:
8569: if (gl.isExtensionAvailable("GL_ARB_texture_env_dot3")
8570: || gl.isExtensionAvailable("GL_EXT_texture_env_dot3")) {
8571: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE_DOT3;
8572: }
8573:
8574: if (gl13) {
8575: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_CUBE_MAP;
8576: }
8577:
8578: if (gl.isExtensionAvailable("GL_SGIS_sharpen_texture")) {
8579: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_SHARPEN;
8580: }
8581:
8582: if (gl.isExtensionAvailable("GL_SGIS_detail_texture")) {
8583: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_DETAIL;
8584: }
8585:
8586: if (gl.isExtensionAvailable("GL_SGIS_texture_filter4")) {
8587: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_FILTER4;
8588: }
8589:
8590: if (gl
8591: .isExtensionAvailable("GL_EXT_texture_filter_anisotropic")) {
8592: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_ANISOTROPIC_FILTER;
8593: float[] tmp = new float[1];
8594: gl
8595: .glGetFloatv(GL.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,
8596: tmp, 0);
8597: cv.anisotropicDegreeMax = tmp[0];
8598: }
8599:
8600: if (gl.isExtensionAvailable("GL_SGIX_texture_lod_bias")) {
8601: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_LOD_OFFSET;
8602: }
8603:
8604: if (!VirtualUniverse.mc.enforcePowerOfTwo
8605: && gl
8606: .isExtensionAvailable("GL_ARB_texture_non_power_of_two")) {
8607: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_NON_POWER_OF_TWO;
8608: }
8609:
8610: if (gl.isExtensionAvailable("GL_SGIS_generate_mipmap")) {
8611: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_AUTO_MIPMAP_GENERATION;
8612: }
8613:
8614: }
8615:
8616: private void checkGLSLShaderExtensions(Canvas3D cv,
8617: JoglContext ctx, GL gl, boolean glslLibraryAvailable) {
8618: if (glslLibraryAvailable
8619: && gl.isExtensionAvailable("GL_ARB_shader_objects")
8620: && gl
8621: .isExtensionAvailable("GL_ARB_shading_language_100")) {
8622: // Initialize shader vertex attribute function pointers
8623: ctx.initGLSLVertexAttributeImpl();
8624:
8625: // FIXME: this isn't complete and would need to set up the
8626: // JoglContext for dispatch of various routines such as those
8627: // related to vertex attributes
8628: int[] tmp = new int[1];
8629: gl.glGetIntegerv(GL.GL_MAX_TEXTURE_IMAGE_UNITS_ARB, tmp, 0);
8630: cv.maxTextureImageUnits = tmp[0];
8631: gl.glGetIntegerv(GL.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB,
8632: tmp, 0);
8633: cv.maxVertexTextureImageUnits = tmp[0];
8634: gl.glGetIntegerv(
8635: GL.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, tmp, 0);
8636: cv.maxCombinedTextureImageUnits = tmp[0];
8637: int vertexAttrOffset = VirtualUniverse.mc.glslVertexAttrOffset;
8638: ctx.setGLSLVertexAttrOffset(vertexAttrOffset);
8639: gl.glGetIntegerv(GL.GL_MAX_VERTEX_ATTRIBS_ARB, tmp, 0);
8640: cv.maxVertexAttrs = tmp[0];
8641: // decr count to allow for reserved vertex attrs
8642: cv.maxVertexAttrs -= vertexAttrOffset;
8643: if (cv.maxVertexAttrs < 0) {
8644: cv.maxVertexAttrs = 0;
8645: }
8646: cv.shadingLanguageGLSL = true;
8647: }
8648: }
8649:
8650: private boolean createCgContext(JoglContext ctx) {
8651: CGcontext cgContext = CgGL.cgCreateContext();
8652:
8653: int err = CgGL.cgGetError();
8654: if (err != 0) {
8655: String detail = CgGL.cgGetErrorString(err);
8656: System.err
8657: .println("JAVA 3D ERROR : Fatal error in creating Cg context: \""
8658: + detail + "\"");
8659: return false;
8660: }
8661:
8662: if (cgContext == null) {
8663: System.err
8664: .println("JAVA 3D ERROR : Invalid null Cg context");
8665: return false;
8666: }
8667:
8668: ctx.setCgContext(cgContext);
8669:
8670: // Use GL_ARB_vertex_program extension if supported by video card
8671: if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_ARBVP1)) {
8672: ctx.setCgVertexProfile(CgGL.CG_PROFILE_ARBVP1);
8673: } else if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_VP20)) {
8674: ctx.setCgVertexProfile(CgGL.CG_PROFILE_VP20);
8675: } else {
8676: System.err
8677: .println("JAVA 3D ERROR : No CG vertex program profile is supported");
8678: ctx.setCgContext(null);
8679: return false;
8680: }
8681:
8682: // Use GL_ARB_fragment_program extension if supported by video card
8683: if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_ARBFP1)) {
8684: ctx.setCgFragmentProfile(CgGL.CG_PROFILE_ARBFP1);
8685: } else if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_FP20)) {
8686: ctx.setCgFragmentProfile(CgGL.CG_PROFILE_FP20);
8687: } else {
8688: System.err
8689: .println("JAVA 3D ERROR : No CG fragment program profile is supported");
8690: ctx.setCgContext(null);
8691: return false;
8692: }
8693:
8694: return true;
8695: }
8696:
8697: private void checkCgShaderExtensions(Canvas3D cv, JoglContext ctx,
8698: GL gl, boolean cgLibraryAvailable) {
8699: if (cgLibraryAvailable) {
8700: if (!createCgContext(ctx)) {
8701: return;
8702: }
8703: cv.shadingLanguageCg = true;
8704: // TODO: Query Cg texture sampler limits
8705: cv.maxTextureImageUnits = cv.maxTextureUnits;
8706: cv.maxVertexTextureImageUnits = 0;
8707: cv.maxCombinedTextureImageUnits = cv.maxTextureUnits;
8708: // TODO: Query max vertex attrs
8709: cv.maxVertexAttrs = 7;
8710: // Initialize shader vertex attribute function pointers
8711: ctx.initCgVertexAttributeImpl();
8712: }
8713: }
8714:
8715: private void setupCanvasProperties(Canvas3D cv, JoglContext ctx,
8716: GL gl, boolean glslLibraryAvailable,
8717: boolean cgLibraryAvailable) {
8718: // Note: this includes relevant portions from both the
8719: // NativePipeline's getPropertiesFromCurrentContext and setupCanvasProperties
8720:
8721: // Reset all fields
8722: cv.multiTexAccelerated = false;
8723: cv.maxTextureUnits = 1;
8724: cv.maxTexCoordSets = 1;
8725: cv.maxTextureImageUnits = 0;
8726: cv.maxVertexTextureImageUnits = 0;
8727: cv.maxCombinedTextureImageUnits = 0;
8728: cv.maxVertexAttrs = 0;
8729: cv.extensionsSupported = 0;
8730: cv.textureExtendedFeatures = 0;
8731: cv.textureColorTableSize = 0;
8732: cv.anisotropicDegreeMax = 0;
8733: cv.textureBoundaryWidthMax = 0;
8734: cv.textureWidthMax = 0;
8735: cv.textureHeightMax = 0;
8736: cv.texture3DWidthMax = 0;
8737: cv.texture3DHeightMax = 0;
8738: cv.texture3DDepthMax = 0;
8739: cv.shadingLanguageGLSL = false;
8740: cv.shadingLanguageCg = false;
8741:
8742: // Now make queries and set up these fields
8743: String glVersion = gl.glGetString(GL.GL_VERSION);
8744: String glVendor = gl.glGetString(GL.GL_VENDOR);
8745: String glRenderer = gl.glGetString(GL.GL_RENDERER);
8746: cv.nativeGraphicsVersion = glVersion;
8747: cv.nativeGraphicsVendor = glVendor;
8748: cv.nativeGraphicsRenderer = glRenderer;
8749:
8750: // find out the version, major and minor version number
8751: int[] versionNumbers = extractVersionInfo(glVersion);
8752: int major = versionNumbers[0];
8753: int minor = versionNumbers[1];
8754:
8755: ///////////////////////////////////////////
8756: // setup the graphics context properties //
8757:
8758: // NOTE: Java 3D now requires OpenGL 1.3 for full functionality.
8759: // For backwards compatibility with certain older graphics cards and
8760: // drivers (e.g., the Linux DRI driver for older ATI cards),
8761: // we will try to run on OpenGL 1.2 in an unsupported manner. However,
8762: // we will not attempt to use OpenGL extensions for any features that
8763: // are available in OpenGL 1.3, specifically multitexture, multisample,
8764: // and cube map textures.
8765:
8766: if (major < 1 || (major == 1 && minor < 2)) {
8767: throw new IllegalRenderingStateException(
8768: "Java 3D ERROR : OpenGL 1.2 or better is required (GL_VERSION="
8769: + major + "." + minor + ")");
8770: }
8771:
8772: boolean gl20 = false;
8773: boolean gl14 = false;
8774: boolean gl13 = false;
8775:
8776: if (major == 1) {
8777: if (minor == 2) {
8778: System.err
8779: .println("JAVA 3D: OpenGL 1.2 detected; will run with reduced functionality");
8780: }
8781: if (minor >= 3) {
8782: gl13 = true;
8783: }
8784: if (minor >= 4) {
8785: gl14 = true;
8786: }
8787: } else /* major >= 2 */{
8788: gl13 = true;
8789: gl14 = true;
8790: gl20 = true;
8791: }
8792:
8793: if (gl20) {
8794: assert gl13;
8795: assert gl14;
8796: assert gl.isExtensionAvailable("GL_VERSION_2_0");
8797: }
8798:
8799: if (gl14) {
8800: assert gl13;
8801: assert gl.isExtensionAvailable("GL_VERSION_1_4");
8802: }
8803:
8804: if (gl13) {
8805: assert gl.isExtensionAvailable("GL_VERSION_1_3");
8806: }
8807:
8808: // Set up properties for OpenGL 1.3
8809: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_3D;
8810:
8811: // Note that we don't query for GL_ARB_imaging here
8812:
8813: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_LOD_RANGE;
8814:
8815: if (gl14) {
8816: cv.textureExtendedFeatures |= Canvas3D.TEXTURE_AUTO_MIPMAP_GENERATION;
8817: }
8818:
8819: // look for OpenGL 2.0 features
8820: // Fix to Issue 455 : Need to disable NPOT textures for older cards that claim to support it.
8821: // Some older cards (e.g., Nvidia fx500 and ATI 9800) claim to support OpenGL 2.0.
8822: // This means that these cards have to support non-power-of-two (NPOT) texture,
8823: // but their lack the necessary HW force the vendors the emulate this feature in software.
8824: // The result is a ~100x slower down compare to power-of-two textures.
8825: // Do not check for gl20 but instead check of GL_ARB_texture_non_power_of_two extension string
8826: // if (gl20) {
8827: // if(!VirtualUniverse.mc.enforcePowerOfTwo) {
8828: // cv.textureExtendedFeatures |= Canvas3D.TEXTURE_NON_POWER_OF_TWO;
8829: // }
8830: // }
8831:
8832: // Setup GL_EXT_abgr
8833: if (gl.isExtensionAvailable("GL_EXT_abgr")) {
8834: cv.extensionsSupported |= Canvas3D.EXT_ABGR;
8835: }
8836:
8837: // GL_BGR is always supported
8838: cv.extensionsSupported |= Canvas3D.EXT_BGR;
8839:
8840: // Setup multisample
8841: // FIXME: this is not correct for the Windows platform yet
8842: if (gl13) {
8843: cv.extensionsSupported |= Canvas3D.MULTISAMPLE;
8844: ctx.setHasMultisample(true);
8845: }
8846:
8847: if ((cv.extensionsSupported & Canvas3D.MULTISAMPLE) != 0
8848: && !VirtualUniverse.mc.implicitAntialiasing) {
8849: gl.glDisable(GL.GL_MULTISAMPLE);
8850: }
8851:
8852: // Check texture extensions
8853: checkTextureExtensions(cv, ctx, gl, gl13);
8854:
8855: // Check shader extensions
8856: if (gl13) {
8857: checkGLSLShaderExtensions(cv, ctx, gl, glslLibraryAvailable);
8858: checkCgShaderExtensions(cv, ctx, gl, cgLibraryAvailable);
8859: } else {
8860: // Force shaders to be disabled, since no multitexture support
8861: checkGLSLShaderExtensions(cv, ctx, gl, false);
8862: checkCgShaderExtensions(cv, ctx, gl, false);
8863: }
8864:
8865: // Setup GL_SUN_gloabl_alpha
8866: if (gl.isExtensionAvailable("GL_SUN_gloabl_alpha")) {
8867: cv.extensionsSupported |= Canvas3D.SUN_GLOBAL_ALPHA;
8868: }
8869:
8870: cv.textureBoundaryWidthMax = 1;
8871: {
8872: int[] tmp = new int[1];
8873: gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, tmp, 0);
8874: cv.textureWidthMax = tmp[0];
8875: cv.textureHeightMax = tmp[0];
8876:
8877: tmp[0] = -1;
8878: gl.glGetIntegerv(GL.GL_MAX_3D_TEXTURE_SIZE, tmp, 0);
8879: cv.texture3DWidthMax = tmp[0];
8880: cv.texture3DHeightMax = tmp[0];
8881: cv.texture3DDepthMax = tmp[0];
8882: }
8883: }
8884:
8885: /*
8886: * Function to disable most rendering attributes when doing a 2D
8887: * clear, image copy, or image composite operation. Note that the
8888: * caller must save/restore the attributes with
8889: * pushAttrib(GL_ENABLE_BIT|...) and popAttrib()
8890: */
8891: private void disableAttribFor2D(GL gl) {
8892: gl.glDisable(GL.GL_ALPHA_TEST);
8893: gl.glDisable(GL.GL_BLEND);
8894: gl.glDisable(GL.GL_COLOR_LOGIC_OP);
8895: gl.glDisable(GL.GL_COLOR_MATERIAL);
8896: gl.glDisable(GL.GL_CULL_FACE);
8897: gl.glDisable(GL.GL_DEPTH_TEST);
8898: gl.glDisable(GL.GL_FOG);
8899: gl.glDisable(GL.GL_LIGHTING);
8900: gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
8901: gl.glDisable(GL.GL_POLYGON_STIPPLE);
8902: gl.glDisable(GL.GL_STENCIL_TEST);
8903: gl.glDisable(GL.GL_TEXTURE_2D);
8904: gl.glDisable(GL.GL_TEXTURE_GEN_Q);
8905: gl.glDisable(GL.GL_TEXTURE_GEN_R);
8906: gl.glDisable(GL.GL_TEXTURE_GEN_S);
8907: gl.glDisable(GL.GL_TEXTURE_GEN_T);
8908:
8909: for (int i = 0; i < 6; i++) {
8910: gl.glDisable(GL.GL_CLIP_PLANE0 + i);
8911: }
8912:
8913: gl.glDisable(GL.GL_TEXTURE_3D);
8914: gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
8915:
8916: if (gl.isExtensionAvailable("GL_NV_register_combiners")) {
8917: gl.glDisable(GL.GL_REGISTER_COMBINERS_NV);
8918: }
8919:
8920: if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) {
8921: gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI);
8922: }
8923:
8924: if (gl.isExtensionAvailable("GL_SUN_global_alpha")) {
8925: gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN);
8926: }
8927:
8928: }
8929:
8930: private void disableAttribForRaster(GL gl) {
8931:
8932: gl.glDisable(GL.GL_COLOR_MATERIAL);
8933: gl.glDisable(GL.GL_CULL_FACE);
8934: gl.glDisable(GL.GL_LIGHTING);
8935: gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
8936: gl.glDisable(GL.GL_POLYGON_STIPPLE);
8937:
8938: // TODO: Disable if Raster.CLIP_POSITION is true
8939: // for (int i = 0; i < 6; i++) {
8940: // gl.glDisable(GL.GL_CLIP_PLANE0 + i);
8941: // }
8942:
8943: if (gl.isExtensionAvailable("GL_SUN_global_alpha")) {
8944: gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN);
8945: }
8946: }
8947:
8948: private void copyTranspose(double[] src, double[] dst) {
8949: dst[0] = src[0];
8950: dst[1] = src[4];
8951: dst[2] = src[8];
8952: dst[3] = src[12];
8953: dst[4] = src[1];
8954: dst[5] = src[5];
8955: dst[6] = src[9];
8956: dst[7] = src[13];
8957: dst[8] = src[2];
8958: dst[9] = src[6];
8959: dst[10] = src[10];
8960: dst[11] = src[14];
8961: dst[12] = src[3];
8962: dst[13] = src[7];
8963: dst[14] = src[11];
8964: dst[15] = src[15];
8965: }
8966:
8967: // ---------------------------------------------------------------------
8968:
8969: //
8970: // Canvas3D / GraphicsConfigTemplate3D methods - logic dealing with
8971: // native graphics configuration or drawing surface
8972: //
8973:
8974: // Return a graphics config based on the one passed in. Note that we can
8975: // assert that the input config is non-null and was created from a
8976: // GraphicsConfigTemplate3D.
8977: // This method must return a valid GraphicsConfig, or else it must throw
8978: // an exception if one cannot be returned.
8979: GraphicsConfiguration getGraphicsConfig(
8980: GraphicsConfiguration gconfig) {
8981: if (VERBOSE)
8982: System.err.println("JoglPipeline.getGraphicsConfig()");
8983: JoglGraphicsConfiguration config = (JoglGraphicsConfiguration) gconfig;
8984: GLCapabilitiesChooser indexChooser = null;
8985: if (config.getChosenIndex() >= 0) {
8986: indexChooser = new IndexCapabilitiesChooser(config
8987: .getChosenIndex());
8988: }
8989:
8990: AbstractGraphicsConfiguration absConfig = GLDrawableFactory
8991: .getFactory().chooseGraphicsConfiguration(
8992: config.getGLCapabilities(), indexChooser,
8993: new AWTGraphicsDevice(config.getDevice()));
8994: if (absConfig == null) {
8995: return null;
8996: }
8997: return ((AWTGraphicsConfiguration) absConfig)
8998: .getGraphicsConfiguration();
8999:
9000: /*
9001:
9002: System.err.println("JoglPipeline.getGraphicsConfig()");
9003: // Just return the input graphics config for now. eventually, we will
9004: // use the input graphics config to get the GraphicsConfigTemplate3D
9005: // parameters, which we will use to create a new graphics config with JOGL.
9006: return gconfig;
9007: */
9008: }
9009:
9010: // Get the native FBconfig pointer
9011: long getFbConfig(GraphicsConfigInfo gcInfo) {
9012: if (VERBOSE)
9013: System.err.println("JoglPipeline.getFbConfig()");
9014: return 0L; // Dummy method in JOGL
9015: }
9016:
9017: private static final int DISABLE_STEREO = 1;
9018: private static final int DISABLE_AA = 2;
9019: private static final int DISABLE_DOUBLE_BUFFER = 3;
9020:
9021: // Get best graphics config from pipeline
9022: GraphicsConfiguration getBestConfiguration(
9023: GraphicsConfigTemplate3D gct, GraphicsConfiguration[] gc) {
9024: if (VERBOSE)
9025: System.err.println("JoglPipeline.getBestConfiguration()");
9026: /*
9027: System.err.println("gct.getDoubleBuffer(): " + gct.getDoubleBuffer());
9028: System.err.println("gct.getStereo(): " + gct.getStereo());
9029: System.err.println("gct.getDepthBits(): " + gct.getDepthSize());
9030: System.err.println("gct.getRedSize(): " + gct.getRedSize());
9031: System.err.println("gct.getGreenSize(): " + gct.getGreenSize());
9032: System.err.println("gct.getBlueSize(): " + gct.getBlueSize());
9033: System.err.println("gct.getSceneAntialiasing(): " + gct.getSceneAntialiasing());
9034: */
9035:
9036: // Create a GLCapabilities based on the GraphicsConfigTemplate3D
9037: GLCapabilities caps = new GLCapabilities();
9038: caps
9039: .setDoubleBuffered(gct.getDoubleBuffer() <= GraphicsConfigTemplate.PREFERRED);
9040: caps
9041: .setStereo(gct.getStereo() <= GraphicsConfigTemplate.PREFERRED);
9042: caps.setDepthBits(gct.getDepthSize());
9043: caps.setStencilBits(gct.getStencilSize());
9044: caps.setRedBits(Math.max(5, gct.getRedSize()));
9045: caps.setGreenBits(Math.max(5, gct.getGreenSize()));
9046: caps.setBlueBits(Math.max(5, gct.getBlueSize()));
9047: caps
9048: .setSampleBuffers(gct.getSceneAntialiasing() <= GraphicsConfigTemplate.PREFERRED);
9049: // FIXME: should be smarter about choosing the number of samples
9050: // (Java3D's native code has a loop trying 8, 6, 4, 3, and 2 samples)
9051: caps.setNumSamples(4);
9052:
9053: // Issue 399: Request alpha buffer if transparentOffScreen is set
9054: if (VirtualUniverse.mc.transparentOffScreen) {
9055: caps.setAlphaBits(1);
9056: }
9057:
9058: java.util.List<Integer> capsToDisable = new ArrayList<Integer>();
9059: // Add PREFERRED capabilities in order we will try disabling them
9060: if (gct.getStereo() == GraphicsConfigTemplate.PREFERRED) {
9061: capsToDisable.add(new Integer(DISABLE_STEREO));
9062: }
9063: if (gct.getSceneAntialiasing() == GraphicsConfigTemplate.PREFERRED) {
9064: capsToDisable.add(new Integer(DISABLE_AA));
9065: }
9066: if (gct.getDoubleBuffer() == GraphicsConfigTemplate.PREFERRED) {
9067: capsToDisable.add(new Integer(DISABLE_DOUBLE_BUFFER));
9068: }
9069:
9070: // Pick the GraphicsDevice from a random configuration
9071: GraphicsDevice dev = gc[0].getDevice();
9072:
9073: // Create a Frame and dummy GLCanvas to perform eager pixel format selection
9074:
9075: // Note that we loop in similar fashion to the NativePipeline's
9076: // native code in the situation where we need to disable certain
9077: // capabilities which aren't required
9078: boolean tryAgain = true;
9079: CapabilitiesCapturer capturer = null;
9080: while (tryAgain) {
9081: Frame f = new Frame(dev.getDefaultConfiguration());
9082: f.setUndecorated(true);
9083: f.setLayout(new BorderLayout());
9084: capturer = new CapabilitiesCapturer();
9085: try {
9086: QueryCanvas canvas = new QueryCanvas(caps, capturer,
9087: dev);
9088: f.add(canvas, BorderLayout.CENTER);
9089: f.setSize(MIN_FRAME_SIZE, MIN_FRAME_SIZE);
9090: f.setVisible(true);
9091: canvas.doQuery();
9092: if (DEBUG_CONFIG) {
9093: System.err
9094: .println("Waiting for CapabilitiesCapturer");
9095: }
9096: // Try to wait for result without blocking EDT
9097: if (!EventQueue.isDispatchThread()) {
9098: synchronized (capturer) {
9099: if (!capturer.done()) {
9100: try {
9101: capturer.wait(WAIT_TIME);
9102: } catch (InterruptedException e) {
9103: }
9104: }
9105: }
9106: }
9107: disposeOnEDT(f);
9108: tryAgain = false;
9109: } catch (GLException e) {
9110: // Failure to select a pixel format; try switching off one
9111: // of the only-preferred capabilities
9112: if (capsToDisable.size() == 0) {
9113: tryAgain = false;
9114: } else {
9115: int whichToDisable = capsToDisable.remove(0)
9116: .intValue();
9117: switch (whichToDisable) {
9118: case DISABLE_STEREO:
9119: caps.setStereo(false);
9120: break;
9121:
9122: case DISABLE_AA:
9123: caps.setSampleBuffers(false);
9124: break;
9125:
9126: case DISABLE_DOUBLE_BUFFER:
9127: caps.setDoubleBuffered(false);
9128: break;
9129:
9130: default:
9131: throw new AssertionError(
9132: "missing case statement");
9133: }
9134: }
9135: }
9136: }
9137: int chosenIndex = capturer.getChosenIndex();
9138: GLCapabilities chosenCaps = null;
9139: if (chosenIndex < 0) {
9140: if (DEBUG_CONFIG) {
9141: System.err
9142: .println("CapabilitiesCapturer returned invalid index");
9143: }
9144: // It's possible some platforms or implementations might not
9145: // support the GLCapabilitiesChooser mechanism; feed in the
9146: // same GLCapabilities later which we gave to the selector
9147: chosenCaps = caps;
9148: } else {
9149: if (DEBUG_CONFIG) {
9150: System.err
9151: .println("CapabilitiesCapturer returned index="
9152: + chosenIndex);
9153: }
9154: chosenCaps = capturer.getCapabilities();
9155: }
9156:
9157: JoglGraphicsConfiguration config = new JoglGraphicsConfiguration(
9158: chosenCaps, chosenIndex, dev);
9159:
9160: // FIXME: because of the fact that JoglGraphicsConfiguration
9161: // doesn't override hashCode() or equals(), we will basically be
9162: // creating a new one each time getBestConfiguration() is
9163: // called; in theory, we should probably map the same
9164: // GLCapabilities on the same GraphicsDevice to the same
9165: // JoglGraphicsConfiguration object
9166:
9167: // Cache the GraphicsTemplate3D
9168: synchronized (Canvas3D.graphicsConfigTable) {
9169: GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(gct);
9170: // We don't need this
9171: // gcInfo.setPrivateData(privateData);
9172: Canvas3D.graphicsConfigTable.put(config, gcInfo);
9173: }
9174:
9175: return config;
9176:
9177: /*
9178:
9179: // TODO: implement this
9180:
9181: // TODO: construct a unique GraphicsConfiguration object that will be
9182: // used the key in the hashmap so we can lookup the GraphicsTemplate3D
9183: GraphicsConfiguration gc1 = GraphicsEnvironment.getLocalGraphicsEnvironment().
9184: getDefaultScreenDevice().getDefaultConfiguration();
9185:
9186: // Cache the GraphicsTemplate3D
9187: synchronized (Canvas3D.graphicsConfigTable) {
9188: if (Canvas3D.graphicsConfigTable.get(gc1) == null) {
9189: GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(gct);
9190: // gcInfo.setPrivateData(privateData);
9191: Canvas3D.graphicsConfigTable.put(gc1, gcInfo);
9192: }
9193: }
9194: return gc1;
9195:
9196: */
9197: }
9198:
9199: // Determine whether specified graphics config is supported by pipeline
9200: boolean isGraphicsConfigSupported(GraphicsConfigTemplate3D gct,
9201: GraphicsConfiguration gc) {
9202: if (VERBOSE)
9203: System.err
9204: .println("JoglPipeline.isGraphicsConfigSupported()");
9205:
9206: // FIXME: it looks like this method is implemented incorrectly
9207: // in the existing NativePipeline in both the Windows and X11
9208: // ports. According to the semantics of the javadoc, it looks
9209: // like this method is supposed to figure out the OpenGL
9210: // capabilities which would be requested by the passed
9211: // GraphicsConfiguration object were it to be used, and see
9212: // whether it is possible to create a context with them.
9213: // Instead, on both platforms, the implementations basically set
9214: // up a query based on the contents of the
9215: // GraphicsConfigTemplate3D object, using the
9216: // GraphicsConfiguration object only to figure out on which
9217: // GraphicsDevice and screen we're making the request, and see
9218: // whether it's possible to choose an OpenGL pixel format based
9219: // on that information. This makes this method less useful and
9220: // we can probably just safely return true here uniformly
9221: // without breaking anything.
9222: return true;
9223: }
9224:
9225: // Methods to get actual capabilities from Canvas3D
9226: boolean hasDoubleBuffer(Canvas3D cv) {
9227: if (VERBOSE)
9228: System.err.println("JoglPipeline.hasDoubleBuffer()");
9229: if (VERBOSE)
9230: System.err.println(" Returning "
9231: + caps(cv).getDoubleBuffered());
9232: return caps(cv).getDoubleBuffered();
9233: }
9234:
9235: boolean hasStereo(Canvas3D cv) {
9236: if (VERBOSE)
9237: System.err.println("JoglPipeline.hasStereo()");
9238: if (VERBOSE)
9239: System.err.println(" Returning " + caps(cv).getStereo());
9240: return caps(cv).getStereo();
9241: }
9242:
9243: int getStencilSize(Canvas3D cv) {
9244: if (VERBOSE)
9245: System.err.println("JoglPipeline.getStencilSize()");
9246: if (VERBOSE)
9247: System.err.println(" Returning "
9248: + caps(cv).getStencilBits());
9249: return caps(cv).getStencilBits();
9250: }
9251:
9252: boolean hasSceneAntialiasingMultisample(Canvas3D cv) {
9253: if (VERBOSE)
9254: System.err
9255: .println("JoglPipeline.hasSceneAntialiasingMultisample()");
9256: if (VERBOSE)
9257: System.err.println(" Returning "
9258: + caps(cv).getSampleBuffers());
9259:
9260: return caps(cv).getSampleBuffers();
9261: }
9262:
9263: boolean hasSceneAntialiasingAccum(Canvas3D cv) {
9264: if (VERBOSE)
9265: System.err
9266: .println("JoglPipeline.hasSceneAntialiasingAccum()");
9267: GLCapabilities caps = caps(cv);
9268: if (VERBOSE)
9269: System.err.println(" Returning "
9270: + (caps.getAccumRedBits() > 0
9271: && caps.getAccumGreenBits() > 0 && caps
9272: .getAccumBlueBits() > 0));
9273: return (caps.getAccumRedBits() > 0
9274: && caps.getAccumGreenBits() > 0 && caps
9275: .getAccumBlueBits() > 0);
9276: }
9277:
9278: // Methods to get native WS display and screen
9279: long getDisplay() {
9280: if (VERBOSE)
9281: System.err.println("JoglPipeline.getDisplay()");
9282: return 0L; // Dummy method in JOGL
9283: }
9284:
9285: private boolean checkedForGetScreenMethod = false;
9286: private Method getScreenMethod = null;
9287:
9288: int getScreen(final GraphicsDevice graphicsDevice) {
9289: if (VERBOSE)
9290: System.err.println("JoglPipeline.getScreen()");
9291:
9292: if (!checkedForGetScreenMethod) {
9293: // All of the Sun GraphicsDevice implementations have a method
9294: // int getScreen();
9295: // which we want to call reflectively if it's available.
9296: AccessController.doPrivileged(new PrivilegedAction() {
9297: public Object run() {
9298: try {
9299: getScreenMethod = graphicsDevice.getClass()
9300: .getDeclaredMethod("getScreen",
9301: new Class[] {});
9302: getScreenMethod.setAccessible(true);
9303: } catch (Exception e) {
9304: }
9305: checkedForGetScreenMethod = true;
9306: return null;
9307: }
9308: });
9309: }
9310:
9311: if (getScreenMethod != null) {
9312: try {
9313: return ((Integer) getScreenMethod.invoke(
9314: graphicsDevice, (Object[]) null)).intValue();
9315: } catch (Exception e) {
9316: throw new RuntimeException(e);
9317: }
9318: }
9319:
9320: return 0;
9321: }
9322:
9323: //----------------------------------------------------------------------
9324: // Helper classes and methods to support query context functionality
9325: // and pixel format selection
9326:
9327: interface ExtendedCapabilitiesChooser extends GLCapabilitiesChooser {
9328: public void init(GLContext context);
9329: }
9330:
9331: // Canvas subclass to help with various query operations such as the
9332: // "query context" mechanism and pixel format selection.
9333: // Must defeat and simplify the single-threading behavior of JOGL's
9334: // GLCanvas in order to be able to set up a temporary pixel format
9335: // and OpenGL context. Apparently simply turning off the
9336: // single-threaded mode isn't enough to do this.
9337: class QueryCanvas extends Canvas {
9338: private GLDrawable drawable;
9339: private ExtendedCapabilitiesChooser chooser;
9340: private boolean alreadyRan;
9341:
9342: public QueryCanvas(GLCapabilities capabilities,
9343: ExtendedCapabilitiesChooser chooser,
9344: GraphicsDevice device) {
9345: // The platform-specific GLDrawableFactory will only provide a
9346: // non-null GraphicsConfiguration on platforms where this is
9347: // necessary (currently only X11, as Windows allows the pixel
9348: // format of the window to be set later and Mac OS X seems to
9349: // handle this very differently than all other platforms). On
9350: // other platforms this method returns null; it is the case (at
9351: // least in the Sun AWT implementation) that this will result in
9352: // equivalent behavior to calling the no-arg super() constructor
9353: // for Canvas.
9354: super (unwrap((AWTGraphicsConfiguration) GLDrawableFactory
9355: .getFactory().chooseGraphicsConfiguration(
9356: capabilities, chooser,
9357: new AWTGraphicsDevice(device))));
9358: drawable = GLDrawableFactory.getFactory().getGLDrawable(
9359: this , capabilities, chooser);
9360: this .chooser = chooser;
9361: }
9362:
9363: public void addNotify() {
9364: super .addNotify();
9365: drawable.setRealized(true);
9366: }
9367:
9368: // It seems that at least on Mac OS X we need to do the OpenGL
9369: // context-related work outside of the addNotify call because the
9370: // Canvas hasn't been resized to a non-zero size by that point
9371: public void doQuery() {
9372: if (alreadyRan)
9373: return;
9374: GLContext context = drawable.createContext(null);
9375: int res = context.makeCurrent();
9376: if (res != GLContext.CONTEXT_NOT_CURRENT) {
9377: try {
9378: chooser.init(context);
9379: } finally {
9380: context.release();
9381: }
9382: }
9383: context.destroy();
9384: alreadyRan = true;
9385: }
9386: }
9387:
9388: private static GraphicsConfiguration unwrap(
9389: AWTGraphicsConfiguration config) {
9390: if (config == null) {
9391: return null;
9392: }
9393: return config.getGraphicsConfiguration();
9394: }
9395:
9396: // Used in conjunction with IndexCapabilitiesChooser in pixel format
9397: // selection -- see getBestConfiguration
9398: class CapabilitiesCapturer extends DefaultGLCapabilitiesChooser
9399: implements ExtendedCapabilitiesChooser {
9400: private boolean done;
9401: private GLCapabilities capabilities;
9402: private int chosenIndex = -1;
9403:
9404: public boolean done() {
9405: return done;
9406: }
9407:
9408: public GLCapabilities getCapabilities() {
9409: return capabilities;
9410: }
9411:
9412: public int getChosenIndex() {
9413: return chosenIndex;
9414: }
9415:
9416: public int chooseCapabilities(GLCapabilities desired,
9417: GLCapabilities[] available,
9418: int windowSystemRecommendedChoice) {
9419: int res = super .chooseCapabilities(desired, available,
9420: windowSystemRecommendedChoice);
9421: capabilities = available[res];
9422: chosenIndex = res;
9423: markDone();
9424: return res;
9425: }
9426:
9427: public void init(GLContext context) {
9428: // Avoid hanging things up for several seconds
9429: kick();
9430: }
9431:
9432: private void markDone() {
9433: synchronized (this ) {
9434: done = true;
9435: notifyAll();
9436: }
9437: }
9438:
9439: private void kick() {
9440: synchronized (this ) {
9441: notifyAll();
9442: }
9443: }
9444: }
9445:
9446: // Used to support the query context mechanism -- needs to be more
9447: // than just a GLCapabilitiesChooser
9448: class ContextQuerier extends DefaultGLCapabilitiesChooser implements
9449: ExtendedCapabilitiesChooser {
9450: private Canvas3D canvas;
9451: private boolean glslLibraryAvailable;
9452: private boolean cgLibraryAvailable;
9453: private boolean done;
9454:
9455: public ContextQuerier(Canvas3D canvas,
9456: boolean glslLibraryAvailable, boolean cgLibraryAvailable) {
9457: this .canvas = canvas;
9458: this .glslLibraryAvailable = glslLibraryAvailable;
9459: this .cgLibraryAvailable = cgLibraryAvailable;
9460: }
9461:
9462: public boolean done() {
9463: return done;
9464: }
9465:
9466: public void init(GLContext context) {
9467: // This is basically a temporary
9468: JoglContext jctx = new JoglContext(context);
9469: // Set up various properties
9470: if (getPropertiesFromCurrentContext(jctx)) {
9471: setupCanvasProperties(canvas, jctx, context.getGL(),
9472: glslLibraryAvailable, cgLibraryAvailable);
9473: }
9474: markDone();
9475: }
9476:
9477: private void markDone() {
9478: synchronized (this ) {
9479: done = true;
9480: notifyAll();
9481: }
9482: }
9483: }
9484:
9485: // Used in two phases of pixel format selection: transforming the
9486: // JoglGraphicsConfiguration to a real AWT GraphicsConfiguration and
9487: // during context creation to select exactly the same graphics
9488: // configuration as was done during getBestConfiguration.
9489: class IndexCapabilitiesChooser implements GLCapabilitiesChooser {
9490: private int indexToChoose;
9491:
9492: IndexCapabilitiesChooser(int indexToChoose) {
9493: this .indexToChoose = indexToChoose;
9494: }
9495:
9496: public int chooseCapabilities(GLCapabilities desired,
9497: GLCapabilities[] available,
9498: int windowSystemRecommendedChoice) {
9499: if (DEBUG_CONFIG) {
9500: System.err
9501: .println("IndexCapabilitiesChooser returning index="
9502: + indexToChoose);
9503: }
9504: return indexToChoose;
9505: }
9506: }
9507:
9508: private void disposeOnEDT(final Frame f) {
9509: Runnable r = new Runnable() {
9510: public void run() {
9511: f.setVisible(false);
9512: f.dispose();
9513: }
9514: };
9515: if (!EventQueue.isDispatchThread()) {
9516: EventQueue.invokeLater(r);
9517: } else {
9518: r.run();
9519: }
9520: }
9521:
9522: // ---------------------------------------------------------------------
9523:
9524: //
9525: // DrawingSurfaceObject methods
9526: //
9527:
9528: // Method to construct a new DrawingSurfaceObject
9529: DrawingSurfaceObject createDrawingSurfaceObject(Canvas3D cv) {
9530: if (VERBOSE)
9531: System.err
9532: .println("JoglPipeline.createDrawingSurfaceObject()");
9533: return new JoglDrawingSurfaceObject(cv);
9534: }
9535:
9536: // Method to free the drawing surface object
9537: void freeDrawingSurface(Canvas3D cv,
9538: DrawingSurfaceObject drawingSurfaceObject) {
9539: if (VERBOSE)
9540: System.err.println("JoglPipeline.freeDrawingSurface()");
9541: // This method is a no-op
9542: }
9543:
9544: // Method to free the native drawing surface object
9545: void freeDrawingSurfaceNative(Object o) {
9546: if (VERBOSE)
9547: System.err
9548: .println("JoglPipeline.freeDrawingSurfaceNative()");
9549: // This method is a no-op
9550: }
9551:
9552: //----------------------------------------------------------------------
9553: // Context-related routines
9554: //
9555:
9556: // Helper used everywhere
9557: GLContext context(Context ctx) {
9558: if (ctx == null)
9559: return null;
9560: return ((JoglContext) ctx).getGLContext();
9561: }
9562:
9563: // Helper used everywhere
9564: GLDrawable drawable(Drawable drawable) {
9565: if (drawable == null)
9566: return null;
9567: return ((JoglDrawable) drawable).getGLDrawable();
9568: }
9569:
9570: GLCapabilities caps(Canvas3D ctx) {
9571: return ((JoglGraphicsConfiguration) ctx.graphicsConfiguration)
9572: .getGLCapabilities();
9573: }
9574:
9575: //----------------------------------------------------------------------
9576: // General helper routines
9577: //
9578:
9579: private static ThreadLocal nioVertexTemp = new ThreadLocal();
9580: private static ThreadLocal nioVertexDoubleTemp = new ThreadLocal();
9581: private static ThreadLocal nioColorTemp = new ThreadLocal();
9582: private static ThreadLocal nioColorByteTemp = new ThreadLocal();
9583: private static ThreadLocal nioNormalTemp = new ThreadLocal();
9584: private static ThreadLocal nioTexCoordSetTemp = new ThreadLocal();
9585: private static ThreadLocal nioVertexAttrSetTemp = new ThreadLocal();
9586:
9587: private static FloatBuffer getVertexArrayBuffer(float[] vertexArray) {
9588: return getVertexArrayBuffer(vertexArray, true);
9589: }
9590:
9591: private static FloatBuffer getVertexArrayBuffer(
9592: float[] vertexArray, boolean copyData) {
9593: return getNIOBuffer(vertexArray, nioVertexTemp, copyData);
9594: }
9595:
9596: private static DoubleBuffer getVertexArrayBuffer(
9597: double[] vertexArray) {
9598: return getVertexArrayBuffer(vertexArray, true);
9599: }
9600:
9601: private static DoubleBuffer getVertexArrayBuffer(
9602: double[] vertexArray, boolean copyData) {
9603: return getNIOBuffer(vertexArray, nioVertexDoubleTemp, true);
9604: }
9605:
9606: private static FloatBuffer getColorArrayBuffer(float[] colorArray) {
9607: return getColorArrayBuffer(colorArray, true);
9608: }
9609:
9610: private static FloatBuffer getColorArrayBuffer(float[] colorArray,
9611: boolean copyData) {
9612: return getNIOBuffer(colorArray, nioColorTemp, true);
9613: }
9614:
9615: private static ByteBuffer getColorArrayBuffer(byte[] colorArray) {
9616: return getColorArrayBuffer(colorArray, true);
9617: }
9618:
9619: private static ByteBuffer getColorArrayBuffer(byte[] colorArray,
9620: boolean copyData) {
9621: return getNIOBuffer(colorArray, nioColorByteTemp, true);
9622: }
9623:
9624: private static FloatBuffer getNormalArrayBuffer(float[] normalArray) {
9625: return getNormalArrayBuffer(normalArray, true);
9626: }
9627:
9628: private static FloatBuffer getNormalArrayBuffer(
9629: float[] normalArray, boolean copyData) {
9630: return getNIOBuffer(normalArray, nioNormalTemp, true);
9631: }
9632:
9633: private static FloatBuffer[] getTexCoordSetBuffer(
9634: Object[] texCoordSet) {
9635: return getNIOBuffer(texCoordSet, nioTexCoordSetTemp);
9636: }
9637:
9638: private static FloatBuffer[] getVertexAttrSetBuffer(
9639: Object[] vertexAttrSet) {
9640: return getNIOBuffer(vertexAttrSet, nioVertexAttrSetTemp);
9641: }
9642:
9643: private static FloatBuffer getNIOBuffer(float[] array,
9644: ThreadLocal threadLocal, boolean copyData) {
9645: if (array == null) {
9646: return null;
9647: }
9648: FloatBuffer buf = (FloatBuffer) threadLocal.get();
9649: if (buf == null) {
9650: buf = BufferUtil.newFloatBuffer(array.length);
9651: threadLocal.set(buf);
9652: } else {
9653: buf.rewind();
9654: if (buf.remaining() < array.length) {
9655: int newSize = Math.max(2 * buf.remaining(),
9656: array.length);
9657: buf = BufferUtil.newFloatBuffer(newSize);
9658: threadLocal.set(buf);
9659: }
9660: }
9661: if (copyData) {
9662: buf.put(array);
9663: buf.rewind();
9664: }
9665: return buf;
9666: }
9667:
9668: private static DoubleBuffer getNIOBuffer(double[] array,
9669: ThreadLocal threadLocal, boolean copyData) {
9670: if (array == null) {
9671: return null;
9672: }
9673: DoubleBuffer buf = (DoubleBuffer) threadLocal.get();
9674: if (buf == null) {
9675: buf = BufferUtil.newDoubleBuffer(array.length);
9676: threadLocal.set(buf);
9677: } else {
9678: buf.rewind();
9679: if (buf.remaining() < array.length) {
9680: int newSize = Math.max(2 * buf.remaining(),
9681: array.length);
9682: buf = BufferUtil.newDoubleBuffer(newSize);
9683: threadLocal.set(buf);
9684: }
9685: }
9686: if (copyData) {
9687: buf.put(array);
9688: buf.rewind();
9689: }
9690: return buf;
9691: }
9692:
9693: private static ByteBuffer getNIOBuffer(byte[] array,
9694: ThreadLocal threadLocal, boolean copyData) {
9695: if (array == null) {
9696: return null;
9697: }
9698: ByteBuffer buf = (ByteBuffer) threadLocal.get();
9699: if (buf == null) {
9700: buf = BufferUtil.newByteBuffer(array.length);
9701: threadLocal.set(buf);
9702: } else {
9703: buf.rewind();
9704: if (buf.remaining() < array.length) {
9705: int newSize = Math.max(2 * buf.remaining(),
9706: array.length);
9707: buf = BufferUtil.newByteBuffer(newSize);
9708: threadLocal.set(buf);
9709: }
9710: }
9711: if (copyData) {
9712: buf.put(array);
9713: buf.rewind();
9714: }
9715: return buf;
9716: }
9717:
9718: private static FloatBuffer[] getNIOBuffer(Object[] array,
9719: ThreadLocal threadLocal) {
9720: if (array == null) {
9721: return null;
9722: }
9723: FloatBuffer[] bufs = (FloatBuffer[]) threadLocal.get();
9724:
9725: // First resize array of FloatBuffers
9726: if (bufs == null) {
9727: bufs = new FloatBuffer[array.length];
9728: threadLocal.set(bufs);
9729: } else if (bufs.length < array.length) {
9730: FloatBuffer[] newBufs = new FloatBuffer[array.length];
9731: System.arraycopy(bufs, 0, newBufs, 0, bufs.length);
9732: bufs = newBufs;
9733: threadLocal.set(bufs);
9734: }
9735:
9736: // Now go down array of arrays, converting each into a direct FloatBuffer
9737: for (int i = 0; i < array.length; i++) {
9738: float[] cur = (float[]) array[i];
9739: FloatBuffer buf = bufs[i];
9740: if (buf == null) {
9741: buf = BufferUtil.newFloatBuffer(cur.length);
9742: bufs[i] = buf;
9743: } else {
9744: buf.rewind();
9745: if (buf.remaining() < cur.length) {
9746: int newSize = Math.max(2 * buf.remaining(),
9747: cur.length);
9748: buf = BufferUtil.newFloatBuffer(newSize);
9749: bufs[i] = buf;
9750: }
9751: }
9752: buf.put(cur);
9753: buf.rewind();
9754: }
9755:
9756: return bufs;
9757: }
9758: }
|