Source Code Cross Referenced for JoglPipeline.java in  » 6.0-JDK-Modules » java-3d » javax » media » j3d » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » java 3d » javax.media.j3d 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.