summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp
diff options
context:
space:
mode:
authorJOGAMP DEV TEAM <[email protected]>2010-04-22 21:12:36 -0400
committerJOGAMP DEV TEAM <[email protected]>2010-04-22 21:12:36 -0400
commit1d889ddc4728d1534e310b44fad74a2932d22d39 (patch)
tree4ad0c3eeb3ef728522ac9459eb12c667301a0c32 /src/jogl/classes/com/jogamp
parent8790075f074013aa3c71b96993838cf1117275f1 (diff)
parenta588326d206ff32e5ff5db97560851cb9b826022 (diff)
Merge branch 'master' of github.com:sgothel/jogl
Diffstat (limited to 'src/jogl/classes/com/jogamp')
-rwxr-xr-xsrc/jogl/classes/com/jogamp/audio/windows/waveout/Audio.java66
-rwxr-xr-xsrc/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java362
-rwxr-xr-xsrc/jogl/classes/com/jogamp/audio/windows/waveout/SoundBuffer.java124
-rwxr-xr-xsrc/jogl/classes/com/jogamp/audio/windows/waveout/TestSpatialization.java89
-rwxr-xr-xsrc/jogl/classes/com/jogamp/audio/windows/waveout/Track.java206
-rwxr-xr-xsrc/jogl/classes/com/jogamp/audio/windows/waveout/Vec3f.java212
-rw-r--r--src/jogl/classes/com/jogamp/opengl/cg/CgException.java67
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/DRIHack.java137
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/Debug.java140
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java211
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java188
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java169
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java1057
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java126
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLContextShareSet.java293
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java397
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java180
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java177
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java109
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java320
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java238
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java275
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp189
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase199
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java1057
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javame_cdc_fp10
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javase18
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/ThreadingImpl.java235
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/ThreadingPlugin.java62
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/awt/AWTThreadingPlugin.java129
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java125
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java569
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/awt/Java2DGLContext.java52
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java302
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java224
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java117
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLookupHelper.java270
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLookupHelper.java68
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLookupHelper.java68
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java99
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java303
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java298
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java90
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java80
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferContext.java62
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferDrawable.java99
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java1041
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/gl2/Util.java244
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/gl2/fixme/GLObjectTracker.java835
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/GLUquadricImpl.java1212
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/Glue.java114
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/error/Error.java100
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2Backend.java49
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2CurveEvaluator.java205
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2SurfaceEvaluator.java217
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GLUgl2nurbsImpl.java862
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/BuildMipmap.java1598
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract.java56
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract1010102.java97
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract1555rev.java97
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract2101010rev.java97
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract233rev.java85
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract332.java84
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract4444.java96
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract4444rev.java97
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract5551.java97
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract565.java92
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract565rev.java92
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract8888.java97
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract8888rev.java97
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractFloat.java74
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractPrimitive.java56
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSByte.java69
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSInt.java76
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSShort.java76
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUByte.java70
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUInt.java76
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUShort.java76
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/HalveImage.java1533
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Image.java1413
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Mipmap.java868
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/PixelStorageModes.java426
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ScaleInternal.java2447
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Type_Widget.java224
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Arc.java258
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcSdirSorter.java63
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcTdirSorter.java60
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcTesselator.java90
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Backend.java217
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/BezierArc.java44
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Bin.java155
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Breakpt.java59
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfArcs.java194
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfBreakpts.java130
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfFloats.java195
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfQuiltspecs.java160
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Curve.java238
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CurveEvaluator.java86
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Curvelist.java121
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/DisplayList.java56
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Flist.java130
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Knotspec.java557
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Knotvector.java179
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Mapdesc.java442
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Maplist.java122
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/NurbsConsts.java184
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_curve.java63
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_nurbscurve.java80
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_nurbssurface.java79
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_pwlcurve.java44
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_surface.java52
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_trim.java44
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Patch.java54
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Patchlist.java145
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Property.java75
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Pspec.java47
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/PwlArc.java71
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Quilt.java282
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Quiltspec.java85
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/README.txt59
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Renderhints.java128
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Splinespec.java204
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Subdivider.java1167
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/SurfaceEvaluator.java111
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/TrimVertex.java56
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/registry/Registry.java79
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/ActiveRegion.java69
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/CachedVertex.java58
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Dict.java140
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/DictNode.java59
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUface.java65
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUhalfEdge.java71
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUmesh.java60
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUtessellatorImpl.java646
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUvertex.java65
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Geom.java338
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Mesh.java734
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Normal.java288
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQ.java100
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQHeap.java262
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQSort.java278
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Render.java557
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Sweep.java1353
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/TessMono.java241
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/TessState.java59
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java340
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java106
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java164
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java231
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java84
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java215
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java64
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java56
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java130
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java100
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java359
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java251
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java65
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java111
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java156
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java102
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java146
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java90
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java64
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java139
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java88
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java63
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java155
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java330
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java445
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java129
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java311
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java641
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java305
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java114
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java106
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java94
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java154
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java132
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java582
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java97
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java398
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java439
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java397
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java77
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java157
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java68
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java64
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java73
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java157
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java150
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java163
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/Animator.java241
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorImpl.java66
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/FBObject.java263
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java123
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/FileUtil.java89
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/FixedPoint.java61
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java354
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java110
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java209
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java215
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayHandler.java11
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/GLBuffers.java137
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLFixedArrayHandler.java65
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/Gamma.java107
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java974
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/Locator.java137
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java686
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/StreamUtil.java98
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/TGAWriter.java116
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/awt/ImageUtil.java127
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/awt/Overlay.java214
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java432
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java1952
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java699
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/BitmapCharRec.java69
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/BitmapFontRec.java63
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/CoordRec.java56
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUT.java1342
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmap8x13.java2078
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmap9x15.java2079
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica10.java1798
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica12.java1808
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica18.java1917
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapTimesRoman10.java1797
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapTimesRoman24.java2080
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTStrokeMonoRoman.java2491
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTStrokeRoman.java2491
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeCharRec.java63
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeFontRec.java66
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeRec.java57
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/gl2/TileRenderer.java601
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/GLSLArrayHandler.java60
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java348
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java215
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java649
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java476
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java90
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/FixedFuncHook.java331
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/FixedFuncPipeline.java554
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColor.fp16
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColor.vp22
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColorLight.vp70
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColorTexture.fp47
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColor.bfpbin0 -> 1108 bytes
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColor.bvpbin0 -> 2344 bytes
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColorLight.bvpbin0 -> 8787 bytes
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColorTexture.bfpbin0 -> 2392 bytes
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/es_precision.glsl14
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_attribute.glsl19
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_const.glsl10
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_lightdef.glsl26
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_settexcoord.vp35
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_uniform.glsl18
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_uniform_light.glsl15
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_varying.glsl12
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/scripts/nvidia-apx/glslc-ff.bat9
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/scripts/nvidia-apx/glslc.bat9
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java185
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShaderNVidia.java53
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/packrect/BackingStoreManager.java99
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/packrect/Level.java275
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/packrect/LevelSet.java213
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/packrect/Rect.java170
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/packrect/RectVisitor.java47
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/packrect/RectanglePacker.java306
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/packrect/package.html9
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/Texture.java1120
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/TextureCoords.java79
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java370
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javame_cdc_fp1256
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javase1258
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java498
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureIO.java129
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java.javame_cdc_fp889
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java.javase919
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java223
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataOutputStream.java165
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java169
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java670
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java.javame_cdc_fp417
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java.javase420
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java172
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureWriter.java57
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java101
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureWriter.java119
-rw-r--r--src/jogl/classes/com/jogamp/openmax/OMXEventListener.java14
-rw-r--r--src/jogl/classes/com/jogamp/openmax/OMXInstance.java509
289 files changed, 88281 insertions, 0 deletions
diff --git a/src/jogl/classes/com/jogamp/audio/windows/waveout/Audio.java b/src/jogl/classes/com/jogamp/audio/windows/waveout/Audio.java
new file mode 100755
index 000000000..2b51be164
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/audio/windows/waveout/Audio.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.audio.windows.waveout;
+
+import java.io.*;
+
+public class Audio {
+ private static Audio instance = null;
+ private Mixer mixer;
+
+ public synchronized static Audio getInstance() {
+ if (instance == null) {
+ instance = new Audio();
+ }
+ return instance;
+ }
+
+ private Audio() {
+ mixer = Mixer.getMixer();
+ }
+
+ public Mixer getMixer() {
+ return mixer;
+ }
+
+ public Track newTrack(File file) throws IOException
+ {
+ Track res = new Track(file);
+ mixer.add(res);
+ return res;
+ }
+
+ public void shutdown() {
+ mixer.shutdown();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java b/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java
new file mode 100755
index 000000000..60972873e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/audio/windows/waveout/Mixer.java
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.audio.windows.waveout;
+
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+
+// Needed only for NIO workarounds on CVM
+import java.lang.reflect.*;
+
+public class Mixer {
+ // This class is a singleton
+ private static Mixer mixer;
+
+ private volatile boolean shutdown;
+ private volatile Object shutdownLock = new Object();
+ private volatile boolean shutdownDone;
+
+ // Windows Event object
+ private long event;
+
+ private volatile ArrayList/*<Track>*/ tracks = new ArrayList();
+
+ private Vec3f leftSpeakerPosition = new Vec3f(-1, 0, 0);
+ private Vec3f rightSpeakerPosition = new Vec3f( 1, 0, 0);
+
+ private float falloffFactor = 1.0f;
+
+ static {
+ mixer = new Mixer();
+ }
+
+ private Mixer() {
+ event = CreateEvent();
+ new FillerThread().start();
+ MixerThread m = new MixerThread();
+ m.setPriority(Thread.MAX_PRIORITY - 1);
+ m.start();
+ }
+
+ public static Mixer getMixer() {
+ return mixer;
+ }
+
+ synchronized void add(Track track) {
+ ArrayList/*<Track>*/ newTracks = (ArrayList) tracks.clone();
+ newTracks.add(track);
+ tracks = newTracks;
+ }
+
+ synchronized void remove(Track track) {
+ ArrayList/*<Track>*/ newTracks = (ArrayList) tracks.clone();
+ newTracks.remove(track);
+ tracks = newTracks;
+ }
+
+ // NOTE: due to a bug on the APX device, we only have mono sounds,
+ // so we currently only pay attention to the position of the left
+ // speaker
+ public void setLeftSpeakerPosition(float x, float y, float z) {
+ leftSpeakerPosition.set(x, y, z);
+ }
+
+ // NOTE: due to a bug on the APX device, we only have mono sounds,
+ // so we currently only pay attention to the position of the left
+ // speaker
+ public void setRightSpeakerPosition(float x, float y, float z) {
+ rightSpeakerPosition.set(x, y, z);
+ }
+
+ /** This defines a scale factor of sorts -- the higher the number,
+ the larger an area the sound will affect. Default value is
+ 1.0f. Valid values are [1.0f, ...]. The formula for the gain
+ for each channel is
+<PRE>
+ falloffFactor
+ -------------------
+ falloffFactor + r^2
+</PRE>
+*/
+ public void setFalloffFactor(float factor) {
+ falloffFactor = factor;
+ }
+
+ public void shutdown() {
+ synchronized(shutdownLock) {
+ shutdown = true;
+ SetEvent(event);
+ try {
+ shutdownLock.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ class FillerThread extends Thread {
+ FillerThread() {
+ super("Mixer Thread");
+ }
+
+ public void run() {
+ while (!shutdown) {
+ List/*<Track>*/ curTracks = tracks;
+
+ for (Iterator iter = curTracks.iterator(); iter.hasNext(); ) {
+ Track track = (Track) iter.next();
+ try {
+ track.fill();
+ } catch (IOException e) {
+ e.printStackTrace();
+ remove(track);
+ }
+ }
+
+ try {
+ // Run ten times per second
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ class MixerThread extends Thread {
+ // Temporary mixing buffer
+ // Interleaved left and right channels
+ float[] mixingBuffer;
+ private Vec3f temp = new Vec3f();
+
+ MixerThread() {
+ super("Mixer Thread");
+ if (!initializeWaveOut(event)) {
+ throw new InternalError("Error initializing waveout device");
+ }
+ }
+
+ public void run() {
+ while (!shutdown) {
+ // Get the next buffer
+ long mixerBuffer = getNextMixerBuffer();
+ if (mixerBuffer != 0) {
+ ByteBuffer buf = getMixerBufferData(mixerBuffer);
+
+ if (buf == null) {
+ // This is happening on CVM because
+ // JNI_NewDirectByteBuffer isn't implemented
+ // by default and isn't compatible with the
+ // JSR-239 NIO implementation (apparently)
+ buf = newDirectByteBuffer(getMixerBufferDataAddress(mixerBuffer),
+ getMixerBufferDataCapacity(mixerBuffer));
+ }
+
+ if (buf == null) {
+ throw new InternalError("Couldn't wrap the native address with a direct byte buffer");
+ }
+
+ // System.out.println("Mixing buffer");
+
+ // If we don't have enough samples in our mixing buffer, expand it
+ // FIXME: knowledge of native output rendering format
+ if ((mixingBuffer == null) || (mixingBuffer.length < (buf.capacity() / 2 /* bytes / sample */))) {
+ mixingBuffer = new float[buf.capacity() / 2];
+ } else {
+ // Zap it
+ for (int i = 0; i < mixingBuffer.length; i++) {
+ mixingBuffer[i] = 0.0f;
+ }
+ }
+
+ // This assertion should be in place if we have stereo
+ if ((mixingBuffer.length % 2) != 0) {
+ String msg = "FATAL ERROR: odd number of samples in the mixing buffer";
+ System.out.println(msg);
+ throw new InternalError(msg);
+ }
+
+ // Run down all of the registered tracks mixing them in
+ List/*<Track>*/ curTracks = tracks;
+
+ for (Iterator iter = curTracks.iterator(); iter.hasNext(); ) {
+ Track track = (Track) iter.next();
+ // Consider only playing tracks
+ if (track.isPlaying()) {
+ // First recompute its gain
+ Vec3f pos = track.getPosition();
+ float leftGain = gain(pos, leftSpeakerPosition);
+ float rightGain = gain(pos, rightSpeakerPosition);
+ // Now mix it in
+ int i = 0;
+ while (i < mixingBuffer.length) {
+ if (track.hasNextSample()) {
+ float sample = track.nextSample();
+ mixingBuffer[i++] = sample * leftGain;
+ mixingBuffer[i++] = sample * rightGain;
+ } else {
+ // This allows tracks to stall without being abruptly cancelled
+ if (track.done()) {
+ remove(track);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ // Now that we have our data, send it down to the card
+ int outPos = 0;
+ for (int i = 0; i < mixingBuffer.length; i++) {
+ short val = (short) mixingBuffer[i];
+ buf.put(outPos++, (byte) val);
+ buf.put(outPos++, (byte) (val >> 8));
+ }
+ if (!prepareMixerBuffer(mixerBuffer)) {
+ throw new RuntimeException("Error preparing mixer buffer");
+ }
+ if (!writeMixerBuffer(mixerBuffer)) {
+ throw new RuntimeException("Error writing mixer buffer to device");
+ }
+ } else {
+ // System.out.println("No mixer buffer available");
+
+ // Wait for a buffer to become available
+ if (!WaitForSingleObject(event)) {
+ throw new RuntimeException("Error while waiting for event object");
+ }
+
+ /*
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ */
+ }
+ }
+
+ // Need to shut down
+ shutdownWaveOut();
+ synchronized(shutdownLock) {
+ shutdownLock.notifyAll();
+ }
+ }
+
+ // This defines the 3D spatialization gain function.
+ // The function is defined as:
+ // falloffFactor
+ // -------------------
+ // falloffFactor + r^2
+ private float gain(Vec3f pos, Vec3f speakerPos) {
+ temp.sub(pos, speakerPos);
+ float dotp = temp.dot(temp);
+ return (falloffFactor / (falloffFactor + dotp));
+ }
+ }
+
+ // Initializes waveout device
+ private static native boolean initializeWaveOut(long eventObject);
+ // Shuts down waveout device
+ private static native void shutdownWaveOut();
+
+ // Gets the next (opaque) buffer of data to fill from the native
+ // code, or 0 if none was available yet (it should not happen that
+ // none is available the way the code is written).
+ private static native long getNextMixerBuffer();
+ // Gets the next ByteBuffer to fill out of the mixer buffer. It
+ // requires interleaved left and right channel samples, 16 signed
+ // bits per sample, little endian. Implicit 44.1 kHz sample rate.
+ private static native ByteBuffer getMixerBufferData(long mixerBuffer);
+ // We need these to work around the lack of
+ // JNI_NewDirectByteBuffer in CVM + the JSR 239 NIO classes
+ private static native long getMixerBufferDataAddress(long mixerBuffer);
+ private static native int getMixerBufferDataCapacity(long mixerBuffer);
+ // Prepares this mixer buffer for writing to the device.
+ private static native boolean prepareMixerBuffer(long mixerBuffer);
+ // Writes this mixer buffer to the device.
+ private static native boolean writeMixerBuffer(long mixerBuffer);
+
+ // Helpers to prevent mixer thread from busy waiting
+ private static native long CreateEvent();
+ private static native boolean WaitForSingleObject(long event);
+ private static native void SetEvent(long event);
+ private static native void CloseHandle(long handle);
+
+ // We need a reflective hack to wrap a direct ByteBuffer around
+ // the native memory because JNI_NewDirectByteBuffer doesn't work
+ // in CVM + JSR-239 NIO
+ private static Class directByteBufferClass;
+ private static Constructor directByteBufferConstructor;
+ private static Map createdBuffers = new HashMap(); // Map Long, ByteBuffer
+
+ private static ByteBuffer newDirectByteBuffer(long address, long capacity) {
+ Long key = new Long(address);
+ ByteBuffer buf = (ByteBuffer) createdBuffers.get(key);
+ if (buf == null) {
+ buf = newDirectByteBufferImpl(address, capacity);
+ if (buf != null) {
+ createdBuffers.put(key, buf);
+ }
+ }
+ return buf;
+ }
+ private static ByteBuffer newDirectByteBufferImpl(long address, long capacity) {
+ if (directByteBufferClass == null) {
+ try {
+ directByteBufferClass = Class.forName("java.nio.DirectByteBuffer");
+ byte[] tmp = new byte[0];
+ directByteBufferConstructor =
+ directByteBufferClass.getDeclaredConstructor(new Class[] { Integer.TYPE,
+ tmp.getClass(),
+ Integer.TYPE });
+ directByteBufferConstructor.setAccessible(true);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (directByteBufferConstructor != null) {
+ try {
+ return (ByteBuffer)
+ directByteBufferConstructor.newInstance(new Object[] {
+ new Integer((int) capacity),
+ null,
+ new Integer((int) address)
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/audio/windows/waveout/SoundBuffer.java b/src/jogl/classes/com/jogamp/audio/windows/waveout/SoundBuffer.java
new file mode 100755
index 000000000..c45430d23
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/audio/windows/waveout/SoundBuffer.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.audio.windows.waveout;
+
+import java.io.*;
+
+class SoundBuffer {
+ private byte[] data;
+ private boolean needsByteSwap;
+ private int numBytes;
+ private int bytesPerSample;
+ private int numSamples;
+ private boolean playing;
+ private boolean empty;
+
+ // Note: needsByteSwap argument makes assumptions about the format
+ SoundBuffer(int size, int bytesPerSample, boolean needsByteSwap) {
+ this.bytesPerSample = bytesPerSample;
+ this.needsByteSwap = needsByteSwap;
+ data = new byte[size * bytesPerSample];
+ empty = true;
+ }
+
+ boolean playing() {
+ return playing;
+ }
+
+ void playing(boolean playing) {
+ this.playing = playing;
+ }
+
+ boolean empty() {
+ return empty;
+ }
+
+ void empty(boolean empty) {
+ this.empty = empty;
+ }
+
+ void fill(InputStream input) throws IOException {
+ synchronized(this) {
+ if (playing) {
+ throw new IllegalStateException("Can not fill a buffer that is playing");
+ }
+ }
+
+ empty(true);
+ int num = input.read(data);
+ if (num > 0) {
+ numBytes = num;
+ numSamples = numBytes / bytesPerSample;
+ empty(false);
+ if ((numBytes % bytesPerSample) != 0) {
+ System.out.println("WARNING: needed integral multiple of " + bytesPerSample +
+ " bytes, but read " + numBytes + " bytes");
+ }
+ } else {
+ numBytes = 0;
+ }
+ }
+
+ int numSamples() {
+ return numSamples;
+ }
+
+ // This is called by the mixer and must be extremely fast
+ // FIXME: may want to reconsider use of floating point at this point
+ // FIXME: assumes all sounds are of the same format to avoid normalization
+ float getSample(int sample) {
+ int startByte = sample * bytesPerSample;
+ // FIXME: assumes no more than 4 bytes per sample
+ int res = 0;
+ if (needsByteSwap) {
+ for (int i = startByte + bytesPerSample - 1; i >= startByte; i--) {
+ res <<= 8;
+ res |= (data[i] & 0xff);
+ }
+ } else {
+ int endByte = startByte + bytesPerSample - 1;
+ for (int i = startByte; i <= endByte; i++) {
+ res <<= 8;
+ res |= (data[i] & 0xff);
+ }
+ }
+ // Sign extend
+ if (bytesPerSample == 2) {
+ res = (short) res;
+ } else if (bytesPerSample == 1) {
+ res = (byte) res;
+ }
+
+ return (float) res;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/audio/windows/waveout/TestSpatialization.java b/src/jogl/classes/com/jogamp/audio/windows/waveout/TestSpatialization.java
new file mode 100755
index 000000000..78fb3493f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/audio/windows/waveout/TestSpatialization.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.audio.windows.waveout;
+
+import java.io.*;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.opengl.GLDrawableFactory;
+
+public class TestSpatialization {
+ public static void main(String[] args) {
+ if (args.length != 1) {
+ System.out.println("Usage: TestSpatialization [file name]");
+ System.exit(1);
+ }
+
+ try {
+ // FIXME: this is a hack to get the native library loaded
+ try {
+ GLDrawableFactory.getFactory(NativeWindow.class);
+ } catch (Exception e) {}
+ // Initialize the audio subsystem
+ Audio audio = Audio.getInstance();
+ // Create a track
+ Track track = audio.newTrack(new File(args[0]));
+ track.setPosition(1, 0, 0);
+ // Run for ten seconds
+ long startTime = System.currentTimeMillis();
+ long duration = 10000;
+ long curTime = 0;
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+ System.out.println("Playing...");
+ track.setLooping(true);
+ track.play();
+ while ((curTime = System.currentTimeMillis()) < startTime + duration) {
+ // Make one revolution every two seconds
+ float rads = (float) (((2 * Math.PI) * (((float) (curTime - startTime)) / 1000.0f)) / 2);
+ track.setPosition((float) Math.cos(rads), 0, (float) Math.sin(rads));
+ // Would like to make it go in a circle, but since
+ // stereo doesn't work now, make it move along a line
+ // track.setPosition(-1.0f, 0, 2.0f * (float) Math.sin(rads));
+ // Sleep a little between updates
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ }
+ System.out.println("Shutting down audio subsystem");
+ audio.shutdown();
+ System.out.println("Exiting.");
+ System.exit(0);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/audio/windows/waveout/Track.java b/src/jogl/classes/com/jogamp/audio/windows/waveout/Track.java
new file mode 100755
index 000000000..b57bf1dc6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/audio/windows/waveout/Track.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.audio.windows.waveout;
+
+import java.io.*;
+import java.nio.*;
+
+public class Track {
+ // Default number of samples per buffer
+ private static final int BUFFER_SIZE = 32768;
+ // Number of bytes per sample (FIXME: dependence on audio format)
+ static final int BYTES_PER_SAMPLE = 2;
+ // Whether we need byte swapping (FIXME: dependence on audio format)
+ static final boolean NEEDS_BYTE_SWAP = true;
+
+ // This is the buffer this track is currently playing from
+ private SoundBuffer activeBuffer;
+ // This is the sample position in the active buffer
+ private int samplePosition;
+ // This is the total number of samples in the file
+ private int totalSamples;
+ // This is the total number of samples we have read
+ private int samplesRead;
+ // This is the buffer that the background filler thread may be filling
+ private SoundBuffer fillingBuffer;
+ // If we're playing the file, this is its input stream
+ private InputStream input;
+ // Keep around the file name
+ private File file;
+ // Whether we're playing this sound
+ private boolean playing;
+ // Whether we're looping this sound
+ private boolean looping;
+ // The position of this sound; defaults to being at the origin
+ private volatile Vec3f position = new Vec3f();
+
+ Track(File file) throws IOException {
+ if (!file.getName().endsWith(".rawsound")) {
+ throw new IOException("Unsupported file format (currently supports only raw sounds)");
+ }
+
+ this.file = file;
+ openInput();
+
+ // Allocate the buffers
+ activeBuffer = new SoundBuffer(BUFFER_SIZE, BYTES_PER_SAMPLE, NEEDS_BYTE_SWAP);
+ fillingBuffer = new SoundBuffer(BUFFER_SIZE, BYTES_PER_SAMPLE, NEEDS_BYTE_SWAP);
+
+ // Fill the first buffer immediately
+ fill();
+ swapBuffers();
+ }
+
+ private void openInput() throws IOException {
+ input = new BufferedInputStream(new FileInputStream(file));
+ totalSamples = (int) file.length() / BYTES_PER_SAMPLE;
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public synchronized void play() {
+ if (input == null) {
+ try {
+ openInput();
+ // Fill it immediately
+ fill();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return;
+ }
+ }
+
+ playing = true;
+ }
+
+ public synchronized boolean isPlaying() {
+ return playing;
+ }
+
+ public synchronized void setLooping(boolean looping) {
+ this.looping = looping;
+ }
+
+ public synchronized boolean isLooping() {
+ return looping;
+ }
+
+ public void setPosition(float x, float y, float z) {
+ position = new Vec3f(x, y, z);
+ }
+
+ synchronized void fill() throws IOException {
+ if (input == null) {
+ return;
+ }
+ SoundBuffer curBuffer = fillingBuffer;
+ if (!curBuffer.empty()) {
+ return;
+ }
+ curBuffer.fill(input);
+ if (curBuffer.empty()) {
+ // End of file
+ InputStream tmp = null;
+ synchronized(this) {
+ tmp = input;
+ input = null;
+ }
+ tmp.close();
+
+ // If looping, re-open
+ if (isLooping()) {
+ openInput();
+ // and fill
+ fill();
+ }
+ }
+ }
+
+ // These are only for use by the Mixer
+ private float leftGain;
+ private float rightGain;
+
+ void setLeftGain(float leftGain) {
+ this.leftGain = leftGain;
+ }
+
+ float getLeftGain() {
+ return leftGain;
+ }
+
+ void setRightGain(float rightGain) {
+ this.rightGain = rightGain;
+ }
+
+ float getRightGain() {
+ return rightGain;
+ }
+
+ Vec3f getPosition() {
+ return position;
+ }
+
+ // This is called by the mixer and must be extremely fast
+ // Note this assumes mono sounds (FIXME)
+ boolean hasNextSample() {
+ return (!activeBuffer.empty() && samplePosition < activeBuffer.numSamples());
+ }
+
+ // This is called by the mixer and must be extremely fast
+ float nextSample() {
+ float res = activeBuffer.getSample(samplePosition++);
+ ++samplesRead;
+ if (!hasNextSample()) {
+ swapBuffers();
+ samplePosition = 0;
+ if (done()) {
+ playing = false;
+ }
+ }
+ return res;
+ }
+
+ synchronized void swapBuffers() {
+ SoundBuffer tmp = activeBuffer;
+ activeBuffer = fillingBuffer;
+ fillingBuffer = tmp;
+ fillingBuffer.empty(true);
+ }
+
+ // This provides a more robust termination condition
+ boolean done() {
+ return (samplesRead == totalSamples) && !looping;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/audio/windows/waveout/Vec3f.java b/src/jogl/classes/com/jogamp/audio/windows/waveout/Vec3f.java
new file mode 100755
index 000000000..1afdaf081
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/audio/windows/waveout/Vec3f.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.audio.windows.waveout;
+
+/** 3-element single-precision vector */
+
+class Vec3f {
+ public static final Vec3f X_AXIS = new Vec3f( 1, 0, 0);
+ public static final Vec3f Y_AXIS = new Vec3f( 0, 1, 0);
+ public static final Vec3f Z_AXIS = new Vec3f( 0, 0, 1);
+ public static final Vec3f NEG_X_AXIS = new Vec3f(-1, 0, 0);
+ public static final Vec3f NEG_Y_AXIS = new Vec3f( 0, -1, 0);
+ public static final Vec3f NEG_Z_AXIS = new Vec3f( 0, 0, -1);
+
+ private float x;
+ private float y;
+ private float z;
+
+ public Vec3f() {}
+
+ public Vec3f(Vec3f arg) {
+ set(arg);
+ }
+
+ public Vec3f(float x, float y, float z) {
+ set(x, y, z);
+ }
+
+ public Vec3f copy() {
+ return new Vec3f(this);
+ }
+
+ public void set(Vec3f arg) {
+ set(arg.x, arg.y, arg.z);
+ }
+
+ public void set(float x, float y, float z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ /** Sets the ith component, 0 <= i < 3 */
+ public void set(int i, float val) {
+ switch (i) {
+ case 0: x = val; break;
+ case 1: y = val; break;
+ case 2: z = val; break;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /** Gets the ith component, 0 <= i < 3 */
+ public float get(int i) {
+ switch (i) {
+ case 0: return x;
+ case 1: return y;
+ case 2: return z;
+ default: throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public float x() { return x; }
+ public float y() { return y; }
+ public float z() { return z; }
+
+ public void setX(float x) { this.x = x; }
+ public void setY(float y) { this.y = y; }
+ public void setZ(float z) { this.z = z; }
+
+ public float dot(Vec3f arg) {
+ return x * arg.x + y * arg.y + z * arg.z;
+ }
+
+ public float length() {
+ return (float) Math.sqrt(lengthSquared());
+ }
+
+ public float lengthSquared() {
+ return this.dot(this);
+ }
+
+ public void normalize() {
+ float len = length();
+ if (len == 0.0f) return;
+ scale(1.0f / len);
+ }
+
+ /** Returns this * val; creates new vector */
+ public Vec3f times(float val) {
+ Vec3f tmp = new Vec3f(this);
+ tmp.scale(val);
+ return tmp;
+ }
+
+ /** this = this * val */
+ public void scale(float val) {
+ x *= val;
+ y *= val;
+ z *= val;
+ }
+
+ /** Returns this + arg; creates new vector */
+ public Vec3f plus(Vec3f arg) {
+ Vec3f tmp = new Vec3f();
+ tmp.add(this, arg);
+ return tmp;
+ }
+
+ /** this = this + b */
+ public void add(Vec3f b) {
+ add(this, b);
+ }
+
+ /** this = a + b */
+ public void add(Vec3f a, Vec3f b) {
+ x = a.x + b.x;
+ y = a.y + b.y;
+ z = a.z + b.z;
+ }
+
+ /** Returns this + s * arg; creates new vector */
+ public Vec3f addScaled(float s, Vec3f arg) {
+ Vec3f tmp = new Vec3f();
+ tmp.addScaled(this, s, arg);
+ return tmp;
+ }
+
+ /** this = a + s * b */
+ public void addScaled(Vec3f a, float s, Vec3f b) {
+ x = a.x + s * b.x;
+ y = a.y + s * b.y;
+ z = a.z + s * b.z;
+ }
+
+ /** Returns this - arg; creates new vector */
+ public Vec3f minus(Vec3f arg) {
+ Vec3f tmp = new Vec3f();
+ tmp.sub(this, arg);
+ return tmp;
+ }
+
+ /** this = this - b */
+ public void sub(Vec3f b) {
+ sub(this, b);
+ }
+
+ /** this = a - b */
+ public void sub(Vec3f a, Vec3f b) {
+ x = a.x - b.x;
+ y = a.y - b.y;
+ z = a.z - b.z;
+ }
+
+ /** Returns this cross arg; creates new vector */
+ public Vec3f cross(Vec3f arg) {
+ Vec3f tmp = new Vec3f();
+ tmp.cross(this, arg);
+ return tmp;
+ }
+
+ /** this = a cross b. NOTE: "this" must be a different vector than
+ both a and b. */
+ public void cross(Vec3f a, Vec3f b) {
+ x = a.y * b.z - a.z * b.y;
+ y = a.z * b.x - a.x * b.z;
+ z = a.x * b.y - a.y * b.x;
+ }
+
+ /** Sets each component of this vector to the product of the
+ component with the corresponding component of the argument
+ vector. */
+ public void componentMul(Vec3f arg) {
+ x *= arg.x;
+ y *= arg.y;
+ z *= arg.z;
+ }
+
+ public String toString() {
+ return "(" + x + ", " + y + ", " + z + ")";
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/cg/CgException.java b/src/jogl/classes/com/jogamp/opengl/cg/CgException.java
new file mode 100644
index 000000000..8bfd9e23e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/cg/CgException.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.cg;
+
+/**
+ * A generic exception for errors that occur throughout the NVidia Cg
+ * binding, as a substitute for {@link RuntimeException}.
+ */
+public class CgException extends RuntimeException {
+ /** Constructs a CgException object. */
+ public CgException() {
+ super();
+ }
+
+ /** Constructs a CgException object with the specified detail message. */
+ public CgException(String message) {
+ super(message);
+ }
+
+ /** Constructs a CgException object with the specified detail message and
+ root cause. */
+ public CgException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /** Constructs a CgException object with the specified root cause. */
+ public CgException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/DRIHack.java b/src/jogl/classes/com/jogamp/opengl/impl/DRIHack.java
new file mode 100755
index 000000000..7e81d194b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/DRIHack.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import com.jogamp.common.os.NativeLibrary;
+import com.jogamp.common.os.Platform;
+import java.io.*;
+import java.security.*;
+
+/**
+ * Helper class for working around problems with open-source DRI
+ * drivers. In the current DRI implementation it is required that the
+ * symbols in libGL.so.1.2 be globally visible to be accessible from
+ * other libraries that are dynamically loaded by the implementation.
+ * Applications may typically satisfy this need either by linking
+ * against libGL.so on the command line (-lGL) or by dlopen'ing
+ * libGL.so.1.2 with the RTLD_GLOBAL flag. The JOGL implementation
+ * links against libGL on all platforms rather than forcing all OpenGL
+ * entry points to be called through a function pointer. This allows
+ * the JOGL library to link directly to core 1.1 OpenGL entry points
+ * like glVertex3f, while calling through function pointers for entry
+ * points from later OpenGL versions as well as from
+ * extensions. However, because libjogl.so (which links against
+ * libGL.so) is loaded by the JVM, and because the JVM implicitly uses
+ * RTLD_LOCAL in the implementation of System.loadLibrary(), this
+ * means via transitivity that the symbols for libGL.so have only
+ * RTLD_LOCAL visibility to the rest of the application, so the DRI
+ * drivers can not find the symbols required. <P>
+ *
+ * There are at least two possible solutions. One would be to change
+ * the JOGL implementation to call through function pointers uniformly
+ * so that it does not need to link against libGL.so. This is
+ * possible, but requires changes to GlueGen and also is not really
+ * necessary in any other situation than with the DRI drivers. Another
+ * solution is to force the first load of libGL.so.1.2 to be done
+ * dynamically with RTLD_GLOBAL before libjogl.so is loaded and causes
+ * libGL.so.1.2 to be loaded again. The NativeLibrary class in the
+ * GlueGen runtime has this property, and we use it to implement this
+ * workaround.
+ */
+
+public class DRIHack {
+
+ private static final boolean DEBUG = Debug.debug("DRIHack");
+ private static boolean driHackNeeded;
+ private static NativeLibrary oglLib;
+
+ static {
+ // Allow manual overriding for now as a workaround for
+ // problems seen in some situations -- needs more investigation
+ if (Debug.getProperty("jogl.drihack.disable", true) != null) {
+ driHackNeeded = false;
+ } else {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String os = Platform.getOS().toLowerCase();
+ // Do DRI hack on all Linux distributions for best robustness
+ driHackNeeded = os.startsWith("linux")
+ || new File("/usr/lib/dri").exists()
+ || new File("/usr/X11R6/lib/modules/dri").exists();
+ return null;
+ }
+ });
+ }
+ }
+
+ public static void begin() {
+
+ if (driHackNeeded) {
+ if (DEBUG) {
+ System.err.println("Beginning DRI hack");
+ }
+
+ // Try a few different variants for best robustness
+ // In theory probably only the first is necessary
+ oglLib = NativeLibrary.open("libGL.so.1", null);
+ if (DEBUG && oglLib != null) {
+ System.err.println(" Found libGL.so.1");
+ }
+ if (oglLib == null) {
+ oglLib = NativeLibrary.open("/usr/lib/libGL.so.1", null);
+ if (DEBUG && oglLib != null) {
+ System.err.println(" Found /usr/lib/libGL.so.1");
+ }
+ }
+ }
+
+ }
+
+ public static void end() {
+ if (oglLib != null) {
+ if (DEBUG) {
+ System.err.println("Ending DRI hack");
+ }
+
+ oglLib.close();
+ oglLib = null;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/Debug.java b/src/jogl/classes/com/jogamp/opengl/impl/Debug.java
new file mode 100644
index 000000000..82a5f2ff2
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/Debug.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.security.*;
+
+/** Helper routines for logging and debugging. */
+
+public class Debug {
+ // Some common properties
+ private static boolean verbose;
+ private static boolean debugAll;
+ private static AccessControlContext localACC;
+
+ static {
+ localACC=AccessController.getContext();
+ verbose = isPropertyDefined("jogl.verbose", true);
+ debugAll = isPropertyDefined("jogl.debug", true);
+ if (verbose) {
+ Package p = Package.getPackage("javax.media.opengl");
+ System.err.println("JOGL specification version " + p.getSpecificationVersion());
+ System.err.println("JOGL implementation version " + p.getImplementationVersion());
+ System.err.println("JOGL implementation vendor " + p.getImplementationVendor());
+ }
+ }
+
+ static int getIntProperty(final String property, final boolean jnlpAlias) {
+ return getIntProperty(property, jnlpAlias, localACC);
+ }
+
+ public static int getIntProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ int i=0;
+ try {
+ Integer iv = Integer.valueOf(Debug.getProperty(property, jnlpAlias, acc));
+ i = iv.intValue();
+ } catch (NumberFormatException nfe) {}
+ return i;
+ }
+
+ static boolean getBooleanProperty(final String property, final boolean jnlpAlias) {
+ return getBooleanProperty(property, jnlpAlias, localACC);
+ }
+
+ public static boolean getBooleanProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ Boolean b = Boolean.valueOf(Debug.getProperty(property, jnlpAlias, acc));
+ return b.booleanValue();
+ }
+
+ static boolean isPropertyDefined(final String property, final boolean jnlpAlias) {
+ return isPropertyDefined(property, jnlpAlias, localACC);
+ }
+
+ public static boolean isPropertyDefined(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ return (Debug.getProperty(property, jnlpAlias, acc) != null) ? true : false;
+ }
+
+ static String getProperty(final String property, final boolean jnlpAlias) {
+ return getProperty(property, jnlpAlias, localACC);
+ }
+
+ public static String getProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ String s=null;
+ if(null!=acc && acc.equals(localACC)) {
+ s = (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String val=null;
+ try {
+ val = System.getProperty(property);
+ } catch (Exception e) {}
+ if(null==val && jnlpAlias && !property.startsWith(jnlp_prefix)) {
+ try {
+ val = System.getProperty(jnlp_prefix + property);
+ } catch (Exception e) {}
+ }
+ return val;
+ }
+ });
+ } else {
+ try {
+ s = System.getProperty(property);
+ } catch (Exception e) {}
+ if(null==s && jnlpAlias && !property.startsWith(jnlp_prefix)) {
+ try {
+ s = System.getProperty(jnlp_prefix + property);
+ } catch (Exception e) {}
+ }
+ }
+ return s;
+ }
+ public static final String jnlp_prefix = "jnlp." ;
+
+ public static boolean verbose() {
+ return verbose;
+ }
+
+ public static boolean debugAll() {
+ return debugAll;
+ }
+
+ public static boolean debug(String subcomponent) {
+ return debugAll() || isPropertyDefined("jogl.debug." + subcomponent, true);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java b/src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java
new file mode 100644
index 000000000..9d1235e13
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import javax.media.opengl.*;
+import java.util.*;
+// FIXME: refactor Java SE dependencies
+//import java.util.regex.*;
+import java.lang.reflect.*;
+
+/**
+ * A utility object intended to be used by implementations to act as a cache
+ * of which OpenGL extensions are currently available on both the host machine
+ * and display.
+ */
+public final class ExtensionAvailabilityCache {
+ private static final boolean DEBUG = Debug.debug("ExtensionAvailabilityCache");
+ private static final boolean DEBUG_AVAILABILITY = Debug.isPropertyDefined("ExtensionAvailabilityCache", true);
+
+ ExtensionAvailabilityCache(GLContextImpl context)
+ {
+ this.context = context;
+ }
+
+ /**
+ * Flush the cache. The cache will be rebuilt lazily as calls to {@link
+ * #isExtensionAvailable(String)} are received.
+ */
+ public void flush()
+ {
+ if(DEBUG) {
+ System.out.println("ExtensionAvailabilityCache: Flush availability OpenGL "+context.getGLVersion());
+ }
+ availableExtensionCache.clear();
+ initialized = false;
+ }
+
+ /**
+ * Flush the cache and rebuild the cache.
+ */
+ public void reset() {
+ flush();
+ initAvailableExtensions();
+ }
+
+ public boolean isInitialized() {
+ return initialized && !availableExtensionCache.isEmpty() ;
+ }
+
+ public boolean isExtensionAvailable(String glExtensionName) {
+ initAvailableExtensions();
+ return availableExtensionCache.contains(mapGLExtensionName(glExtensionName));
+ }
+
+ public String getPlatformExtensionsString() {
+ initAvailableExtensions();
+ return glXExtensions;
+ }
+
+ public String getGLExtensions() {
+ initAvailableExtensions();
+ if(DEBUG) {
+ System.err.println("ExtensionAvailabilityCache: getGLExtensions() called");
+ }
+ return glExtensions;
+ }
+
+ private void initAvailableExtensions() {
+ GL gl = context.getGL();
+ // if hash is empty (meaning it was flushed), pre-cache it with the list
+ // of extensions that are in the GL_EXTENSIONS string
+ if (availableExtensionCache.isEmpty() || !initialized) {
+ if (DEBUG) {
+ System.err.println("ExtensionAvailabilityCache: Pre-caching init "+gl+", OpenGL "+context.getGLVersion());
+ }
+
+ boolean useGetStringi = false;
+
+ if ( gl.isGL2GL3() ) {
+ if ( ! gl.isFunctionAvailable("glGetStringi") ) {
+ if(DEBUG) {
+ System.err.println("GLContext: GL >= 3.1 usage, but no glGetStringi");
+ }
+ } else {
+ useGetStringi = true;
+ }
+ }
+
+ if (DEBUG) {
+ System.err.println("ExtensionAvailabilityCache: Pre-caching extension availability OpenGL "+context.getGLVersion()+
+ ", use "+ ( useGetStringi ? "glGetStringi" : "glGetString" ) );
+ }
+
+ StringBuffer sb = new StringBuffer();
+ if(useGetStringi) {
+ GL2GL3 gl2gl3 = gl.getGL2GL3();
+ int[] numExtensions = { 0 } ;
+ gl2gl3.glGetIntegerv(gl2gl3.GL_NUM_EXTENSIONS, numExtensions, 0);
+ for (int i = 0; i < numExtensions[0]; i++) {
+ sb.append(gl2gl3.glGetStringi(gl2gl3.GL_EXTENSIONS, i));
+ if(i < numExtensions[0]) {
+ sb.append(" ");
+ }
+ }
+ } else {
+ sb.append(gl.glGetString(GL.GL_EXTENSIONS));
+ }
+ glExtensions = sb.toString();
+ glXExtensions = context.getPlatformExtensionsString();
+
+ sb.append(" ");
+ sb.append(glXExtensions);
+
+ String allAvailableExtensions = sb.toString();
+ if (DEBUG_AVAILABILITY) {
+ System.err.println("ExtensionAvailabilityCache: Available extensions: " + allAvailableExtensions);
+ System.err.println("ExtensionAvailabilityCache: GL vendor: " + gl.glGetString(GL.GL_VENDOR));
+ }
+ StringTokenizer tok = new StringTokenizer(allAvailableExtensions);
+ while (tok.hasMoreTokens()) {
+ String availableExt = tok.nextToken().trim();
+ availableExt = availableExt.intern();
+ availableExtensionCache.add(availableExt);
+ if (DEBUG_AVAILABILITY) {
+ System.err.println("ExtensionAvailabilityCache: Available: " + availableExt);
+ }
+ }
+
+ int major[] = new int[] { context.getGLVersionMajor() };
+ int minor[] = new int[] { context.getGLVersionMinor() };
+ if( !gl.isGL3() && !gl.isGL4() &&
+ ( major[0] > 3 ||
+ ( major[0] == 3 && minor[0] >= 1 ) ) ) {
+ // downsize version to 3.0 in case we are not using GL3 (>=3.1)
+ major[0] = 3;
+ minor[0] = 0;
+ }
+ while (GLContext.isValidGLVersion(major[0], minor[0])) {
+ availableExtensionCache.add("GL_VERSION_" + major[0] + "_" + minor[0]);
+ if (DEBUG) {
+ System.err.println("ExtensionAvailabilityCache: Added GL_VERSION_" + major[0] + "_" + minor[0] + " to known extensions");
+ }
+ if(!GLContext.decrementGLVersion(major, minor)) break;
+ }
+
+ // put a dummy var in here so that the cache is no longer empty even if
+ // no extensions are in the GL_EXTENSIONS string
+ availableExtensionCache.add("<INTERNAL_DUMMY_PLACEHOLDER>");
+
+ initialized = true;
+ }
+ }
+
+ // FIXME: hack to re-enable GL_NV_vertex_array_range extension after
+ // recent upgrade to new wglext.h and glxext.h headers
+ private static String mapGLExtensionName(String extensionName) {
+ if (extensionName != null &&
+ (extensionName.equals("WGL_NV_vertex_array_range") ||
+ extensionName.equals("GLX_NV_vertex_array_range")))
+ return "GL_NV_vertex_array_range";
+ return extensionName;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private boolean initialized = false;
+ private String glExtensions = null;
+ private String glXExtensions = null;
+ private HashSet availableExtensionCache = new HashSet(50);
+ private GLContextImpl context;
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java
new file mode 100755
index 000000000..48affa534
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.util.*;
+import javax.media.opengl.*;
+
+/**
+ * Tracks as closely as possible the sizes of allocated OpenGL buffer
+ * objects. When glMapBuffer or glMapBufferARB is called, in order to
+ * turn the resulting base address into a java.nio.ByteBuffer, we need
+ * to know the size in bytes of the allocated OpenGL buffer object.
+ * Previously we would compute this size by using
+ * glGetBufferParameterivARB with a pname of GL_BUFFER_SIZE, but
+ * it appears doing so each time glMapBuffer is called is too costly
+ * on at least Apple's new multithreaded OpenGL implementation. <P>
+ *
+ * Instead we now try to track the sizes of allocated buffer objects.
+ * We watch calls to glBindBuffer to see which buffer is bound to
+ * which target and to glBufferData to see how large the buffer's
+ * allocated size is. When glMapBuffer is called, we consult our table
+ * of buffer sizes to see if we can return an answer without a glGet
+ * call. <P>
+ *
+ * We share the GLBufferSizeTracker objects among all GLContexts for
+ * which sharing is enabled, because the namespace for buffer objects
+ * is the same for these contexts. <P>
+ *
+ * Tracking the state of which buffer objects are bound is done in the
+ * GLBufferStateTracker and is not completely trivial. In the face of
+ * calls to glPushClientAttrib / glPopClientAttrib we currently punt
+ * and re-fetch the bound buffer object for the state in question;
+ * see, for example, glVertexPointer and the calls down to
+ * GLBufferStateTracker.getBoundBufferObject(). Note that we currently
+ * ignore new binding targets such as GL_TRANSFORM_FEEDBACK_BUFFER_NV;
+ * the fact that new binding targets may be added in the future makes
+ * it impossible to cache state for these new targets. <P>
+ *
+ * Ignoring new binding targets, the primary situation in which we may
+ * not be able to return a cached answer is in the case of an error,
+ * where glBindBuffer may not have been called before trying to call
+ * glBufferData. Also, if external native code modifies a buffer
+ * object, we may return an incorrect answer. (FIXME: this case
+ * requires more thought, and perhaps stochastic and
+ * exponential-fallback checking. However, note that it can only occur
+ * in the face of external native code which requires that the
+ * application be signed anyway, so there is no security risk in this
+ * area.)
+ */
+
+public class GLBufferSizeTracker {
+ // Map from buffer names to sizes.
+ // Note: should probably have some way of shrinking this map, but
+ // can't just make it a WeakHashMap because nobody holds on to the
+ // keys; would have to always track creation and deletion of buffer
+ // objects, which is probably sub-optimal. The expected usage
+ // pattern of buffer objects indicates that the fact that this map
+ // never shrinks is probably not that bad.
+ private Map/*<Integer,Integer>*/ bufferSizeMap =
+ Collections.synchronizedMap(new HashMap/*<Integer,Integer>*/());
+
+ private static final boolean DEBUG = Debug.debug("GLBufferSizeTracker");
+
+ public GLBufferSizeTracker() {
+ }
+
+ public void setBufferSize(GLBufferStateTracker bufferStateTracker,
+ int target,
+ GL caller,
+ int size) {
+ // Need to do some similar queries to getBufferSize below
+ int buffer = bufferStateTracker.getBoundBufferObject(target, caller);
+ boolean valid = bufferStateTracker.isBoundBufferObjectKnown(target);
+ if (valid) {
+ if (buffer == 0) {
+ // FIXME: this really should not happen if we know what's
+ // going on. Very likely there is an OpenGL error in the
+ // application if we get here. Could silently return 0, but it
+ // seems better to get an early warning that something is
+ // wrong.
+ throw new GLException("Error: no OpenGL buffer object appears to be bound to target 0x" +
+ Integer.toHexString(target));
+ }
+ bufferSizeMap.put(new Integer(buffer), new Integer(size));
+ }
+ // We don't know the current buffer state. Note that the buffer
+ // state tracker will have made the appropriate OpenGL query if it
+ // didn't know what was going on, so at this point we have nothing
+ // left to do except drop this piece of information on the floor.
+ }
+
+ public int getBufferSize(GLBufferStateTracker bufferStateTracker,
+ int target,
+ GL caller) {
+ // See whether we know what buffer is currently bound to the given
+ // state
+ int buffer = bufferStateTracker.getBoundBufferObject(target, caller);
+ boolean valid = bufferStateTracker.isBoundBufferObjectKnown(target);
+ if (valid) {
+ if (buffer == 0) {
+ // FIXME: this really should not happen if we know what's
+ // going on. Very likely there is an OpenGL error in the
+ // application if we get here. Could silently return 0, but it
+ // seems better to get an early warning that something is
+ // wrong.
+ throw new GLException("Error: no OpenGL buffer object appears to be bound to target 0x" +
+ Integer.toHexString(target));
+ }
+ // See whether we know the size of this buffer object; at this
+ // point we almost certainly should if the application is
+ // written correctly
+ Integer key = new Integer(buffer);
+ Integer sz = (Integer) bufferSizeMap.get(key);
+ if (sz == null) {
+ // For robustness, try to query this value from the GL as we used to
+ int[] tmp = new int[1];
+ caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0);
+ if (tmp[0] == 0) {
+ // Assume something is wrong rather than silently going along
+ throw new GLException("Error: buffer size returned by glGetBufferParameteriv was zero; probably application error");
+ }
+ // Assume we just don't know what's happening
+ sz = new Integer(tmp[0]);
+ bufferSizeMap.put(key, sz);
+ if (DEBUG) {
+ System.err.println("GLBufferSizeTracker.getBufferSize(): made slow query to cache size " +
+ tmp[0] +
+ " for buffer " +
+ buffer);
+ }
+ }
+ return sz.intValue();
+ }
+ // We don't know what's going on in this case; query the GL for an answer
+ int[] tmp = new int[1];
+ caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0);
+ if (DEBUG) {
+ System.err.println("GLBufferSizeTracker.getBufferSize(): no cached buffer information");
+ }
+ return tmp[0];
+ }
+
+ // This should be called on any major event where we might start
+ // producing wrong answers, such as OpenGL context creation and
+ // destruction if we don't know whether there are other currently-
+ // created contexts that might be keeping the buffer objects alive
+ // that we're dealing with
+ public void clearCachedBufferSizes() {
+ bufferSizeMap.clear();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java
new file mode 100755
index 000000000..df8d673a1
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.util.*;
+import javax.media.opengl.*;
+
+/**
+ * Tracks as closely as possible which OpenGL buffer object is bound
+ * to which binding target in the current OpenGL context.
+ * GLBufferStateTracker objects are allocated on a per-OpenGL-context basis.
+ * This class is used to verify that e.g. the vertex
+ * buffer object extension is in use when the glVertexPointer variant
+ * taking a long as argument is called. <P>
+ *
+ * Note that because the enumerated value used for the binding of a
+ * buffer object (e.g. GL_ARRAY_BUFFER) is different than that used to
+ * query the binding using glGetIntegerv (e.g.
+ * GL_ARRAY_BUFFER_BINDING), then in the face of new binding targets
+ * being added to the GL (e.g. GL_TRANSFORM_FEEDBACK_BUFFER_NV) it is
+ * impossible to set up a query of the buffer object currently bound
+ * to a particular state. It turns out that for some uses, such as
+ * finding the size of the currently bound buffer, this doesn't
+ * matter, though of course without knowing the buffer object we can't
+ * re-associate the queried size with the buffer object ID. <P>
+ *
+ * Because the namespace of buffer objects is the unsigned integers
+ * with 0 reserved by the GL, and because we have to be able to return
+ * both 0 and other integers as valid answers from
+ * getBoundBufferObject(), we need a second query, which is to ask
+ * whether we know the state of the binding for a given target. For
+ * "unknown" targets such as GL_TRANSFORM_FEEDBACK_BUFFER_NV we return
+ * false from this, but we also clear the valid bit and later refresh
+ * the binding state if glPushClientAttrib / glPopClientAttrib are
+ * called, since we don't want the complexity of tracking stacks of
+ * these attributes.
+ *
+ */
+
+public class GLBufferStateTracker {
+ private static final boolean DEBUG = Debug.debug("GLBufferStateTracker");
+
+ private static final Integer arrayBufferEnum = new Integer(GL.GL_ARRAY_BUFFER);
+ private static final Integer elementArrayBufferEnum = new Integer(GL.GL_ELEMENT_ARRAY_BUFFER);
+ private static final Integer pixelPackBufferEnum = new Integer(GL2.GL_PIXEL_PACK_BUFFER);
+ private static final Integer pixelUnpackBufferEnum = new Integer(GL2.GL_PIXEL_UNPACK_BUFFER);
+ private static final Integer zero = new Integer(0);
+
+ // Maps binding targets to buffer objects. A null value indicates
+ // that the binding is unknown. A zero value indicates that it is
+ // known that no buffer is bound to the target.
+ private Map/*<Integer,Integer>*/ bindingMap = new HashMap/*<Integer,Integer>*/();
+
+ private int[] bufTmp = new int[1];
+
+ public GLBufferStateTracker() {
+ // Start with known unbound targets for known keys
+ bindingMap.put(arrayBufferEnum, zero);
+ bindingMap.put(elementArrayBufferEnum, zero);
+ bindingMap.put(pixelPackBufferEnum, zero);
+ bindingMap.put(pixelUnpackBufferEnum, zero);
+ }
+
+ public void setBoundBufferObject(int target, int buffer) {
+ bindingMap.put(box(target), box(buffer));
+ }
+
+ /** Note: returns an unspecified value if the binding for the
+ specified target (e.g. GL_ARRAY_BUFFER) is currently unknown.
+ You must use isBoundBufferObjectKnown() to see whether the
+ return value is valid. */
+ public int getBoundBufferObject(int target, GL caller) {
+ Integer value = (Integer) bindingMap.get(box(target));
+ if (value == null) {
+ // User probably either called glPushClientAttrib /
+ // glPopClientAttrib or is querying an unknown target. See
+ // whether we know how to fetch this state.
+ boolean gotQueryTarget = true;
+ int queryTarget = 0;
+ switch (target) {
+ case GL.GL_ARRAY_BUFFER: queryTarget = GL.GL_ARRAY_BUFFER_BINDING; break;
+ case GL.GL_ELEMENT_ARRAY_BUFFER: queryTarget = GL.GL_ELEMENT_ARRAY_BUFFER_BINDING; break;
+ case GL2.GL_PIXEL_PACK_BUFFER: queryTarget = GL2.GL_PIXEL_PACK_BUFFER_BINDING; break;
+ case GL2.GL_PIXEL_UNPACK_BUFFER: queryTarget = GL2.GL_PIXEL_UNPACK_BUFFER_BINDING; break;
+ default: gotQueryTarget = false; break;
+ }
+ if (gotQueryTarget) {
+ caller.glGetIntegerv(queryTarget, bufTmp, 0);
+ if (DEBUG) {
+ System.err.println("GLBufferStateTracker.getBoundBufferObject(): queried bound buffer " +
+ bufTmp[0] +
+ " for query target 0x" + Integer.toHexString(queryTarget));
+ }
+ setBoundBufferObject(target, bufTmp[0]);
+ // Try once more
+ return getBoundBufferObject(target, caller);
+ }
+ return 0;
+ }
+ return value.intValue();
+ }
+
+ /** Indicates whether the binding state for the specified target is
+ currently known. Should be called after getBoundBufferObject()
+ because that method may change the answer for a given target. */
+ public boolean isBoundBufferObjectKnown(int target) {
+ return (bindingMap.get(box(target)) != null);
+ }
+
+ /** Clears out the known/unknown state of the various buffer object
+ binding states. These will be refreshed later on an as-needed
+ basis. This is called by the implementations of
+ glPushClientAttrib / glPopClientAttrib. Might want to call this
+ from GLContext.makeCurrent() in the future to possibly increase
+ the robustness of these caches in the face of external native
+ code manipulating OpenGL state. */
+ public void clearBufferObjectState() {
+ bindingMap.clear();
+ }
+
+ // FIXME: could largely remove this and use Integer.valueOf() in JDK 5
+ private static Integer box(int key) {
+ switch (key) {
+ case 0: return zero;
+ case GL.GL_ARRAY_BUFFER: return arrayBufferEnum;
+ case GL.GL_ELEMENT_ARRAY_BUFFER: return elementArrayBufferEnum;
+ case GL2.GL_PIXEL_PACK_BUFFER: return pixelPackBufferEnum;
+ case GL2.GL_PIXEL_UNPACK_BUFFER: return pixelUnpackBufferEnum;
+ default: return new Integer(key);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
new file mode 100644
index 000000000..7143344bf
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
@@ -0,0 +1,1057 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import com.jogamp.common.os.DynamicLookupHelper;
+import java.nio.*;
+import java.util.*;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.gluegen.runtime.*;
+import com.jogamp.gluegen.runtime.opengl.*;
+import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.util.ReflectionUtil;
+
+public abstract class GLContextImpl extends GLContext {
+ protected GLContextLock lock = new GLContextLock();
+ protected static final boolean DEBUG = Debug.debug("GLContext");
+ protected static final boolean VERBOSE = Debug.verbose();
+ // NOTE: default sense of GLContext optimization disabled in JSR-231
+ // 1.0 beta 5 due to problems on X11 platforms (both Linux and
+ // Solaris) when moving and resizing windows. Apparently GLX tokens
+ // get sent to the X server under the hood (and out from under the
+ // cover of the AWT lock) in these situations. Users requiring
+ // multi-screen X11 applications can manually enable this flag. It
+ // basically had no tangible effect on the Windows or Mac OS X
+ // platforms anyway in particular with the disabling of the
+ // GLWorkerThread which we found to be necessary in 1.0 beta 4.
+ protected boolean optimizationEnabled = Debug.isPropertyDefined("jogl.GLContext.optimize", true);
+
+ // Cache of the functions that are available to be called at the current
+ // moment in time
+ protected ExtensionAvailabilityCache extensionAvailability;
+ // Table that holds the addresses of the native C-language entry points for
+ // OpenGL functions.
+ private ProcAddressTable glProcAddressTable;
+
+ // Tracks creation and initialization of buffer objects to avoid
+ // repeated glGet calls upon glMapBuffer operations
+ private GLBufferSizeTracker bufferSizeTracker; // Singleton - Set by GLContextShareSet
+ private GLBufferStateTracker bufferStateTracker = new GLBufferStateTracker();
+ private GLStateTracker glStateTracker = new GLStateTracker();
+
+ protected GLDrawableImpl drawable;
+ protected GLDrawableImpl drawableRead;
+
+ protected GL gl;
+
+ public GLContextImpl(GLDrawableImpl drawable, GLDrawableImpl drawableRead, GLContext shareWith) {
+ extensionAvailability = new ExtensionAvailabilityCache(this);
+ if (shareWith != null) {
+ GLContextShareSet.registerSharing(this, shareWith);
+ }
+ GLContextShareSet.registerForBufferObjectSharing(shareWith, this);
+ // This must occur after the above calls into the
+ // GLContextShareSet, which set up state needed by the GL object
+ setGL(createGL(drawable.getGLProfile()));
+
+ this.drawable = drawable;
+ setGLDrawableRead(drawableRead);
+ }
+
+ public GLContextImpl(GLDrawableImpl drawable, GLContext shareWith) {
+ this(drawable, null, shareWith);
+ }
+
+ public void setGLDrawableRead(GLDrawable read) {
+ boolean lockHeld = lock.isHeld();
+ if(lockHeld) {
+ release();
+ }
+ drawableRead = ( null != read ) ? (GLDrawableImpl) read : drawable;
+ if(lockHeld) {
+ makeCurrent();
+ }
+ }
+
+ public GLDrawable getGLDrawable() {
+ return drawable;
+ }
+
+ public GLDrawable getGLDrawableRead() {
+ return drawableRead;
+ }
+
+ public GLDrawableImpl getDrawableImpl() {
+ return (GLDrawableImpl) getGLDrawable();
+ }
+
+ public final GL getGL() {
+ return gl;
+ }
+
+ public GL setGL(GL gl) {
+ if(DEBUG) {
+ String sgl1 = (null!=this.gl)?this.gl.getClass().toString()+", "+this.gl.toString():new String("<null>");
+ String sgl2 = (null!=gl)?gl.getClass().toString()+", "+gl.toString():new String("<null>");
+ Exception e = new Exception("setGL (OpenGL "+getGLVersion()+"): "+Thread.currentThread()+", "+sgl1+" -> "+sgl2);
+ e.printStackTrace();
+ }
+ this.gl = gl;
+ return gl;
+ }
+
+ // This is only needed for Mac OS X on-screen contexts
+ protected void update() throws GLException { }
+
+ public boolean isSynchronized() {
+ return !lock.getFailFastMode();
+ }
+
+ public void setSynchronized(boolean isSynchronized) {
+ lock.setFailFastMode(!isSynchronized);
+ }
+
+ public abstract Object getPlatformGLExtensions();
+
+ public void release() throws GLException {
+ if (!lock.isHeld()) {
+ throw new GLException("Context not current on current thread");
+ }
+ setCurrent(null);
+ try {
+ releaseImpl();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ protected abstract void releaseImpl() throws GLException;
+
+ public void destroy() {
+ if (lock.isHeld()) {
+ // release current context
+ release();
+ }
+
+ // Must hold the lock around the destroy operation to make sure we
+ // don't destroy the context out from under another thread rendering to it
+ lock.lock();
+ try {
+ /* FIXME: refactor dependence on Java 2D / JOGL bridge
+ if (tracker != null) {
+ // Don't need to do anything for contexts that haven't been
+ // created yet
+ if (isCreated()) {
+ // If we are tracking creation and destruction of server-side
+ // OpenGL objects, we must decrement the reference count of the
+ // GLObjectTracker upon context destruction.
+ //
+ // Note that we can only eagerly delete these server-side
+ // objects if there is another context currrent right now
+ // which shares textures and display lists with this one.
+ tracker.unref(deletedObjectTracker);
+ }
+ }
+ */
+
+ // Because we don't know how many other contexts we might be
+ // sharing with (and it seems too complicated to implement the
+ // GLObjectTracker's ref/unref scheme for the buffer-related
+ // optimizations), simply clear the cache of known buffers' sizes
+ // when we destroy contexts
+ if (bufferSizeTracker != null) {
+ bufferSizeTracker.clearCachedBufferSizes();
+ }
+
+ if (bufferStateTracker != null) {
+ bufferStateTracker.clearBufferObjectState();
+ }
+
+ if (glStateTracker != null) {
+ glStateTracker.clearStates(false);
+ }
+
+ destroyImpl();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ protected abstract void destroyImpl() throws GLException;
+
+ //----------------------------------------------------------------------
+ //
+
+ /**
+ * MakeCurrent functionality, which also issues the creation of the actual OpenGL context.<br>
+ * The complete callgraph for general OpenGL context creation is:<br>
+ * <ul>
+ * <li> {@link #makeCurrent} <i>GLContextImpl</i>
+ * <li> {@link #makeCurrentImpl} <i>Platform Implementation</i>
+ * <li> {@link #create} <i>Platform Implementation</i>
+ * <li> If <code>ARB_create_context</code> is supported:
+ * <ul>
+ * <li> {@link #createContextARB} <i>GLContextImpl</i>
+ * <li> {@link #createContextARBImpl} <i>Platform Implementation</i>
+ * </ul>
+ * </ul><br>
+ *
+ * Once at startup, ie triggered by the singleton {@link GLDrawableImpl} constructor,
+ * calling {@link #createContextARB} will query all available OpenGL versions:<br>
+ * <ul>
+ * <li> <code>FOR ALL GL* DO</code>:
+ * <ul>
+ * <li> {@link #createContextARBMapVersionsAvailable}
+ * <ul>
+ * <li> {@link #createContextARBVersions}
+ * </ul>
+ * <li> {@link #mapVersionAvailable}
+ * </ul>
+ * </ul><br>
+ *
+ * @see #makeCurrentImpl
+ * @see #create
+ * @see #createContextARB
+ * @see #createContextARBImpl
+ * @see #mapVersionAvailable
+ * @see #destroyContextARBImpl
+ */
+ public int makeCurrent() throws GLException {
+ // Support calls to makeCurrent() over and over again with
+ // different contexts without releasing them
+ // Could implement this more efficiently without explicit
+ // releasing of the underlying context; would require more error
+ // checking during the makeCurrentImpl phase
+ GLContext current = getCurrent();
+ if (current != null) {
+ if (current == this) {
+ // Assume we don't need to make this context current again
+ // For Mac OS X, however, we need to update the context to track resizes
+ update();
+ return CONTEXT_CURRENT;
+ } else {
+ current.release();
+ }
+ }
+
+ if (GLWorkerThread.isStarted() &&
+ !GLWorkerThread.isWorkerThread()) {
+ // Kick the GLWorkerThread off its current context
+ GLWorkerThread.invokeLater(new Runnable() { public void run() {} });
+ }
+
+ lock.lock();
+ int res = 0;
+ try {
+ res = makeCurrentImpl();
+
+ /* FIXME: refactor dependence on Java 2D / JOGL bridge
+ if ((tracker != null) &&
+ (res == CONTEXT_CURRENT_NEW)) {
+ // Increase reference count of GLObjectTracker
+ tracker.ref();
+ }
+ */
+ } catch (GLException e) {
+ lock.unlock();
+ throw(e);
+ }
+ if (res == CONTEXT_NOT_CURRENT) {
+ lock.unlock();
+ } else {
+ if(res == CONTEXT_CURRENT_NEW) {
+ // check if the drawable's and the GL's GLProfile are equal
+ // throws an GLException if not
+ getGLDrawable().getGLProfile().verifyEquality(gl.getGLProfile());
+ }
+ setCurrent(this);
+
+ /* FIXME: refactor dependence on Java 2D / JOGL bridge
+
+ // Try cleaning up any stale server-side OpenGL objects
+ // FIXME: not sure what to do here if this throws
+ if (deletedObjectTracker != null) {
+ deletedObjectTracker.clean(getGL());
+ }
+ */
+ }
+ return res;
+ }
+
+ /**
+ * @see #makeCurrent
+ */
+ protected abstract int makeCurrentImpl() throws GLException;
+
+ /**
+ * @see #makeCurrent
+ */
+ protected abstract void create() throws GLException ;
+
+ /**
+ * Platform dependent but harmonized implementation of the <code>ARB_create_context</code>
+ * mechanism to create a context.<br>
+ *
+ * This method is called from {@link #createContextARB}.<br>
+ *
+ * The implementation shall verify this context with a
+ * <code>MakeContextCurrent</code> call.<br>
+ *
+ * @param share the shared context or null
+ * @param direct flag if direct is requested
+ * @param ctxOptionFlags <code>ARB_create_context</code> related, see references below
+ * @param major major number
+ * @param minor minor number
+ * @return the valid context if successfull, or null
+ *
+ * @see #makeCurrent
+ * @see #CTX_PROFILE_COMPAT
+ * @see #CTX_OPTION_FORWARD
+ * @see #CTX_OPTION_DEBUG
+ * @see #makeCurrentImpl
+ * @see #create
+ * @see #createContextARB
+ * @see #createContextARBImpl
+ * @see #destroyContextARBImpl
+ */
+ protected abstract long createContextARBImpl(long share, boolean direct, int ctxOptionFlags,
+ int major, int minor);
+
+ /**
+ * Destroy the context created by {@link #createContextARBImpl}.
+ *
+ * @see #makeCurrent
+ * @see #makeCurrentImpl
+ * @see #create
+ * @see #createContextARB
+ * @see #createContextARBImpl
+ * @see #destroyContextARBImpl
+ */
+ protected abstract void destroyContextARBImpl(long context);
+
+ /**
+ * Platform independent part of using the <code>ARB_create_context</code>
+ * mechanism to create a context.<br>
+ *
+ * The implementation of {@link #create} shall use this protocol in case the platform supports <code>ARB_create_context</code>.<br>
+ *
+ * This method may call {@link #createContextARBImpl} and {@link #destroyContextARBImpl}. <br>
+ *
+ * This method will also query all available native OpenGL context when first called,<br>
+ * usually the first call should happen with the shared GLContext of the DrawableFactory.<br>
+ *
+ * @see #makeCurrentImpl
+ * @see #create
+ * @see #createContextARB
+ * @see #createContextARBImpl
+ * @see #destroyContextARBImpl
+ */
+ protected long createContextARB(long share, boolean direct,
+ int major[], int minor[], int ctp[])
+ {
+ AbstractGraphicsConfiguration config = drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities();
+ GLProfile glp = glCaps.getGLProfile();
+ long _context = 0;
+
+ if( !mappedVersionsAvailableSet ) {
+ synchronized(mappedVersionsAvailableLock) {
+ if( !mappedVersionsAvailableSet ) {
+ createContextARBMapVersionsAvailable(4, false /* compat */); // GL4
+ createContextARBMapVersionsAvailable(4, true /* compat */); // GL4bc
+ createContextARBMapVersionsAvailable(3, false /* compat */); // GL3
+ createContextARBMapVersionsAvailable(3, true /* compat */); // GL3bc
+ createContextARBMapVersionsAvailable(2, true /* compat */); // GL2
+ mappedVersionsAvailableSet=true;
+ }
+ }
+ }
+
+ int reqMajor;
+ if(glp.isGL4()) {
+ reqMajor=4;
+ } else if (glp.isGL3()) {
+ reqMajor=3;
+ } else /* if (glp.isGL2()) */ {
+ reqMajor=2;
+ }
+ boolean compat = glp.isGL2(); // incl GL3bc and GL4bc
+
+ int key = compose8bit(reqMajor, compat?CTX_PROFILE_COMPAT:CTX_PROFILE_CORE, 0, 0);
+ int val = mappedVersionsAvailable.get( key );
+ long _ctx = 0;
+ if(val>0) {
+ int _major = getComposed8bit(val, 1);
+ int _minor = getComposed8bit(val, 2);
+ int _ctp = getComposed8bit(val, 3);
+
+ _ctx = createContextARBImpl(share, direct, _ctp, _major, _minor);
+ if(0!=_ctx) {
+ setGLFunctionAvailability(true, _major, _minor, _ctp);
+ }
+ }
+ return _ctx;
+ }
+
+ private void createContextARBMapVersionsAvailable(int reqMajor, boolean compat)
+ {
+ long _context;
+ int ctp = CTX_IS_ARB_CREATED | CTX_PROFILE_CORE | CTX_OPTION_ANY; // default
+ if(compat) {
+ ctp &= ~CTX_PROFILE_CORE ;
+ ctp |= CTX_PROFILE_COMPAT ;
+ }
+
+ // FIXME GL3GL4:
+ // To avoid OpenGL implementation bugs and raise compatibility
+ // within JOGL, we map to the proper GL version.
+ // This may change later when GL3 and GL4 drivers become more mature!
+ // Bug: To ensure GL profile compatibility within the JOGL application
+ // Bug: we always try to map against the highest GL version,
+ // Bug: so the use can always cast to a higher one
+ // Bug: int majorMax=GLContext.getMaxMajor();
+ // Bug: int minorMax=GLContext.getMaxMinor(majorMax);
+ int majorMax, minorMax;
+ int majorMin, minorMin;
+ int major[] = new int[1];
+ int minor[] = new int[1];
+ if( 4 == reqMajor ) {
+ majorMax=4; minorMax=GLContext.getMaxMinor(majorMax);
+ majorMin=4; minorMin=0;
+ } else if( 3 == reqMajor ) {
+ majorMax=3; minorMax=GLContext.getMaxMinor(majorMax);
+ majorMin=3; minorMin=1;
+ } else /* if( glp.isGL2() ) */ {
+ majorMax=3; minorMax=0;
+ majorMin=1; minorMin=1; // our minimum desktop OpenGL runtime requirements
+ }
+ _context = createContextARBVersions(0, true, ctp,
+ /* max */ majorMax, minorMax,
+ /* min */ majorMin, minorMin,
+ /* res */ major, minor);
+
+ if(0==_context && !compat) {
+ ctp &= ~CTX_PROFILE_COMPAT ;
+ ctp |= CTX_PROFILE_CORE ;
+ ctp &= ~CTX_OPTION_ANY ;
+ ctp |= CTX_OPTION_FORWARD ;
+ _context = createContextARBVersions(0, true, ctp,
+ /* max */ majorMax, minorMax,
+ /* min */ majorMin, minorMin,
+ /* res */ major, minor);
+ if(0==_context) {
+ // Try a compatible one .. even though not requested .. last resort
+ ctp &= ~CTX_PROFILE_CORE ;
+ ctp |= CTX_PROFILE_COMPAT ;
+ ctp &= ~CTX_OPTION_FORWARD ;
+ ctp |= CTX_OPTION_ANY ;
+ _context = createContextARBVersions(0, true, ctp,
+ /* max */ majorMax, minorMax,
+ /* min */ majorMin, minorMin,
+ /* res */ major, minor);
+ }
+ }
+ if(0!=_context) {
+ destroyContextARBImpl(_context);
+ mapVersionAvailable(reqMajor, compat, major[0], minor[0], ctp);
+ }
+ }
+
+ private long createContextARBVersions(long share, boolean direct, int ctxOptionFlags,
+ int majorMax, int minorMax,
+ int majorMin, int minorMin,
+ int major[], int minor[]) {
+ major[0]=majorMax;
+ minor[0]=minorMax;
+ long _context=0;
+
+ while ( 0==_context &&
+ GLContext.isValidGLVersion(major[0], minor[0]) &&
+ ( major[0]>majorMin || major[0]==majorMin && minor[0] >=minorMin ) ) {
+
+ _context = createContextARBImpl(share, direct, ctxOptionFlags, major[0], minor[0]);
+
+ if(0==_context) {
+ if(!GLContext.decrementGLVersion(major, minor)) break;
+ }
+ }
+ return _context;
+ }
+
+ //----------------------------------------------------------------------
+ // Managing the actual OpenGL version, usually figured at creation time.
+ // As a last resort, the GL_VERSION string may be used ..
+ //
+
+ /**
+ * If major > 0 || minor > 0 : Use passed values, determined at creation time
+ * If major==0 && minor == 0 : Use GL_VERSION
+ * Otherwise .. don't touch ..
+ */
+ protected void setContextVersion(int major, int minor, int ctp) {
+ if (0==ctp) {
+ GLException e = new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
+ throw e;
+ }
+ if(major>0 || minor>0) {
+ if (!GLContext.isValidGLVersion(major, minor)) {
+ GLException e = new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
+ throw e;
+ }
+ ctxMajorVersion = major;
+ ctxMinorVersion = minor;
+ ctxOptions = ctp;
+ ctxVersionString = getGLVersion(gl, ctxMajorVersion, ctxMinorVersion, ctxOptions, getGL().glGetString(GL.GL_VERSION));
+ return;
+ }
+
+ if(major==0 && minor==0) {
+ String versionStr = getGL().glGetString(GL.GL_VERSION);
+ if(null==versionStr) {
+ throw new GLException("GL_VERSION is NULL: "+this);
+ }
+ ctxOptions = ctp;
+
+ // Set version
+ Version version = new Version(versionStr);
+ if (version.isValid()) {
+ ctxMajorVersion = version.getMajor();
+ ctxMinorVersion = version.getMinor();
+
+ ctxVersionString = getGLVersion(gl, ctxMajorVersion, ctxMinorVersion, ctxOptions, versionStr);
+ return;
+ }
+ }
+ }
+
+ private static boolean appendString(StringBuffer sb, String string, boolean needColon, boolean condition) {
+ if(condition) {
+ if(needColon) {
+ sb.append(", ");
+ }
+ sb.append(string);
+ needColon=true;
+ }
+ return needColon;
+ }
+
+ protected static String getGLVersion(GL gl, int major, int minor, int ctp, String gl_version) {
+ boolean needColon = false;
+ StringBuffer sb = new StringBuffer();
+ sb.append(major);
+ sb.append(".");
+ sb.append(minor);
+ sb.append(" (");
+ needColon = appendString(sb, "ES", needColon, null!=gl && gl.isGLES());
+ needColon = appendString(sb, "compatibility profile", needColon, 0 != ( CTX_PROFILE_COMPAT & ctp ));
+ needColon = appendString(sb, "core profile", needColon, 0 != ( CTX_PROFILE_CORE & ctp ));
+ needColon = appendString(sb, "forward compatible", needColon, 0 != ( CTX_OPTION_FORWARD & ctp ));
+ needColon = appendString(sb, "any", needColon, 0 != ( CTX_OPTION_ANY & ctp ));
+ needColon = appendString(sb, "new", needColon, 0 != ( CTX_IS_ARB_CREATED & ctp ));
+ needColon = appendString(sb, "old", needColon, 0 == ( CTX_IS_ARB_CREATED & ctp ));
+ sb.append(") - ");
+ if(null!=gl_version) {
+ sb.append(gl_version);
+ } else {
+ sb.append("n/a");
+ }
+ return sb.toString();
+ }
+
+ //----------------------------------------------------------------------
+ // Helpers for various context implementations
+ //
+
+ private Object createInstance(GLProfile glp, String suffix, Class[] cstrArgTypes, Object[] cstrArgs) {
+ return ReflectionUtil.createInstance(glp.getGLImplBaseClassName()+suffix, cstrArgTypes, cstrArgs);
+ }
+
+ /** Create the GL for this context. */
+ protected GL createGL(GLProfile glp) {
+ GL gl = (GL) createInstance(glp, "Impl", new Class[] { GLProfile.class, GLContextImpl.class }, new Object[] { glp, this } );
+
+ /* FIXME: refactor dependence on Java 2D / JOGL bridge
+ if (tracker != null) {
+ gl.setObjectTracker(tracker);
+ }
+ */
+ return gl;
+ }
+
+ public final ProcAddressTable getGLProcAddressTable() {
+ return glProcAddressTable;
+ }
+
+ /**
+ * Shall return the platform extension ProcAddressTable,
+ * ie for GLXExt, EGLExt, ..
+ */
+ public abstract ProcAddressTable getPlatformExtProcAddressTable();
+
+ /**
+ * Pbuffer support; given that this is a GLContext associated with a
+ * pbuffer, binds this pbuffer to its texture target.
+ */
+ public abstract void bindPbufferToTexture();
+
+ /**
+ * Pbuffer support; given that this is a GLContext associated with a
+ * pbuffer, releases this pbuffer from its texture target.
+ */
+ public abstract void releasePbufferFromTexture();
+
+ public abstract ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3);
+
+ public void setSwapInterval(final int interval) {
+ GLContext current = getCurrent();
+ if (current != this) {
+ throw new GLException("This context is not current. Current context: "+current+
+ ", this context "+this);
+ }
+ setSwapIntervalImpl(interval);
+ }
+
+ protected int currentSwapInterval = -1; // default: not set yet ..
+
+ public int getSwapInterval() {
+ return currentSwapInterval;
+ }
+
+ protected void setSwapIntervalImpl(final int interval) {
+ // nop per default ..
+ }
+
+ /** Maps the given "platform-independent" function name to a real function
+ name. Currently this is only used to map "glAllocateMemoryNV" and
+ associated routines to wglAllocateMemoryNV / glXAllocateMemoryNV. */
+ protected String mapToRealGLFunctionName(String glFunctionName) {
+ Map/*<String, String>*/ map = getFunctionNameMap();
+ String lookup = ( null != map ) ? (String) map.get(glFunctionName) : null;
+ if (lookup != null) {
+ return lookup;
+ }
+ return glFunctionName;
+ }
+ protected abstract Map/*<String, String>*/ getFunctionNameMap() ;
+
+ /** Maps the given "platform-independent" extension name to a real
+ function name. Currently this is only used to map
+ "GL_ARB_pbuffer" to "WGL_ARB_pbuffer/GLX_SGIX_pbuffer" and
+ "GL_ARB_pixel_format" to "WGL_ARB_pixel_format/n.a."
+ */
+ protected String mapToRealGLExtensionName(String glExtensionName) {
+ Map/*<String, String>*/ map = getExtensionNameMap();
+ String lookup = ( null != map ) ? (String) map.get(glExtensionName) : null;
+ if (lookup != null) {
+ return lookup;
+ }
+ return glExtensionName;
+ }
+ protected abstract Map/*<String, String>*/ getExtensionNameMap() ;
+
+ /** Helper routine which resets a ProcAddressTable generated by the
+ GLEmitter by looking up anew all of its function pointers. */
+ protected void resetProcAddressTable(Object table) {
+ GLProcAddressHelper.resetProcAddressTable(table, getDrawableImpl().getDynamicLookupHelper() );
+ }
+
+ /** Indicates whether the underlying OpenGL context has been
+ created. This is used to manage sharing of display lists and
+ textures between contexts. */
+ public abstract boolean isCreated();
+
+ /**
+ * Sets the OpenGL implementation class and
+ * the cache of which GL functions are available for calling through this
+ * context. See {@link #isFunctionAvailable(String)} for more information on
+ * the definition of "available".
+ *
+ * @param force force the setting, even if is already being set.
+ * This might be usefull if you change the OpenGL implementation.
+ *
+ * @see #setContextVersion
+ */
+ protected void setGLFunctionAvailability(boolean force, int major, int minor, int ctp) {
+ if(null!=this.gl && null!=glProcAddressTable && !force) {
+ return; // already done and not forced
+ }
+ if(null==this.gl || force) {
+ setGL(createGL(getGLDrawable().getGLProfile()));
+ }
+
+ updateGLProcAddressTable(major, minor, ctp);
+ }
+
+ /**
+ * Updates the cache of which GL functions are available for calling through this
+ * context. See {@link #isFunctionAvailable(String)} for more information on
+ * the definition of "available".
+ *
+ * @see #setContextVersion
+ */
+ protected void updateGLProcAddressTable(int major, int minor, int ctp) {
+ if(null==this.gl) {
+ throw new GLException("setGLFunctionAvailability not called yet");
+ }
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing OpenGL extension address table for " + this);
+ }
+ if (glProcAddressTable == null) {
+ glProcAddressTable = (ProcAddressTable) createInstance(gl.getGLProfile(), "ProcAddressTable", new Class[0], null);
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ }
+ resetProcAddressTable(getGLProcAddressTable());
+
+ setContextVersion(major, minor, ctp);
+
+ extensionAvailability.reset();
+ }
+
+ /**
+ * Returns true if the specified OpenGL core- or extension-function can be
+ * successfully called using this GL context given the current host (OpenGL
+ * <i>client</i>) and display (OpenGL <i>server</i>) configuration.
+ *
+ * See {@link GL#isFunctionAvailable(String)} for more details.
+ *
+ * @param glFunctionName the name of the OpenGL function (e.g., use
+ * "glPolygonOffsetEXT" or "glPolygonOffset" to check if the {@link
+ * javax.media.opengl.GL#glPolygonOffset(float,float)} is available).
+ */
+ public boolean isFunctionAvailable(String glFunctionName) {
+ if(isCreated()) {
+ // Check GL 1st (cached)
+ ProcAddressTable pTable = getGLProcAddressTable();
+ try {
+ if(0!=pTable.getAddressFor(glFunctionName)) {
+ return true;
+ }
+ } catch (Exception e) {}
+
+ // Check platform extensions 2nd (cached)
+ pTable = getPlatformExtProcAddressTable();
+ try {
+ if(0!=pTable.getAddressFor(glFunctionName)) {
+ return true;
+ }
+ } catch (Exception e) {}
+ }
+ // dynamic function lookup at last incl name aliasing (not cached)
+ DynamicLookupHelper dynLookup = getDrawableImpl().getDynamicLookupHelper();
+ String tmpBase = GLExtensionNames.normalizeVEN(GLExtensionNames.normalizeARB(glFunctionName, true), true);
+ long addr = 0;
+ int variants = GLExtensionNames.getFuncNamePermutationNumber(tmpBase);
+ for(int i = 0; 0==addr && i < variants; i++) {
+ String tmp = GLExtensionNames.getFuncNamePermutation(tmpBase, i);
+ try {
+ addr = dynLookup.dynamicLookupFunction(tmp);
+ } catch (Exception e) { }
+ }
+ if(0!=addr) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the specified OpenGL extension can be
+ * successfully called using this GL context given the current host (OpenGL
+ * <i>client</i>) and display (OpenGL <i>server</i>) configuration.
+ *
+ * See {@link GL#isExtensionAvailable(String)} for more details.
+ *
+ * @param glExtensionName the name of the OpenGL extension (e.g.,
+ * "GL_VERTEX_PROGRAM_ARB").
+ */
+ public boolean isExtensionAvailable(String glExtensionName) {
+ return extensionAvailability.isExtensionAvailable(mapToRealGLExtensionName(glExtensionName));
+ }
+
+ public String getPlatformExtensionsString() {
+ return extensionAvailability.getPlatformExtensionsString();
+ }
+
+ public String getGLExtensions() {
+ return extensionAvailability.getGLExtensions();
+ }
+
+ public boolean isExtensionCacheInitialized() {
+ return extensionAvailability.isInitialized();
+ }
+
+ /** Indicates which floating-point pbuffer implementation is in
+ use. Returns one of GLPbuffer.APPLE_FLOAT, GLPbuffer.ATI_FLOAT,
+ or GLPbuffer.NV_FLOAT. */
+ public int getFloatingPointMode() throws GLException {
+ throw new GLException("Not supported on non-pbuffer contexts");
+ }
+
+ /** On some platforms the mismatch between OpenGL's coordinate
+ system (origin at bottom left) and the window system's
+ coordinate system (origin at top left) necessitates a vertical
+ flip of pixels read from offscreen contexts. */
+ public abstract boolean offscreenImageNeedsVerticalFlip();
+
+ /** Only called for offscreen contexts; needed by glReadPixels */
+ public abstract int getOffscreenContextPixelDataType();
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+
+ //----------------------------------------------------------------------
+ // Helpers for buffer object optimizations
+
+ public void setBufferSizeTracker(GLBufferSizeTracker bufferSizeTracker) {
+ this.bufferSizeTracker = bufferSizeTracker;
+ }
+
+ public GLBufferSizeTracker getBufferSizeTracker() {
+ return bufferSizeTracker;
+ }
+
+ public GLBufferStateTracker getBufferStateTracker() {
+ return bufferStateTracker;
+ }
+
+ public GLStateTracker getGLStateTracker() {
+ return glStateTracker;
+ }
+
+ //---------------------------------------------------------------------------
+ // Helpers for context optimization where the last context is left
+ // current on the OpenGL worker thread
+ //
+
+ public boolean isOptimizable() {
+ return optimizationEnabled;
+ }
+
+ public boolean hasWaiters() {
+ return lock.hasWaiters();
+ }
+
+ /* FIXME: needed only by the Java 2D / JOGL bridge; refactor
+
+ public GLContextImpl(GLContext shareWith) {
+ this(shareWith, false);
+ }
+
+ public GLContextImpl(GLContext shareWith, boolean dontShareWithJava2D) {
+ extensionAvailability = new ExtensionAvailabilityCache(this);
+ GLContext shareContext = shareWith;
+ if (!dontShareWithJava2D) {
+ shareContext = Java2D.filterShareContext(shareWith);
+ }
+ if (shareContext != null) {
+ GLContextShareSet.registerSharing(this, shareContext);
+ }
+ // Always indicate real behind-the-scenes sharing to track deleted objects
+ if (shareContext == null) {
+ shareContext = Java2D.filterShareContext(shareWith);
+ }
+ GLContextShareSet.registerForObjectTracking(shareWith, this, shareContext);
+ GLContextShareSet.registerForBufferObjectSharing(shareWith, this);
+ // This must occur after the above calls into the
+ // GLContextShareSet, which set up state needed by the GL object
+ setGL(createGL());
+ }
+
+ //---------------------------------------------------------------------------
+ // Helpers for integration with Java2D/OpenGL pipeline when FBOs are
+ // being used
+ //
+
+ public void setObjectTracker(GLObjectTracker tracker) {
+ this.tracker = tracker;
+ }
+
+ public GLObjectTracker getObjectTracker() {
+ return tracker;
+ }
+
+ public void setDeletedObjectTracker(GLObjectTracker deletedObjectTracker) {
+ this.deletedObjectTracker = deletedObjectTracker;
+ }
+
+ public GLObjectTracker getDeletedObjectTracker() {
+ return deletedObjectTracker;
+ }
+
+ // Tracks creation and deletion of server-side OpenGL objects when
+ // the Java2D/OpenGL pipeline is active and using FBOs to render
+ private GLObjectTracker tracker;
+ // Supports deletion of these objects when no other context is
+ // current which can support immediate deletion of them
+ private GLObjectTracker deletedObjectTracker;
+
+ */
+
+ /**
+ * A class for storing and comparing OpenGL version numbers.
+ * This only works for desktop OpenGL at the moment.
+ */
+ private static class Version implements Comparable
+ {
+ private boolean valid;
+ private int major, minor, sub;
+ public Version(int majorRev, int minorRev, int subMinorRev)
+ {
+ major = majorRev;
+ minor = minorRev;
+ sub = subMinorRev;
+ }
+
+ /**
+ * @param versionString must be of the form "GL_VERSION_X" or
+ * "GL_VERSION_X_Y" or "GL_VERSION_X_Y_Z" or "X.Y", where X, Y,
+ * and Z are integers.
+ *
+ * @exception IllegalArgumentException if the argument is not a valid
+ * OpenGL version identifier
+ */
+ public Version(String versionString)
+ {
+ try
+ {
+ if (versionString.startsWith("GL_VERSION_"))
+ {
+ StringTokenizer tok = new StringTokenizer(versionString, "_");
+
+ tok.nextToken(); // GL_
+ tok.nextToken(); // VERSION_
+ if (!tok.hasMoreTokens()) { major = 0; return; }
+ major = Integer.valueOf(tok.nextToken()).intValue();
+ if (!tok.hasMoreTokens()) { minor = 0; return; }
+ minor = Integer.valueOf(tok.nextToken()).intValue();
+ if (!tok.hasMoreTokens()) { sub = 0; return; }
+ sub = Integer.valueOf(tok.nextToken()).intValue();
+ }
+ else
+ {
+ int radix = 10;
+ if (versionString.length() > 2) {
+ if (Character.isDigit(versionString.charAt(0)) &&
+ versionString.charAt(1) == '.' &&
+ Character.isDigit(versionString.charAt(2))) {
+ major = Character.digit(versionString.charAt(0), radix);
+ minor = Character.digit(versionString.charAt(2), radix);
+
+ // See if there's version-specific information which might
+ // imply a more recent OpenGL version
+ StringTokenizer tok = new StringTokenizer(versionString, " ");
+ if (tok.hasMoreTokens()) {
+ tok.nextToken();
+ if (tok.hasMoreTokens()) {
+ String token = tok.nextToken();
+ int i = 0;
+ while (i < token.length() && !Character.isDigit(token.charAt(i))) {
+ i++;
+ }
+ if (i < token.length() - 2 &&
+ Character.isDigit(token.charAt(i)) &&
+ token.charAt(i+1) == '.' &&
+ Character.isDigit(token.charAt(i+2))) {
+ int altMajor = Character.digit(token.charAt(i), radix);
+ int altMinor = Character.digit(token.charAt(i+2), radix);
+ // Avoid possibly confusing situations by putting some
+ // constraints on the upgrades we do to the major and
+ // minor versions
+ if ((altMajor == major && altMinor > minor) ||
+ altMajor == major + 1) {
+ major = altMajor;
+ minor = altMinor;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ valid = true;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ // FIXME: refactor desktop OpenGL dependencies and make this
+ // class work properly for OpenGL ES
+ System.err.println("ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: "+e);
+ major = 1;
+ minor = 0;
+ /*
+ throw (IllegalArgumentException)
+ new IllegalArgumentException(
+ "Illegally formatted version identifier: \"" + versionString + "\"")
+ .initCause(e);
+ */
+ }
+ }
+
+ public boolean isValid() {
+ return valid;
+ }
+
+ public int compareTo(Object o)
+ {
+ Version vo = (Version)o;
+ if (major > vo.major) return 1;
+ else if (major < vo.major) return -1;
+ else if (minor > vo.minor) return 1;
+ else if (minor < vo.minor) return -1;
+ else if (sub > vo.sub) return 1;
+ else if (sub < vo.sub) return -1;
+
+ return 0; // they are equal
+ }
+
+ public int getMajor() {
+ return major;
+ }
+
+ public int getMinor() {
+ return minor;
+ }
+
+ } // end class Version
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java
new file mode 100644
index 000000000..56a5b023f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import javax.media.opengl.*;
+
+/** Implements the makeCurrent / release locking behavior of the
+ GLContext class. When "fail fast mode" is enabled, attempts to
+ lock the same GLContextLock on more than one thread cause
+ GLException to be raised. This lock is not recursive. Attempts to
+ lock it more than once on a given thread will cause GLException to
+ be raised. */
+
+public class GLContextLock {
+ private Object lock = new Object();
+ private Thread owner;
+ private boolean failFastMode = true;
+ private volatile int waiters;
+
+ /** Locks this GLContextLock on the current thread. If fail fast
+ mode is enabled and the GLContextLock is already owned by
+ another thread, throws GLException. */
+ public void lock() throws GLException {
+ synchronized(lock) {
+ Thread current = Thread.currentThread();
+ if (owner == null) {
+ owner = current;
+ } else if (owner != current) {
+ while (owner != null) {
+ if (failFastMode) {
+ throw new GLException("Attempt to make context current on thread " + current +
+ " which is already current on thread " + owner);
+ } else {
+ try {
+ ++waiters;
+ lock.wait();
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ } finally {
+ --waiters;
+ }
+ }
+ }
+ owner = current;
+ } else {
+ throw new GLException("Attempt to make the same context current twice on thread " + current);
+ }
+ }
+ }
+
+ /** Unlocks this GLContextLock. */
+ public void unlock() throws GLException {
+ synchronized (lock) {
+ Thread current = Thread.currentThread();
+ if (owner == current) {
+ owner = null;
+ lock.notifyAll();
+ } else {
+ if (owner != null) {
+ throw new GLException("Attempt by thread " + current +
+ " to release context owned by thread " + owner);
+ } else {
+ throw new GLException("Attempt by thread " + current +
+ " to release unowned context");
+ }
+ }
+ }
+ }
+
+ /** Indicates whether this lock is held by the current thread. */
+ public boolean isHeld() {
+ synchronized(lock) {
+ Thread current = Thread.currentThread();
+ return (owner == current);
+ }
+ }
+
+ public void setFailFastMode(boolean onOrOff) {
+ failFastMode = onOrOff;
+ }
+
+ public boolean getFailFastMode() {
+ return failFastMode;
+ }
+
+ public boolean hasWaiters() {
+ return (waiters != 0);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextShareSet.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextShareSet.java
new file mode 100644
index 000000000..abeb231f4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextShareSet.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+// FIXME: refactor Java SE dependencies
+// import java.awt.GraphicsConfiguration;
+// import java.awt.GraphicsDevice;
+// import java.awt.GraphicsEnvironment;
+import java.lang.ref.*;
+import java.util.*;
+import javax.media.opengl.*;
+
+/** Provides a mechanism by which OpenGL contexts can share textures
+ and display lists in the face of multithreading and asynchronous
+ context creation as is inherent in the AWT and Swing. */
+
+public class GLContextShareSet {
+ // FIXME: refactor Java SE dependencies
+ // private static boolean forceTracking = Debug.isPropertyDefined("jogl.glcontext.forcetracking");
+ private static final boolean DEBUG = Debug.debug("GLContextShareSet");
+
+ // This class is implemented with a WeakHashMap that goes from the
+ // contexts as keys to a complex data structure as value that tracks
+ // context creation and deletion.
+
+ private static Map/*<GLContext, ShareSet>*/ shareMap = new WeakHashMap();
+ private static Object dummyValue = new Object();
+
+ private static class ShareSet {
+ private Map allShares = new WeakHashMap();
+ private Map createdShares = new WeakHashMap();
+ private Map destroyedShares = new WeakHashMap();
+
+ public void add(GLContext ctx) {
+ if (allShares.put(ctx, dummyValue) == null) {
+ // FIXME: downcast to GLContextImpl undesirable
+ if (((GLContextImpl) ctx).isCreated()) {
+ createdShares.put(ctx, dummyValue);
+ } else {
+ destroyedShares.put(ctx, dummyValue);
+ }
+ }
+ }
+
+ public GLContext getCreatedShare(GLContext ignore) {
+ for (Iterator iter = createdShares.keySet().iterator(); iter.hasNext(); ) {
+ GLContext ctx = (GLContext) iter.next();
+ if (ctx != ignore) {
+ return ctx;
+ }
+ }
+ return null;
+ }
+
+ public void contextCreated(GLContext ctx) {
+ Object res = destroyedShares.remove(ctx);
+ assert res != null : "State of ShareSet corrupted; thought context " +
+ ctx + " should have been in destroyed set but wasn't";
+ res = createdShares.put(ctx, dummyValue);
+ assert res == null : "State of ShareSet corrupted; thought context " +
+ ctx + " shouldn't have been in created set but was";
+ }
+
+ public void contextDestroyed(GLContext ctx) {
+ Object res = createdShares.remove(ctx);
+ assert res != null : "State of ShareSet corrupted; thought context " +
+ ctx + " should have been in created set but wasn't";
+ res = destroyedShares.put(ctx, dummyValue);
+ assert res == null : "State of ShareSet corrupted; thought context " +
+ ctx + " shouldn't have been in destroyed set but was";
+ }
+ }
+
+ /** Indicate that contexts <code>share1</code> and
+ <code>share2</code> will share textures and display lists. Both
+ must be non-null. */
+ public static synchronized void registerSharing(GLContext share1, GLContext share2) {
+ if (share1 == null || share2 == null) {
+ throw new IllegalArgumentException("Both share1 and share2 must be non-null");
+ }
+ ShareSet share = entryFor(share1);
+ if (share == null) {
+ share = entryFor(share2);
+ }
+ if (share == null) {
+ share = new ShareSet();
+ }
+ share.add(share1);
+ share.add(share2);
+ addEntry(share1, share);
+ addEntry(share2, share);
+ }
+
+ public static synchronized GLContext getShareContext(GLContext contextToCreate) {
+ ShareSet share = entryFor(contextToCreate);
+ if (share == null) {
+ return null;
+ }
+ return share.getCreatedShare(contextToCreate);
+ }
+
+ public static synchronized void contextCreated(GLContext context) {
+ ShareSet share = entryFor(context);
+ if (share != null) {
+ share.contextCreated(context);
+ }
+ }
+
+ public static synchronized void contextDestroyed(GLContext context) {
+ ShareSet share = entryFor(context);
+ if (share != null) {
+ share.contextDestroyed(context);
+ }
+ }
+
+ /** In order to avoid glGet calls for buffer object checks related
+ to glVertexPointer, etc. calls as well as glMapBuffer calls, we
+ need to share the same GLBufferSizeTracker object between
+ contexts sharing textures and display lists. For now we keep
+ this mechanism orthogonal to the GLObjectTracker to hopefully
+ keep things easier to understand. (The GLObjectTracker is
+ currently only needed in a fairly esoteric case, when the
+ Java2D/JOGL bridge is active, but the GLBufferSizeTracker
+ mechanism is now always required.) */
+ public static void registerForBufferObjectSharing(GLContext olderContextOrNull, GLContext newContext) {
+ // FIXME: downcasts to GLContextImpl undesirable
+ GLContextImpl older = (GLContextImpl) olderContextOrNull;
+ GLContextImpl newer = (GLContextImpl) newContext;
+ GLBufferSizeTracker tracker = null;
+ if (older != null) {
+ tracker = older.getBufferSizeTracker();
+ assert (tracker != null)
+ : "registerForBufferObjectSharing was not called properly for the older context, or has a bug in it";
+ }
+ if (tracker == null) {
+ tracker = new GLBufferSizeTracker();
+ }
+ newer.setBufferSizeTracker(tracker);
+ }
+
+ // FIXME: refactor Java SE dependencies
+ // /** Indicates that the two supplied contexts (which must be able to
+ // share textures and display lists) should be in the same
+ // namespace for tracking of server-side object creation and
+ // deletion. Because the sharing necessary behind the scenes is
+ // different than that requested at the user level, the two notions
+ // are different. This must be called immediately after the
+ // creation of the new context (which is the second argument)
+ // before any server-side OpenGL objects have been created in that
+ // context. */
+ // public static void registerForObjectTracking(GLContext olderContextOrNull,
+ // GLContext newContext,
+ // GLContext realShareContext) {
+ // if (isObjectTrackingEnabled() || isObjectTrackingDebuggingEnabled()) {
+ // GLContextImpl impl1 = null;
+ // GLContextImpl impl2 = null;
+ // GLObjectTracker tracker = null;
+ //
+ // synchronized (GLContextShareSet.class) {
+ // if (olderContextOrNull != null &&
+ // newContext != null) {
+ // if (entryFor(olderContextOrNull) != entryFor(newContext)) {
+ // throw new IllegalArgumentException("old and new contexts must be able to share textures and display lists");
+ // }
+ // }
+ //
+ // // FIXME: downcast to GLContextImpl undesirable
+ // impl1 = (GLContextImpl) olderContextOrNull;
+ // impl2 = (GLContextImpl) newContext;
+ //
+ // GLObjectTracker deletedObjectTracker = null;
+ // GLContextImpl shareImpl = (GLContextImpl) realShareContext;
+ // // Before we zap the "user-level" object trackers, make sure
+ // // that all contexts in the share set share the destroyed object
+ // // tracker
+ // if (shareImpl != null) {
+ // deletedObjectTracker = shareImpl.getDeletedObjectTracker();
+ // }
+ // if (deletedObjectTracker == null) {
+ // // Must create one and possibly set it up in the older context
+ // deletedObjectTracker = new GLObjectTracker();
+ // if (DEBUG) {
+ // System.err.println("Created deletedObjectTracker " + deletedObjectTracker + " because " +
+ // ((shareImpl == null) ? "shareImpl was null" : "shareImpl's (" + shareImpl + ") deletedObjectTracker was null"));
+ // }
+ //
+ // if (shareImpl != null) {
+ // // FIXME: think should really assert in this case
+ // shareImpl.setDeletedObjectTracker(deletedObjectTracker);
+ // if (DEBUG) {
+ // System.err.println("Set deletedObjectTracker " + deletedObjectTracker + " in shareImpl context " + shareImpl);
+ // }
+ // }
+ // }
+ // impl2.setDeletedObjectTracker(deletedObjectTracker);
+ // if (DEBUG) {
+ // System.err.println("Set deletedObjectTracker " + deletedObjectTracker + " in impl2 context " + impl2);
+ // }
+ // }
+ //
+ // // Must not hold lock around this operation
+ // // Don't share object trackers with the primordial share context from Java2D
+ // if (Java2D.isOGLPipelineActive()) {
+ // // FIXME: probably need to do something different here
+ // // Need to be able to figure out the GraphicsDevice for the
+ // // older context if it's on-screen
+ // GraphicsDevice device = GraphicsEnvironment.
+ // getLocalGraphicsEnvironment().
+ // getDefaultScreenDevice();
+ // GLContext j2dShareContext = Java2D.getShareContext(device);
+ // if (impl1 != null && impl1 == j2dShareContext) {
+ // impl1 = null;
+ // }
+ // }
+ //
+ // synchronized (GLContextShareSet.class) {
+ // if (impl1 != null) {
+ // tracker = impl1.getObjectTracker();
+ // assert (tracker != null)
+ // : "registerForObjectTracking was not called properly for the older context";
+ // }
+ // if (tracker == null) {
+ // tracker = new GLObjectTracker();
+ // }
+ // // Note that we don't assert that the tracker is non-null for
+ // // impl2 because the way we use this functionality we actually
+ // // overwrite the initially-set object tracker in the new context
+ // impl2.setObjectTracker(tracker);
+ // }
+ // }
+ // }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+
+
+ private static ShareSet entryFor(GLContext context) {
+ return (ShareSet) shareMap.get(context);
+ }
+
+ private static void addEntry(GLContext context, ShareSet share) {
+ if (shareMap.get(context) == null) {
+ shareMap.put(context, share);
+ }
+ }
+
+ // FIXME: refactor Java SE dependencies
+ // private static boolean isObjectTrackingEnabled() {
+ // return ((Java2D.isOGLPipelineActive() && Java2D.isFBOEnabled()) ||
+ // isObjectTrackingDebuggingEnabled());
+ // }
+ //
+ // private static boolean isObjectTrackingDebuggingEnabled() {
+ // return forceTracking;
+ // }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
new file mode 100644
index 000000000..cdf5beb24
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.nio.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.common.util.*;
+import com.jogamp.gluegen.runtime.*;
+import java.lang.reflect.*;
+
+/** Extends GLDrawableFactory with a few methods for handling
+ typically software-accelerated offscreen rendering (Device
+ Independent Bitmaps on Windows, pixmaps on X11). Direct access to
+ these GLDrawables is not supplied directly to end users, though
+ they may be instantiated by the GLJPanel implementation. */
+public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
+ protected static final boolean DEBUG = Debug.debug("GLDrawableFactory");
+
+ private boolean isValid = false;
+
+ public void shutdown() {
+ validate();
+ isValid = false;
+ }
+
+ protected final void validate() {
+ if(!isValid) {
+ throw new GLException("GLDrawableFactory is already shutdown!");
+ }
+ }
+
+ //---------------------------------------------------------------------------
+ // Dispatching GLDrawable construction in respect to the NativeWindow Capabilities
+ //
+ public GLDrawable createGLDrawable(NativeWindow target) {
+ validate();
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities caps = (GLCapabilities) target.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ GLDrawable result = null;
+ if(caps.isOnscreen()) {
+ if(DEBUG) {
+ System.out.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target);
+ }
+ result = createOnscreenDrawable(target);
+ } else {
+ if( ! ( target instanceof SurfaceChangeable ) ) {
+ throw new IllegalArgumentException("Passed NativeWindow must implement SurfaceChangeable for offscreen: "+target);
+ }
+ if(caps.isPBuffer()) {
+ if(DEBUG) {
+ System.out.println("GLDrawableFactoryImpl.createGLDrawable -> PbufferDrawable: "+target);
+ }
+ result = createGLPbufferDrawable(target);
+ }
+ if(null==result) {
+ if(DEBUG) {
+ System.out.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable: "+target);
+ }
+ result = createOffscreenDrawable(target);
+ }
+ }
+ if(DEBUG) {
+ System.out.println("GLDrawableFactoryImpl.createGLDrawable: "+result);
+ }
+ return result;
+ }
+
+ //---------------------------------------------------------------------------
+ //
+ // Onscreen GLDrawable construction
+ //
+
+ protected abstract GLDrawableImpl createOnscreenDrawable(NativeWindow target);
+
+ //---------------------------------------------------------------------------
+ //
+ // PBuffer GLDrawable construction
+ //
+
+ /** Target must implement SurfaceChangeable */
+ protected abstract GLDrawableImpl createGLPbufferDrawableImpl(NativeWindow target);
+
+ protected GLDrawableImpl createGLPbufferDrawable(NativeWindow target) {
+ if (!canCreateGLPbuffer(target.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice())) {
+ throw new GLException("Pbuffer support not available with current graphics card");
+ }
+ return createGLPbufferDrawableImpl(target);
+ }
+
+ public GLDrawable createGLPbufferDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ int width,
+ int height) {
+ validate();
+ if(height<=0 || height<=0) {
+ throw new GLException("Width and height of pbuffer must be positive (were (" +
+ width + ", " + height + "))");
+ }
+ capabilities.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
+ capabilities.setOnscreen(false);
+ capabilities.setPBuffer(true);
+ return createGLPbufferDrawable( createOffscreenWindow(capabilities, chooser, height, height) );
+ }
+
+ public GLPbuffer createGLPbuffer(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ int width,
+ int height,
+ GLContext shareWith) {
+ validate();
+ return new GLPbufferImpl( (GLDrawableImpl) createGLPbufferDrawable(capabilities, chooser, height, height),
+ shareWith);
+ }
+
+
+ //---------------------------------------------------------------------------
+ //
+ // Offscreen GLDrawable construction
+ //
+
+ protected abstract GLDrawableImpl createOffscreenDrawable(NativeWindow target) ;
+
+ public GLDrawable createOffscreenDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ int width,
+ int height) {
+ validate();
+ if(width<=0 || height<=0) {
+ throw new GLException("Width and height of pbuffer must be positive (were (" +
+ width + ", " + height + "))");
+ }
+ capabilities.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
+ capabilities.setOnscreen(false);
+ capabilities.setPBuffer(false);
+ return createOffscreenDrawable( createOffscreenWindow(capabilities, chooser, width, height) );
+ }
+
+ /**
+ * creates an offscreen NativeWindow, which must implement SurfaceChangeable as well,
+ * so the windowing system related implementation is able to set the surface handle.
+ */
+ protected abstract NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser,
+ int width, int height);
+
+ protected abstract GLDrawableImpl getSharedDrawable();
+ protected abstract GLContextImpl getSharedContext();
+
+ protected GLDrawableFactoryImpl() {
+ super();
+ isValid = true;
+ }
+
+ protected void maybeDoSingleThreadedWorkaround(Runnable action) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ Threading.invokeOnOpenGLThread(action);
+ } else {
+ action.run();
+ }
+ }
+
+ /**
+ * Returns the sole GLDrawableFactoryImpl instance.
+ *
+ * @param glProfile GLProfile to determine the factory type, ie EGLDrawableFactory,
+ * or one of the native GLDrawableFactory's, ie X11/GLX, Windows/WGL or MacOSX/CGL.
+ */
+ public static GLDrawableFactoryImpl getFactoryImpl(GLProfile glp) {
+ return (GLDrawableFactoryImpl) getFactory(glp);
+ }
+
+ // Helper function for more lazily loading the GLU library;
+ // apparently can't use System.loadLibrary on UNIX because it uses
+ // RTLD_LOCAL and we need to call dlsym(RTLD_DEFAULT)
+ public abstract void loadGLULibrary();
+
+ //----------------------------------------------------------------------
+ // Support for locking and unlocking the toolkit -- needed only on X11 platforms
+ //
+
+ public void lockToolkit() {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ }
+
+ public void unlockToolkit() {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+
+ //---------------------------------------------------------------------------
+ // Support for Java2D/JOGL bridge on Mac OS X; the external
+ // GLDrawable mechanism in the public API is sufficient to
+ // implement this functionality on all other platforms
+ //
+
+ public abstract boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device);
+
+ public abstract GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException;
+
+ //----------------------------------------------------------------------
+ // Gamma adjustment support
+ // Thanks to the LWJGL team for illustrating how to make these
+ // adjustments on various OSs.
+
+ /*
+ * Portions Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'LWJGL' nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /**
+ * Sets the gamma, brightness, and contrast of the current main
+ * display. Returns true if the settings were changed, false if
+ * not. If this method returns true, the display settings will
+ * automatically be reset upon JVM exit (assuming the JVM does not
+ * crash); if the user wishes to change the display settings back to
+ * normal ahead of time, use resetDisplayGamma(). Throws
+ * IllegalArgumentException if any of the parameters were
+ * out-of-bounds.
+ *
+ * @param gamma The gamma value, typically > 1.0 (default value is
+ * 1.0)
+ * @param brightness The brightness value between -1.0 and 1.0,
+ * inclusive (default value is 0)
+ * @param contrast The contrast, greater than 0.0 (default value is 1)
+ * @throws IllegalArgumentException if any of the parameters were
+ * out-of-bounds
+ */
+ public boolean setDisplayGamma(float gamma, float brightness, float contrast) throws IllegalArgumentException {
+ validate();
+ if ((brightness < -1.0f) || (brightness > 1.0f)) {
+ throw new IllegalArgumentException("Brightness must be between -1.0 and 1.0");
+ }
+ if (contrast < 0) {
+ throw new IllegalArgumentException("Contrast must be greater than 0.0");
+ }
+ // FIXME: ensure gamma is > 1.0? Are smaller / negative values legal?
+ int rampLength = getGammaRampLength();
+ if (rampLength == 0) {
+ return false;
+ }
+ float[] gammaRamp = new float[rampLength];
+ for (int i = 0; i < rampLength; i++) {
+ float intensity = (float) i / (float) (rampLength - 1);
+ // apply gamma
+ float rampEntry = (float) java.lang.Math.pow(intensity, gamma);
+ // apply brightness
+ rampEntry += brightness;
+ // apply contrast
+ rampEntry = (rampEntry - 0.5f) * contrast + 0.5f;
+ // Clamp entry to [0, 1]
+ if (rampEntry > 1.0f)
+ rampEntry = 1.0f;
+ else if (rampEntry < 0.0f)
+ rampEntry = 0.0f;
+ gammaRamp[i] = rampEntry;
+ }
+ registerGammaShutdownHook();
+ return setGammaRamp(gammaRamp);
+ }
+
+ public synchronized void resetDisplayGamma() {
+ validate();
+ if (gammaShutdownHook == null) {
+ throw new IllegalArgumentException("Should not call this unless setDisplayGamma called first");
+ }
+ resetGammaRamp(originalGammaRamp);
+ unregisterGammaShutdownHook();
+ }
+
+ //------------------------------------------------------
+ // Gamma-related methods to be implemented by subclasses
+ //
+
+ /** Returns the length of the computed gamma ramp for this OS and
+ hardware. Returns 0 if gamma changes are not supported. */
+ protected int getGammaRampLength() {
+ return 0;
+ }
+
+ /** Sets the gamma ramp for the main screen. Returns false if gamma
+ ramp changes were not supported. */
+ protected boolean setGammaRamp(float[] ramp) {
+ return false;
+ }
+
+ /** Gets the current gamma ramp. This is basically an opaque value
+ used only on some platforms to reset the gamma ramp to its
+ original settings. */
+ protected Buffer getGammaRamp() {
+ return null;
+ }
+
+ /** Resets the gamma ramp, potentially using the specified Buffer as
+ data to restore the original values. */
+ protected void resetGammaRamp(Buffer originalGammaRamp) {
+ }
+
+ // Shutdown hook mechanism for resetting gamma
+ private boolean gammaShutdownHookRegistered;
+ private Thread gammaShutdownHook;
+ private Buffer originalGammaRamp;
+ private synchronized void registerGammaShutdownHook() {
+ if (gammaShutdownHookRegistered)
+ return;
+ if (gammaShutdownHook == null) {
+ gammaShutdownHook = new Thread(new Runnable() {
+ public void run() {
+ synchronized (GLDrawableFactoryImpl.this) {
+ resetGammaRamp(originalGammaRamp);
+ }
+ }
+ });
+ originalGammaRamp = getGammaRamp();
+ }
+ Runtime.getRuntime().addShutdownHook(gammaShutdownHook);
+ gammaShutdownHookRegistered = true;
+ }
+
+ private synchronized void unregisterGammaShutdownHook() {
+ if (!gammaShutdownHookRegistered)
+ return;
+ if (gammaShutdownHook == null) {
+ throw new InternalError("Error in gamma shutdown hook logic");
+ }
+ Runtime.getRuntime().removeShutdownHook(gammaShutdownHook);
+ gammaShutdownHookRegistered = false;
+ // Leave the original gamma ramp data alone
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
new file mode 100644
index 000000000..7a4e84081
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.util.*;
+import javax.media.opengl.*;
+
+/** Encapsulates the implementation of most of the GLAutoDrawable's
+ methods to be able to share it between GLCanvas and GLJPanel. */
+
+public class GLDrawableHelper {
+ private volatile List listeners = new ArrayList();
+ private static final boolean DEBUG = Debug.debug("GLDrawableHelper");
+ private static final boolean VERBOSE = Debug.verbose();
+ private static final boolean NVIDIA_CRASH_WORKAROUND = Debug.isPropertyDefined("jogl.nvidia.crash.workaround", true);
+ private boolean autoSwapBufferMode = true;
+
+ public GLDrawableHelper() {
+ }
+
+ public synchronized String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("GLEventListeners num "+listeners.size()+" [");
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ sb.append(iter.next()+", ");
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public synchronized void addGLEventListener(GLEventListener listener) {
+ List newListeners = (List) ((ArrayList) listeners).clone();
+ newListeners.add(listener);
+ listeners = newListeners;
+ }
+
+ public synchronized void removeGLEventListener(GLEventListener listener) {
+ List newListeners = (List) ((ArrayList) listeners).clone();
+ newListeners.remove(listener);
+ listeners = newListeners;
+ }
+
+ public synchronized void dispose(GLAutoDrawable drawable) {
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ ((GLEventListener) iter.next()).dispose(drawable);
+ }
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ ((GLEventListener) iter.next()).init(drawable);
+ }
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ ((GLEventListener) iter.next()).display(drawable);
+ }
+ }
+
+ public void reshape(GLAutoDrawable drawable,
+ int x, int y, int width, int height) {
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ ((GLEventListener) iter.next()).reshape(drawable, x, y, width, height);
+ }
+ }
+
+ public void setAutoSwapBufferMode(boolean onOrOff) {
+ autoSwapBufferMode = onOrOff;
+ }
+
+ public boolean getAutoSwapBufferMode() {
+ return autoSwapBufferMode;
+ }
+
+ private static final ThreadLocal perThreadInitAction = new ThreadLocal();
+ /** Principal helper method which runs a Runnable with the context
+ made current. This could have been made part of GLContext, but a
+ desired goal is to be able to implement the GLCanvas in terms of
+ the GLContext's public APIs, and putting it into a separate
+ class helps ensure that we don't inadvertently use private
+ methods of the GLContext or its implementing classes. */
+ public void invokeGL(GLDrawable drawable,
+ GLContext context,
+ Runnable runnable,
+ Runnable initAction) {
+ if(null==context) {
+ if (DEBUG) {
+ Exception e = new GLException(Thread.currentThread().getName()+" GLDrawableHelper " + this + ".invokeGL(): NULL GLContext");
+ e.printStackTrace();
+ }
+ return;
+ }
+ // Support for recursive makeCurrent() calls as well as calling
+ // other drawables' display() methods from within another one's
+ GLContext lastContext = GLContext.getCurrent();
+ Runnable lastInitAction = (Runnable) perThreadInitAction.get();
+ if (lastContext != null) {
+ lastContext.release();
+ }
+
+ int res = 0;
+ try {
+ res = context.makeCurrent();
+ if (res != GLContext.CONTEXT_NOT_CURRENT) {
+ if(null!=initAction) {
+ perThreadInitAction.set(initAction);
+ if (res == GLContext.CONTEXT_CURRENT_NEW) {
+ if (DEBUG) {
+ System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running initAction");
+ }
+ initAction.run();
+ }
+ }
+ if(null!=runnable) {
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running runnable");
+ }
+ runnable.run();
+ if (autoSwapBufferMode) {
+ if (drawable != null) {
+ drawable.swapBuffers();
+ }
+ }
+ }
+ }
+ } finally {
+ try {
+ if (res != GLContext.CONTEXT_NOT_CURRENT) {
+ context.release();
+ }
+ } catch (Exception e) {
+ }
+ if (lastContext != null) {
+ int res2 = lastContext.makeCurrent();
+ if (res2 == GLContext.CONTEXT_CURRENT_NEW) {
+ lastInitAction.run();
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java
new file mode 100644
index 000000000..2fef8fd80
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import com.jogamp.common.os.DynamicLookupHelper;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+
+public abstract class GLDrawableImpl implements GLDrawable {
+ protected static final boolean DEBUG = Debug.debug("GLDrawable");
+
+ protected GLDrawableImpl(GLDrawableFactory factory,
+ NativeWindow comp,
+ boolean realized) {
+ this.factory = factory;
+ this.component = comp;
+ this.realized = realized;
+ this.requestedCapabilities = (GLCapabilities)component.getGraphicsConfiguration().getNativeGraphicsConfiguration().getRequestedCapabilities(); // a copy ..
+ }
+
+ /**
+ * Returns the DynamicLookupHelper
+ */
+ public abstract DynamicLookupHelper getDynamicLookupHelper();
+
+ public GLDrawableFactoryImpl getFactoryImpl() {
+ return (GLDrawableFactoryImpl) getFactory();
+ }
+
+ /** For offscreen GLDrawables (pbuffers and "pixmap" drawables),
+ indicates that native resources should be reclaimed. */
+ public void destroy() {
+ throw new GLException("Should not call this (should only be called for offscreen GLDrawables)");
+ }
+
+ public void swapBuffers() throws GLException {
+ GLCapabilities caps = (GLCapabilities)component.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ if ( caps.getDoubleBuffered() ) {
+ if(!component.surfaceSwap()) {
+ swapBuffersImpl();
+ }
+ } else {
+ GLContext ctx = GLContext.getCurrent();
+ if(null!=ctx && ctx.getGLDrawable()==this) {
+ ctx.getGL().glFinish();
+ }
+ }
+ component.surfaceUpdated(this, component, System.currentTimeMillis());
+ }
+
+ protected abstract void swapBuffersImpl();
+
+ public static String toHexString(long hex) {
+ return "0x" + Long.toHexString(hex);
+ }
+
+ public GLProfile getGLProfile() {
+ return requestedCapabilities.getGLProfile();
+ }
+
+ public GLCapabilities getChosenGLCapabilities() {
+ return (GLCapabilities)component.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); // a copy
+ }
+
+ public GLCapabilities getRequestedGLCapabilities() {
+ return requestedCapabilities;
+ }
+
+ public NativeWindow getNativeWindow() {
+ return component;
+ }
+
+ public GLDrawableFactory getFactory() {
+ return factory;
+ }
+
+ public void setRealized(boolean realized) {
+ if ( this.realized != realized ) {
+ if(DEBUG) {
+ System.err.println("setRealized: "+getClass().getName()+" "+this.realized+" -> "+realized);
+ }
+ this.realized = realized;
+ setRealizedImpl();
+ } else if(DEBUG) {
+ System.err.println("setRealized: "+getClass().getName()+" "+this.realized+" == "+realized);
+ }
+ }
+ protected abstract void setRealizedImpl();
+
+ public boolean getRealized() {
+ return realized;
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ /** Returns the current height of this GLDrawable. */
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+ public int lockSurface() throws GLException {
+ if (!realized) {
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
+ return component.lockSurface();
+ }
+
+ public void unlockSurface() {
+ component.unlockSurface();
+ }
+
+ public boolean isSurfaceLocked() {
+ return component.isSurfaceLocked();
+ }
+
+ public String toString() {
+ return getClass().getName()+"[Realized "+getRealized()+
+ ",\n\tFactory "+getFactory()+
+ ",\n\tWindow "+getNativeWindow()+"]";
+ }
+
+ protected GLDrawableFactory factory;
+ protected NativeWindow component;
+ protected GLCapabilities requestedCapabilities;
+
+ // Indicates whether the component (if an onscreen context) has been
+ // realized. Plausibly, before the component is realized the JAWT
+ // should return an error or NULL object from some of its
+ // operations; this appears to be the case on Win32 but is not true
+ // at least with Sun's current X11 implementation (1.4.x), which
+ // crashes with no other error reported if the DrawingSurfaceInfo is
+ // fetched from a locked DrawingSurface during the validation as a
+ // result of calling show() on the main thread. To work around this
+ // we prevent any JAWT or OpenGL operations from being done until
+ // addNotify() is called on the component.
+ protected boolean realized;
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java b/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java
new file mode 100644
index 000000000..c3958eedf
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+// FIXME: refactor Java SE dependencies
+//import java.awt.Toolkit;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashSet;
+import com.jogamp.common.jvm.JNILibLoaderBase;
+
+public class GLJNILibLoader extends JNILibLoaderBase {
+ public static void loadNEWT() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("newt", nativeOSPreload, true);
+ return null;
+ }
+ });
+ }
+
+ public static void loadGLDesktop() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("jogl_desktop", nativeOSPreload, true);
+ return null;
+ }
+ });
+ }
+
+ public static void loadGLDesktopES12() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("jogl_gl2es12", nativeOSPreload, true);
+ return null;
+ }
+ });
+ }
+
+ public static void loadES2() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("jogl_es2", nativeOSPreload, true);
+ return null;
+ }
+ });
+ }
+
+ public static void loadES1() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("jogl_es1", nativeOSPreload, true);
+ return null;
+ }
+ });
+ }
+
+ public static void loadCgImpl() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String[] preload = { "nativewindow", "cg", "cgGL" };
+ loadLibrary("jogl_cg", preload, true);
+ return null;
+ }
+ });
+ }
+
+ private static final String[] nativeOSPreload = { "nativewindow_x11" };
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
new file mode 100644
index 000000000..dd8d980a6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+/**
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.event.*;
+import java.beans.PropertyChangeListener;
+ */
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+
+/** Platform-independent class exposing pbuffer functionality to
+ applications. This class is not exposed in the public API as it
+ would probably add no value; however it implements the GLDrawable
+ interface so can be interacted with via its display() method. */
+
+public class GLPbufferImpl implements GLPbuffer {
+ private GLDrawableImpl pbufferDrawable;
+ private GLContextImpl context;
+ private GLDrawableHelper drawableHelper = new GLDrawableHelper();
+ private int floatMode;
+
+ public GLPbufferImpl(GLDrawableImpl pbufferDrawable,
+ GLContext parentContext) {
+ GLCapabilities caps = (GLCapabilities)
+ pbufferDrawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ if(caps.isOnscreen()) {
+ if(caps.isPBuffer()) {
+ throw new IllegalArgumentException("Error: Given drawable is Onscreen and Pbuffer: "+pbufferDrawable);
+ }
+ throw new IllegalArgumentException("Error: Given drawable is Onscreen: "+pbufferDrawable);
+ } else {
+ if(!caps.isPBuffer()) {
+ throw new IllegalArgumentException("Error: Given drawable is not Pbuffer: "+pbufferDrawable);
+ }
+ }
+ this.pbufferDrawable = pbufferDrawable;
+ context = (GLContextImpl) pbufferDrawable.createContext(parentContext);
+ context.setSynchronized(true);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return pbufferDrawable.createContext(shareWith);
+ }
+
+ public void setRealized(boolean realized) {
+ }
+
+ public void setSize(int width, int height) {
+ // FIXME
+ throw new GLException("Not yet implemented");
+ }
+
+ public NativeWindow getNativeWindow() {
+ return pbufferDrawable.getNativeWindow();
+ }
+
+ public GLDrawableFactory getFactory() {
+ return pbufferDrawable.getFactory();
+ }
+
+ public int getWidth() {
+ return pbufferDrawable.getWidth();
+ }
+
+ public int getHeight() {
+ return pbufferDrawable.getHeight();
+ }
+
+ public void display() {
+ maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction,
+ displayAction,
+ false);
+ }
+
+ public void repaint() {
+ display();
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ drawableHelper.addGLEventListener(listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public void setContext(GLContext ctx) {
+ context=(GLContextImpl)ctx;
+ }
+
+ public GLContext getContext() {
+ return context;
+ }
+
+ public GLDrawable getDrawable() {
+ return pbufferDrawable;
+ }
+
+ public GL getGL() {
+ return getContext().getGL();
+ }
+
+ public GL setGL(GL gl) {
+ return getContext().setGL(gl);
+ }
+
+ public void setAutoSwapBufferMode(boolean onOrOff) {
+ drawableHelper.setAutoSwapBufferMode(onOrOff);
+ }
+
+ public boolean getAutoSwapBufferMode() {
+ return drawableHelper.getAutoSwapBufferMode();
+ }
+
+ public void swapBuffers() {
+ maybeDoSingleThreadedWorkaround(swapBuffersOnEventDispatchThreadAction, swapBuffersAction, false);
+ }
+
+ public void bindTexture() {
+ // Doesn't make much sense to try to do this on the event dispatch
+ // thread given that it has to be called while the context is current
+ context.bindPbufferToTexture();
+ }
+
+ public void releaseTexture() {
+ // Doesn't make much sense to try to do this on the event dispatch
+ // thread given that it has to be called while the context is current
+ context.releasePbufferFromTexture();
+ }
+
+ public GLCapabilities getChosenGLCapabilities() {
+ if (pbufferDrawable == null)
+ return null;
+
+ return pbufferDrawable.getChosenGLCapabilities();
+ }
+
+ public GLCapabilities getRequestedGLCapabilities() {
+ if (pbufferDrawable == null)
+ return null;
+
+ return pbufferDrawable.getRequestedGLCapabilities();
+ }
+
+ public GLProfile getGLProfile() {
+ if (pbufferDrawable == null)
+ return null;
+
+ return pbufferDrawable.getGLProfile();
+ }
+
+ private boolean surfaceLocked = false;
+
+ public int lockSurface() throws GLException {
+ surfaceLocked=true;
+ return NativeWindow.LOCK_SUCCESS;
+ }
+
+ public void unlockSurface() {
+ surfaceLocked=false;
+ }
+
+ public boolean isSurfaceLocked() {
+ return surfaceLocked;
+ }
+
+ //----------------------------------------------------------------------
+ // No-ops for ComponentEvents
+ //
+
+ /*
+ public void addComponentListener(ComponentListener l) {}
+ public void removeComponentListener(ComponentListener l) {}
+ public void addFocusListener(FocusListener l) {}
+ public void removeFocusListener(FocusListener l) {}
+ public void addHierarchyBoundsListener(HierarchyBoundsListener l) {}
+ public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {}
+ public void addHierarchyListener(HierarchyListener l) {}
+ public void removeHierarchyListener(HierarchyListener l) {}
+ public void addInputMethodListener(InputMethodListener l) {}
+ public void removeInputMethodListener(InputMethodListener l) {}
+ public void addKeyListener(KeyListener l) {}
+ public void removeKeyListener(KeyListener l) {}
+ public void addMouseListener(MouseListener l) {}
+ public void removeMouseListener(MouseListener l) {}
+ public void addMouseMotionListener(MouseMotionListener l) {}
+ public void removeMouseMotionListener(MouseMotionListener l) {}
+ public void addMouseWheelListener(MouseWheelListener l) {}
+ public void removeMouseWheelListener(MouseWheelListener l) {}
+ public void addPropertyChangeListener(PropertyChangeListener listener) {}
+ public void removePropertyChangeListener(PropertyChangeListener listener) {}
+ public void addPropertyChangeListener(String propertyName,
+ PropertyChangeListener listener) {}
+ public void removePropertyChangeListener(String propertyName,
+ PropertyChangeListener listener) {}
+ */
+
+ public void destroy() {
+ // FIXME: not calling event listeners .. see GLAutoDrawable spec
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ Threading.invokeOnOpenGLThread(destroyAction);
+ } else {
+ destroyAction.run();
+ }
+ }
+
+ public int getFloatingPointMode() {
+ if (floatMode == 0) {
+ throw new GLException("Pbuffer not initialized, or floating-point support not requested");
+ }
+ return floatMode;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private void maybeDoSingleThreadedWorkaround(Runnable eventDispatchThreadAction,
+ Runnable invokeGLAction,
+ boolean isReshape) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ Threading.invokeOnOpenGLThread(eventDispatchThreadAction);
+ } else {
+ drawableHelper.invokeGL(pbufferDrawable, context, invokeGLAction, initAction);
+ }
+ }
+
+ class InitAction implements Runnable {
+ public void run() {
+ floatMode = context.getFloatingPointMode();
+ drawableHelper.init(GLPbufferImpl.this);
+ }
+ }
+ private InitAction initAction = new InitAction();
+
+ class DisplayAction implements Runnable {
+ public void run() {
+ drawableHelper.display(GLPbufferImpl.this);
+ }
+ }
+ private DisplayAction displayAction = new DisplayAction();
+
+ class SwapBuffersAction implements Runnable {
+ public void run() {
+ pbufferDrawable.swapBuffers();
+ }
+ }
+ private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
+
+ // Workaround for ATI driver bugs related to multithreading issues
+ // like simultaneous rendering via Animators to canvases that are
+ // being resized on the AWT event dispatch thread
+ class DisplayOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(pbufferDrawable, context, displayAction, initAction);
+ }
+ }
+ private DisplayOnEventDispatchThreadAction displayOnEventDispatchThreadAction =
+ new DisplayOnEventDispatchThreadAction();
+ class SwapBuffersOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(pbufferDrawable, context, swapBuffersAction, initAction);
+ }
+ }
+ private SwapBuffersOnEventDispatchThreadAction swapBuffersOnEventDispatchThreadAction =
+ new SwapBuffersOnEventDispatchThreadAction();
+
+ class DestroyAction implements Runnable {
+ public void run() {
+ if (null != context) {
+ context.destroy();
+ }
+ pbufferDrawable.destroy();
+ }
+ }
+ private DestroyAction destroyAction = new DestroyAction();
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java
new file mode 100755
index 000000000..744e7b924
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.util.*;
+import javax.media.opengl.*;
+
+/**
+ * Tracks as closely as possible OpenGL states.
+ * GLStateTracker objects are allocated on a per-OpenGL-context basis.
+ * <p>
+ * Currently supported states: PixelStorei
+ */
+
+public class GLStateTracker {
+ private static final boolean DEBUG = Debug.debug("GLStateTracker");
+
+ private volatile boolean enabled = true;
+
+ private Map/*<Integer,Integer>*/ pixelStateMap = new HashMap/*<Integer,Integer>*/();
+
+ static class SavedState {
+ SavedState() {
+ this.pixelStateMap = null;
+ }
+ void putPixelStateMap(Map pixelStateMap) {
+ this.pixelStateMap = new HashMap();
+ this.pixelStateMap.putAll(pixelStateMap);
+ }
+ Map getPixelStateMap() { return pixelStateMap; }
+
+ private Map pixelStateMap;
+ // private Map otherStateMap;
+ }
+ private List/*<SavedState>*/ stack = new ArrayList();
+
+ public GLStateTracker() {
+ resetStates();
+ }
+
+ public void clearStates(boolean enable) {
+ enabled = enable;
+ pixelStateMap.clear();
+ }
+
+ public void setEnabled(boolean on) {
+ enabled = on;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public boolean getInt(int pname, int[] params, int params_offset) {
+ if(enabled) {
+ Integer key = boxKey(pname);
+ if(null!=key) {
+ Integer value = (Integer) pixelStateMap.get(key);
+ if(null!=value) {
+ params[params_offset] = value.intValue();
+ } else {
+ GLException re = new GLException("Key (0x"+Integer.toHexString(key.intValue())+") is not mapped");
+ throw re;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean getInt(int pname, java.nio.IntBuffer params, int dummy) {
+ if(enabled) {
+ Integer key = boxKey(pname);
+ if(null!=key) {
+ Integer value = (Integer) pixelStateMap.get(key);
+ if(null!=value) {
+ params.put(params.position(), value.intValue());
+ } else {
+ GLException re = new GLException("Key (0x"+Integer.toHexString(key.intValue())+") is not mapped");
+ throw re;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setInt(int pname, int param) {
+ if(enabled) {
+ Integer key = boxKey(pname);
+ if(null!=key) {
+ pixelStateMap.put(key, boxInt(param));
+ }
+ }
+ }
+
+ public void pushAttrib(int flags) {
+ if(enabled) {
+ SavedState state = new SavedState();
+ if( 0 != (flags&GL2.GL_CLIENT_PIXEL_STORE_BIT) ) {
+ state.putPixelStateMap(pixelStateMap);
+ }
+ stack.add(0, state);
+ }
+ }
+
+ public void popAttrib() {
+ if(enabled) {
+ if(stack.size()==0) {
+ throw new GLException("stack contains no elements");
+ }
+ SavedState state = (SavedState) stack.remove(0);
+ if(null==state) {
+ throw new GLException("null stack element (remaining stack size "+stack.size()+")");
+ }
+
+ Map/*<Integer,Integer>*/ pixelStateMapNew = new HashMap/*<Integer,Integer>*/();
+ if ( null != state.getPixelStateMap() ) {
+ pixelStateMapNew.putAll(state.getPixelStateMap());
+ }
+ pixelStateMap = pixelStateMapNew;
+ }
+ }
+
+ private static final Integer GL_PACK_SWAP_BYTES = new Integer(GL2GL3.GL_PACK_SWAP_BYTES);
+ private static final Integer GL_PACK_LSB_FIRST = new Integer(GL2GL3.GL_PACK_LSB_FIRST);
+ private static final Integer GL_PACK_ROW_LENGTH = new Integer(GL2GL3.GL_PACK_ROW_LENGTH);
+ private static final Integer GL_PACK_SKIP_ROWS = new Integer(GL2GL3.GL_PACK_SKIP_ROWS);
+ private static final Integer GL_PACK_SKIP_PIXELS = new Integer(GL2GL3.GL_PACK_SKIP_PIXELS);
+ private static final Integer GL_PACK_ALIGNMENT = new Integer(GL.GL_PACK_ALIGNMENT);
+ private static final Integer GL_PACK_IMAGE_HEIGHT = new Integer(GL2GL3.GL_PACK_IMAGE_HEIGHT);
+ private static final Integer GL_PACK_SKIP_IMAGES = new Integer(GL2GL3.GL_PACK_SKIP_IMAGES);
+
+ private static final Integer GL_UNPACK_SWAP_BYTES = new Integer(GL2GL3.GL_UNPACK_SWAP_BYTES);
+ private static final Integer GL_UNPACK_LSB_FIRST = new Integer(GL2GL3.GL_UNPACK_LSB_FIRST);
+ private static final Integer GL_UNPACK_ROW_LENGTH = new Integer(GL2GL3.GL_UNPACK_ROW_LENGTH);
+ private static final Integer GL_UNPACK_SKIP_ROWS = new Integer(GL2GL3.GL_UNPACK_SKIP_ROWS);
+ private static final Integer GL_UNPACK_SKIP_PIXELS = new Integer(GL2GL3.GL_UNPACK_SKIP_PIXELS);
+ private static final Integer GL_UNPACK_ALIGNMENT = new Integer(GL.GL_UNPACK_ALIGNMENT);
+ private static final Integer GL_UNPACK_IMAGE_HEIGHT = new Integer(GL2GL3.GL_UNPACK_IMAGE_HEIGHT);
+ private static final Integer GL_UNPACK_SKIP_IMAGES = new Integer(GL2GL3.GL_UNPACK_SKIP_IMAGES);
+
+ private static final Integer zero = new Integer(0);
+ private static final Integer one = new Integer(1);
+
+ private static Integer boxKey(int key) {
+ switch (key) {
+ case 0: return zero;
+ case GL2GL3.GL_PACK_SWAP_BYTES: return GL_PACK_SWAP_BYTES;
+ case GL2GL3.GL_PACK_LSB_FIRST: return GL_PACK_LSB_FIRST;
+ case GL2GL3.GL_PACK_ROW_LENGTH: return GL_PACK_ROW_LENGTH;
+ case GL2GL3.GL_PACK_SKIP_ROWS: return GL_PACK_SKIP_ROWS;
+ case GL2GL3.GL_PACK_SKIP_PIXELS: return GL_PACK_SKIP_PIXELS;
+ case GL.GL_PACK_ALIGNMENT: return GL_PACK_ALIGNMENT;
+ case GL2GL3.GL_PACK_IMAGE_HEIGHT: return GL_PACK_IMAGE_HEIGHT;
+ case GL2GL3.GL_PACK_SKIP_IMAGES: return GL_PACK_SKIP_IMAGES;
+
+ case GL2GL3.GL_UNPACK_SWAP_BYTES: return GL_UNPACK_SWAP_BYTES;
+ case GL2GL3.GL_UNPACK_LSB_FIRST: return GL_UNPACK_LSB_FIRST;
+ case GL2GL3.GL_UNPACK_ROW_LENGTH: return GL_UNPACK_ROW_LENGTH;
+ case GL2GL3.GL_UNPACK_SKIP_ROWS: return GL_UNPACK_SKIP_ROWS;
+ case GL2GL3.GL_UNPACK_SKIP_PIXELS: return GL_UNPACK_SKIP_PIXELS;
+ case GL.GL_UNPACK_ALIGNMENT: return GL_UNPACK_ALIGNMENT;
+ case GL2GL3.GL_UNPACK_IMAGE_HEIGHT: return GL_UNPACK_IMAGE_HEIGHT;
+ case GL2GL3.GL_UNPACK_SKIP_IMAGES: return GL_UNPACK_SKIP_IMAGES;
+
+ default: return null;
+ }
+ }
+
+ public void resetStates() {
+ pixelStateMap.clear();
+
+ pixelStateMap.put(GL_PACK_SWAP_BYTES, zero /* GL_FALSE */);
+ pixelStateMap.put(GL_PACK_LSB_FIRST, zero /* GL_FALSE */);
+ pixelStateMap.put(GL_PACK_ROW_LENGTH, zero);
+ pixelStateMap.put(GL_PACK_SKIP_ROWS, zero);
+ pixelStateMap.put(GL_PACK_SKIP_PIXELS, zero);
+ pixelStateMap.put(GL_PACK_ALIGNMENT, new Integer(4));
+ pixelStateMap.put(GL_PACK_IMAGE_HEIGHT, zero);
+ pixelStateMap.put(GL_PACK_SKIP_IMAGES, zero);
+
+ pixelStateMap.put(GL_UNPACK_SWAP_BYTES, zero /* GL_FALSE */);
+ pixelStateMap.put(GL_UNPACK_LSB_FIRST, zero /* GL_FALSE */);
+ pixelStateMap.put(GL_UNPACK_ROW_LENGTH, zero);
+ pixelStateMap.put(GL_UNPACK_SKIP_ROWS, zero);
+ pixelStateMap.put(GL_UNPACK_SKIP_PIXELS, zero);
+ pixelStateMap.put(GL_UNPACK_ALIGNMENT, new Integer(4));
+ pixelStateMap.put(GL_UNPACK_IMAGE_HEIGHT, zero);
+ pixelStateMap.put(GL_UNPACK_SKIP_IMAGES, zero);
+ }
+
+ private static Integer boxInt(int value) {
+ switch (value) {
+ case 0: return zero;
+ case 1: return one;
+
+ default: return new Integer(value);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java b/src/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java
new file mode 100755
index 000000000..768eea3f7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.security.*;
+import java.util.*;
+import javax.media.opengl.*;
+
+/** Singleton thread upon which all OpenGL work is performed by
+ default. Unfortunately many vendors' OpenGL drivers are not really
+ thread-safe and stability is much improved by performing OpenGL
+ work on at most one thread. This is the default behavior of the
+ GLAutoDrawable implementations according to the {@link
+ javax.media.opengl.Threading Threading} class. The GLWorkerThread
+ replaces the original AWT event queue thread-based mechanism for
+ two reasons: first, more than one AWT event queue thread may be
+ spawned, for example if a dialog is being shown; second, it avoids
+ blocking the AWT event queue thread during OpenGL rendering. */
+
+public class GLWorkerThread {
+ private static volatile boolean started;
+ private static volatile Thread thread;
+ private static Object lock;
+ private static volatile boolean shouldTerminate;
+ private static volatile Throwable exception;
+
+ // The Runnable to execute immediately on the worker thread
+ private static volatile Runnable work;
+ // Queue of Runnables to be asynchronously invoked
+ private static List queue = new LinkedList();
+
+ /** Should only be called by Threading class if creation of the
+ GLWorkerThread was requested via the opengl.1thread system
+ property. */
+ public static void start() {
+ if (!started) {
+ synchronized (GLWorkerThread.class) {
+ if (!started) {
+ lock = new Object();
+ thread = new Thread(new WorkerRunnable(),
+ "JOGL GLWorkerThread");
+ thread.setDaemon(true);
+ started = true;
+ synchronized (lock) {
+ thread.start();
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ /*
+
+ // Note: it appears that there is a bug in NVidia's current
+ // drivers where if a context was ever made current on a
+ // given thread and that thread has exited before program
+ // exit, a crash occurs in the drivers. Releasing the
+ // context from the given thread does not work around the
+ // problem.
+ //
+ // For the time being, we're going to work around this
+ // problem by not terminating the GLWorkerThread. In theory,
+ // shutting down the GLWorkerThread cleanly could be a good
+ // general solution to the problem of needing to
+ // cooperatively terminate all Animators at program exit.
+ //
+ // It appears that this doesn't even work around all of the
+ // kinds of crashes. Causing the context to be unilaterally
+ // released from the GLWorkerThread after each invocation
+ // seems to work around all of the kinds of crashes seen.
+ //
+ // These appear to be similar to the kinds of crashes seen
+ // when the Java2D/OpenGL pipeline terminates, and those are
+ // a known issue being fixed, so presumably these will be
+ // fixed in NVidia's next driver set.
+
+ // Install shutdown hook to terminate daemon thread more or
+ // less cooperatively
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ Object lockTemp = lock;
+ if (lockTemp == null) {
+ // Already terminating (?)
+ return;
+ }
+ synchronized (lockTemp) {
+ shouldTerminate = true;
+ lockTemp.notifyAll();
+ try {
+ lockTemp.wait(500);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ });
+ return null;
+ }
+ });
+
+ */
+
+ } else {
+ throw new RuntimeException("Should not start GLWorkerThread twice");
+ }
+ }
+ }
+ }
+
+ public static void invokeAndWait(Runnable runnable)
+ throws InvocationTargetException, InterruptedException {
+ if (!started) {
+ throw new RuntimeException("May not invokeAndWait on worker thread without starting it first");
+ }
+
+ Object lockTemp = lock;
+ if (lockTemp == null) {
+ return; // Terminating
+ }
+
+ synchronized (lockTemp) {
+ if (thread == null) {
+ // Terminating
+ return;
+ }
+
+ work = runnable;
+ lockTemp.notifyAll();
+ lockTemp.wait();
+ if (exception != null) {
+ Throwable localException = exception;
+ exception = null;
+ throw new InvocationTargetException(localException);
+ }
+ }
+ }
+
+ public static void invokeLater(Runnable runnable) {
+ if (!started) {
+ throw new RuntimeException("May not invokeLater on worker thread without starting it first");
+ }
+
+ Object lockTemp = lock;
+ if (lockTemp == null) {
+ return; // Terminating
+ }
+
+ synchronized (lockTemp) {
+ if (thread == null) {
+ // Terminating
+ return;
+ }
+
+ queue.add(runnable);
+ lockTemp.notifyAll();
+ }
+ }
+
+ /** Indicates whether the OpenGL worker thread was started, i.e.,
+ whether it is currently in use. */
+ public static boolean isStarted() {
+ return started;
+ }
+
+ /** Indicates whether the current thread is the OpenGL worker
+ thread. */
+ public static boolean isWorkerThread() {
+ return (Thread.currentThread() == thread);
+ }
+
+ static class WorkerRunnable implements Runnable {
+ public void run() {
+ // Notify starting thread that we're ready
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+
+ while (!shouldTerminate) {
+ synchronized (lock) {
+ while (!shouldTerminate &&
+ (work == null) &&
+ queue.isEmpty()) {
+ try {
+ // Avoid race conditions with wanting to release contexts on this thread
+ lock.wait(1000);
+ } catch (InterruptedException e) {
+ }
+
+ if (GLContext.getCurrent() != null) {
+ // Test later to see whether we need to release this context
+ break;
+ }
+ }
+
+ if (shouldTerminate) {
+ lock.notifyAll();
+ thread = null;
+ lock = null;
+ return;
+ }
+
+ if (work != null) {
+ try {
+ work.run();
+ } catch (Throwable t) {
+ exception = t;
+ } finally {
+ work = null;
+ lock.notifyAll();
+ }
+ }
+
+ while (!queue.isEmpty()) {
+ try {
+ Runnable curAsync = (Runnable) queue.remove(0);
+ curAsync.run();
+ } catch (Throwable t) {
+ System.out.println("Exception occurred on JOGL OpenGL worker thread:");
+ t.printStackTrace();
+ }
+ }
+
+ // See about releasing current context
+ GLContext curContext = GLContext.getCurrent();
+ if (curContext != null &&
+ (curContext instanceof GLContextImpl)) {
+ GLContextImpl impl = (GLContextImpl) curContext;
+ if (impl.hasWaiters()) {
+ impl.release();
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp b/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp
new file mode 100644
index 000000000..4a0eaa22b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.lang.reflect.*;
+import java.nio.*;
+
+/** Internal copy of selected routines from BufferUtil to avoid
+ outward dependencies on com.jogamp.opengl.util package. */
+public class InternalBufferUtil {
+ public static final int SIZEOF_BYTE = 1;
+ public static final int SIZEOF_SHORT = 2;
+ public static final int SIZEOF_INT = 4;
+ public static final int SIZEOF_FLOAT = 4;
+
+ //----------------------------------------------------------------------
+ // Allocation routines
+ //
+
+ /** Allocates a new direct ByteBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ByteBuffer newByteBuffer(int numElements) {
+ ByteBuffer bb = ByteBuffer.allocateDirect(numElements);
+ nativeOrder(bb);
+ return bb;
+ }
+
+ /** Allocates a new direct IntBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static IntBuffer newIntBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT);
+ return bb.asIntBuffer();
+ }
+
+ /** Allocates a new direct ShortBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ShortBuffer newShortBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_SHORT);
+ return bb.asShortBuffer();
+ }
+
+ /** Allocates a new direct FloatBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static FloatBuffer newFloatBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT);
+ return bb.asFloatBuffer();
+ }
+
+ //----------------------------------------------------------------------
+ // Copy routines (type-to-type)
+ //
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed FloatBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyFloatBufferAsByteBuffer(FloatBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_FLOAT);
+ dest.asFloatBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed IntBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyIntBufferAsByteBuffer(IntBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_INT);
+ dest.asIntBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ShortBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyShortBufferAsByteBuffer(ShortBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_SHORT);
+ dest.asShortBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ByteBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyByteBuffer(ByteBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining());
+ dest.put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ //----------------------------------------------------------------------
+ // Conversion routines
+ //
+
+ public static float[] getFloatArray(double[] source) {
+ int i=source.length;
+ float[] dest = new float[i--];
+ while(i>=0) { dest[i]=(float)source[i]; i--; }
+ return dest;
+ }
+
+ public static ByteBuffer nativeOrder(ByteBuffer buf) {
+ if (!isCDCFP) {
+ try {
+ if (byteOrderClass == null) {
+ byteOrderClass = Class.forName("java.nio.ByteOrder");
+ orderMethod = ByteBuffer.class.getMethod("order", new Class[] { byteOrderClass });
+ Method nativeOrderMethod = byteOrderClass.getMethod("nativeOrder", null);
+ nativeOrderObject = nativeOrderMethod.invoke(null, null);
+ }
+ } catch (Throwable t) {
+ // Must be running on CDC / FP
+ isCDCFP = true;
+ }
+
+ if (!isCDCFP) {
+ try {
+ orderMethod.invoke(buf, new Object[] { nativeOrderObject });
+ } catch (Throwable t) {
+ }
+ }
+ }
+ return buf;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // NOTE that this work must be done reflectively at the present time
+ // because this code must compile and run correctly on both CDC/FP and J2SE
+ private static boolean isCDCFP;
+ private static Class byteOrderClass;
+ private static Object nativeOrderObject;
+ private static Method orderMethod;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase b/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase
new file mode 100644
index 000000000..655fa95de
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.lang.reflect.*;
+import java.nio.*;
+
+/** Internal copy of selected routines from BufferUtil to avoid
+ outward dependencies on com.jogamp.opengl.util package. */
+public class InternalBufferUtil {
+ public static final int SIZEOF_BYTE = 1;
+ public static final int SIZEOF_SHORT = 2;
+ public static final int SIZEOF_INT = 4;
+ public static final int SIZEOF_FLOAT = 4;
+ public static final int SIZEOF_LONG = 8;
+ public static final int SIZEOF_DOUBLE = 8;
+
+ //----------------------------------------------------------------------
+ // Allocation routines
+ //
+
+ /** Allocates a new direct ByteBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ByteBuffer newByteBuffer(int numElements) {
+ ByteBuffer bb = ByteBuffer.allocateDirect(numElements);
+ nativeOrder(bb);
+ return bb;
+ }
+
+ /** Allocates a new direct DoubleBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static DoubleBuffer newDoubleBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_DOUBLE);
+ return bb.asDoubleBuffer();
+ }
+
+ /** Allocates a new direct IntBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static IntBuffer newIntBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT);
+ return bb.asIntBuffer();
+ }
+
+ /** Allocates a new direct ShortBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ShortBuffer newShortBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_SHORT);
+ return bb.asShortBuffer();
+ }
+
+ /** Allocates a new direct FloatBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static FloatBuffer newFloatBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT);
+ return bb.asFloatBuffer();
+ }
+
+ //----------------------------------------------------------------------
+ // Copy routines (type-to-ByteBuffer)
+ //
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed FloatBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyFloatBufferAsByteBuffer(FloatBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_FLOAT);
+ dest.asFloatBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed IntBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyIntBufferAsByteBuffer(IntBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_INT);
+ dest.asIntBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ShortBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyShortBufferAsByteBuffer(ShortBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_SHORT);
+ dest.asShortBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ByteBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyByteBuffer(ByteBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining());
+ dest.put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ //----------------------------------------------------------------------
+ // Conversion routines
+ //
+
+ public static float[] getFloatArray(double[] source) {
+ int i=source.length;
+ float[] dest = new float[i--];
+ while(i>=0) { dest[i]=(float)source[i]; i--; }
+ return dest;
+ }
+
+ public static ByteBuffer nativeOrder(ByteBuffer buf) {
+ if (!isCDCFP) {
+ try {
+ if (byteOrderClass == null) {
+ byteOrderClass = Class.forName("java.nio.ByteOrder");
+ orderMethod = ByteBuffer.class.getMethod("order", new Class[] { byteOrderClass });
+ Method nativeOrderMethod = byteOrderClass.getMethod("nativeOrder", null);
+ nativeOrderObject = nativeOrderMethod.invoke(null, null);
+ }
+ } catch (Throwable t) {
+ // Must be running on CDC / FP
+ isCDCFP = true;
+ }
+
+ if (!isCDCFP) {
+ try {
+ orderMethod.invoke(buf, new Object[] { nativeOrderObject });
+ } catch (Throwable t) {
+ }
+ }
+ }
+ return buf;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // NOTE that this work must be done reflectively at the present time
+ // because this code must compile and run correctly on both CDC/FP and J2SE
+ private static boolean isCDCFP;
+ private static Class byteOrderClass;
+ private static Object nativeOrderObject;
+ private static Method orderMethod;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java b/src/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java
new file mode 100755
index 000000000..dbd84c9de
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java
@@ -0,0 +1,1057 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** $Date: 2009-03-13 22:20:29 -0700 (Fri, 13 Mar 2009) $ $Revision: 1867 $
+** $Header$
+*/
+
+/*
+ * Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'LWJGL' nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+package com.jogamp.opengl.impl;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+/**
+ * ProjectFloat.java
+ * <p/>
+ * <p/>
+ * Created 11-jan-2004
+ *
+ * @author Erik Duijs
+ * @author Kenneth Russell
+ */
+public class ProjectFloat {
+ private static final float[] IDENTITY_MATRIX =
+ new float[] {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f };
+
+ private static final float[] ZERO_MATRIX =
+ new float[] {
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f };
+
+ // Note that we have cloned parts of the implementation in order to
+ // support incoming Buffers. The reason for this is to avoid loading
+ // non-direct buffer subclasses unnecessarily, because doing so can
+ // cause performance decreases on direct buffer operations, at least
+ // on the current HotSpot JVM. It would be nicer (and make the code
+ // simpler) to simply have the array-based entry points delegate to
+ // the versions taking Buffers by wrapping the arrays.
+
+ // Array-based implementation
+ private final float[] matrix = new float[16];
+ private final float[][] tempInvertMatrix = new float[4][4];
+
+ private final float[] in = new float[4];
+ private final float[] out = new float[4];
+
+ private final float[] forward = new float[3];
+ private final float[] side = new float[3];
+ private final float[] up = new float[3];
+
+ // Buffer-based implementation
+ private FloatBuffer locbuf;
+ private final FloatBuffer matrixBuf;
+ private final FloatBuffer tempInvertMatrixBuf;
+
+ private final FloatBuffer inBuf;
+ private final FloatBuffer outBuf;
+
+ private final FloatBuffer forwardBuf;
+ private final FloatBuffer sideBuf;
+ private final FloatBuffer upBuf;
+
+ public ProjectFloat() {
+ // Use direct buffers to avoid loading indirect buffer
+ // implementations for applications trying to avoid doing so.
+ // Slice up one big buffer because some NIO implementations
+ // allocate a huge amount of memory to back even the smallest of
+ // buffers.
+ locbuf = InternalBufferUtil.newFloatBuffer(2*16+2*4+3*3);
+ int pos = 0;
+ int sz = 16;
+ matrixBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ tempInvertMatrixBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sz = 4;
+ inBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ outBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sz = 3;
+ forwardBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sideBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ upBuf = slice(locbuf, pos, sz);
+ }
+
+ public void destroy() {
+ if(locbuf!=null) {
+ locbuf.clear();
+ locbuf=null;
+ }
+ }
+
+ private static FloatBuffer slice(FloatBuffer buf, int pos, int len) {
+ buf.position(pos);
+ buf.limit(pos + len);
+ return buf.slice();
+ }
+
+ /**
+ * Make matrix an identity matrix
+ */
+ public static void gluMakeIdentityf(FloatBuffer m) {
+ int oldPos = m.position();
+ m.put(IDENTITY_MATRIX);
+ m.position(oldPos);
+ }
+
+ /**
+ * Make matrix an zero matrix
+ */
+ public static void gluMakeZero(FloatBuffer m) {
+ int oldPos = m.position();
+ m.put(ZERO_MATRIX);
+ m.position(oldPos);
+ }
+
+ /**
+ * Make matrix an identity matrix
+ */
+ public static void gluMakeIdentityf(float[] m) {
+ for (int i = 0; i < 16; i++) {
+ m[i] = IDENTITY_MATRIX[i];
+ }
+ }
+
+ /**
+ * Method __gluMultMatrixVecf
+ *
+ * @param matrix
+ * @param in
+ * @param out
+ */
+ private void __gluMultMatrixVecf(float[] matrix, int matrix_offset, float[] in, float[] out) {
+ for (int i = 0; i < 4; i++) {
+ out[i] =
+ in[0] * matrix[0*4+i+matrix_offset] +
+ in[1] * matrix[1*4+i+matrix_offset] +
+ in[2] * matrix[2*4+i+matrix_offset] +
+ in[3] * matrix[3*4+i+matrix_offset];
+ }
+ }
+
+ /**
+ * Method __gluMultMatrixVecf
+ *
+ * @param matrix
+ * @param in
+ * @param out
+ */
+ private void __gluMultMatrixVecf(FloatBuffer matrix, FloatBuffer in, FloatBuffer out) {
+ int inPos = in.position();
+ int outPos = out.position();
+ int matrixPos = matrix.position();
+ for (int i = 0; i < 4; i++) {
+ out.put(i + outPos,
+ in.get(0+inPos) * matrix.get(0*4+i+matrixPos) +
+ in.get(1+inPos) * matrix.get(1*4+i+matrixPos) +
+ in.get(2+inPos) * matrix.get(2*4+i+matrixPos) +
+ in.get(3+inPos) * matrix.get(3*4+i+matrixPos));
+ }
+ }
+
+ /**
+ * @param src
+ * @param inverse
+ *
+ * @return
+ */
+ public boolean gluInvertMatrixf(float[] src, float[] inverse) {
+ int i, j, k, swap;
+ float t;
+ float[][] temp = tempInvertMatrix;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ temp[i][j] = src[i*4+j];
+ }
+ }
+ gluMakeIdentityf(inverse);
+
+ for (i = 0; i < 4; i++) {
+ //
+ // Look for largest element in column
+ //
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ //
+ // Swap rows.
+ //
+ for (k = 0; k < 4; k++) {
+ t = temp[i][k];
+ temp[i][k] = temp[swap][k];
+ temp[swap][k] = t;
+
+ t = inverse[i*4+k];
+ inverse[i*4+k] = inverse[swap*4+k];
+ inverse[swap*4+k] = t;
+ }
+ }
+
+ if (temp[i][i] == 0) {
+ //
+ // No non-zero pivot. The matrix is singular, which shouldn't
+ // happen. This means the user gave us a bad matrix.
+ //
+ return false;
+ }
+
+ t = temp[i][i];
+ for (k = 0; k < 4; k++) {
+ temp[i][k] /= t;
+ inverse[i*4+k] /= t;
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ t = temp[j][i];
+ for (k = 0; k < 4; k++) {
+ temp[j][k] -= temp[i][k] * t;
+ inverse[j*4+k] -= inverse[i*4+k]*t;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @param src
+ * @param inverse
+ *
+ * @return
+ */
+ public boolean gluInvertMatrixf(FloatBuffer src, FloatBuffer inverse) {
+ int i, j, k, swap;
+ float t;
+
+ int srcPos = src.position();
+ int invPos = inverse.position();
+
+ FloatBuffer temp = tempInvertMatrixBuf;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ temp.put(i*4+j, src.get(i*4+j + srcPos));
+ }
+ }
+ gluMakeIdentityf(inverse);
+
+ for (i = 0; i < 4; i++) {
+ //
+ // Look for largest element in column
+ //
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (Math.abs(temp.get(j*4+i)) > Math.abs(temp.get(i*4+i))) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ //
+ // Swap rows.
+ //
+ for (k = 0; k < 4; k++) {
+ t = temp.get(i*4+k);
+ temp.put(i*4+k, temp.get(swap*4+k));
+ temp.put(swap*4+k, t);
+
+ t = inverse.get(i*4+k + invPos);
+ inverse.put(i*4+k + invPos, inverse.get(swap*4+k + invPos));
+ inverse.put(swap*4+k + invPos, t);
+ }
+ }
+
+ if (temp.get(i*4+i) == 0) {
+ //
+ // No non-zero pivot. The matrix is singular, which shouldn't
+ // happen. This means the user gave us a bad matrix.
+ //
+ return false;
+ }
+
+ t = temp.get(i*4+i);
+ for (k = 0; k < 4; k++) {
+ temp.put(i*4+k, temp.get(i*4+k) / t);
+ inverse.put(i*4+k + invPos, inverse.get(i*4+k + invPos) / t);
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ t = temp.get(j*4+i);
+ for (k = 0; k < 4; k++) {
+ temp.put(j*4+k, temp.get(j*4+k) - temp.get(i*4+k) * t);
+ inverse.put(j*4+k + invPos, inverse.get(j*4+k + invPos) - inverse.get(i*4+k + invPos) * t);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * @param a
+ * @param b
+ * @param r
+ */
+ private void gluMultMatricesf(float[] a, int a_offset, float[] b, int b_offset, float[] r) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ r[i*4+j] =
+ a[i*4+0+a_offset]*b[0*4+j+b_offset] +
+ a[i*4+1+a_offset]*b[1*4+j+b_offset] +
+ a[i*4+2+a_offset]*b[2*4+j+b_offset] +
+ a[i*4+3+a_offset]*b[3*4+j+b_offset];
+ }
+ }
+ }
+
+
+ /**
+ * @param a
+ * @param b
+ * @param r
+ */
+ public static void gluMultMatricesf(FloatBuffer a, FloatBuffer b, FloatBuffer r) {
+ int aPos = a.position();
+ int bPos = b.position();
+ int rPos = r.position();
+
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ r.put(i*4+j + rPos,
+ a.get(i*4+0+aPos)*b.get(0*4+j+bPos) +
+ a.get(i*4+1+aPos)*b.get(1*4+j+bPos) +
+ a.get(i*4+2+aPos)*b.get(2*4+j+bPos) +
+ a.get(i*4+3+aPos)*b.get(3*4+j+bPos));
+ }
+ }
+ }
+
+ /**
+ * Normalize vector
+ *
+ * @param v
+ */
+ public static void normalize(float[] v) {
+ float r;
+
+ r = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+ if ( r == 0.0 || r == 1.0)
+ return;
+
+ r = 1.0f / r;
+
+ v[0] *= r;
+ v[1] *= r;
+ v[2] *= r;
+
+ return;
+ }
+
+ /**
+ * Normalize vector
+ *
+ * @param v
+ */
+ public static void normalize(FloatBuffer v) {
+ float r;
+
+ int vPos = v.position();
+
+ r = (float) Math.sqrt(v.get(0+vPos) * v.get(0+vPos) +
+ v.get(1+vPos) * v.get(1+vPos) +
+ v.get(2+vPos) * v.get(2+vPos));
+ if ( r == 0.0 || r == 1.0)
+ return;
+
+ r = 1.0f / r;
+
+ v.put(0+vPos, v.get(0+vPos) * r);
+ v.put(1+vPos, v.get(1+vPos) * r);
+ v.put(2+vPos, v.get(2+vPos) * r);
+
+ return;
+ }
+
+
+ /**
+ * Calculate cross-product
+ *
+ * @param v1
+ * @param v2
+ * @param result
+ */
+ private static void cross(float[] v1, float[] v2, float[] result) {
+ result[0] = v1[1] * v2[2] - v1[2] * v2[1];
+ result[1] = v1[2] * v2[0] - v1[0] * v2[2];
+ result[2] = v1[0] * v2[1] - v1[1] * v2[0];
+ }
+
+ /**
+ * Calculate cross-product
+ *
+ * @param v1
+ * @param v2
+ * @param result
+ */
+ private static void cross(FloatBuffer v1, FloatBuffer v2, FloatBuffer result) {
+ int v1Pos = v1.position();
+ int v2Pos = v2.position();
+ int rPos = result.position();
+
+ result.put(0+rPos, v1.get(1+v1Pos) * v2.get(2+v2Pos) - v1.get(2+v1Pos) * v2.get(1+v2Pos));
+ result.put(1+rPos, v1.get(2+v1Pos) * v2.get(0+v2Pos) - v1.get(0+v1Pos) * v2.get(2+v2Pos));
+ result.put(2+rPos, v1.get(0+v1Pos) * v2.get(1+v2Pos) - v1.get(1+v1Pos) * v2.get(0+v2Pos));
+ }
+
+ /**
+ * Method gluOrtho2D.
+ *
+ * @param left
+ * @param right
+ * @param bottom
+ * @param top
+ */
+ public void gluOrtho2D(GLMatrixFunc gl, float left, float right, float bottom, float top) {
+ gl.glOrthof(left, right, bottom, top, -1, 1);
+ }
+
+ /**
+ * Method gluPerspective.
+ *
+ * @param fovy
+ * @param aspect
+ * @param zNear
+ * @param zFar
+ */
+ public void gluPerspective(GLMatrixFunc gl, float fovy, float aspect, float zNear, float zFar) {
+ float sine, cotangent, deltaZ;
+ float radians = fovy / 2 * (float) Math.PI / 180;
+
+ deltaZ = zFar - zNear;
+ sine = (float) Math.sin(radians);
+
+ if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
+ return;
+ }
+
+ cotangent = (float) Math.cos(radians) / sine;
+
+ gluMakeIdentityf(matrixBuf);
+
+ matrixBuf.put(0 * 4 + 0, cotangent / aspect);
+ matrixBuf.put(1 * 4 + 1, cotangent);
+ matrixBuf.put(2 * 4 + 2, - (zFar + zNear) / deltaZ);
+ matrixBuf.put(2 * 4 + 3, -1);
+ matrixBuf.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ);
+ matrixBuf.put(3 * 4 + 3, 0);
+
+ gl.glMultMatrixf(matrixBuf);
+ }
+
+ /**
+ * Method gluLookAt
+ *
+ * @param eyex
+ * @param eyey
+ * @param eyez
+ * @param centerx
+ * @param centery
+ * @param centerz
+ * @param upx
+ * @param upy
+ * @param upz
+ */
+ public void gluLookAt(GLMatrixFunc gl,
+ float eyex,
+ float eyey,
+ float eyez,
+ float centerx,
+ float centery,
+ float centerz,
+ float upx,
+ float upy,
+ float upz) {
+ FloatBuffer forward = this.forwardBuf;
+ FloatBuffer side = this.sideBuf;
+ FloatBuffer up = this.upBuf;
+
+ forward.put(0, centerx - eyex);
+ forward.put(1, centery - eyey);
+ forward.put(2, centerz - eyez);
+
+ up.put(0, upx);
+ up.put(1, upy);
+ up.put(2, upz);
+
+ normalize(forward);
+
+ /* Side = forward x up */
+ cross(forward, up, side);
+ normalize(side);
+
+ /* Recompute up as: up = side x forward */
+ cross(side, forward, up);
+
+ gluMakeIdentityf(matrixBuf);
+ matrixBuf.put(0 * 4 + 0, side.get(0));
+ matrixBuf.put(1 * 4 + 0, side.get(1));
+ matrixBuf.put(2 * 4 + 0, side.get(2));
+
+ matrixBuf.put(0 * 4 + 1, up.get(0));
+ matrixBuf.put(1 * 4 + 1, up.get(1));
+ matrixBuf.put(2 * 4 + 1, up.get(2));
+
+ matrixBuf.put(0 * 4 + 2, -forward.get(0));
+ matrixBuf.put(1 * 4 + 2, -forward.get(1));
+ matrixBuf.put(2 * 4 + 2, -forward.get(2));
+
+ gl.glMultMatrixf(matrixBuf);
+ gl.glTranslatef(-eyex, -eyey, -eyez);
+ }
+
+ /**
+ * Method gluProject
+ *
+ * @param objx
+ * @param objy
+ * @param objz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param win_pos
+ *
+ * @return
+ */
+ public boolean gluProject(float objx,
+ float objy,
+ float objz,
+ float[] modelMatrix,
+ int modelMatrix_offset,
+ float[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ float[] win_pos,
+ int win_pos_offset ) {
+
+ float[] in = this.in;
+ float[] out = this.out;
+
+ in[0] = objx;
+ in[1] = objy;
+ in[2] = objz;
+ in[3] = 1.0f;
+
+ __gluMultMatrixVecf(modelMatrix, modelMatrix_offset, in, out);
+ __gluMultMatrixVecf(projMatrix, projMatrix_offset, out, in);
+
+ if (in[3] == 0.0f)
+ return false;
+
+ in[3] = (1.0f / in[3]) * 0.5f;
+
+ // Map x, y and z to range 0-1
+ in[0] = in[0] * in[3] + 0.5f;
+ in[1] = in[1] * in[3] + 0.5f;
+ in[2] = in[2] * in[3] + 0.5f;
+
+ // Map x,y to viewport
+ win_pos[0+win_pos_offset] = in[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset];
+ win_pos[1+win_pos_offset] = in[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset];
+ win_pos[2+win_pos_offset] = in[2];
+
+ return true;
+ }
+
+ /**
+ * Method gluProject
+ *
+ * @param objx
+ * @param objy
+ * @param objz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param win_pos
+ *
+ * @return
+ */
+ public boolean gluProject(float objx,
+ float objy,
+ float objz,
+ FloatBuffer modelMatrix,
+ FloatBuffer projMatrix,
+ IntBuffer viewport,
+ FloatBuffer win_pos) {
+
+ FloatBuffer in = this.inBuf;
+ FloatBuffer out = this.outBuf;
+
+ in.put(0, objx);
+ in.put(1, objy);
+ in.put(2, objz);
+ in.put(3, 1.0f);
+
+ __gluMultMatrixVecf(modelMatrix, in, out);
+ __gluMultMatrixVecf(projMatrix, out, in);
+
+ if (in.get(3) == 0.0f)
+ return false;
+
+ in.put(3, (1.0f / in.get(3)) * 0.5f);
+
+ // Map x, y and z to range 0-1
+ in.put(0, in.get(0) * in.get(3) + 0.5f);
+ in.put(1, in.get(1) * in.get(3) + 0.5f);
+ in.put(2, in.get(2) * in.get(3) + 0.5f);
+
+ // Map x,y to viewport
+ int vPos = viewport.position();
+ int wPos = win_pos.position();
+ win_pos.put(0+wPos, in.get(0) * viewport.get(2+vPos) + viewport.get(0+vPos));
+ win_pos.put(1+wPos, in.get(1) * viewport.get(3+vPos) + viewport.get(1+vPos));
+ win_pos.put(2+wPos, in.get(2));
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject(float winx,
+ float winy,
+ float winz,
+ float[] modelMatrix,
+ int modelMatrix_offset,
+ float[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ float[] obj_pos,
+ int obj_pos_offset) {
+ float[] in = this.in;
+ float[] out = this.out;
+
+ gluMultMatricesf(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
+
+ if (!gluInvertMatrixf(matrix, matrix))
+ return false;
+
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = 1.0f;
+
+ // Map x and y from window coordinates
+ in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+
+ // Map to range -1 to 1
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
+
+ __gluMultMatrixVecf(matrix, 0, in, out);
+
+ if (out[3] == 0.0)
+ return false;
+
+ out[3] = 1.0f / out[3];
+
+ obj_pos[0+obj_pos_offset] = out[0] * out[3];
+ obj_pos[1+obj_pos_offset] = out[1] * out[3];
+ obj_pos[2+obj_pos_offset] = out[2] * out[3];
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject(float winx,
+ float winy,
+ float winz,
+ FloatBuffer modelMatrix,
+ FloatBuffer projMatrix,
+ IntBuffer viewport,
+ FloatBuffer obj_pos) {
+ FloatBuffer in = this.inBuf;
+ FloatBuffer out = this.outBuf;
+
+ gluMultMatricesf(modelMatrix, projMatrix, matrixBuf);
+
+ if (!gluInvertMatrixf(matrixBuf, matrixBuf))
+ return false;
+
+ in.put(0, winx);
+ in.put(1, winy);
+ in.put(2, winz);
+ in.put(3, 1.0f);
+
+ // Map x and y from window coordinates
+ int vPos = viewport.position();
+ int oPos = obj_pos.position();
+ in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
+ in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+
+ // Map to range -1 to 1
+ in.put(0, in.get(0) * 2 - 1);
+ in.put(1, in.get(1) * 2 - 1);
+ in.put(2, in.get(2) * 2 - 1);
+
+ __gluMultMatrixVecf(matrixBuf, in, out);
+
+ if (out.get(3) == 0.0f)
+ return false;
+
+ out.put(3, 1.0f / out.get(3));
+
+ obj_pos.put(0+oPos, out.get(0) * out.get(3));
+ obj_pos.put(1+oPos, out.get(1) * out.get(3));
+ obj_pos.put(2+oPos, out.get(2) * out.get(3));
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject4
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param clipw
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param near
+ * @param far
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject4(float winx,
+ float winy,
+ float winz,
+ float clipw,
+ float[] modelMatrix,
+ int modelMatrix_offset,
+ float[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ float near,
+ float far,
+ float[] obj_pos,
+ int obj_pos_offset ) {
+ float[] in = this.in;
+ float[] out = this.out;
+
+ gluMultMatricesf(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
+
+ if (!gluInvertMatrixf(matrix, matrix))
+ return false;
+
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = clipw;
+
+ // Map x and y from window coordinates
+ in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+ in[2] = (in[2] - near) / (far - near);
+
+ // Map to range -1 to 1
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
+
+ __gluMultMatrixVecf(matrix, 0, in, out);
+
+ if (out[3] == 0.0f)
+ return false;
+
+ obj_pos[0+obj_pos_offset] = out[0];
+ obj_pos[1+obj_pos_offset] = out[1];
+ obj_pos[2+obj_pos_offset] = out[2];
+ obj_pos[3+obj_pos_offset] = out[3];
+ return true;
+ }
+
+ /**
+ * Method gluUnproject4
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param clipw
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param near
+ * @param far
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject4(float winx,
+ float winy,
+ float winz,
+ float clipw,
+ FloatBuffer modelMatrix,
+ FloatBuffer projMatrix,
+ IntBuffer viewport,
+ float near,
+ float far,
+ FloatBuffer obj_pos) {
+ FloatBuffer in = this.inBuf;
+ FloatBuffer out = this.outBuf;
+
+ gluMultMatricesf(modelMatrix, projMatrix, matrixBuf);
+
+ if (!gluInvertMatrixf(matrixBuf, matrixBuf))
+ return false;
+
+ in.put(0, winx);
+ in.put(1, winy);
+ in.put(2, winz);
+ in.put(3, clipw);
+
+ // Map x and y from window coordinates
+ int vPos = viewport.position();
+ in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
+ in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+ in.put(2, (in.get(2) - near) / (far - near));
+
+ // Map to range -1 to 1
+ in.put(0, in.get(0) * 2 - 1);
+ in.put(1, in.get(1) * 2 - 1);
+ in.put(2, in.get(2) * 2 - 1);
+
+ __gluMultMatrixVecf(matrixBuf, in, out);
+
+ if (out.get(3) == 0.0f)
+ return false;
+
+ int oPos = obj_pos.position();
+ obj_pos.put(0+oPos, out.get(0));
+ obj_pos.put(1+oPos, out.get(1));
+ obj_pos.put(2+oPos, out.get(2));
+ obj_pos.put(3+oPos, out.get(3));
+ return true;
+ }
+
+
+ /**
+ * Method gluPickMatrix
+ *
+ * @param x
+ * @param y
+ * @param deltaX
+ * @param deltaY
+ * @param viewport
+ */
+ public void gluPickMatrix(GLMatrixFunc gl,
+ float x,
+ float y,
+ float deltaX,
+ float deltaY,
+ IntBuffer viewport) {
+ if (deltaX <= 0 || deltaY <= 0) {
+ return;
+ }
+
+ /* Translate and scale the picked region to the entire window */
+ int vPos = viewport.position();
+ gl.glTranslatef((viewport.get(2+vPos) - 2 * (x - viewport.get(0+vPos))) / deltaX,
+ (viewport.get(3+vPos) - 2 * (y - viewport.get(1+vPos))) / deltaY,
+ 0);
+ gl.glScalef(viewport.get(2) / deltaX, viewport.get(3) / deltaY, 1.0f);
+ }
+
+ /**
+ * Method gluPickMatrix
+ *
+ * @param x
+ * @param y
+ * @param deltaX
+ * @param deltaY
+ * @param viewport
+ * @param viewport_offset
+ */
+ public void gluPickMatrix(GLMatrixFunc gl,
+ float x,
+ float y,
+ float deltaX,
+ float deltaY,
+ int[] viewport,
+ int viewport_offset) {
+ if (deltaX <= 0 || deltaY <= 0) {
+ return;
+ }
+
+ /* Translate and scale the picked region to the entire window */
+ gl.glTranslatef((viewport[2+viewport_offset] - 2 * (x - viewport[0+viewport_offset])) / deltaX,
+ (viewport[3+viewport_offset] - 2 * (y - viewport[1+viewport_offset])) / deltaY,
+ 0);
+ gl.glScalef(viewport[2+viewport_offset] / deltaX, viewport[3+viewport_offset] / deltaY, 1.0f);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javame_cdc_fp b/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javame_cdc_fp
new file mode 100644
index 000000000..f686bea92
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javame_cdc_fp
@@ -0,0 +1,10 @@
+package com.jogamp.opengl.impl;
+
+public class SystemUtil {
+
+ /** Wrapper for System.getenv(), which doesn't work on platforms
+ earlier than JDK 5 */
+ public static String getenv(String variableName) {
+ return null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javase b/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javase
new file mode 100644
index 000000000..dbb717a32
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javase
@@ -0,0 +1,18 @@
+package com.jogamp.opengl.impl;
+
+public class SystemUtil {
+
+ private static volatile boolean getenvSupported = true;
+ /** Wrapper for System.getenv(), which doesn't work on platforms
+ earlier than JDK 5 */
+ public static String getenv(String variableName) {
+ if (getenvSupported) {
+ try {
+ return System.getenv(variableName);
+ } catch (Error e) {
+ getenvSupported = false;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/ThreadingImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/ThreadingImpl.java
new file mode 100644
index 000000000..1a68f38d4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/ThreadingImpl.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.util.*;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.opengl.GLException;
+
+/** Implementation of the {@link javax.media.opengl.Threading} class. */
+
+public class ThreadingImpl {
+ public static final int AWT = 1;
+ public static final int WORKER = 2;
+
+ protected static final boolean DEBUG = Debug.debug("Threading");
+
+ private static boolean singleThreaded = true;
+ private static int mode;
+ private static boolean hasAWT;
+ // We need to know whether we're running on X11 platforms to change
+ // our behavior when the Java2D/JOGL bridge is active
+ private static boolean _isX11;
+
+ private static final ThreadingPlugin threadingPlugin;
+
+ static {
+ Object threadingPluginTmp =
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String workaround = Debug.getProperty("jogl.1thread", true);
+ // Default to using the AWT thread on all platforms except
+ // Windows. On OS X there is instability apparently due to
+ // using the JAWT on non-AWT threads. On X11 platforms there
+ // are potential deadlocks which can be caused if the AWT
+ // EventQueue thread hands work off to the GLWorkerThread
+ // while holding the AWT lock. The optimization of
+ // makeCurrent / release calls isn't worth these stability
+ // problems.
+ hasAWT = ReflectionUtil.isClassAvailable("java.awt.Canvas") &&
+ ReflectionUtil.isClassAvailable("javax.media.opengl.awt.GLCanvas");
+
+ String osType = NativeWindowFactory.getNativeWindowType(false);
+ _isX11 = NativeWindowFactory.TYPE_X11.equals(osType);
+ // boolean isWindows = NativeWindowFactory.TYPE_WINDOWS.equals(osType);
+
+ // int defaultMode = (isWindows ? WORKER : ( hasAWT ? AWT : WORKER ) );
+ int defaultMode = ( hasAWT ? AWT : WORKER );
+
+ mode = defaultMode;
+ if (workaround != null) {
+ workaround = workaround.toLowerCase();
+ if (workaround.equals("true") ||
+ workaround.equals("auto")) {
+ // Nothing to do; singleThreaded and mode already set up
+ } else if (workaround.equals("worker")) {
+ singleThreaded = true;
+ mode = WORKER;
+ } else if (workaround.equals("awt")) {
+ singleThreaded = true;
+ mode = AWT;
+ } else {
+ singleThreaded = false;
+ }
+ }
+ printWorkaroundNotice();
+
+ Object threadingPluginObj=null;
+ // try to fetch the AWTThreadingPlugin
+ try {
+ threadingPluginObj = ReflectionUtil.createInstance("com.jogamp.opengl.impl.awt.AWTThreadingPlugin");
+ } catch (JogampRuntimeException jre) { /* n/a .. */ }
+ return threadingPluginObj;
+ }
+ });
+ threadingPlugin = (ThreadingPlugin) threadingPluginTmp;
+ if(DEBUG) {
+ System.err.println("Threading: hasAWT "+hasAWT+", mode "+((mode==AWT)?"AWT":"WORKER")+", plugin "+threadingPlugin);
+ }
+ }
+
+ /** No reason to ever instantiate this class */
+ private ThreadingImpl() {}
+
+ public static boolean isX11() { return _isX11; }
+ public static int getMode() { return mode; }
+
+ /** If an implementation of the javax.media.opengl APIs offers a
+ multithreading option but the default behavior is single-threading,
+ this API provides a mechanism for end users to disable single-threading
+ in this implementation. Users are strongly discouraged from
+ calling this method unless they are aware of all of the
+ consequences and are prepared to enforce some amount of
+ threading restrictions in their applications. Disabling
+ single-threading, for example, may have unintended consequences
+ on GLAutoDrawable implementations such as GLCanvas, GLJPanel and
+ GLPbuffer. Currently there is no supported way to re-enable it
+ once disabled, partly to discourage careless use of this
+ method. This method should be called as early as possible in an
+ application. */
+ public static void disableSingleThreading() {
+ singleThreaded = false;
+ if (Debug.verbose()) {
+ System.err.println("Application forced disabling of single-threading of javax.media.opengl implementation");
+ }
+ }
+
+ /** Indicates whether OpenGL work is being automatically forced to a
+ single thread in this implementation. */
+ public static boolean isSingleThreaded() {
+ return singleThreaded;
+ }
+
+ /** Indicates whether the current thread is the single thread on
+ which this implementation of the javax.media.opengl APIs
+ performs all of its OpenGL-related work. This method should only
+ be called if the single-thread model is in effect. */
+ public static boolean isOpenGLThread() throws GLException {
+ if (!isSingleThreaded()) {
+ throw new GLException("Should only call this in single-threaded mode");
+ }
+
+ if(null!=threadingPlugin) {
+ return threadingPlugin.isOpenGLThread();
+ }
+
+ switch (mode) {
+ case AWT:
+ return true;
+ case WORKER:
+ return GLWorkerThread.isWorkerThread();
+ default:
+ throw new InternalError("Illegal single-threading mode " + mode);
+ }
+ }
+
+ /** Executes the passed Runnable on the single thread used for all
+ OpenGL work in this javax.media.opengl API implementation. It is
+ not specified exactly which thread is used for this
+ purpose. This method should only be called if the single-thread
+ model is in use and if the current thread is not the OpenGL
+ thread (i.e., if <code>isOpenGLThread()</code> returns
+ false). It is up to the end user to check to see whether the
+ current thread is the OpenGL thread and either execute the
+ Runnable directly or perform the work inside it. */
+ public static void invokeOnOpenGLThread(Runnable r) throws GLException {
+ if (!isSingleThreaded()) {
+ throw new GLException ("Should only call this in single-threaded mode");
+ }
+
+ if (isOpenGLThread()) {
+ throw new GLException ("Should only call this from other threads than the OpenGL thread");
+ }
+
+ if(null!=threadingPlugin) {
+ threadingPlugin.invokeOnOpenGLThread(r);
+ return;
+ }
+
+ switch (mode) {
+ case AWT:
+ r.run();
+ break;
+
+ case WORKER:
+ if (!GLWorkerThread.isStarted()) {
+ synchronized (GLWorkerThread.class) {
+ if (!GLWorkerThread.isStarted()) {
+ GLWorkerThread.start();
+ }
+ }
+ }
+ try {
+ GLWorkerThread.invokeAndWait(r);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ break;
+
+ default:
+ throw new InternalError("Illegal single-threading mode " + mode);
+ }
+ }
+
+ /** This is a workaround for AWT-related deadlocks which only seem
+ to show up in the context of applets */
+ public static boolean isAWTMode() {
+ return (mode == AWT);
+ }
+
+ private static void printWorkaroundNotice() {
+ if (singleThreaded && Debug.verbose()) {
+ System.err.println("Using " +
+ (mode == AWT ? "AWT" : "OpenGL worker") +
+ " thread for performing OpenGL work in javax.media.opengl implementation");
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/ThreadingPlugin.java b/src/jogl/classes/com/jogamp/opengl/impl/ThreadingPlugin.java
new file mode 100644
index 000000000..37e4aac70
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/ThreadingPlugin.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl;
+
+import javax.media.opengl.*;
+
+public interface ThreadingPlugin {
+ /** Indicates whether the current thread is the single thread on
+ which this implementation of the javax.media.opengl APIs
+ performs all of its OpenGL-related work. This method should only
+ be called if the single-thread model is in effect. */
+ public boolean isOpenGLThread() throws GLException;
+
+ /** Executes the passed Runnable on the single thread used for all
+ OpenGL work in this javax.media.opengl API implementation. It is
+ not specified exactly which thread is used for this
+ purpose. This method should only be called if the single-thread
+ model is in use and if the current thread is not the OpenGL
+ thread (i.e., if <code>isOpenGLThread()</code> returns
+ false). It is up to the end user to check to see whether the
+ current thread is the OpenGL thread and either execute the
+ Runnable directly or perform the work inside it. */
+ public void invokeOnOpenGLThread(Runnable r) throws GLException;
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTThreadingPlugin.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTThreadingPlugin.java
new file mode 100755
index 000000000..07bf2f2db
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTThreadingPlugin.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.awt;
+
+import javax.media.opengl.*;
+
+import java.awt.event.*;
+
+import java.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+
+import com.jogamp.opengl.impl.*;
+
+public class AWTThreadingPlugin implements ThreadingPlugin {
+
+ public AWTThreadingPlugin() {}
+
+ public boolean isOpenGLThread() throws GLException {
+ switch (ThreadingImpl.getMode()) {
+ case ThreadingImpl.AWT:
+ if (Java2D.isOGLPipelineActive()) {
+ // FIXME: ideally only the QFT would be considered to be the
+ // "OpenGL thread", but we can not currently run all of
+ // JOGL's OpenGL work on that thread. See the FIXME in
+ // invokeOnOpenGLThread.
+ return (Java2D.isQueueFlusherThread() ||
+ (ThreadingImpl.isX11() && EventQueue.isDispatchThread()));
+ } else {
+ return EventQueue.isDispatchThread();
+ }
+ case ThreadingImpl.WORKER:
+ if (Java2D.isOGLPipelineActive()) {
+ // FIXME: ideally only the QFT would be considered to be the
+ // "OpenGL thread", but we can not currently run all of
+ // JOGL's OpenGL work on that thread. See the FIXME in
+ // invokeOnOpenGLThread.
+ return (Java2D.isQueueFlusherThread() ||
+ (ThreadingImpl.isX11() && GLWorkerThread.isWorkerThread()));
+ } else {
+ return GLWorkerThread.isWorkerThread();
+ }
+ default:
+ throw new InternalError("Illegal single-threading mode " + ThreadingImpl.getMode());
+ }
+ }
+
+ public void invokeOnOpenGLThread(Runnable r) throws GLException {
+ switch (ThreadingImpl.getMode()) {
+ case ThreadingImpl.AWT:
+ // FIXME: ideally should run all OpenGL work on the Java2D QFT
+ // thread when it's enabled, but unfortunately there are
+ // deadlock issues on X11 platforms when making our
+ // heavyweight OpenGL contexts current on the QFT because we
+ // perform the JAWT lock inside the makeCurrent()
+ // implementation, which attempts to grab the AWT lock on the
+ // QFT which is not allowed. For now, on X11 platforms,
+ // continue to perform this work on the EDT.
+ if (Java2D.isOGLPipelineActive() && !ThreadingImpl.isX11()) {
+ Java2D.invokeWithOGLContextCurrent(null, r);
+ } else {
+ try {
+ EventQueue.invokeAndWait(r);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ }
+ break;
+
+ case ThreadingImpl.WORKER:
+ if (!GLWorkerThread.isStarted()) {
+ synchronized (GLWorkerThread.class) {
+ if (!GLWorkerThread.isStarted()) {
+ GLWorkerThread.start();
+ }
+ }
+ }
+ try {
+ GLWorkerThread.invokeAndWait(r);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ break;
+
+ default:
+ throw new InternalError("Illegal single-threading mode " + ThreadingImpl.getMode());
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java
new file mode 100644
index 000000000..e5570a8ee
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.impl.awt;
+
+import com.jogamp.nativewindow.impl.jawt.*;
+
+import com.jogamp.opengl.impl.*;
+
+import javax.media.opengl.*;
+
+import java.lang.reflect.*;
+import java.awt.GraphicsEnvironment;
+
+public class AWTUtil {
+ // See whether we're running in headless mode
+ private static boolean headlessMode;
+ private static Class j2dClazz = null;
+ private static Method isOGLPipelineActive = null;
+ private static Method isQueueFlusherThread = null;
+ private static boolean j2dOk = false;
+
+ static {
+ lockedToolkit = false;
+ headlessMode = GraphicsEnvironment.isHeadless();
+ if(!headlessMode) {
+ try {
+ j2dClazz = Class.forName("com.jogamp.opengl.impl.awt.Java2D");
+ isOGLPipelineActive = j2dClazz.getMethod("isOGLPipelineActive", null);
+ isQueueFlusherThread = j2dClazz.getMethod("isQueueFlusherThread", null);
+ j2dOk = true;
+ } catch (Exception e) {}
+ }
+ }
+
+ private static boolean lockedToolkit;
+
+ public static synchronized void lockToolkit() throws GLException {
+ if (lockedToolkit) {
+ throw new GLException("Toolkit already locked");
+ }
+ lockedToolkit = true;
+
+ if (headlessMode) {
+ // Workaround for running (to some degree) in headless
+ // environments but still supporting rendering via pbuffers
+ // For full correctness, would need to implement a Lock class
+ return;
+ }
+
+ if(j2dOk) {
+ try {
+ if( !((Boolean)isOGLPipelineActive.invoke(null, null)).booleanValue() ||
+ !((Boolean)isQueueFlusherThread.invoke(null, null)).booleanValue() ) {
+ JAWTUtil.lockToolkit();
+ }
+ } catch (Exception e) { j2dOk=false; }
+ }
+ if(!j2dOk) {
+ JAWTUtil.lockToolkit();
+ }
+ }
+
+ public static synchronized void unlockToolkit() {
+ if (lockedToolkit) {
+ lockedToolkit = false;
+ if (headlessMode) {
+ // Workaround for running (to some degree) in headless
+ // environments but still supporting rendering via pbuffers
+ // For full correctness, would need to implement a Lock class
+ return;
+ }
+
+ if(j2dOk) {
+ try {
+ if( !((Boolean)isOGLPipelineActive.invoke(null, null)).booleanValue() ||
+ !((Boolean)isQueueFlusherThread.invoke(null, null)).booleanValue() ) {
+ JAWTUtil.unlockToolkit();
+ }
+ } catch (Exception e) { j2dOk=false; }
+ }
+ if(!j2dOk) {
+ JAWTUtil.unlockToolkit();
+ }
+ }
+ }
+
+ public static boolean isToolkitLocked() {
+ return JAWTUtil.isToolkitLocked();
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java
new file mode 100755
index 000000000..b871c66a7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.awt;
+
+import com.jogamp.opengl.impl.*;
+
+import java.awt.*;
+import java.awt.image.*;
+import java.lang.reflect.*;
+import java.security.*;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+
+/** Defines integration with the Java2D OpenGL pipeline. This
+ integration is only supported in 1.6 and is highly experimental. */
+
+public class Java2D {
+ private static boolean DEBUG = Debug.debug("Java2D");
+ private static boolean VERBOSE = Debug.verbose();
+ private static boolean isHeadless;
+ private static boolean isOGLPipelineActive;
+ private static Method invokeWithOGLContextCurrentMethod;
+ private static Method isQueueFlusherThreadMethod;
+ private static Method getOGLViewportMethod;
+ private static Method getOGLScissorBoxMethod;
+ private static Method getOGLSurfaceIdentifierMethod;
+ // This one is currently optional and is only in very recent Mustang builds
+ private static Method getOGLTextureTypeMethod;
+
+ // The following methods and fields are needed for proper support of
+ // Frame Buffer Objects in the Java2D/OpenGL pipeline
+ // (-Dsun.java2d.opengl.fbobject=true)
+ private static boolean fbObjectSupportInitialized;
+ private static Method invokeWithOGLSharedContextCurrentMethod;
+ private static Method getOGLSurfaceTypeMethod;
+
+ // Publicly-visible constants for OpenGL surface types
+ public static final int UNDEFINED = getOGLUtilitiesIntField("UNDEFINED");
+ public static final int WINDOW = getOGLUtilitiesIntField("WINDOW");
+ public static final int PBUFFER = getOGLUtilitiesIntField("PBUFFER");
+ public static final int TEXTURE = getOGLUtilitiesIntField("TEXTURE");
+ public static final int FLIP_BACKBUFFER = getOGLUtilitiesIntField("FLIP_BACKBUFFER");
+ public static final int FBOBJECT = getOGLUtilitiesIntField("FBOBJECT");
+
+ // If FBOs are enabled in the Java2D/OpenGL pipeline, all contexts
+ // created by JOGL must share textures and display lists with the
+ // Java2D contexts in order to access the frame buffer object for
+ // potential rendering, and to simultaneously support sharing of
+ // textures and display lists with one another. Java2D has the
+ // notion of a single shared context with which all other contexts
+ // (on the same display device?) share textures and display lists;
+ // this is an approximation to that notion which will be refined
+ // later.
+ private static boolean initializedJ2DFBOShareContext;
+ private static GLContext j2dFBOShareContext;
+
+ // Accessors for new methods in sun.java2d.opengl.CGLSurfaceData
+ // class on OS X for enabling bridge
+ // public static long createOGLContextOnSurface(Graphics g, long ctx);
+ // public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx);
+ // public static void destroyOGLContext(long ctx);
+ private static Method createOGLContextOnSurfaceMethod;
+ private static Method makeOGLContextCurrentOnSurfaceMethod;
+ private static Method destroyOGLContextMethod;
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ if (DEBUG && VERBOSE) {
+ System.err.println("Checking for Java2D/OpenGL support");
+ }
+ try {
+ isHeadless = true;
+ // Figure out whether the default graphics configuration is an
+ // OpenGL graphics configuration
+ GraphicsConfiguration cfg =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().
+ getDefaultConfiguration();
+ // If we get here, we aren't running in headless mode
+ isHeadless = false;
+ String name = cfg.getClass().getName();
+ if (DEBUG && VERBOSE) {
+ System.err.println("Java2D support: default GraphicsConfiguration = " + name);
+ }
+ isOGLPipelineActive = (name.startsWith("sun.java2d.opengl"));
+
+ if (isOGLPipelineActive) {
+ try {
+ // Try to get methods we need to integrate
+ Class utils = Class.forName("sun.java2d.opengl.OGLUtilities");
+ invokeWithOGLContextCurrentMethod = utils.getDeclaredMethod("invokeWithOGLContextCurrent",
+ new Class[] {
+ Graphics.class,
+ Runnable.class
+ });
+ invokeWithOGLContextCurrentMethod.setAccessible(true);
+
+ isQueueFlusherThreadMethod = utils.getDeclaredMethod("isQueueFlusherThread",
+ new Class[] {});
+ isQueueFlusherThreadMethod.setAccessible(true);
+
+ getOGLViewportMethod = utils.getDeclaredMethod("getOGLViewport",
+ new Class[] {
+ Graphics.class,
+ Integer.TYPE,
+ Integer.TYPE
+ });
+ getOGLViewportMethod.setAccessible(true);
+
+ getOGLScissorBoxMethod = utils.getDeclaredMethod("getOGLScissorBox",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLScissorBoxMethod.setAccessible(true);
+
+ getOGLSurfaceIdentifierMethod = utils.getDeclaredMethod("getOGLSurfaceIdentifier",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLSurfaceIdentifierMethod.setAccessible(true);
+
+ // Try to get additional methods required for proper FBO support
+ fbObjectSupportInitialized = true;
+ try {
+ invokeWithOGLSharedContextCurrentMethod = utils.getDeclaredMethod("invokeWithOGLSharedContextCurrent",
+ new Class[] {
+ GraphicsConfiguration.class,
+ Runnable.class
+ });
+ invokeWithOGLSharedContextCurrentMethod.setAccessible(true);
+
+ getOGLSurfaceTypeMethod = utils.getDeclaredMethod("getOGLSurfaceType",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLSurfaceTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ fbObjectSupportInitialized = false;
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ System.err.println("Disabling Java2D/JOGL FBO support");
+ }
+ }
+
+ // Try to get an additional method for FBO support in recent Mustang builds
+ try {
+ getOGLTextureTypeMethod = utils.getDeclaredMethod("getOGLTextureType",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLTextureTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ System.err.println("GL_ARB_texture_rectangle FBO support disabled");
+ }
+ }
+
+ // Try to set up APIs for enabling the bridge on OS X,
+ // where it isn't possible to create generalized
+ // external GLDrawables
+ Class cglSurfaceData = null;
+ try {
+ cglSurfaceData = Class.forName("sun.java2d.opengl.CGLSurfaceData");
+ } catch (Exception e) {
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ System.err.println("Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X");
+ }
+ }
+ if (cglSurfaceData != null) {
+ // FIXME: for now, assume that FBO support is not enabled on OS X
+ fbObjectSupportInitialized = false;
+
+ // We need to find these methods in order to make the bridge work on OS X
+ createOGLContextOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("createOGLContextOnSurface",
+ new Class[] {
+ Graphics.class,
+ Long.TYPE
+ });
+ createOGLContextOnSurfaceMethod.setAccessible(true);
+
+ makeOGLContextCurrentOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("makeOGLContextCurrentOnSurface",
+ new Class[] {
+ Graphics.class,
+ Long.TYPE
+ });
+ makeOGLContextCurrentOnSurfaceMethod.setAccessible(true);
+
+ destroyOGLContextMethod = cglSurfaceData.getDeclaredMethod("destroyOGLContext",
+ new Class[] {
+ Long.TYPE
+ });
+ destroyOGLContextMethod.setAccessible(true);
+ }
+ } catch (Exception e) {
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ System.err.println("Disabling Java2D/JOGL integration");
+ }
+ isOGLPipelineActive = false;
+ }
+ }
+ } catch (HeadlessException e) {
+ // The AWT is running in headless mode, so the Java 2D / JOGL bridge is clearly disabled
+ }
+
+ if (DEBUG) {
+ System.err.println("JOGL/Java2D integration " + (isOGLPipelineActive ? "enabled" : "disabled"));
+ }
+ return null;
+ }
+ });
+ }
+
+ public static boolean isOGLPipelineActive() {
+ return isOGLPipelineActive;
+ }
+
+ public static boolean isFBOEnabled() {
+ return fbObjectSupportInitialized;
+ }
+
+ public static boolean isQueueFlusherThread() {
+ checkActive();
+
+ try {
+ return ((Boolean) isQueueFlusherThreadMethod.invoke(null, new Object[] {})).booleanValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Makes current the OpenGL context associated with the passed
+ Graphics object and runs the given Runnable on the Queue
+ Flushing Thread in one atomic action. */
+ public static void invokeWithOGLContextCurrent(Graphics g, Runnable r) throws GLException {
+ checkActive();
+
+ try {
+ // FIXME: this may need adjustment
+ // This seems to be needed in many applications which don't
+ // initialize an OpenGL context before this and which would
+ // otherwise cause initFBOShareContext to be called from the
+ // Queue Flusher Thread, which isn't allowed
+ initFBOShareContext(GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice());
+
+ AWTUtil.lockToolkit();
+ try {
+ invokeWithOGLContextCurrentMethod.invoke(null, new Object[] {g, r});
+ } finally {
+ AWTUtil.unlockToolkit();
+ }
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Makes current the "shared" OpenGL context associated with the
+ given GraphicsConfiguration object, allowing JOGL to share
+ server-side OpenGL objects like textures and display lists with
+ this context when necessary. This is needed when Java2D's FBO
+ support is enabled, because in order to render into that FBO,
+ JOGL must share textures and display lists with it. Returns
+ false if the passed GraphicsConfiguration was not an OpenGL
+ GraphicsConfiguration. */
+ public static boolean invokeWithOGLSharedContextCurrent(GraphicsConfiguration g, Runnable r) throws GLException {
+ checkActive();
+
+ try {
+ AWTUtil.lockToolkit();
+ try {
+ return ((Boolean) invokeWithOGLSharedContextCurrentMethod.invoke(null, new Object[] {g, r})).booleanValue();
+ } finally {
+ AWTUtil.unlockToolkit();
+ }
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns the OpenGL viewport associated with the given Graphics
+ object, assuming that the Graphics object is associated with a
+ component of the specified width and height. The user should
+ call glViewport() with the returned rectangle's bounds in order
+ to get correct rendering results. Should only be called from the
+ Queue Flusher Thread. */
+ public static Rectangle getOGLViewport(Graphics g,
+ int componentWidth,
+ int componentHeight) {
+ checkActive();
+
+ try {
+ return (Rectangle) getOGLViewportMethod.invoke(null, new Object[] {g,
+ new Integer(componentWidth),
+ new Integer(componentHeight)});
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns the OpenGL scissor region associated with the given
+ Graphics object, taking into account all clipping regions, etc.
+ To avoid destroying Java2D's previous rendering results, this
+ method should be called and the resulting rectangle's bounds
+ passed to a call to glScissor(). Should only be called from the
+ Queue Flusher Thread. */
+ public static Rectangle getOGLScissorBox(Graphics g) {
+ checkActive();
+
+ try {
+ return (Rectangle) getOGLScissorBoxMethod.invoke(null, new Object[] {g});
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns an opaque "surface identifier" associated with the given
+ Graphics object. If this changes from invocation to invocation,
+ the underlying OpenGL drawable for the Graphics object has
+ changed and a new external GLDrawable and GLContext should be
+ created (and the old ones destroyed). Should only be called from
+ the Queue Flusher Thread.*/
+ public static Object getOGLSurfaceIdentifier(Graphics g) {
+ checkActive();
+
+ try {
+ return getOGLSurfaceIdentifierMethod.invoke(null, new Object[] {g});
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns the underlying surface type for the given Graphics
+ object. This indicates, in particular, whether Java2D is
+ currently rendering into a pbuffer or FBO. */
+ public static int getOGLSurfaceType(Graphics g) {
+ checkActive();
+
+ try {
+ // FIXME: fallback path for pre-b73 (?) Mustang builds -- remove
+ // once fbobject support is in OGLUtilities
+ if (!fbObjectSupportInitialized) {
+ return 0;
+ }
+
+ return ((Integer) getOGLSurfaceTypeMethod.invoke(null, new Object[] { g })).intValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns the underlying texture target of the given Graphics
+ object assuming it is rendering to an FBO. Returns either
+ GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB. */
+ public static int getOGLTextureType(Graphics g) {
+ checkActive();
+
+ if (getOGLTextureTypeMethod == null) {
+ return GL.GL_TEXTURE_2D;
+ }
+
+ try {
+ return ((Integer) getOGLTextureTypeMethod.invoke(null, new Object[] { g })).intValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns either the given GLContext or a substitute one with
+ which clients should share textures and display lists. Needed
+ when the Java2D/OpenGL pipeline is active and FBOs are being
+ used for rendering. FIXME: may need to alter the API in the
+ future to indicate which GraphicsDevice the source context is
+ associated with. */
+ public static GLContext filterShareContext(GLContext shareContext) {
+ if (isHeadless)
+ return shareContext;
+
+ // FIXME: this may need adjustment
+ initFBOShareContext(GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice());
+ if (j2dFBOShareContext != null) {
+ return j2dFBOShareContext;
+ }
+ return shareContext;
+ }
+
+ /** Returns the GLContext associated with the Java2D "share
+ context", with which all contexts created by JOGL must share
+ textures and display lists when the FBO option is enabled for
+ the Java2D/OpenGL pipeline. */
+ public static GLContext getShareContext(GraphicsDevice device) {
+ initFBOShareContext(device);
+ // FIXME: for full generality probably need to have multiple of
+ // these, one per GraphicsConfiguration seen?
+ return j2dFBOShareContext;
+ }
+
+ //----------------------------------------------------------------------
+ // Mac OS X-specific methods
+ //
+
+ /** (Mac OS X-specific) Creates a new OpenGL context on the surface
+ associated with the given Graphics object, sharing textures and
+ display lists with the specified (CGLContextObj) share context. */
+ public static long createOGLContextOnSurface(Graphics g, long shareCtx) {
+ checkActive();
+
+ try {
+ return ((Long) createOGLContextOnSurfaceMethod.invoke(null, new Object[] { g, new Long(shareCtx) })).longValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** (Mac OS X-specific) Makes the given OpenGL context current on
+ the surface associated with the given Graphics object. */
+ public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx) {
+ checkActive();
+
+ try {
+ return ((Boolean) makeOGLContextCurrentOnSurfaceMethod.invoke(null, new Object[] { g, new Long(ctx) })).booleanValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** (Mac OS X-specific) Destroys the given OpenGL context. */
+ public static void destroyOGLContext(long ctx) {
+ checkActive();
+
+ try {
+ destroyOGLContextMethod.invoke(null, new Object[] { new Long(ctx) });
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static void checkActive() {
+ if (!isOGLPipelineActive()) {
+ throw new GLException("Java2D OpenGL pipeline not active (or necessary support not present)");
+ }
+ }
+
+ private static int getOGLUtilitiesIntField(final String name) {
+ Integer i = (Integer) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ Class utils = Class.forName("sun.java2d.opengl.OGLUtilities");
+ Field f = utils.getField(name);
+ f.setAccessible(true);
+ return f.get(null);
+ } catch (Exception e) {
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ }
+ });
+ if (i == null)
+ return 0;
+ if (DEBUG && VERBOSE) {
+ System.err.println("OGLUtilities." + name + " = " + i.intValue());
+ }
+ return i.intValue();
+ }
+
+ private static void initFBOShareContext(final GraphicsDevice device) {
+ // Note 1: this must not be done in the static initalizer due to
+ // deadlock problems.
+
+ // Note 2: the first execution of this method must not be from the
+ // Java2D Queue Flusher Thread.
+
+ if (isOGLPipelineActive() &&
+ isFBOEnabled() &&
+ !initializedJ2DFBOShareContext) {
+
+ // FIXME: this technique is probably not adequate in multi-head
+ // situations. Ideally we would keep track of a given share
+ // context on a per-GraphicsConfiguration basis or something
+ // similar rather than keeping one share context in a global
+ // variable.
+ initializedJ2DFBOShareContext = true;
+ if (DEBUG) {
+ System.err.println("Starting initialization of J2D FBO share context");
+ }
+ invokeWithOGLSharedContextCurrent(device.getDefaultConfiguration(), new Runnable() {
+ public void run() {
+ j2dFBOShareContext = GLDrawableFactory.getFactory(GLProfile.getDefault()).createExternalGLContext();
+ }
+ });
+ if (DEBUG) {
+ System.err.println("Ending initialization of J2D FBO share context");
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2DGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2DGLContext.java
new file mode 100644
index 000000000..07bc54b6a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2DGLContext.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.awt;
+
+import com.jogamp.opengl.impl.*;
+import java.awt.Graphics;
+
+/** Provides a construct by which the shared GLJPanel code can
+ * interact with a few methods in the Mac OS X-specific Java2D/JOGL
+ * bridge implementation.
+ */
+
+public interface Java2DGLContext {
+ public void setGraphics(Graphics g);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java
new file mode 100755
index 000000000..48f80977c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+import java.nio.*;
+import java.util.*;
+
+public abstract class EGLContext extends GLContextImpl {
+ private long eglContext;
+ private boolean eglQueryStringInitialized;
+ private boolean eglQueryStringAvailable;
+ private EGLExt eglExt;
+ // Table that holds the addresses of the native C-language entry points for
+ // EGL extension functions.
+ private EGLExtProcAddressTable eglExtProcAddressTable;
+
+ public EGLContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead,
+ GLContext shareWith) {
+ super(drawable, drawableRead, shareWith);
+ }
+
+ public EGLContext(GLDrawableImpl drawable,
+ GLContext shareWith) {
+ this(drawable, null, shareWith);
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getEGLExt();
+ }
+
+ public EGLExt getEGLExt() {
+ if (eglExt == null) {
+ eglExt = new EGLExtImpl(this);
+ }
+ return eglExt;
+ }
+
+ public final ProcAddressTable getPlatformExtProcAddressTable() {
+ return eglExtProcAddressTable;
+ }
+
+ public final EGLExtProcAddressTable getEGLExtProcAddressTable() {
+ return eglExtProcAddressTable;
+ }
+
+ protected Map/*<String, String>*/ getFunctionNameMap() { return null; }
+
+ protected Map/*<String, String>*/ getExtensionNameMap() { return null; }
+
+ public long getContext() {
+ return eglContext;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if(EGL.EGL_NO_DISPLAY==((EGLDrawable)drawable).getDisplay() ) {
+ throw new GLException("drawable not properly initialized: "+drawable);
+ }
+ boolean created = false;
+ if (eglContext == 0) {
+ create();
+ created = true;
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created GL context 0x" +
+ Long.toHexString(eglContext) + " for " + getClass().getName());
+ }
+ }
+ if (EGL.eglGetCurrentContext() != eglContext) {
+ if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
+ ((EGLDrawable)drawable).getSurface(),
+ ((EGLDrawable)drawableRead).getSurface(),
+ eglContext)) {
+ throw new GLException("Error making context 0x" +
+ Long.toHexString(eglContext) + " current: error code " + EGL.eglGetError());
+ }
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_ES|CTX_PROFILE_CORE|CTX_OPTION_ANY);
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
+ EGL.EGL_NO_SURFACE,
+ EGL.EGL_NO_SURFACE,
+ EGL.EGL_NO_CONTEXT)) {
+ throw new GLException("Error freeing OpenGL context 0x" +
+ Long.toHexString(eglContext) + ": error code " + EGL.eglGetError());
+ }
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ if (eglContext != 0) {
+ if (!EGL.eglDestroyContext(((EGLDrawable)drawable).getDisplay(), eglContext)) {
+ throw new GLException("Error destroying OpenGL context 0x" +
+ Long.toHexString(eglContext) + ": error code " + EGL.eglGetError());
+ }
+ eglContext = 0;
+ GLContextShareSet.contextDestroyed(this);
+ }
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) {
+ return 0; // FIXME
+ }
+
+ protected void destroyContextARBImpl(long _context) {
+ // FIXME
+ }
+
+ protected void create() throws GLException {
+ long eglDisplay = ((EGLDrawable)drawable).getDisplay();
+ EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration();
+ GLProfile glProfile = drawable.getGLProfile();
+ long eglConfig = config.getNativeConfig();
+ long shareWith = EGL.EGL_NO_CONTEXT;
+
+ if (eglDisplay == 0) {
+ throw new GLException("Error: attempted to create an OpenGL context without a display connection");
+ }
+ if (eglConfig == 0) {
+ throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration");
+ }
+
+ try {
+ // might be unavailable on EGL < 1.2
+ if(!EGL.eglBindAPI(EGL.EGL_OPENGL_ES_API)) {
+ throw new GLException("eglBindAPI to ES failed , error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ } catch (GLException glex) {
+ if (DEBUG) {
+ glex.printStackTrace();
+ }
+ }
+
+ EGLContext other = (EGLContext) GLContextShareSet.getShareContext(this);
+ if (other != null) {
+ shareWith = other.getContext();
+ if (shareWith == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+
+ int[] contextAttrs = new int[] {
+ EGL.EGL_CONTEXT_CLIENT_VERSION, -1,
+ EGL.EGL_NONE
+ };
+ if (glProfile.usesNativeGLES2()) {
+ contextAttrs[1] = 2;
+ } else if (glProfile.usesNativeGLES1()) {
+ contextAttrs[1] = 1;
+ } else {
+ throw new GLException("Error creating OpenGL context - invalid GLProfile: "+glProfile);
+ }
+ eglContext = EGL.eglCreateContext(eglDisplay, eglConfig, shareWith, contextAttrs, 0);
+ if (eglContext == 0) {
+ throw new GLException("Error creating OpenGL context: eglDisplay 0x"+Long.toHexString(eglDisplay)+
+ ", "+glProfile+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ GLContextShareSet.contextCreated(this);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created OpenGL context 0x" +
+ Long.toHexString(eglContext) +
+ ",\n\twrite surface 0x" + Long.toHexString(((EGLDrawable)drawable).getSurface()) +
+ ",\n\tread surface 0x" + Long.toHexString(((EGLDrawable)drawableRead).getSurface())+
+ ",\n\t"+this+
+ ",\n\tsharing with 0x" + Long.toHexString(shareWith));
+ }
+ if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
+ ((EGLDrawable)drawable).getSurface(),
+ ((EGLDrawable)drawableRead).getSurface(),
+ eglContext)) {
+ throw new GLException("Error making context 0x" +
+ Long.toHexString(eglContext) + " current: error code " + EGL.eglGetError());
+ }
+ setGLFunctionAvailability(true, glProfile.usesNativeGLES2()?2:1, 0, CTX_PROFILE_ES|CTX_PROFILE_CORE|CTX_OPTION_ANY);
+ }
+
+ public boolean isCreated() {
+ return (eglContext != 0);
+ }
+
+ protected void updateGLProcAddressTable(int major, int minor, int ctp) {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing EGL extension address table");
+ }
+ eglQueryStringInitialized = false;
+ eglQueryStringAvailable = false;
+
+ if (eglExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ eglExtProcAddressTable = new EGLExtProcAddressTable();
+ }
+ resetProcAddressTable(getEGLExtProcAddressTable());
+ super.updateGLProcAddressTable(major, minor, ctp);
+ }
+
+ public synchronized String getPlatformExtensionsString() {
+ if (!eglQueryStringInitialized) {
+ eglQueryStringAvailable =
+ getDrawableImpl().getDynamicLookupHelper().dynamicLookupFunction("eglQueryString") != 0;
+ eglQueryStringInitialized = true;
+ }
+ if (eglQueryStringAvailable) {
+ GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl();
+ factory.lockToolkit();
+ try {
+ String ret = EGL.eglQueryString(((EGLDrawable)drawable).getDisplay(),
+ EGL.EGL_EXTENSIONS);
+ if (DEBUG) {
+ System.err.println("!!! EGL extensions: " + ret);
+ }
+ return ret;
+ } finally {
+ factory.unlockToolkit();
+ }
+ } else {
+ return "";
+ }
+ }
+
+ protected void setSwapIntervalImpl(int interval) {
+ if (EGL.eglSwapInterval(((EGLDrawable)drawable).getDisplay(), interval)) {
+ currentSwapInterval = interval ;
+ }
+ }
+
+ public abstract void bindPbufferToTexture();
+
+ public abstract void releasePbufferFromTexture();
+
+ //----------------------------------------------------------------------
+ // Currently unimplemented stuff
+ //
+
+ public void copy(GLContext source, int mask) throws GLException {
+ throw new GLException("Not yet implemented");
+ }
+
+
+ public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ throw new GLException("Should not call this");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java
new file mode 100755
index 000000000..dcfe06bdc
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import com.jogamp.common.os.DynamicLookupHelper;
+import com.jogamp.opengl.impl.GLDrawableImpl;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+import javax.media.opengl.*;
+
+public abstract class EGLDrawable extends GLDrawableImpl {
+ protected boolean ownEGLDisplay = false; // for destruction
+ protected boolean ownEGLSurface = false; // for destruction
+ private EGLGraphicsConfiguration eglConfig;
+ protected long eglDisplay;
+ protected long eglSurface;
+
+ protected EGLDrawable(EGLDrawableFactory factory,
+ NativeWindow component) throws GLException {
+ super(factory, component, false);
+ eglSurface=EGL.EGL_NO_SURFACE;
+ eglDisplay=0;
+ }
+
+ public long getDisplay() {
+ return eglDisplay;
+ }
+
+ public long getSurface() {
+ return eglSurface;
+ }
+
+ public EGLGraphicsConfiguration getGraphicsConfiguration() {
+ return eglConfig;
+ }
+
+ public GLCapabilities getChosenGLCapabilities() {
+ return (null==eglConfig)?super.getChosenGLCapabilities():(GLCapabilities)eglConfig.getChosenCapabilities();
+ }
+
+ public abstract GLContext createContext(GLContext shareWith);
+
+ protected abstract long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle);
+
+ private void recreateSurface() {
+ // create a new EGLSurface ..
+ if(EGL.EGL_NO_SURFACE!=eglSurface) {
+ EGL.eglDestroySurface(eglDisplay, eglSurface);
+ }
+
+ if(DEBUG) {
+ System.err.println("createSurface using eglDisplay 0x"+Long.toHexString(eglDisplay)+", "+eglConfig);
+ }
+
+ eglSurface = createSurface(eglDisplay, eglConfig.getNativeConfig(), component.getSurfaceHandle());
+ if (EGL.EGL_NO_SURFACE==eglSurface) {
+ throw new GLException("Creation of window surface failed: "+eglConfig+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+
+ if(DEBUG) {
+ System.err.println("setSurface using component: handle 0x"+Long.toHexString(component.getSurfaceHandle())+" -> 0x"+Long.toHexString(eglSurface));
+ }
+ }
+
+ protected void setRealizedImpl() {
+ if (realized) {
+ if ( NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface() ) {
+ throw new GLException("Couldn't lock surface");
+ }
+ // lockSurface() also resolved the window/surface handles
+ try {
+ AbstractGraphicsConfiguration aConfig = component.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
+ if(aDevice instanceof EGLGraphicsDevice) {
+ // just fetch the data .. trust but verify ..
+ eglDisplay = aDevice.getHandle();
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Invalid EGL display in EGLGraphicsDevice from "+aDevice);
+ }
+ if(aConfig instanceof EGLGraphicsConfiguration) {
+ eglConfig = (EGLGraphicsConfiguration) aConfig; // done ..
+ if (null == eglConfig) {
+ throw new GLException("Null EGLGraphicsConfiguration from "+aConfig);
+ }
+
+ int[] tmp = new int[1];
+ if ( 0 != component.getSurfaceHandle() &&
+ EGL.eglQuerySurface(eglDisplay, component.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0) ) {
+ // component holds static EGLSurface
+ eglSurface = component.getSurfaceHandle();
+ if(DEBUG) {
+ System.err.println("setSurface re-using component's EGLSurface: handle 0x"+Long.toHexString(eglSurface));
+ }
+ } else {
+ // EGLSurface is ours ..
+ ownEGLSurface=true;
+
+ eglConfig.updateGraphicsConfiguration();
+
+ recreateSurface();
+ }
+ } else {
+ throw new GLException("EGLGraphicsDevice hold by non EGLGraphicsConfiguration: "+aConfig);
+ }
+ } else {
+ // create a new EGL config ..
+ ownEGLDisplay=true;
+ // EGLSurface is ours ..
+ ownEGLSurface=true;
+
+ long nDisplay=0;
+ if( NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) {
+ nDisplay = component.getSurfaceHandle(); // don't even ask ..
+ } else {
+ nDisplay = aDevice.getHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY
+ }
+ eglDisplay = EGL.eglGetDisplay(nDisplay);
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ if(DEBUG) {
+ System.err.println("eglDisplay("+Long.toHexString(nDisplay)+" <surfaceHandle>): failed, using EGL_DEFAULT_DISPLAY");
+ }
+ nDisplay = EGL.EGL_DEFAULT_DISPLAY;
+ eglDisplay = EGL.eglGetDisplay(nDisplay);
+ }
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Failed to created EGL display: nhandle 0x"+Long.toHexString(nDisplay)+", "+aDevice+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ } else if(DEBUG) {
+ System.err.println("eglDisplay("+Long.toHexString(nDisplay)+"): 0x"+Long.toHexString(eglDisplay));
+ }
+ if (!EGL.eglInitialize(eglDisplay, null, null)) {
+ throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ EGLGraphicsDevice e = new EGLGraphicsDevice(eglDisplay);
+ DefaultGraphicsScreen s = new DefaultGraphicsScreen(e, aConfig.getScreen().getIndex());
+ GLCapabilities caps = (GLCapabilities) aConfig.getChosenCapabilities(); // yes, use the already choosen Capabilities (x11,win32,..)
+ eglConfig = (EGLGraphicsConfiguration) GraphicsConfigurationFactory.getFactory(e).chooseGraphicsConfiguration(caps, null, s);
+ if (null == eglConfig) {
+ throw new GLException("Couldn't create EGLGraphicsConfiguration from "+s);
+ } else if(DEBUG) {
+ System.err.println("Chosen eglConfig: "+eglConfig);
+ }
+ recreateSurface();
+ }
+ } finally {
+ unlockSurface();
+ }
+ } else if (ownEGLSurface && eglSurface != EGL.EGL_NO_SURFACE) {
+ // Destroy the window surface
+ if (!EGL.eglDestroySurface(eglDisplay, eglSurface)) {
+ throw new GLException("Error destroying window surface (eglDestroySurface)");
+ }
+ eglSurface = EGL.EGL_NO_SURFACE;
+ if (ownEGLDisplay && EGL.EGL_NO_DISPLAY!=eglDisplay) {
+ EGL.eglTerminate(eglDisplay);
+ }
+ eglDisplay=EGL.EGL_NO_DISPLAY;
+ eglConfig=null;
+ }
+ }
+
+ public int getWidth() {
+ int[] tmp = new int[1];
+ if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, tmp, 0)) {
+ throw new GLException("Error querying surface width");
+ }
+ return tmp[0];
+ }
+
+ public int getHeight() {
+ int[] tmp = new int[1];
+ if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_HEIGHT, tmp, 0)) {
+ throw new GLException("Error querying surface height");
+ }
+ return tmp[0];
+ }
+
+ public DynamicLookupHelper getDynamicLookupHelper() {
+ return EGLDynamicLookupHelper.getDynamicLookupHelper(getGLProfile());
+ }
+
+ public String toString() {
+ return getClass().getName()+"[realized "+getRealized()+
+ ",\n\tfactory "+getFactory()+
+ ",\n\twindow "+getNativeWindow()+
+ ",\n\teglSurface 0x"+Long.toHexString(eglSurface)+
+ ",\n\teglConfig "+eglConfig+
+ ",\n\trequested "+getRequestedGLCapabilities()+
+ ",\n\tchosen "+getChosenGLCapabilities()+"]";
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
new file mode 100755
index 000000000..4fccf22f8
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.util.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+
+public class EGLDrawableFactory extends GLDrawableFactoryImpl {
+
+ static {
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ new EGLGraphicsConfigurationFactory();
+
+ // Check for other underlying stuff ..
+ if(NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+ try {
+ ReflectionUtil.createInstance("com.jogamp.opengl.impl.x11.glx.X11GLXGraphicsConfigurationFactory");
+ } catch (JogampRuntimeException jre) { /* n/a .. */ }
+ }
+ }
+
+ public EGLDrawableFactory() {
+ super();
+ }
+
+
+ protected final GLDrawableImpl getSharedDrawable() { return null; }
+ protected final GLContextImpl getSharedContext() { return null; }
+
+ public GLDrawableImpl createOnscreenDrawable(NativeWindow target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ return new EGLOnscreenDrawable(this, target);
+ }
+
+ protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) {
+ throw new GLException("Not yet implemented");
+ }
+
+ public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+ return true;
+ }
+
+ protected GLDrawableImpl createGLPbufferDrawableImpl(NativeWindow target) {
+ return new EGLPbufferDrawable(this, target);
+ }
+
+ protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
+ NullWindow nw = new NullWindow(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(capabilities, chooser));
+ nw.setSize(width, height);
+ return nw;
+ }
+
+ public GLContext createExternalGLContext() {
+ AbstractGraphicsScreen absScreen = DefaultGraphicsScreen.createScreenDevice(0);
+ return new EGLExternalContext(absScreen);
+ }
+
+ public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) {
+ return false;
+ }
+
+ public GLDrawable createExternalGLDrawable() {
+ throw new GLException("Not yet implemented");
+ }
+
+ public void loadGLULibrary() {
+ }
+
+ public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) {
+ return false;
+ }
+
+ public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ throw new GLException("Unimplemented on this platform");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLookupHelper.java
new file mode 100755
index 000000000..9e34dc9e9
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLookupHelper.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import com.jogamp.common.os.DynamicLookupHelper;
+import com.jogamp.common.os.NativeLibrary;
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import java.security.*;
+
+/**
+ * Abstract implementation of the DynamicLookupHelper for EGL,
+ * which decouples it's dependencies to EGLDrawableFactory.
+ *
+ * Currently two implementations exist, one for ES1 and one for ES2.
+ */
+public abstract class EGLDynamicLookupHelper implements DynamicLookupHelper {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("EGL");
+ protected static final boolean DEBUG_LOOKUP;
+
+ private static final EGLDynamicLookupHelper eglES1DynamicLookupHelper;
+ private static final EGLDynamicLookupHelper eglES2DynamicLookupHelper;
+ private List/*<NativeLibrary>*/ glesLibraries;
+
+ static {
+ AccessControlContext localACC=AccessController.getContext();
+ DEBUG_LOOKUP = com.jogamp.opengl.impl.Debug.isPropertyDefined("jogl.debug.DynamicLookup", true, localACC);
+
+ EGLDynamicLookupHelper tmp=null;
+ try {
+ tmp = new EGLES1DynamicLookupHelper();
+ } catch (GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
+ }
+ eglES1DynamicLookupHelper = tmp;
+
+ tmp=null;
+ try {
+ tmp = new EGLES2DynamicLookupHelper();
+ } catch (GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
+ }
+ eglES2DynamicLookupHelper = tmp;
+ }
+
+ public static EGLDynamicLookupHelper getDynamicLookupHelper(GLProfile glp) {
+ if (glp.usesNativeGLES2()) {
+ if(null==eglES2DynamicLookupHelper) {
+ throw new GLException("EGLDynamicLookupHelper for ES2 not available");
+ }
+ return eglES2DynamicLookupHelper;
+ } else if (glp.usesNativeGLES1()) {
+ if(null==eglES1DynamicLookupHelper) {
+ throw new GLException("EGLDynamicLookupHelper for ES1 not available");
+ }
+ return eglES1DynamicLookupHelper;
+ } else {
+ throw new GLException("Unsupported: "+glp);
+ }
+ }
+
+ public static EGLDynamicLookupHelper getDynamicLookupHelper(int esProfile) {
+ if (2==esProfile) {
+ if(null==eglES2DynamicLookupHelper) {
+ throw new GLException("EGLDynamicLookupHelper for ES2 not available");
+ }
+ return eglES2DynamicLookupHelper;
+ } else if (1==esProfile) {
+ if(null==eglES1DynamicLookupHelper) {
+ throw new GLException("EGLDynamicLookupHelper for ES1 not available");
+ }
+ return eglES1DynamicLookupHelper;
+ } else {
+ throw new GLException("Unsupported: ES"+esProfile);
+ }
+ }
+
+ protected EGLDynamicLookupHelper() {
+ loadGLESLibrary(getESProfile());
+ EGL.resetProcAddressTable(this);
+ }
+
+ /** Must return the proper ES profile number, 1 for ES1 and 2 for ES2 */
+ protected abstract int getESProfile();
+
+ /** Must return at least one OpenGL ES library name */
+ protected abstract List/*<String>*/ getGLESLibNames();
+
+ /** May return OpenGL ES library name(s) */
+ protected List/*<String>*/ getEGLLibNames() {
+ List/*<String>*/ eglLibNames = new ArrayList();
+
+ // EGL
+ eglLibNames.add("EGL");
+ // for windows distributions using the 'unlike' lib prefix,
+ // where our tool does not add it.
+ eglLibNames.add("libEGL");
+
+ return eglLibNames;
+ }
+
+ private NativeLibrary loadFirstAvailable(List/*<String>*/ libNames, ClassLoader loader) {
+ for (Iterator iter = libNames.iterator(); iter.hasNext(); ) {
+ NativeLibrary lib = NativeLibrary.open((String) iter.next(), loader, false /*global*/);
+ if (lib != null) {
+ return lib;
+ }
+ }
+ return null;
+ }
+
+ private boolean loadEGLLibrary(ClassLoader loader, List/*<String>*/ eglLibNames) {
+ NativeLibrary lib = null;
+ if(null!=eglLibNames && eglLibNames.size()>0) {
+ // EGL libraries ..
+ lib = loadFirstAvailable(eglLibNames, loader);
+ if ( null != lib ) {
+ glesLibraries.add(lib);
+ }
+ }
+ return null!=lib;
+ }
+
+ private void loadGLESLibrary(int esProfile) {
+ List/*<String>*/ glesLibNames = getGLESLibNames();
+ List/*<String>*/ eglLibNames = getEGLLibNames();
+ boolean eglLoaded = false;
+
+ ClassLoader loader = getClass().getClassLoader();
+ NativeLibrary lib = null;
+
+ glesLibraries = new ArrayList();
+
+ // ES libraries ..
+ lib = loadFirstAvailable(glesLibNames, loader);
+ if ( null == lib ) {
+ /*** FIXME: Have to think about this ..
+ // try again with EGL loaded first ..
+ if ( !eglLoaded && loadEGLLibrary(loader, eglLibNames) ) {
+ eglLoaded = true ;
+ lib = loadFirstAvailable(glesLibNames, loader);
+ }
+ if ( null == lib ) {
+ throw new GLException("Unable to dynamically load OpenGL ES library for profile ES" + esProfile);
+ } */
+ throw new GLException("Unable to dynamically load OpenGL ES library for profile ES" + esProfile);
+ }
+ glesLibraries.add(lib);
+
+ if ( !eglLoaded && !loadEGLLibrary(loader, eglLibNames) ) {
+ throw new GLException("Unable to dynamically load EGL library for profile ES" + esProfile);
+ }
+
+ if (esProfile==2) {
+ GLJNILibLoader.loadES2();
+ } else if (esProfile==1) {
+ GLJNILibLoader.loadES1();
+ } else {
+ throw new GLException("Unsupported: ES"+esProfile);
+ }
+ }
+
+ private long dynamicLookupFunctionOnLibs(String glFuncName) {
+ String funcName=glFuncName;
+ long addr = dynamicLookupFunctionOnLibsImpl(funcName);
+ if( 0==addr && NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) {
+ // Hack: try some C++ decoration here for Imageon's emulation libraries ..
+ final int argAlignment=4; // 4 byte alignment of each argument
+ final int maxArguments=12; // experience ..
+ for(int arg=0; 0==addr && arg<=maxArguments; arg++) {
+ funcName = "_"+glFuncName+"@"+(arg*argAlignment);
+ addr = dynamicLookupFunctionOnLibsImpl(funcName);
+ }
+ }
+ if(DEBUG_LOOKUP) {
+ if(0!=addr) {
+ System.err.println("Lookup-Native: "+glFuncName+" / "+funcName+" 0x"+Long.toHexString(addr));
+ } else {
+ System.err.println("Lookup-Native: "+glFuncName+" / "+funcName+" ** FAILED ** ");
+ }
+ }
+ return addr;
+ }
+
+ private long dynamicLookupFunctionOnLibsImpl(String glFuncName) {
+ // Look up this function name in all known libraries
+ for (Iterator iter = glesLibraries.iterator(); iter.hasNext(); ) {
+ NativeLibrary lib = (NativeLibrary) iter.next();
+ long addr = lib.dynamicLookupFunction(glFuncName);
+ if (addr != 0) {
+ return addr;
+ }
+ }
+ return 0;
+ }
+
+ private long eglGetProcAddressHandle = 0;
+
+ public long dynamicLookupFunction(String glFuncName) {
+ if(null==glFuncName) {
+ return 0;
+ }
+
+ // bootstrap eglGetProcAddress
+ if(0==eglGetProcAddressHandle) {
+ eglGetProcAddressHandle = dynamicLookupFunctionOnLibs("eglGetProcAddress");
+ if(0==eglGetProcAddressHandle) {
+ GLException e = new GLException("Couldn't find eglGetProcAddress function entry");
+ if(DEBUG) {
+ e.printStackTrace();
+ }
+ throw e;
+ }
+ }
+
+ if(glFuncName.equals("eglGetProcAddress")) {
+ return eglGetProcAddressHandle;
+ }
+
+ long addr = EGL.eglGetProcAddress(eglGetProcAddressHandle, glFuncName);
+ if(DEBUG_LOOKUP) {
+ if(0!=addr) {
+ System.err.println("Lookup-EGL: <"+glFuncName+"> 0x"+Long.toHexString(addr));
+ }
+ }
+ if(0==addr) {
+ addr = dynamicLookupFunctionOnLibs(glFuncName);
+ }
+ return addr;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLookupHelper.java
new file mode 100755
index 000000000..e5740a4f0
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLookupHelper.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import java.util.*;
+
+/**
+ * Implementation of the EGLDynamicLookupHelper for ES1.
+ */
+public class EGLES1DynamicLookupHelper extends EGLDynamicLookupHelper {
+
+ protected EGLES1DynamicLookupHelper() {
+ super();
+ }
+
+ protected int getESProfile() {
+ return 1;
+ }
+
+ protected List/*<String>*/ getGLESLibNames() {
+ List/*<String>*/ glesLibNames = new ArrayList();
+
+ glesLibNames.add("GLES_CM");
+ glesLibNames.add("GLES_CL");
+ glesLibNames.add("GLESv1_CM");
+ // for windows distributions using the 'unlike' lib prefix,
+ // where our tool does not add it.
+ glesLibNames.add("libGLES_CM");
+ glesLibNames.add("libGLES_CL");
+ glesLibNames.add("libGLESv1_CM");
+
+ return glesLibNames;
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLookupHelper.java
new file mode 100755
index 000000000..c4fc66630
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLookupHelper.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import java.util.*;
+
+/**
+ * Implementation of the EGLDynamicLookupHelper for ES2.
+ */
+public class EGLES2DynamicLookupHelper extends EGLDynamicLookupHelper {
+
+ protected EGLES2DynamicLookupHelper() {
+ super();
+ }
+
+ protected int getESProfile() {
+ return 2;
+ }
+
+ protected List/*<String>*/ getGLESLibNames() {
+ List/*<String>*/ glesLibNames = new ArrayList();
+
+ glesLibNames.add("GLES20");
+ glesLibNames.add("GLESv2");
+ glesLibNames.add("GLESv2_CM");
+ // for windows distributions using the 'unlike' lib prefix
+ // where our tool does not add it.
+ glesLibNames.add("libGLES20");
+ glesLibNames.add("libGLESv2");
+ glesLibNames.add("libGLESv2_CM");
+
+ return glesLibNames;
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java
new file mode 100755
index 000000000..5a8454ea7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import javax.media.nativewindow.*;
+
+public class EGLExternalContext extends EGLContext {
+ private boolean firstMakeCurrent = true;
+ private boolean created = true;
+ private GLContext lastContext;
+
+ public EGLExternalContext(AbstractGraphicsScreen screen) {
+ super(null, null);
+ GLContextShareSet.contextCreated(this);
+ setGLFunctionAvailability(false, 0, 0, CTX_IS_ARB_CREATED|CTX_PROFILE_ES|CTX_PROFILE_CORE|CTX_OPTION_ANY);
+ getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
+ }
+
+ public int makeCurrent() throws GLException {
+ // Save last context if necessary to allow external GLContexts to
+ // talk to other GLContexts created by this library
+ GLContext cur = getCurrent();
+ if (cur != null && cur != this) {
+ lastContext = cur;
+ setCurrent(null);
+ }
+ return super.makeCurrent();
+ }
+
+ public void release() throws GLException {
+ super.release();
+ setCurrent(lastContext);
+ lastContext = null;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ created = false;
+ GLContextShareSet.contextDestroyed(this);
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
new file mode 100644
index 000000000..2d5154442
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import com.jogamp.common.nio.PointerBuffer;
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+ protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+
+ public long getNativeConfig() {
+ return config;
+ }
+
+ public int getNativeConfigID() {
+ return configID;
+ }
+
+ public EGLGraphicsConfiguration(AbstractGraphicsScreen absScreen,
+ GLCapabilities capsChosen, GLCapabilities capsRequested, GLCapabilitiesChooser chooser,
+ long cfg, int cfgID) {
+ super(absScreen, capsChosen, capsRequested);
+ this.chooser = chooser;
+ config = cfg;
+ configID = cfgID;
+ }
+
+ public static EGLGraphicsConfiguration create(GLCapabilities capsRequested, AbstractGraphicsScreen absScreen, int cfgID) {
+ AbstractGraphicsDevice absDevice = absScreen.getDevice();
+ if(null==absDevice || !(absDevice instanceof EGLGraphicsDevice)) {
+ throw new GLException("GraphicsDevice must be a valid EGLGraphicsDevice");
+ }
+ long dpy = absDevice.getHandle();
+ if (dpy == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Invalid EGL display: "+absDevice);
+ }
+ GLProfile glp = capsRequested.getGLProfile();
+ long cfg = EGLConfigId2EGLConfig(glp, dpy, cfgID);
+ GLCapabilities caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer());
+ return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser(), cfg, cfgID);
+ }
+
+ public Object clone() {
+ return super.clone();
+ }
+
+ protected void updateGraphicsConfiguration() {
+ EGLGraphicsConfiguration newConfig = (EGLGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(getScreen().getDevice()).chooseGraphicsConfiguration(getRequestedCapabilities(),
+ chooser,
+ getScreen());
+ if(null!=newConfig) {
+ // FIXME: setScreen( ... );
+ setChosenCapabilities(newConfig.getChosenCapabilities());
+ config = newConfig.getNativeConfig();
+ configID = newConfig.getNativeConfigID();
+ if(DEBUG) {
+ System.err.println("!!! updateGraphicsConfiguration: "+this);
+ }
+ }
+ }
+
+ public static long EGLConfigId2EGLConfig(GLProfile glp, long display, int configID) {
+ int[] attrs = new int[] {
+ EGL.EGL_CONFIG_ID, configID,
+ EGL.EGL_NONE
+ };
+ PointerBuffer configs = PointerBuffer.allocateDirect(1);
+ int[] numConfigs = new int[1];
+ if (!EGL.eglChooseConfig(display,
+ attrs, 0,
+ configs, 1,
+ numConfigs, 0)) {
+ return 0;
+ }
+ if (numConfigs[0] == 0) {
+ return 0;
+ }
+ return configs.get(0);
+ }
+
+ public static boolean EGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) {
+ boolean res;
+
+ if ( onscreen ) {
+ res = ( 0 != (val & EGL.EGL_WINDOW_BIT) ) ;
+ } else {
+ if ( usePBuffer ) {
+ res = ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ;
+ } else {
+ res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) ;
+ }
+ }
+
+ return res;
+ }
+
+ public static GLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config,
+ boolean relaxed, boolean onscreen, boolean usePBuffer) {
+ GLCapabilities caps = new GLCapabilities(glp);
+ int[] val = new int[1];
+
+ // Read the actual configuration into the choosen caps
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_RED_SIZE, val, 0)) {
+ caps.setRedBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_GREEN_SIZE, val, 0)) {
+ caps.setGreenBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_BLUE_SIZE, val, 0)) {
+ caps.setBlueBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_ALPHA_SIZE, val, 0)) {
+ caps.setAlphaBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_STENCIL_SIZE, val, 0)) {
+ caps.setStencilBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_DEPTH_SIZE, val, 0)) {
+ caps.setDepthBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SAMPLES, val, 0)) {
+ caps.setSampleBuffers(val[0]>0?true:false);
+ caps.setNumSamples(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_TYPE, val, 0)) {
+ caps.setBackgroundOpaque(val[0] != EGL.EGL_TRANSPARENT_RGB);
+ }
+ if(!caps.isBackgroundOpaque()) {
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_RED_VALUE, val, 0)) {
+ caps.setTransparentRedValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_GREEN_VALUE, val, 0)) {
+ caps.setTransparentGreenValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_BLUE_VALUE, val, 0)) {
+ caps.setTransparentBlueValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]);
+ }
+ /** Not defined in EGL
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_ALPHA_VALUE, val, 0)) {
+ caps.setTransparentAlphaValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]);
+ } */
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, val, 0)) {
+ if(EGLConfigDrawableTypeVerify(val[0], onscreen, usePBuffer)) {
+ caps.setDoubleBuffered(onscreen);
+ caps.setOnscreen(onscreen);
+ caps.setPBuffer(usePBuffer);
+ } else if(relaxed) {
+ caps.setDoubleBuffered( 0 != (val[0] & EGL.EGL_WINDOW_BIT) );
+ caps.setOnscreen( 0 != (val[0] & EGL.EGL_WINDOW_BIT) );
+ caps.setPBuffer ( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) );
+ } else {
+ if(DEBUG) {
+ System.err.println("EGL_SURFACE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val[0] & EGL.EGL_WINDOW_BIT) )+", pbuffer "+( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) )+", pixmap "+( 0 != (val[0] & EGL.EGL_PIXMAP_BIT) )+")");
+ }
+ return null;
+ }
+ } else {
+ throw new GLException("Could not determine EGL_SURFACE_TYPE !!!");
+ }
+
+ return caps;
+ }
+
+ public static int[] GLCapabilities2AttribList(GLCapabilities caps) {
+ int[] attrs = new int[32];
+ int idx=0;
+
+ attrs[idx++] = EGL.EGL_SURFACE_TYPE;
+ attrs[idx++] = caps.isOnscreen() ? ( EGL.EGL_WINDOW_BIT ) : ( caps.isPBuffer() ? EGL.EGL_PBUFFER_BIT : EGL.EGL_PIXMAP_BIT ) ;
+
+ attrs[idx++] = EGL.EGL_RED_SIZE;
+ attrs[idx++] = caps.getRedBits();
+
+ attrs[idx++] = EGL.EGL_GREEN_SIZE;
+ attrs[idx++] = caps.getGreenBits();
+
+ attrs[idx++] = EGL.EGL_BLUE_SIZE;
+ attrs[idx++] = caps.getBlueBits();
+
+ attrs[idx++] = EGL.EGL_ALPHA_SIZE;
+ attrs[idx++] = caps.getAlphaBits() > 0 ? caps.getAlphaBits() : EGL.EGL_DONT_CARE;
+
+ attrs[idx++] = EGL.EGL_STENCIL_SIZE;
+ attrs[idx++] = caps.getStencilBits() > 0 ? caps.getStencilBits() : EGL.EGL_DONT_CARE;
+
+ attrs[idx++] = EGL.EGL_DEPTH_SIZE;
+ attrs[idx++] = caps.getDepthBits();
+
+ attrs[idx++] = EGL.EGL_SAMPLES;
+ attrs[idx++] = caps.getSampleBuffers() ? caps.getNumSamples() : 1;
+
+ attrs[idx++] = EGL.EGL_TRANSPARENT_TYPE;
+ attrs[idx++] = caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE;
+
+ // 20
+
+ if(!caps.isBackgroundOpaque()) {
+ attrs[idx++] = EGL.EGL_TRANSPARENT_RED_VALUE;
+ attrs[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():EGL.EGL_DONT_CARE;
+
+ attrs[idx++] = EGL.EGL_TRANSPARENT_GREEN_VALUE;
+ attrs[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():EGL.EGL_DONT_CARE;
+
+ attrs[idx++] = EGL.EGL_TRANSPARENT_BLUE_VALUE;
+ attrs[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():EGL.EGL_DONT_CARE;
+
+ /** Not define in EGL
+ attrs[idx++] = EGL.EGL_TRANSPARENT_ALPHA_VALUE;
+ attrs[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE; */
+ }
+
+ // 26
+
+ attrs[idx++] = EGL.EGL_RENDERABLE_TYPE;
+ if(caps.getGLProfile().usesNativeGLES1()) {
+ attrs[idx++] = EGL.EGL_OPENGL_ES_BIT;
+ }
+ else if(caps.getGLProfile().usesNativeGLES2()) {
+ attrs[idx++] = EGL.EGL_OPENGL_ES2_BIT;
+ } else {
+ attrs[idx++] = EGL.EGL_OPENGL_BIT;
+ }
+
+ // 28
+
+ attrs[idx++] = EGL.EGL_NONE;
+
+ return attrs;
+ }
+
+ public static int[] CreatePBufferSurfaceAttribList(int width, int height, int texFormat) {
+ int[] attrs = new int[16];
+ int idx=0;
+
+ attrs[idx++] = EGL.EGL_WIDTH;
+ attrs[idx++] = width;
+
+ attrs[idx++] = EGL.EGL_HEIGHT;
+ attrs[idx++] = height;
+
+ attrs[idx++] = EGL.EGL_TEXTURE_FORMAT;
+ attrs[idx++] = texFormat;
+
+ attrs[idx++] = EGL.EGL_TEXTURE_TARGET;
+ attrs[idx++] = EGL.EGL_NO_TEXTURE==texFormat ? EGL.EGL_NO_TEXTURE : EGL.EGL_TEXTURE_2D;
+
+ attrs[idx++] = EGL.EGL_NONE;
+
+ return attrs;
+ }
+
+ public String toString() {
+ return getClass().toString()+"["+getScreen()+", eglConfigID 0x"+Integer.toHexString(configID)+
+ ",\n\trequested " + getRequestedCapabilities()+
+ ",\n\tchosen " + getChosenCapabilities()+
+ "]";
+
+ }
+
+ private GLCapabilitiesChooser chooser;
+ private long config;
+ private int configID;
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..33e301ee9
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import com.jogamp.common.nio.PointerBuffer;
+import java.io.PrintStream;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+
+import javax.media.opengl.*;
+
+
+/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
+ are used on X11 platforms. Toolkits will likely need to delegate
+ to this one to change the accepted and returned types of the
+ GraphicsDevice and GraphicsConfiguration abstractions. */
+
+public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = GraphicsConfigurationFactory.DEBUG || com.jogamp.opengl.impl.Debug.debug("EGL");
+
+ public EGLGraphicsConfigurationFactory() {
+ // become the selector for KD/EGL ..
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.egl.EGLGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only AbstractGraphicsDevice objects");
+ }
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ return chooseGraphicsConfigurationStatic((GLCapabilities) capabilities,
+ (GLCapabilitiesChooser) chooser,
+ absScreen);
+ }
+
+ public static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ if (capabilities == null) {
+ capabilities = new GLCapabilities(null);
+ }
+ GLProfile glp = capabilities.getGLProfile();
+
+ if(null==absScreen) {
+ throw new GLException("Null AbstractGraphicsScreen");
+ }
+ AbstractGraphicsDevice absDevice = absScreen.getDevice();
+
+ if(null==absDevice || !(absDevice instanceof EGLGraphicsDevice)) {
+ throw new GLException("GraphicsDevice must be a valid EGLGraphicsDevice");
+ }
+ long eglDisplay = absDevice.getHandle();
+
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Invalid EGL display: "+absDevice);
+ }
+
+ GLCapabilities caps2 = (GLCapabilities) capabilities.clone();
+ if(!caps2.isOnscreen()) {
+ // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN
+ caps2.setDoubleBuffered(false);
+ }
+
+ EGLGraphicsConfiguration res = eglChooseConfig(eglDisplay, caps2, capabilities, chooser, absScreen);
+ if(null!=res) {
+ return res;
+ }
+ if(DEBUG) {
+ System.err.println("eglChooseConfig failed with given capabilities "+caps2);
+ }
+
+ if (chooser == null) {
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
+
+ PointerBuffer configs = PointerBuffer.allocateDirect(10);
+ int[] numConfigs = new int[1];
+
+ if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) {
+ throw new GLException("Graphics configuration fetch (eglGetConfigs) failed");
+ }
+ if (numConfigs[0] == 0) {
+ throw new GLException("Graphics configuration fetch (eglGetConfigs) - no EGLConfig found");
+ }
+ GLCapabilities[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0],
+ caps2.isOnscreen(), caps2.isPBuffer());
+ if(DEBUG) {
+ System.err.println("EGL Get Configs: "+numConfigs[0]+", Caps "+caps.length);
+ printCaps("eglGetConfigs", caps, System.err);
+ }
+ int chosen = -1;
+ try {
+ chosen = chooser.chooseCapabilities(caps2, caps, -1);
+ } catch (NativeWindowException e) { throw new GLException(e); }
+ if(chosen<0) {
+ throw new GLException("Graphics configuration chooser failed");
+ }
+ if(DEBUG) {
+ System.err.println("Chosen "+caps[chosen]);
+ }
+ res = eglChooseConfig(eglDisplay, caps[chosen], capabilities, chooser, absScreen);
+ if(null!=res) {
+ return res;
+ }
+ if(DEBUG) {
+ System.err.println("eglChooseConfig failed with eglGetConfig/choosen capabilities "+caps[chosen]);
+ }
+
+ // Last try .. add a fixed embedded profile [ATI, Nokia, Intel, ..]
+ //
+ // rgb888 - d16, s4
+ GLCapabilities fixedCaps = new GLCapabilities(glp);
+ fixedCaps.setRedBits(8);
+ fixedCaps.setGreenBits(8);
+ fixedCaps.setBlueBits(8);
+ fixedCaps.setDepthBits(16);
+ fixedCaps.setSampleBuffers(true);
+ fixedCaps.setNumSamples(4);
+ if(DEBUG) {
+ System.err.println("trying fixed caps (1): "+fixedCaps);
+ }
+ res = eglChooseConfig(eglDisplay, fixedCaps, capabilities, chooser, absScreen);
+ if(null!=res) {
+ return res;
+ }
+
+ //
+ // rgb565 - d16, s0
+ fixedCaps = new GLCapabilities(glp);
+ fixedCaps.setRedBits(5);
+ fixedCaps.setGreenBits(6);
+ fixedCaps.setBlueBits(5);
+ fixedCaps.setDepthBits(16);
+ if(DEBUG) {
+ System.err.println("trying fixed caps (2): "+fixedCaps);
+ }
+ res = eglChooseConfig(eglDisplay, fixedCaps, capabilities, chooser, absScreen);
+ if(null!=res) {
+ return res;
+ }
+
+ //
+ // rgb565 - d16, s4
+ fixedCaps = new GLCapabilities(glp);
+ fixedCaps.setRedBits(5);
+ fixedCaps.setGreenBits(6);
+ fixedCaps.setBlueBits(5);
+ fixedCaps.setDepthBits(16);
+ fixedCaps.setSampleBuffers(true);
+ fixedCaps.setNumSamples(4);
+ if(DEBUG) {
+ System.err.println("trying fixed caps (3): "+fixedCaps);
+ }
+ res = eglChooseConfig(eglDisplay, fixedCaps, capabilities, chooser, absScreen);
+ if(null!=res) {
+ return res;
+ }
+ throw new GLException("Graphics configuration failed [direct caps, eglGetConfig/chooser and fixed-caps(1-3)]");
+ }
+
+ protected static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay,
+ GLCapabilities capsChosen0, GLCapabilities capsRequested, GLCapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ GLProfile glp = capsChosen0.getGLProfile();
+ int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen0);
+ PointerBuffer configs = PointerBuffer.allocateDirect(1);
+ int[] numConfigs = new int[1];
+ if (!EGL.eglChooseConfig(eglDisplay,
+ attrs, 0,
+ configs, configs.capacity(),
+ numConfigs, 0)) {
+ throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen0);
+ }
+ if (numConfigs[0] > 0) {
+ if(DEBUG) {
+ GLCapabilities[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0],
+ capsChosen0.isOnscreen(), capsChosen0.isPBuffer());
+ System.err.println("EGL Choose Configs: "+numConfigs[0]+", Caps "+caps.length);
+ printCaps("eglChooseConfig", caps, System.err);
+ }
+ int[] val = new int[1];
+ // get the configID
+ if(!EGL.eglGetConfigAttrib(eglDisplay, configs.get(0), EGL.EGL_CONFIG_ID, val, 0)) {
+ if(DEBUG) {
+ // FIXME: this happens on a ATI PC Emulation ..
+ System.err.println("EGL couldn't retrieve ConfigID for already chosen eglConfig "+capsChosen0+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ return null;
+ }
+ GLCapabilities capsChosen1 = EGLGraphicsConfiguration.EGLConfig2Capabilities(glp, eglDisplay, configs.get(0),
+ true, capsChosen0.isOnscreen(), capsChosen0.isPBuffer());
+ if(null!=capsChosen1) {
+ if(DEBUG) {
+ System.err.println("eglChooseConfig found: eglDisplay 0x"+Long.toHexString(eglDisplay)+
+ ", eglConfig ID 0x"+Integer.toHexString(val[0])+
+ ", "+capsChosen0+" -> "+capsChosen1);
+ }
+ return new EGLGraphicsConfiguration(absScreen, capsChosen1, capsRequested, chooser, configs.get(0), val[0]);
+ }
+ if(DEBUG) {
+ System.err.println("eglChooseConfig couldn't verify: eglDisplay 0x"+Long.toHexString(eglDisplay)+
+ ", eglConfig ID 0x"+Integer.toHexString(val[0])+
+ ", for "+capsChosen0);
+ }
+ } else {
+ if(DEBUG) {
+ System.err.println("EGL Choose Configs: None using eglDisplay 0x"+Long.toHexString(eglDisplay)+
+ ", "+capsChosen0);
+ }
+ }
+ return null;
+ }
+
+ protected static GLCapabilities[] eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num,
+ boolean onscreen, boolean usePBuffer) {
+ GLCapabilities[] caps = new GLCapabilities[num];
+ for(int i=0; i<num; i++) {
+ caps[i] = EGLGraphicsConfiguration.EGLConfig2Capabilities(glp, eglDisplay, configs.get(i),
+ true, onscreen, usePBuffer);
+ }
+ return caps;
+ }
+
+ protected static void printCaps(String prefix, GLCapabilities[] caps, PrintStream out) {
+ for(int i=0; i<caps.length; i++) {
+ out.println(prefix+"["+i+"] "+caps[i]);
+ }
+ }
+
+ protected static EGLGraphicsConfiguration createOffscreenGraphicsConfiguration(GLCapabilities caps, GLCapabilitiesChooser chooser) {
+ if(caps.isOnscreen()) {
+ throw new GLException("Error: Onscreen set: "+caps);
+ }
+ caps.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
+ long eglDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Failed to created EGL default display: error 0x"+Integer.toHexString(EGL.eglGetError()));
+ } else if(DEBUG) {
+ System.err.println("eglDisplay(EGL_DEFAULT_DISPLAY): 0x"+Long.toHexString(eglDisplay));
+ }
+ if (!EGL.eglInitialize(eglDisplay, null, null)) {
+ throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ EGLGraphicsDevice e = new EGLGraphicsDevice(eglDisplay);
+ DefaultGraphicsScreen s = new DefaultGraphicsScreen(e, 0);
+ EGLGraphicsConfiguration eglConfig = chooseGraphicsConfigurationStatic(caps, chooser, s);
+ if (null == eglConfig) {
+ EGL.eglTerminate(eglDisplay);
+ throw new GLException("Couldn't create EGLGraphicsConfiguration from "+s);
+ } else if(DEBUG) {
+ System.err.println("Chosen eglConfig: "+eglConfig);
+ }
+ return eglConfig;
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java
new file mode 100755
index 000000000..b74991671
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+import java.nio.*;
+import java.util.*;
+
+public class EGLOnscreenContext extends EGLContext {
+ public EGLOnscreenContext(EGLOnscreenDrawable drawable, GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected int makeCurrentImpl() throws GLException {
+ int lockRes = drawable.lockSurface();
+ boolean exceptionOccurred = false;
+ try {
+ if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ return super.makeCurrentImpl();
+ } catch (RuntimeException e) {
+ exceptionOccurred = true;
+ throw e;
+ } finally {
+ if (exceptionOccurred ||
+ (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY) && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected void releaseImpl() throws GLException {
+ try {
+ super.releaseImpl();
+ } finally {
+ if (!isOptimizable() && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java
new file mode 100644
index 000000000..3864fc39c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+
+public class EGLOnscreenDrawable extends EGLDrawable {
+ protected EGLOnscreenDrawable(EGLDrawableFactory factory, NativeWindow component) throws GLException {
+ super(factory, component);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new EGLOnscreenContext(this, shareWith);
+ }
+
+ protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
+ return EGL.eglCreateWindowSurface(eglDpy, eglNativeCfg, surfaceHandle, null);
+ }
+
+ protected void swapBuffersImpl() {
+ boolean didLock = false;
+ if (!isSurfaceLocked()) {
+ // Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return;
+ }
+ didLock = true;
+ }
+ try {
+ EGL.eglSwapBuffers(eglDisplay, eglSurface);
+ } finally {
+ if (didLock) {
+ unlockSurface();
+ }
+ }
+ }
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferContext.java
new file mode 100755
index 000000000..5c634b9bd
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferContext.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+import java.nio.*;
+import java.util.*;
+
+public class EGLPbufferContext extends EGLContext {
+ public EGLPbufferContext(EGLPbufferDrawable drawable, GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ public int getFloatingPointMode() {
+ return 0; // FIXME ??
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Not yet implemented");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Not yet implemented");
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferDrawable.java
new file mode 100644
index 000000000..03b02b77e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferDrawable.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+import com.jogamp.opengl.impl.*;
+
+public class EGLPbufferDrawable extends EGLDrawable {
+ private int texFormat;
+ protected static final boolean useTexture = false; // No yet ..
+
+ protected EGLPbufferDrawable(EGLDrawableFactory factory, NativeWindow target) {
+ super(factory, target);
+ ownEGLDisplay = true;
+
+ // get choosen ones ..
+ GLCapabilities caps = (GLCapabilities) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+
+ if(useTexture) {
+ this.texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
+ } else {
+ this.texFormat = EGL.EGL_NO_TEXTURE;
+ }
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration());
+ }
+
+ setRealized(true);
+
+ if (DEBUG) {
+ System.out.println("Created pbuffer: " + this);
+ }
+
+ }
+
+ protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
+ NativeWindow nw = getNativeWindow();
+ int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(nw.getWidth(), nw.getHeight(), texFormat);
+ long surf = EGL.eglCreatePbufferSurface(eglDpy, eglNativeCfg, attrs, 0);
+ if (EGL.EGL_NO_SURFACE==surf) {
+ throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+nw.getWidth()+"x"+nw.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ } else if(DEBUG) {
+ System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
+ }
+ ((SurfaceChangeable)nw).setSurfaceHandle(surf);
+ return surf;
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new EGLPbufferContext(this, shareWith);
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java b/src/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java
new file mode 100755
index 000000000..2eb3ca5df
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java
@@ -0,0 +1,1041 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** $Date: 2009-03-13 22:20:29 -0700 (Fri, 13 Mar 2009) $ $Revision: 1867 $
+** $Header$
+*/
+
+/*
+ * Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'LWJGL' nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+package com.jogamp.opengl.impl.gl2;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+/**
+ * Project.java
+ * <p/>
+ * <p/>
+ * Created 11-jan-2004
+ *
+ * @author Erik Duijs
+ * @author Kenneth Russell
+ */
+public class ProjectDouble {
+ private static final double[] IDENTITY_MATRIX =
+ new double[] {
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0 };
+
+ // Note that we have cloned parts of the implementation in order to
+ // support incoming Buffers. The reason for this is to avoid loading
+ // non-direct buffer subclasses unnecessarily, because doing so can
+ // cause performance decreases on direct buffer operations, at least
+ // on the current HotSpot JVM. It would be nicer (and make the code
+ // simpler) to simply have the array-based entry points delegate to
+ // the versions taking Buffers by wrapping the arrays.
+
+ // Array-based implementation
+ private final double[] matrix = new double[16];
+
+ private final double[][] tempMatrix = new double[4][4];
+ private final double[] in = new double[4];
+ private final double[] out = new double[4];
+
+ private final double[] forward = new double[3];
+ private final double[] side = new double[3];
+ private final double[] up = new double[3];
+
+ // Buffer-based implementation
+ private DoubleBuffer locbuf;
+ private final DoubleBuffer matrixBuf;
+
+ private final DoubleBuffer tempMatrixBuf;
+ private final DoubleBuffer inBuf;
+ private final DoubleBuffer outBuf;
+
+ private final DoubleBuffer forwardBuf;
+ private final DoubleBuffer sideBuf;
+ private final DoubleBuffer upBuf;
+
+ public ProjectDouble() {
+ // Use direct buffers to avoid loading indirect buffer
+ // implementations for applications trying to avoid doing so.
+ // Slice up one big buffer because some NIO implementations
+ // allocate a huge amount of memory to back even the smallest of
+ // buffers.
+ DoubleBuffer locbuf = InternalBufferUtil.newDoubleBuffer(128);
+ int pos = 0;
+ int sz = 16;
+ matrixBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ tempMatrixBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sz = 4;
+ inBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ outBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sz = 3;
+ forwardBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sideBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ upBuf = slice(locbuf, pos, sz);
+ }
+
+ public void destroy() {
+ if(locbuf!=null) {
+ locbuf.clear();
+ locbuf=null;
+ }
+ }
+
+ private static DoubleBuffer slice(DoubleBuffer buf, int pos, int len) {
+ buf.position(pos);
+ buf.limit(pos + len);
+ return buf.slice();
+ }
+
+ /**
+ * Make matrix an identity matrix
+ */
+ private void __gluMakeIdentityd(DoubleBuffer m) {
+ int oldPos = m.position();
+ m.put(IDENTITY_MATRIX);
+ m.position(oldPos);
+ }
+
+ /**
+ * Make matrix an identity matrix
+ */
+ private void __gluMakeIdentityd(double[] m) {
+ for (int i = 0; i < 16; i++) {
+ m[i] = IDENTITY_MATRIX[i];
+ }
+ }
+
+ /**
+ * Method __gluMultMatrixVecd
+ *
+ * @param matrix
+ * @param in
+ * @param out
+ */
+ private void __gluMultMatrixVecd(double[] matrix, int matrix_offset, double[] in, double[] out) {
+ for (int i = 0; i < 4; i++) {
+ out[i] =
+ in[0] * matrix[0*4+i+matrix_offset] +
+ in[1] * matrix[1*4+i+matrix_offset] +
+ in[2] * matrix[2*4+i+matrix_offset] +
+ in[3] * matrix[3*4+i+matrix_offset];
+ }
+ }
+
+ /**
+ * Method __gluMultMatrixVecd
+ *
+ * @param matrix
+ * @param in
+ * @param out
+ */
+ private void __gluMultMatrixVecd(DoubleBuffer matrix, DoubleBuffer in, DoubleBuffer out) {
+ int inPos = in.position();
+ int outPos = out.position();
+ int matrixPos = matrix.position();
+ for (int i = 0; i < 4; i++) {
+ out.put(i + outPos,
+ in.get(0+inPos) * matrix.get(0*4+i+matrixPos) +
+ in.get(1+inPos) * matrix.get(1*4+i+matrixPos) +
+ in.get(2+inPos) * matrix.get(2*4+i+matrixPos) +
+ in.get(3+inPos) * matrix.get(3*4+i+matrixPos));
+ }
+ }
+
+ /**
+ * @param src
+ * @param inverse
+ *
+ * @return
+ */
+ private boolean __gluInvertMatrixd(double[] src, double[] inverse) {
+ int i, j, k, swap;
+ double t;
+ double[][] temp = tempMatrix;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ temp[i][j] = src[i*4+j];
+ }
+ }
+ __gluMakeIdentityd(inverse);
+
+ for (i = 0; i < 4; i++) {
+ //
+ // Look for largest element in column
+ //
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ //
+ // Swap rows.
+ //
+ for (k = 0; k < 4; k++) {
+ t = temp[i][k];
+ temp[i][k] = temp[swap][k];
+ temp[swap][k] = t;
+
+ t = inverse[i*4+k];
+ inverse[i*4+k] = inverse[swap*4+k];
+ inverse[swap*4+k] = t;
+ }
+ }
+
+ if (temp[i][i] == 0) {
+ //
+ // No non-zero pivot. The matrix is singular, which shouldn't
+ // happen. This means the user gave us a bad matrix.
+ //
+ return false;
+ }
+
+ t = temp[i][i];
+ for (k = 0; k < 4; k++) {
+ temp[i][k] /= t;
+ inverse[i*4+k] /= t;
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ t = temp[j][i];
+ for (k = 0; k < 4; k++) {
+ temp[j][k] -= temp[i][k] * t;
+ inverse[j*4+k] -= inverse[i*4+k]*t;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @param src
+ * @param inverse
+ *
+ * @return
+ */
+ private boolean __gluInvertMatrixd(DoubleBuffer src, DoubleBuffer inverse) {
+ int i, j, k, swap;
+ double t;
+
+ int srcPos = src.position();
+ int invPos = inverse.position();
+
+ DoubleBuffer temp = tempMatrixBuf;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ temp.put(i*4+j, src.get(i*4+j + srcPos));
+ }
+ }
+ __gluMakeIdentityd(inverse);
+
+ for (i = 0; i < 4; i++) {
+ //
+ // Look for largest element in column
+ //
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (Math.abs(temp.get(j*4+i)) > Math.abs(temp.get(i*4+i))) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ //
+ // Swap rows.
+ //
+ for (k = 0; k < 4; k++) {
+ t = temp.get(i*4+k);
+ temp.put(i*4+k, temp.get(swap*4+k));
+ temp.put(swap*4+k, t);
+
+ t = inverse.get(i*4+k + invPos);
+ inverse.put(i*4+k + invPos, inverse.get(swap*4+k + invPos));
+ inverse.put(swap*4+k + invPos, t);
+ }
+ }
+
+ if (temp.get(i*4+i) == 0) {
+ //
+ // No non-zero pivot. The matrix is singular, which shouldn't
+ // happen. This means the user gave us a bad matrix.
+ //
+ return false;
+ }
+
+ t = temp.get(i*4+i);
+ for (k = 0; k < 4; k++) {
+ temp.put(i*4+k, temp.get(i*4+k) / t);
+ inverse.put(i*4+k + invPos, inverse.get(i*4+k + invPos) / t);
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ t = temp.get(j*4+i);
+ for (k = 0; k < 4; k++) {
+ temp.put(j*4+k, temp.get(j*4+k) - temp.get(i*4+k) * t);
+ inverse.put(j*4+k + invPos, inverse.get(j*4+k + invPos) - inverse.get(i*4+k + invPos) * t);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * @param a
+ * @param b
+ * @param r
+ */
+ private void __gluMultMatricesd(double[] a, int a_offset, double[] b, int b_offset, double[] r) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ r[i*4+j] =
+ a[i*4+0+a_offset]*b[0*4+j+b_offset] +
+ a[i*4+1+a_offset]*b[1*4+j+b_offset] +
+ a[i*4+2+a_offset]*b[2*4+j+b_offset] +
+ a[i*4+3+a_offset]*b[3*4+j+b_offset];
+ }
+ }
+ }
+
+
+ /**
+ * @param a
+ * @param b
+ * @param r
+ */
+ private void __gluMultMatricesd(DoubleBuffer a, DoubleBuffer b, DoubleBuffer r) {
+ int aPos = a.position();
+ int bPos = b.position();
+ int rPos = r.position();
+
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ r.put(i*4+j + rPos,
+ a.get(i*4+0+aPos)*b.get(0*4+j+bPos) +
+ a.get(i*4+1+aPos)*b.get(1*4+j+bPos) +
+ a.get(i*4+2+aPos)*b.get(2*4+j+bPos) +
+ a.get(i*4+3+aPos)*b.get(3*4+j+bPos));
+ }
+ }
+ }
+
+ /**
+ * Normalize vector
+ *
+ * @param v
+ */
+ private static void normalize(double[] v) {
+ double r;
+
+ r = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+ if ( r == 0.0 )
+ return;
+
+ r = 1.0 / r;
+
+ v[0] *= r;
+ v[1] *= r;
+ v[2] *= r;
+
+ return;
+ }
+
+ /**
+ * Normalize vector
+ *
+ * @param v
+ */
+ private static void normalize(DoubleBuffer v) {
+ double r;
+
+ int vPos = v.position();
+
+ r = Math.sqrt(v.get(0+vPos) * v.get(0+vPos) +
+ v.get(1+vPos) * v.get(1+vPos) +
+ v.get(2+vPos) * v.get(2+vPos));
+ if ( r == 0.0 )
+ return;
+
+ r = 1.0 / r;
+
+ v.put(0+vPos, v.get(0+vPos) * r);
+ v.put(1+vPos, v.get(1+vPos) * r);
+ v.put(2+vPos, v.get(2+vPos) * r);
+
+ return;
+ }
+
+
+ /**
+ * Calculate cross-product
+ *
+ * @param v1
+ * @param v2
+ * @param result
+ */
+ private static void cross(double[] v1, double[] v2, double[] result) {
+ result[0] = v1[1] * v2[2] - v1[2] * v2[1];
+ result[1] = v1[2] * v2[0] - v1[0] * v2[2];
+ result[2] = v1[0] * v2[1] - v1[1] * v2[0];
+ }
+
+ /**
+ * Calculate cross-product
+ *
+ * @param v1
+ * @param v2
+ * @param result
+ */
+ private static void cross(DoubleBuffer v1, DoubleBuffer v2, DoubleBuffer result) {
+ int v1Pos = v1.position();
+ int v2Pos = v2.position();
+ int rPos = result.position();
+
+ result.put(0+rPos, v1.get(1+v1Pos) * v2.get(2+v2Pos) - v1.get(2+v1Pos) * v2.get(1+v2Pos));
+ result.put(1+rPos, v1.get(2+v1Pos) * v2.get(0+v2Pos) - v1.get(0+v1Pos) * v2.get(2+v2Pos));
+ result.put(2+rPos, v1.get(0+v1Pos) * v2.get(1+v2Pos) - v1.get(1+v1Pos) * v2.get(0+v2Pos));
+ }
+
+ /**
+ * Method gluOrtho2D.
+ *
+ * @param left
+ * @param right
+ * @param bottom
+ * @param top
+ */
+ public void gluOrtho2D(GL2 gl, double left, double right, double bottom, double top) {
+ gl.glOrtho(left, right, bottom, top, -1, 1);
+ }
+
+ /**
+ * Method gluPerspective.
+ *
+ * @param fovy
+ * @param aspect
+ * @param zNear
+ * @param zFar
+ */
+ public void gluPerspective(GL2 gl, double fovy, double aspect, double zNear, double zFar) {
+ double sine, cotangent, deltaZ;
+ double radians = fovy / 2 * Math.PI / 180;
+
+ deltaZ = zFar - zNear;
+ sine = Math.sin(radians);
+
+ if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
+ return;
+ }
+
+ cotangent = Math.cos(radians) / sine;
+
+ __gluMakeIdentityd(matrixBuf);
+
+ matrixBuf.put(0 * 4 + 0, cotangent / aspect);
+ matrixBuf.put(1 * 4 + 1, cotangent);
+ matrixBuf.put(2 * 4 + 2, - (zFar + zNear) / deltaZ);
+ matrixBuf.put(2 * 4 + 3, -1);
+ matrixBuf.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ);
+ matrixBuf.put(3 * 4 + 3, 0);
+
+ gl.glMultMatrixd(matrixBuf);
+ }
+
+ /**
+ * Method gluLookAt
+ *
+ * @param eyex
+ * @param eyey
+ * @param eyez
+ * @param centerx
+ * @param centery
+ * @param centerz
+ * @param upx
+ * @param upy
+ * @param upz
+ */
+ public void gluLookAt(GL2 gl,
+ double eyex,
+ double eyey,
+ double eyez,
+ double centerx,
+ double centery,
+ double centerz,
+ double upx,
+ double upy,
+ double upz) {
+ DoubleBuffer forward = this.forwardBuf;
+ DoubleBuffer side = this.sideBuf;
+ DoubleBuffer up = this.upBuf;
+
+ forward.put(0, centerx - eyex);
+ forward.put(1, centery - eyey);
+ forward.put(2, centerz - eyez);
+
+ up.put(0, upx);
+ up.put(1, upy);
+ up.put(2, upz);
+
+ normalize(forward);
+
+ /* Side = forward x up */
+ cross(forward, up, side);
+ normalize(side);
+
+ /* Recompute up as: up = side x forward */
+ cross(side, forward, up);
+
+ __gluMakeIdentityd(matrixBuf);
+ matrixBuf.put(0 * 4 + 0, side.get(0));
+ matrixBuf.put(1 * 4 + 0, side.get(1));
+ matrixBuf.put(2 * 4 + 0, side.get(2));
+
+ matrixBuf.put(0 * 4 + 1, up.get(0));
+ matrixBuf.put(1 * 4 + 1, up.get(1));
+ matrixBuf.put(2 * 4 + 1, up.get(2));
+
+ matrixBuf.put(0 * 4 + 2, -forward.get(0));
+ matrixBuf.put(1 * 4 + 2, -forward.get(1));
+ matrixBuf.put(2 * 4 + 2, -forward.get(2));
+
+ gl.glMultMatrixd(matrixBuf);
+ gl.glTranslated(-eyex, -eyey, -eyez);
+ }
+
+ /**
+ * Method gluProject
+ *
+ * @param objx
+ * @param objy
+ * @param objz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param win_pos
+ *
+ * @return
+ */
+ public boolean gluProject(double objx,
+ double objy,
+ double objz,
+ double[] modelMatrix,
+ int modelMatrix_offset,
+ double[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ double[] win_pos,
+ int win_pos_offset ) {
+
+ double[] in = this.in;
+ double[] out = this.out;
+
+ in[0] = objx;
+ in[1] = objy;
+ in[2] = objz;
+ in[3] = 1.0;
+
+ __gluMultMatrixVecd(modelMatrix, modelMatrix_offset, in, out);
+ __gluMultMatrixVecd(projMatrix, projMatrix_offset, out, in);
+
+ if (in[3] == 0.0)
+ return false;
+
+ in[3] = (1.0 / in[3]) * 0.5;
+
+ // Map x, y and z to range 0-1
+ in[0] = in[0] * in[3] + 0.5f;
+ in[1] = in[1] * in[3] + 0.5f;
+ in[2] = in[2] * in[3] + 0.5f;
+
+ // Map x,y to viewport
+ win_pos[0+win_pos_offset] = in[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset];
+ win_pos[1+win_pos_offset] = in[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset];
+ win_pos[2+win_pos_offset] = in[2];
+
+ return true;
+ }
+
+ /**
+ * Method gluProject
+ *
+ * @param objx
+ * @param objy
+ * @param objz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param win_pos
+ *
+ * @return
+ */
+ public boolean gluProject(double objx,
+ double objy,
+ double objz,
+ DoubleBuffer modelMatrix,
+ DoubleBuffer projMatrix,
+ IntBuffer viewport,
+ DoubleBuffer win_pos) {
+
+ DoubleBuffer in = this.inBuf;
+ DoubleBuffer out = this.outBuf;
+
+ in.put(0, objx);
+ in.put(1, objy);
+ in.put(2, objz);
+ in.put(3, 1.0);
+
+ __gluMultMatrixVecd(modelMatrix, in, out);
+ __gluMultMatrixVecd(projMatrix, out, in);
+
+ if (in.get(3) == 0.0)
+ return false;
+
+ in.put(3, (1.0 / in.get(3)) * 0.5);
+
+ // Map x, y and z to range 0-1
+ in.put(0, in.get(0) * in.get(3) + 0.5f);
+ in.put(1, in.get(1) * in.get(3) + 0.5f);
+ in.put(2, in.get(2) * in.get(3) + 0.5f);
+
+ // Map x,y to viewport
+ int vPos = viewport.position();
+ int wPos = win_pos.position();
+ win_pos.put(0+wPos, in.get(0) * viewport.get(2+vPos) + viewport.get(0+vPos));
+ win_pos.put(1+wPos, in.get(1) * viewport.get(3+vPos) + viewport.get(1+vPos));
+ win_pos.put(2+wPos, in.get(2));
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject(double winx,
+ double winy,
+ double winz,
+ double[] modelMatrix,
+ int modelMatrix_offset,
+ double[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ double[] obj_pos,
+ int obj_pos_offset) {
+ double[] in = this.in;
+ double[] out = this.out;
+
+ __gluMultMatricesd(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
+
+ if (!__gluInvertMatrixd(matrix, matrix))
+ return false;
+
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = 1.0;
+
+ // Map x and y from window coordinates
+ in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+
+ // Map to range -1 to 1
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
+
+ __gluMultMatrixVecd(matrix, 0, in, out);
+
+ if (out[3] == 0.0)
+ return false;
+
+ out[3] = 1.0 / out[3];
+
+ obj_pos[0+obj_pos_offset] = out[0] * out[3];
+ obj_pos[1+obj_pos_offset] = out[1] * out[3];
+ obj_pos[2+obj_pos_offset] = out[2] * out[3];
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject(double winx,
+ double winy,
+ double winz,
+ DoubleBuffer modelMatrix,
+ DoubleBuffer projMatrix,
+ IntBuffer viewport,
+ DoubleBuffer obj_pos) {
+ DoubleBuffer in = this.inBuf;
+ DoubleBuffer out = this.outBuf;
+
+ __gluMultMatricesd(modelMatrix, projMatrix, matrixBuf);
+
+ if (!__gluInvertMatrixd(matrixBuf, matrixBuf))
+ return false;
+
+ in.put(0, winx);
+ in.put(1, winy);
+ in.put(2, winz);
+ in.put(3, 1.0);
+
+ // Map x and y from window coordinates
+ int vPos = viewport.position();
+ int oPos = obj_pos.position();
+ in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
+ in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+
+ // Map to range -1 to 1
+ in.put(0, in.get(0) * 2 - 1);
+ in.put(1, in.get(1) * 2 - 1);
+ in.put(2, in.get(2) * 2 - 1);
+
+ __gluMultMatrixVecd(matrixBuf, in, out);
+
+ if (out.get(3) == 0.0)
+ return false;
+
+ out.put(3, 1.0 / out.get(3));
+
+ obj_pos.put(0+oPos, out.get(0) * out.get(3));
+ obj_pos.put(1+oPos, out.get(1) * out.get(3));
+ obj_pos.put(2+oPos, out.get(2) * out.get(3));
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject4
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param clipw
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param near
+ * @param far
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject4(double winx,
+ double winy,
+ double winz,
+ double clipw,
+ double[] modelMatrix,
+ int modelMatrix_offset,
+ double[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ double near,
+ double far,
+ double[] obj_pos,
+ int obj_pos_offset ) {
+ double[] in = this.in;
+ double[] out = this.out;
+
+ __gluMultMatricesd(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
+
+ if (!__gluInvertMatrixd(matrix, matrix))
+ return false;
+
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = clipw;
+
+ // Map x and y from window coordinates
+ in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+ in[2] = (in[2] - near) / (far - near);
+
+ // Map to range -1 to 1
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
+
+ __gluMultMatrixVecd(matrix, 0, in, out);
+
+ if (out[3] == 0.0)
+ return false;
+
+ obj_pos[0+obj_pos_offset] = out[0];
+ obj_pos[1+obj_pos_offset] = out[1];
+ obj_pos[2+obj_pos_offset] = out[2];
+ obj_pos[3+obj_pos_offset] = out[3];
+ return true;
+ }
+
+ /**
+ * Method gluUnproject4
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param clipw
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param near
+ * @param far
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject4(double winx,
+ double winy,
+ double winz,
+ double clipw,
+ DoubleBuffer modelMatrix,
+ DoubleBuffer projMatrix,
+ IntBuffer viewport,
+ double near,
+ double far,
+ DoubleBuffer obj_pos) {
+ DoubleBuffer in = this.inBuf;
+ DoubleBuffer out = this.outBuf;
+
+ __gluMultMatricesd(modelMatrix, projMatrix, matrixBuf);
+
+ if (!__gluInvertMatrixd(matrixBuf, matrixBuf))
+ return false;
+
+ in.put(0, winx);
+ in.put(1, winy);
+ in.put(2, winz);
+ in.put(3, clipw);
+
+ // Map x and y from window coordinates
+ int vPos = viewport.position();
+ in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
+ in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+ in.put(2, (in.get(2) - near) / (far - near));
+
+ // Map to range -1 to 1
+ in.put(0, in.get(0) * 2 - 1);
+ in.put(1, in.get(1) * 2 - 1);
+ in.put(2, in.get(2) * 2 - 1);
+
+ __gluMultMatrixVecd(matrixBuf, in, out);
+
+ if (out.get(3) == 0.0)
+ return false;
+
+ int oPos = obj_pos.position();
+ obj_pos.put(0+oPos, out.get(0));
+ obj_pos.put(1+oPos, out.get(1));
+ obj_pos.put(2+oPos, out.get(2));
+ obj_pos.put(3+oPos, out.get(3));
+ return true;
+ }
+
+
+ /**
+ * Method gluPickMatrix
+ *
+ * @param x
+ * @param y
+ * @param deltaX
+ * @param deltaY
+ * @param viewport
+ */
+ public void gluPickMatrix(GL2 gl,
+ double x,
+ double y,
+ double deltaX,
+ double deltaY,
+ IntBuffer viewport) {
+ if (deltaX <= 0 || deltaY <= 0) {
+ return;
+ }
+
+ /* Translate and scale the picked region to the entire window */
+ int vPos = viewport.position();
+ gl.glTranslated((viewport.get(2+vPos) - 2 * (x - viewport.get(0+vPos))) / deltaX,
+ (viewport.get(3+vPos) - 2 * (y - viewport.get(1+vPos))) / deltaY,
+ 0);
+ gl.glScaled(viewport.get(2) / deltaX, viewport.get(3) / deltaY, 1.0);
+ }
+
+ /**
+ * Method gluPickMatrix
+ *
+ * @param x
+ * @param y
+ * @param deltaX
+ * @param deltaY
+ * @param viewport
+ * @param viewport_offset
+ */
+ public void gluPickMatrix(GL2 gl,
+ double x,
+ double y,
+ double deltaX,
+ double deltaY,
+ int[] viewport,
+ int viewport_offset) {
+ if (deltaX <= 0 || deltaY <= 0) {
+ return;
+ }
+
+ /* Translate and scale the picked region to the entire window */
+ gl.glTranslated((viewport[2+viewport_offset] - 2 * (x - viewport[0+viewport_offset])) / deltaX,
+ (viewport[3+viewport_offset] - 2 * (y - viewport[1+viewport_offset])) / deltaY,
+ 0);
+ gl.glScaled(viewport[2+viewport_offset] / deltaX, viewport[3+viewport_offset] / deltaY, 1.0);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/gl2/Util.java b/src/jogl/classes/com/jogamp/opengl/impl/gl2/Util.java
new file mode 100644
index 000000000..a542dcf19
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/gl2/Util.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'LWJGL' nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.impl.gl2;
+
+import com.jogamp.opengl.impl.*;
+
+import java.nio.IntBuffer;
+import javax.media.opengl.*;
+
+/**
+ * Util.java
+ * <p/>
+ * <p/>
+ * Created 7-jan-2004
+ *
+ * @author Erik Duijs
+ */
+class Util {
+
+ /**
+ * temp int[] of one for getting an int from some GL functions
+ */
+ private int[] scratch = new int[1];
+
+ /**
+ * Return ceiling of integer division
+ *
+ * @param a
+ * @param b
+ *
+ * @return int
+ */
+ protected static int ceil(int a, int b) {
+ return (a % b == 0 ? a / b : a / b + 1);
+ }
+
+ /**
+ * Method compPerPix.
+ *
+ * @param format
+ *
+ * @return int
+ */
+ protected static int compPerPix(int format) {
+ /* Determine number of components per pixel */
+ switch ( format ) {
+ case GL2.GL_COLOR_INDEX:
+ case GL2.GL_STENCIL_INDEX:
+ case GL2.GL_DEPTH_COMPONENT:
+ case GL2.GL_RED:
+ case GL2.GL_GREEN:
+ case GL2.GL_BLUE:
+ case GL2.GL_ALPHA:
+ case GL2.GL_LUMINANCE:
+ return 1;
+ case GL2.GL_LUMINANCE_ALPHA:
+ return 2;
+ case GL2.GL_RGB:
+ case GL2.GL_BGR:
+ return 3;
+ case GL2.GL_RGBA:
+ case GL2.GL_BGRA:
+ return 4;
+ default :
+ return -1;
+ }
+ }
+
+ /**
+ * Method nearestPower.
+ * <p/>
+ * Compute the nearest power of 2 number. This algorithm is a little strange, but it works quite well.
+ *
+ * @param value
+ *
+ * @return int
+ */
+ protected static int nearestPower(int value) {
+ int i;
+
+ i = 1;
+
+ /* Error! */
+ if ( value == 0 )
+ return -1;
+
+ for ( ; ; ) {
+ if ( value == 1 ) {
+ return i;
+ } else if ( value == 3 ) {
+ return i << 2;
+ }
+ value >>= 1;
+ i <<= 1;
+ }
+ }
+
+ /**
+ * Method bytesPerPixel.
+ *
+ * @param format
+ * @param type
+ *
+ * @return int
+ */
+ protected static int bytesPerPixel(int format, int type) {
+ int n, m;
+
+ switch ( format ) {
+ case GL2.GL_COLOR_INDEX:
+ case GL2.GL_STENCIL_INDEX:
+ case GL2.GL_DEPTH_COMPONENT:
+ case GL2.GL_RED:
+ case GL2.GL_GREEN:
+ case GL2.GL_BLUE:
+ case GL2.GL_ALPHA:
+ case GL2.GL_LUMINANCE:
+ n = 1;
+ break;
+ case GL2.GL_LUMINANCE_ALPHA:
+ n = 2;
+ break;
+ case GL2.GL_RGB:
+ case GL2.GL_BGR:
+ n = 3;
+ break;
+ case GL2.GL_RGBA:
+ case GL2.GL_BGRA:
+ n = 4;
+ break;
+ default :
+ n = 0;
+ }
+
+ switch ( type ) {
+ case GL2.GL_UNSIGNED_BYTE:
+ m = 1;
+ break;
+ case GL2.GL_BYTE:
+ m = 1;
+ break;
+ case GL2.GL_BITMAP:
+ m = 1;
+ break;
+ case GL2.GL_UNSIGNED_SHORT:
+ m = 2;
+ break;
+ case GL2.GL_SHORT:
+ m = 2;
+ break;
+ case GL2.GL_UNSIGNED_INT:
+ m = 4;
+ break;
+ case GL2.GL_INT:
+ m = 4;
+ break;
+ case GL2.GL_FLOAT:
+ m = 4;
+ break;
+ default :
+ m = 0;
+ }
+
+ return n * m;
+ }
+
+ /**
+ * Convenience method for returning an int, rather than getting it out of a buffer yourself.
+ *
+ * @param what
+ *
+ * @return int
+ */
+ protected int glGetIntegerv(GL gl, int what) {
+ gl.glGetIntegerv(what, scratch, 0);
+ return scratch[0];
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/gl2/fixme/GLObjectTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/gl2/fixme/GLObjectTracker.java
new file mode 100755
index 000000000..3e3b6ae87
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/gl2/fixme/GLObjectTracker.java
@@ -0,0 +1,835 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.gl2;
+
+import com.jogamp.opengl.impl.*;
+
+import java.nio.*;
+import javax.media.opengl.*;
+
+/**
+ * Tracks the creation of server-side OpenGL objects which can be
+ * shared between contexts. Ordinarily, when an OpenGL context is
+ * deleted and no other contexts are sharing server-side objects with
+ * it, all of the server-side objects are automatically deleted by the
+ * OpenGL implementation. It is not necessary for the end user to
+ * explicitly delete these objects. However, when the Java2D/OpenGL
+ * pipeline is active and frame buffer objects are being used for
+ * rendering, it is necessary for all OpenGL contexts created by JOGL
+ * to share server-side objects with the Java2D OpenGL context. This
+ * means that these objects "leak" into the namespace used by Java2D.
+ * In order to prevent memory leaks and to present the same
+ * programming model to the end user, it is necessary to track the
+ * creation and destruction of all of these server-side OpenGL objects
+ * and to explicitly release them when all of the JOGL-created
+ * contexts which can see them have been released. <P>
+ *
+ * The {@link #ref ref} and {@link #unref unref} methods should be
+ * used during the creation and destruction of OpenGL contexts by JOGL
+ * in order to update the liveness of the objects being tracked. The
+ * various other methods should be called by the OpenGL binding in the
+ * various named methods.
+ */
+
+public class GLObjectTracker {
+ private static final boolean DEBUG = Debug.debug("GLObjectTracker");
+
+ //----------------------------------------------------------------------
+ // Adders
+ //
+
+ // glGenBuffers
+ public synchronized void addBuffers(int n, IntBuffer ids) {
+ add(getList(BUFFERS), n, ids);
+ }
+
+ // glGenBuffers
+ public synchronized void addBuffers(int n, int[] ids, int ids_offset) {
+ add(getList(BUFFERS), n, ids, ids_offset);
+ }
+
+ // glGenBuffersARB
+ public synchronized void addBuffersARB(int n, IntBuffer ids) {
+ add(getList(BUFFERS_ARB), n, ids);
+ }
+
+ // glGenBuffersARB
+ public synchronized void addBuffersARB(int n, int[] ids, int ids_offset) {
+ add(getList(BUFFERS_ARB), n, ids, ids_offset);
+ }
+
+ // glGenFencesAPPLE
+ public synchronized void addFencesAPPLE(int n, IntBuffer ids) {
+ add(getList(FENCES_APPLE), n, ids);
+ }
+
+ // glGenFencesAPPLE
+ public synchronized void addFencesAPPLE(int n, int[] ids, int ids_offset) {
+ add(getList(FENCES_APPLE), n, ids, ids_offset);
+ }
+
+ // glGenFencesNV
+ public synchronized void addFencesNV(int n, IntBuffer ids) {
+ add(getList(FENCES_NV), n, ids);
+ }
+
+ // glGenFencesNV
+ public synchronized void addFencesNV(int n, int[] ids, int ids_offset) {
+ add(getList(FENCES_NV), n, ids, ids_offset);
+ }
+
+ // glGenFragmentShadersATI
+ public synchronized void addFragmentShadersATI(int start, int n) {
+ add(getList(FRAGMENT_SHADERS_ATI), start, n);
+ }
+
+ // glGenFramebuffersEXT
+ public synchronized void addFramebuffersEXT(int n, IntBuffer ids) {
+ add(getList(FRAMEBUFFERS_EXT), n, ids);
+ }
+
+ // glGenFramebuffersEXT
+ public synchronized void addFramebuffersEXT(int n, int[] ids, int ids_offset) {
+ add(getList(FRAMEBUFFERS_EXT), n, ids, ids_offset);
+ }
+
+ // glGenLists
+ public synchronized void addLists(int start, int n) {
+ add(getList(LISTS), start, n);
+ }
+
+ // glGenOcclusionQueriesNV
+ public synchronized void addOcclusionQueriesNV(int n, IntBuffer ids) {
+ add(getList(OCCLUSION_QUERIES_NV), n, ids);
+ }
+
+ // glGenOcclusionQueriesNV
+ public synchronized void addOcclusionQueriesNV(int n, int[] ids, int ids_offset) {
+ add(getList(OCCLUSION_QUERIES_NV), n, ids, ids_offset);
+ }
+
+ // glCreateProgram
+ public synchronized void addProgramObject(int obj) {
+ add(getList(PROGRAM_OBJECTS), obj, 1);
+ }
+
+ // glCreateProgramObjectARB
+ public synchronized void addProgramObjectARB(int obj) {
+ add(getList(PROGRAM_AND_SHADER_OBJECTS_ARB), obj, 1);
+ }
+
+ // glGenProgramsARB
+ public synchronized void addProgramsARB(int n, IntBuffer ids) {
+ add(getList(PROGRAMS_ARB), n, ids);
+ }
+
+ // glGenProgramsARB
+ public synchronized void addProgramsARB(int n, int[] ids, int ids_offset) {
+ add(getList(PROGRAMS_ARB), n, ids, ids_offset);
+ }
+
+ // glGenProgramsNV
+ public synchronized void addProgramsNV(int n, IntBuffer ids) {
+ add(getList(PROGRAMS_NV), n, ids);
+ }
+
+ // glGenProgramsNV
+ public synchronized void addProgramsNV(int n, int[] ids, int ids_offset) {
+ add(getList(PROGRAMS_NV), n, ids, ids_offset);
+ }
+
+ // glGenQueries
+ public synchronized void addQueries(int n, IntBuffer ids) {
+ add(getList(QUERIES), n, ids);
+ }
+
+ // glGenQueries
+ public synchronized void addQueries(int n, int[] ids, int ids_offset) {
+ add(getList(QUERIES), n, ids, ids_offset);
+ }
+
+ // glGenQueriesARB
+ public synchronized void addQueriesARB(int n, IntBuffer ids) {
+ add(getList(QUERIES_ARB), n, ids);
+ }
+
+ // glGenQueriesARB
+ public synchronized void addQueriesARB(int n, int[] ids, int ids_offset) {
+ add(getList(QUERIES_ARB), n, ids, ids_offset);
+ }
+
+ // glGenRenderbuffersEXT
+ public synchronized void addRenderbuffersEXT(int n, IntBuffer ids) {
+ add(getList(RENDERBUFFERS_EXT), n, ids);
+ }
+
+ // glGenRenderbuffersEXT
+ public synchronized void addRenderbuffersEXT(int n, int[] ids, int ids_offset) {
+ add(getList(RENDERBUFFERS_EXT), n, ids, ids_offset);
+ }
+
+ // glCreateShader
+ public synchronized void addShaderObject(int obj) {
+ add(getList(SHADER_OBJECTS), obj, 1);
+ }
+
+ // glCreateShaderObjectARB
+ public synchronized void addShaderObjectARB(int obj) {
+ add(getList(PROGRAM_AND_SHADER_OBJECTS_ARB), obj, 1);
+ }
+
+ // glGenTextures
+ public synchronized void addTextures(int n, IntBuffer ids) {
+ add(getList(TEXTURES), n, ids);
+ }
+
+ // glGenTextures
+ public synchronized void addTextures(int n, int[] ids, int ids_offset) {
+ add(getList(TEXTURES), n, ids, ids_offset);
+ }
+
+ // glGenVertexArraysAPPLE
+ public synchronized void addVertexArraysAPPLE(int n, IntBuffer ids) {
+ add(getList(VERTEX_ARRAYS_APPLE), n, ids);
+ }
+
+ // glGenVertexArraysAPPLE
+ public synchronized void addVertexArraysAPPLE(int n, int[] ids, int ids_offset) {
+ add(getList(VERTEX_ARRAYS_APPLE), n, ids, ids_offset);
+ }
+
+ // glGenVertexShadersEXT
+ public synchronized void addVertexShadersEXT(int start, int n) {
+ add(getList(VERTEX_SHADERS_EXT), start, n);
+ }
+
+ //----------------------------------------------------------------------
+ // Removers
+ //
+
+ // glDeleteBuffers
+ public synchronized void removeBuffers(int n, IntBuffer ids) {
+ remove(getList(BUFFERS), n, ids);
+ }
+
+ // glDeleteBuffers
+ public synchronized void removeBuffers(int n, int[] ids, int ids_offset) {
+ remove(getList(BUFFERS), n, ids, ids_offset);
+ }
+
+ // glDeleteBuffersARB
+ public synchronized void removeBuffersARB(int n, IntBuffer ids) {
+ remove(getList(BUFFERS_ARB), n, ids);
+ }
+
+ // glDeleteBuffersARB
+ public synchronized void removeBuffersARB(int n, int[] ids, int ids_offset) {
+ remove(getList(BUFFERS_ARB), n, ids, ids_offset);
+ }
+
+ // glDeleteFencesAPPLE
+ public synchronized void removeFencesAPPLE(int n, IntBuffer ids) {
+ remove(getList(FENCES_APPLE), n, ids);
+ }
+
+ // glDeleteFencesAPPLE
+ public synchronized void removeFencesAPPLE(int n, int[] ids, int ids_offset) {
+ remove(getList(FENCES_APPLE), n, ids, ids_offset);
+ }
+
+ // glDeleteFencesNV
+ public synchronized void removeFencesNV(int n, IntBuffer ids) {
+ remove(getList(FENCES_NV), n, ids);
+ }
+
+ // glDeleteFencesNV
+ public synchronized void removeFencesNV(int n, int[] ids, int ids_offset) {
+ remove(getList(FENCES_NV), n, ids, ids_offset);
+ }
+
+ // glDeleteFragmentShaderATI
+ public synchronized void removeFragmentShaderATI(int obj) {
+ remove(getList(FRAGMENT_SHADERS_ATI), obj, 1);
+ }
+
+ // glDeleteFramebuffersEXT
+ public synchronized void removeFramebuffersEXT(int n, IntBuffer ids) {
+ remove(getList(FRAMEBUFFERS_EXT), n, ids);
+ }
+
+ // glDeleteFramebuffersEXT
+ public synchronized void removeFramebuffersEXT(int n, int[] ids, int ids_offset) {
+ remove(getList(FRAMEBUFFERS_EXT), n, ids, ids_offset);
+ }
+
+ // glDeleteLists
+ public synchronized void removeLists(int start, int n) {
+ remove(getList(LISTS), start, n);
+ }
+
+ // glDeleteOcclusionQueriesNV
+ public synchronized void removeOcclusionQueriesNV(int n, IntBuffer ids) {
+ remove(getList(OCCLUSION_QUERIES_NV), n, ids);
+ }
+
+ // glDeleteOcclusionQueriesNV
+ public synchronized void removeOcclusionQueriesNV(int n, int[] ids, int ids_offset) {
+ remove(getList(OCCLUSION_QUERIES_NV), n, ids, ids_offset);
+ }
+
+ // glDeleteProgram
+ public synchronized void removeProgramObject(int obj) {
+ remove(getList(PROGRAM_OBJECTS), obj, 1);
+ }
+
+ // glDeleteObjectARB
+ public synchronized void removeProgramOrShaderObjectARB(int obj) {
+ remove(getList(PROGRAM_AND_SHADER_OBJECTS_ARB), obj, 1);
+ }
+
+ // glDeleteProgramsARB
+ public synchronized void removeProgramsARB(int n, IntBuffer ids) {
+ remove(getList(PROGRAMS_ARB), n, ids);
+ }
+
+ // glDeleteProgramsARB
+ public synchronized void removeProgramsARB(int n, int[] ids, int ids_offset) {
+ remove(getList(PROGRAMS_ARB), n, ids, ids_offset);
+ }
+
+ // glDeleteProgramsNV
+ public synchronized void removeProgramsNV(int n, IntBuffer ids) {
+ remove(getList(PROGRAMS_NV), n, ids);
+ }
+
+ // glDeleteProgramsNV
+ public synchronized void removeProgramsNV(int n, int[] ids, int ids_offset) {
+ remove(getList(PROGRAMS_NV), n, ids, ids_offset);
+ }
+
+ // glDeleteQueries
+ public synchronized void removeQueries(int n, IntBuffer ids) {
+ remove(getList(QUERIES), n, ids);
+ }
+
+ // glDeleteQueries
+ public synchronized void removeQueries(int n, int[] ids, int ids_offset) {
+ remove(getList(QUERIES), n, ids, ids_offset);
+ }
+
+ // glDeleteQueriesARB
+ public synchronized void removeQueriesARB(int n, IntBuffer ids) {
+ remove(getList(QUERIES_ARB), n, ids);
+ }
+
+ // glDeleteQueriesARB
+ public synchronized void removeQueriesARB(int n, int[] ids, int ids_offset) {
+ remove(getList(QUERIES_ARB), n, ids, ids_offset);
+ }
+
+ // glDeleteRenderbuffersEXT
+ public synchronized void removeRenderbuffersEXT(int n, IntBuffer ids) {
+ remove(getList(RENDERBUFFERS_EXT), n, ids);
+ }
+
+ // glDeleteRenderbuffersEXT
+ public synchronized void removeRenderbuffersEXT(int n, int[] ids, int ids_offset) {
+ remove(getList(RENDERBUFFERS_EXT), n, ids, ids_offset);
+ }
+
+ // glDeleteShader
+ public synchronized void removeShaderObject(int obj) {
+ remove(getList(SHADER_OBJECTS), obj, 1);
+ }
+
+ // glDeleteTextures
+ public synchronized void removeTextures(int n, IntBuffer ids) {
+ remove(getList(TEXTURES), n, ids);
+ }
+
+ // glDeleteTextures
+ public synchronized void removeTextures(int n, int[] ids, int ids_offset) {
+ remove(getList(TEXTURES), n, ids, ids_offset);
+ }
+
+ // glDeleteVertexArraysAPPLE
+ public synchronized void removeVertexArraysAPPLE(int n, IntBuffer ids) {
+ remove(getList(VERTEX_ARRAYS_APPLE), n, ids);
+ }
+
+ // glDeleteVertexArraysAPPLE
+ public synchronized void removeVertexArraysAPPLE(int n, int[] ids, int ids_offset) {
+ remove(getList(VERTEX_ARRAYS_APPLE), n, ids, ids_offset);
+ }
+
+ // glDeleteVertexShaderEXT
+ public synchronized void removeVertexShaderEXT(int obj) {
+ remove(getList(VERTEX_SHADERS_EXT), obj, 1);
+ }
+
+ //----------------------------------------------------------------------
+ // Reference count maintenance and manual deletion
+ //
+
+ public synchronized void transferAll(GLObjectTracker other) {
+ for (int i = 0; i < lists.length; i++) {
+ getList(i).addAll(other.lists[i]);
+ if (other.lists[i] != null) {
+ other.lists[i].clear();
+ }
+ }
+ dirty = true;
+ }
+
+ public synchronized void ref() {
+ ++refCount;
+ }
+
+ public void unref(GLObjectTracker deletedObjectPool) {
+ boolean tryDelete = false;
+ synchronized (this) {
+ if (--refCount == 0) {
+ tryDelete = true;
+ }
+ }
+ if (tryDelete) {
+ // See whether we should try to do the work now or whether we
+ // have to postpone
+ GLContext cur = GLContext.getCurrent();
+ if ((cur != null) &&
+ (cur instanceof GLContextImpl)) {
+ GLContextImpl curImpl = (GLContextImpl) cur;
+ if (deletedObjectPool != null &&
+ deletedObjectPool == curImpl.getDeletedObjectTracker()) {
+ // Should be safe to delete these objects now
+ try {
+ delete((GL2)curImpl.getGL());
+ return;
+ } catch (GLException e) {
+ // Shouldn't happen, but if it does, transfer all objects
+ // to the deleted object pool hoping we can later clean
+ // them up
+ deletedObjectPool.transferAll(this);
+ throw(e);
+ }
+ }
+ }
+ // If we get here, we couldn't attempt to delete the objects
+ // right now; instead try to transfer them to the
+ // deletedObjectPool for later cleanup (FIXME: should consider
+ // throwing an exception if deletedObjectPool is null, since
+ // that shouldn't happen)
+ if (DEBUG) {
+ String s = null;
+ if (cur == null) {
+ s = "current context was null";
+ } else if (!(cur instanceof GLContextImpl)) {
+ s = "current context was not a GLContextImpl";
+ } else if (deletedObjectPool == null) {
+ s = "no current deletedObjectPool";
+ } else if (deletedObjectPool != ((GLContextImpl) cur).getDeletedObjectTracker()) {
+ s = "deletedObjectTracker didn't match";
+ if (((GLContextImpl) cur).getDeletedObjectTracker() == null) {
+ s += " (other was null)";
+ }
+ } else {
+ s = "unknown reason";
+ }
+ System.err.println("Deferred destruction of server-side OpenGL objects into " + deletedObjectPool + ": " + s);
+ }
+
+ if (deletedObjectPool != null) {
+ deletedObjectPool.transferAll(this);
+ }
+ }
+ }
+
+ public void clean(GL2 gl) {
+ if (dirty) {
+ try {
+ delete(gl);
+ dirty = false;
+ } catch (GLException e) {
+ // FIXME: not sure what to do here; probably a bad idea to be
+ // throwing exceptions during an otherwise-successful makeCurrent
+ }
+ }
+ }
+
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // Kinds of sharable server-side OpenGL objects this class tracks
+ private static final int BUFFERS = 0;
+ private static final int BUFFERS_ARB = 1;
+ private static final int FENCES_APPLE = 2;
+ private static final int FENCES_NV = 3;
+ private static final int FRAGMENT_SHADERS_ATI = 4;
+ private static final int FRAMEBUFFERS_EXT = 5;
+ private static final int LISTS = 6;
+ private static final int OCCLUSION_QUERIES_NV = 7;
+ private static final int PROGRAM_AND_SHADER_OBJECTS_ARB = 8;
+ private static final int PROGRAM_OBJECTS = 9;
+ private static final int PROGRAMS_ARB = 10;
+ private static final int PROGRAMS_NV = 11;
+ private static final int QUERIES = 12;
+ private static final int QUERIES_ARB = 13;
+ private static final int RENDERBUFFERS_EXT = 14;
+ private static final int SHADER_OBJECTS = 15;
+ private static final int TEXTURES = 16;
+ private static final int VERTEX_ARRAYS_APPLE = 17;
+ private static final int VERTEX_SHADERS_EXT = 18;
+ private static final int NUM_OBJECT_TYPES = 19;
+
+ static abstract class Deleter {
+ public abstract void delete(GL2 gl, int obj);
+ }
+
+ static class ObjectList {
+ private static final int MIN_CAPACITY = 4;
+
+ private int size;
+ private int capacity;
+ private int[] data;
+ private Deleter deleter;
+ private String name;
+
+ public ObjectList(Deleter deleter) {
+ this.deleter = deleter;
+ clear();
+ }
+
+ public void add(int obj) {
+ if (size == capacity) {
+ int newCapacity = 2 * capacity;
+ int[] newData = new int[newCapacity];
+ System.arraycopy(data, 0, newData, 0, size);
+ data = newData;
+ capacity = newCapacity;
+ }
+
+ data[size++] = obj;
+ }
+
+ public void addAll(ObjectList other) {
+ if (other == null) {
+ return;
+ }
+ for (int i = 0; i < other.size; i++) {
+ add(other.data[i]);
+ }
+ }
+
+ public boolean remove(int value) {
+ for (int i = 0; i < size; i++) {
+ if (data[i] == value) {
+ if (i < size - 1) {
+ System.arraycopy(data, i+1, data, i, size - i - 1);
+ }
+ --size;
+ if ((size < capacity / 4) &&
+ (capacity > MIN_CAPACITY)) {
+ int newCapacity = capacity / 4;
+ if (newCapacity < MIN_CAPACITY) {
+ newCapacity = MIN_CAPACITY;
+ }
+ int[] newData = new int[newCapacity];
+ System.arraycopy(data, 0, newData, 0, size);
+ data = newData;
+ capacity = newCapacity;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setName(String name) {
+ if (DEBUG) {
+ this.name = name;
+ }
+ }
+
+ public void delete(GL2 gl) {
+ // Just in case we start throwing exceptions during deletion,
+ // make sure we make progress rather than going into an infinite
+ // loop
+ while (size > 0) {
+ int obj = data[size - 1];
+ --size;
+ if (DEBUG) {
+ System.err.println("Deleting server-side OpenGL object " + obj +
+ ((name != null) ? (" (" + name + ")") : ""));
+ }
+ deleter.delete(gl, obj);
+ }
+ }
+
+ public void clear() {
+ size = 0;
+ capacity = MIN_CAPACITY;
+ data = new int[capacity];
+ }
+ }
+
+ private ObjectList[] lists = new ObjectList[NUM_OBJECT_TYPES];
+ private int refCount;
+ private boolean dirty;
+
+ private void add(ObjectList list, int n, IntBuffer ids) {
+ int pos = ids.position();
+ for (int i = 0; i < n; i++) {
+ list.add(ids.get(pos + i));
+ }
+ }
+
+ private void add(ObjectList list, int n, int[] ids, int ids_offset) {
+ for (int i = 0; i < n; i++) {
+ list.add(ids[i + ids_offset]);
+ }
+ }
+
+ private void add(ObjectList list, int start, int n) {
+ for (int i = 0; i < n; i++) {
+ list.add(start + i);
+ }
+ }
+
+ private void remove(ObjectList list, int n, IntBuffer ids) {
+ int pos = ids.position();
+ for (int i = 0; i < n; i++) {
+ list.remove(ids.get(pos + i));
+ }
+ }
+
+ private void remove(ObjectList list, int n, int[] ids, int ids_offset) {
+ for (int i = 0; i < n; i++) {
+ list.remove(ids[i + ids_offset]);
+ }
+ }
+
+ private void remove(ObjectList list, int start, int n) {
+ for (int i = 0; i < n; i++) {
+ list.remove(start + i);
+ }
+ }
+
+ private ObjectList getList(int which) {
+ ObjectList list = lists[which];
+ if (list == null) {
+ Deleter deleter = null;
+ String name = null;
+ // Figure out which deleter we need
+ switch (which) {
+ case BUFFERS:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteBuffers(1, new int[] { obj }, 0);
+ }
+ };
+ name = "buffer";
+ break;
+ case BUFFERS_ARB:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteBuffersARB(1, new int[] { obj }, 0);
+ }
+ };
+ name = "ARB buffer";
+ break;
+ case FENCES_APPLE:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteFencesAPPLE(1, new int[] { obj }, 0);
+ }
+ };
+ name = "APPLE fence";
+ break;
+ case FENCES_NV:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteFencesNV(1, new int[] { obj }, 0);
+ }
+ };
+ name = "NV fence";
+ break;
+ case FRAGMENT_SHADERS_ATI:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteFragmentShaderATI(obj);
+ }
+ };
+ name = "ATI fragment shader";
+ break;
+ case FRAMEBUFFERS_EXT:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteFramebuffersEXT(1, new int[] { obj }, 0);
+ }
+ };
+ name = "EXT framebuffer";
+ break;
+ case LISTS:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteLists(obj, 1);
+ }
+ };
+ name = "display list";
+ break;
+ case OCCLUSION_QUERIES_NV:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteOcclusionQueriesNV(1, new int[] { obj }, 0);
+ }
+ };
+ name = "NV occlusion query";
+ break;
+ case PROGRAM_AND_SHADER_OBJECTS_ARB:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteObjectARB(obj);
+ }
+ };
+ name = "ARB program or shader object";
+ break;
+ case PROGRAM_OBJECTS:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteProgram(obj);
+ }
+ };
+ name = "program object";
+ break;
+ case PROGRAMS_ARB:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteProgramsARB(1, new int[] { obj }, 0);
+ }
+ };
+ name = "ARB program object";
+ break;
+ case PROGRAMS_NV:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteProgramsNV(1, new int[] { obj }, 0);
+ }
+ };
+ name = "NV program";
+ break;
+ case QUERIES:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteQueries(1, new int[] { obj }, 0);
+ }
+ };
+ name = "query";
+ break;
+ case QUERIES_ARB:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteQueriesARB(1, new int[] { obj }, 0);
+ }
+ };
+ name = "ARB query";
+ break;
+ case RENDERBUFFERS_EXT:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteRenderbuffersEXT(1, new int[] { obj }, 0);
+ }
+ };
+ name = "EXT renderbuffer";
+ break;
+ case SHADER_OBJECTS:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteShader(obj);
+ }
+ };
+ name = "shader object";
+ break;
+ case TEXTURES:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteTextures(1, new int[] { obj }, 0);
+ }
+ };
+ name = "texture";
+ break;
+ case VERTEX_ARRAYS_APPLE:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteVertexArraysAPPLE(1, new int[] { obj }, 0);
+ }
+ };
+ name = "APPLE vertex array";
+ break;
+ case VERTEX_SHADERS_EXT:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteVertexShaderEXT(obj);
+ }
+ };
+ name = "EXT vertex shader";
+ break;
+ default:
+ throw new InternalError("Unexpected OpenGL object type " + which);
+ }
+
+ list = new ObjectList(deleter);
+ list.setName(name);
+ lists[which] = list;
+ }
+ return list;
+ }
+
+ private void delete(GL2 gl) {
+ for (int i = 0; i < lists.length; i++) {
+ ObjectList list = lists[i];
+ if (list != null) {
+ list.delete(gl);
+ lists[i] = null;
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/GLUquadricImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/GLUquadricImpl.java
new file mode 100644
index 000000000..d7e6a23c1
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/GLUquadricImpl.java
@@ -0,0 +1,1212 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** $Date: 2009-03-04 17:23:34 -0800 (Wed, 04 Mar 2009) $ $Revision: 1856 $
+** $Header$
+*/
+
+/*
+ * Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'LWJGL' nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.impl.glu;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import com.jogamp.opengl.util.ImmModeSink;
+import java.nio.*;
+
+/**
+ * GLUquadricImpl.java
+ *
+ *
+ * Created 22-dec-2003 (originally Quadric.java)
+ * @author Erik Duijs
+ * @author Kenneth Russell, Sven Gothel
+ */
+
+public class GLUquadricImpl implements GLUquadric {
+ private boolean useGLSL;
+ private int drawStyle;
+ private int orientation;
+ private boolean textureFlag;
+ private int normals;
+ private boolean immModeSinkEnabled;
+ private boolean immModeSinkImmediate;
+ public int normalType;
+ public GL gl;
+
+ public static final boolean USE_NORM = true;
+ public static final boolean USE_TEXT = false;
+
+ private ImmModeSink immModeSink=null;
+
+ public GLUquadricImpl(GL gl, boolean useGLSL) {
+ this.gl=gl;
+ this.useGLSL = useGLSL;
+ drawStyle = GLU.GLU_FILL;
+ orientation = GLU.GLU_OUTSIDE;
+ textureFlag = false;
+ normals = GLU.GLU_SMOOTH;
+ normalType = gl.isGLES1()?GL.GL_BYTE:GL.GL_FLOAT;
+ immModeSinkImmediate=true;
+ immModeSinkEnabled=!gl.isGL2();
+ replaceImmModeSink();
+ }
+
+ public void enableImmModeSink(boolean val) {
+ if(gl.isGL2()) {
+ immModeSinkEnabled=val;
+ } else {
+ immModeSinkEnabled=true;
+ }
+ if(null==immModeSink && immModeSinkEnabled) {
+ replaceImmModeSink();
+ }
+ }
+
+ public boolean isImmModeSinkEnabled() {
+ return immModeSinkEnabled;
+ }
+
+ public void setImmMode(boolean val) {
+ if(immModeSinkEnabled) {
+ immModeSinkImmediate=val;
+ } else {
+ immModeSinkImmediate=true;
+ }
+ }
+
+ public boolean getImmMode() {
+ return immModeSinkImmediate;
+ }
+
+ public ImmModeSink replaceImmModeSink() {
+ if(!immModeSinkEnabled) return null;
+
+ ImmModeSink res = immModeSink;
+ if(useGLSL) {
+ immModeSink = ImmModeSink.createGLSL (gl, GL.GL_STATIC_DRAW, 32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, normalType,// normal
+ USE_TEXT?2:0, GL.GL_FLOAT); // texture
+ } else {
+ immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, normalType,// normal
+ USE_TEXT?2:0, GL.GL_FLOAT); // texture
+ }
+ return res;
+ }
+
+ public void resetImmModeSink(GL gl) {
+ if(immModeSinkEnabled) {
+ immModeSink.reset(gl);
+ }
+ }
+
+ /**
+ * specifies the draw style for quadrics.
+ *
+ * The legal values are as follows:
+ *
+ * GLU.FILL: Quadrics are rendered with polygon primitives. The polygons
+ * are drawn in a counterclockwise fashion with respect to
+ * their normals (as defined with glu.quadricOrientation).
+ *
+ * GLU.LINE: Quadrics are rendered as a set of lines.
+ *
+ * GLU.SILHOUETTE: Quadrics are rendered as a set of lines, except that edges
+ * separating coplanar faces will not be drawn.
+ *
+ * GLU.POINT: Quadrics are rendered as a set of points.
+ *
+ * @param drawStyle The drawStyle to set
+ */
+ public void setDrawStyle(int drawStyle) {
+ this.drawStyle = drawStyle;
+ }
+
+ /**
+ * specifies what kind of normals are desired for quadrics.
+ * The legal values are as follows:
+ *
+ * GLU.NONE: No normals are generated.
+ *
+ * GLU.FLAT: One normal is generated for every facet of a quadric.
+ *
+ * GLU.SMOOTH: One normal is generated for every vertex of a quadric. This
+ * is the default.
+ *
+ * @param normals The normals to set
+ */
+ public void setNormals(int normals) {
+ this.normals = normals;
+ }
+
+ /**
+ * specifies what kind of orientation is desired for.
+ * The orientation values are as follows:
+ *
+ * GLU.OUTSIDE: Quadrics are drawn with normals pointing outward.
+ *
+ * GLU.INSIDE: Normals point inward. The default is GLU.OUTSIDE.
+ *
+ * Note that the interpretation of outward and inward depends on the quadric
+ * being drawn.
+ *
+ * @param orientation The orientation to set
+ */
+ public void setOrientation(int orientation) {
+ this.orientation = orientation;
+ }
+
+ /**
+ * specifies if texture coordinates should be generated for
+ * quadrics rendered with qobj. If the value of textureCoords is true,
+ * then texture coordinates are generated, and if textureCoords is false,
+ * they are not.. The default is false.
+ *
+ * The manner in which texture coordinates are generated depends upon the
+ * specific quadric rendered.
+ *
+ * @param textureFlag The textureFlag to set
+ */
+ public void setTextureFlag(boolean textureFlag) {
+ this.textureFlag = textureFlag;
+ }
+
+ /**
+ * Returns the drawStyle.
+ * @return int
+ */
+ public int getDrawStyle() {
+ return drawStyle;
+ }
+
+ /**
+ * Returns the normals.
+ * @return int
+ */
+ public int getNormals() {
+ return normals;
+ }
+
+ /**
+ * Returns the orientation.
+ * @return int
+ */
+ public int getOrientation() {
+ return orientation;
+ }
+
+ /**
+ * Returns the textureFlag.
+ * @return boolean
+ */
+ public boolean getTextureFlag() {
+ return textureFlag;
+ }
+
+
+ /**
+ * draws a cylinder oriented along the z axis. The base of the
+ * cylinder is placed at z = 0, and the top at z=height. Like a sphere, a
+ * cylinder is subdivided around the z axis into slices, and along the z axis
+ * into stacks.
+ *
+ * Note that if topRadius is set to zero, then this routine will generate a
+ * cone.
+ *
+ * If the orientation is set to GLU.OUTSIDE (with glu.quadricOrientation), then
+ * any generated normals point away from the z axis. Otherwise, they point
+ * toward the z axis.
+ *
+ * If texturing is turned on (with glu.quadricTexture), then texture
+ * coordinates are generated so that t ranges linearly from 0.0 at z = 0 to
+ * 1.0 at z = height, and s ranges from 0.0 at the +y axis, to 0.25 at the +x
+ * axis, to 0.5 at the -y axis, to 0.75 at the -x axis, and back to 1.0 at the
+ * +y axis.
+ *
+ * @param baseRadius Specifies the radius of the cylinder at z = 0.
+ * @param topRadius Specifies the radius of the cylinder at z = height.
+ * @param height Specifies the height of the cylinder.
+ * @param slices Specifies the number of subdivisions around the z axis.
+ * @param stacks Specifies the number of subdivisions along the z axis.
+ */
+ public void drawCylinder(GL gl, float baseRadius, float topRadius, float height, int slices, int stacks) {
+
+ float da, r, dr, dz;
+ float x, y, z, nz, nsign;
+ int i, j;
+
+ if (orientation == GLU.GLU_INSIDE) {
+ nsign = -1.0f;
+ } else {
+ nsign = 1.0f;
+ }
+
+ da = 2.0f * PI / slices;
+ dr = (topRadius - baseRadius) / stacks;
+ dz = height / stacks;
+ nz = (baseRadius - topRadius) / height;
+ // Z component of normal vectors
+
+ if (drawStyle == GLU.GLU_POINT) {
+ glBegin(gl, GL.GL_POINTS);
+ for (i = 0; i < slices; i++) {
+ x = cos((i * da));
+ y = sin((i * da));
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
+
+ z = 0.0f;
+ r = baseRadius;
+ for (j = 0; j <= stacks; j++) {
+ glVertex3f(gl, (x * r), (y * r), z);
+ z += dz;
+ r += dr;
+ }
+ }
+ glEnd(gl);
+ } else if (drawStyle == GLU.GLU_LINE || drawStyle == GLU.GLU_SILHOUETTE) {
+ // Draw rings
+ if (drawStyle == GLU.GLU_LINE) {
+ z = 0.0f;
+ r = baseRadius;
+ for (j = 0; j <= stacks; j++) {
+ glBegin(gl, GL.GL_LINE_LOOP);
+ for (i = 0; i < slices; i++) {
+ x = cos((i * da));
+ y = sin((i * da));
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
+ glVertex3f(gl, (x * r), (y * r), z);
+ }
+ glEnd(gl);
+ z += dz;
+ r += dr;
+ }
+ } else {
+ // draw one ring at each end
+ if (baseRadius != 0.0) {
+ glBegin(gl, GL.GL_LINE_LOOP);
+ for (i = 0; i < slices; i++) {
+ x = cos((i * da));
+ y = sin((i * da));
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
+ glVertex3f(gl, (x * baseRadius), (y * baseRadius), 0.0f);
+ }
+ glEnd(gl);
+ glBegin(gl, GL.GL_LINE_LOOP);
+ for (i = 0; i < slices; i++) {
+ x = cos((i * da));
+ y = sin((i * da));
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
+ glVertex3f(gl, (x * topRadius), (y * topRadius), height);
+ }
+ glEnd(gl);
+ }
+ }
+ // draw length lines
+ glBegin(gl, GL.GL_LINES);
+ for (i = 0; i < slices; i++) {
+ x = cos((i * da));
+ y = sin((i * da));
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
+ glVertex3f(gl, (x * baseRadius), (y * baseRadius), 0.0f);
+ glVertex3f(gl, (x * topRadius), (y * topRadius), (height));
+ }
+ glEnd(gl);
+ } else if (drawStyle == GLU.GLU_FILL) {
+ float ds = 1.0f / slices;
+ float dt = 1.0f / stacks;
+ float t = 0.0f;
+ z = 0.0f;
+ r = baseRadius;
+ for (j = 0; j < stacks; j++) {
+ float s = 0.0f;
+ glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ for (i = 0; i <= slices; i++) {
+ if (i == slices) {
+ x = sin(0.0f);
+ y = cos(0.0f);
+ } else {
+ x = sin((i * da));
+ y = cos((i * da));
+ }
+ if (nsign == 1.0f) {
+ normal3f(gl, (x * nsign), (y * nsign), (nz * nsign));
+ TXTR_COORD(gl, s, t);
+ glVertex3f(gl, (x * r), (y * r), z);
+ normal3f(gl, (x * nsign), (y * nsign), (nz * nsign));
+ TXTR_COORD(gl, s, t + dt);
+ glVertex3f(gl, (x * (r + dr)), (y * (r + dr)), (z + dz));
+ } else {
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
+ TXTR_COORD(gl, s, t);
+ glVertex3f(gl, (x * r), (y * r), z);
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
+ TXTR_COORD(gl, s, t + dt);
+ glVertex3f(gl, (x * (r + dr)), (y * (r + dr)), (z + dz));
+ }
+ s += ds;
+ } // for slices
+ glEnd(gl);
+ r += dr;
+ t += dt;
+ z += dz;
+ } // for stacks
+ }
+ }
+
+ /**
+ * renders a disk on the z = 0 plane. The disk has a radius of
+ * outerRadius, and contains a concentric circular hole with a radius of
+ * innerRadius. If innerRadius is 0, then no hole is generated. The disk is
+ * subdivided around the z axis into slices (like pizza slices), and also
+ * about the z axis into rings (as specified by slices and loops,
+ * respectively).
+ *
+ * With respect to orientation, the +z side of the disk is considered to be
+ * "outside" (see glu.quadricOrientation). This means that if the orientation
+ * is set to GLU.OUTSIDE, then any normals generated point along the +z axis.
+ * Otherwise, they point along the -z axis.
+ *
+ * If texturing is turned on (with glu.quadricTexture), texture coordinates are
+ * generated linearly such that where r=outerRadius, the value at (r, 0, 0) is
+ * (1, 0.5), at (0, r, 0) it is (0.5, 1), at (-r, 0, 0) it is (0, 0.5), and at
+ * (0, -r, 0) it is (0.5, 0).
+ */
+ public void drawDisk(GL gl, float innerRadius, float outerRadius, int slices, int loops)
+ {
+ float da, dr;
+
+ /* Normal vectors */
+ if (normals != GLU.GLU_NONE) {
+ if (orientation == GLU.GLU_OUTSIDE) {
+ glNormal3f(gl, 0.0f, 0.0f, +1.0f);
+ }
+ else {
+ glNormal3f(gl, 0.0f, 0.0f, -1.0f);
+ }
+ }
+
+ da = 2.0f * PI / slices;
+ dr = (outerRadius - innerRadius) / loops;
+
+ switch (drawStyle) {
+ case GLU.GLU_FILL:
+ {
+ /* texture of a gluDisk is a cut out of the texture unit square
+ * x, y in [-outerRadius, +outerRadius]; s, t in [0, 1]
+ * (linear mapping)
+ */
+ float dtc = 2.0f * outerRadius;
+ float sa, ca;
+ float r1 = innerRadius;
+ int l;
+ for (l = 0; l < loops; l++) {
+ float r2 = r1 + dr;
+ if (orientation == GLU.GLU_OUTSIDE) {
+ int s;
+ glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ for (s = 0; s <= slices; s++) {
+ float a;
+ if (s == slices)
+ a = 0.0f;
+ else
+ a = s * da;
+ sa = sin(a);
+ ca = cos(a);
+ TXTR_COORD(gl, 0.5f + sa * r2 / dtc, 0.5f + ca * r2 / dtc);
+ glVertex2f(gl, r2 * sa, r2 * ca);
+ TXTR_COORD(gl, 0.5f + sa * r1 / dtc, 0.5f + ca * r1 / dtc);
+ glVertex2f(gl, r1 * sa, r1 * ca);
+ }
+ glEnd(gl);
+ }
+ else {
+ int s;
+ glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ for (s = slices; s >= 0; s--) {
+ float a;
+ if (s == slices)
+ a = 0.0f;
+ else
+ a = s * da;
+ sa = sin(a);
+ ca = cos(a);
+ TXTR_COORD(gl, 0.5f - sa * r2 / dtc, 0.5f + ca * r2 / dtc);
+ glVertex2f(gl, r2 * sa, r2 * ca);
+ TXTR_COORD(gl, 0.5f - sa * r1 / dtc, 0.5f + ca * r1 / dtc);
+ glVertex2f(gl, r1 * sa, r1 * ca);
+ }
+ glEnd(gl);
+ }
+ r1 = r2;
+ }
+ break;
+ }
+ case GLU.GLU_LINE:
+ {
+ int l, s;
+ /* draw loops */
+ for (l = 0; l <= loops; l++) {
+ float r = innerRadius + l * dr;
+ glBegin(gl, GL.GL_LINE_LOOP);
+ for (s = 0; s < slices; s++) {
+ float a = s * da;
+ glVertex2f(gl, r * sin(a), r * cos(a));
+ }
+ glEnd(gl);
+ }
+ /* draw spokes */
+ for (s = 0; s < slices; s++) {
+ float a = s * da;
+ float x = sin(a);
+ float y = cos(a);
+ glBegin(gl, GL.GL_LINE_STRIP);
+ for (l = 0; l <= loops; l++) {
+ float r = innerRadius + l * dr;
+ glVertex2f(gl, r * x, r * y);
+ }
+ glEnd(gl);
+ }
+ break;
+ }
+ case GLU.GLU_POINT:
+ {
+ int s;
+ glBegin(gl, GL.GL_POINTS);
+ for (s = 0; s < slices; s++) {
+ float a = s * da;
+ float x = sin(a);
+ float y = cos(a);
+ int l;
+ for (l = 0; l <= loops; l++) {
+ float r = innerRadius * l * dr;
+ glVertex2f(gl, r * x, r * y);
+ }
+ }
+ glEnd(gl);
+ break;
+ }
+ case GLU.GLU_SILHOUETTE:
+ {
+ if (innerRadius != 0.0) {
+ float a;
+ glBegin(gl, GL.GL_LINE_LOOP);
+ for (a = 0.0f; a < 2.0 * PI; a += da) {
+ float x = innerRadius * sin(a);
+ float y = innerRadius * cos(a);
+ glVertex2f(gl, x, y);
+ }
+ glEnd(gl);
+ }
+ {
+ float a;
+ glBegin(gl, GL.GL_LINE_LOOP);
+ for (a = 0; a < 2.0f * PI; a += da) {
+ float x = outerRadius * sin(a);
+ float y = outerRadius * cos(a);
+ glVertex2f(gl, x, y);
+ }
+ glEnd(gl);
+ }
+ break;
+ }
+ default:
+ return;
+ }
+ }
+
+ /**
+ * renders a partial disk on the z=0 plane. A partial disk is similar to a
+ * full disk, except that only the subset of the disk from startAngle
+ * through startAngle + sweepAngle is included (where 0 degrees is along
+ * the +y axis, 90 degrees along the +x axis, 180 along the -y axis, and
+ * 270 along the -x axis).
+ *
+ * The partial disk has a radius of outerRadius, and contains a concentric
+ * circular hole with a radius of innerRadius. If innerRadius is zero, then
+ * no hole is generated. The partial disk is subdivided around the z axis
+ * into slices (like pizza slices), and also about the z axis into rings
+ * (as specified by slices and loops, respectively).
+ *
+ * With respect to orientation, the +z side of the partial disk is
+ * considered to be outside (see gluQuadricOrientation). This means that if
+ * the orientation is set to GLU.GLU_OUTSIDE, then any normals generated point
+ * along the +z axis. Otherwise, they point along the -z axis.
+ *
+ * If texturing is turned on (with gluQuadricTexture), texture coordinates
+ * are generated linearly such that where r=outerRadius, the value at (r, 0, 0)
+ * is (1, 0.5), at (0, r, 0) it is (0.5, 1), at (-r, 0, 0) it is (0, 0.5),
+ * and at (0, -r, 0) it is (0.5, 0).
+ */
+ public void drawPartialDisk(GL gl,
+ float innerRadius,
+ float outerRadius,
+ int slices,
+ int loops,
+ float startAngle,
+ float sweepAngle) {
+ int i, j, max;
+ float[] sinCache = new float[CACHE_SIZE];
+ float[] cosCache = new float[CACHE_SIZE];
+ float angle;
+ float x, y;
+ float sintemp, costemp;
+ float deltaRadius;
+ float radiusLow, radiusHigh;
+ float texLow = 0, texHigh = 0;
+ float angleOffset;
+ int slices2;
+ int finish;
+
+ if (slices >= CACHE_SIZE)
+ slices = CACHE_SIZE - 1;
+ if (slices < 2
+ || loops < 1
+ || outerRadius <= 0.0f
+ || innerRadius < 0.0f
+ || innerRadius > outerRadius) {
+ //gluQuadricError(qobj, GLU.GLU_INVALID_VALUE);
+ System.err.println("PartialDisk: GLU_INVALID_VALUE");
+ return;
+ }
+
+ if (sweepAngle < -360.0f)
+ sweepAngle = 360.0f;
+ if (sweepAngle > 360.0f)
+ sweepAngle = 360.0f;
+ if (sweepAngle < 0) {
+ startAngle += sweepAngle;
+ sweepAngle = -sweepAngle;
+ }
+
+ if (sweepAngle == 360.0f) {
+ slices2 = slices;
+ } else {
+ slices2 = slices + 1;
+ }
+
+ /* Compute length (needed for normal calculations) */
+ deltaRadius = outerRadius - innerRadius;
+
+ /* Cache is the vertex locations cache */
+
+ angleOffset = startAngle / 180.0f * PI;
+ for (i = 0; i <= slices; i++) {
+ angle = angleOffset + ((PI * sweepAngle) / 180.0f) * i / slices;
+ sinCache[i] = sin(angle);
+ cosCache[i] = cos(angle);
+ }
+
+ if (sweepAngle == 360.0f) {
+ sinCache[slices] = sinCache[0];
+ cosCache[slices] = cosCache[0];
+ }
+
+ switch (normals) {
+ case GLU.GLU_FLAT :
+ case GLU.GLU_SMOOTH :
+ if (orientation == GLU.GLU_OUTSIDE) {
+ glNormal3f(gl, 0.0f, 0.0f, 1.0f);
+ } else {
+ glNormal3f(gl, 0.0f, 0.0f, -1.0f);
+ }
+ break;
+ default :
+ case GLU.GLU_NONE :
+ break;
+ }
+
+ switch (drawStyle) {
+ case GLU.GLU_FILL :
+ if (innerRadius == .0f) {
+ finish = loops - 1;
+ /* Triangle strip for inner polygons */
+ glBegin(gl, GL.GL_TRIANGLE_FAN);
+ if (textureFlag) {
+ glTexCoord2f(gl, 0.5f, 0.5f);
+ }
+ glVertex3f(gl, 0.0f, 0.0f, 0.0f);
+ radiusLow = outerRadius - deltaRadius * ((float) (loops - 1) / loops);
+ if (textureFlag) {
+ texLow = radiusLow / outerRadius / 2;
+ }
+
+ if (orientation == GLU.GLU_OUTSIDE) {
+ for (i = slices; i >= 0; i--) {
+ if (textureFlag) {
+ glTexCoord2f(gl, texLow * sinCache[i] + 0.5f,
+ texLow * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
+ }
+ } else {
+ for (i = 0; i <= slices; i++) {
+ if (textureFlag) {
+ glTexCoord2f(gl, texLow * sinCache[i] + 0.5f,
+ texLow * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
+ }
+ }
+ glEnd(gl);
+ } else {
+ finish = loops;
+ }
+ for (j = 0; j < finish; j++) {
+ radiusLow = outerRadius - deltaRadius * ((float) j / loops);
+ radiusHigh = outerRadius - deltaRadius * ((float) (j + 1) / loops);
+ if (textureFlag) {
+ texLow = radiusLow / outerRadius / 2;
+ texHigh = radiusHigh / outerRadius / 2;
+ }
+
+ glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ for (i = 0; i <= slices; i++) {
+ if (orientation == GLU.GLU_OUTSIDE) {
+ if (textureFlag) {
+ glTexCoord2f(gl, texLow * sinCache[i] + 0.5f,
+ texLow * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
+
+ if (textureFlag) {
+ glTexCoord2f(gl, texHigh * sinCache[i] + 0.5f,
+ texHigh * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusHigh * sinCache[i],
+ radiusHigh * cosCache[i],
+ 0.0f);
+ } else {
+ if (textureFlag) {
+ glTexCoord2f(gl, texHigh * sinCache[i] + 0.5f,
+ texHigh * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusHigh * sinCache[i],
+ radiusHigh * cosCache[i],
+ 0.0f);
+
+ if (textureFlag) {
+ glTexCoord2f(gl, texLow * sinCache[i] + 0.5f,
+ texLow * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
+ }
+ }
+ glEnd(gl);
+ }
+ break;
+ case GLU.GLU_POINT :
+ glBegin(gl, GL.GL_POINTS);
+ for (i = 0; i < slices2; i++) {
+ sintemp = sinCache[i];
+ costemp = cosCache[i];
+ for (j = 0; j <= loops; j++) {
+ radiusLow = outerRadius - deltaRadius * ((float) j / loops);
+
+ if (textureFlag) {
+ texLow = radiusLow / outerRadius / 2;
+
+ glTexCoord2f(gl, texLow * sinCache[i] + 0.5f,
+ texLow * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusLow * sintemp, radiusLow * costemp, 0.0f);
+ }
+ }
+ glEnd(gl);
+ break;
+ case GLU.GLU_LINE :
+ if (innerRadius == outerRadius) {
+ glBegin(gl, GL.GL_LINE_STRIP);
+
+ for (i = 0; i <= slices; i++) {
+ if (textureFlag) {
+ glTexCoord2f(gl, sinCache[i] / 2 + 0.5f, cosCache[i] / 2 + 0.5f);
+ }
+ glVertex3f(gl, innerRadius * sinCache[i], innerRadius * cosCache[i], 0.0f);
+ }
+ glEnd(gl);
+ break;
+ }
+ for (j = 0; j <= loops; j++) {
+ radiusLow = outerRadius - deltaRadius * ((float) j / loops);
+ if (textureFlag) {
+ texLow = radiusLow / outerRadius / 2;
+ }
+
+ glBegin(gl, GL.GL_LINE_STRIP);
+ for (i = 0; i <= slices; i++) {
+ if (textureFlag) {
+ glTexCoord2f(gl, texLow * sinCache[i] + 0.5f,
+ texLow * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
+ }
+ glEnd(gl);
+ }
+ for (i = 0; i < slices2; i++) {
+ sintemp = sinCache[i];
+ costemp = cosCache[i];
+ glBegin(gl, GL.GL_LINE_STRIP);
+ for (j = 0; j <= loops; j++) {
+ radiusLow = outerRadius - deltaRadius * ((float) j / loops);
+ if (textureFlag) {
+ texLow = radiusLow / outerRadius / 2;
+ }
+
+ if (textureFlag) {
+ glTexCoord2f(gl, texLow * sinCache[i] + 0.5f,
+ texLow * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusLow * sintemp, radiusLow * costemp, 0.0f);
+ }
+ glEnd(gl);
+ }
+ break;
+ case GLU.GLU_SILHOUETTE :
+ if (sweepAngle < 360.0f) {
+ for (i = 0; i <= slices; i += slices) {
+ sintemp = sinCache[i];
+ costemp = cosCache[i];
+ glBegin(gl, GL.GL_LINE_STRIP);
+ for (j = 0; j <= loops; j++) {
+ radiusLow = outerRadius - deltaRadius * ((float) j / loops);
+
+ if (textureFlag) {
+ texLow = radiusLow / outerRadius / 2;
+ glTexCoord2f(gl, texLow * sinCache[i] + 0.5f,
+ texLow * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusLow * sintemp, radiusLow * costemp, 0.0f);
+ }
+ glEnd(gl);
+ }
+ }
+ for (j = 0; j <= loops; j += loops) {
+ radiusLow = outerRadius - deltaRadius * ((float) j / loops);
+ if (textureFlag) {
+ texLow = radiusLow / outerRadius / 2;
+ }
+
+ glBegin(gl, GL.GL_LINE_STRIP);
+ for (i = 0; i <= slices; i++) {
+ if (textureFlag) {
+ glTexCoord2f(gl, texLow * sinCache[i] + 0.5f,
+ texLow * cosCache[i] + 0.5f);
+ }
+ glVertex3f(gl, radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f);
+ }
+ glEnd(gl);
+ if (innerRadius == outerRadius)
+ break;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ /**
+ * draws a sphere of the given radius centered around the origin.
+ * The sphere is subdivided around the z axis into slices and along the z axis
+ * into stacks (similar to lines of longitude and latitude).
+ *
+ * If the orientation is set to GLU.OUTSIDE (with glu.quadricOrientation), then
+ * any normals generated point away from the center of the sphere. Otherwise,
+ * they point toward the center of the sphere.
+
+ * If texturing is turned on (with glu.quadricTexture), then texture
+ * coordinates are generated so that t ranges from 0.0 at z=-radius to 1.0 at
+ * z=radius (t increases linearly along longitudinal lines), and s ranges from
+ * 0.0 at the +y axis, to 0.25 at the +x axis, to 0.5 at the -y axis, to 0.75
+ * at the -x axis, and back to 1.0 at the +y axis.
+ */
+ public void drawSphere(GL gl, float radius, int slices, int stacks) {
+ // TODO
+
+ float rho, drho, theta, dtheta;
+ float x, y, z;
+ float s, t, ds, dt;
+ int i, j, imin, imax;
+ boolean normals;
+ float nsign;
+
+ normals = (this.normals != GLU.GLU_NONE);
+
+ if (orientation == GLU.GLU_INSIDE) {
+ nsign = -1.0f;
+ } else {
+ nsign = 1.0f;
+ }
+
+ drho = PI / stacks;
+ dtheta = 2.0f * PI / slices;
+
+ if (drawStyle == GLU.GLU_FILL) {
+ if (!textureFlag) {
+ // draw +Z end as a triangle fan
+ glBegin(gl, GL.GL_TRIANGLE_FAN);
+ glNormal3f(gl, 0.0f, 0.0f, 1.0f);
+ glVertex3f(gl, 0.0f, 0.0f, nsign * radius);
+ for (j = 0; j <= slices; j++) {
+ theta = (j == slices) ? 0.0f : j * dtheta;
+ x = -sin(theta) * sin(drho);
+ y = cos(theta) * sin(drho);
+ z = nsign * cos(drho);
+ if (normals) {
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
+ }
+ glVertex3f(gl, x * radius, y * radius, z * radius);
+ }
+ glEnd(gl);
+ }
+
+ ds = 1.0f / slices;
+ dt = 1.0f / stacks;
+ t = 1.0f; // because loop now runs from 0
+ if (textureFlag) {
+ imin = 0;
+ imax = stacks;
+ } else {
+ imin = 1;
+ imax = stacks - 1;
+ }
+
+ // draw intermediate stacks as quad strips
+ for (i = imin; i < imax; i++) {
+ rho = i * drho;
+ glBegin(gl, immModeSink.GL_QUAD_STRIP);
+ s = 0.0f;
+ for (j = 0; j <= slices; j++) {
+ theta = (j == slices) ? 0.0f : j * dtheta;
+ x = -sin(theta) * sin(rho);
+ y = cos(theta) * sin(rho);
+ z = nsign * cos(rho);
+ if (normals) {
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
+ }
+ TXTR_COORD(gl, s, t);
+ glVertex3f(gl, x * radius, y * radius, z * radius);
+ x = -sin(theta) * sin(rho + drho);
+ y = cos(theta) * sin(rho + drho);
+ z = nsign * cos(rho + drho);
+ if (normals) {
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
+ }
+ TXTR_COORD(gl, s, t - dt);
+ s += ds;
+ glVertex3f(gl, x * radius, y * radius, z * radius);
+ }
+ glEnd(gl);
+ t -= dt;
+ }
+
+ if (!textureFlag) {
+ // draw -Z end as a triangle fan
+ glBegin(gl, GL.GL_TRIANGLE_FAN);
+ glNormal3f(gl, 0.0f, 0.0f, -1.0f);
+ glVertex3f(gl, 0.0f, 0.0f, -radius * nsign);
+ rho = PI - drho;
+ s = 1.0f;
+ for (j = slices; j >= 0; j--) {
+ theta = (j == slices) ? 0.0f : j * dtheta;
+ x = -sin(theta) * sin(rho);
+ y = cos(theta) * sin(rho);
+ z = nsign * cos(rho);
+ if (normals)
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
+ s -= ds;
+ glVertex3f(gl, x * radius, y * radius, z * radius);
+ }
+ glEnd(gl);
+ }
+ } else if (
+ drawStyle == GLU.GLU_LINE
+ || drawStyle == GLU.GLU_SILHOUETTE) {
+ // draw stack lines
+ for (i = 1;
+ i < stacks;
+ i++) { // stack line at i==stacks-1 was missing here
+ rho = i * drho;
+ glBegin(gl, GL.GL_LINE_LOOP);
+ for (j = 0; j < slices; j++) {
+ theta = j * dtheta;
+ x = cos(theta) * sin(rho);
+ y = sin(theta) * sin(rho);
+ z = cos(rho);
+ if (normals)
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
+ glVertex3f(gl, x * radius, y * radius, z * radius);
+ }
+ glEnd(gl);
+ }
+ // draw slice lines
+ for (j = 0; j < slices; j++) {
+ theta = j * dtheta;
+ glBegin(gl, GL.GL_LINE_STRIP);
+ for (i = 0; i <= stacks; i++) {
+ rho = i * drho;
+ x = cos(theta) * sin(rho);
+ y = sin(theta) * sin(rho);
+ z = cos(rho);
+ if (normals)
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
+ glVertex3f(gl, x * radius, y * radius, z * radius);
+ }
+ glEnd(gl);
+ }
+ } else if (drawStyle == GLU.GLU_POINT) {
+ // top and bottom-most points
+ glBegin(gl, GL.GL_POINTS);
+ if (normals)
+ glNormal3f(gl, 0.0f, 0.0f, nsign);
+ glVertex3f(gl, 0.0f, 0.0f, radius);
+ if (normals)
+ glNormal3f(gl, 0.0f, 0.0f, -nsign);
+ glVertex3f(gl, 0.0f, 0.0f, -radius);
+
+ // loop over stacks
+ for (i = 1; i < stacks - 1; i++) {
+ rho = i * drho;
+ for (j = 0; j < slices; j++) {
+ theta = j * dtheta;
+ x = cos(theta) * sin(rho);
+ y = sin(theta) * sin(rho);
+ z = cos(rho);
+ if (normals)
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
+ glVertex3f(gl, x * radius, y * radius, z * radius);
+ }
+ }
+ glEnd(gl);
+ }
+ }
+
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static final float PI = (float)Math.PI;
+ private static final int CACHE_SIZE = 240;
+
+ private final void glBegin(GL gl, int mode) {
+ if(immModeSinkEnabled) {
+ immModeSink.glBegin(mode);
+ } else {
+ gl.getGL2().glBegin(mode);
+ }
+ }
+
+ private final void glEnd(GL gl) {
+ if(immModeSinkEnabled) {
+ immModeSink.glEnd(gl, immModeSinkImmediate);
+ } else {
+ gl.getGL2().glEnd();
+ }
+ }
+
+ private final void glVertex2f(GL gl, float x, float y) {
+ if(immModeSinkEnabled) {
+ immModeSink.glVertex2f(x, y);
+ } else {
+ gl.getGL2().glVertex2f(x, y);
+ }
+ }
+
+ private final void glVertex3f(GL gl, float x, float y, float z) {
+ if(immModeSinkEnabled) {
+ immModeSink.glVertex3f(x, y, z);
+ } else {
+ gl.getGL2().glVertex3f(x, y, z);
+ }
+ }
+
+ private final void glNormal3f_s(GL gl, float x, float y, float z) {
+ short a=(short)(x*0xFFFF);
+ short b=(short)(y*0xFFFF);
+ short c=(short)(z*0xFFFF);
+ if(immModeSinkEnabled) {
+ immModeSink.glNormal3s(a, b, c);
+ } else {
+ gl.getGL2().glNormal3s(a, b, c);
+ }
+ }
+
+ private final void glNormal3f_b(GL gl, float x, float y, float z) {
+ byte a=(byte)(x*0xFF);
+ byte b=(byte)(y*0xFF);
+ byte c=(byte)(z*0xFF);
+ if(immModeSinkEnabled) {
+ immModeSink.glNormal3b(a, b, c);
+ } else {
+ gl.getGL2().glNormal3b(a, b, c);
+ }
+ }
+
+ private final void glNormal3f(GL gl, float x, float y, float z) {
+ switch(normalType) {
+ case GL.GL_FLOAT:
+ if(immModeSinkEnabled) {
+ immModeSink.glNormal3f(x,y,z);
+ } else {
+ gl.getGL2().glNormal3f(x,y,z);
+ }
+ break;
+ case GL.GL_SHORT:
+ glNormal3f_s(gl, x, y, z);
+ break;
+ case GL.GL_BYTE:
+ glNormal3f_b(gl, x, y, z);
+ break;
+ }
+ }
+
+ private final void glTexCoord2f(GL gl, float x, float y) {
+ if(immModeSinkEnabled) {
+ immModeSink.glTexCoord2f(x, y);
+ } else {
+ gl.getGL2().glTexCoord2f(x, y);
+ }
+ }
+
+ /**
+ * Call glNormal3f after scaling normal to unit length.
+ *
+ * @param x
+ * @param y
+ * @param z
+ */
+ private void normal3f(GL gl, float x, float y, float z) {
+ float mag;
+
+ mag = (float)Math.sqrt(x * x + y * y + z * z);
+ if (mag > 0.00001F) {
+ x /= mag;
+ y /= mag;
+ z /= mag;
+ }
+ glNormal3f(gl, x, y, z);
+ }
+
+ private final void TXTR_COORD(GL gl, float x, float y) {
+ if (textureFlag) glTexCoord2f(gl, x,y);
+ }
+
+ private float sin(float r) {
+ return (float)Math.sin(r);
+ }
+
+ private float cos(float r) {
+ return (float)Math.cos(r);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/Glue.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/Glue.java
new file mode 100755
index 000000000..7c360c574
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/Glue.java
@@ -0,0 +1,114 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Glue {
+ private static String[] __gluNurbsErrors = {
+ " ",
+ "spline order un-supported",
+ "too few knots",
+ "valid knot range is empty",
+ "decreasing knot sequence knot",
+ "knot multiplicity greater than order of spline",
+ "gluEndCurve() must follow gluBeginCurve()",
+ "gluBeginCurve() must precede gluEndCurve()",
+ "missing or extra geometric data",
+ "can't draw piecewise linear trimming curves",
+ "missing or extra domain data",
+ "missing or extra domain data",
+ "gluEndTrim() must precede gluEndSurface()",
+ "gluBeginSurface() must precede gluEndSurface()",
+ "curve of improper type passed as trim curve",
+ "gluBeginSurface() must precede gluBeginTrim()",
+ "gluEndTrim() must follow gluBeginTrim()",
+ "gluBeginTrim() must follow gluEndTrim()",
+ "invalid or missing trim curve",
+ "gluBeginTrim() must precede gluPwlCurve()",
+ "piecewise linear trimming curve referenced twice",
+ "piecewise linear trimming curve and nurbs curve mixed",
+ "improper usage of trim data type",
+ "nurbs curve referenced twice",
+ "nurbs curve and piecewise linear trimming curve mixed",
+ "nurbs surface referenced twice",
+ "invalid property",
+ "gluEndSurface() must follow gluBeginSurface()",
+ "intersecting or misoriented trim curve",
+ "intersecting trim curves",
+ "UNUSED",
+ "inconnected trim curves",
+ "unknown knot error",
+ "negative vertex count encountered",
+ "negative byte-stride encountered",
+ "unknown type descriptor",
+ "null control point reference",
+ "duplicate point on piecewise linear trimming curve"
+ } ;
+
+ /** Creates a new instance of Glue */
+ public Glue() {
+ }
+
+ public static String __gluNURBSErrorString( int errno ) {
+ return( __gluNurbsErrors[ errno ] );
+ }
+
+ private static String[] __gluTessErrors = {
+ " ",
+ "gluTessBeginPolygon() must precede a gluTessEndPolygon",
+ "gluTessBeginContour() must precede a gluTessEndContour()",
+ "gluTessEndPolygon() must follow a gluTessBeginPolygon()",
+ "gluTessEndContour() must follow a gluTessBeginContour()",
+ "a coordinate is too large",
+ "need combine callback"
+ };
+
+ public static String __gluTessErrorString( int errno ) {
+ return( __gluTessErrors[ errno ] );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/error/Error.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/error/Error.java
new file mode 100644
index 000000000..7c7e6b0d8
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/error/Error.java
@@ -0,0 +1,100 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.error;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.glu.GLU;
+import com.jogamp.opengl.impl.glu.Glue;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Error {
+
+ private static String[] glErrorStrings = {
+ "invalid enumerant",
+ "invalid value",
+ "invalid operation",
+ "stack overflow",
+ "stack underflow",
+ "out of memory",
+ "invalid framebuffer operation"
+ };
+
+ private static String[] gluErrorStrings = {
+ "invalid enumerant",
+ "invalid value",
+ "out of memory",
+ "",
+ "invalid operation"
+ };
+
+ /** Creates a new instance of Error */
+ public Error() {
+ }
+
+ public static String gluErrorString( int errorCode ) {
+ if( errorCode == 0 ) {
+ return( "no error" );
+ }
+ if( (errorCode >= GL.GL_INVALID_ENUM) && (errorCode <= GL.GL_INVALID_FRAMEBUFFER_OPERATION) ) {
+ return( glErrorStrings[ errorCode - GL.GL_INVALID_ENUM ] );
+ }
+ if( errorCode == 0x8031 /* GL.GL_TABLE_TOO_LARGE */ ) {
+ return( "table too large" );
+ }
+ if( (errorCode >= GLU.GLU_INVALID_ENUM) && (errorCode <= GLU.GLU_INVALID_OPERATION) ) {
+ return( gluErrorStrings[ errorCode - GLU.GLU_INVALID_ENUM ] );
+ }
+// if( (errorCode >= GLU.GLU_NURBS_ERROR1) && (errorCode <= GLU.GLU_NURBS_ERROR37) ) {
+// return( gluErrorStrings[ errorCode - (GLU.GLU_NURBS_ERROR1 - 1) ] );
+// }
+ if( (errorCode >= GLU.GLU_TESS_ERROR1) && (errorCode <= GLU.GLU_TESS_ERROR8) ) {
+ return( Glue.__gluTessErrorString(errorCode - (GLU.GLU_TESS_ERROR1 - 1)) );
+ }
+ return( "error ("+errorCode+")" );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2Backend.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2Backend.java
new file mode 100755
index 000000000..42ddeea50
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2Backend.java
@@ -0,0 +1,49 @@
+package com.jogamp.opengl.impl.glu.gl2.nurbs;
+import com.jogamp.opengl.impl.glu.nurbs.*;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class responsible for rendering
+ * @author Tomas Hrasky
+ *
+ */
+public class GL2Backend extends Backend {
+ public GL2Backend() {
+ super();
+ curveEvaluator = new GL2CurveEvaluator();
+ surfaceEvaluator = new GL2SurfaceEvaluator();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2CurveEvaluator.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2CurveEvaluator.java
new file mode 100755
index 000000000..adb8c51d8
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2CurveEvaluator.java
@@ -0,0 +1,205 @@
+package com.jogamp.opengl.impl.glu.gl2.nurbs;
+import com.jogamp.opengl.impl.glu.nurbs.*;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.gl2.GLUgl2;
+
+/**
+ * Class rendering curves with OpenGL
+ * @author Tomáš Hráský
+ *
+ */
+class GL2CurveEvaluator implements CurveEvaluator {
+
+ /**
+ * Output triangles (for callback) or render curve
+ */
+ private boolean output_triangles;
+
+ /**
+ * OpenGL object
+ */
+ private GL2 gl;
+
+ /**
+ * Not used
+ */
+ private int vertex_flag;
+
+ /**
+ * Not used
+ */
+ private int normal_flag;
+
+ /**
+ * Not used
+ */
+ private int color_flag;
+
+ /**
+ * Not used
+ */
+ private int texcoord_flag;
+
+ /**
+ * Number of bezier arc - used for color distinguishing of arcs forming NURBS curve
+ */
+ private int poradi;
+
+ /**
+ * Makes new Evaluator
+ */
+ public GL2CurveEvaluator() {
+ gl = GLUgl2.getCurrentGL2();
+ }
+
+ /**
+ * Pushes eval bit
+ */
+ public void bgnmap1f() {
+ // DONE
+ if (output_triangles) {
+ vertex_flag = 0;
+ normal_flag = 0;
+ color_flag = 0;
+ texcoord_flag = 0;
+ } else {
+ gl.glPushAttrib(GL2.GL_EVAL_BIT);
+ }
+
+ }
+
+ /**
+ * Pops all OpenGL attributes
+ */
+ public void endmap1f() {
+ // DONE
+ if (output_triangles) {
+
+ } else {
+ gl.glPopAttrib();
+ }
+
+ }
+
+ /**
+ * Initializes opengl evaluator
+ * @param type curve type
+ * @param ulo lowest u
+ * @param uhi highest u
+ * @param stride control point coords
+ * @param order curve order
+ * @param ps control points
+ */
+ public void map1f(int type, float ulo, float uhi, int stride, int order,
+ CArrayOfFloats ps) {
+ if (output_triangles) {
+ // TODO code for callback (output_triangles probably indicates callback)
+ // System.out.println("TODO curveevaluator.map1f-output_triangles");
+ } else {
+ gl.glMap1f(type, ulo, uhi, stride, order, ps.getArray(), ps
+ .getPointer());
+
+ // DEBUG - drawing bézier control points
+ // gl.glColor3d(.5,.5,.5);
+ // gl.glPointSize(5);
+ // gl.glBegin(GL2.GL_POINTS);
+ // float[] ctrlpoints=ps.getArray();
+ // for(int i=ps.getPointer();i<ps.getPointer()+order;i++){
+ // gl.glVertex3d(ctrlpoints[i * 4], ctrlpoints[i * 4 + 1],0);
+ // }
+ // gl.glEnd();
+ }
+
+ }
+
+ /**
+ * Calls opengl enable
+ * @param type what to enable
+ */
+ public void enable(int type) {
+ // DONE
+ gl.glEnable(type);
+ }
+
+ /**
+ * Calls glMapGrid1f
+ * @param nu steps
+ * @param u1 low u
+ * @param u2 high u
+ */
+ public void mapgrid1f(int nu, float u1, float u2) {
+ if (output_triangles) {
+ // System.out.println("TODO curveevaluator.mapgrid1f");
+ } else
+ gl.glMapGrid1f(nu, u1, u2);
+ // // System.out.println("upravit NU");
+ // gl.glMapGrid1f(50,u1,u2);
+ }
+
+ /**
+ * Evaluates a curve using glEvalMesh1f
+ * @param style Backend.N_MESHFILL/N_MESHLINE/N_MESHPOINT
+ * @param from lowest param
+ * @param to highest param
+ */
+ public void mapmesh1f(int style, int from, int to) {
+ /* //DEBUG drawing control points
+ this.poradi++;
+ if (poradi % 2 == 0)
+ gl.glColor3f(1, 0, 0);
+ else
+ gl.glColor3f(0, 1, 0);
+ */
+ if (output_triangles) {
+ // TODO code for callback
+ // System.out.println("TODO openglcurveevaluator.mapmesh1f output_triangles");
+ } else {
+ switch (style) {
+ case Backend.N_MESHFILL:
+ case Backend.N_MESHLINE:
+ gl.glEvalMesh1(GL2.GL_LINE, from, to);
+ break;
+ case Backend.N_MESHPOINT:
+ gl.glEvalMesh1(GL2.GL_POINT, from, to);
+ break;
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2SurfaceEvaluator.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2SurfaceEvaluator.java
new file mode 100755
index 000000000..393601ff7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GL2SurfaceEvaluator.java
@@ -0,0 +1,217 @@
+package com.jogamp.opengl.impl.glu.gl2.nurbs;
+import com.jogamp.opengl.impl.glu.nurbs.*;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.glu.gl2.GLUgl2;
+
+/**
+ * Class rendering surfaces with OpenGL
+ * @author Tomas Hrasky
+ *
+ */
+class GL2SurfaceEvaluator implements SurfaceEvaluator {
+
+ /**
+ * JOGL OpenGL object
+ */
+ private GL2 gl;
+
+ /**
+ * Output triangles (callback)
+ */
+ private boolean output_triangles;
+
+ /**
+ * Number of patch - used for distinguishing bezier plates forming NURBS surface with different colors
+ */
+ private int poradi;
+
+ /**
+ * Creates new evaluator
+ */
+ public GL2SurfaceEvaluator() {
+ gl = GLUgl2.getCurrentGL2();
+ }
+
+ /**
+ * Pushes eval bit
+ */
+ public void bgnmap2f() {
+
+ if (output_triangles) {
+ // TODO outp triangles surfaceevaluator bgnmap2f
+ // System.out.println("TODO surfaceevaluator.bgnmap2f output triangles");
+ } else {
+ gl.glPushAttrib(GL2.GL_EVAL_BIT);
+ // System.out.println("TODO surfaceevaluator.bgnmap2f glgetintegerv");
+ }
+
+ }
+
+ /**
+ * Sets glPolygonMode
+ * @param style polygon mode (N_MESHFILL/N_MESHLINE/N_MESHPOINT)
+ */
+ public void polymode(int style) {
+ if (!output_triangles) {
+ switch (style) {
+ default:
+ case NurbsConsts.N_MESHFILL:
+ gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_FILL);
+ break;
+ case NurbsConsts.N_MESHLINE:
+ gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
+ break;
+ case NurbsConsts.N_MESHPOINT:
+ gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_POINT);
+ break;
+ }
+ }
+
+ }
+
+ /**
+ * Pops all attributes
+ */
+ public void endmap2f() {
+ // TODO Auto-generated method stub
+ if (output_triangles) {
+ // System.out.println("TODO surfaceevaluator.endmap2f output triangles");
+ } else {
+ gl.glPopAttrib();
+ // TODO use LOD
+ }
+ }
+
+ /**
+ * Empty method
+ * @param ulo
+ * @param uhi
+ * @param vlo
+ * @param vhi
+ */
+ public void domain2f(float ulo, float uhi, float vlo, float vhi) {
+ // DONE
+ }
+
+ /**
+ * Defines 2D mesh
+ * @param nu number of steps in u direction
+ * @param u0 lowest u
+ * @param u1 highest u
+ * @param nv number of steps in v direction
+ * @param v0 lowest v
+ * @param v1 highest v
+ */
+ public void mapgrid2f(int nu, float u0, float u1, int nv, float v0, float v1) {
+
+ if (output_triangles) {
+ // System.out.println("TODO openglsurfaceavaluator.mapgrid2f output_triangles");
+ } else {
+ gl.glMapGrid2d(nu, u0, u1, nv, v0, v1);
+ }
+
+ }
+
+ /**
+ * Evaluates surface
+ * @param style surface style
+ * @param umin minimum U
+ * @param umax maximum U
+ * @param vmin minimum V
+ * @param vmax maximum V
+ */
+ public void mapmesh2f(int style, int umin, int umax, int vmin, int vmax) {
+ if (output_triangles) {
+ // System.out.println("TODO openglsurfaceavaluator.mapmesh2f output_triangles");
+ } else {
+ /* //DEBUG - draw control points
+ this.poradi++;
+ if (poradi % 2 == 0)
+ gl.glColor3f(1, 0, 0);
+ else if (poradi % 2 == 1)
+ gl.glColor3f(0, 1, 0);
+ */
+ switch (style) {
+ case NurbsConsts.N_MESHFILL:
+ gl.glEvalMesh2(GL2.GL_FILL, umin, umax, vmin, vmax);
+ break;
+ case NurbsConsts.N_MESHLINE:
+ gl.glEvalMesh2(GL2.GL_LINE, umin, umax, vmin, vmax);
+ break;
+ case NurbsConsts.N_MESHPOINT:
+ gl.glEvalMesh2(GL2.GL_POINT, umin, umax, vmin, vmax);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Initializes evaluator
+ * @param type surface type
+ * @param ulo lowest u
+ * @param uhi highest u
+ * @param ustride number of objects between control points in u direction
+ * @param uorder surface order in u direction
+ * @param vlo lowest v
+ * @param vhi highest v
+ * @param vstride number of control points' coords
+ * @param vorder surface order in v direction
+ * @param pts control points
+ */
+ public void map2f(int type, float ulo, float uhi, int ustride, int uorder,
+ float vlo, float vhi, int vstride, int vorder, CArrayOfFloats pts) {
+ // TODO Auto-generated method stub
+ if (output_triangles) {
+ // System.out.println("TODO openglsurfaceevaluator.map2f output_triangles");
+ } else {
+ gl.glMap2f(type, ulo, uhi, ustride, uorder, vlo, vhi, vstride,
+ vorder, pts.getArray(), pts.getPointer());
+ }
+ }
+
+ /**
+ * Calls opengl enable
+ * @param type what to enable
+ */
+ public void enable(int type) {
+ //DONE
+ gl.glEnable(type);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GLUgl2nurbsImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GLUgl2nurbsImpl.java
new file mode 100755
index 000000000..13b68138c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/gl2/nurbs/GLUgl2nurbsImpl.java
@@ -0,0 +1,862 @@
+package com.jogamp.opengl.impl.glu.gl2.nurbs;
+import com.jogamp.opengl.impl.glu.nurbs.*;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+import java.lang.reflect.Method;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.glu.GLUnurbs;
+
+/**
+ * Base object for working with NURBS curves and surfaces
+ *
+ * @author Tomas Hrasky
+ *
+ */
+public class GLUgl2nurbsImpl implements GLUnurbs {
+
+ /**
+ * Curve type - no type
+ */
+ public static final int CT_NONE = 0;
+
+ /**
+ * Curve type - NURBS curve
+ */
+ public static final int CT_NURBSCURVE = 1;
+
+ /**
+ * Curve type - picewise linear curve
+ */
+ public static final int CT_NPWLCURVE = 2;
+
+ /**
+ * Matrixes autoloading
+ */
+ private boolean autoloadmode;
+
+ /**
+ * Using callback
+ */
+ private int callBackFlag;
+
+ /**
+ * Object for error call backs
+ */
+ private Object errorCallback;
+
+ /**
+ * List of map definitions
+ */
+ Maplist maplist;
+
+ /**
+ * Indicates validity of data
+ */
+ private int isDataValid;
+
+ /**
+ * Are we in the middle of curve processing
+ */
+ private int inCurve;
+
+ /**
+ * Current curve
+ */
+ private O_curve currentCurve;
+
+ /**
+ * Are we in trim
+ */
+ private boolean inTrim;
+
+ /**
+ * Are we playbacking curve/surface rendering
+ */
+ private boolean playBack;
+
+ /**
+ * Next curve in linked list
+ */
+ private O_curve nextCurve;
+
+ /**
+ * Is curve modified
+ */
+ private int isCurveModified;
+
+ /**
+ * Object holding rendering settings
+ */
+ private Renderhints renderhints;
+
+ /**
+ * Display list
+ */
+ private DisplayList dl;
+
+ /**
+ * Object for subdividing curves and surfaces
+ */
+ private Subdivider subdivider;
+
+ /**
+ * Object responsible for rendering
+ */
+ private Backend backend;
+
+ /**
+ * Next picewise linear curve in linked list
+ */
+ private O_pwlcurve nextPwlcurve;
+
+ /**
+ * Next trimming NURBS curve in linked list
+ */
+ private O_nurbscurve nextNurbscurve;
+
+ /**
+ * Are we in the middle of surface processing
+ */
+ private int inSurface;
+
+ /**
+ * Are there any changes in trimming
+ */
+ private boolean isTrimModified;
+
+ /**
+ * Are there any changes in surface data
+ */
+ private boolean isDataSurfaceModified;
+
+ /**
+ * Nurber of trmims of processed surface
+ */
+ private int numTrims;
+
+ /**
+ * Current processed surface
+ */
+ private O_surface currentSurface;
+
+ /**
+ * Next trimming curve
+ */
+ private O_trim nextTrim;
+
+ /**
+ * Nextr surface in linked list
+ */
+ private O_nurbssurface nextNurbssurface;
+
+ /**
+ * Are there any changes in surface
+ */
+ private boolean isSurfaceModified;
+
+ /**
+ * Initializes default GLUgl2nurbs object
+ */
+ public GLUgl2nurbsImpl() {
+ // DONE
+ maplist = new Maplist(backend);
+ renderhints = new Renderhints();
+ subdivider = new Subdivider();
+ // original code
+
+ redefineMaps();
+
+ defineMap(GL2.GL_MAP2_NORMAL, 0, 3);
+ defineMap(GL2.GL_MAP1_NORMAL, 0, 3);
+ defineMap(GL2.GL_MAP2_TEXTURE_COORD_1, 0, 1);
+ defineMap(GL2.GL_MAP1_TEXTURE_COORD_1, 0, 1);
+ defineMap(GL2.GL_MAP2_TEXTURE_COORD_2, 0, 2);
+ defineMap(GL2.GL_MAP1_TEXTURE_COORD_2, 0, 2);
+ defineMap(GL2.GL_MAP2_TEXTURE_COORD_3, 0, 3);
+ defineMap(GL2.GL_MAP1_TEXTURE_COORD_3, 0, 3);
+ defineMap(GL2.GL_MAP2_TEXTURE_COORD_4, 1, 4);
+ defineMap(GL2.GL_MAP1_TEXTURE_COORD_4, 1, 4);
+ defineMap(GL2.GL_MAP2_VERTEX_4, 1, 4);
+ defineMap(GL2.GL_MAP1_VERTEX_4, 1, 4);
+ defineMap(GL2.GL_MAP2_VERTEX_3, 0, 3);
+ defineMap(GL2.GL_MAP1_VERTEX_3, 0, 3);
+ defineMap(GL2.GL_MAP2_COLOR_4, 0, 4);
+ defineMap(GL2.GL_MAP1_COLOR_4, 0, 4);
+ defineMap(GL2.GL_MAP2_INDEX, 0, 1);
+ defineMap(GL2.GL_MAP1_INDEX, 0, 1);
+
+ setnurbsproperty(GL2.GL_MAP1_VERTEX_3, NurbsConsts.N_SAMPLINGMETHOD,
+ (float) NurbsConsts.N_PATHLENGTH);
+ setnurbsproperty(GL2.GL_MAP1_VERTEX_4, NurbsConsts.N_SAMPLINGMETHOD,
+ (float) NurbsConsts.N_PATHLENGTH);
+ setnurbsproperty(GL2.GL_MAP2_VERTEX_3, NurbsConsts.N_SAMPLINGMETHOD,
+ (float) NurbsConsts.N_PATHLENGTH);
+ setnurbsproperty(GL2.GL_MAP2_VERTEX_4, NurbsConsts.N_SAMPLINGMETHOD,
+ (float) NurbsConsts.N_PATHLENGTH);
+
+ setnurbsproperty(GL2.GL_MAP1_VERTEX_3, NurbsConsts.N_PIXEL_TOLERANCE,
+ (float) 50.0);
+ setnurbsproperty(GL2.GL_MAP1_VERTEX_4, NurbsConsts.N_PIXEL_TOLERANCE,
+ (float) 50.0);
+ setnurbsproperty(GL2.GL_MAP2_VERTEX_3, NurbsConsts.N_PIXEL_TOLERANCE,
+ (float) 50.0);
+ setnurbsproperty(GL2.GL_MAP2_VERTEX_4, NurbsConsts.N_PIXEL_TOLERANCE,
+ (float) 50.0);
+
+ setnurbsproperty(GL2.GL_MAP1_VERTEX_3, NurbsConsts.N_ERROR_TOLERANCE,
+ (float) 0.50);
+ setnurbsproperty(GL2.GL_MAP1_VERTEX_4, NurbsConsts.N_ERROR_TOLERANCE,
+ (float) 0.50);
+ setnurbsproperty(GL2.GL_MAP2_VERTEX_3, NurbsConsts.N_ERROR_TOLERANCE,
+ (float) 0.50);
+ setnurbsproperty(GL2.GL_MAP2_VERTEX_4, NurbsConsts.N_ERROR_TOLERANCE,
+ (float) 0.50);
+
+ setnurbsproperty(GL2.GL_MAP1_VERTEX_3, NurbsConsts.N_S_STEPS,
+ (float) 100.0);
+ setnurbsproperty(GL2.GL_MAP1_VERTEX_4, NurbsConsts.N_S_STEPS,
+ (float) 100.0);
+ setnurbsproperty(GL2.GL_MAP2_VERTEX_3, NurbsConsts.N_S_STEPS,
+ (float) 100.0);
+ setnurbsproperty(GL2.GL_MAP2_VERTEX_4, NurbsConsts.N_S_STEPS,
+ (float) 100.0);
+
+ setnurbsproperty(GL2.GL_MAP1_VERTEX_3, NurbsConsts.N_SAMPLINGMETHOD,
+ NurbsConsts.N_PATHLENGTH);
+
+ set_domain_distance_u_rate(100.0);
+ set_domain_distance_v_rate(100.0);
+ set_is_domain_distance_sampling(0);
+
+ this.autoloadmode = true;
+
+ this.callBackFlag = 0;
+
+ this.errorCallback = null;
+ }
+
+ /**
+ * Sets domain distance for dom.dist. sampling in u direction
+ *
+ * @param d
+ * distance
+ */
+ private void set_domain_distance_u_rate(double d) {
+ // DONE
+ subdivider.set_domain_distance_u_rate(d);
+ }
+
+ /**
+ * Sets domain distance for dom.dist. sampling in v direction
+ *
+ * @param d
+ * distance
+ */
+ private void set_domain_distance_v_rate(double d) {
+ // DONE
+ subdivider.set_domain_distance_v_rate(d);
+ }
+
+ /**
+ * Begins new NURBS curve
+ */
+ public void bgncurve() {
+ // DONE
+ O_curve o_curve = new O_curve();
+ thread("do_bgncurve", o_curve);
+ }
+
+ /**
+ * Calls a method with given name and passes argumet
+ *
+ * @param name
+ * name of a method to be called
+ * @param arg
+ * parameter to be passed to called method
+ */
+ private void thread(String name, Object arg) {
+ // DONE
+ Class partype[] = new Class[1];
+ partype[0] = arg.getClass();
+ Method m;
+ try {
+ m = this.getClass().getMethod(name, partype);
+ if (dl != null) {
+ dl.append(this, m, arg);
+ } else {
+ m.invoke(this, new Object[] { arg });
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Calls a method with given name
+ *
+ * @param name
+ * name of a method to be called
+ */
+ private void thread2(String name) {
+ // DONE
+ try {
+ Method m = this.getClass().getMethod(name, (Class[]) null);
+ if (dl != null) {
+ dl.append(this, m, null);
+ } else {
+ m.invoke(this, (Object[]) null);
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Begins a NURBS curve
+ *
+ * @param o_curve
+ * curve object
+ */
+ public void do_bgncurve(O_curve o_curve) {
+ if (inCurve > 0) {
+ do_nurbserror(6);
+ endcurve();
+ }
+ inCurve = 1;
+ currentCurve = o_curve;
+
+ currentCurve.curvetype = CT_NONE;
+
+ if (inTrim) {
+ if (!nextCurve.equals(o_curve)) {
+ isCurveModified = 1;
+ nextCurve = o_curve;
+ }
+ } else {
+ if (!playBack)
+ bgnrender();
+ isDataValid = 1;
+ }
+ nextCurve = o_curve.next;
+ // kind of solution of union
+ nextPwlcurve = o_curve.o_pwlcurve;
+ nextNurbscurve = o_curve.o_nurbscurve;
+ }
+
+ /**
+ * Begins new surface
+ *
+ * @param o_surface
+ * surface object
+ */
+ public void do_bgnsurface(O_surface o_surface) {
+ // DONE
+ if (inSurface > 0) {
+ do_nurbserror(27);
+ endsurface();
+ }
+ inSurface = 1;
+ if (!playBack)
+ bgnrender();
+
+ isTrimModified = false;
+ isDataSurfaceModified = false;
+ isDataValid = 1;
+ numTrims = 0;
+ currentSurface = o_surface;
+ nextTrim = o_surface.o_trim;
+ nextNurbssurface = o_surface.o_nurbssurface;
+ }
+
+ /**
+ * End a curve
+ */
+ public void endcurve() {
+ // DONE
+ thread2("do_endcurve");
+ }
+
+ /**
+ * Ends surface
+ */
+ public void do_endsurface() {
+ // DONE
+ if (inTrim) {
+ do_nurbserror(12);
+ endtrim();
+ }
+
+ if (inSurface <= 0) {
+ do_nurbserror(13);
+ return;
+ }
+
+ inSurface = 0;
+
+ nextNurbssurface = null;
+
+ if (isDataValid <= 0) {
+ return;
+ }
+
+ if (nextTrim != null) {
+ isTrimModified = true;
+ nextTrim = null;
+ }
+
+ // TODO errval ??
+ if (numTrims > 0) {
+ // System.out.println("TODO glunurbs.do_endsurface - numtrims > 0");
+ }
+
+ subdivider.beginQuilts(new GL2Backend());
+ for (O_nurbssurface n = currentSurface.o_nurbssurface; n != null; n = n.next) {
+ subdivider.addQuilt(n.bezier_patches);
+ }
+ subdivider.endQuilts();
+ subdivider.drawSurfaces();
+ if (!playBack)
+ endrender();
+
+ }
+
+ /**
+ * Ends a curve
+ */
+ public void do_endcurve() {
+ // DONE
+ // // System.out.println("do_endcurve");
+ if (inCurve <= 0) {
+ do_nurbserror(7);
+ return;
+ }
+ inCurve = 0;
+
+ nextCurve = null;
+
+ if (currentCurve.curvetype == CT_NURBSCURVE) {
+ // nextNurbscurve = null;
+ // currentCurve.o_nurbscurve=null;
+ } else {
+ // nextPwlcurve = null;
+ // currentCurve.o_pwlcurve=null;
+ }
+ if (!inTrim) {
+ if (isDataValid <= 0) {
+ return;
+ }
+ // TODO errval?
+ if (currentCurve.curvetype == CT_NURBSCURVE) {
+ subdivider.beginQuilts(new GL2Backend());
+
+ for (O_nurbscurve n = currentCurve.o_nurbscurve; n != null; n = n.next)
+ subdivider.addQuilt(n.bezier_curves);
+
+ subdivider.endQuilts();
+ subdivider.drawCurves();
+ if (!playBack)
+ endrender();
+ } else {
+ if (!playBack)
+ endrender();
+ do_nurbserror(9);
+ }
+ }
+
+ }
+
+ /**
+ * Method for handling error codes
+ *
+ * @param i
+ * error code
+ */
+ private void do_nurbserror(int i) {
+ // TODO nurberror
+ // System.out.println("TODO nurbserror " + i);
+ }
+
+ /**
+ * Begin rendering
+ */
+ private void bgnrender() {
+ // DONE
+ if (autoloadmode) {
+ loadGLMatrices();
+ }
+ }
+
+ /**
+ * Load matrices from OpenGL state machine
+ */
+ private void loadGLMatrices() {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO glunurbs.loadGLMatrices");
+ }
+
+ /**
+ * End rendering
+ */
+ private void endrender() {
+ // DONE
+ }
+
+ /**
+ * Make a NURBS curve
+ *
+ * @param nknots
+ * number of knots in knot vector
+ * @param knot
+ * knot vector
+ * @param stride
+ * number of control points coordinates
+ * @param ctlarray
+ * control points
+ * @param order
+ * order of the curve
+ * @param realType
+ * type of the curve
+ */
+ public void nurbscurve(int nknots, float[] knot, int stride,
+ float[] ctlarray, int order, int realType) {
+ // DONE
+ Mapdesc mapdesc = maplist.locate(realType);
+ if (mapdesc == null) {
+ do_nurbserror(35);
+ isDataValid = 0;
+ return;
+ }
+ if (ctlarray == null) {
+ do_nurbserror(36);
+ isDataValid = 0;
+ return;
+ }
+ if (stride < 0) {
+ do_nurbserror(34);
+ isDataValid = 0;
+ return;
+ }
+ Knotvector knots = new Knotvector(nknots, stride, order, knot);
+
+ if (!do_check_knots(knots, "curve"))
+ return;
+
+ O_nurbscurve o_nurbscurve = new O_nurbscurve(realType);
+ o_nurbscurve.bezier_curves = new Quilt(mapdesc);
+ CArrayOfFloats ctrlcarr = new CArrayOfFloats(ctlarray);
+ o_nurbscurve.bezier_curves.toBezier(knots, ctrlcarr, mapdesc
+ .getNCoords());
+ thread("do_nurbscurve", o_nurbscurve);
+ }
+
+ /**
+ * Check knot vector specification
+ *
+ * @param knots
+ * knot vector
+ * @param msg
+ * error message
+ * @return knot vector is / is not valid
+ */
+ public boolean do_check_knots(Knotvector knots, String msg) {
+ // DONE
+ int status = knots.validate();
+ if (status > 0) {
+ do_nurbserror(status);
+ if (renderhints.errorchecking != NurbsConsts.N_NOMSG)
+ knots.show(msg);
+ }
+ return (status > 0) ? false : true;
+ }
+
+ /**
+ * Draw a curve
+ *
+ * @param o_nurbscurve
+ * NURBS curve object
+ */
+ public void do_nurbscurve(O_nurbscurve o_nurbscurve) {
+ // DONE
+
+ if (inCurve <= 0) {
+ bgncurve();
+ inCurve = 2;
+ }
+
+ if (o_nurbscurve.used) {
+ do_nurbserror(23);
+ isDataValid = 0;
+ return;
+ } else
+ o_nurbscurve.used = true;
+
+ if (currentCurve.curvetype == CT_NONE) {
+ currentCurve.curvetype = CT_NURBSCURVE;
+ } else if (currentCurve.curvetype != CT_NURBSCURVE) {
+ do_nurbserror(24);
+ isDataValid = 0;
+ return;
+ }
+
+ // it was necessary to overcome problem with pointer to pointer here
+
+ // if(!o_nurbscurve.equals(nextNurbscurve)){
+ if (!o_nurbscurve.equals(currentCurve.o_nurbscurve)) {
+ isCurveModified = 1;
+ currentCurve.o_nurbscurve = o_nurbscurve;
+ // nextNurbscurve=o_nurbscurve;
+
+ }
+
+ nextNurbscurve = o_nurbscurve.next;
+
+ if (!currentCurve.equals(o_nurbscurve.owner)) {
+ isCurveModified = 1;
+ o_nurbscurve.owner = currentCurve;
+ }
+
+ if (o_nurbscurve.owner == null)
+ isCurveModified = 1;
+
+ if (inCurve == 2)
+ endcurve();
+ }
+
+ /**
+ * Draw NURBS surface
+ *
+ * @param o_nurbssurface
+ * NURBS surface object
+ */
+ public void do_nurbssurface(O_nurbssurface o_nurbssurface) {
+ // DONE
+ if (inSurface <= 0) {
+ bgnsurface();
+ inSurface = 2;
+ }
+ if (o_nurbssurface.used) {
+ do_nurbserror(25);
+ isDataValid = 0;
+ return;
+ } else
+ o_nurbssurface.used = true;
+
+ if (!o_nurbssurface.equals(nextNurbscurve)) {
+ isSurfaceModified = true;
+ // nextNurbssurface=o_nurbssurface;
+ currentSurface.o_nurbssurface = o_nurbssurface;
+ }
+
+ if (!currentSurface.equals(o_nurbssurface.owner)) {
+ isSurfaceModified = true;
+ o_nurbssurface.owner = currentSurface;
+ }
+
+ nextNurbssurface = o_nurbssurface.next;
+
+ if (inSurface == 2)
+ endsurface();
+ }
+
+ /**
+ * (Re)Inicialize maps
+ */
+ public void redefineMaps() {
+ // DONE
+ maplist.initialize();
+ }
+
+ /**
+ * Define a map of given properties
+ *
+ * @param type
+ * map type
+ * @param rational
+ * is rational
+ * @param ncoords
+ * number of control point coordinates
+ */
+ public void defineMap(int type, int rational, int ncoords) {
+ // DONE
+ maplist.define(type, rational, ncoords);
+ }
+
+ /**
+ * Set NURBS property
+ *
+ * @param type
+ * property type
+ * @param tag
+ * property tag
+ * @param value
+ * property value
+ */
+ public void setnurbsproperty(int type, int tag, float value) {
+ // DONE
+ Mapdesc mapdesc = maplist.locate(type);
+ if (mapdesc == null) {
+ do_nurbserror(35);
+ return;
+ }
+ if (!mapdesc.isProperty(tag)) {
+ do_nurbserror(26);
+ return;
+ }
+ Property prop = new Property(type, tag, value);
+ thread("do_setnurbsproperty2", prop);
+ }
+
+ /**
+ * Set parameters of existing property
+ *
+ * @param prop
+ * property
+ */
+ public void do_setnurbsproperty2(Property prop) {
+ Mapdesc mapdesc = maplist.find(prop.type);
+ mapdesc.setProperty(prop.tag, prop.value);
+ }
+
+ /**
+ * Set given property to rendering hints
+ *
+ * @param prop
+ * property to be set
+ */
+ public void do_setnurbsproperty(Property prop) {
+ // DONE
+ renderhints.setProperty(prop);
+ // TODO freeproperty?
+ }
+
+ /**
+ * Sets wheteher we use domain distance sampling
+ *
+ * @param i
+ * domain distance sampling flag
+ */
+ public void set_is_domain_distance_sampling(int i) {
+ // DONE
+ subdivider.set_is_domain_distance_sampling(i);
+ }
+
+ /**
+ * Begin new surface
+ */
+ public void bgnsurface() {
+ // DONE
+ O_surface o_surface = new O_surface();
+ // TODO nuid
+ // System.out.println("TODO glunurbs.bgnsurface nuid");
+ thread("do_bgnsurface", o_surface);
+ }
+
+ /**
+ * End current surface
+ */
+ public void endsurface() {
+ // DONE
+ thread2("do_endsurface");
+ }
+
+ /**
+ * End surface trimming
+ */
+ private void endtrim() {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO glunurbs.endtrim");
+ }
+
+ /**
+ * Make NURBS surface
+ *
+ * @param sknot_count
+ * number of knots in s direction
+ * @param sknot
+ * knot vector in s direction
+ * @param tknot_count
+ * number of knots in t direction
+ * @param tknot
+ * knot vector in t direction
+ * @param s_stride
+ * number of coords of control points in s direction
+ * @param t_stride
+ * number of coords of control points in t direction
+ * @param ctlarray
+ * control points
+ * @param sorder
+ * order of curve in s direction
+ * @param torder
+ * order of curve in t direction
+ * @param type
+ * NURBS surface type (rational,...)
+ */
+ public void nurbssurface(int sknot_count, float[] sknot, int tknot_count,
+ float[] tknot, int s_stride, int t_stride, float[] ctlarray,
+ int sorder, int torder, int type) {
+ // DONE
+ Mapdesc mapdesc = maplist.locate(type);
+ if (mapdesc == null) {
+ do_nurbserror(35);
+ isDataValid = 0;
+ return;
+ }
+ if (s_stride < 0 || t_stride < 0) {
+ do_nurbserror(34);
+ isDataValid = 0;
+ return;
+ }
+ Knotvector sknotvector = new Knotvector(sknot_count, s_stride, sorder,
+ sknot);
+ if (!do_check_knots(sknotvector, "surface"))
+ return;
+ Knotvector tknotvector = new Knotvector(tknot_count, t_stride, torder,
+ tknot);
+ if (!do_check_knots(tknotvector, "surface"))
+ return;
+
+ O_nurbssurface o_nurbssurface = new O_nurbssurface(type);
+ o_nurbssurface.bezier_patches = new Quilt(mapdesc);
+
+ CArrayOfFloats ctrlarr = new CArrayOfFloats(ctlarray);
+ o_nurbssurface.bezier_patches.toBezier(sknotvector, tknotvector,
+ ctrlarr, mapdesc.getNCoords());
+ thread("do_nurbssurface", o_nurbssurface);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/BuildMipmap.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/BuildMipmap.java
new file mode 100644
index 000000000..501f5f585
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/BuildMipmap.java
@@ -0,0 +1,1598 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.glu.GLU;
+import com.jogamp.opengl.impl.Debug;
+import com.jogamp.opengl.impl.InternalBufferUtil;
+import java.nio.*;
+import java.io.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class BuildMipmap {
+
+ private static final boolean DEBUG = Debug.debug("BuildMipmap");
+ private static final boolean VERBOSE = Debug.verbose();
+
+ /** Creates a new instance of BuildMipmap */
+ public BuildMipmap() {
+ }
+
+ public static int gluBuild1DMipmapLevelsCore( GL gl, int target, int internalFormat,
+ int width, int widthPowerOf2, int format, int type, int userLevel,
+ int baseLevel, int maxLevel, ByteBuffer data ) {
+ int newwidth;
+ int level, levels;
+ ShortBuffer newImage = null;
+ int newImage_width;
+ ShortBuffer otherImage = null;
+ ShortBuffer imageTemp = null;
+ int memReq;
+ int maxsize;
+ int cmpts;
+ PixelStorageModes psm = new PixelStorageModes();
+
+ assert( Mipmap.checkMipmapArgs( internalFormat, format, type ) == 0 );
+ assert( width >= 1 );
+
+ newwidth = widthPowerOf2;
+ levels = Mipmap.computeLog( newwidth );
+
+ levels += userLevel;
+
+ Mipmap.retrieveStoreModes( gl, psm );
+ try {
+ newImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( Mipmap.image_size( width, 1, format,
+ GL2.GL_UNSIGNED_SHORT ) )).asShortBuffer();
+ } catch( OutOfMemoryError ome ) {
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ newImage_width = width;
+
+ Image.fill_image( psm, width, 1, format, type, Mipmap.is_index( format ), data, newImage );
+ cmpts = Mipmap.elements_per_group( format, type );
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, 2 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, 0 );
+
+ // if swap_bytes was set, swapping occurred in fill_image
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE );
+
+ for( level = userLevel; level <= levels; level++ ) {
+ if( newImage_width == newwidth ) {
+ // user newimage for this level
+ if( baseLevel <= level && level <= maxLevel ) {
+ gl.getGL2().glTexImage1D( target, level, internalFormat, newImage_width, 0, format,
+ GL2.GL_UNSIGNED_SHORT, newImage );
+ }
+ } else {
+ if( otherImage == null ) {
+ memReq = Mipmap.image_size( newwidth, 1, format, GL2.GL_UNSIGNED_SHORT );
+ try {
+ otherImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )).asShortBuffer();
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ }
+ ScaleInternal.scale_internal( cmpts, newImage_width, 1, newImage, newwidth, 1, otherImage );
+ // swap newImage and otherImage
+ imageTemp = otherImage;
+ otherImage = newImage;
+ newImage = imageTemp;
+
+ newImage_width = newwidth;
+ if( baseLevel <= level && level <= maxLevel ) {
+ gl.getGL2().glTexImage1D( target, level, internalFormat, newImage_width, 0,
+ format, GL2.GL_UNSIGNED_SHORT, newImage );
+ }
+ }
+ if( newwidth > 1 ) {
+ newwidth /= 2;
+ }
+ }
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+
+ return( 0 );
+ }
+
+ public static int bitmapBuild2DMipmaps( GL gl, int target, int internalFormat,
+ int width, int height, int format, int type, ByteBuffer data ) {
+ int newwidth[] = new int[1];
+ int newheight[] = new int[1];
+ int level, levels;
+ ShortBuffer newImage = null;
+ int newImage_width;
+ int newImage_height;
+ ShortBuffer otherImage = null;
+ ShortBuffer tempImage = null;
+ int memReq;
+ int maxsize;
+ int cmpts;
+ PixelStorageModes psm = new PixelStorageModes();
+
+ Mipmap.retrieveStoreModes( gl, psm );
+
+ Mipmap.closestFit( gl, target, width, height, internalFormat, format, type, newwidth, newheight );
+
+ levels = Mipmap.computeLog( newwidth[0] );
+ level = Mipmap.computeLog( newheight[0] );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ try {
+ newImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( Mipmap.image_size( width, height,
+ format, GL2.GL_UNSIGNED_SHORT ) )).asShortBuffer();
+ } catch( OutOfMemoryError ome ) {
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ newImage_width = width;
+ newImage_height = height;
+
+ Image.fill_image( psm, width, height, format, type, Mipmap.is_index( format ), data, newImage );
+
+ cmpts = Mipmap.elements_per_group( format, type );
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, 2 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, 0 );
+
+ // if swap_bytes is set, swapping occurred in fill_image
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE );
+
+ for( level = 0; level < levels; level++ ) {
+ if( newImage_width == newwidth[0] && newImage_height == newheight[0] ) {
+ newImage.rewind();
+ gl.glTexImage2D( target, level, internalFormat, newImage_width,
+ newImage_height, 0, format, GL2.GL_UNSIGNED_SHORT, newImage );
+ } else {
+ if( otherImage == null ) {
+ memReq = Mipmap.image_size( newwidth[0], newheight[0], format, GL2.GL_UNSIGNED_SHORT );
+ try {
+ otherImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )).asShortBuffer();
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ }
+ ScaleInternal.scale_internal( cmpts, newImage_width, newImage_height,
+ newImage, newwidth[0], newheight[0], otherImage );
+ // swap newImage and otherImage
+ tempImage = otherImage;
+ otherImage = newImage;
+ newImage = tempImage;
+
+ newImage_width = newwidth[0];
+ newImage_height = newheight[0];
+ newImage.rewind();
+ gl.glTexImage2D( target, level, internalFormat, newImage_width, newImage_height,
+ 0, format, GL2.GL_UNSIGNED_SHORT, newImage );
+ }
+ if( newheight[0] > 1 ) {
+ newwidth[0] /= 2;
+ }
+ if( newheight[0] > 1 ) {
+ newheight[0] /= 2;
+ }
+ }
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+
+ return( 0 );
+ }
+
+ public static int gluBuild2DMipmapLevelsCore( GL gl, int target, int internalFormat,
+ int width, int height, int widthPowerOf2, int heightPowerOf2,
+ int format, int type, int userLevel, int baseLevel, int maxLevel,
+ ByteBuffer data ) { // PointerWrapper data
+ int newwidth;
+ int newheight;
+ int level, levels;
+ int usersImage;
+ ByteBuffer srcImage = null;
+ ByteBuffer dstImage = null;
+ ByteBuffer tempImage = null;
+ int newImage_width;
+ int newImage_height;
+ short[] SWAP_IMAGE = null;
+ int memReq;
+ int maxsize;
+ int cmpts;
+ int mark=-1;
+
+ boolean myswap_bytes;
+ int groups_per_line, element_size, group_size;
+ int rowsize, padding;
+ PixelStorageModes psm = new PixelStorageModes();
+
+ assert( Mipmap.checkMipmapArgs( internalFormat, format, type ) == 0 );
+ assert( width >= 1 && height >= 1 );
+
+ if( type == GL2.GL_BITMAP ) {
+ return( bitmapBuild2DMipmaps( gl, target, internalFormat, width, height, format, type, data ) );
+ }
+
+ newwidth = widthPowerOf2;
+ newheight = heightPowerOf2;
+ levels = Mipmap.computeLog( newwidth );
+ level = Mipmap.computeLog( newheight );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ levels += userLevel;
+
+ Mipmap.retrieveStoreModes( gl, psm );
+ myswap_bytes = psm.getUnpackSwapBytes();
+ cmpts = Mipmap.elements_per_group( format, type );
+ if( psm.getUnpackRowLength() > 0 ) {
+ groups_per_line = psm.getUnpackRowLength();
+ } else {
+ groups_per_line = width;
+ }
+
+ element_size = Mipmap.bytes_per_element( type );
+ group_size = element_size * cmpts;
+ if( element_size == 1 ) {
+ myswap_bytes = false;
+ }
+
+ rowsize = groups_per_line * group_size;
+ padding = ( rowsize % psm.getUnpackAlignment() );
+ if( padding != 0 ) {
+ rowsize += psm.getUnpackAlignment() - padding;
+ }
+
+ mark = psm.getUnpackSkipRows() * rowsize + psm.getUnpackSkipPixels() * group_size;
+ data.position( mark );
+
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, 0 );
+
+ level = userLevel;
+
+ // already power of two square
+ if( width == newwidth && height == newheight ) {
+ // use usersImage for level userLevel
+ if( baseLevel <= level && level <= maxLevel ) {
+ data.rewind();
+ gl.glTexImage2D( target, level, internalFormat, width, height, 0, format, type, data );
+ }
+ if( levels == 0 ) { /* we're done. clean up and return */
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( 0 );
+ }
+ int nextWidth = newwidth / 2;
+ int nextHeight = newheight / 2;
+
+ // clamp to 1
+ if( nextWidth < 1 ) {
+ nextWidth = 1;
+ }
+ if( nextHeight < 1 ) {
+ nextHeight = 1;
+ }
+ memReq = Mipmap.image_size( nextWidth, nextHeight, format, type );
+
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq ));
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ if( dstImage != null ) {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ HalveImage.halveImage_ubyte( cmpts, width, height, data, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_BYTE ):
+ HalveImage.halveImage_byte( cmpts, width, height, data, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ HalveImage.halveImage_ushort( cmpts, width, height, data, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_SHORT ):
+ HalveImage.halveImage_short( cmpts, width, height, data, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT ):
+ HalveImage.halveImage_uint( cmpts, width, height, data, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_INT ):
+ HalveImage.halveImage_int( cmpts, width, height, data, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_FLOAT ):
+ HalveImage.halveImage_float( cmpts, width, height, data, dstImage.asFloatBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel( 3, new Extract332(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel( 3, new Extract233rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ HalveImage.halveImagePackedPixel( 3, new Extract565(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ HalveImage.halveImagePackedPixel( 3, new Extract565rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract4444(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract4444rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract5551(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract1555rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract8888(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract8888rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract1010102(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract2101010rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+ }
+ newwidth = width / 2;
+ newheight = height / 2;
+ // clamp to 1
+ if( newwidth < 1 ) {
+ newwidth = 1;
+ }
+ if( newheight < 1 ) {
+ newheight = 1;
+ }
+
+ myswap_bytes = false;
+ rowsize = newwidth * group_size;
+ memReq = Mipmap.image_size( newwidth, newheight, format, type );
+ // swap srcImage and dstImage
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq ));
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ // level userLevel+1 is in srcImage; level userLevel already saved
+ level = userLevel + 1;
+ } else { // user's image is not nice powerof2 size square
+ memReq = Mipmap.image_size( newwidth, newheight, format, type );
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq ));
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ data.position( mark );
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ ScaleInternal.scale_internal_ubyte( cmpts, width, height, data,
+ newwidth, newheight, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_BYTE ):
+ ScaleInternal.scale_internal_byte( cmpts, width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ ScaleInternal.scale_internal_ushort( cmpts, width, height, data, newwidth,
+ newheight, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_SHORT ):
+ ScaleInternal.scale_internal_ushort( cmpts, width, height, data, newwidth,
+ newheight, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT ):
+ ScaleInternal.scale_internal_uint( cmpts, width, height, data, newwidth,
+ newheight, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_INT ):
+ ScaleInternal.scale_internal_int( cmpts, width, height, data, newwidth,
+ newheight, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_FLOAT ):
+ ScaleInternal.scale_internal_float( cmpts, width, height, data, newwidth,
+ newheight, dstImage.asFloatBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ ScaleInternal.scaleInternalPackedPixel( 3, new Extract332(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 3, new Extract233rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ ScaleInternal.scaleInternalPackedPixel( 3, new Extract565(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 3, new Extract565rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract4444(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract4444rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract5551(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract1555rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract8888(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract8888rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract1010102(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract2101010rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+ myswap_bytes = false;
+ rowsize = newwidth * group_size;
+ // swap dstImage and srcImage
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+
+ if( levels != 0 ) { // use as little memory as possible
+ int nextWidth = newwidth / 2;
+ int nextHeight = newheight / 2;
+ if( nextWidth < 1 ) {
+ nextWidth = 1;
+ }
+ if( nextHeight < 1 ) {
+ nextHeight = 1;
+ }
+
+ memReq = Mipmap.image_size( nextWidth, nextHeight, format, type );
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq ));
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ }
+ // level userLevel is in srcImage; nothing saved yet
+ level = userLevel;
+ }
+
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE );
+ if( baseLevel <= level && level <= maxLevel ) {
+ srcImage.rewind();
+ gl.glTexImage2D( target, level, internalFormat, newwidth, newheight, 0, format, type, srcImage );
+ if (DEBUG) {
+ System.err.println("GL Error(" + level + "): " + gl.glGetError() );
+ if (VERBOSE) {
+ srcImage.limit( Mipmap.image_size( newwidth, newheight, format, type ) );
+ writeTargaFile("glu2DMipmapJ" + level + ".tga",
+ srcImage, newwidth, newheight);
+ srcImage.clear();
+ }
+ }
+ }
+
+ level++; // update current level for the loop
+ for( ; level <= levels; level++ ) {
+ srcImage.rewind();
+ dstImage.rewind();
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ HalveImage.halveImage_ubyte( cmpts, newwidth, newheight, srcImage, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_BYTE ):
+ HalveImage.halveImage_byte( cmpts, newwidth, newheight, srcImage, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ HalveImage.halveImage_ushort( cmpts, newwidth, newheight, srcImage, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_SHORT ):
+ HalveImage.halveImage_short( cmpts, newwidth, newheight, srcImage, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT ):
+ HalveImage.halveImage_uint( cmpts, newwidth, newheight, srcImage, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_INT ):
+ HalveImage.halveImage_int( cmpts, newwidth, newheight, srcImage, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_FLOAT ):
+ HalveImage.halveImage_float( cmpts, newwidth, newheight, srcImage, dstImage.asFloatBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel( 3, new Extract332(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel( 3, new Extract233rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ HalveImage.halveImagePackedPixel( 3, new Extract565(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ HalveImage.halveImagePackedPixel( 3, new Extract565rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract4444(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract4444rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract5551(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract1555rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract8888(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract8888rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract1010102(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract2101010rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+
+ // swap dstImage and srcImage
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+
+ if( newwidth > 1 ) {
+ newwidth /= 2;
+ rowsize /= 2;
+ }
+ if( newheight > 1 ) {
+ newheight /= 2;
+ }
+ // compute amount to pad per row if any
+ int rowPad = rowsize % psm.getUnpackAlignment();
+
+ // should row be padded
+ if( rowPad == 0 ) {
+ // call teximage with srcImage untouched since its not padded
+ if( baseLevel <= level && level <= maxLevel ) {
+ srcImage.rewind();
+ gl.glTexImage2D( target, level, internalFormat, newwidth, newheight, 0, format, type, srcImage );
+ if (DEBUG) {
+ System.err.println("GL Error(" + level + "): " + gl.glGetError() );
+ if (VERBOSE) {
+ srcImage.limit( Mipmap.image_size( newwidth, newheight, format, type ) );
+ writeTargaFile("glu2DMipmapJ" + level + ".tga",
+ srcImage, newwidth, newheight);
+ srcImage.clear();
+ }
+ }
+ }
+ } else {
+ // compute length of new row in bytes, including padding
+ int newRowLength = rowsize + psm.getUnpackAlignment() - rowPad;
+ int ii, jj;
+ int dstTrav;
+ int srcTrav;
+
+ // allocate new image for mipmap of size newRowLength x newheight
+ ByteBuffer newMipmapImage = null;
+ try {
+ newMipmapImage = ByteBuffer.allocateDirect( newRowLength * newheight );
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ srcImage.rewind();
+ // copy image from srcImage into newMipmapImage by rows
+ for( ii = 0; ii < newheight; ii++ ) {
+ newMipmapImage.position(newRowLength * ii);
+ for( jj = 0; jj < rowsize; jj++ ) {
+ newMipmapImage.put( srcImage.get() );
+ }
+ }
+
+ // and use this new image for mipmapping instead
+ if( baseLevel <= level && level <= maxLevel ) {
+ newMipmapImage.rewind();
+ gl.glTexImage2D( target, level, internalFormat, newwidth, newheight, 0, format, type, newMipmapImage );
+ if (DEBUG) {
+ System.err.println("GL Error(" + level + " padded): " + gl.glGetError() );
+ if (VERBOSE) {
+ writeTargaFile("glu2DMipmapJ" + level + ".tga",
+ newMipmapImage, newwidth, newheight);
+ }
+ }
+ }
+ }
+ }
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+
+ return( 0 );
+ }
+
+ public static int fastBuild2DMipmaps( GL gl, PixelStorageModes psm, int target,
+ int components, int width, int height, int format, int type, ByteBuffer data ) {
+ int[] newwidth = new int[1];
+ int[] newheight = new int[1];
+ int level, levels;
+ ByteBuffer newImage;
+ int newImage_width;
+ int newImage_height;
+ ByteBuffer otherImage;
+ ByteBuffer imageTemp;
+ int memReq;
+ int maxsize;
+ int cmpts;
+
+ Mipmap.closestFit( gl, target, width, height, components, format, type, newwidth,
+ newheight );
+
+ levels = Mipmap.computeLog( newwidth[0] );
+ level = Mipmap.computeLog( newheight[0] );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ cmpts = Mipmap.elements_per_group( format, type );
+
+ otherImage = null;
+ // No need to copy the user data if its packed correctly.
+ // Make sure that later routines don't change that data.
+
+ if( psm.getUnpackSkipRows() == 0 && psm.getUnpackSkipPixels() == 0 ) {
+ newImage = data;
+ newImage_width = width;
+ newImage_height = height;
+ } else {
+ int rowsize;
+ int group_per_line;
+ int elements_per_line;
+ int start;
+ int iter;
+ int iter2;
+ int i, j;
+
+ try {
+ newImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( Mipmap.image_size(
+ width, height, format, GL2.GL_UNSIGNED_BYTE ) ));
+ } catch( OutOfMemoryError err ) {
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ newImage_width = width;
+ newImage_height = height;
+
+ // Abbreviated version of fill_image for the restricted case.
+ if( psm.getUnpackRowLength() > 0 ) {
+ group_per_line = psm.getUnpackRowLength();
+ } else {
+ group_per_line = width;
+ }
+ rowsize = group_per_line * cmpts;
+ elements_per_line = width * cmpts;
+ start = psm.getUnpackSkipRows() * rowsize + psm.getUnpackSkipPixels() * cmpts;
+
+ for( i = 0; i < height; i++ ) {
+ iter = start;
+ data.position( iter );
+ for( j = 0; j < elements_per_line; j++ ) {
+ newImage.put( data.get() );
+ }
+ start += rowsize;
+ }
+ }
+
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, 1 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE );
+
+ for( level = 0; level <= levels; level++ ) {
+ if( newImage_width == newwidth[0] && newImage_height == newheight[0] ) {
+ // use newImage for this level
+ newImage.rewind();
+ gl.glTexImage2D( target, level, components, newImage_width, newImage_height,
+ 0, format, GL2.GL_UNSIGNED_BYTE, newImage );
+ } else {
+ if( otherImage == null ) {
+ memReq = Mipmap.image_size( newwidth[0], newheight[0], format, GL2.GL_UNSIGNED_BYTE );
+ try {
+ otherImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq ));
+ } catch( OutOfMemoryError err ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, ( psm.getUnpackSwapBytes() ? 1 : 0 ) ) ;
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ }
+ // swap newImage and otherImage
+ imageTemp = otherImage;
+ otherImage = newImage;
+ newImage = imageTemp;
+
+ newImage_width = newwidth[0];
+ newImage_height = newheight[0];
+ newImage.rewind();
+ gl.glTexImage2D( target, level, components, newImage_width, newImage_height,
+ 0, format, GL2.GL_UNSIGNED_BYTE, newImage );
+ }
+ if( newwidth[0] > 1 ) {
+ newwidth[0] /= 2;
+ }
+ if( newheight[0] > 1 ) {
+ newheight[0] /= 2;
+ }
+ }
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, ( psm.getUnpackSwapBytes() ? 1 : 0 ) ) ;
+
+ return( 0 );
+ }
+
+ public static int gluBuild3DMipmapLevelsCore( GL gl, int target, int internalFormat,
+ int width, int height, int depth, int widthPowerOf2, int heightPowerOf2,
+ int depthPowerOf2, int format, int type, int userLevel, int baseLevel,
+ int maxLevel, ByteBuffer data ) {
+ int newWidth;
+ int newHeight;
+ int newDepth;
+ int level, levels;
+ ByteBuffer usersImage;
+ ByteBuffer srcImage, dstImage, tempImage;
+ int newImageWidth;
+ int newImageHeight;
+ int newImageDepth;
+ int memReq;
+ int maxSize;
+ int cmpts;
+ int mark=-1;
+
+ boolean myswapBytes;
+ int groupsPerLine, elementSize, groupSize;
+ int rowsPerImage, imageSize;
+ int rowSize, padding;
+ PixelStorageModes psm = new PixelStorageModes();
+
+ assert( Mipmap.checkMipmapArgs( internalFormat, format, type ) == 0 );
+ assert( width >= 1 && height >= 1 && depth >= 1 );
+ assert( type != GL2.GL_BITMAP );
+
+ srcImage = dstImage = null;
+
+ newWidth = widthPowerOf2;
+ newHeight = heightPowerOf2;
+ newDepth = depthPowerOf2;
+ levels = Mipmap.computeLog( newWidth );
+ level = Mipmap.computeLog( newHeight );
+ if( level > levels ) {
+ levels = level;
+ }
+ level = Mipmap.computeLog( newDepth );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ levels += userLevel;
+
+ Mipmap.retrieveStoreModes3D( gl, psm );
+ myswapBytes = psm.getUnpackSwapBytes();
+ cmpts = Mipmap.elements_per_group( format, type );
+ if( psm.getUnpackRowLength() > 0 ) {
+ groupsPerLine = psm.getUnpackRowLength();
+ } else {
+ groupsPerLine = width;
+ }
+
+ elementSize = Mipmap.bytes_per_element( type );
+ groupSize = elementSize * cmpts;
+ if( elementSize == 1 ) {
+ myswapBytes = false;
+ }
+
+ // 3dstuff
+ if( psm.getUnpackImageHeight() > 0 ) {
+ rowsPerImage = psm.getUnpackImageHeight();
+ } else {
+ rowsPerImage = height;
+ }
+
+ rowSize = groupsPerLine * groupSize;
+ padding = ( rowSize % psm.getUnpackAlignment() );
+ if( padding != 0 ) {
+ rowSize += psm.getUnpackAlignment() - padding;
+ }
+
+ imageSize = rowsPerImage * rowSize;
+
+ usersImage = ByteBuffer.wrap(data.array());
+ mark = psm.getUnpackSkipRows() * rowSize +
+ psm.getUnpackSkipPixels() * groupSize +
+ psm.getUnpackSkipImages() * imageSize;
+ usersImage.position( mark );
+
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, 0 );
+
+ level = userLevel;
+
+ if( width == newWidth && height == newHeight && depth == newDepth ) {
+ // use usersImage for level userlevel
+ if( baseLevel <= level && level <= maxLevel ) {
+ gl.getGL2().glTexImage3D( target, level, internalFormat, width, height, depth,
+ 0, format, type, usersImage );
+ }
+ if( levels == 0 ) { /* we're done. clean up and return */
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( 0 );
+ }
+ int nextWidth = newWidth / 2;
+ int nextHeight = newHeight / 2;
+ int nextDepth = newDepth / 2;
+
+ // clamp to one
+ if( nextWidth < 1 ) {
+ nextWidth = 1;
+ }
+ if( nextHeight < 1 ) {
+ nextHeight = 1;
+ }
+ if( nextDepth < 1 ) {
+ nextDepth = 1;
+ }
+ memReq = Mipmap.imageSize3D( nextWidth, nextHeight, nextDepth, format, type );
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq ));
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError err ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+
+ if( dstImage != null ) {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUByte(), width, height, depth,
+ usersImage, dstImage, elementSize,
+ groupSize, rowSize, imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_ubyte( cmpts, width, height, usersImage,
+ dstImage, elementSize, rowSize, groupSize );
+ }
+ break;
+ case( GL2.GL_BYTE ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSByte(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_byte( cmpts, width, height, usersImage,
+ dstImage, elementSize, rowSize, groupSize );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUShort(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_ushort( cmpts, width, height, usersImage,
+ dstImage.asShortBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_SHORT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSShort(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_short( cmpts, width, height, usersImage,
+ dstImage.asShortBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUInt(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_uint( cmpts, width, height, usersImage,
+ dstImage.asIntBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_INT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSInt(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_int( cmpts, width, height, usersImage,
+ dstImage.asIntBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_FLOAT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractFloat(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_float( cmpts, width, height, usersImage,
+ dstImage.asFloatBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel3D( 3, new Extract332(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel3D( 3, new Extract233rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract565(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract565rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract4444(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract4444rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract5551(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract1555rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract8888(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract8888rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract1010102(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract2101010rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+ }
+ newWidth = width / 2;
+ newHeight = height / 2;
+ newDepth = depth / 2;
+ // clamp to 1
+ if( newWidth < 1 ) {
+ newWidth = 1;
+ }
+ if( newHeight < 1 ) {
+ newHeight = 1;
+ }
+ if( newDepth < 1 ) {
+ newDepth = 1;
+ }
+
+ myswapBytes = false;
+ rowSize = newWidth * groupSize;
+ imageSize = rowSize * newHeight;
+ memReq = Mipmap.imageSize3D( newWidth, newHeight, newDepth, format, type );
+ // swap srcImage and dstImage
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq ));
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError err ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+
+ // level userLevel + 1 is in srcImage; level userLevel already saved
+ level = userLevel + 1;
+ } else {
+ memReq = Mipmap.imageSize3D( newWidth, newHeight, newDepth, format, type );
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq ));
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError err ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+
+ ScaleInternal.gluScaleImage3D( gl, format, width, height, depth, type,
+ usersImage, newWidth, newHeight, newDepth, type, dstImage );
+
+ myswapBytes = false;
+ rowSize = newWidth * groupSize;
+ imageSize = rowSize * newHeight;
+ // swap dstImage and srcImage
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+
+ if( levels != 0 ) {
+ int nextWidth = newWidth / 2;
+ int nextHeight = newHeight / 2;
+ int nextDepth = newDepth / 2;
+ if( nextWidth < 1 ) {
+ nextWidth = 1;
+ }
+ if( nextHeight < 1 ) {
+ nextHeight = 1;
+ }
+ if( nextDepth < 1 ) {
+ nextDepth = 1;
+ }
+ memReq = Mipmap.imageSize3D( nextWidth, nextHeight, nextDepth, format, type );
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq ));
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError err ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ }
+ // level userLevel is in srcImage; nothing saved yet
+ level = userLevel;
+ }
+
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE );
+ if( baseLevel <= level && level <= maxLevel ) {
+ usersImage.position( mark );
+ gl.getGL2().glTexImage3D( target, level, internalFormat, width, height, depth,
+ 0, format, type, usersImage );
+ }
+ level++;
+ for( ; level <= levels; level++ ) {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUByte(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_ubyte( cmpts, width, height, usersImage,
+ dstImage, elementSize, rowSize, groupSize );
+ }
+ break;
+ case( GL2.GL_BYTE ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSByte(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_byte( cmpts, width, height, usersImage,
+ dstImage, elementSize, rowSize, groupSize );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUShort(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_ushort( cmpts, width, height, usersImage,
+ dstImage.asShortBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_SHORT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSShort(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_short( cmpts, width, height, usersImage,
+ dstImage.asShortBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUInt(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_uint( cmpts, width, height, usersImage,
+ dstImage.asIntBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_INT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSInt(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_int( cmpts, width, height, usersImage,
+ dstImage.asIntBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_FLOAT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractFloat(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_float( cmpts, width, height, usersImage,
+ dstImage.asFloatBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract332(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract233rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract565(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract565rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract4444(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract4444rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract5551(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract1555rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract8888(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract8888rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract1010102(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract2101010rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+
+ if( newWidth > 1 ) {
+ newWidth /= 2;
+ rowSize /= 2;
+ }
+ if( newHeight > 1 ) {
+ newHeight /= 2;
+ imageSize = rowSize * newHeight;
+ }
+ if( newDepth > 1 ) {
+ newDepth /= 2;
+ }
+ if( baseLevel <= level && level <= maxLevel ) {
+ usersImage.position( mark );
+ gl.getGL2().glTexImage3D( target, level, internalFormat, width, height, depth,
+ 0, format, type, usersImage );
+ }
+ }
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( 0 );
+ }
+
+ private static final int TARGA_HEADER_SIZE = 18;
+ private static void writeTargaFile(String filename, ByteBuffer data,
+ int width, int height) {
+ try {
+ FileOutputStream fos = new FileOutputStream(new File(filename));
+ ByteBuffer header = ByteBuffer.allocateDirect(TARGA_HEADER_SIZE);
+ header.put(0, (byte) 0).put(1, (byte) 0);
+ header.put(2, (byte) 2); // uncompressed type
+ header.put(12, (byte) (width & 0xFF)); // width
+ header.put(13, (byte) (width >> 8)); // width
+ header.put(14, (byte) (height & 0xFF)); // height
+ header.put(15, (byte) (height >> 8)); // height
+ header.put(16, (byte) 24); // pixel size
+ fos.write(header.array());
+ fos.write(data.array());
+ data.clear();
+ fos.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract.java
new file mode 100644
index 000000000..be86585e7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract.java
@@ -0,0 +1,56 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author Administrator
+ */
+public interface Extract {
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents );
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel );
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract1010102.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract1010102.java
new file mode 100644
index 000000000..7e172b1ce
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract1010102.java
@@ -0,0 +1,97 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract1010102 implements Extract {
+
+ /** Creates a new instance of Extract1010102 */
+ public Extract1010102() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ long uint = 0;
+
+ if( isSwap ) {
+ uint = 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( packedPixel.getInt() );
+ } else {
+ uint = 0x00000000FFFFFFFF & packedPixel.getInt();
+ }
+
+ // 11111111,11000000,00000000,00000000 == 0xFFC00000
+ // 00000000,00111111,11110000,00000000 == 0x003F0000
+ // 00000000,00000000,00001111,11111100 == 0x00000FFC
+ // 00000000,00000000,00000000,00000011 == 0x00000003
+
+ extractComponents[0] = (float)( ( uint & 0xFFC00000 ) >> 22 ) / 1023.0f;
+ extractComponents[1] = (float)( ( uint & 0x003FF000 ) >> 12 ) / 1023.0f;
+ extractComponents[2] = (float)( ( uint & 0x00000FFC ) >> 2 ) / 1023.0f;
+ extractComponents[3] = (float)( ( uint & 0x00000003 ) ) / 3.0f;
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 11110000,00000000 == 0xF000
+ // 00001111,00000000 == 0x0F00
+ // 00000000,11110000 == 0x00F0
+ // 00000000,00001111 == 0x000F
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+ assert( 0.0f <= shoveComponents[3] && shoveComponents[3] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ long uint = (((int)((shoveComponents[0] * 1023) + 0.5f) << 22) & 0xFFC00000 );
+ uint |= (((int)((shoveComponents[1] * 1023) + 0.5f) << 12) & 0x003FF000 );
+ uint |= (((int)((shoveComponents[2] * 1023) + 0.5f) << 2) & 0x00000FFC );
+ uint |= (((int)((shoveComponents[3] * 3) + 0.5f) ) & 0x00000003 );
+ packedPixel.asIntBuffer().put( index, (int)uint );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract1555rev.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract1555rev.java
new file mode 100644
index 000000000..37895096e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract1555rev.java
@@ -0,0 +1,97 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract1555rev implements Extract {
+
+ /** Creates a new instance of Extract1555rev */
+ public Extract1555rev() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ int ushort = 0;
+
+ if( isSwap ) {
+ ushort = 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( packedPixel.getShort() );
+ } else {
+ ushort = 0x0000FFFF & packedPixel.getShort();
+ }
+
+ // 00000000,00011111 == 0x001F
+ // 00000011,11100000 == 0x03E0
+ // 01111100,00000000 == 0x7C00
+ // 10000000,00000000 == 0x8000
+
+ extractComponents[0] = (float)( ( ushort & 0x001F ) ) / 31.0f;
+ extractComponents[1] = (float)( ( ushort & 0x003E ) >> 5 ) / 31.0f;
+ extractComponents[2] = (float)( ( ushort & 0x7C00 ) >> 10) / 31.0f;
+ extractComponents[3] = (float)( ( ushort & 0x8000 ) >> 15);
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 00000000,00011111 == 0x001F
+ // 00000011,11100000 == 0x03E0
+ // 01111100,00000000 == 0x7C00
+ // 10000000,00000000 == 0x8000
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+ assert( 0.0f <= shoveComponents[3] && shoveComponents[3] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ int ushort = (((int)((shoveComponents[0] * 31) + 0.5f) ) & 0x0000001F );
+ ushort |= (((int)((shoveComponents[1] * 31) + 0.5f) << 5) & 0x000003E0 );
+ ushort |= (((int)((shoveComponents[2] * 31) + 0.5f) << 10) & 0x00007C00 );
+ ushort |= (((int)((shoveComponents[3]) + 0.5f) << 15) & 0x00008000 );
+ packedPixel.asShortBuffer().put( index, (short)ushort );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract2101010rev.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract2101010rev.java
new file mode 100644
index 000000000..077f3037b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract2101010rev.java
@@ -0,0 +1,97 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract2101010rev implements Extract {
+
+ /** Creates a new instance of Extract2101010 */
+ public Extract2101010rev() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ long uint = 0;
+
+ if( isSwap ) {
+ uint = 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( packedPixel.getInt() );
+ } else {
+ uint = 0x00000000FFFFFFFF & packedPixel.getInt();
+ }
+
+ // 11111111,11000000,00000000,00000000 == 0xFFC00000
+ // 00000000,00111111,11110000,00000000 == 0x003F0000
+ // 00000000,00000000,00001111,11111100 == 0x00000FFC
+ // 00000000,00000000,00000000,00000011 == 0x00000003
+
+ extractComponents[0] = (float)( ( uint & 0x000003FF ) ) / 1023.0f;
+ extractComponents[1] = (float)( ( uint & 0x000FFC00 ) >> 10 ) / 1023.0f;
+ extractComponents[2] = (float)( ( uint & 0x3FF00000 ) >> 20 ) / 1023.0f;
+ extractComponents[3] = (float)( ( uint & 0xC0000000 ) >> 30 ) / 3.0f;
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 11110000,00000000 == 0xF000
+ // 00001111,00000000 == 0x0F00
+ // 00000000,11110000 == 0x00F0
+ // 00000000,00001111 == 0x000F
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+ assert( 0.0f <= shoveComponents[3] && shoveComponents[3] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ long uint = (((int)((shoveComponents[0] * 1023) + 0.5f) ) & 0x000003FF );
+ uint |= (((int)((shoveComponents[1] * 1023) + 0.5f) << 10) & 0x000FFC00 );
+ uint |= (((int)((shoveComponents[2] * 1023) + 0.5f) << 20) & 0x3FF00000 );
+ uint |= (((int)((shoveComponents[3] * 3) + 0.5f) << 30) & 0xC0000000 );
+ packedPixel.asIntBuffer().put( index, (int)uint );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract233rev.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract233rev.java
new file mode 100644
index 000000000..fa35c6fbc
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract233rev.java
@@ -0,0 +1,85 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract233rev implements Extract {
+
+ /** Creates a new instance of Extract223rev */
+ public Extract233rev() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ // 11100000 == 0xe0
+ // 00011100 == 0x1c
+ // 00000011 == 0x03
+ byte ubyte = packedPixel.get();
+ extractComponents[0] = (float)((ubyte & 0x07) ) / 7.0f;
+ extractComponents[1] = (float)((ubyte & 0x38) >> 3) / 7.0f;
+ extractComponents[2] = (float)((ubyte & 0xC0) >> 6) / 3.0f;
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 11100000 == 0xE0
+ // 00011100 == 0x1C
+ // 00000011 == 0x03
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ byte b = (byte)( ( (int)( ( shoveComponents[0] * 7 ) + 0.5f ) ) & 0x07 );
+ b |= (byte)( ( (int)( ( shoveComponents[1] * 7 ) + 0.5f ) << 3 ) & 0x38 );
+ b |= (byte)( ( (int)( ( shoveComponents[2] * 3 ) + 0.5f ) << 6 ) & 0xC0 );
+ packedPixel.position( index );
+ packedPixel.put( b );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract332.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract332.java
new file mode 100644
index 000000000..35936466c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract332.java
@@ -0,0 +1,84 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract332 implements Extract {
+
+ /** Creates a new instance of Extract332 */
+ public Extract332() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ // 11100000 == 0xe0
+ // 00011100 == 0x1c
+ // 00000011 == 0x03
+ byte ubyte = packedPixel.get();
+ extractComponents[0] = (float)((ubyte & 0xe0) >> 5) / 7.0f;
+ extractComponents[1] = (float)((ubyte & 0x1c) >> 2) / 7.0f;
+ extractComponents[2] = (float)((ubyte & 0x03)) / 3.0f;
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 11100000 == 0xE0
+ // 00011100 == 0x1C
+ // 00000011 == 0x03
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ byte b = (byte)( ( (int)( ( shoveComponents[0] * 7 ) + 0.5f ) << 5 ) & 0xE0 );
+ b |= (byte)( ( (int)( ( shoveComponents[1] * 7 ) + 0.5f ) << 2 ) & 0x1C );
+ b |= (byte)( ( (int)( ( shoveComponents[2] * 3 ) + 0.5f ) ) & 0x03 );
+ packedPixel.put( index, b );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract4444.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract4444.java
new file mode 100644
index 000000000..bac4f57aa
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract4444.java
@@ -0,0 +1,96 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract4444 implements Extract {
+
+ /** Creates a new instance of Extract4444 */
+ public Extract4444() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ int ushort = 0;
+
+ if( isSwap ) {
+ ushort = 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( packedPixel.getShort() );
+ } else {
+ ushort = 0x0000FFFF & packedPixel.getShort();
+ }
+
+ // 11110000,00000000 == 0xF000
+ // 00001111,00000000 == 0x0F00
+ // 00000000,11110000 == 0x00F0
+ // 00000000,00001111 == 0x000F
+
+ extractComponents[0] = (float)( ( ushort & 0xF000 ) >> 12 ) / 15.0f;
+ extractComponents[1] = (float)( ( ushort & 0x0F00 ) >> 8 ) / 15.0f;
+ extractComponents[2] = (float)( ( ushort & 0x00F0 ) >> 4 ) / 15.0f;
+ extractComponents[3] = (float)( ( ushort & 0x000F ) ) / 15.0f;
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 11110000,00000000 == 0xF000
+ // 00001111,00000000 == 0x0F00
+ // 00000000,11110000 == 0x00F0
+ // 00000000,00001111 == 0x000F
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ int ushort = (((int)((shoveComponents[0] * 15) + 0.5f) << 12) & 0x0000F000 );
+ ushort |= (((int)((shoveComponents[1] * 15) + 0.5f) << 8) & 0x00000F00 );
+ ushort |= (((int)((shoveComponents[2] * 15) + 0.5f) << 4) & 0x000000F0 );
+ ushort |= (((int)((shoveComponents[3] * 15) + 0.5f) ) & 0x0000000F );
+ packedPixel.asShortBuffer().put( index, (short)ushort );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract4444rev.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract4444rev.java
new file mode 100644
index 000000000..b1bea75e1
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract4444rev.java
@@ -0,0 +1,97 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract4444rev implements Extract {
+
+ /** Creates a new instance of Extract4444rev */
+ public Extract4444rev() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ int ushort = 0;
+
+ if( isSwap ) {
+ ushort = 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( packedPixel.getShort() );
+ } else {
+ ushort = 0x0000FFFF & packedPixel.getShort();
+ }
+
+ // 00000000,00001111 == 0x000F
+ // 00000000,11110000 == 0x00F0
+ // 00001111,00000000 == 0x0F00
+ // 11110000,00000000 == 0xF000
+
+ extractComponents[0] = (float)( ( ushort & 0x000F ) ) / 15.0f;
+ extractComponents[1] = (float)( ( ushort & 0x00F0 ) >> 4 ) / 15.0f;
+ extractComponents[2] = (float)( ( ushort & 0x0F00 ) >> 8 ) / 15.0f;
+ extractComponents[3] = (float)( ( ushort & 0xF000 ) >> 12 ) / 15.0f;
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 11110000,00000000 == 0xF000
+ // 00001111,00000000 == 0x0F00
+ // 00000000,11110000 == 0x00F0
+ // 00000000,00001111 == 0x000F
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+ assert( 0.0f <= shoveComponents[3] && shoveComponents[3] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ int ushort = (((int)((shoveComponents[0] * 15) + 0.5f) ) & 0x0000000F );
+ ushort |= (((int)((shoveComponents[1] * 15) + 0.5f) << 4) & 0x000000F0 );
+ ushort |= (((int)((shoveComponents[2] * 15) + 0.5f) << 8) & 0x00000F00 );
+ ushort |= (((int)((shoveComponents[3] * 15) + 0.5f) << 12) & 0x0000F000 );
+ packedPixel.asShortBuffer().put( index, (short)ushort );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract5551.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract5551.java
new file mode 100644
index 000000000..a6247844f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract5551.java
@@ -0,0 +1,97 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract5551 implements Extract {
+
+ /** Creates a new instance of Extract5551 */
+ public Extract5551() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ int ushort = 0;
+
+ if( isSwap ) {
+ ushort = 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( packedPixel.getShort() );
+ } else {
+ ushort = 0x0000FFFF & packedPixel.getShort();
+ }
+
+ // 11111000,00000000 == 0xF800
+ // 00000111,11000000 == 0x07C0
+ // 00000000,00111110 == 0x003E
+ // 00000000,00000001 == 0x0001
+
+ extractComponents[0] = (float)( ( ushort & 0xF800 ) >> 11 ) / 31.0f;
+ extractComponents[1] = (float)( ( ushort & 0x00F0 ) >> 6 ) / 31.0f;
+ extractComponents[2] = (float)( ( ushort & 0x0F00 ) >> 1 ) / 31.0f;
+ extractComponents[3] = (float)( ( ushort & 0xF000 ) );
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 11110000,00000000 == 0xF000
+ // 00001111,00000000 == 0x0F00
+ // 00000000,11110000 == 0x00F0
+ // 00000000,00001111 == 0x000F
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+ assert( 0.0f <= shoveComponents[3] && shoveComponents[3] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ int ushort = (((int)((shoveComponents[0] * 31) + 0.5f) << 11) & 0x0000F800 );
+ ushort |= (((int)((shoveComponents[1] * 31) + 0.5f) << 6) & 0x000007C0 );
+ ushort |= (((int)((shoveComponents[2] * 31) + 0.5f) << 1) & 0x0000003E );
+ ushort |= (((int)((shoveComponents[3]) + 0.5f)) & 0x00000001 );
+ packedPixel.asShortBuffer().put( index, (short)ushort );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract565.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract565.java
new file mode 100644
index 000000000..624a4f3f2
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract565.java
@@ -0,0 +1,92 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract565 implements Extract {
+
+ /** Creates a new instance of Extract565 */
+ public Extract565() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ int ushort = 0;
+
+ if( isSwap ) {
+ ushort = 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( packedPixel.getShort() );
+ } else {
+ ushort = 0x0000FFFF & packedPixel.getShort();
+ }
+
+ // 11111000,00000000 == 0xF800
+ // 00000111,11100000 == 0x07E0
+ // 00000000,00111111 == 0x001F
+
+ extractComponents[0] = (float)( ( ushort & 0xF800 ) >> 11 ) / 31.0f;
+ extractComponents[1] = (float)( ( ushort & 0x07E0 ) >> 5 ) / 63.0f;
+ extractComponents[2] = (float)( ( ushort & 0x001F ) ) / 31.0f;
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 11111000,00000000 == 0xF800
+ // 00000111,11100000 == 0x07E0
+ // 00000000,00111111 == 0x001F
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ int ushort = (((int)((shoveComponents[0] * 31) + 0.5f) << 11) & 0x0000F800 );
+ ushort |= (((int)((shoveComponents[1] * 63) + 0.5f) << 5) & 0x000007E0 );
+ ushort |= (((int)((shoveComponents[2] * 31) + 0.5f) ) & 0x0000001F );
+ packedPixel.asShortBuffer().put( index, (short)ushort );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract565rev.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract565rev.java
new file mode 100644
index 000000000..4ab6d7e98
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract565rev.java
@@ -0,0 +1,92 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract565rev implements Extract {
+
+ /** Creates a new instance of Extract565rev */
+ public Extract565rev() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ int ushort = 0;
+
+ if( isSwap ) {
+ ushort = 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( packedPixel.getShort() );
+ } else {
+ ushort = 0x0000FFFF & packedPixel.getShort();
+ }
+
+ // 00000000,00011111 == 0x001F
+ // 00000111,11100000 == 0x07E0
+ // 11111000,00000000 == 0xF800
+
+ extractComponents[0] = (float)( ( ushort & 0x001F ) ) / 31.0f;
+ extractComponents[1] = (float)( ( ushort & 0x07E0 ) >> 5 ) / 63.0f;
+ extractComponents[2] = (float)( ( ushort & 0xF800 ) >> 11 ) / 31.0f;
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 00000000,00111111 == 0x001F
+ // 00000111,11100000 == 0x07E0
+ // 11111000,00000000 == 0xF800
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ int ushort = (((int)((shoveComponents[0] * 31) + 0.5f) ) & 0x0000001F );
+ ushort |= (((int)((shoveComponents[1] * 63) + 0.5f) << 5) & 0x000007E0 );
+ ushort |= (((int)((shoveComponents[2] * 31) + 0.5f) << 11) & 0x0000F800 );
+ packedPixel.asShortBuffer().put( index, (short)ushort );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract8888.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract8888.java
new file mode 100644
index 000000000..90d7e57c9
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract8888.java
@@ -0,0 +1,97 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract8888 implements Extract {
+
+ /** Creates a new instance of Extract8888 */
+ public Extract8888() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ long uint = 0;
+
+ if( isSwap ) {
+ uint = 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( packedPixel.getInt() );
+ } else {
+ uint = 0x00000000FFFFFFFF & packedPixel.getInt();
+ }
+
+ // 11111000,00000000 == 0xF800
+ // 00000111,11000000 == 0x07C0
+ // 00000000,00111110 == 0x003E
+ // 00000000,00000001 == 0x0001
+
+ extractComponents[0] = (float)( ( uint & 0xFF000000 ) >> 24 ) / 255.0f;
+ extractComponents[1] = (float)( ( uint & 0x00FF0000 ) >> 16 ) / 255.0f;
+ extractComponents[2] = (float)( ( uint & 0x0000FF00 ) >> 8 ) / 255.0f;
+ extractComponents[3] = (float)( ( uint & 0x000000FF ) ) / 255.0f;
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 11110000,00000000 == 0xF000
+ // 00001111,00000000 == 0x0F00
+ // 00000000,11110000 == 0x00F0
+ // 00000000,00001111 == 0x000F
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+ assert( 0.0f <= shoveComponents[3] && shoveComponents[3] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ long uint = (((int)((shoveComponents[0] * 255) + 0.5f) << 24) & 0xFF000000 );
+ uint |= (((int)((shoveComponents[1] * 255) + 0.5f) << 16) & 0x00FF0000 );
+ uint |= (((int)((shoveComponents[2] * 255) + 0.5f) << 8) & 0x0000FF00 );
+ uint |= (((int)((shoveComponents[3] * 255) + 0.5f) ) & 0x000000FF );
+ packedPixel.asIntBuffer().put( index, (int)uint );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract8888rev.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract8888rev.java
new file mode 100644
index 000000000..10970573b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Extract8888rev.java
@@ -0,0 +1,97 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Extract8888rev implements Extract {
+
+ /** Creates a new instance of Extract8888rev */
+ public Extract8888rev() {
+ }
+
+ public void extract( boolean isSwap, ByteBuffer packedPixel, float[] extractComponents ) {
+ long uint = 0;
+
+ if( isSwap ) {
+ uint = 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( packedPixel.getInt() );
+ } else {
+ uint = 0x00000000FFFFFFFF & packedPixel.getInt();
+ }
+
+ // 11111000,00000000 == 0xF800
+ // 00000111,11000000 == 0x07C0
+ // 00000000,00111110 == 0x003E
+ // 00000000,00000001 == 0x0001
+
+ extractComponents[0] = (float)( ( uint & 0x000000FF ) ) / 255.0f;
+ extractComponents[1] = (float)( ( uint & 0x0000FF00 ) >> 8 ) / 255.0f;
+ extractComponents[2] = (float)( ( uint & 0x00FF0000 ) >> 16 ) / 255.0f;
+ extractComponents[3] = (float)( ( uint & 0xFF000000 ) >> 24 ) / 255.0f;
+ }
+
+ public void shove( float[] shoveComponents, int index, ByteBuffer packedPixel ) {
+ // 11110000,00000000 == 0xF000
+ // 00001111,00000000 == 0x0F00
+ // 00000000,11110000 == 0x00F0
+ // 00000000,00001111 == 0x000F
+
+ assert( 0.0f <= shoveComponents[0] && shoveComponents[0] <= 1.0f );
+ assert( 0.0f <= shoveComponents[1] && shoveComponents[1] <= 1.0f );
+ assert( 0.0f <= shoveComponents[2] && shoveComponents[2] <= 1.0f );
+ assert( 0.0f <= shoveComponents[3] && shoveComponents[3] <= 1.0f );
+
+ // due to limited precision, need to round before shoving
+ long uint = (((int)((shoveComponents[0] * 255) + 0.5f) ) & 0x000000FF );
+ uint |= (((int)((shoveComponents[1] * 255) + 0.5f) << 8) & 0x0000FF00 );
+ uint |= (((int)((shoveComponents[2] * 255) + 0.5f) << 16) & 0x00FF0000 );
+ uint |= (((int)((shoveComponents[3] * 255) + 0.5f) << 24) & 0xFF000000 );
+ packedPixel.asIntBuffer().put( index, (int)uint );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractFloat.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractFloat.java
new file mode 100644
index 000000000..c42799470
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractFloat.java
@@ -0,0 +1,74 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class ExtractFloat implements ExtractPrimitive {
+
+ /** Creates a new instance of ExtractFloat */
+ public ExtractFloat() {
+ }
+
+ public double extract( boolean isSwap, ByteBuffer data ) {
+ float f = 0;
+ if( isSwap ) {
+ f = Mipmap.GLU_SWAP_4_BYTES( data.getInt() );
+ } else {
+ f = data.getInt();
+ }
+ assert( f <= 1.0f );
+ return( f );
+ }
+
+ public void shove( double value, int index, ByteBuffer data ) {
+ assert(0.0 <= value && value < 1.0);
+ data.asFloatBuffer().put( index, (float)value );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractPrimitive.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractPrimitive.java
new file mode 100644
index 000000000..8b986d6d0
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractPrimitive.java
@@ -0,0 +1,56 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author Administrator
+ */
+public interface ExtractPrimitive {
+ public double extract( boolean isSwap, ByteBuffer pointer );
+ public void shove( double value, int index, ByteBuffer pointer );
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSByte.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSByte.java
new file mode 100644
index 000000000..4f61015f4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSByte.java
@@ -0,0 +1,69 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author Administrator
+ */
+public class ExtractSByte implements ExtractPrimitive {
+
+ /** Creates a new instance of ExtractUByte */
+ public ExtractSByte() {
+ }
+
+ public double extract( boolean isSwap, ByteBuffer sbyte ) {
+ byte b = sbyte.get();
+ assert( b <= 127 );
+ return( b );
+ }
+
+ public void shove( double value, int index, ByteBuffer data ) {
+ data.position( index );
+ data.put( (byte)value );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSInt.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSInt.java
new file mode 100644
index 000000000..2d5ac5329
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSInt.java
@@ -0,0 +1,76 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class ExtractSInt implements ExtractPrimitive {
+
+ /** Creates a new instance of ExtractSInt */
+ public ExtractSInt() {
+ }
+
+ public double extract( boolean isSwap, ByteBuffer uint ) {
+ int i = 0;
+ if( isSwap ) {
+ i = Mipmap.GLU_SWAP_4_BYTES( uint.getInt() );
+ } else {
+ i = uint.getInt();
+ }
+ assert( i <= 0x7FFFFFFF );
+ return( i );
+ }
+
+ public void shove( double value, int index, ByteBuffer data ) {
+ assert(0.0 <= value && value < Integer.MAX_VALUE);
+ IntBuffer ib = data.asIntBuffer();
+ ib.position( index );
+ ib.put( (int)value );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSShort.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSShort.java
new file mode 100644
index 000000000..8b8d50cbf
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractSShort.java
@@ -0,0 +1,76 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class ExtractSShort implements ExtractPrimitive {
+
+ /** Creates a new instance of ExtractSShort */
+ public ExtractSShort() {
+ }
+
+ public double extract( boolean isSwap, ByteBuffer ushort ) {
+ short s = 0;
+ if( isSwap ) {
+ s = Mipmap.GLU_SWAP_2_BYTES( ushort.getShort() );
+ } else {
+ s = ushort.getShort();
+ }
+ assert( s <= 32767 );
+ return( s );
+ }
+
+ public void shove( double value, int index, ByteBuffer data ) {
+ assert(0.0 <= value && value < 32768.0);
+ ShortBuffer sb = data.asShortBuffer();
+ sb.position( index );
+ sb.put( (short)value );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUByte.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUByte.java
new file mode 100644
index 000000000..d33213f89
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUByte.java
@@ -0,0 +1,70 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author Administrator
+ */
+public class ExtractUByte implements ExtractPrimitive {
+
+ /** Creates a new instance of ExtractUByte */
+ public ExtractUByte() {
+ }
+
+ public double extract( boolean isSwap, ByteBuffer ubyte ) {
+ int i = 0x000000FF & ubyte.get();
+ assert( i <= 255 );
+ return( i );
+ }
+
+ public void shove( double value, int index, ByteBuffer data ) {
+ assert(0.0 <= value && value < 256.0);
+ data.position( index );
+ data.put( (byte)value );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUInt.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUInt.java
new file mode 100644
index 000000000..873668a43
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUInt.java
@@ -0,0 +1,76 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class ExtractUInt implements ExtractPrimitive {
+
+ /** Creates a new instance of ExtractUInt */
+ public ExtractUInt() {
+ }
+
+ public double extract( boolean isSwap, ByteBuffer uint ) {
+ long i = 0;
+ if( isSwap ) {
+ i = 0xFFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( uint.getInt() );
+ } else {
+ i = 0xFFFFFFFF & uint.getInt();
+ }
+ assert( i <= 0xFFFFFFFF );
+ return( i );
+ }
+
+ public void shove( double value, int index, ByteBuffer data ) {
+ assert(0.0 <= value && value < 0xFFFFFFFF);
+ IntBuffer ib = data.asIntBuffer();
+ ib.position( index );
+ ib.put( (int)value );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUShort.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUShort.java
new file mode 100644
index 000000000..86bbb95f1
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ExtractUShort.java
@@ -0,0 +1,76 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class ExtractUShort implements ExtractPrimitive {
+
+ /** Creates a new instance of ExtracUShort */
+ public ExtractUShort() {
+ }
+
+ public double extract( boolean isSwap, ByteBuffer ushort ) {
+ int i = 0;
+ if( isSwap ) {
+ i = 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( ushort.getShort() );
+ } else {
+ i = 0x0000FFFF & ushort.getShort();
+ }
+ assert( i <= 65535 );
+ return( i );
+ }
+
+ public void shove( double value, int index, ByteBuffer data ) {
+ assert(0.0 <= value && value < 65536.0);
+ ShortBuffer sb = data.asShortBuffer();
+ sb.position( index );
+ sb.put( (short)value );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/HalveImage.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/HalveImage.java
new file mode 100644
index 000000000..893d33c66
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/HalveImage.java
@@ -0,0 +1,1533 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import javax.media.opengl.GL;
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class HalveImage {
+
+ private static final int BOX2 = 2;
+ private static final int BOX4 = 4;
+ private static final int BOX8 = 8;
+
+ public static void halveImage( int components, int width, int height,
+ ShortBuffer datain, ShortBuffer dataout ) {
+ int i, j, k;
+ int newwidth, newheight;
+ int delta;
+ int t = 0;
+ short temp = 0;
+
+ newwidth = width / 2;
+ newheight = height /2;
+ delta = width * components;
+
+ // Piece of cake
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = datain.get();
+ datain.position( t + components );
+ temp += datain.get();
+ datain.position( t + delta );
+ temp += datain.get();
+ datain.position( t + delta + components );
+ temp +=datain.get();
+ temp += 2;
+ temp /= 4;
+ dataout.put( temp );
+ t++;
+ }
+ t += components;
+ }
+ t += delta;
+ }
+ }
+
+ public static void halveImage_ubyte( int components, int width, int height,
+ ByteBuffer datain, ByteBuffer dataout,
+ int element_size, int ysize, int group_size ) {
+ int i, j, k;
+ int newwidth, newheight;
+ int s;
+ int t;
+
+ // Handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_ubyte( components, width, height, datain, dataout, element_size, ysize, group_size );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+ s = 0;
+ t = 0;
+
+ int temp = 0;
+ // piece of cake
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = ( 0x000000FF & datain.get() );
+ datain.position( t + group_size );
+ temp += ( 0x000000FF & datain.get() );
+ datain.position( t + ysize );
+ temp += ( 0x000000FF & datain.get() );
+ datain.position( t + ysize + group_size );
+ temp += ( 0x000000FF & datain.get() ) + 2;
+ dataout.put( (byte)(temp / 4) );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+
+ public static void halve1Dimage_ubyte( int components, int width, int height,
+ ByteBuffer datain, ByteBuffer dataout,
+ int element_size, int ysize, int group_size ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+ int temp = 0;
+
+ assert( width == 1 || height == 1 ); // Must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // widthxheight can't be 1x1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ datain.position( src );
+ temp = ( 0x000000FF & datain.get() );
+ datain.position( src + group_size );
+ temp += ( 0x000000FF & datain.get() );
+ temp /= 2;
+ dataout.put( (byte)temp );
+ /*
+ dataout.setByte( (byte)(((0x000000FF & datain.setIndexInBytes(src).getByte()) +
+ (0x000000FF & datain.setIndexInBytes( src + group_size ).getByte())) / 2 ) );
+ */
+ src += element_size;
+ //dataout.plusPlus();
+ dest++;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) { // 1 column
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 );
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ datain.position( src );
+ temp = ( 0x000000FF & datain.get() );
+ datain.position( src + ysize );
+ temp += ( 0x000000FF & datain.get() );
+ temp /= 2;
+ dataout.put( (byte)temp );
+ /*
+ dataout.setByte( (byte)(((0x000000FF & datain.setIndexInBytes(src).getByte()) +
+ (0x000000FF & datain.setIndexInBytes(src + ysize).getByte()) ) / 2 ) );
+ */
+ src += element_size;
+ //dataout.plusPlus();
+ dest++;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ }
+ assert( src == ysize * height );
+ assert( dest == components * element_size * halfWidth * halfHeight );
+ }
+
+ public static void halveImage_byte( int components, int width, int height,
+ ByteBuffer datain, ByteBuffer dataout, int element_size,
+ int ysize, int group_size ) {
+ int i, j, k;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ byte temp = (byte)0;
+
+ // handle case where there is only 1 column
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) );
+ halve1Dimage_byte( components, width, height, datain, dataout, element_size,
+ ysize, group_size );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = datain.get();
+ datain.position( t + group_size );
+ temp += datain.get();
+ datain.position( t + ysize );
+ temp += datain.get();
+ datain.position( t + ysize + group_size );
+ temp += datain.get();
+ temp += 2;
+ temp /= 4;
+ dataout.put( temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+
+ public static void halve1Dimage_byte( int components, int width, int height,
+ ByteBuffer datain, ByteBuffer dataout,
+ int element_size, int ysize, int group_size ) {
+ int halfWidth = width / 2;
+ int halfHeight = width / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+ byte temp = (byte)0;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // widthxheight can't be 1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ datain.position( src );
+ temp = datain.get();
+ datain.position( src + group_size );
+ temp += datain.get();
+ temp /= 2;
+ dataout.put( temp );
+ src += element_size;
+ dest++;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assert only
+ } else if( width == 1 ) { // 1 column
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 ); // widthxheight can't be 1
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ datain.position( src );
+ temp = datain.get();
+ datain.position( src + ysize );
+ temp += datain.get();
+ temp /= 2;
+ src += element_size;
+ dest++;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == components * element_size * halfWidth * halfHeight );
+ }
+
+ public static void halveImage_ushort( int components, int width, int height,
+ ByteBuffer datain, ShortBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int i, j, k, l;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ int temp = 0;
+ // handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_ushort( components, width, height, datain, dataout, element_size,
+ ysize, group_size, myswap_bytes );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ // Piece of cake
+ if( !myswap_bytes ) {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = ( 0x0000FFFF & datain.getShort() );
+ datain.position( t + group_size );
+ temp += ( 0x0000FFFF & datain.getShort() );
+ datain.position( t + ysize );
+ temp += ( 0x0000FFFF & datain.getShort() );
+ datain.position( t + ysize + group_size );
+ temp += ( 0x0000FFFF & datain.getShort() );
+ dataout.put( (short)( ( temp + 2 ) / 4 ) );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ } else {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ datain.position( t + group_size );
+ temp += ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ datain.position( t + ysize );
+ temp += ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ datain.position( t + ysize + group_size );
+ temp += ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ dataout.put( (short)( ( temp + 2 ) / 4 ) );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+ }
+
+ public static void halve1Dimage_ushort( int components, int width, int height,
+ ByteBuffer datain, ShortBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // widthxheight can't be 1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < halfHeight; kk++ ) {
+ int[] ushort = new int[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ ushort[0] = ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ datain.position( src + group_size );
+ ushort[1] = (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ } else {
+ datain.position( src );
+ ushort[0] = (0x0000FFFF & datain.getShort() );
+ datain.position( src + group_size );
+ ushort[1] = (0x0000FFFF & datain.getShort() );
+ }
+ dataout.put( (short)( (ushort[0] + ushort[1]) / 2 ) );
+ src += element_size;
+ dest += 2;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) { // 1 column
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 ); // widthxheight can't be 1
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ int[] ushort = new int[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ ushort[0] = ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ datain.position( src + ysize );
+ ushort[0] = ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ) );
+ } else {
+ datain.position( src );
+ ushort[0] = ( 0x0000FFFF & datain.getShort() );
+ datain.position( src + ysize );
+ ushort[1] = ( 0x0000FFFF & datain.getShort() );
+ }
+ dataout.put( (short)((ushort[0] + ushort[1]) / 2) );
+ src += element_size;
+ dest += 2;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == components * element_size * halfWidth * halfHeight );
+ }
+
+ public static void halveImage_short( int components, int width, int height,
+ ByteBuffer datain, ShortBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int i, j, k, l;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ short temp = (short)0;
+ // handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_short( components, width, height, datain, dataout, element_size,
+ ysize, group_size, myswap_bytes );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ // Piece of cake
+ if( !myswap_bytes ) {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = datain.getShort();
+ datain.position( t + group_size );
+ temp += datain.getShort();
+ datain.position( t + ysize );
+ temp += datain.getShort();
+ datain.position( t + ysize + group_size );
+ temp += datain.getShort();
+ temp += 2;
+ temp /= 4;
+ dataout.put( (short)temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ } else {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ short b;
+ int buf;
+ datain.position( t );
+ temp = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ datain.position( t + group_size );
+ temp += Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ datain.position( t + ysize );
+ temp += Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ datain.position( t + ysize + group_size );
+ temp += Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ temp += 2;
+ temp /= 4;
+ dataout.put( temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+ }
+
+ public static void halve1Dimage_short( int components, int width, int height,
+ ByteBuffer datain, ShortBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // can't be 1x1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ short[] sshort = new short[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ sshort[0] = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ datain.position( src + group_size );
+ sshort[1] = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ } else {
+ datain.position( src );
+ sshort[0] = datain.getShort();
+ datain.position( src + group_size );
+ sshort[1] = datain.getShort();
+ }
+ dataout.put( (short)(( sshort[0] + sshort[1] ) / 2) );
+ src += element_size;
+ dest += 2;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) {
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 );
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ short[] sshort = new short[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ sshort[0] = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ datain.position( src + ysize );
+ sshort[1] = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ } else {
+ datain.position( src );
+ sshort[0] = datain.getShort();
+ datain.position( src + ysize );
+ sshort[1] = datain.getShort();
+ }
+ dataout.put( (short)(( sshort[0] + sshort[1] ) / 2) );
+ src += element_size;
+ dest += 2;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == ( components * element_size * halfWidth * halfHeight ) );
+ }
+
+ public static void halveImage_uint( int components, int width, int height,
+ ByteBuffer datain, IntBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int i, j, k, l;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ double temp = 0;
+
+ // handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_uint( components, width, height, datain, dataout, element_size,
+ ysize, group_size, myswap_bytes );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ // Piece of cake
+ if( !myswap_bytes ) {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = (0x000000007FFFFFFFL & datain.getInt() );
+ datain.position( t + group_size );
+ temp += (0x000000007FFFFFFFL & datain.getInt() );
+ datain.position( t + ysize );
+ temp += (0x000000007FFFFFFFL & datain.getInt() );
+ datain.position( t + ysize + group_size );
+ temp += (0x000000007FFFFFFFL & datain.getInt() );
+ dataout.put( (int)( ( temp / 4 ) + 0.5 ) );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ } else {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ // need to cast to double to hold large unsigned ints
+ double buf;
+ datain.position( t );
+ buf = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( t + group_size );
+ buf += ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( t + ysize );
+ buf += ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( t + ysize + group_size );
+ buf += ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ temp /= 4;
+ temp += 0.5;
+ dataout.put( (int)temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+ }
+
+ public static void halve1Dimage_uint( int components, int width, int height,
+ ByteBuffer datain, IntBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // widthxheight can't be 1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < halfHeight; kk++ ) {
+ long[] uint = new long[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( src + group_size );
+ uint[1] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ } else {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ datain.position( src + group_size );
+ uint[1] = (0x00000000FFFFFFFF & datain.getInt() );
+ }
+ dataout.put( (int)( ( uint[0] + uint[1] ) / 2.0 ) );
+ src += element_size;
+ dest += 4;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) { // 1 column
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 ); // widthxheight can't be 1
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ long[] uint = new long[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( src + group_size );
+ uint[0] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ } else {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ datain.position( src + ysize );
+ uint[1] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ }
+ dataout.put( (int)( ( uint[0] + uint[1] ) / 2.0 ) );
+ src += element_size;
+ dest += 4;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == components * element_size * halfWidth * halfHeight );
+ }
+
+ public static void halveImage_int( int components, int width, int height,
+ ByteBuffer datain, IntBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int i, j, k, l;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ int temp = 0;
+
+ // handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_int( components, width, height, datain, dataout, element_size,
+ ysize, group_size, myswap_bytes );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ // Piece of cake
+ if( !myswap_bytes ) {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = datain.getInt();
+ datain.position( t + group_size );
+ temp += datain.getInt();
+ datain.position( t + ysize );
+ temp += datain.getInt();
+ datain.position( t + ysize + group_size );
+ temp += datain.getInt();
+ temp = (int)( ( temp / 4.0f ) + 0.5f );
+ dataout.put( temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ } else {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ long b;
+ float buf;
+ datain.position( t );
+ b = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ buf = b;
+ datain.position( t + group_size );
+ b = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ buf += b;
+ datain.position( t + ysize );
+ b = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ buf += b;
+ datain.position( t + ysize + group_size );
+ b = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ buf += b;
+ dataout.put( (int)( ( buf / 4.0f ) + 0.5f ) );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+ }
+
+ public static void halve1Dimage_int( int components, int width, int height,
+ ByteBuffer datain, IntBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // can't be 1x1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ long[] uint = new long[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( src + group_size );
+ uint[1] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ } else {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ datain.position( src + group_size );
+ uint[1] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ }
+ dataout.put( (int)( ( (float)uint[0] + (float)uint[1] ) / 2.0f) );
+ src += element_size;
+ dest += 4;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) {
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 );
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ long[] uint = new long[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ datain.position( src + ysize );
+ uint[1] = ( 0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt() ) );
+ } else {
+ datain.position( src );
+ uint[0] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ datain.position( src + ysize );
+ uint[1] = ( 0x00000000FFFFFFFF & datain.getInt() );
+ }
+ dataout.put( (int)(( (float)uint[0] + (float)uint[1] ) / 2.0f) );
+ src += element_size;
+ dest += 4;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == ( components * element_size * halfWidth * halfHeight ) );
+ }
+
+ public static void halveImage_float( int components, int width, int height,
+ ByteBuffer datain, FloatBuffer dataout, int element_size,
+ int ysize, int group_size, boolean myswap_bytes ) {
+ int i, j, k, l;
+ int newwidth, newheight;
+ int s = 0;
+ int t = 0;
+ float temp = 0.0f;
+ // handle case where there is only 1 column/row
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) ); // can't be 1x1
+ halve1Dimage_float( components, width, height, datain, dataout, element_size,
+ ysize, group_size, myswap_bytes );
+ return;
+ }
+
+ newwidth = width / 2;
+ newheight = height / 2;
+
+ // Piece of cake
+ if( !myswap_bytes ) {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ datain.position( t );
+ temp = datain.getFloat();
+ datain.position( t + group_size );
+ temp += datain.getFloat();
+ datain.position( t + ysize );
+ temp += datain.getFloat();
+ datain.position( t + ysize + group_size );
+ temp /= 4.0f;
+ dataout.put( temp );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ } else {
+ for( i = 0; i < newheight; i++ ) {
+ for( j = 0; j < newwidth; j++ ) {
+ for( k = 0; k < components; k++ ) {
+ float buf;
+ datain.position( t );
+ buf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ datain.position( t + group_size );
+ buf += Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ datain.position( t + ysize );
+ buf += Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ datain.position( t + ysize + group_size );
+ buf += Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ dataout.put( buf / 4.0f );
+ t += element_size;
+ }
+ t += group_size;
+ }
+ t += ysize;
+ }
+ }
+ }
+
+ public static void halve1Dimage_float( int components, int width, int height,
+ ByteBuffer datain, FloatBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int dest = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 ); // must be 1D
+ assert( width != height ); // can't be square
+
+ if( height == 1 ) { // 1 row
+ assert( width != 1 ); // can't be 1x1
+ halfHeight = 1;
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ float[] sfloat = new float[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ sfloat[0] = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ datain.position( src + group_size );
+ sfloat[1] = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ } else {
+ datain.position( src );
+ sfloat[0] = datain.getFloat();
+ datain.position( src + group_size );
+ sfloat[1] = datain.getFloat();
+ }
+ dataout.put( (sfloat[0] + sfloat[1]) / 2.0f );
+ src += element_size;
+ dest += 4;
+ }
+ src += group_size; // skip to next 2
+ }
+ int padBytes = ysize - ( width * group_size );
+ src += padBytes; // for assertion only
+ } else if( width == 1 ) {
+ int padBytes = ysize - ( width * group_size );
+ assert( height != 1 );
+ halfWidth = 1;
+ // one vertical column with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int kk;
+ for( kk = 0; kk < components; kk++ ) {
+ float[] sfloat = new float[BOX2];
+ if( myswap_bytes ) {
+ datain.position( src );
+ sfloat[0] = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ datain.position( src + ysize );
+ sfloat[1] = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ } else {
+ datain.position( src );
+ sfloat[0] = datain.getFloat();
+ datain.position( src + ysize );
+ sfloat[1] = datain.getFloat();
+ }
+ dataout.put( ( sfloat[0] + sfloat[1] ) / 2.0f );
+ src += element_size;
+ dest += 4;
+ }
+ src += padBytes; // add pad bytes, if any, to get to end of row
+ src += ysize;
+ }
+ assert( src == ysize * height );
+ }
+ assert( dest == ( components * element_size * halfWidth * halfHeight ) );
+ }
+
+ public static void halveImagePackedPixel( int components, Extract extract, int width,
+ int height, ByteBuffer datain, ByteBuffer dataout,
+ int pixelSizeInBytes, int rowSizeInBytes, boolean isSwap ) {
+ if( width == 1 || height == 1 ) {
+ assert( !( width == 1 && height == 1 ) );
+ halve1DimagePackedPixel( components, extract, width, height, datain, dataout,
+ pixelSizeInBytes, rowSizeInBytes, isSwap );
+ return;
+ }
+ int ii, jj;
+
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int padBytes = rowSizeInBytes - ( width * pixelSizeInBytes );
+ int outIndex = 0;
+
+ for( ii = 0; ii < halfHeight; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ float totals[] = new float[4];
+ float extractTotals[][] = new float[BOX4][4];
+ int cc;
+
+ datain.position( src );
+ extract.extract( isSwap, datain, extractTotals[0] );
+ datain.position( src + pixelSizeInBytes );
+ extract.extract( isSwap, datain, extractTotals[1] );
+ datain.position( src + rowSizeInBytes );
+ extract.extract( isSwap, datain, extractTotals[2] );
+ datain.position( src + rowSizeInBytes + pixelSizeInBytes );
+ extract.extract( isSwap, datain, extractTotals[3] );
+ for( cc = 0; cc < components; cc++ ) {
+ int kk = 0;
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX4; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= BOX4;
+ }
+ extract.shove( totals, outIndex, dataout );
+ outIndex++;
+ src += pixelSizeInBytes + pixelSizeInBytes;
+ }
+ // skip past pad bytes, if any, to get to next row
+ src += padBytes;
+ src += rowSizeInBytes;
+ }
+ assert( src == rowSizeInBytes * height );
+ assert( outIndex == halfWidth * halfHeight );
+ }
+
+ public static void halve1DimagePackedPixel( int components, Extract extract, int width,
+ int height, ByteBuffer datain, ByteBuffer dataout,
+ int pixelSizeInBytes, int rowSizeInBytes, boolean isSwap ) {
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int src = 0;
+ int jj;
+
+ assert( width == 1 || height == 1 );
+ assert( width != height );
+
+ if( height == 1 ) {
+ int outIndex = 0;
+
+ assert( width != 1 );
+ halfHeight = 1;
+
+ // one horizontal row with possible pad bytes
+
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ float[] totals = new float[4];
+ float[][] extractTotals = new float[BOX2][4];
+ int cc;
+
+ datain.position( src );
+ extract.extract( isSwap, datain, extractTotals[0] );
+ datain.position( src + pixelSizeInBytes );
+ extract.extract( isSwap, datain, extractTotals[1] );
+ for( cc = 0; cc < components; cc++ ) {
+ int kk = 0;
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX2; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= BOX2;
+ }
+ extract.shove( totals, outIndex, dataout );
+ outIndex++;
+ // skip over to next group of 2
+ src += pixelSizeInBytes + pixelSizeInBytes;
+ }
+ int padBytes = rowSizeInBytes - ( width * pixelSizeInBytes );
+ src += padBytes;
+
+ assert( src == rowSizeInBytes );
+ assert( outIndex == halfWidth * halfHeight );
+ } else if( width == 1 ) {
+ int outIndex = 0;
+
+ assert( height != 1 );
+ halfWidth = 1;
+ // one vertical volumn with possible pad bytes per row
+ // average two at a time
+
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ float[] totals = new float[4];
+ float[][] extractTotals = new float[BOX2][4];
+ int cc;
+ // average two at a time, instead of four
+ datain.position( src );
+ extract.extract( isSwap, datain, extractTotals[0] );
+ datain.position( src + rowSizeInBytes );
+ extract.extract( isSwap, datain, extractTotals[1] );
+ for( cc = 0; cc < components; cc++ ) {
+ int kk = 0;
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX2; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= BOX2;
+ }
+ extract.shove( totals, outIndex, dataout );
+ outIndex++;
+ // skip over to next group of 2
+ src += rowSizeInBytes + rowSizeInBytes;
+ }
+ assert( src == rowSizeInBytes );
+ assert( outIndex == halfWidth * halfHeight );
+ }
+ }
+
+ public static void halveImagePackedPixelSlice( int components, Extract extract,
+ int width, int height, int depth, ByteBuffer dataIn,
+ ByteBuffer dataOut, int pixelSizeInBytes, int rowSizeInBytes,
+ int imageSizeInBytes, boolean isSwap ) {
+ int ii, jj;
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int halfDepth = depth / 2;
+ int src = 0;
+ int padBytes = rowSizeInBytes - ( width * pixelSizeInBytes );
+ int outIndex = 0;
+
+ assert( (width == 1 || height == 1) && depth >= 2 );
+
+ if( width == height ) {
+ assert( width == 1 && height == 1 );
+ assert( depth >= 2 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ float totals[] = new float[4];
+ float extractTotals[][] = new float[BOX2][4];
+ int cc;
+
+ dataIn.position( src );
+ extract.extract( isSwap, dataIn, extractTotals[0] );
+ dataIn.position( src + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[1] );
+
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+
+ // average only 2 pixels since a column
+ totals[cc]= 0.0f;
+ for( kk = 0; kk < BOX2; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= BOX2;
+ } // for cc
+
+ extract.shove( totals, outIndex, dataOut );
+ outIndex++;
+ // skip over to next group of 2
+ src += imageSizeInBytes + imageSizeInBytes;
+ } // for ii
+ } else if( height == 1 ) {
+ assert( width != 1 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ float totals[] = new float[4];
+ float extractTotals[][] = new float[BOX4][4];
+ int cc;
+
+ dataIn.position( src );
+ extract.extract( isSwap, dataIn, extractTotals[0] );
+ dataIn.position( src + pixelSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[1] );
+ dataIn.position( src + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[2] );
+ dataIn.position( src + pixelSizeInBytes + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[3] );
+
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX4; kk++ ) {
+ totals[cc]+= extractTotals[kk][cc];
+ }
+ totals[cc]/= (float)BOX4;
+ }
+ extract.shove( totals, outIndex, dataOut );
+ outIndex++;
+ // skip over to next horizontal square of 4
+ src += imageSizeInBytes + imageSizeInBytes;
+ }
+ }
+ } else if( width == 1 ) {
+ assert( height != 1 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ float totals[] = new float[4];
+ float extractTotals[][] = new float[BOX4][4];
+ int cc;
+
+ dataIn.position( src );
+ extract.extract( isSwap, dataIn, extractTotals[0] );
+ dataIn.position( src + rowSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[1] );
+ dataIn.position( src + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[2] );
+ dataIn.position( src + rowSizeInBytes + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[3] );
+
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX4; kk++ ) {
+ totals[cc]+= extractTotals[kk][cc];
+ }
+ totals[cc]/= (float)BOX4;
+ }
+ extract.shove( totals, outIndex, dataOut );
+ outIndex++;
+ // skip over to next horizontal square of 4
+ src += imageSizeInBytes + imageSizeInBytes;
+ }
+ }
+ }
+ }
+
+ public static void halveImageSlice( int components, ExtractPrimitive extract, int width,
+ int height, int depth, ByteBuffer dataIn, ByteBuffer dataOut,
+ int elementSizeInBytes, int groupSizeInBytes, int rowSizeInBytes,
+ int imageSizeInBytes, boolean isSwap ) {
+ int ii, jj;
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int halfDepth = depth / 2;
+ int src = 0;
+ int padBytes = rowSizeInBytes - ( width * groupSizeInBytes );
+ int outIndex = 0;
+
+ assert( (width == 1 || height == 1) && depth >= 2 );
+
+ if( width == height ) {
+ assert( width == 1 && height == 1 );
+ assert( depth >= 2 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ int cc;
+ for( cc = 0; cc < components; cc++ ) {
+ double[] totals = new double[4];
+ double[][] extractTotals = new double[BOX2][4];
+ int kk;
+
+ dataIn.position( src );
+ extractTotals[0][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes );
+ extractTotals[1][cc] = extract.extract( isSwap, dataIn );
+
+ // average 2 pixels since only a column
+ totals[cc] = 0.0f;
+ // totals[red] = extractTotals[0][red] + extractTotals[1][red];
+ // totals[red] = red / 2;
+ for( kk = 0; kk < BOX2; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= (double)BOX2;
+
+ extract.shove( totals[cc], outIndex, dataOut );
+ outIndex++;
+ src += elementSizeInBytes;
+ } // for cc
+ // skip over next group of 2
+ src += rowSizeInBytes;
+ } // for ii
+
+ assert( src == rowSizeInBytes * height * depth );
+ assert( outIndex == halfDepth * components );
+ } else if( height == 1 ) {
+ assert( width != 1 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int cc;
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+ double totals[] = new double[4];
+ double extractTotals[][] = new double[BOX4][4];
+
+ dataIn.position( src );
+ extractTotals[0][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + groupSizeInBytes );
+ extractTotals[1][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes );
+ extractTotals[2][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes + groupSizeInBytes );
+ extractTotals[3][cc] = extract.extract( isSwap, dataIn );
+
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ // totals[red] = extractTotals[0][red] + extractTotals[1][red] +
+ // extractTotals[2][red] + extractTotals[3][red];
+ // totals[red] /= (double)BOX4;
+ for( kk = 0; kk < BOX4; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= (double)BOX4;
+
+ extract.shove( totals[cc], outIndex, dataOut );
+ outIndex++;
+ src += elementSizeInBytes;
+ } // for cc
+ // skip over to next horizontal square of 4
+ src += elementSizeInBytes;
+ } // for jj
+ src += padBytes;
+ src += rowSizeInBytes;
+ } // for ii
+ assert( src == rowSizeInBytes * height * depth );
+ assert( outIndex == halfWidth * halfDepth * components );
+ } else if( width == 1 ) {
+ assert( height != 1 );
+
+ for( ii = 0; ii < halfDepth; ii++ ) {
+ for( jj = 0; jj < halfHeight; jj++ ) {
+ int cc;
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+ double totals[] = new double[4];
+ double extractTotals[][] = new double[BOX4][4];
+
+ dataIn.position( src );
+ extractTotals[0][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + rowSizeInBytes );
+ extractTotals[1][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes );
+ extractTotals[2][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes + groupSizeInBytes );
+ extractTotals[3][cc] = extract.extract( isSwap, dataIn );
+
+
+ // grab 4 pixels to average
+ totals[cc] = 0.0f;
+ // totals[red] = extractTotals[0][red] + extractTotals[1][red] +
+ // extractTotals[2][red] + extractTotals[3][red];
+ // totals[red] /= (double)BOX4;
+ for( kk = 0; kk < BOX4; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= (double)BOX4;
+
+ extract.shove( totals[cc], outIndex, dataOut );
+ outIndex++;
+ src += elementSizeInBytes;
+ } // for cc
+ // skip over to next horizontal square of 4
+ src += padBytes;
+ src += rowSizeInBytes;
+ } // for jj
+ src += imageSizeInBytes;
+ } // for ii
+ assert( src == rowSizeInBytes * height * depth );
+ assert( outIndex == halfWidth * halfDepth * components );
+ }
+ }
+
+ public static void halveImage3D( int components, ExtractPrimitive extract,
+ int width, int height, int depth, ByteBuffer dataIn, ByteBuffer dataOut,
+ int elementSizeInBytes, int groupSizeInBytes, int rowSizeInBytes,
+ int imageSizeInBytes, boolean isSwap ) {
+ assert( depth > 1 );
+
+ // horizontal/vertical/onecolumn slice viewed from top
+ if( width == 1 || height == 1 ) {
+ assert( 1 <= depth );
+
+ halveImageSlice( components, extract, width, height, depth, dataIn, dataOut,
+ elementSizeInBytes, groupSizeInBytes, rowSizeInBytes, imageSizeInBytes,
+ isSwap );
+ return;
+ }
+
+ int ii, jj, dd;
+
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int halfDepth = depth / 2;
+ int src = 0;
+ int padBytes = rowSizeInBytes - ( width * groupSizeInBytes );
+ int outIndex = 0;
+
+ for( dd = 0; dd < halfDepth; dd++ ) {
+ for( ii = 0; ii < halfHeight; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ int cc;
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+ double totals[] = new double[4];
+ double extractTotals[][] = new double[BOX8][4];
+
+ dataIn.position( src );
+ extractTotals[0][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + groupSizeInBytes );
+ extractTotals[1][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + rowSizeInBytes );
+ extractTotals[2][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + rowSizeInBytes + groupSizeInBytes );
+ extractTotals[3][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + imageSizeInBytes );
+ extractTotals[4][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + groupSizeInBytes + imageSizeInBytes );
+ extractTotals[5][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + rowSizeInBytes + imageSizeInBytes );
+ extractTotals[6][cc] = extract.extract( isSwap, dataIn );
+ dataIn.position( src + rowSizeInBytes + imageSizeInBytes + groupSizeInBytes );
+ extractTotals[7][cc] = extract.extract( isSwap, dataIn );
+
+ totals[cc] = 0.0f;
+
+ for( kk = 0; kk < BOX8; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= (double)BOX8;
+
+ extract.shove( totals[cc], outIndex, dataOut );
+ outIndex++;
+
+ src += elementSizeInBytes;
+ } // for cc
+ // skip over to next square of 4
+ src += groupSizeInBytes;
+ } // for jj
+ // skip past pad bytes, if any, to get to next row
+ src += padBytes;
+ src += rowSizeInBytes;
+ } // for ii
+ src += imageSizeInBytes;
+ } // for dd
+ assert( src == rowSizeInBytes * height * depth );
+ assert( outIndex == halfWidth * halfHeight * halfDepth * components );
+ }
+
+ public static void halveImagePackedPixel3D( int components, Extract extract,
+ int width, int height, int depth, ByteBuffer dataIn,
+ ByteBuffer dataOut, int pixelSizeInBytes, int rowSizeInBytes,
+ int imageSizeInBytes, boolean isSwap ) {
+ if( depth == 1 ) {
+ assert( 1 <= width && 1 <= height );
+
+ halveImagePackedPixel( components, extract, width, height, dataIn, dataOut,
+ pixelSizeInBytes, rowSizeInBytes, isSwap );
+ return;
+ } else if( width == 1 || height == 1 ) { // a horizontal or vertical slice viewed from top
+ assert( 1 <= depth );
+
+ halveImagePackedPixelSlice( components, extract, width, height, depth, dataIn,
+ dataOut, pixelSizeInBytes, rowSizeInBytes, imageSizeInBytes, isSwap );
+ return;
+ }
+ int ii, jj, dd;
+
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+ int halfDepth = depth / 2;
+ int src = 0;
+ int padBytes = rowSizeInBytes - ( width * pixelSizeInBytes );
+ int outIndex = 0;
+
+ for( dd = 0; dd < halfDepth; dd++ ) {
+ for( ii = 0; ii < halfHeight; ii++ ) {
+ for( jj = 0; jj < halfWidth; jj++ ) {
+ float totals[] = new float[4]; // 4 is max components
+ float extractTotals[][] = new float[BOX8][4];
+ int cc;
+
+ dataIn.position( src );
+ extract.extract( isSwap, dataIn, extractTotals[0] );
+ dataIn.position( src + pixelSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[1] );
+ dataIn.position( src + rowSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[2] );
+ dataIn.position( src + rowSizeInBytes + pixelSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[3] );
+ dataIn.position( src + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[4] );
+ dataIn.position( src + pixelSizeInBytes + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[5] );
+ dataIn.position( src + rowSizeInBytes + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[6] );
+ dataIn.position( src + rowSizeInBytes + pixelSizeInBytes + imageSizeInBytes );
+ extract.extract( isSwap, dataIn, extractTotals[7] );
+
+ for( cc = 0; cc < components; cc++ ) {
+ int kk;
+ // grab 8 pixels to average
+ totals[cc] = 0.0f;
+ for( kk = 0; kk < BOX8; kk++ ) {
+ totals[cc] += extractTotals[kk][cc];
+ }
+ totals[cc] /= (float)BOX8;
+ }
+ extract.shove( totals, outIndex, dataOut );
+ outIndex++;
+ // skip over to next square of 4
+ src += pixelSizeInBytes + pixelSizeInBytes;
+ }
+ // skip past pad bytes, if any, to get to next row
+ src += padBytes;
+ src += rowSizeInBytes;
+ }
+ src += imageSizeInBytes;
+ }
+ assert( src == rowSizeInBytes * height * depth );
+ assert( outIndex == halfWidth * halfHeight * halfDepth );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Image.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Image.java
new file mode 100644
index 000000000..b2aaad2f7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Image.java
@@ -0,0 +1,1413 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Image {
+
+ /** Creates a new instance of Image */
+ public Image() {
+ }
+
+ public static short getShortFromByteArray( byte[] array, int index ) {
+ short s;
+ s = (short)(array[index] << 8 );
+ s |= (short)(0x00FF & array[index+1]);
+ return( s );
+ }
+
+ public static int getIntFromByteArray( byte[] array, int index ) {
+ int i;
+ i = ( array[index] << 24 ) & 0xFF000000;
+ i |= ( array[index+1] << 16 ) & 0x00FF0000;
+ i |= ( array[index+2] << 8 ) & 0x0000FF00;
+ i |= ( array[index+3] ) & 0x000000FF;
+ return( i );
+ }
+
+ public static float getFloatFromByteArray( byte[] array, int index ) {
+ int i = getIntFromByteArray( array, index );
+ return( Float.intBitsToFloat(i) );
+ }
+
+ /*
+ * Extract array from user's data applying all pixel store modes.
+ * The internal format used is an array of unsigned shorts.
+ */
+ public static void fill_image( PixelStorageModes psm, int width, int height,
+ int format, int type, boolean index_format, ByteBuffer userdata,
+ ShortBuffer newimage ) {
+ int components;
+ int element_size;
+ int rowsize;
+ int padding;
+ int groups_per_line;
+ int group_size;
+ int elements_per_line;
+ int start;
+ int iter = 0;
+ int iter2;
+ int i, j, k;
+ boolean myswap_bytes;
+
+ // Create a Extract interface object
+ Extract extract = null;
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ extract = new Extract332();
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ extract = new Extract233rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ extract = new Extract565();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ extract = new Extract565rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ extract = new Extract4444();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ extract = new Extract4444rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ extract = new Extract5551();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ extract = new Extract1555rev();
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ extract = new Extract8888();
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ extract = new Extract8888rev();
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ extract = new Extract1010102();
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ extract = new Extract2101010rev();
+ break;
+ }
+
+ myswap_bytes = psm.getUnpackSwapBytes();
+ components = Mipmap.elements_per_group( format, type );
+ if( psm.getUnpackRowLength() > 0 ) {
+ groups_per_line = psm.getUnpackRowLength();
+ } else {
+ groups_per_line = width;
+ }
+
+ // All formats except GL_BITMAP fall out trivially
+ if( type == GL2.GL_BITMAP ) {
+ int bit_offset;
+ int current_bit;
+
+ rowsize = ( groups_per_line * components + 7 ) / 8;
+ padding = ( rowsize % psm.getUnpackAlignment() );
+ if( padding != 0 ) {
+ rowsize += psm.getUnpackAlignment() - padding;
+ }
+ start = psm.getUnpackSkipRows() * rowsize + ( psm.getUnpackSkipPixels() * components / 8 );
+ elements_per_line = width * components;
+ iter2 = 0;
+ for( i = 0; i < height; i++ ) {
+ iter = start;
+ userdata.position( iter ); // ****************************************
+ bit_offset = (psm.getUnpackSkipPixels() * components) % 8;
+ for( j = 0; j < elements_per_line; j++ ) {
+ // retrieve bit
+ if( psm.getUnpackLsbFirst() ) {
+ userdata.position( iter );
+ current_bit = ( userdata.get() & 0x000000FF ) & ( 1 << bit_offset );//userdata[iter] & ( 1 << bit_offset );
+ } else {
+ current_bit = ( userdata.get() & 0x000000FF ) & ( 1 << ( 7 - bit_offset ) );
+ }
+ if( current_bit != 0 ) {
+ if( index_format ) {
+ newimage.position( iter2 );
+ newimage.put( (short)1 );
+ } else {
+ newimage.position( iter2 );
+ newimage.put( (short)65535 );
+ }
+ } else {
+ newimage.position( iter2 );
+ newimage.put( (short)0 );
+ }
+ bit_offset++;
+ if( bit_offset == 8 ) {
+ bit_offset = 0;
+ iter++;
+ }
+ iter2++;
+ }
+ start += rowsize;
+ }
+ } else {
+ element_size = Mipmap.bytes_per_element( type );
+ group_size = element_size * components;
+ if( element_size == 1 ) {
+ myswap_bytes = false;
+ }
+
+ rowsize = groups_per_line * group_size;
+ padding = ( rowsize % psm.getUnpackAlignment() );
+ if( padding != 0 ) {
+ rowsize += psm.getUnpackAlignment() - padding;
+ }
+ start = psm.getUnpackSkipRows() * rowsize + psm.getUnpackSkipPixels() * group_size;
+ elements_per_line = width * components;
+
+ iter2 = 0;
+ for( i = 0; i < height; i++ ) {
+ iter = start;
+ userdata.position( iter ); //***************************************
+ for( j = 0; j < elements_per_line; j++ ) {
+ Type_Widget widget = new Type_Widget();
+ float[] extractComponents = new float[4];
+ userdata.position( iter );
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ extract.extract( false, userdata /*userdata[iter]*/, extractComponents );
+ for( k = 0; k < 3; k++ ) {
+ newimage.put( iter2++, (short)(extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ extract.extract( false, userdata /*userdata[iter]*/, extractComponents );
+ for( k = 0; k < 3; k++ ) {
+ newimage.put( iter2++, (short)(extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_BYTE ):
+ if( index_format ) {
+ newimage.put( iter2++, (short)( 0x000000FF & userdata.get() ) );//userdata[iter];
+ } else {
+ newimage.put( iter2++, (short)( 0x000000FF & userdata.get()/*userdata[iter]*/ * 257 ) );
+ }
+ break;
+ case( GL2.GL_BYTE ):
+ if( index_format ) {
+ newimage.put( iter2++, userdata.get() ); //userdata[iter];
+ } else {
+ newimage.put( iter2++, (short)(userdata.get()/*userdata[iter]*/ * 516 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ extract.extract( myswap_bytes, userdata/*userdata[iter]*/, extractComponents );
+ for( k = 0; k < 3; k++ ) {
+ newimage.put( iter2++, (short)(extractComponents[k] * 65535) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ extract.extract( myswap_bytes, userdata, extractComponents );
+ for( k = 0; k < 3; k++ ) {
+ newimage.put( iter2++, (short)(extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ extract.extract( myswap_bytes, userdata, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newimage.put( iter2++, (short)(extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ extract.extract( myswap_bytes, userdata, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newimage.put( iter2++, (short)( extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ extract.extract( myswap_bytes, userdata, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newimage.put( iter2++, (short)(extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ extract.extract( myswap_bytes, userdata, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newimage.put( iter2++, (short)( extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ if( myswap_bytes ) {
+ widget.setUB1( userdata.get() );
+ widget.setUB0( userdata.get() );
+ } else {
+ widget.setUB0( userdata.get() );
+ widget.setUB1( userdata.get() );
+ }
+ if( type == GL2.GL_SHORT ) {
+ if( index_format ) {
+ newimage.put( iter2++, widget.getS0() );
+ } else {
+ newimage.put( iter2++, (short)(widget.getS0() * 2) );
+ }
+ } else {
+ newimage.put( iter2++, widget.getUS0() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ extract.extract( myswap_bytes, userdata, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newimage.put( iter2++, (short)( extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ extract.extract( myswap_bytes, userdata, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newimage.put( iter2++, (short)( extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ extract.extract( myswap_bytes, userdata, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newimage.put( iter2++, (short)( extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ extract.extract( myswap_bytes, userdata, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newimage.put( iter2++, (short)( extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_INT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_FLOAT ):
+ if( myswap_bytes ) {
+ widget.setUB3( userdata.get() );
+ widget.setUB2( userdata.get() );
+ widget.setUB1( userdata.get() );
+ widget.setUB0( userdata.get() );
+ } else {
+ widget.setUB0( userdata.get() );
+ widget.setUB1( userdata.get() );
+ widget.setUB2( userdata.get() );
+ widget.setUB3( userdata.get() );
+ }
+ if( type == GL2.GL_FLOAT ) {
+ if( index_format ) {
+ newimage.put( iter2++, (short)widget.getF() );
+ } else {
+ newimage.put( iter2++, (short)(widget.getF() * 65535 ) );
+ }
+ } else if( type == GL2.GL_UNSIGNED_INT ) {
+ if( index_format ) {
+ newimage.put( iter2++, (short)( widget.getUI() ) );
+ } else {
+ newimage.put( iter2++, (short)( widget.getUI() >> 16 ) );
+ }
+ } else {
+ if( index_format ) {
+ newimage.put( iter2++, (short)( widget.getI() ) );
+ } else {
+ newimage.put( iter2++, (short)( widget.getI() >> 15 ) );
+ }
+ }
+ break;
+ }
+ iter += element_size;
+ } // for j
+ start += rowsize;
+ // want iter pointing at start, not within, row for assertion purposes
+ iter = start;
+ } // for i
+
+ // iterators should be one byte past end
+ if( !Mipmap.isTypePackedPixel( type ) ) {
+ assert( iter2 == ( width * height * components ) );
+ } else {
+ assert( iter2 == ( width * height * Mipmap.elements_per_group( format, 0 ) ) );
+ }
+ assert( iter == ( rowsize * height + psm.getUnpackSkipRows() * rowsize + psm.getUnpackSkipPixels() * group_size ) );
+ }
+ }
+
+ /*
+ * Insert array into user's data applying all pixel store modes.
+ * Theinternal format is an array of unsigned shorts.
+ * empty_image() because it is the opposet of fill_image().
+ */
+ public static void empty_image( PixelStorageModes psm, int width, int height,
+ int format, int type, boolean index_format,
+ ShortBuffer oldimage, ByteBuffer userdata ) {
+
+ int components;
+ int element_size;
+ int rowsize;
+ int padding;
+ int groups_per_line;
+ int group_size;
+ int elements_per_line;
+ int start;
+ int iter = 0;
+ int iter2;
+ int i, j, k;
+ boolean myswap_bytes;
+
+ // Create a Extract interface object
+ Extract extract = null;
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ extract = new Extract332();
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ extract = new Extract233rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ extract = new Extract565();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ extract = new Extract565rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ extract = new Extract4444();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ extract = new Extract4444rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ extract = new Extract5551();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ extract = new Extract1555rev();
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ extract = new Extract8888();
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ extract = new Extract8888rev();
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ extract = new Extract1010102();
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ extract = new Extract2101010rev();
+ break;
+ }
+
+ myswap_bytes = psm.getPackSwapBytes();
+ components = Mipmap.elements_per_group( format, type );
+ if( psm.getPackRowLength() > 0 ) {
+ groups_per_line = psm.getPackRowLength();
+ } else {
+ groups_per_line = width;
+ }
+
+ // all formats except GL_BITMAP fall out trivially
+ if( type == GL2.GL_BITMAP ) {
+ int bit_offset;
+ int current_bit;
+
+ rowsize = ( groups_per_line * components + 7 ) / 8;
+ padding = ( rowsize % psm.getPackAlignment() );
+ if( padding != 0 ) {
+ rowsize += psm.getPackAlignment() - padding;
+ }
+ start = psm.getPackSkipRows() * rowsize + psm.getPackSkipPixels() * components / 8;
+ elements_per_line = width * components;
+ iter2 = 0;
+ for( i = 0; i < height; i++ ) {
+ iter = start;
+ bit_offset = ( psm.getPackSkipPixels() * components ) % 8;
+ for( j = 0; j < elements_per_line; j++ ) {
+ if( index_format ) {
+ current_bit = oldimage.get( iter2 ) & 1;
+ } else {
+ if( oldimage.get( iter2 ) < 0 ) { // must check for negative rather than 32767
+ current_bit = 1;
+ } else {
+ current_bit = 0;
+ }
+ }
+
+ if( current_bit != 0 ) {
+ if( psm.getPackLsbFirst() ) {
+ userdata.put( iter, (byte)( ( userdata.get( iter ) | ( 1 << bit_offset ) ) ) );
+ } else {
+ userdata.put( iter, (byte)( ( userdata.get( iter ) | ( 7 - bit_offset ) ) ) );
+ }
+ } else {
+ if( psm.getPackLsbFirst() ) {
+ //userdata[iter] &= ~( 1 << bit_offset );
+ userdata.put( iter, (byte)( ( userdata.get( iter ) & ~( 1 << bit_offset ) ) ) );
+ } else {
+ //userdata[iter] &= ~( 1 << ( 7 - bit_offset ) );
+ userdata.put( iter, (byte)( ( userdata.get( iter ) & ~( 7 - bit_offset ) ) ) );
+ }
+ }
+
+ bit_offset++;
+ if( bit_offset == 8 ) {
+ bit_offset = 0;
+ iter++;
+ }
+ iter2++;
+ }
+ start += rowsize;
+ }
+ } else {
+ float shoveComponents[] = new float[4];
+
+ element_size = Mipmap.bytes_per_element( type );
+ group_size = element_size * components;
+ if( element_size == 1 ) {
+ myswap_bytes = false;
+ }
+
+ rowsize = groups_per_line * group_size;
+ padding = ( rowsize % psm.getPackAlignment() );
+ if( padding != 0 ) {
+ rowsize += psm.getPackAlignment() - padding;
+ }
+ start = psm.getPackSkipRows() * rowsize + psm.getPackSkipPixels() * group_size;
+ elements_per_line = width * components;
+
+ iter2 = 0;
+ for( i = 0; i < height; i++ ) {
+ iter = start;
+ for( j = 0; j < elements_per_line; j++ ) {
+ Type_Widget widget = new Type_Widget();
+
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ for( k = 0; k < 3; k++ ) {
+ shoveComponents[k] = oldimage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, userdata );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ for( k = 0; k < 3; k++ ) {
+ shoveComponents[k] = oldimage.get(iter2++) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, userdata );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE ):
+ if( index_format ) {
+ //userdata[iter] = (byte)oldimage[iter2++];
+ userdata.put( iter, (byte)oldimage.get(iter2++) );
+ } else {
+ //userdata[iter] = (byte)( oldimage[iter2++] >> 8 );
+ userdata.put( iter, (byte)( oldimage.get(iter2++) ) );
+ }
+ break;
+ case( GL2.GL_BYTE ):
+ if( index_format ) {
+ //userdata[iter] = (byte)oldimage[iter2++];
+ userdata.put( iter, (byte)oldimage.get(iter2++) );
+ } else {
+ //userdata[iter] = (byte)( oldimage[iter2++] >> 9 );
+ userdata.put( iter, (byte)( oldimage.get(iter2++) ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ for( k = 0; k < 3; k++ ) {
+ shoveComponents[k] = oldimage.get(iter2++) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswap_bytes ) {
+ //userdata[iter] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB0();
+ userdata.put( iter, widget.getUB1() );
+ userdata.put( iter + 1,widget.getUB0() );
+ } else {
+ //userdata[iter] = widget.getUB0();
+ //userdata[iter+1] = widget.getUB1();
+ userdata.put( iter, widget.getUB0() );
+ userdata.put( iter + 1, widget.getUB1() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ for( k = 0; k < 3; k++ ) {
+ shoveComponents[k] = oldimage.get(iter2++) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswap_bytes ) {
+ //userdata[iter] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB0();
+ userdata.put( iter, widget.getUB1() );
+ userdata.put( iter + 1, widget.getUB0() );
+ } else {
+ //userdata[iter] = widget.getUB0();
+ //userdata[iter+1] = widget.getUB1();
+ userdata.put( iter, widget.getUB0() );
+ userdata.put( iter, widget.getUB1() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldimage.get(iter2++) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswap_bytes ) {
+ //userdata[iter] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB0();
+ userdata.put( iter, widget.getUB1() );
+ userdata.put( iter + 1, widget.getUB0() );
+ } else {
+ //userdata[iter] = widget.getUB0();
+ //userdata[iter+1] = widget.getUB1();
+ userdata.put( iter, widget.getUB0() );
+ userdata.put( iter + 1, widget.getUB1() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldimage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswap_bytes ) {
+ //userdata[iter] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB0();
+ userdata.put( iter, widget.getUB1() );
+ userdata.put( iter + 1, widget.getUB0() );
+ } else {
+ //userdata[iter] = widget.getUB0();
+ //userdata[iter+1] = widget.getUB1();
+ userdata.put( iter, widget.getUB0() );
+ userdata.put( iter + 1, widget.getUB1() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldimage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswap_bytes ) {
+ //userdata[iter] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB0();
+ userdata.put( iter, widget.getUB1() );
+ userdata.put( iter + 1, widget.getUB0() );
+ } else {
+ //userdata[iter] = widget.getUB0();
+ //userdata[iter+1] = widget.getUB1();
+ userdata.put( iter, widget.getUB0() );
+ userdata.put( iter + 1, widget.getUB1() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldimage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswap_bytes ) {
+ //userdata[iter] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB0();
+ userdata.put( iter, widget.getUB1() );
+ userdata.put( iter + 1, widget.getUB0() );
+ } else {
+ //userdata[iter] = widget.getUB0();
+ //userdata[iter+1] = widget.getUB1();
+ userdata.put( iter, widget.getUB0() );
+ userdata.put( iter + 1, widget.getUB1() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ if( type == GL2.GL_SHORT ) {
+ if( index_format ) {
+ widget.setS0( oldimage.get( iter2++ ) );
+ } else {
+ widget.setS0( (short)(oldimage.get( iter2++ ) >> 1) );
+ }
+ } else {
+ widget.setUS0( oldimage.get( iter2++ ) );
+ }
+ if( myswap_bytes ) {
+ //userdata[iter] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB0();
+ userdata.put( iter, widget.getUB1() );
+ userdata.put( iter + 1, widget.getUB0() );
+ } else {
+ //userdata[iter] = widget.getUB0();
+ //userdata[iter] = widget.getUB1();
+ userdata.put( iter, widget.getUB0() );
+ userdata.put( iter + 1, widget.getUB1() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldimage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswap_bytes ) {
+ //userdata[iter+3] = widget.getUB0();
+ //userdata[iter+2] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB2();
+ //userdata[iter ] = widget.getUB3();
+ userdata.put( iter + 3, widget.getUB0() );
+ userdata.put( iter + 2, widget.getUB1() );
+ userdata.put( iter + 1, widget.getUB2() );
+ userdata.put( iter , widget.getUB3() );
+ } else {
+ userdata.putInt( iter, widget.getUI() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldimage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswap_bytes ) {
+ //userdata[iter+3] = widget.getUB0();
+ //userdata[iter+2] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB2();
+ //userdata[iter ] = widget.getUB3();
+ userdata.put( iter + 3, widget.getUB0() );
+ userdata.put( iter + 2, widget.getUB1() );
+ userdata.put( iter + 2, widget.getUB2() );
+ userdata.put( iter , widget.getUB3() );
+ } else {
+ userdata.putInt( iter, widget.getUI() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldimage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswap_bytes ) {
+ //userdata[iter+3] = widget.getUB0();
+ //userdata[iter+2] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB2();
+ //userdata[iter ] = widget.getUB3();
+ userdata.put( iter + 3, widget.getUB0() );
+ userdata.put( iter + 2, widget.getUB1() );
+ userdata.put( iter + 1, widget.getUB2() );
+ userdata.put( iter , widget.getUB3() );
+ } else {
+ userdata.putInt( iter, widget.getUI() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldimage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswap_bytes ) {
+ //userdata[iter+3] = widget.getUB0();
+ //userdata[iter+2] = widget.getUB1();
+ //userdata[iter+1] = widget.getUB2();
+ //userdata[iter ] = widget.getUB3();
+ userdata.put( iter + 3, widget.getUB0() );
+ userdata.put( iter + 2, widget.getUB1() );
+ userdata.put( iter + 1, widget.getUB2() );
+ userdata.put( iter , widget.getUB3() );
+ } else {
+ userdata.putInt( iter, widget.getUI() );
+ }
+ break;
+ case( GL2.GL_INT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_FLOAT ):
+ if( type == GL2.GL_FLOAT ) {
+ if( index_format ) {
+ widget.setF( oldimage.get( iter2++ ) );
+ } else {
+ widget.setF( oldimage.get( iter2++ ) / 65535.0f );
+ }
+ } else if( type == GL2.GL_UNSIGNED_INT ) {
+ if( index_format ) {
+ widget.setUI( oldimage.get( iter2++ ) );
+ } else {
+ widget.setUI( oldimage.get( iter2++ ) * 65537 );
+ }
+ } else {
+ if( index_format ) {
+ widget.setI( oldimage.get( iter2++ ) );
+ } else {
+ widget.setI( (oldimage.get( iter2++ ) * 65537) / 2 );
+ }
+ }
+ if( myswap_bytes ) {
+ userdata.put( iter + 3, widget.getUB0() );
+ userdata.put( iter + 2, widget.getUB1() );
+ userdata.put( iter + 1, widget.getUB2() );
+ userdata.put( iter , widget.getUB3() );
+ } else {
+ userdata.put( iter , widget.getUB0() );
+ userdata.put( iter + 1, widget.getUB1() );
+ userdata.put( iter + 2, widget.getUB2() );
+ userdata.put( iter + 3, widget.getUB3() );
+ }
+ break;
+ }
+ iter += element_size;
+ } // for j
+ start += rowsize;
+ // want iter pointing at start, not within, row for assertion purposes
+ iter = start;
+ } // for i
+ // iterators should be one byte past end
+ if( !Mipmap.isTypePackedPixel( type ) ) {
+ assert( iter2 == width * height * components );
+ } else {
+ assert( iter2 == width * height * Mipmap.elements_per_group( format, 0 ) );
+ }
+ assert( iter == rowsize * height + psm.getPackSkipRows() * rowsize + psm.getPackSkipPixels() * group_size );
+ }
+ }
+
+ public static void fillImage3D( PixelStorageModes psm, int width, int height,
+ int depth, int format, int type, boolean indexFormat, ByteBuffer userImage,
+ ShortBuffer newImage ) {
+ boolean myswapBytes;
+ int components;
+ int groupsPerLine;
+ int elementSize;
+ int groupSize;
+ int rowSize;
+ int padding;
+ int elementsPerLine;
+ int rowsPerImage;
+ int imageSize;
+ int start, rowStart;
+ int iter = 0;
+ int iter2 = 0;
+ int ww, hh, dd, k;
+ Type_Widget widget = new Type_Widget();
+ float extractComponents[] = new float[4];
+
+ // Create a Extract interface object
+ Extract extract = null;
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ extract = new Extract332();
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ extract = new Extract233rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ extract = new Extract565();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ extract = new Extract565rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ extract = new Extract4444();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ extract = new Extract4444rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ extract = new Extract5551();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ extract = new Extract1555rev();
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ extract = new Extract8888();
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ extract = new Extract8888rev();
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ extract = new Extract1010102();
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ extract = new Extract2101010rev();
+ break;
+ }
+
+ myswapBytes = psm.getUnpackSwapBytes();
+ components = Mipmap.elements_per_group( format, type );
+ if( psm.getUnpackRowLength() > 0 ) {
+ groupsPerLine = psm.getUnpackRowLength();
+ } else {
+ groupsPerLine = width;
+ }
+ elementSize = Mipmap.bytes_per_element( type );
+ groupSize = elementSize * components;
+ if( elementSize == 1 ) {
+ myswapBytes = false;
+ }
+
+ // 3dstuff begin
+ if( psm.getUnpackImageHeight() > 0 ) {
+ rowsPerImage = psm.getUnpackImageHeight();
+ } else {
+ rowsPerImage = height;
+ }
+ // 3dstuff end
+
+ rowSize = groupsPerLine * groupSize;
+ padding = rowSize % psm.getUnpackAlignment();
+ if( padding != 0 ) {
+ rowSize += psm.getUnpackAlignment() - padding;
+ }
+
+ imageSize = rowsPerImage * rowSize; // 3dstuff
+
+ start = psm.getUnpackSkipRows() * rowSize +
+ psm.getUnpackSkipPixels() * groupSize +
+ psm.getUnpackSkipImages() * imageSize;
+ elementsPerLine = width * components;
+
+ iter2 = 0;
+ for( dd = 0; dd < depth; dd++ ) {
+ rowStart = start;
+ for( hh = 0; hh < height; hh++ ) {
+ iter = rowStart;
+ for( ww = 0; ww < elementsPerLine; ww++ ) {
+
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ if( indexFormat ) {
+ newImage.put( iter2++, (short)(0x000000FF & userImage.get( iter ) ) );
+ } else {
+ newImage.put( iter2++, (short)((0x000000FF & userImage.get( iter ) ) * 257 ) );
+ }
+ break;
+ case( GL2.GL_BYTE ):
+ if( indexFormat ) {
+ newImage.put( iter2++, userImage.get( iter ) );
+ } else {
+ newImage.put( iter2++, (short)(userImage.get( iter ) * 516 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ userImage.position( iter );
+ extract.extract( false, userImage, extractComponents );
+ for( k = 0; k < 3; k++ ) {
+ newImage.put( iter2++, (short)(extractComponents[k] * 65535) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ userImage.position( iter );
+ extract.extract( false, userImage, extractComponents );
+ for( k = 0; k < 3; k++ ) {
+ newImage.put( iter2++, (short)(extractComponents[k] * 65535) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ userImage.position( iter );
+ extract.extract( myswapBytes, userImage, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newImage.put( iter2++, (short)(extractComponents[k] * 65535) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ userImage.position( iter );
+ extract.extract( myswapBytes, userImage, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newImage.put( iter2++, (short)(extractComponents[k] * 65535) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ userImage.position( iter );
+ extract.extract( myswapBytes, userImage, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newImage.put( iter2++, (short)(extractComponents[k] * 65535) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ userImage.position( iter );
+ extract.extract( myswapBytes, userImage, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newImage.put( iter2++, (short)(extractComponents[k] * 65535) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ userImage.position( iter );
+ extract.extract( myswapBytes, userImage, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newImage.put( iter2++, (short)(extractComponents[k] * 65535) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ userImage.position( iter );
+ extract.extract( myswapBytes, userImage, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newImage.put( iter2++, (short)(extractComponents[k] * 65535) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ if( myswapBytes ) {
+ widget.setUB0( userImage.get( iter + 1 ) );
+ widget.setUB1( userImage.get( iter ) );
+ } else {
+ widget.setUB0( userImage.get( iter ) );
+ widget.setUB1( userImage.get( iter + 1 ) );
+ }
+ if( type == GL2.GL_SHORT ) {
+ if( indexFormat ) {
+ newImage.put( iter2++, widget.getUS0() );
+ } else {
+ newImage.put( iter2++, (short)(widget.getUS0() * 2) );
+ }
+ } else {
+ newImage.put( iter2++, widget.getUS0() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ userImage.position( iter );
+ extract.extract( myswapBytes, userImage, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newImage.put( iter2++, (short)( extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ userImage.position( iter );
+ extract.extract( myswapBytes, userImage, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newImage.put( iter2++, (short)( extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ userImage.position( iter );
+ extract.extract( myswapBytes, userImage, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newImage.put( iter2++, (short)( extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ extract.extract( myswapBytes, userImage, extractComponents );
+ for( k = 0; k < 4; k++ ) {
+ newImage.put( iter2++, (short)( extractComponents[k] * 65535 ) );
+ }
+ break;
+ case( GL2.GL_INT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_FLOAT ):
+ if( myswapBytes ) {
+ widget.setUB0( userImage.get( iter + 3 ) );
+ widget.setUB1( userImage.get( iter + 2 ) );
+ widget.setUB2( userImage.get( iter + 1 ) );
+ widget.setUB3( userImage.get( iter ) );
+ } else {
+ widget.setUB0( userImage.get( iter ) );
+ widget.setUB1( userImage.get( iter + 1 ) );
+ widget.setUB2( userImage.get( iter + 2 ) );
+ widget.setUB3( userImage.get( iter + 3 ) );
+ }
+ if( type == GL2.GL_FLOAT ) {
+ if( indexFormat ) {
+ newImage.put( iter2++, (short)widget.getF() );
+ } else {
+ newImage.put( iter2++, (short)( widget.getF() * 65535.0f ) );
+ }
+ } else if( type == GL2.GL_UNSIGNED_INT ) {
+ if( indexFormat ) {
+ newImage.put( iter2++, (short)widget.getUI() );
+ } else {
+ newImage.put( iter2++, (short)(widget.getUI() >> 16) );
+ }
+ } else {
+ if( indexFormat ) {
+ newImage.put( iter2++, (short)widget.getI() );
+ } else {
+ newImage.put( iter2++, (short)(widget.getI() >> 15) );
+ }
+ }
+ break;
+ default:
+ assert( false );
+ }
+ iter += elementSize;
+ } // for ww
+ rowStart += rowSize;
+ iter = rowStart; // for assert
+ } // for hh
+ start += imageSize;
+ }// for dd
+
+ // iterators should be one byte past end
+ if( !Mipmap.isTypePackedPixel( type ) ) {
+ assert( iter2 == width * height * depth * components );
+ } else {
+ assert( iter2 == width * height * depth * Mipmap.elements_per_group( format, 0 ) );
+ }
+ assert( iter == rowSize * height * depth + psm.getUnpackSkipRows() * rowSize +
+ psm.getUnpackSkipPixels() * groupSize +
+ psm.getUnpackSkipImages() * imageSize );
+ }
+
+ public static void emptyImage3D( PixelStorageModes psm, int width, int height, int depth,
+ int format, int type, boolean indexFormat, ShortBuffer oldImage, ByteBuffer userImage ) {
+ boolean myswapBytes;
+ int components;
+ int groupsPerLine;
+ int elementSize;
+ int groupSize;
+ int rowSize;
+ int padding;
+ int start, rowStart, iter;
+ int elementsPerLine;
+ int iter2;
+ int ii, jj, dd, k;
+ int rowsPerImage;
+ int imageSize;
+ Type_Widget widget = new Type_Widget();
+ float[] shoveComponents = new float[4];
+
+ // Create a Extract interface object
+ Extract extract = null;
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ extract = new Extract332();
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ extract = new Extract233rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ extract = new Extract565();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ extract = new Extract565rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ extract = new Extract4444();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ extract = new Extract4444rev();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ extract = new Extract5551();
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ extract = new Extract1555rev();
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ extract = new Extract8888();
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ extract = new Extract8888rev();
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ extract = new Extract1010102();
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ extract = new Extract2101010rev();
+ break;
+ }
+
+ iter = 0;
+
+ myswapBytes = psm.getPackSwapBytes();
+ components = Mipmap.elements_per_group( format, type );
+ if( psm.getPackRowLength() > 0 ) {
+ groupsPerLine = psm.getPackRowLength();
+ } else {
+ groupsPerLine = width;
+ }
+
+ elementSize = Mipmap.bytes_per_element( type );
+ groupSize = elementSize * components;
+ if( elementSize == 1 ) {
+ myswapBytes = false;
+ }
+
+ // 3dstuff begin
+ if( psm.getPackImageHeight() > 0 ) {
+ rowsPerImage = psm.getPackImageHeight();
+ } else {
+ rowsPerImage = height;
+ }
+
+ // 3dstuff end
+
+ rowSize = groupsPerLine * groupSize;
+ padding = rowSize % psm.getPackAlignment();
+ if( padding != 0 ) {
+ rowSize += psm.getPackAlignment() - padding;
+ }
+
+ imageSize = rowsPerImage * rowSize;
+
+ start = psm.getPackSkipRows() * rowSize +
+ psm.getPackSkipPixels() * groupSize +
+ psm.getPackSkipImages() * imageSize;
+ elementsPerLine = width * components;
+
+ iter2 = 0;
+ for( dd = 0; dd < depth; dd++ ) {
+ rowStart = start;
+
+ for( ii = 0; ii < height; ii++ ) {
+ iter = rowStart;
+
+ for( jj = 0; jj < elementsPerLine; jj++ ) {
+
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ if( indexFormat ) {
+ userImage.put( iter, (byte)(oldImage.get( iter2++ ) ) );
+ } else {
+ userImage.put( iter, (byte)(oldImage.get( iter2++ ) >> 8 ) );
+ }
+ break;
+ case( GL2.GL_BYTE ):
+ if( indexFormat ) {
+ userImage.put( iter, (byte)(oldImage.get(iter2++) ) );
+ } else {
+ userImage.put( iter, (byte)(oldImage.get(iter2++) >> 9) );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ for( k = 0; k < 3; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, userImage );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ for( k = 0; k < 3; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, userImage );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswapBytes ) {
+ userImage.putShort( iter, widget.getUB1() );
+ userImage.putShort( iter + 1, widget.getUB0() );
+ } else {
+ userImage.putShort( iter, widget.getUS0() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswapBytes ) {
+ userImage.put( iter, widget.getUB1() );
+ userImage.put( iter + 1, widget.getUB0() );
+ } else {
+ userImage.putShort( iter, widget.getUS0() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswapBytes ) {
+ userImage.put( iter, widget.getUB1() );
+ userImage.put( iter + 1, widget.getUB0() );
+ } else {
+ userImage.putShort( iter, widget.getUS0() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswapBytes ) {
+ userImage.put( iter, widget.getUB1() );
+ userImage.put( iter + 1, widget.getUB0() );
+ } else {
+ userImage.putShort( iter, widget.getUS0() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswapBytes ) {
+ userImage.put( iter, widget.getUB1() );
+ userImage.put( iter + 1, widget.getUB0() );
+ } else {
+ userImage.putShort( iter, widget.getUS0() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswapBytes ) {
+ userImage.put( iter, widget.getUB1() );
+ userImage.put( iter + 1, widget.getUB0() );
+ } else {
+ userImage.putShort( iter, widget.getUS0() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ if( type == GL2.GL_SHORT ) {
+ if( indexFormat ) {
+ widget.setS0( (short)oldImage.get( iter2++ ) );
+ } else {
+ widget.setS0( (short)(oldImage.get( iter2++ ) >> 1) );
+ }
+ } else {
+ widget.setUS0( (short)oldImage.get( iter2++ ) );
+ }
+ if( myswapBytes ) {
+ userImage.put( iter, widget.getUB1() );
+ userImage.put( iter + 1, widget.getUB0() );
+ } else {
+ userImage.put( iter, widget.getUB0() );
+ userImage.put( iter + 1, widget.getUB1() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswapBytes ) {
+ userImage.put( iter + 3, widget.getUB0() );
+ userImage.put( iter + 2, widget.getUB1() );
+ userImage.put( iter + 1, widget.getUB2() );
+ userImage.put( iter , widget.getUB3() );
+ } else {
+ userImage.putInt( iter, widget.getUI() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswapBytes ) {
+ userImage.put( iter + 3, widget.getUB0() );
+ userImage.put( iter + 2, widget.getUB1() );
+ userImage.put( iter + 1, widget.getUB2() );
+ userImage.put( iter , widget.getUB3() );
+ } else {
+ userImage.putInt( iter, widget.getUI() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswapBytes ) {
+ userImage.put( iter + 3, widget.getUB0() );
+ userImage.put( iter + 2, widget.getUB1() );
+ userImage.put( iter + 1, widget.getUB2() );
+ userImage.put( iter ,widget.getUB3() );
+ } else {
+ userImage.putInt( iter, widget.getUI() );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ for( k = 0; k < 4; k++ ) {
+ shoveComponents[k] = oldImage.get( iter2++ ) / 65535.0f;
+ }
+ extract.shove( shoveComponents, 0, widget.getBuffer() );
+ if( myswapBytes ) {
+ userImage.put( iter + 3, widget.getUB0() );
+ userImage.put( iter + 2, widget.getUB2() );
+ userImage.put( iter + 1, widget.getUB1() );
+ userImage.put( iter , widget.getUB0() );
+ } else {
+ userImage.putInt( iter, widget.getUI() );
+ }
+ break;
+ case( GL2.GL_INT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_FLOAT ):
+ if( type == GL2.GL_FLOAT ) {
+ if( indexFormat ) {
+ widget.setF( oldImage.get( iter2++ ) );
+ } else {
+ widget.setF( oldImage.get( iter2++ ) / 65535.0f );
+ }
+ } else if( type == GL2.GL_UNSIGNED_INT ) {
+ if( indexFormat ) {
+ widget.setUI( oldImage.get( iter2++ ) );
+ } else {
+ widget.setUI( oldImage.get( iter2++ ) * 65537 );
+ }
+ } else {
+ if( indexFormat ) {
+ widget.setI( oldImage.get( iter2++ ) );
+ } else {
+ widget.setI( ( oldImage.get( iter2++ ) * 65535 ) / 2 );
+ }
+ }
+ if( myswapBytes ) {
+ userImage.put( iter + 3, widget.getUB0() );
+ userImage.put( iter + 2, widget.getUB1() );
+ userImage.put( iter + 1, widget.getUB2() );
+ userImage.put( iter , widget.getUB3() );
+ } else {
+ userImage.put( iter , widget.getUB0() );
+ userImage.put( iter + 1, widget.getUB1() );
+ userImage.put( iter + 2, widget.getUB2() );
+ userImage.put( iter + 3, widget.getUB3() );
+ }
+ break;
+ default:
+ assert( false );
+ }
+
+ iter += elementSize;
+ } // for jj
+ rowStart += rowSize;
+ } // for ii
+ start += imageSize;
+ } // for dd
+
+ if( !Mipmap.isTypePackedPixel( type ) ) {
+ assert( iter2 == width * height * depth * components );
+ } else {
+ assert( iter2 == width * height * depth * Mipmap.elements_per_group( format, 0 ) );
+ }
+ assert( iter == rowSize * height * depth +
+ psm.getUnpackSkipRows() * rowSize +
+ psm.getUnpackSkipPixels() * groupSize +
+ psm.getUnpackSkipImages() * imageSize );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Mipmap.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Mipmap.java
new file mode 100644
index 000000000..1c0707c57
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Mipmap.java
@@ -0,0 +1,868 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.glu.GLU;
+import javax.media.opengl.GLException;
+import java.nio.*;
+import com.jogamp.opengl.impl.InternalBufferUtil;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Mipmap {
+
+ /** Creates a new instance of Mipmap */
+ public Mipmap() {
+ }
+
+ public static int computeLog( int value ) {
+ int i = 0;
+ // Error
+ if( value == 0 ) {
+ return( -1 );
+ }
+ for( ;; ) {
+ if( (value & 1) >= 1 ) {
+ if( value != 1 ) {
+ return( -1 );
+ }
+ return( i );
+ }
+ value = value >> 1;
+ i++;
+ }
+ }
+
+ /* Compute the nearest power of 2 number. This algorithm is a little strange
+ * but it works quite well.
+ */
+ public static int nearestPower( int value ) {
+ int i = 1;
+ // Error!
+ if( value == 0 ) {
+ return( -1 );
+ }
+ for( ;; ) {
+ if( value == 1 ) {
+ return( i );
+ } else if( value == 3 ) {
+ return( i * 4 );
+ }
+ value = value >> 1;
+ i *= 2;
+ }
+ }
+
+ public static short GLU_SWAP_2_BYTES( short s ) {
+ byte b = 0;
+ b = (byte)( s >>> 8 );
+ s = (short)( s << 8 );
+ s = (short)( s | (0x00FF & b) );
+ return( s );
+ }
+
+ public static int GLU_SWAP_4_BYTES( int i ) {
+ int t = i << 24;
+ t |= 0x00FF0000 & ( i << 8 );
+ t |= 0x0000FF00 & ( i >>> 8 );
+ t |= 0x000000FF & ( i >>> 24 );
+ return( t );
+ }
+
+ public static float GLU_SWAP_4_BYTES( float f ) {
+ int i = Float.floatToRawIntBits( f );
+ float temp = Float.intBitsToFloat( i );
+ return( temp );
+ }
+
+ public static int checkMipmapArgs( int internalFormat, int format, int type ) {
+ if( !legalFormat( format ) || !legalType( type ) ) {
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ if( format == GL2GL3.GL_STENCIL_INDEX ) {
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ if( !isLegalFormatForPackedPixelType( format, type ) ) {
+ return( GLU.GLU_INVALID_OPERATION );
+ }
+ return( 0 );
+ }
+
+ public static boolean legalFormat( int format ) {
+ switch( format ) {
+ case( GL2.GL_COLOR_INDEX ):
+ case( GL2GL3.GL_STENCIL_INDEX ):
+ case( GL2GL3.GL_DEPTH_COMPONENT ):
+ case( GL2GL3.GL_RED ):
+ case( GL2GL3.GL_GREEN ):
+ case( GL2GL3.GL_BLUE ):
+ case( GL2GL3.GL_ALPHA ):
+ case( GL2GL3.GL_RGB ):
+ case( GL2GL3.GL_RGBA ):
+ case( GL2GL3.GL_LUMINANCE ):
+ case( GL2GL3.GL_LUMINANCE_ALPHA ):
+ case( GL2GL3.GL_BGR ):
+ case( GL2GL3.GL_BGRA ):
+ return( true );
+ default:
+ return( false );
+ }
+ }
+
+ public static boolean legalType( int type ) {
+ switch( type ) {
+ case( GL2.GL_BITMAP ):
+ case( GL2GL3.GL_BYTE ):
+ case( GL2GL3.GL_UNSIGNED_BYTE ):
+ case( GL2GL3.GL_SHORT ):
+ case( GL2GL3.GL_UNSIGNED_SHORT ):
+ case( GL2GL3.GL_INT ):
+ case( GL2GL3.GL_UNSIGNED_INT ):
+ case( GL2GL3.GL_FLOAT ):
+ case( GL2GL3.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2GL3.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2GL3.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2GL3.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ return( true );
+ default:
+ return( false );
+ }
+ }
+
+ public static boolean isTypePackedPixel( int type ) {
+ assert( legalType( type ) );
+
+ if( type == GL2GL3.GL_UNSIGNED_BYTE_3_3_2 ||
+ type == GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_5_6_5 ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4 ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1 ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV ||
+ type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8 ||
+ type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV ||
+ type == GL2GL3.GL_UNSIGNED_INT_10_10_10_2 ||
+ type == GL2GL3.GL_UNSIGNED_INT_2_10_10_10_REV ) {
+ return( true );
+ }
+ return( false );
+ }
+
+ public static boolean isLegalFormatForPackedPixelType( int format, int type ) {
+ // if not a packed pixel type then return true
+ if( isTypePackedPixel( type ) ) {
+ return( true );
+ }
+
+ // 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB
+ if( (type == GL2GL3.GL_UNSIGNED_BYTE_3_3_2 || type == GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_5_6_5 || type == GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV )
+ & format != GL2GL3.GL_RGB ) {
+ return( false );
+ }
+
+ // 4_4_4_4/4_4_4_4_REV & 5_5_5_1/1_5_5_5_REV & 8_8_8_8/8_8_8_8_REV &
+ // 10_10_10_2/2_10_10_10_REV are only campatible with RGBA, BGRA & ARGB_EXT
+ if( ( type == GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4 ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1 ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV ||
+ type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8 ||
+ type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV ||
+ type == GL2GL3.GL_UNSIGNED_INT_10_10_10_2 ||
+ type == GL2GL3.GL_UNSIGNED_INT_2_10_10_10_REV ) &&
+ (format != GL2GL3.GL_RGBA && format != GL2GL3.GL_BGRA) ) {
+ return( false );
+ }
+ return( true );
+ }
+
+ public static boolean isLegalLevels( int userLevel, int baseLevel, int maxLevel,
+ int totalLevels ) {
+ if( (baseLevel < 0) || (baseLevel < userLevel) || (maxLevel < baseLevel) ||
+ (totalLevels < maxLevel) ) {
+ return( false );
+ }
+ return( true );
+ }
+
+ /* Given user requested textures size, determine if it fits. If it doesn't then
+ * halve both sides and make the determination again until it does fit ( for
+ * IR only ).
+ * Note that proxy textures are not implemented in RE* even though they
+ * advertise the texture extension.
+ * Note that proxy textures are implemented but not according to spec in IMPACT*
+ */
+ public static void closestFit( GL gl, int target, int width, int height, int internalFormat,
+ int format, int type, int[] newWidth, int[] newHeight ) {
+ // Use proxy textures if OpenGL version >= 1.1
+ if( Double.parseDouble( gl.glGetString( GL.GL_VERSION ).trim().substring( 0, 3 ) ) >= 1.1 ) {
+ int widthPowerOf2 = nearestPower( width );
+ int heightPowerOf2 = nearestPower( height );
+ int[] proxyWidth = new int[1];
+ boolean noProxyTextures = false;
+
+ // Some drivers (in particular, ATI's) seem to set a GL error
+ // when proxy textures are used even though this is in violation
+ // of the spec. Guard against this and interactions with the
+ // DebugGL by watching for GLException.
+ try {
+ do {
+ // compute level 1 width & height, clamping each at 1
+ int widthAtLevelOne = ( ( width > 1 ) ? (widthPowerOf2 >> 1) : widthPowerOf2 );
+ int heightAtLevelOne = ( ( height > 1 ) ? (heightPowerOf2 >> 1) : heightPowerOf2 );
+ int proxyTarget;
+
+ assert( widthAtLevelOne > 0 );
+ assert( heightAtLevelOne > 0 );
+
+ // does width x height at level 1 & all their mipmaps fit?
+ if( target == GL2GL3.GL_TEXTURE_2D || target == GL2GL3.GL_PROXY_TEXTURE_2D ) {
+ proxyTarget = GL2GL3.GL_PROXY_TEXTURE_2D;
+ gl.glTexImage2D( proxyTarget, 1, internalFormat, widthAtLevelOne,
+ heightAtLevelOne, 0, format, type, null );
+ } else if( (target == GL2GL3.GL_TEXTURE_CUBE_MAP_POSITIVE_X) ||
+ (target == GL2GL3.GL_TEXTURE_CUBE_MAP_NEGATIVE_X) ||
+ (target == GL2GL3.GL_TEXTURE_CUBE_MAP_POSITIVE_Y) ||
+ (target == GL2GL3.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ||
+ (target == GL2GL3.GL_TEXTURE_CUBE_MAP_POSITIVE_Z) ||
+ (target == GL2GL3.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) ) {
+ proxyTarget = GL2GL3.GL_PROXY_TEXTURE_CUBE_MAP;
+ gl.glTexImage2D( proxyTarget, 1, internalFormat, widthAtLevelOne,
+ heightAtLevelOne, 0, format, type, null );
+ } else {
+ assert( target == GL2GL3.GL_TEXTURE_1D || target == GL2GL3.GL_PROXY_TEXTURE_1D );
+ proxyTarget = GL2GL3.GL_PROXY_TEXTURE_1D;
+ gl.getGL2GL3().glTexImage1D( proxyTarget, 1, internalFormat, widthAtLevelOne,
+ 0, format, type, null );
+ }
+ if(gl.isGL2GL3()) {
+ gl.getGL2GL3().glGetTexLevelParameteriv( proxyTarget, 1, GL2GL3.GL_TEXTURE_WIDTH, proxyWidth, 0 );
+ } else {
+ proxyWidth[0] = 0;
+ }
+ // does it fit?
+ if( proxyWidth[0] == 0 ) { // nope, so try again with theses sizes
+ if( widthPowerOf2 == 1 && heightPowerOf2 == 1 ) {
+ /* A 1x1 texture couldn't fit for some reason so break out. This
+ * should never happen. But things happen. The disadvantage with
+ * this if-statement is that we will never be aware of when this
+ * happens since it will silently branch out.
+ */
+ noProxyTextures = true;
+ break;
+ }
+ widthPowerOf2 = widthAtLevelOne;
+ heightPowerOf2 = heightAtLevelOne;
+ }
+ // else it does fit
+ } while( proxyWidth[0] == 0 );
+ } catch (GLException e) {
+ noProxyTextures = true;
+ }
+ // loop must terminate
+ // return the width & height at level 0 that fits
+ if( !noProxyTextures ) {
+ newWidth[0] = widthPowerOf2;
+ newHeight[0] = heightPowerOf2;
+ return;
+ }
+ }
+ int[] maxsize = new int[1];
+ gl.glGetIntegerv( GL2GL3.GL_MAX_TEXTURE_SIZE, maxsize , 0);
+ // clamp user's texture sizes to maximum sizes, if necessary
+ newWidth[0] = nearestPower( width );
+ if( newWidth[0] > maxsize[0] ) {
+ newWidth[0] = maxsize[0];
+ }
+ newHeight[0] = nearestPower( height );
+ if( newHeight[0] > maxsize[0] ) {
+ newHeight[0] = maxsize[0];
+ }
+ }
+
+ public static void closestFit3D( GL gl, int target, int width, int height, int depth,
+ int internalFormat, int format, int type, int[] newWidth, int[] newHeight,
+ int[] newDepth ) {
+ int widthPowerOf2 = nearestPower( width );
+ int heightPowerOf2 = nearestPower( height );
+ int depthPowerOf2 = nearestPower( depth );
+ int[] proxyWidth = new int[1];
+
+ do {
+ // compute level 1 width & height & depth, clamping each at 1
+ int widthAtLevelOne = (widthPowerOf2 > 1) ? widthPowerOf2 >> 1 : widthPowerOf2;
+ int heightAtLevelOne = (heightPowerOf2 > 1) ? heightPowerOf2 >> 1 : heightPowerOf2;
+ int depthAtLevelOne = (depthPowerOf2 > 1) ? depthPowerOf2 >> 1 : depthPowerOf2;
+ int proxyTarget = 0;
+ assert( widthAtLevelOne > 0 );
+ assert( heightAtLevelOne > 0 );
+ assert( depthAtLevelOne > 0 );
+
+ // does width x height x depth at level 1 & all their mipmaps fit?
+ if( target == GL2GL3.GL_TEXTURE_3D || target == GL2GL3.GL_PROXY_TEXTURE_3D ) {
+ proxyTarget = GL2GL3.GL_PROXY_TEXTURE_3D;
+ gl.getGL2GL3().glTexImage3D( proxyTarget, 1, internalFormat, widthAtLevelOne,
+ heightAtLevelOne, depthAtLevelOne, 0, format, type, null );
+ }
+ if(gl.isGL2GL3()) {
+ gl.getGL2GL3().glGetTexLevelParameteriv( proxyTarget, 1, GL2GL3.GL_TEXTURE_WIDTH, proxyWidth, 0 );
+ } else {
+ proxyWidth[0] = 0;
+ }
+ // does it fit
+ if( proxyWidth[0] == 0 ) {
+ if( widthPowerOf2 == 1 && heightPowerOf2 == 1 && depthPowerOf2 == 1 ) {
+ newWidth[0] = newHeight[0] = newDepth[0] = 1;
+ return;
+ }
+ widthPowerOf2 = widthAtLevelOne;
+ heightPowerOf2 = heightAtLevelOne;
+ depthPowerOf2 = depthAtLevelOne;
+ }
+ } while( proxyWidth[0] == 0 );
+ // loop must terminate
+
+ // return the width & height at level 0 that fits
+ newWidth[0] = widthPowerOf2;
+ newHeight[0] = heightPowerOf2;
+ newDepth[0] = depthPowerOf2;
+ }
+
+ public static int elements_per_group( int format, int type ) {
+ // Return the number of elements per grtoup of a specified gromat
+
+ // If the type is packedpixels then answer is 1
+ if( type == GL2GL3.GL_UNSIGNED_BYTE_3_3_2 ||
+ type == GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_5_6_5 ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4 ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1 ||
+ type == GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV ||
+ type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8 ||
+ type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV ||
+ type == GL2GL3.GL_UNSIGNED_INT_10_10_10_2 ||
+ type == GL2GL3.GL_UNSIGNED_INT_2_10_10_10_REV ) {
+ return( 1 );
+ }
+
+ // Types are not packed pixels so get elements per group
+ switch( format ) {
+ case( GL2GL3.GL_RGB ):
+ case( GL2GL3.GL_BGR ):
+ return( 3 );
+ case( GL2GL3.GL_LUMINANCE_ALPHA ):
+ return( 2 );
+ case( GL2GL3.GL_RGBA ):
+ case( GL2GL3.GL_BGRA ):
+ return( 4 );
+ default:
+ return( 1 );
+ }
+ }
+
+ public static int bytes_per_element( int type ) {
+ // return the number of bytes per element, based on the element type
+
+ switch( type ) {
+ case( GL2.GL_BITMAP ):
+ case( GL2GL3.GL_BYTE ):
+ case( GL2GL3.GL_UNSIGNED_BYTE ):
+ case( GL2GL3.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ return( 1 );
+ case( GL2GL3.GL_SHORT ):
+ case( GL2GL3.GL_UNSIGNED_SHORT ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ return( 2 );
+ case( GL2GL3.GL_INT ):
+ case( GL2GL3.GL_UNSIGNED_INT ):
+ case( GL2GL3.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2GL3.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2GL3.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ case( GL2GL3.GL_FLOAT ):
+ return( 4 );
+ default:
+ return( 4 );
+ }
+ }
+
+ public static boolean is_index( int format ) {
+ return( format == GL2.GL_COLOR_INDEX || format == GL2GL3.GL_STENCIL_INDEX );
+ }
+
+ /* Compute memory required for internal packed array of data of given type and format. */
+
+ public static int image_size( int width, int height, int format, int type ) {
+ int bytes_per_row;
+ int components;
+
+ assert( width > 0 );
+ assert( height > 0 );
+ components = elements_per_group( format, type );
+ if( type == GL2.GL_BITMAP ) {
+ bytes_per_row = (width + 7) / 8;
+ } else {
+ bytes_per_row = bytes_per_element( type ) * width;
+ }
+ return( bytes_per_row * height * components );
+ }
+
+ public static int imageSize3D( int width, int height, int depth, int format, int type ) {
+ int components = elements_per_group( format, type );
+ int bytes_per_row = bytes_per_element( type ) * width;
+
+ assert( width > 0 && height > 0 && depth > 0 );
+ assert( type != GL2.GL_BITMAP );
+
+ return( bytes_per_row * height * depth * components );
+ }
+
+ public static void retrieveStoreModes( GL gl, PixelStorageModes psm ) {
+ int[] a = new int[1];
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_ALIGNMENT, a, 0);
+ psm.setUnpackAlignment( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_ROW_LENGTH, a, 0);
+ psm.setUnpackRowLength( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_SKIP_ROWS, a, 0);
+ psm.setUnpackSkipRows( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_SKIP_PIXELS, a, 0);
+ psm.setUnpackSkipPixels( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_LSB_FIRST, a, 0);
+ psm.setUnpackLsbFirst( ( a[0] == 1 ) );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_SWAP_BYTES, a, 0);
+ psm.setUnpackSwapBytes( ( a[0] == 1 ) );
+
+ gl.glGetIntegerv( GL2GL3.GL_PACK_ALIGNMENT, a, 0);
+ psm.setPackAlignment( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_ROW_LENGTH, a, 0);
+ psm.setPackRowLength( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_SKIP_ROWS, a, 0);
+ psm.setPackSkipRows( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_SKIP_PIXELS, a, 0);
+ psm.setPackSkipPixels( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_LSB_FIRST, a, 0);
+ psm.setPackLsbFirst( ( a[0] == 1 ) );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_SWAP_BYTES, a, 0);
+ psm.setPackSwapBytes( ( a[0] == 1 ) );
+ }
+
+ public static void retrieveStoreModes3D( GL gl, PixelStorageModes psm ) {
+ int[] a = new int[1];
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_ALIGNMENT, a, 0);
+ psm.setUnpackAlignment( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_ROW_LENGTH, a, 0);
+ psm.setUnpackRowLength( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_SKIP_ROWS, a, 0);
+ psm.setUnpackSkipRows( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_SKIP_PIXELS, a, 0);
+ psm.setUnpackSkipPixels( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_LSB_FIRST, a, 0);
+ psm.setUnpackLsbFirst( ( a[0] == 1 ) );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_SWAP_BYTES, a, 0);
+ psm.setUnpackSwapBytes( ( a[0] == 1 ) );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_SKIP_IMAGES, a, 0);
+ psm.setUnpackSkipImages( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_UNPACK_IMAGE_HEIGHT, a, 0);
+ psm.setUnpackImageHeight( a[0] );
+
+ gl.glGetIntegerv( GL2GL3.GL_PACK_ALIGNMENT, a, 0);
+ psm.setPackAlignment( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_ROW_LENGTH, a, 0);
+ psm.setPackRowLength( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_SKIP_ROWS, a, 0);
+ psm.setPackSkipRows( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_SKIP_PIXELS, a, 0 );
+ psm.setPackSkipPixels( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_LSB_FIRST, a, 0 );
+ psm.setPackLsbFirst( ( a[0] == 1 ) );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_SWAP_BYTES, a, 0 );
+ psm.setPackSwapBytes( ( a[0] == 1 ) );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_SKIP_IMAGES, a, 0 );
+ psm.setPackSkipImages( a[0] );
+ gl.glGetIntegerv( GL2GL3.GL_PACK_IMAGE_HEIGHT, a, 0 );
+ psm.setPackImageHeight( a[0] );
+ }
+
+ public static int gluScaleImage( GL gl, int format, int widthin, int heightin,
+ int typein, ByteBuffer datain, int widthout, int heightout,
+ int typeout, ByteBuffer dataout ) {
+ int datainPos = datain.position();
+ int dataoutPos = dataout.position();
+ try {
+
+ int components;
+ ByteBuffer beforeimage;
+ ByteBuffer afterimage;
+ PixelStorageModes psm = new PixelStorageModes();
+
+ if( (widthin == 0) || (heightin == 0) || (widthout == 0) || (heightout == 0) ) {
+ return( 0 );
+ }
+ if( (widthin < 0) || (heightin < 0) || (widthout < 0) || (heightout < 0) ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+ if( !legalFormat( format ) || !legalType( typein ) || !legalType( typeout ) ) {
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ if( !isLegalFormatForPackedPixelType( format, typein ) ) {
+ return( GLU.GLU_INVALID_OPERATION );
+ }
+ if( !isLegalFormatForPackedPixelType( format, typeout ) ) {
+ return( GLU.GLU_INVALID_OPERATION );
+ }
+ beforeimage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( image_size( widthin, heightin, format, GL2GL3.GL_UNSIGNED_SHORT ) ));
+ afterimage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( image_size( widthout, heightout, format, GL2GL3.GL_UNSIGNED_SHORT ) ));
+ if( beforeimage == null || afterimage == null ) {
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+
+ retrieveStoreModes( gl, psm );
+ Image.fill_image( psm, widthin, heightin, format, typein, is_index( format ), datain, beforeimage.asShortBuffer() );
+ components = elements_per_group( format, 0 );
+ ScaleInternal.scale_internal( components, widthin, heightin, beforeimage.asShortBuffer(), widthout, heightout, afterimage.asShortBuffer() );
+ Image.empty_image( psm, widthout, heightout, format, typeout, is_index( format ), afterimage.asShortBuffer(), dataout );
+
+ return( 0 );
+ } finally {
+ datain.position(datainPos);
+ dataout.position(dataoutPos);
+ }
+ }
+
+ public static int gluBuild1DMipmapLevels( GL gl, int target, int internalFormat,
+ int width, int format, int type, int userLevel, int baseLevel,
+ int maxLevel, ByteBuffer data ) {
+ int dataPos = data.position();
+ try {
+
+ int levels;
+
+ int rc = checkMipmapArgs( internalFormat, format, type );
+ if( rc != 0 ) {
+ return( rc );
+ }
+
+ if( width < 1 ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+
+ levels = computeLog( width );
+
+ levels += userLevel;
+ if( !isLegalLevels( userLevel, baseLevel, maxLevel, levels ) ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+
+ return( BuildMipmap.gluBuild1DMipmapLevelsCore( gl, target, internalFormat, width,
+ width, format, type, userLevel, baseLevel, maxLevel, data ) );
+ } finally {
+ data.position(dataPos);
+ }
+ }
+
+ public static int gluBuild1DMipmaps( GL gl, int target, int internalFormat, int width,
+ int format, int type, ByteBuffer data ) {
+ int dataPos = data.position();
+
+ try {
+ int[] widthPowerOf2 = new int[1];
+ int levels;
+ int[] dummy = new int[1];
+
+ int rc = checkMipmapArgs( internalFormat, format, type );
+ if( rc != 0 ) {
+ return( rc );
+ }
+
+ if( width < 1 ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+
+ closestFit( gl, target, width, 1, internalFormat, format, type, widthPowerOf2, dummy );
+ levels = computeLog( widthPowerOf2[0] );
+
+ return( BuildMipmap.gluBuild1DMipmapLevelsCore( gl, target, internalFormat,
+ width, widthPowerOf2[0], format, type, 0, 0, levels, data ) );
+ } finally {
+ data.position(dataPos);
+ }
+ }
+
+
+ public static int gluBuild2DMipmapLevels( GL gl, int target, int internalFormat,
+ int width, int height, int format, int type, int userLevel,
+ int baseLevel, int maxLevel, Object data ) {
+ int dataPos = 0;
+
+ int level, levels;
+
+ int rc = checkMipmapArgs( internalFormat, format, type );
+ if( rc != 0 ) {
+ return( rc );
+ }
+
+ if( width < 1 || height < 1 ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+
+ levels = computeLog( width );
+ level = computeLog( height );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ levels += userLevel;
+ if( !isLegalLevels( userLevel, baseLevel, maxLevel, levels ) ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+
+ //PointerWrapper pointer = PointerWrapperFactory.getPointerWrapper( data );
+ ByteBuffer buffer = null;
+ if( data instanceof ByteBuffer ) {
+ buffer = (ByteBuffer)data;
+ dataPos = buffer.position();
+ } else if( data instanceof byte[] ) {
+ byte[] array = (byte[])data;
+ buffer = ByteBuffer.allocateDirect(array.length);
+ buffer.put(array);
+ } else if( data instanceof short[] ) {
+ short[] array = (short[])data;
+ buffer = ByteBuffer.allocateDirect( array.length * 2 );
+ ShortBuffer sb = buffer.asShortBuffer();
+ sb.put( array );
+ } else if( data instanceof int[] ) {
+ int[] array = (int[])data;
+ buffer = ByteBuffer.allocateDirect( array.length * 4 );
+ IntBuffer ib = buffer.asIntBuffer();
+ ib.put( array );
+ } else if( data instanceof float[] ) {
+ float[] array = (float[])data;
+ buffer = ByteBuffer.allocateDirect( array.length * 4 );
+ FloatBuffer fb = buffer.asFloatBuffer();
+ fb.put( array );
+ }
+
+ try {
+ return( BuildMipmap.gluBuild2DMipmapLevelsCore( gl, target, internalFormat,
+ width, height, width, height, format, type, userLevel, baseLevel,
+ maxLevel, buffer ) );
+ } finally {
+ buffer.position(dataPos);
+ }
+ }
+
+
+ public static int gluBuild2DMipmaps( GL gl, int target, int internalFormat,
+ int width, int height, int format, int type, Object data ) {
+ int dataPos = 0;
+
+ int[] widthPowerOf2 = new int[1];
+ int[] heightPowerOf2 = new int[1];
+ int level, levels;
+
+ int rc = checkMipmapArgs( internalFormat, format, type );
+ if( rc != 0 ) {
+ return( rc );
+ }
+
+ if( width < 1 || height < 1 ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+
+ closestFit( gl, target, width, height, internalFormat, format, type,
+ widthPowerOf2, heightPowerOf2 );
+
+ levels = computeLog( widthPowerOf2[0] );
+ level = computeLog( heightPowerOf2[0] );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ //PointerWrapper pointer = PointerWrapperFactory.getPointerWrapper( data );
+ ByteBuffer buffer = null;
+ if( data instanceof ByteBuffer ) {
+ buffer = (ByteBuffer)data;
+ dataPos = buffer.position();
+ } else if( data instanceof byte[] ) {
+ byte[] array = (byte[])data;
+ buffer = ByteBuffer.allocateDirect(array.length);
+ buffer.put(array);
+ } else if( data instanceof short[] ) {
+ short[] array = (short[])data;
+ buffer = ByteBuffer.allocateDirect( array.length * 2 );
+ ShortBuffer sb = buffer.asShortBuffer();
+ sb.put( array );
+ } else if( data instanceof int[] ) {
+ int[] array = (int[])data;
+ buffer = ByteBuffer.allocateDirect( array.length * 4 );
+ IntBuffer ib = buffer.asIntBuffer();
+ ib.put( array );
+ } else if( data instanceof float[] ) {
+ float[] array = (float[])data;
+ buffer = ByteBuffer.allocateDirect( array.length * 4 );
+ FloatBuffer fb = buffer.asFloatBuffer();
+ fb.put( array );
+ }
+
+ try {
+ return( BuildMipmap.gluBuild2DMipmapLevelsCore( gl, target, internalFormat,
+ width, height, widthPowerOf2[0], heightPowerOf2[0], format, type, 0,
+ 0, levels, buffer ) );
+ } finally {
+ buffer.position(dataPos);
+ }
+ }
+
+
+ public static int gluBuild3DMipmaps( GL gl, int target, int internalFormat,
+ int width, int height, int depth, int format, int type, ByteBuffer data ) {
+ int dataPos = data.position();
+ try {
+
+ int[] widthPowerOf2 = new int[1];
+ int[] heightPowerOf2 = new int[1];
+ int[] depthPowerOf2 = new int[1];
+ int level, levels;
+
+ int rc = checkMipmapArgs( internalFormat, format, type );
+ if( rc != 0 ) {
+ return( rc );
+ }
+
+ if( width < 1 || height < 1 || depth < 1 ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+
+ if( type == GL2.GL_BITMAP ) {
+ return( GLU.GLU_INVALID_ENUM );
+ }
+
+ closestFit3D( gl, target, width, height, depth, internalFormat, format,
+ type, widthPowerOf2, heightPowerOf2, depthPowerOf2 );
+
+ levels = computeLog( widthPowerOf2[0] );
+ level = computeLog( heightPowerOf2[0] );
+ if( level > levels ) {
+ levels = level;
+ }
+ level = computeLog( depthPowerOf2[0] );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ return( BuildMipmap.gluBuild3DMipmapLevelsCore( gl, target, internalFormat, width,
+ height, depth, widthPowerOf2[0], heightPowerOf2[0], depthPowerOf2[0],
+ format, type, 0, 0, levels, data ) );
+ } finally {
+ data.position(dataPos);
+ }
+ }
+
+ public static int gluBuild3DMipmapLevels( GL gl, int target, int internalFormat,
+ int width, int height, int depth, int format, int type, int userLevel,
+ int baseLevel, int maxLevel, ByteBuffer data ) {
+ int dataPos = data.position();
+ try {
+ int level, levels;
+
+ int rc = checkMipmapArgs( internalFormat, format, type );
+ if( rc != 0 ) {
+ return( rc );
+ }
+
+ if( width < 1 || height < 1 || depth < 1 ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+
+ if( type == GL2.GL_BITMAP ) {
+ return( GLU.GLU_INVALID_ENUM );
+ }
+
+ levels = computeLog( width );
+ level = computeLog( height );
+ if( level > levels ) {
+ levels = level;
+ }
+ level = computeLog( depth );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ levels += userLevel;
+ if( !isLegalLevels( userLevel, baseLevel, maxLevel, levels ) ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+
+ return( BuildMipmap.gluBuild3DMipmapLevelsCore( gl, target, internalFormat, width,
+ height, depth, width, height, depth, format, type, userLevel,
+ baseLevel, maxLevel, data ) );
+ } finally {
+ data.position(dataPos);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/PixelStorageModes.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/PixelStorageModes.java
new file mode 100644
index 000000000..43b5c5691
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/PixelStorageModes.java
@@ -0,0 +1,426 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+/**
+ *
+ * @author Administrator
+ */
+public class PixelStorageModes {
+
+ /**
+ * Holds value of property packAlignment.
+ */
+ private int packAlignment;
+
+ /**
+ * Holds value of property packRowLength.
+ */
+ private int packRowLength;
+
+ /**
+ * Holds value of property packSkipRows.
+ */
+ private int packSkipRows;
+
+ /**
+ * Holds value of property packSkipPixels.
+ */
+ private int packSkipPixels;
+
+ /**
+ * Holds value of property packLsbFirst.
+ */
+ private boolean packLsbFirst;
+
+ /**
+ * Holds value of property packSwapBytes.
+ */
+ private boolean packSwapBytes;
+
+ /**
+ * Holds value of property packSkipImages.
+ */
+ private int packSkipImages;
+
+ /**
+ * Holds value of property packImageHeight.
+ */
+ private int packImageHeight;
+
+ /**
+ * Holds value of property unpackAlignment.
+ */
+ private int unpackAlignment;
+
+ /**
+ * Holds value of property unpackRowLength.
+ */
+ private int unpackRowLength;
+
+ /**
+ * Holds value of property unpackSkipRows.
+ */
+ private int unpackSkipRows;
+
+ /**
+ * Holds value of property unpackSkipPixels.
+ */
+ private int unpackSkipPixels;
+
+ /**
+ * Holds value of property unpackLsbFirst.
+ */
+ private boolean unpackLsbFirst;
+
+ /**
+ * Holds value of property unpackSwapBytes.
+ */
+ private boolean unpackSwapBytes;
+
+ /**
+ * Holds value of property unpackSkipImages.
+ */
+ private int unpackSkipImages;
+
+ /**
+ * Holds value of property unpackImageHeight.
+ */
+ private int unpackImageHeight;
+
+ /** Creates a new instance of PixelStorageModes */
+ public PixelStorageModes() {
+ }
+
+ /**
+ * Getter for property packAlignment.
+ * @return Value of property packAlignment.
+ */
+ public int getPackAlignment() {
+
+ return this.packAlignment;
+ }
+
+ /**
+ * Setter for property packAlignment.
+ * @param packAlignment New value of property packAlignment.
+ */
+ public void setPackAlignment(int packAlignment) {
+
+ this.packAlignment = packAlignment;
+ }
+
+ /**
+ * Getter for property packRowLength.
+ * @return Value of property packRowLength.
+ */
+ public int getPackRowLength() {
+
+ return this.packRowLength;
+ }
+
+ /**
+ * Setter for property packRowLength.
+ * @param packRowLength New value of property packRowLength.
+ */
+ public void setPackRowLength(int packRowLength) {
+
+ this.packRowLength = packRowLength;
+ }
+
+ /**
+ * Getter for property packSkipRows.
+ * @return Value of property packSkipRows.
+ */
+ public int getPackSkipRows() {
+
+ return this.packSkipRows;
+ }
+
+ /**
+ * Setter for property packSkipRows.
+ * @param packSkipRows New value of property packSkipRows.
+ */
+ public void setPackSkipRows(int packSkipRows) {
+
+ this.packSkipRows = packSkipRows;
+ }
+
+ /**
+ * Getter for property packSkipPixels.
+ * @return Value of property packSkipPixels.
+ */
+ public int getPackSkipPixels() {
+
+ return this.packSkipPixels;
+ }
+
+ /**
+ * Setter for property packSkipPixels.
+ * @param packSkipPixels New value of property packSkipPixels.
+ */
+ public void setPackSkipPixels(int packSkipPixels) {
+
+ this.packSkipPixels = packSkipPixels;
+ }
+
+ /**
+ * Getter for property packLsbFirst.
+ * @return Value of property packLsbFirst.
+ */
+ public boolean getPackLsbFirst() {
+
+ return this.packLsbFirst;
+ }
+
+ /**
+ * Setter for property packLsbFirst.
+ * @param packLsbFirst New value of property packLsbFirst.
+ */
+ public void setPackLsbFirst(boolean packLsbFirst) {
+
+ this.packLsbFirst = packLsbFirst;
+ }
+
+ /**
+ * Getter for property packSwapBytes.
+ * @return Value of property packSwapBytes.
+ */
+ public boolean getPackSwapBytes() {
+
+ return this.packSwapBytes;
+ }
+
+ /**
+ * Setter for property packSwapBytes.
+ * @param packSwapBytes New value of property packSwapBytes.
+ */
+ public void setPackSwapBytes(boolean packSwapBytes) {
+
+ this.packSwapBytes = packSwapBytes;
+ }
+
+ /**
+ * Getter for property packSkipImages.
+ * @return Value of property packSkipImages.
+ */
+ public int getPackSkipImages() {
+
+ return this.packSkipImages;
+ }
+
+ /**
+ * Setter for property packSkipImages.
+ * @param packSkipImages New value of property packSkipImages.
+ */
+ public void setPackSkipImages(int packSkipImages) {
+
+ this.packSkipImages = packSkipImages;
+ }
+
+ /**
+ * Getter for property packImageHeight.
+ * @return Value of property packImageHeight.
+ */
+ public int getPackImageHeight() {
+
+ return this.packImageHeight;
+ }
+
+ /**
+ * Setter for property packImageHeight.
+ * @param packImageHeight New value of property packImageHeight.
+ */
+ public void setPackImageHeight(int packImageHeight) {
+
+ this.packImageHeight = packImageHeight;
+ }
+
+ /**
+ * Getter for property unpackAlignment.
+ * @return Value of property unpackAlignment.
+ */
+ public int getUnpackAlignment() {
+
+ return this.unpackAlignment;
+ }
+
+ /**
+ * Setter for property unpackAlignment.
+ * @param unpackAlignment New value of property unpackAlignment.
+ */
+ public void setUnpackAlignment(int unpackAlignment) {
+
+ this.unpackAlignment = unpackAlignment;
+ }
+
+ /**
+ * Getter for property unpackRowLength.
+ * @return Value of property unpackRowLength.
+ */
+ public int getUnpackRowLength() {
+
+ return this.unpackRowLength;
+ }
+
+ /**
+ * Setter for property unpackRowLength.
+ * @param unpackRowLength New value of property unpackRowLength.
+ */
+ public void setUnpackRowLength(int unpackRowLength) {
+
+ this.unpackRowLength = unpackRowLength;
+ }
+
+ /**
+ * Getter for property unpackSkipRows.
+ * @return Value of property unpackSkipRows.
+ */
+ public int getUnpackSkipRows() {
+
+ return this.unpackSkipRows;
+ }
+
+ /**
+ * Setter for property unpackSkipRows.
+ * @param unpackSkipRows New value of property unpackSkipRows.
+ */
+ public void setUnpackSkipRows(int unpackSkipRows) {
+
+ this.unpackSkipRows = unpackSkipRows;
+ }
+
+ /**
+ * Getter for property unpackSkipPixels.
+ * @return Value of property unpackSkipPixels.
+ */
+ public int getUnpackSkipPixels() {
+
+ return this.unpackSkipPixels;
+ }
+
+ /**
+ * Setter for property unpackSkipPixels.
+ * @param unpackSkipPixels New value of property unpackSkipPixels.
+ */
+ public void setUnpackSkipPixels(int unpackSkipPixels) {
+
+ this.unpackSkipPixels = unpackSkipPixels;
+ }
+
+ /**
+ * Getter for property unpackLsbFirst.
+ * @return Value of property unpackLsbFirst.
+ */
+ public boolean getUnpackLsbFirst() {
+
+ return this.unpackLsbFirst;
+ }
+
+ /**
+ * Setter for property unpackLsbFirst.
+ * @param unpackLsbFirst New value of property unpackLsbFirst.
+ */
+ public void setUnpackLsbFirst(boolean unpackLsbFirst) {
+
+ this.unpackLsbFirst = unpackLsbFirst;
+ }
+
+ /**
+ * Getter for property unpackSwapBytes.
+ * @return Value of property unpackSwapBytes.
+ */
+ public boolean getUnpackSwapBytes() {
+
+ return this.unpackSwapBytes;
+ }
+
+ /**
+ * Setter for property unpackSwapBytes.
+ * @param unpackSwapBytes New value of property unpackSwapBytes.
+ */
+ public void setUnpackSwapBytes(boolean unpackSwapBytes) {
+
+ this.unpackSwapBytes = unpackSwapBytes;
+ }
+
+ /**
+ * Getter for property unpackSkipImages.
+ * @return Value of property unpackSkipImages.
+ */
+ public int getUnpackSkipImages() {
+
+ return this.unpackSkipImages;
+ }
+
+ /**
+ * Setter for property unpackSkipImages.
+ * @param unpackSkipImages New value of property unpackSkipImages.
+ */
+ public void setUnpackSkipImages(int unpackSkipImages) {
+
+ this.unpackSkipImages = unpackSkipImages;
+ }
+
+ /**
+ * Getter for property unpackImageHeight.
+ * @return Value of property unpackImageHeight.
+ */
+ public int getUnpackImageHeight() {
+
+ return this.unpackImageHeight;
+ }
+
+ /**
+ * Setter for property unpackImageHeight.
+ * @param unpackImageHeight New value of property unpackImageHeight.
+ */
+ public void setUnpackImageHeight(int unpackImageHeight) {
+
+ this.unpackImageHeight = unpackImageHeight;
+ }
+
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ScaleInternal.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ScaleInternal.java
new file mode 100644
index 000000000..f0bb7fb33
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ScaleInternal.java
@@ -0,0 +1,2447 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.glu.GLU;
+import java.nio.*;
+import com.jogamp.opengl.impl.InternalBufferUtil;
+
+/**
+ *
+ * @author Administrator
+ */
+public class ScaleInternal {
+
+ public static final float UINT_MAX = (float)(0x00000000FFFFFFFF);
+
+ public static void scale_internal( int components, int widthin, int heightin,
+ ShortBuffer datain, int widthout, int heightout, ShortBuffer dataout ) {
+ float x, lowx, highx, convx, halfconvx;
+ float y, lowy, highy, convy, halfconvy;
+ float xpercent, ypercent;
+ float percent;
+ // Max components in a format is 4, so...
+ float[] totals = new float[4];
+ float area;
+ int i, j, k, yint, xint, xindex, yindex;
+ int temp;
+
+ if( (widthin == (widthout * 2)) && (heightin == (heightout * 2)) ) {
+ HalveImage.halveImage( components, widthin, heightin, datain, dataout );
+ return;
+ }
+ convy = (float)heightin / heightout;
+ convx = (float)widthin / widthout;
+ halfconvx = convx / 2;
+ halfconvy = convy / 2;
+ for( i = 0; i < heightout; i++ ) {
+ y = convy * ( i + 0.5f );
+ if( heightin > heightout ) {
+ highy = y + halfconvy;
+ lowy = y - halfconvy;
+ } else {
+ highy = y + 0.5f;
+ lowy = y - 0.5f;
+ }
+ for( j = 0; j < widthout; j++ ) {
+ x = convx * ( j + 0.5f );
+ if( widthin > widthout ) {
+ highx = x + halfconvx;
+ lowx = x - halfconvx;
+ } else {
+ highx = x + 0.5f;
+ lowx = x - 0.5f;
+ }
+ // Ok, now apply box filter to box that goes from (lowx, lowy)
+ // to (highx, highy) on input data into this pixel on output
+ // data.
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0f;
+ area = 0.0f;
+
+ y = lowy;
+ yint = (int)Math.floor( y );
+ while( y < highy ) {
+ yindex = ( yint + heightin ) % heightin;
+ if( highy < yint + 1 ) {
+ ypercent = highy - y;
+ } else {
+ ypercent = yint + 1 - y;
+ }
+
+ x = lowx;
+ xint = (int)Math.floor( x );
+
+ while( x < highx ) {
+ xindex = ( xint + widthin ) % widthin;
+ if( highx < xint + 1 ) {
+ xpercent = highx -x;
+ } else {
+ xpercent = xint + 1 - x;
+ }
+
+ percent = xpercent * ypercent;
+ area += percent;
+ temp = ( xindex + ( yindex * widthin) ) * components;
+ for( k = 0; k < components; k++ ) {
+ totals[k] += datain.get( temp + k ) * percent;
+ }
+
+ xint++;
+ x = xint;
+ }
+ yint++;
+ y = yint;
+ }
+
+ temp = ( j + ( i * widthout ) ) * components;
+ for( k = 0; k < components; k++ ) {
+ // totals[] should be rounded in the case of enlarging an RGB
+ // ramp when the type is 332 or 4444
+ dataout.put( temp + k, (short)((totals[k] + 0.5f) / area) );
+ }
+ }
+ }
+ }
+
+ public static void scale_internal_ubyte( int components, int widthin, int heightin,
+ ByteBuffer datain, int widthout, int heightout,
+ ByteBuffer dataout, int element_size, int ysize, int group_size ) {
+ float x, convx;
+ float y, convy;
+ float percent;
+ // Max components in a format is 4, so...
+ float[] totals = new float[4];
+ float area;
+ int i, j, k, xindex;
+
+ int temp, temp0;
+ int temp_index;
+ int outindex;
+
+ int lowx_int, highx_int, lowy_int, highy_int;
+ float x_percent, y_percent;
+ float lowx_float, highx_float, lowy_float, highy_float;
+ float convy_float, convx_float;
+ int convy_int, convx_int;
+ int l, m;
+ int left, right;
+
+ if( (widthin == (widthout * 2)) && (heightin == (heightout * 2)) ) {
+ HalveImage.halveImage_ubyte( components, widthin, heightin, datain, dataout,
+ element_size, ysize, group_size );
+ return;
+ }
+ convy = (float)heightin / heightout;
+ convx = (float)widthin / widthout;
+ convy_int = (int)Math.floor( convy );
+ convy_float = convy - convy_int;
+ convx_int = (int)Math.floor( convx );
+ convx_float = convx - convx_int;
+
+ area = convx * convy;
+
+ lowy_int = 0;
+ lowy_float = 0.0f;
+ highy_int = convy_int;
+ highy_float = convy_float;
+
+ for( i = 0; i < heightout; i++ ) {
+ // Clamp here to be sure we don't read beyond input buffer.
+ if (highy_int >= heightin)
+ highy_int = heightin - 1;
+ lowx_int = 0;
+ lowx_float = 0.0f;
+ highx_int = convx_int;
+ highx_float = convx_float;
+
+ for( j = 0; j < widthout; j++ ) {
+
+ // Ok, now apply box filter to box that goes from (lowx, lowy)
+ // to (highx, highy) on input data into this pixel on output
+ // data.
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0f;
+
+ // caulate the value for pixels in the 1st row
+ xindex = lowx_int * group_size;
+
+ if( ( highy_int > lowy_int ) && ( highx_int > lowx_int ) ) {
+
+ y_percent = 1 - lowy_float;
+ temp = xindex + lowy_int * ysize;
+ percent = y_percent * ( 1 - lowx_float );
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * percent;
+ }
+ left = temp;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * y_percent;
+ }
+ }
+ temp += group_size;
+ right = temp;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * percent;
+ }
+
+ // calculate the value for pixels in the last row
+ y_percent = highy_float;
+ percent = y_percent * ( 1 - lowx_float );
+ temp = xindex + highy_int * ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * percent;
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * y_percent;
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * percent;
+ }
+
+ // calculate the value for the pixels in the 1st and last column
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ left += ysize;
+ right += ysize;
+ for( k = 0; k < components; k++, left += element_size, right += element_size ) {
+ float f = 0.0f;
+ datain.position( left );
+ f = ( 0x000000FF & datain.get() ) * ( 1.0f - lowx_float );
+ datain.position( right );
+ f += ( 0x000000FF & datain.get() ) * highx_float;
+ totals[k] += f;
+ }
+ }
+ } else if( highy_int > lowy_int ) {
+ x_percent = highx_float - lowx_float;
+ percent = ( 1 - lowy_float) * x_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * percent;
+ }
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * x_percent;
+ }
+ }
+ percent = x_percent * highy_float;
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * percent;
+ }
+ } else if( highx_int > lowx_int ) {
+ y_percent = highy_float - lowy_float;
+ percent = ( 1 - lowx_float ) * y_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * percent;
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * y_percent;
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * percent;
+ }
+ } else {
+ percent = ( highy_float - lowy_float ) * ( highx_float - lowx_float );
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() ) * percent;
+ }
+ }
+
+ // this is for the pixels in the body
+ temp0 = xindex + group_size + ( lowy_int + 1 ) * ysize;
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp = temp0;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += ( 0x000000FF & datain.get() );
+ }
+ temp += group_size;
+ }
+ temp0 += ysize;
+ }
+
+ outindex = ( j + ( i * widthout ) ) * components;
+ for( k = 0; k < components; k++ ) {
+ dataout.position( outindex + k );
+ dataout.put( (byte)(totals[k] / area) );
+ }
+ lowx_int = highx_int;
+ lowx_float = highx_float;
+ highx_int += convx_int;
+ highx_float += convx_float;
+ if( highx_float > 1.0f ) {
+ highx_float -= 1.0f;
+ highx_int++;
+ }
+
+ // Clamp to make sure we don't run off the right edge
+ if (highx_int > widthin - 1) {
+ int delta = (highx_int - widthin + 1);
+ lowx_int -= delta;
+ highx_int -= delta;
+ }
+ }
+ lowy_int = highy_int;
+ lowy_float = highy_float;
+ highy_int += convy_int;
+ highy_float += convy_float;
+ if( highy_float > 1.0f ) {
+ highy_float -= 1.0f;
+ highy_int++;
+ }
+ }
+ }
+
+ public static void scale_internal_byte( int components, int widthin, int heightin,
+ ByteBuffer datain, int widthout, int heightout,
+ ByteBuffer dataout, int element_size, int ysize,
+ int group_size ) {
+ float x, convx;
+ float y, convy;
+ float percent;
+ // Max components in a format is 4, so...
+ float[] totals = new float[4];
+ float area;
+ int i, j, k, xindex;
+
+ int temp, temp0;
+ int temp_index;
+ int outindex;
+
+ int lowx_int, highx_int, lowy_int, highy_int;
+ float x_percent, y_percent;
+ float lowx_float, highx_float, lowy_float, highy_float;
+ float convy_float, convx_float;
+ int convy_int, convx_int;
+ int l, m;
+ int left, right;
+
+ if( (widthin == (widthout * 2)) && (heightin == (heightout * 2)) ) {
+ HalveImage.halveImage_byte( components, widthin, heightin, datain, dataout,
+ element_size, ysize, group_size );
+ return;
+ }
+ convy = (float)heightin / heightout;
+ convx = (float)widthin / widthout;
+ convy_int = (int)Math.floor( convy );
+ convy_float = convy - convy_int;
+ convx_int = (int)Math.floor( convx );
+ convx_float = convx - convx_int;
+
+ area = convx * convy;
+
+ lowy_int = 0;
+ lowy_float = 0.0f;
+ highy_int = convy_int;
+ highy_float = convy_float;
+
+ for( i = 0; i < heightout; i++ ) {
+ // Clamp here to be sure we don't read beyond input buffer.
+ if (highy_int >= heightin)
+ highy_int = heightin - 1;
+ lowx_int = 0;
+ lowx_float = 0.0f;
+ highx_int = convx_int;
+ highx_float = convx_float;
+
+ for( j = 0; j < widthout; j++ ) {
+
+ // Ok, now apply box filter to box that goes from (lowx, lowy)
+ // to (highx, highy) on input data into this pixel on output
+ // data.
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0f;
+
+ // caulate the value for pixels in the 1st row
+ xindex = lowx_int * group_size;
+ if( ( highy_int > lowy_int ) && ( highx_int > lowx_int ) ) {
+
+ y_percent = 1 - lowy_float;
+ temp = xindex + lowy_int * ysize;
+ percent = y_percent * ( 1 - lowx_float );
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * percent;
+ }
+ left = temp;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * y_percent;
+ }
+ }
+ temp += group_size;
+ right = temp;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * percent;
+ }
+
+ // calculate the value for pixels in the last row
+ y_percent = highy_float;
+ percent = y_percent * ( 1 - lowx_float );
+ temp = xindex + highy_int * ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * percent;
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * y_percent;
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * percent;
+ }
+
+ // calculate the value for the pixels in the 1st and last column
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ left += ysize;
+ right += ysize;
+ for( k = 0; k < components; k++, left += element_size, right += element_size ) {
+ float f = 0.0f;
+ datain.position( left );
+ f = datain.get() * ( 1 - lowx_float );
+ datain.position( right );
+ f += datain.get() * highx_float;
+ totals[k] += f;
+ }
+ }
+ } else if( highy_int > lowy_int ) {
+ x_percent = highx_float - lowx_float;
+ percent = ( 1 - lowy_float) * x_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * percent;
+ }
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * x_percent;
+ }
+ }
+ percent = x_percent * highy_float;
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * percent;
+ }
+ } else if( highx_int > lowx_int ) {
+ y_percent = highy_float - lowy_float;
+ percent = ( 1 - lowx_float ) * y_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * percent;
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * y_percent;
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * percent;
+ }
+ } else {
+ percent = ( highy_float - lowy_float ) * ( highx_float - lowx_float );
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get() * percent;
+ }
+ }
+
+ // this is for the pixels in the body
+ temp0 = xindex + group_size + ( lowy_int + 1 ) * ysize;
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp = temp0;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ totals[k] += datain.get();
+ }
+ temp += group_size;
+ }
+ temp0 += ysize;
+ }
+
+ outindex = ( j + ( i * widthout ) ) * components;
+ for( k = 0; k < components; k++ ) {
+ dataout.position( outindex + k );
+ dataout.put( (byte)(totals[k] / area) );
+ }
+ lowx_int = highx_int;
+ lowx_float = highx_float;
+ highx_int += convx_int;
+ highx_float += convx_float;
+ if( highx_float > 1.0f ) {
+ highx_float -= 1.0f;
+ highx_int++;
+ }
+
+ // Clamp to make sure we don't run off the right edge
+ if (highx_int > widthin - 1) {
+ int delta = (highx_int - widthin + 1);
+ lowx_int -= delta;
+ highx_int -= delta;
+ }
+ }
+ lowy_int = highy_int;
+ lowy_float = highy_float;
+ highy_int += convy_int;
+ highy_float += convy_float;
+ if( highy_float > 1.0f ) {
+ highy_float -= 1.0f;
+ highy_int++;
+ }
+ }
+ }
+
+ public static void scale_internal_ushort( int components, int widthin, int heightin,
+ ByteBuffer datain, int widthout, int heightout,
+ ShortBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ float x, convx;
+ float y, convy;
+ float percent;
+ // Max components in a format is 4, so...
+ float[] totals = new float[4];
+ float area;
+ int i, j, k, xindex;
+
+ int temp, temp0;
+ int temp_index;
+ int outindex;
+
+ int lowx_int, highx_int, lowy_int, highy_int;
+ float x_percent, y_percent;
+ float lowx_float, highx_float, lowy_float, highy_float;
+ float convy_float, convx_float;
+ int convy_int, convx_int;
+ int l, m;
+ int left, right;
+
+ if( (widthin == (widthout * 2)) && (heightin == (heightout * 2)) ) {
+ HalveImage.halveImage_ushort( components, widthin, heightin, datain, dataout,
+ element_size, ysize, group_size, myswap_bytes );
+ return;
+ }
+ convy = (float)heightin / heightout;
+ convx = (float)widthin / widthout;
+ convy_int = (int)Math.floor( convy );
+ convy_float = convy - convy_int;
+ convx_int = (int)Math.floor( convx );
+ convx_float = convx - convx_int;
+
+ area = convx * convy;
+
+ lowy_int = 0;
+ lowy_float = 0.0f;
+ highy_int = convy_int;
+ highy_float = convy_float;
+
+ for( i = 0; i < heightout; i++ ) {
+ // Clamp here to be sure we don't read beyond input buffer.
+ if (highy_int >= heightin)
+ highy_int = heightin - 1;
+ lowx_int = 0;
+ lowx_float = 0.0f;
+ highx_int = convx_int;
+ highx_float = convx_float;
+
+ for( j = 0; j < widthout; j++ ) {
+
+ // Ok, now apply box filter to box that goes from (lowx, lowy)
+ // to (highx, highy) on input data into this pixel on output
+ // data.
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0f;
+
+ // caulate the value for pixels in the 1st row
+ xindex = lowx_int * group_size;
+ if( ( highy_int > lowy_int ) && ( highx_int > lowx_int ) ) {
+
+ y_percent = 1 - lowy_float;
+ temp = xindex + lowy_int * ysize;
+ percent = y_percent * ( 1 - lowx_float );
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += ( 0x0000FFFF & ((int)Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ))) * percent;
+ } else {
+ totals[k] += ( 0x0000FFFF & datain.getShort() ) * percent;
+ }
+ }
+ left = temp;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += ( 0x0000FFFF & ((int)Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ))) * y_percent;
+ } else {
+ totals[k] += ( 0x0000FFFF & datain.getShort()) * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ right = temp;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += ( 0x0000FFFF & (Mipmap.GLU_SWAP_2_BYTES( datain.getShort() ))) * percent;
+ } else {
+ totals[k] += ( 0x0000FFFF & datain.getShort()) * percent;
+ }
+ }
+
+ // calculate the value for pixels in the last row
+ y_percent = highy_float;
+ percent = y_percent * ( 1 - lowx_float );
+ temp = xindex + highy_int * ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort()) ) * percent;
+ } else {
+ totals[k] += ( 0x0000FFFF & datain.getShort() ) * percent;
+ }
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort()) ) * y_percent;
+ } else {
+ totals[k] += ( 0x0000FFFF & datain.getShort()) * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += ( 0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort()) ) * percent;
+ } else {
+ totals[k] += ( 0x0000FFFF & datain.getShort()) * percent;
+ }
+ }
+
+ // calculate the value for the pixels in the 1st and last column
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ left += ysize;
+ right += ysize;
+ for( k = 0; k < components; k++, left += element_size, right += element_size ) {
+ if( myswap_bytes ) {
+ datain.position( left );
+ float f = (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES(datain.getShort())) * ( 1 - lowx_float );
+ datain.position( right );
+ f += ((0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES(datain.getShort())) * highx_float);
+ totals[k] += f;
+ } else {
+ datain.position( left );
+ float f = ((0x0000FFFF & datain.getShort()) * ( 1 - lowx_float ));
+ datain.position( right );
+ f += ((0x0000FFFF & datain.getShort()) * highx_float);
+ totals[k] += f;
+ }
+ }
+ }
+ } else if( highy_int > lowy_int ) {
+ x_percent = highx_float - lowx_float;
+ percent = ( 1 - lowy_float) * x_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() )) * percent;
+ } else {
+ totals[k] += (0x0000FFFF & datain.getShort()) * percent;
+ }
+ }
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort()) ) * x_percent;
+ } else {
+ totals[k] += (0x0000FFFF & datain.getShort()) * x_percent;
+ }
+ }
+ }
+ percent = x_percent * highy_float;
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort() )) * percent;
+ } else {
+ totals[k] += (0x0000FFFF & datain.getShort()) * percent;
+ }
+ }
+ } else if( highx_int > lowx_int ) {
+ y_percent = highy_float - lowy_float;
+ percent = ( 1 - lowx_float ) * y_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort()) ) * percent;
+ } else {
+ totals[k] += (0x0000FFFF & datain.getShort()) * percent;
+ }
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort()) ) * y_percent;
+ } else {
+ totals[k] += (0x0000FFFF & datain.getShort()) * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort()) ) * percent;
+ } else {
+ totals[k] += (0x0000FFFF & datain.getShort()) * percent;
+ }
+ }
+ } else {
+ percent = ( highy_float - lowy_float ) * ( highx_float - lowx_float );
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort()) ) * percent;
+ } else {
+ totals[k] += (0x0000FFFF & datain.getShort()) * percent;
+ }
+ }
+ }
+
+ // this is for the pixels in the body
+ temp0 = xindex + group_size + ( lowy_int + 1 ) * ysize;
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp = temp0;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x0000FFFF & Mipmap.GLU_SWAP_2_BYTES( datain.getShort()));
+ } else {
+ totals[k] += (0x0000FFFF & datain.getShort());
+ }
+ }
+ temp += group_size;
+ }
+ temp0 += ysize;
+ }
+
+ outindex = ( j + ( i * widthout ) ) * components;
+ for( k = 0; k < components; k++ ) {
+ dataout.position( outindex + k );
+ dataout.put( (short)(totals[k] / area) );
+ }
+ lowx_int = highx_int;
+ lowx_float = highx_float;
+ highx_int += convx_int;
+ highx_float += convx_float;
+ if( highx_float > 1.0f ) {
+ highx_float -= 1.0f;
+ highx_int++;
+ }
+
+ // Clamp to make sure we don't run off the right edge
+ if (highx_int > widthin - 1) {
+ int delta = (highx_int - widthin + 1);
+ lowx_int -= delta;
+ highx_int -= delta;
+ }
+ }
+ lowy_int = highy_int;
+ lowy_float = highy_float;
+ highy_int += convy_int;
+ highy_float += convy_float;
+ if( highy_float > 1.0f ) {
+ highy_float -= 1.0f;
+ highy_int++;
+ }
+ }
+ }
+
+ public static void scale_internal_short( int components, int widthin, int heightin,
+ ByteBuffer datain, int widthout, int heightout,
+ ShortBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ float x, convx;
+ float y, convy;
+ float percent;
+ // Max components in a format is 4, so...
+ float[] totals = new float[4];
+ float area;
+ int i, j, k, xindex;
+
+ int temp, temp0;
+ int temp_index;
+ int outindex;
+
+ int lowx_int, highx_int, lowy_int, highy_int;
+ float x_percent, y_percent;
+ float lowx_float, highx_float, lowy_float, highy_float;
+ float convy_float, convx_float;
+ int convy_int, convx_int;
+ int l, m;
+ int left, right;
+
+ int swapbuf; // unsigned buffer
+
+ if( (widthin == (widthout * 2)) && (heightin == (heightout * 2)) ) {
+ HalveImage.halveImage_short( components, widthin, heightin, datain, dataout,
+ element_size, ysize, group_size, myswap_bytes );
+ return;
+ }
+ convy = (float)heightin / heightout;
+ convx = (float)widthin / widthout;
+ convy_int = (int)Math.floor( convy );
+ convy_float = convy - convy_int;
+ convx_int = (int)Math.floor( convx );
+ convx_float = convx - convx_int;
+
+ area = convx * convy;
+
+ lowy_int = 0;
+ lowy_float = 0.0f;
+ highy_int = convy_int;
+ highy_float = convy_float;
+
+ for( i = 0; i < heightout; i++ ) {
+ // Clamp here to be sure we don't read beyond input buffer.
+ if (highy_int >= heightin)
+ highy_int = heightin - 1;
+ lowx_int = 0;
+ lowx_float = 0.0f;
+ highx_int = convx_int;
+ highx_float = convx_float;
+
+ for( j = 0; j < widthout; j++ ) {
+
+ // Ok, now apply box filter to box that goes from (lowx, lowy)
+ // to (highx, highy) on input data into this pixel on output
+ // data.
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0f;
+
+ // caulate the value for pixels in the 1st row
+ xindex = lowx_int * group_size;
+ if( ( highy_int > lowy_int ) && ( highx_int > lowx_int ) ) {
+
+ y_percent = 1 - lowy_float;
+ temp = xindex + lowy_int * ysize;
+ percent = y_percent * ( 1 - lowx_float );
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getShort() * percent;
+ }
+ }
+ left = temp;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * y_percent;
+ } else {
+ totals[k] += datain.getShort() * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ right = temp;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getShort() * percent;
+ }
+ }
+
+ // calculate the value for pixels in the last row
+ y_percent = highy_float;
+ percent = y_percent * ( 1 - lowx_float );
+ temp = xindex + highy_int * ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getShort() * percent;
+ }
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * y_percent;
+ } else {
+ totals[k] += datain.getShort() * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getShort() * percent;
+ }
+ }
+
+ // calculate the value for the pixels in the 1st and last column
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ left += ysize;
+ right += ysize;
+ for( k = 0; k < components; k++, left += element_size, right += element_size ) {
+ if( myswap_bytes ) {
+ datain.position( left );
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * ( 1 - lowx_float );
+ datain.position( right );
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * highx_float;
+ } else {
+ datain.position( left );
+ totals[k] += datain.getShort() * ( 1 - lowx_float );
+ datain.position( right );
+ totals[k] += datain.getShort() * highx_float;
+ }
+ }
+ }
+ } else if( highy_int > lowy_int ) {
+ x_percent = highx_float - lowx_float;
+ percent = ( 1 - lowy_float) * x_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getShort() * percent;
+ }
+ }
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort());
+ totals[k] += swapbuf * x_percent;
+ } else {
+ totals[k] += datain.getShort() * x_percent;
+ }
+ }
+ }
+ percent = x_percent * highy_float;
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getShort() * percent;
+ }
+ }
+ } else if( highx_int > lowx_int ) {
+ y_percent = highy_float - lowy_float;
+ percent = ( 1 - lowx_float ) * y_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getShort() * percent;
+ }
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * y_percent;
+ } else {
+ totals[k] += datain.getShort() * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getShort() * percent;
+ }
+ }
+ } else {
+ percent = ( highy_float - lowy_float ) * ( highx_float - lowx_float );
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getShort() * percent;
+ }
+ }
+ }
+
+ // this is for the pixels in the body
+ temp0 = xindex + group_size + ( lowy_int + 1 ) * ysize;
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp = temp0;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_2_BYTES( datain.getShort() );
+ totals[k] += swapbuf;
+ } else {
+ totals[k] += datain.getShort();
+ }
+ }
+ temp += group_size;
+ }
+ temp0 += ysize;
+ }
+
+ outindex = ( j + ( i * widthout ) ) * components;
+ for( k = 0; k < components; k++ ) {
+ dataout.position( outindex + k );
+ dataout.put( (short)(totals[k] / area) );
+ }
+ lowx_int = highx_int;
+ lowx_float = highx_float;
+ highx_int += convx_int;
+ highx_float += convx_float;
+ if( highx_float > 1.0f ) {
+ highx_float -= 1.0f;
+ highx_int++;
+ }
+
+ // Clamp to make sure we don't run off the right edge
+ if (highx_int > widthin - 1) {
+ int delta = (highx_int - widthin + 1);
+ lowx_int -= delta;
+ highx_int -= delta;
+ }
+ }
+ lowy_int = highy_int;
+ lowy_float = highy_float;
+ highy_int += convy_int;
+ highy_float += convy_float;
+ if( highy_float > 1.0f ) {
+ highy_float -= 1.0f;
+ highy_int++;
+ }
+ }
+ }
+
+ public static void scale_internal_uint( int components, int widthin, int heightin,
+ ByteBuffer datain, int widthout, int heightout,
+ IntBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ float x, convx;
+ float y, convy;
+ float percent;
+ // Max components in a format is 4, so...
+ float[] totals = new float[4];
+ float area;
+ int i, j, k, xindex;
+
+ int temp, temp0;
+ int temp_index;
+ int outindex;
+
+ int lowx_int, highx_int, lowy_int, highy_int;
+ float x_percent, y_percent;
+ float lowx_float, highx_float, lowy_float, highy_float;
+ float convy_float, convx_float;
+ int convy_int, convx_int;
+ int l, m;
+ int left, right;
+
+ if( (widthin == (widthout * 2)) && (heightin == (heightout * 2)) ) {
+ HalveImage.halveImage_uint( components, widthin, heightin, datain, dataout,
+ element_size, ysize, group_size, myswap_bytes );
+ return;
+ }
+ convy = (float)heightin / heightout;
+ convx = (float)widthin / widthout;
+ convy_int = (int)Math.floor( convy );
+ convy_float = convy - convy_int;
+ convx_int = (int)Math.floor( convx );
+ convx_float = convx - convx_int;
+
+ area = convx * convy;
+
+ lowy_int = 0;
+ lowy_float = 0.0f;
+ highy_int = convy_int;
+ highy_float = convy_float;
+
+ for( i = 0; i < heightout; i++ ) {
+ // Clamp here to be sure we don't read beyond input buffer.
+ if (highy_int >= heightin)
+ highy_int = heightin - 1;
+ lowx_int = 0;
+ lowx_float = 0.0f;
+ highx_int = convx_int;
+ highx_float = convx_float;
+
+ for( j = 0; j < widthout; j++ ) {
+
+ // Ok, now apply box filter to box that goes from (lowx, lowy)
+ // to (highx, highy) on input data into this pixel on output
+ // data.
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0f;
+
+ // caulate the value for pixels in the 1st row
+ xindex = lowx_int * group_size;
+ if( ( highy_int > lowy_int ) && ( highx_int > lowx_int ) ) {
+
+ y_percent = 1 - lowy_float;
+ temp = xindex + lowy_int * ysize;
+ percent = y_percent * ( 1 - lowx_float );
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt()) ) * percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * percent;
+ }
+ }
+ left = temp;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt()) ) * y_percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ right = temp;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt()) ) * percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * percent;
+ }
+ }
+
+ // calculate the value for pixels in the last row
+ y_percent = highy_float;
+ percent = y_percent * ( 1 - lowx_float );
+ temp = xindex + highy_int * ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt()) ) * percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * percent;
+ }
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt()) ) * y_percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt()) ) * percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * percent;
+ }
+ }
+
+ // calculate the value for the pixels in the 1st and last column
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ left += ysize;
+ right += ysize;
+ for( k = 0; k < components; k++, left += element_size, right += element_size ) {
+ if( myswap_bytes ) {
+ datain.position( left );
+ totals[k] += ((0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES(datain.getInt())) * ( 1 - lowx_float ));
+ datain.position( right );
+ totals[k] += ((0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES(datain.getInt())) * highx_float);
+ } else {
+ datain.position( left );
+ totals[k] += ((0x00000000FFFFFFFF & datain.getInt()) * ( 1 - lowx_float ));
+ datain.position( right );
+ totals[k] += ((0x00000000FFFFFFFF & datain.getInt()) * highx_float);
+ }
+ }
+ }
+ } else if( highy_int > lowy_int ) {
+ x_percent = highx_float - lowx_float;
+ percent = ( 1 - lowy_float) * x_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt())) * percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * percent;
+ }
+ }
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt())) * x_percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * x_percent;
+ }
+ }
+ }
+ percent = x_percent * highy_float;
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt())) * percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * percent;
+ }
+ }
+ } else if( highx_int > lowx_int ) {
+ y_percent = highy_float - lowy_float;
+ percent = ( 1 - lowx_float ) * y_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt())) * percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * percent;
+ }
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt())) * y_percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt())) * percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * percent;
+ }
+ }
+ } else {
+ percent = ( highy_float - lowy_float ) * ( highx_float - lowx_float );
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ long tempInt0 = ( 0xFFFFFFFFL & datain.getInt( temp_index ) );
+ datain.position( temp_index );
+ long tempInt1 = ( 0xFFFFFFFFL & datain.getInt() );
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt())) * percent;
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt()) * percent;
+ }
+ }
+ }
+
+ // this is for the pixels in the body
+ temp0 = xindex + group_size + ( lowy_int + 1 ) * ysize;
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp = temp0;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ totals[k] += (0x00000000FFFFFFFF & Mipmap.GLU_SWAP_4_BYTES( datain.getInt()));
+ } else {
+ totals[k] += (0x00000000FFFFFFFF & datain.getInt());
+ }
+ }
+ temp += group_size;
+ }
+ temp0 += ysize;
+ }
+
+ outindex = ( j + ( i * widthout ) ) * components;
+ float value = 0.0f;
+ for( k = 0; k < components; k++ ) {
+ value = totals[k] / area;
+ dataout.position( outindex + k );
+ if( value >= UINT_MAX ) {
+ dataout.put( (int)value );
+ } else {
+ dataout.put( (int)(totals[k] / area) );
+ }
+ }
+ lowx_int = highx_int;
+ lowx_float = highx_float;
+ highx_int += convx_int;
+ highx_float += convx_float;
+ if( highx_float > 1.0f ) {
+ highx_float -= 1.0f;
+ highx_int++;
+ }
+
+ // Clamp to make sure we don't run off the right edge
+ if (highx_int > widthin - 1) {
+ int delta = (highx_int - widthin + 1);
+ lowx_int -= delta;
+ highx_int -= delta;
+ }
+ }
+ lowy_int = highy_int;
+ lowy_float = highy_float;
+ highy_int += convy_int;
+ highy_float += convy_float;
+ if( highy_float > 1.0f ) {
+ highy_float -= 1.0f;
+ highy_int++;
+ }
+ }
+ }
+
+ public static void scale_internal_int( int components, int widthin, int heightin,
+ ByteBuffer datain, int widthout, int heightout,
+ IntBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ float x, convx;
+ float y, convy;
+ float percent;
+ // Max components in a format is 4, so...
+ float[] totals = new float[4];
+ float area;
+ int i, j, k, xindex;
+
+ int temp, temp0;
+ int temp_index;
+ int outindex;
+
+ int lowx_int, highx_int, lowy_int, highy_int;
+ float x_percent, y_percent;
+ float lowx_float, highx_float, lowy_float, highy_float;
+ float convy_float, convx_float;
+ int convy_int, convx_int;
+ int l, m;
+ int left, right;
+
+ long swapbuf; // unsigned buffer
+
+ if( (widthin == (widthout * 2)) && (heightin == (heightout * 2)) ) {
+ HalveImage.halveImage_int( components, widthin, heightin, datain, dataout,
+ element_size, ysize, group_size, myswap_bytes );
+ return;
+ }
+ convy = (float)heightin / heightout;
+ convx = (float)widthin / widthout;
+ convy_int = (int)Math.floor( convy );
+ convy_float = convy - convy_int;
+ convx_int = (int)Math.floor( convx );
+ convx_float = convx - convx_int;
+
+ area = convx * convy;
+
+ lowy_int = 0;
+ lowy_float = 0.0f;
+ highy_int = convy_int;
+ highy_float = convy_float;
+
+ for( i = 0; i < heightout; i++ ) {
+ // Clamp here to be sure we don't read beyond input buffer.
+ if (highy_int >= heightin)
+ highy_int = heightin - 1;
+ lowx_int = 0;
+ lowx_float = 0.0f;
+ highx_int = convx_int;
+ highx_float = convx_float;
+
+ for( j = 0; j < widthout; j++ ) {
+
+ // Ok, now apply box filter to box that goes from (lowx, lowy)
+ // to (highx, highy) on input data into this pixel on output
+ // data.
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0f;
+
+ // caulate the value for pixels in the 1st row
+ xindex = lowx_int * group_size;
+ if( ( highy_int > lowy_int ) && ( highx_int > lowx_int ) ) {
+
+ y_percent = 1 - lowy_float;
+ temp = xindex + lowy_int * ysize;
+ percent = y_percent * ( 1 - lowx_float );
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getInt() * percent;
+ }
+ }
+ left = temp;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * y_percent;
+ } else {
+ totals[k] += datain.getInt() * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ right = temp;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getInt() * percent;
+ }
+ }
+
+ // calculate the value for pixels in the last row
+ y_percent = highy_float;
+ percent = y_percent * ( 1 - lowx_float );
+ temp = xindex + highy_int * ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getInt() * percent;
+ }
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * y_percent;
+ } else {
+ totals[k] += datain.getInt() * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getInt() * percent;
+ }
+ }
+
+ // calculate the value for the pixels in the 1st and last column
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ left += ysize;
+ right += ysize;
+ for( k = 0; k < components; k++, left += element_size, right += element_size ) {
+ if( myswap_bytes ) {
+ datain.position( left );
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * ( 1 - lowx_float );
+ datain.position( right );
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * highx_float;
+ } else {
+ datain.position( left );
+ totals[k] += (datain.getInt() * ( 1 - lowx_float ));
+ datain.position( right );
+ totals[k] += (datain.getInt() * highx_float);
+ }
+ }
+ }
+ } else if( highy_int > lowy_int ) {
+ x_percent = highx_float - lowx_float;
+ percent = ( 1 - lowy_float) * x_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getInt() * percent;
+ }
+ }
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * x_percent;
+ } else {
+ totals[k] += datain.getInt() * x_percent;
+ }
+ }
+ }
+ percent = x_percent * highy_float;
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getInt() * percent;
+ }
+ }
+ } else if( highx_int > lowx_int ) {
+ y_percent = highy_float - lowy_float;
+ percent = ( 1 - lowx_float ) * y_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getInt() * percent;
+ }
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * y_percent;
+ } else {
+ totals[k] += datain.getInt() * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getInt() * percent;
+ }
+ }
+ } else {
+ percent = ( highy_float - lowy_float ) * ( highx_float - lowx_float );
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getInt() * percent;
+ }
+ }
+ }
+
+ // this is for the pixels in the body
+ temp0 = xindex + group_size + ( lowy_int + 1 ) * ysize;
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp = temp0;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getInt() );
+ totals[k] += swapbuf;
+ } else {
+ totals[k] += datain.getInt();
+ }
+ }
+ temp += group_size;
+ }
+ temp0 += ysize;
+ }
+
+ outindex = ( j + ( i * widthout ) ) * components;
+ for( k = 0; k < components; k++ ) {
+ dataout.position( outindex + k );
+ dataout.put( (int)(totals[k] / area) );
+ }
+ lowx_int = highx_int;
+ lowx_float = highx_float;
+ highx_int += convx_int;
+ highx_float += convx_float;
+ if( highx_float > 1.0f ) {
+ highx_float -= 1.0f;
+ highx_int++;
+ }
+
+ // Clamp to make sure we don't run off the right edge
+ if (highx_int > widthin - 1) {
+ int delta = (highx_int - widthin + 1);
+ lowx_int -= delta;
+ highx_int -= delta;
+ }
+ }
+ lowy_int = highy_int;
+ lowy_float = highy_float;
+ highy_int += convy_int;
+ highy_float += convy_float;
+ if( highy_float > 1.0f ) {
+ highy_float -= 1.0f;
+ highy_int++;
+ }
+ }
+ }
+
+ public static void scale_internal_float( int components, int widthin, int heightin,
+ ByteBuffer datain, int widthout, int heightout,
+ FloatBuffer dataout, int element_size, int ysize,
+ int group_size, boolean myswap_bytes ) {
+ float x, convx;
+ float y, convy;
+ float percent;
+ // Max components in a format is 4, so...
+ float[] totals = new float[4];
+ float area;
+ int i, j, k, xindex;
+
+ int temp, temp0;
+ int temp_index;
+ int outindex;
+
+ int lowx_int, highx_int, lowy_int, highy_int;
+ float x_percent, y_percent;
+ float lowx_float, highx_float, lowy_float, highy_float;
+ float convy_float, convx_float;
+ int convy_int, convx_int;
+ int l, m;
+ int left, right;
+
+ float swapbuf; // unsigned buffer
+
+ if( (widthin == (widthout * 2)) && (heightin == (heightout * 2)) ) {
+ HalveImage.halveImage_float( components, widthin, heightin, datain, dataout,
+ element_size, ysize, group_size, myswap_bytes );
+ return;
+ }
+ convy = (float)heightin / heightout;
+ convx = (float)widthin / widthout;
+ convy_int = (int)Math.floor( convy );
+ convy_float = convy - convy_int;
+ convx_int = (int)Math.floor( convx );
+ convx_float = convx - convx_int;
+
+ area = convx * convy;
+
+ lowy_int = 0;
+ lowy_float = 0.0f;
+ highy_int = convy_int;
+ highy_float = convy_float;
+
+ for( i = 0; i < heightout; i++ ) {
+ // Clamp here to be sure we don't read beyond input buffer.
+ if (highy_int >= heightin)
+ highy_int = heightin - 1;
+ lowx_int = 0;
+ lowx_float = 0.0f;
+ highx_int = convx_int;
+ highx_float = convx_float;
+
+ for( j = 0; j < widthout; j++ ) {
+
+ // Ok, now apply box filter to box that goes from (lowx, lowy)
+ // to (highx, highy) on input data into this pixel on output
+ // data.
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0f;
+
+ // caulate the value for pixels in the 1st row
+ xindex = lowx_int * group_size;
+ if( ( highy_int > lowy_int ) && ( highx_int > lowx_int ) ) {
+
+ y_percent = 1 - lowy_float;
+ temp = xindex + lowy_int * ysize;
+ percent = y_percent * ( 1 - lowx_float );
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getFloat() * percent;
+ }
+ }
+ left = temp;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * y_percent;
+ } else {
+ totals[k] += datain.getFloat() * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ right = temp;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getFloat() * percent;
+ }
+ }
+
+ // calculate the value for pixels in the last row
+ y_percent = highy_float;
+ percent = y_percent * ( 1 - lowx_float );
+ temp = xindex + highy_int * ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getFloat() * percent;
+ }
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * y_percent;
+ } else {
+ totals[k] += datain.getFloat() * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getFloat() * percent;
+ }
+ }
+
+ // calculate the value for the pixels in the 1st and last column
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ left += ysize;
+ right += ysize;
+ for( k = 0; k < components; k++, left += element_size, right += element_size ) {
+ if( myswap_bytes ) {
+ datain.position( left );
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * ( 1 - lowx_float );
+ datain.position( right );
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * highx_float;
+ } else {
+ datain.position( left );
+ totals[k] += (datain.getFloat() * ( 1 - lowx_float ));
+ datain.position( right );
+ totals[k] += (datain.getFloat() * highx_float);
+ }
+ }
+ }
+ } else if( highy_int > lowy_int ) {
+ x_percent = highx_float - lowx_float;
+ percent = ( 1 - lowy_float) * x_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getFloat() * percent;
+ }
+ }
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * x_percent;
+ } else {
+ totals[k] += datain.getFloat() * x_percent;
+ }
+ }
+ }
+ percent = x_percent * highy_float;
+ temp += ysize;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getFloat() * percent;
+ }
+ }
+ } else if( highx_int > lowx_int ) {
+ y_percent = highy_float - lowy_float;
+ percent = ( 1 - lowx_float ) * y_percent;
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getFloat() * percent;
+ }
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += group_size;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * y_percent;
+ } else {
+ totals[k] += datain.getFloat() * y_percent;
+ }
+ }
+ }
+ temp += group_size;
+ percent = y_percent * highx_float;
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getFloat() * percent;
+ }
+ }
+ } else {
+ percent = ( highy_float - lowy_float ) * ( highx_float - lowx_float );
+ temp = xindex + (lowy_int * ysize);
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf * percent;
+ } else {
+ totals[k] += datain.getFloat() * percent;
+ }
+ }
+ }
+
+ // this is for the pixels in the body
+ temp0 = xindex + group_size + ( lowy_int + 1 ) * ysize;
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp = temp0;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ for( k = 0, temp_index = temp; k < components; k++, temp_index += element_size ) {
+ datain.position( temp_index );
+ if( myswap_bytes ) {
+ swapbuf = Mipmap.GLU_SWAP_4_BYTES( datain.getFloat() );
+ totals[k] += swapbuf;
+ } else {
+ totals[k] += datain.getFloat();
+ }
+ }
+ temp += group_size;
+ }
+ temp0 += ysize;
+ }
+
+ outindex = ( j + ( i * widthout ) ) * components;
+ for( k = 0; k < components; k++ ) {
+ dataout.position( outindex + k );
+ dataout.put( (totals[k] / area) );
+ }
+ lowx_int = highx_int;
+ lowx_float = highx_float;
+ highx_int += convx_int;
+ highx_float += convx_float;
+ if( highx_float > 1.0f ) {
+ highx_float -= 1.0f;
+ highx_int++;
+ }
+
+ // Clamp to make sure we don't run off the right edge
+ if (highx_int > widthin - 1) {
+ int delta = (highx_int - widthin + 1);
+ lowx_int -= delta;
+ highx_int -= delta;
+ }
+ }
+ lowy_int = highy_int;
+ lowy_float = highy_float;
+ highy_int += convy_int;
+ highy_float += convy_float;
+ if( highy_float > 1.0f ) {
+ highy_float -= 1.0f;
+ highy_int++;
+ }
+ }
+ }
+
+ public static void scaleInternalPackedPixel( int components, Extract extract,
+ int widthIn, int heightIn, ByteBuffer dataIn, int widthOut,
+ int heightOut, ByteBuffer dataOut, int pixelSizeInBytes,
+ int rowSizeInBytes, boolean isSwap ) {
+ float x, convx;
+ float y, convy;
+ float percent;
+
+ // max components in a format is 4, so
+ float[] totals = new float[4];
+ float[] extractTotals = new float[4];
+ float[] extractMoreTotals = new float[4];
+ float[] shoveTotals = new float[4];
+
+ float area;
+ int i, j, k, xindex;
+
+ int temp, temp0;
+ int temp_index;
+ int outIndex = 0;
+
+ int lowx_int, highx_int, lowy_int, highy_int;
+ float x_percent, y_percent;
+ float lowx_float, highx_float, lowy_float, highy_float;
+ float convy_float, convx_float;
+ int convy_int, convx_int;
+ int l, m;
+ int left, right;
+
+ if( widthIn == widthOut * 2 && heightIn == heightOut * 2 ) {
+ HalveImage.halveImagePackedPixel( components, extract, widthIn, heightIn, dataIn, dataOut,
+ pixelSizeInBytes, rowSizeInBytes, isSwap );
+ return;
+ }
+ convy = (float)heightIn / (float)heightOut;
+ convx = (float)widthIn / (float)widthOut;
+ convy_int = (int)Math.floor( convy );
+ convy_float = convy - convy_int;
+ convx_int = (int)Math.floor( convx );
+ convx_float = convx - convx_int;
+
+ area = convx * convy;
+
+ lowy_int = 0;
+ lowy_float = 0.0f;
+ highy_int = convy_int;
+ highy_float = convx_float;
+
+ for( i = 0; i < heightOut; i++ ) {
+ // Clamp here to be sure we don't read beyond input buffer.
+ if (highy_int >= heightIn)
+ highy_int = heightIn - 1;
+ lowx_int = 0;
+ lowx_float = 0.0f;
+ highx_int = convx_int;
+ highx_float = convx_float;
+
+ for( j = 0; j < widthOut; j++ ) {
+ // ok now apply box filter to box that goes from( lowx, lowy )
+ // to ( highx, highy ) on input data into this pixel on output data
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0f;
+
+ // calculate that value for pixels in the 1st row
+ xindex = lowx_int * pixelSizeInBytes;
+ if( (highy_int > lowy_int) && (highx_int > lowx_int) ) {
+
+ y_percent = 1 - lowy_float;
+ temp = xindex + lowy_int * rowSizeInBytes;
+ percent = y_percent * ( 1 - lowx_float );
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * percent;
+ }
+ left = temp;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += pixelSizeInBytes;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * y_percent;
+ }
+ }
+ temp += pixelSizeInBytes;
+ right = temp;
+ percent = y_percent * highx_float;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * percent;
+ }
+ // calculate the value for pixels in the last row
+
+ y_percent = highy_float;
+ percent = y_percent * ( 1 - lowx_float );
+ temp = xindex + highy_int * rowSizeInBytes;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * percent;
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += pixelSizeInBytes;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * y_percent;
+ }
+ }
+ temp += pixelSizeInBytes;
+ percent = y_percent * highx_float;
+ dataIn.position( temp );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * percent;
+ }
+
+ // calculate the value for pixels in the 1st and last column
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ left += rowSizeInBytes;
+ right += rowSizeInBytes;
+ dataIn.position( left );
+ extract.extract( isSwap, dataIn, extractTotals );
+ dataIn.position( right );
+ extract.extract( isSwap, dataIn, extractMoreTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += ( extractTotals[k] * ( 1 - lowx_float ) + extractMoreTotals[k] * highx_float );
+ }
+ }
+ } else if( highy_int > lowy_int ) {
+ x_percent = highx_float - lowx_float;
+ percent = ( 1 - lowy_float ) * x_percent;
+ temp = xindex + lowy_int * rowSizeInBytes;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * percent;
+ }
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp += rowSizeInBytes;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * x_percent;
+ }
+ }
+ percent = x_percent * highy_float;
+ temp += rowSizeInBytes;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * percent;
+ }
+ } else if( highx_int > lowx_int ) {
+ y_percent = highy_float - lowy_float;
+ percent = ( 1 - lowx_float ) * y_percent;
+ temp = xindex + lowy_int * rowSizeInBytes;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * percent;
+ }
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ temp += pixelSizeInBytes;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * y_percent;
+ }
+ }
+ temp += pixelSizeInBytes;
+ percent = y_percent * highx_float;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * percent;
+ }
+ } else {
+ percent = ( highy_float - lowy_float ) * ( highx_float - lowx_float );
+ temp = xindex + lowy_int * rowSizeInBytes;
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * percent;
+ }
+ }
+
+ // this is for the pixels in the body
+ temp0 = xindex + pixelSizeInBytes + ( lowy_int + 1 ) * rowSizeInBytes;
+ for( m = lowy_int + 1; m < highy_int; m++ ) {
+ temp = temp0;
+ for( l = lowx_int + 1; l < highx_int; l++ ) {
+ dataIn.position( temp );
+ extract.extract( isSwap, dataIn, extractTotals );
+ for( k = 0; k < components; k++ ) {
+ totals[k] += extractTotals[k] * percent;
+ }
+ temp += pixelSizeInBytes;
+ }
+ temp0 += rowSizeInBytes;
+ }
+
+ outIndex = ( j + ( i * widthOut ) );
+ for( k = 0; k < components; k++ ) {
+ shoveTotals[k] = totals[k] / area;
+ }
+ extract.shove( shoveTotals, outIndex, dataOut );
+ lowx_int = highx_int;
+ lowx_float = highx_float;
+ highx_int += convx_int;
+ highx_float += convx_float;
+ if( highx_float > 1.0f ) {
+ highx_float -= 1.0f;
+ highx_int++;
+ }
+
+ // Clamp to make sure we don't run off the right edge
+ if (highx_int > widthIn - 1) {
+ int delta = (highx_int - widthIn + 1);
+ lowx_int -= delta;
+ highx_int -= delta;
+ }
+ }
+ lowy_int = highy_int;
+ lowy_float = highy_float;
+ highy_int += convy_int;
+ highy_float += convy_float;
+ if( highy_float > 1.0f ) {
+ highy_float -= 1.0f;
+ highy_int++;
+ }
+ }
+ assert( outIndex == ( widthOut * heightOut - 1) );
+ }
+
+ public static void scaleInternal3D( int components, int widthIn, int heightIn,
+ int depthIn, ShortBuffer dataIn, int widthOut, int heightOut,
+ int depthOut, ShortBuffer dataOut ) {
+ float x, lowx, highx, convx, halfconvx;
+ float y, lowy, highy, convy, halfconvy;
+ float z, lowz, highz, convz, halfconvz;
+ float xpercent, ypercent, zpercent;
+ float percent;
+ // max compnents in a format is 4
+ float[] totals = new float[4];
+ float volume;
+ int i, j, d, k, zint, yint, xint, xindex, yindex, zindex;
+ int temp;
+
+ lowy = highy = lowx = highx = 0.0f;
+
+ convz = (float)depthIn / depthOut;
+ convy = (float)heightIn / heightOut;
+ convx = (float)widthIn / widthOut;
+ halfconvz = convz / 2.0f;
+ halfconvy = convy / 2.0f;
+ halfconvx = convx / 2.0f;
+ for( d = 0; d < depthOut; d++ ) {
+ z = convz * ( d + 0.5f );
+ if( depthIn > depthOut ) {
+ highz = z + halfconvz;
+ lowz = z - halfconvz;
+ } else {
+ highz = z + 0.5f;
+ lowz = z - 0.5f;
+ }
+ for( i = 0; i < heightOut; i++ ) {
+ y = convy * ( i + 0.5f );
+ if( heightIn > heightOut ) {
+ highz = y + halfconvy;
+ lowz = y - halfconvy;
+ } else {
+ highz = y + 0.5f;
+ lowz = y - 0.5f;
+ }
+ for( j = 0; j < widthOut; j++ ) {
+ x = convx * ( j + 0.5f );
+ if( depthIn > depthOut ) {
+ highz = x + halfconvx;
+ lowz = x - halfconvx;
+ } else {
+ highz = x + 0.5f;
+ lowz = x - 0.5f;
+ }
+
+ // Ok, now apply box filter to box that goes from ( lowx, lowy, lowz )
+ // to ( highx, highy, highz ) on input data into this pixel on output data
+
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0f;
+ volume = 0.0f;
+
+ z = lowz;
+ zint = (int)(Math.floor( z ) );
+ while( z < highz ) {
+ zindex = ( zint + depthIn ) % depthIn;
+ if( highz < zint + 1 ) {
+ zpercent = highz - z;
+ } else {
+ zpercent = zint + 1 - z;
+ }
+
+ y = lowy;
+ yint = (int)(Math.floor( y ) );
+ while( y < highy ) {
+ yindex = ( yint + heightIn ) % heightIn;
+ if( highy < yint + 1 ) {
+ ypercent = highy - y;
+ } else {
+ ypercent = yint + 1 - y;
+ }
+
+ x = lowx;
+ xint = (int)(Math.floor( x ) );
+
+ while( x < highx ) {
+ xindex = (xint + widthIn ) % widthIn;
+ if( highx < xint + 1 ) {
+ xpercent = highx - x;
+ } else {
+ xpercent = xint + 1 - x;
+ }
+
+ percent = xpercent * ypercent * zpercent;
+ volume += percent;
+
+ temp = (xindex + ( yindex *widthIn) + (zindex * widthIn *heightIn)) * components;
+ for( k = 0; k < components; k++ ) {
+ assert( 0 <= (temp+k) && (temp+k) < (widthIn * heightIn * depthIn * components) );
+ totals[k] += dataIn.get( temp + k ) * percent;
+ }
+ xint++;
+ x = xint;
+ } // while x
+ yint++;
+ y = yint;
+ } // while y
+ zint++;
+ z = zint;
+ } // while z
+
+ temp = ( j + ( i * widthOut ) + (d * widthOut * heightOut ) ) * components;
+ for( k = 0; k < components; k++ ) {
+ // totals should be rounded in the case of enlarging an rgb ramp when the type is 332 or 4444
+ assert( 0 <= ( temp + k ) && ( temp + k ) < (widthOut * heightOut* depthOut * components) );
+ dataOut.put( temp + k, (short)((totals[k] + 0.5f) / volume ) );
+ }
+ }
+ }
+ }
+ }
+
+ public static int gluScaleImage3D( GL gl, int format, int widthIn, int heightIn,
+ int depthIn, int typeIn, ByteBuffer dataIn, int widthOut, int heightOut,
+ int depthOut, int typeOut, ByteBuffer dataOut ) {
+ int components;
+ ShortBuffer beforeImage, afterImage;
+ PixelStorageModes psm = new PixelStorageModes();
+
+ if( widthIn == 0 || heightIn == 0 || depthIn == 0 ||
+ widthOut == 0 || heightOut == 0 || depthOut == 0 ) {
+ return( 0 );
+ }
+
+ if( widthIn < 0 || heightIn < 0 || depthIn < 0 ||
+ widthOut < 0 || heightOut < 0 || depthOut < 0 ) {
+ return( GLU.GLU_INVALID_VALUE );
+ }
+
+ if( !Mipmap.legalFormat(format) || !Mipmap.legalType(typeIn) ||
+ !Mipmap.legalType(typeOut) || typeIn == GL2.GL_BITMAP ||
+ typeOut == GL2.GL_BITMAP ) {
+ return( GLU.GLU_INVALID_ENUM );
+ }
+
+ if( !Mipmap.isLegalFormatForPackedPixelType( format, typeIn ) ) {
+ return( GLU.GLU_INVALID_OPERATION );
+ }
+
+ if( !Mipmap.isLegalFormatForPackedPixelType( format, typeOut ) ) {
+ return( GLU.GLU_INVALID_OPERATION );
+ }
+
+ try {
+ beforeImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( Mipmap.imageSize3D( widthIn,
+ heightIn, depthIn, format, GL2.GL_UNSIGNED_SHORT ) )).asShortBuffer();
+ afterImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( Mipmap.imageSize3D( widthIn,
+ heightIn, depthIn, format, GL2.GL_UNSIGNED_SHORT ) )).asShortBuffer();
+ } catch( OutOfMemoryError err ) {
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ Mipmap.retrieveStoreModes3D( gl, psm );
+
+ Image.fillImage3D( psm, widthIn, heightIn, depthIn, format, typeIn,
+ Mipmap.is_index( format ), dataIn, beforeImage );
+ components = Mipmap.elements_per_group( format, 0 );
+ ScaleInternal.scaleInternal3D( components, widthIn, heightIn, depthIn,
+ beforeImage, widthOut, heightOut, depthOut, afterImage );
+ Image.emptyImage3D( psm, widthOut, heightOut, depthOut, format, typeOut,
+ Mipmap.is_index( format ), afterImage, dataOut );
+
+ return( 0 );
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Type_Widget.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Type_Widget.java
new file mode 100644
index 000000000..b329840ef
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Type_Widget.java
@@ -0,0 +1,224 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.mipmap;
+
+import java.nio.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Type_Widget {
+
+ ByteBuffer buffer;
+
+ /** Creates a new instance of Type_Widget */
+ public Type_Widget() {
+ buffer = ByteBuffer.allocateDirect( 4 );
+ }
+
+ public void setUB0( byte b ) {
+ buffer.position( 0 );
+ buffer.put( b );
+ }
+
+ public byte getUB0() {
+ buffer.position( 0 );
+ return( buffer.get() );
+ }
+
+ public void setUB1( byte b ) {
+ buffer.position( 1 );
+ buffer.put( b );
+ }
+
+ public byte getUB1() {
+ buffer.position( 1 );
+ return( buffer.get() );
+ }
+
+ public void setUB2( byte b ) {
+ buffer.position( 2 );
+ buffer.put( b );
+ }
+
+ public byte getUB2() {
+ buffer.position( 2 );
+ return( buffer.get() );
+ }
+
+ public void setUB3( byte b ) {
+ buffer.position( 3 );
+ buffer.put( b );
+ }
+
+ public byte getUB3() {
+ buffer.position( 3 );
+ return( buffer.get() );
+ }
+
+ public void setUS0( short s ) {
+ buffer.position( 0 );
+ buffer.putShort( s );
+ }
+
+ public short getUS0() {
+ buffer.position( 0 );
+ return( buffer.getShort() );
+ }
+
+ public void setUS1( short s ) {
+ buffer.position( 2 );
+ buffer.putShort( s );
+ }
+
+ public short getUS1() {
+ buffer.position( 2 );
+ return( buffer.getShort() );
+ }
+
+ public void setUI( int i ) {
+ buffer.position( 0 );
+ buffer.putInt( i );
+ }
+
+ public int getUI() {
+ buffer.position( 0 );
+ return( buffer.getInt() );
+ }
+
+ public void setB0( byte b ) {
+ buffer.position( 0 );
+ buffer.put( b );
+ }
+
+ public byte getB0() {
+ buffer.position( 0 );
+ return( buffer.get() );
+ }
+
+ public void setB1( byte b ) {
+ buffer.position( 1 );
+ buffer.put( b );
+ }
+
+ public byte getB1() {
+ buffer.position( 1 );
+ return( buffer.get() );
+ }
+
+ public void setB2( byte b ) {
+ buffer.position( 2 );
+ buffer.put( b );
+ }
+
+ public byte getB2() {
+ buffer.position( 2 );
+ return( buffer.get() );
+ }
+
+ public void setB3( byte b ) {
+ buffer.position( 3 );
+ buffer.put( b );
+ }
+
+ public byte getB3() {
+ buffer.position( 3 );
+ return( buffer.get() );
+ }
+
+ public void setS0( short s ) {
+ buffer.position( 0 );
+ buffer.putShort( s );
+ }
+
+ public short getS0() {
+ buffer.position( 0 );
+ return( buffer.getShort() );
+ }
+
+ public void setS1( short s ) {
+ buffer.position( 2 );
+ buffer.putShort( s );
+ }
+
+ public short getS1() {
+ buffer.position( 2 );
+ return( buffer.getShort() );
+ }
+
+ public void setI( int i ) {
+ buffer.position( 0 );
+ buffer.putInt( i );
+ }
+
+ public int getI() {
+ buffer.position( 0 );
+ return( buffer.getInt() );
+ }
+
+ public void setF( float f ) {
+ buffer.position( 0 );
+ buffer.putFloat( f );
+ }
+
+ public float getF() {
+ buffer.position( 0 );
+ return( buffer.getFloat() );
+ }
+
+ public ByteBuffer getBuffer() {
+ buffer.rewind();
+ return( buffer );
+ }
+
+ public static void main( String args[] ) {
+ Type_Widget t = new Type_Widget();
+ t.setI( 1000000 );
+
+ System.out.println("int: " + Integer.toHexString( t.getI() ) );
+
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Arc.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Arc.java
new file mode 100755
index 000000000..9ee2494a1
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Arc.java
@@ -0,0 +1,258 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+*/
+
+/**
+ * Trimming arc
+ * @author Tomas Hrasky
+ *
+ */
+public class Arc {
+ /**
+ * Corresponding picewise-linear arc
+ */
+ public PwlArc pwlArc;
+
+ /**
+ * Arc type
+ */
+ private long type;
+
+ /**
+ * Arc link in linked list
+ */
+ public Arc link;
+
+ /**
+ * Previous arc
+ */
+ Arc prev;
+
+ /**
+ * Next arc
+ */
+ Arc next;
+
+ /**
+ * Corresponding berizer type arc
+ */
+ private BezierArc bezierArc;
+
+ /**
+ * Makes new arc at specified side
+ *
+ * @param side
+ * which side doeas this arc form
+ */
+ public Arc(int side) {
+ bezierArc = null;
+ pwlArc = null;
+ type = 0;
+ setside(side);
+ // nuid=_nuid
+ }
+
+ /**
+ * Sets side the arc is at
+ *
+ * @param side
+ * arc side
+ */
+ private void setside(int side) {
+ // DONE
+ clearside();
+ type |= side << 8;
+ }
+
+ /**
+ * Unsets side
+ */
+ private void clearside() {
+ // DONE
+ type &= ~(0x7 << 8);
+ }
+
+ // this one replaces enum arc_side
+ /**
+ * Side not specified
+ */
+ public static final int ARC_NONE = 0;
+
+ /**
+ * Arc on right
+ */
+ public static final int ARC_RIGHT = 1;
+
+ /**
+ * Arc on top
+ */
+ public static final int ARC_TOP = 2;
+
+ /**
+ * Arc on left
+ */
+ public static final int ARC_LEFT = 3;
+
+ /**
+ * Arc on bottom
+ */
+ public static final int ARC_BOTTOM = 4;
+
+ /**
+ * Bezier type flag
+ */
+ private static final long BEZIER_TAG = 1 << 13;
+
+ /**
+ * Arc type flag
+ */
+ private static final long ARC_TAG = 1 << 3;
+
+ /**
+ * Tail type tag
+ */
+ private static final long TAIL_TAG = 1 << 6;
+
+ /**
+ * Appends arc to the list
+ *
+ * @param jarc
+ * arc to be append
+ * @return this
+ */
+ public Arc append(Arc jarc) {
+ // DONE
+ if (jarc != null) {
+ next = jarc.next;
+ prev = jarc;
+ next.prev = this;
+ prev.next = this;
+ } else {
+ next = this;
+ prev = this;
+ }
+
+ return this;
+ }
+
+ /**
+ * Unused
+ *
+ * @return true
+ */
+ public boolean check() {
+ return true;
+ }
+
+ /**
+ * Sets bezier type flag
+ */
+ public void setbezier() {
+ // DONE
+ type |= BEZIER_TAG;
+
+ }
+
+ /**
+ * Returns tail of linked list coords
+ *
+ * @return tail coords
+ */
+ public float[] tail() {
+ // DONE
+ return pwlArc.pts[0].param;
+ }
+
+ /**
+ * Returns head of linked list coords
+ *
+ * @return head coords
+ */
+ public float[] head() {
+ // DONE
+ return next.pwlArc.pts[0].param;
+ }
+
+ /**
+ * Returns whether arc is marked with arc_tag
+ *
+ * @return is arc marked with arc_tag
+ */
+ public boolean ismarked() {
+ // DONE
+ return ((type & ARC_TAG) > 0) ? true : false;
+ }
+
+ /**
+ * Cleans arc_tag flag
+ */
+ public void clearmark() {
+ // DONE
+ type &= (~ARC_TAG);
+ }
+
+ /**
+ * Sets arc_tag flag
+ */
+ public void setmark() {
+ // DONE
+ type |= ARC_TAG;
+ }
+
+ /**
+ * sets tail tag
+ */
+ public void setitail() {
+ // DONE
+ type |= TAIL_TAG;
+ }
+
+ /**
+ * Returns whether arc is marked tail
+ *
+ * @return is tail
+ */
+ public boolean getitail() {
+ return false;
+ }
+
+ /**
+ * Unsets tail tag
+ */
+ public void clearitail() {
+ // DONE
+ type &= (~TAIL_TAG);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcSdirSorter.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcSdirSorter.java
new file mode 100755
index 000000000..3955e3176
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcSdirSorter.java
@@ -0,0 +1,63 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class for sorting list of Arcs
+ * @author Tomas Hrasky
+ *
+ */
+public class ArcSdirSorter {
+
+ /**
+ * Makes new ArcSdirSorter with Subdivider
+ * @param subdivider subdivider
+ */
+ public ArcSdirSorter(Subdivider subdivider) {
+ //TODO
+ // System.out.println("TODO arcsdirsorter.constructor");
+ }
+
+ /**
+ * Sorts list of arcs
+ * @param list arc list to be sorted
+ * @param count size of list
+ */
+ public void qsort(CArrayOfArcs list, int count) {
+ // TODO
+ // System.out.println("TODO arcsdirsorter.qsort");
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcTdirSorter.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcTdirSorter.java
new file mode 100755
index 000000000..098ba97b7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcTdirSorter.java
@@ -0,0 +1,60 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class for sorting list of Arcs
+ * @author Tomas Hrasky
+ *
+ */
+public class ArcTdirSorter {
+ /**
+ * Makes new ArcSdirSorter with Subdivider
+ * @param subdivider subdivider
+ */
+ public ArcTdirSorter(Subdivider subdivider) {
+ // TODO Auto-generated constructor stub
+ // System.out.println("TODO arcTsorter.konstruktor");
+ }
+ /**
+ * Sorts list of arcs
+ * @param list arc list to be sorted
+ * @param count size of list
+ */
+ public void qsort(CArrayOfArcs list, int count) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO arcTsorter.qsort");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcTesselator.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcTesselator.java
new file mode 100755
index 000000000..edfb8905f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/ArcTesselator.java
@@ -0,0 +1,90 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class for arc tesselation
+ * @author Tomas Hrasky
+ *
+ */
+public class ArcTesselator {
+
+ /**
+ * Makes given arc an bezier arc
+ * @param arc arc to work with
+ * @param s1 minimum s param
+ * @param s2 maximum s param
+ * @param t1 minimum t param
+ * @param t2 maximum s param
+ */
+ public void bezier(Arc arc, float s1, float s2, float t1, float t2) {
+ // DONE
+ TrimVertex[] p = new TrimVertex[2];
+ p[0] = new TrimVertex();
+ p[1] = new TrimVertex();
+ arc.pwlArc = new PwlArc(2, p);
+ p[0].param[0] = s1;
+ p[0].param[1] = s2;
+ p[1].param[0] = t1;
+ p[1].param[1] = t2;
+ arc.setbezier();
+ }
+
+ /**
+ * Empty method
+ * @param newright arc to work with
+ * @param s first tail
+ * @param t2 second tail
+ * @param t1 third tail
+ * @param f stepsize
+ */
+ public void pwl_right(Arc newright, float s, float t1, float t2, float f) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO arctesselator.pwl_right");
+ }
+
+ /**
+ * Empty method
+ * @param newright arc to work with
+ * @param s first tail
+ * @param t2 second tail
+ * @param t1 third tail
+ * @param f stepsize
+ */
+ public void pwl_left(Arc newright, float s, float t2, float t1, float f) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO arctesselator.pwl_left");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Backend.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Backend.java
new file mode 100755
index 000000000..39097720c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Backend.java
@@ -0,0 +1,217 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class responsible for rendering
+ * @author Tomas Hrasky
+ *
+ */
+public abstract class Backend {
+
+ /**
+ * Fill surface
+ */
+ public static final int N_MESHFILL = 0;
+
+ /**
+ * Draw surface as wire model
+ */
+ public static final int N_MESHLINE = 1;
+
+ /**
+ * Draw surface with points
+ */
+ public static final int N_MESHPOINT = 2;
+
+ /**
+ * Object rendering curves
+ */
+ protected CurveEvaluator curveEvaluator;
+
+ /**
+ * Object rendering surfaces
+ */
+ protected SurfaceEvaluator surfaceEvaluator;
+
+ /**
+ * Makes new backend
+ */
+ public Backend() {
+ // curveEvaluator = new OpenGLCurveEvaluator();
+ // surfaceEvaluator = new OpenGLSurfaceEvaluator();
+ }
+
+ /**
+ * Begin a curve
+ */
+ public void bgncurv() {
+ // DONE
+ curveEvaluator.bgnmap1f();
+
+ }
+
+ /**
+ * End a curve
+ */
+ public void endcurv() {
+ // DONE
+ curveEvaluator.endmap1f();
+
+ }
+
+ /**
+ * Make cuve with given parameters
+ * @param type curve type
+ * @param ps control points
+ * @param stride control points coordinates number
+ * @param order order of curve
+ * @param ulo smallest u
+ * @param uhi highest u
+ */
+ public void curvpts(int type, CArrayOfFloats ps, int stride, int order,
+ float ulo, float uhi) {
+ // DONE
+ curveEvaluator.map1f(type, ulo, uhi, stride, order, ps);
+ curveEvaluator.enable(type);
+ }
+
+ /**
+ * Draw curve
+ * @param u1 smallest u
+ * @param u2 highest u
+ * @param nu number of pieces
+ */
+ public void curvgrid(float u1, float u2, int nu) {
+ // DONE
+ curveEvaluator.mapgrid1f(nu, u1, u2);
+
+ }
+
+ /**
+ * Evaluates curve mesh
+ * @param from low param
+ * @param n step
+ */
+ public void curvmesh(int from, int n) {
+ // DONE
+ curveEvaluator.mapmesh1f(N_MESHFILL, from, from + n);
+ }
+
+ /**
+ * Begin surface
+ * @param wiretris use triangles
+ * @param wirequads use quads
+ */
+ public void bgnsurf(int wiretris, int wirequads) {
+ // DONE
+ surfaceEvaluator.bgnmap2f();
+
+ if (wiretris > 0)
+ surfaceEvaluator.polymode(NurbsConsts.N_MESHLINE);
+ else
+ surfaceEvaluator.polymode(NurbsConsts.N_MESHFILL);
+ }
+
+ /**
+ * End surface
+ */
+ public void endsurf() {
+ // DONE
+ surfaceEvaluator.endmap2f();
+ }
+
+ /**
+ * Empty method
+ * @param ulo low u param
+ * @param uhi hig u param
+ * @param vlo low v param
+ * @param vhi high v param
+ */
+ public void patch(float ulo, float uhi, float vlo, float vhi) {
+ // DONE
+ surfaceEvaluator.domain2f(ulo, uhi, vlo, vhi);
+ }
+
+ /**
+ * Draw surface
+ * @param u0 lowest u
+ * @param u1 highest u
+ * @param nu number of pieces in u direction
+ * @param v0 lowest v
+ * @param v1 highest v
+ * @param nv number of pieces in v direction
+ */
+ public void surfgrid(float u0, float u1, int nu, float v0, float v1, int nv) {
+ // DONE
+ surfaceEvaluator.mapgrid2f(nu, u0, u1, nv, v0, v1);
+
+ }
+
+ /**
+ * Evaluates surface mesh
+ * @param u u param
+ * @param v v param
+ * @param n step in u direction
+ * @param m step in v direction
+ */
+ public void surfmesh(int u, int v, int n, int m) {
+ // System.out.println("TODO backend.surfmesh wireframequads");
+ // TODO wireframequads
+ surfaceEvaluator.mapmesh2f(NurbsConsts.N_MESHFILL, u, u + n, v, v + m);
+ }
+
+ /**
+ * Make surface
+ * @param type surface type
+ * @param pts control points
+ * @param ustride control points coordinates in u direction
+ * @param vstride control points coordinates in v direction
+ * @param uorder surface order in u direction
+ * @param vorder surface order in v direction
+ * @param ulo lowest u
+ * @param uhi hightest u
+ * @param vlo lowest v
+ * @param vhi hightest v
+ */
+ public void surfpts(int type, CArrayOfFloats pts, int ustride, int vstride,
+ int uorder, int vorder, float ulo, float uhi, float vlo, float vhi) {
+ // DONE
+ surfaceEvaluator.map2f(type, ulo, uhi, ustride, uorder, vlo, vhi,
+ vstride, vorder, pts);
+ surfaceEvaluator.enable(type);
+
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/BezierArc.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/BezierArc.java
new file mode 100755
index 000000000..d9b390b67
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/BezierArc.java
@@ -0,0 +1,44 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Empty class
+ * @author Tomas Hrasky
+ *
+ */
+public class BezierArc {
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Bin.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Bin.java
new file mode 100755
index 000000000..61316f348
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Bin.java
@@ -0,0 +1,155 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class holding trimming arcs
+ * @author Tomas Hrasky
+ *
+ */
+public class Bin {
+
+ /**
+ * Head of linked list of arcs
+ */
+ private Arc head;
+
+ /**
+ * Current arc
+ */
+ private Arc current;
+
+ /**
+ * Indicates whether there are any Arcs in linked list
+ * @return true if there are any Arcs in linked list
+ */
+ public boolean isnonempty() {
+ // DONE
+ return this.head != null ? true : false;
+ }
+
+ /**
+ * Adds and arc to linked list
+ * @param jarc added arc
+ */
+ public void addarc(Arc jarc) {
+ // DONE
+ // if (head == null)
+ // head = jarc;
+ // else {
+ jarc.link = head;
+ head = jarc;
+ // }
+
+ }
+
+ /**
+ * Returns number of arcs in linked list
+ * @return number of arcs
+ */
+ public int numarcs() {
+ // DONE
+ int count = 0;
+ for (Arc jarc = firstarc(); jarc != null; jarc = nextarc())
+ count++;
+ return count;
+ }
+
+ /**
+ * Removes first arc in list
+ * @return new linked list head
+ */
+ public Arc removearc() {
+ // DONE
+ Arc jarc = head;
+ if (jarc != null)
+ head = jarc.link;
+ return jarc;
+
+ }
+
+ /**
+ * Consolidates linked list
+ */
+ public void adopt() {
+ // DONE
+ markall();
+
+ Arc orphan;
+ while ((orphan = removearc()) != null) {
+ for (Arc parent = orphan.next; !parent.equals(orphan); parent = parent.next) {
+ if (!parent.ismarked()) {
+ orphan.link = parent.link;
+ parent.link = orphan;
+ orphan.clearmark();
+ break;
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Marks all arc in linked list
+ */
+ private void markall() {
+ // DONE
+ for (Arc jarc = firstarc(); jarc != null; jarc = nextarc())
+ jarc.setmark();
+ }
+
+ /**
+ * Returns first arc in linked list
+ * @return first arc in linked list
+ */
+ private Arc firstarc() {
+ // DONE
+ current = head;
+ return nextarc();
+ }
+
+ /**
+ * Returns next arc in linked list
+ * @return next arc
+ *
+ */
+ private Arc nextarc() {
+ // DONE
+ Arc jarc = current;
+ if (jarc != null)
+ current = jarc.link;
+ return jarc;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Breakpt.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Breakpt.java
new file mode 100755
index 000000000..b5b88ad96
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Breakpt.java
@@ -0,0 +1,59 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class holding break point parameters
+ *
+ * @author Tomas Hrasky
+ *
+ */
+public class Breakpt {
+
+ /**
+ * Breakpoint multiplicity
+ */
+ public int multi;
+
+ /**
+ * Breakpint value
+ */
+ public float value;
+
+ /**
+ * Breakpoint deficit (how many times it has to be added)
+ */
+ public int def;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfArcs.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfArcs.java
new file mode 100755
index 000000000..0646e1d9f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfArcs.java
@@ -0,0 +1,194 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/**
+ * Class replacing C language pointer
+ *
+ * @author Tomas Hrasky
+ *
+ */
+public class CArrayOfArcs {
+ /**
+ * Underlaying array
+ */
+ private Arc[] array;
+
+ /**
+ * Pointer to array member
+ */
+ private int pointer;
+
+ /**
+ * Don't check for array borders?
+ */
+ private boolean noCheck = true;
+
+ /**
+ * Makes new CArray
+ *
+ * @param array
+ * underlaying array
+ * @param pointer
+ * pointer (index) to array
+ */
+ public CArrayOfArcs(Arc[] array, int pointer) {
+ this.array = array;
+ // this.pointer=pointer;
+ setPointer(pointer);
+ }
+
+ /**
+ * Makes new CArray from other CArray
+ *
+ * @param carray
+ * reference array
+ */
+ public CArrayOfArcs(CArrayOfArcs carray) {
+ this.array = carray.array;
+ // this.pointer=carray.pointer;
+ setPointer(carray.pointer);
+ }
+
+ /**
+ * Makes new CArray with pointer set to 0
+ *
+ * @param ctlarray
+ * underlaying array
+ */
+ public CArrayOfArcs(Arc[] ctlarray) {
+ this.array = ctlarray;
+ this.pointer = 0;
+ }
+
+ /**
+ * Returns element at pointer
+ *
+ * @return element at pointer
+ */
+ public Arc get() {
+ return array[pointer];
+ }
+
+ /**
+ * Increases pointer by one (++)
+ */
+ public void pp() {
+ // pointer++;
+ setPointer(pointer + 1);
+ }
+
+ /**
+ * Sets element at pointer
+ *
+ * @param f
+ * desired value
+ */
+ public void set(Arc f) {
+ array[pointer] = f;
+
+ }
+
+ /**
+ * Returns array element at specified index
+ *
+ * @param i
+ * array index
+ * @return element at index
+ */
+ public Arc get(int i) {
+ return array[i];
+ }
+
+ /**
+ * Returns array element at specified index relatively to pointer
+ *
+ * @param i
+ * relative index
+ * @return element at relative index
+ */
+ public Arc getRelative(int i) {
+ return array[pointer + i];
+ }
+
+ /**
+ * Sets value of element at specified index relatively to pointer
+ *
+ * @param i
+ * relative index
+ * @param value
+ * value to be set
+ */
+ public void setRelative(int i, Arc value) {
+ array[pointer + i] = value;
+ }
+
+ /**
+ * Lessens pointer by value
+ *
+ * @param i
+ * lessen by
+ */
+ public void lessenPointerBy(int i) {
+ // pointer-=i;
+ setPointer(pointer - i);
+ }
+
+ /**
+ * Returns pointer value
+ *
+ * @return pointer value
+ */
+ public int getPointer() {
+ return pointer;
+ }
+
+ /**
+ * Sets ponter value
+ *
+ * @param pointer
+ * pointer value to be set
+ */
+ public void setPointer(int pointer) {
+ if (!noCheck && pointer > array.length)
+ throw new IllegalArgumentException("Pointer " + pointer
+ + " out of bounds " + array.length);
+ this.pointer = pointer;
+ }
+
+ /**
+ * Raises pointer by value
+ *
+ * @param i
+ * raise by
+ */
+ public void raisePointerBy(int i) {
+ // pointer+=i;
+ setPointer(pointer + i);
+ }
+
+ /**
+ * Lessens ponter by one (--)
+ */
+ public void mm() {
+ // pointer--;
+ setPointer(pointer - 1);
+ }
+
+ /**
+ * Returns underlaying array
+ *
+ * @return underlaying array
+ */
+ public Arc[] getArray() {
+ return array;
+ }
+
+ /**
+ * Sets underlaying array
+ *
+ * @param array
+ * underlaying array
+ */
+ public void setArray(Arc[] array) {
+ this.array = array;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfBreakpts.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfBreakpts.java
new file mode 100755
index 000000000..e47fdf966
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfBreakpts.java
@@ -0,0 +1,130 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/**
+ * Class replacing C language pointer
+ *
+ * @author Tomas Hrasky
+ *
+ */
+public class CArrayOfBreakpts {
+ /**
+ * Underlaying array
+ */
+ private Breakpt[] pole;
+
+ /**
+ * Pointer to array member
+ */
+ private int pointer;
+
+ /**
+ * Makes new CArray
+ *
+ * @param array
+ * underlaying array
+ * @param pointer
+ * pointer (index) to array
+ */
+ public CArrayOfBreakpts(Breakpt[] array, int pointer) {
+ this.pole = array;
+ this.pointer = pointer;
+ }
+
+ /**
+ * Makes new CArray from other CArray
+ *
+ * @param carray
+ * reference array
+ */
+ public CArrayOfBreakpts(CArrayOfBreakpts carray) {
+ this.pole = carray.pole;
+ this.pointer = carray.pointer;
+ }
+
+ /**
+ * Returns element at pointer
+ *
+ * @return element at pointer
+ */
+ public Breakpt get() {
+ return pole[pointer];
+ }
+
+ /**
+ * Increases pointer by one (++)
+ */
+ public void pp() {
+ pointer++;
+ }
+
+ /**
+ * Sets element at pointer
+ *
+ * @param f
+ * desired value
+ */
+ public void set(Breakpt f) {
+ pole[pointer] = f;
+
+ }
+
+ /**
+ * Returns array element at specified index
+ *
+ * @param i
+ * array index
+ * @return element at index
+ */
+ public Breakpt get(int i) {
+ return pole[i];
+ }
+
+ /**
+ * Lessens pointer by value
+ *
+ * @param i
+ * lessen by
+ */
+ public void lessenPointerBy(int i) {
+ pointer -= i;
+
+ }
+
+ /**
+ * Returns pointer value
+ *
+ * @return pointer value
+ */
+ public int getPointer() {
+ return pointer;
+ }
+
+ /**
+ * Sets ponter value
+ *
+ * @param pointer
+ * pointer value to be set
+ */
+ public void setPointer(int pointer) {
+ this.pointer = pointer;
+ }
+
+ /**
+ * Raises pointer by value
+ *
+ * @param i
+ * raise by
+ */
+ public void raisePointerBy(int i) {
+ pointer += i;
+
+ }
+
+ /**
+ * Lessens ponter by one (--)
+ */
+ public void mm() {
+ pointer--;
+
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfFloats.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfFloats.java
new file mode 100755
index 000000000..60cef9919
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfFloats.java
@@ -0,0 +1,195 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/**
+ * Class replacing C language pointer
+ *
+ * @author Tomas Hrasky
+ *
+ */
+public class CArrayOfFloats {
+
+ /**
+ * Underlaying array
+ */
+ private float[] array;
+
+ /**
+ * Pointer to array member
+ */
+ private int pointer;
+
+ /**
+ * Don't check for array borders?
+ */
+ private boolean noCheck = true;
+
+ /**
+ * Makes new CArray
+ *
+ * @param array
+ * underlaying array
+ * @param pointer
+ * pointer (index) to array
+ */
+ public CArrayOfFloats(float[] array, int pointer) {
+ this.array = array;
+ // this.pointer=pointer;
+ setPointer(pointer);
+ }
+
+ /**
+ * Makes new CArray from other CArray
+ *
+ * @param carray
+ * reference array
+ */
+ public CArrayOfFloats(CArrayOfFloats carray) {
+ this.array = carray.array;
+ // this.pointer=carray.pointer;
+ setPointer(carray.pointer);
+ }
+
+ /**
+ * Makes new CArray with pointer set to 0
+ *
+ * @param ctlarray
+ * underlaying array
+ */
+ public CArrayOfFloats(float[] ctlarray) {
+ this.array = ctlarray;
+ this.pointer = 0;
+ }
+
+ /**
+ * Returns element at pointer
+ *
+ * @return element at pointer
+ */
+ public float get() {
+ return array[pointer];
+ }
+
+ /**
+ * Increases pointer by one (++)
+ */
+ public void pp() {
+ // pointer++;
+ setPointer(pointer + 1);
+ }
+
+ /**
+ * Sets element at pointer
+ *
+ * @param f
+ * desired value
+ */
+ public void set(float f) {
+ array[pointer] = f;
+
+ }
+
+ /**
+ * Returns array element at specified index
+ *
+ * @param i
+ * array index
+ * @return element at index
+ */
+ public float get(int i) {
+ return array[i];
+ }
+
+ /**
+ * Returns array element at specified index relatively to pointer
+ *
+ * @param i
+ * relative index
+ * @return element at relative index
+ */
+ public float getRelative(int i) {
+ return array[pointer + i];
+ }
+
+ /**
+ * Sets value of element at specified index relatively to pointer
+ *
+ * @param i
+ * relative index
+ * @param value
+ * value to be set
+ */
+ public void setRelative(int i, float value) {
+ array[pointer + i] = value;
+ }
+
+ /**
+ * Lessens pointer by value
+ *
+ * @param i
+ * lessen by
+ */
+ public void lessenPointerBy(int i) {
+ // pointer-=i;
+ setPointer(pointer - i);
+ }
+
+ /**
+ * Returns pointer value
+ *
+ * @return pointer value
+ */
+ public int getPointer() {
+ return pointer;
+ }
+
+ /**
+ * Sets ponter value
+ *
+ * @param pointer
+ * pointer value to be set
+ */
+ public void setPointer(int pointer) {
+ if (!noCheck && pointer > array.length)
+ throw new IllegalArgumentException("Pointer " + pointer
+ + " out of bounds " + array.length);
+ this.pointer = pointer;
+ }
+
+ /**
+ * Raises pointer by value
+ *
+ * @param i
+ * raise by
+ */
+ public void raisePointerBy(int i) {
+ // pointer+=i;
+ setPointer(pointer + i);
+ }
+
+ /**
+ * Lessens ponter by one (--)
+ */
+ public void mm() {
+ // pointer--;
+ setPointer(pointer - 1);
+ }
+
+ /**
+ * Returns underlaying array
+ *
+ * @return underlaying array
+ */
+ public float[] getArray() {
+ return array;
+ }
+
+ /**
+ * Sets underlaying array
+ *
+ * @param array
+ * underlaying array
+ */
+ public void setArray(float[] array) {
+ this.array = array;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfQuiltspecs.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfQuiltspecs.java
new file mode 100755
index 000000000..ef16a8204
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CArrayOfQuiltspecs.java
@@ -0,0 +1,160 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/**
+ * Class replacing C language pointer
+ *
+ * @author Tomas Hrasky
+ *
+ */
+public class CArrayOfQuiltspecs {
+ /**
+ * Underlaying array
+ */
+ private Quiltspec[] array;
+
+ /**
+ * Pointer to array member
+ */
+ private int pointer;
+
+ /**
+ * Makes new CArray
+ *
+ * @param array
+ * underlaying array
+ * @param pointer
+ * pointer (index) to array
+ */
+ public CArrayOfQuiltspecs(Quiltspec[] array, int pointer) {
+ this.array = array;
+ this.pointer = pointer;
+ }
+
+ /**
+ * Makes new CArray from other CArray
+ *
+ * @param carray
+ * reference array
+ */
+ public CArrayOfQuiltspecs(CArrayOfQuiltspecs carray) {
+ this.array = carray.array;
+ this.pointer = carray.pointer;
+ }
+
+ /**
+ * Makes new CArray with pointer set to 0
+ *
+ * @param array
+ * underlaying array
+ */
+ public CArrayOfQuiltspecs(Quiltspec[] array) {
+ this.array = array;
+ this.pointer = 0;
+ }
+
+ /**
+ * Returns element at pointer
+ *
+ * @return element at pointer
+ */
+ public Quiltspec get() {
+ return array[pointer];
+ }
+
+ /**
+ * Increases pointer by one (++)
+ */
+ public void pp() {
+ pointer++;
+ }
+
+ /**
+ * Sets element at pointer
+ *
+ * @param f
+ * desired value
+ */
+ public void set(Quiltspec f) {
+ array[pointer] = f;
+
+ }
+
+ /**
+ * Returns array element at specified index
+ *
+ * @param i
+ * array index
+ * @return element at index
+ */
+ public Quiltspec get(int i) {
+ return array[i];
+ }
+
+ /**
+ * Lessens pointer by value
+ *
+ * @param i
+ * lessen by
+ */
+ public void lessenPointerBy(int i) {
+ pointer -= i;
+
+ }
+
+ /**
+ * Returns pointer value
+ *
+ * @return pointer value
+ */
+ public int getPointer() {
+ return pointer;
+ }
+
+ /**
+ * Sets ponter value
+ *
+ * @param pointer
+ * pointer value to be set
+ */
+ public void setPointer(int pointer) {
+ this.pointer = pointer;
+ }
+
+ /**
+ * Raises pointer by value
+ *
+ * @param i
+ * raise by
+ */
+ public void raisePointerBy(int i) {
+ pointer += i;
+
+ }
+
+ /**
+ * Lessens ponter by one (--)
+ */
+ public void mm() {
+ pointer--;
+
+ }
+
+ /**
+ * Returns underlaying array
+ *
+ * @return underlaying array
+ */
+ public Quiltspec[] getArray() {
+ return array;
+ }
+
+ /**
+ * Sets underlaying array
+ *
+ * @param array
+ * underlaying array
+ */
+ public void setArray(Quiltspec[] array) {
+ this.array = array;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Curve.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Curve.java
new file mode 100755
index 000000000..fb1a5acea
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Curve.java
@@ -0,0 +1,238 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class holding curve definition
+ * @author Tomáš Hráský
+ *
+ */
+public class Curve {
+
+ /**
+ * Maximum coordinates per control point
+ */
+ private static final int MAXCOORDS = 5;
+
+ /**
+ * Max curve order
+ */
+ private static final int MAXORDER = 24;
+
+ /**
+ * Next curve in linked list
+ */
+ public Curve next;
+
+ /**
+ * OpenGL maps
+ */
+ private Mapdesc mapdesc;
+
+ /**
+ * Does the curve need sampling
+ */
+ private boolean needsSampling;
+
+ /**
+ * Culling
+ */
+ private int cullval;
+
+ /**
+ * Number of coords
+ */
+ private int stride;
+
+ /**
+ * Curve order
+ */
+ private int order;
+
+ /**
+ * Holds conversion range borders
+ */
+ private float[] range;
+
+ /**
+ * Subdivision stepsize
+ */
+ public float stepsize;
+
+ /**
+ * Minimal subdivision stepsize
+ */
+ private float minstepsize;
+
+ /**
+ * Sampling points
+ */
+ float[] spts;
+
+ /**
+ * Makes new Curve
+ *
+ * @param geo
+ * @param pta
+ * @param ptb
+ * @param c
+ * next curve in linked list
+ */
+ public Curve(Quilt geo, float[] pta, float[] ptb, Curve c) {
+
+ spts = new float[MAXORDER * MAXCOORDS];
+
+ mapdesc = geo.mapdesc;
+
+ next = c;
+ needsSampling = mapdesc.isRangeSampling() ? true : false;
+
+ cullval = mapdesc.isCulling() ? Subdivider.CULL_ACCEPT
+ : Subdivider.CULL_TRIVIAL_REJECT;
+ order = geo.qspec.get(0).order;
+ stride = MAXCOORDS;
+
+ // CArrayOfFloats ps = geo.cpts;
+ CArrayOfFloats ps = new CArrayOfFloats(geo.cpts.getArray(), 0);
+ CArrayOfQuiltspecs qs = geo.qspec;
+ ps.raisePointerBy(qs.get().offset);
+ ps.raisePointerBy(qs.get().index * qs.get().order * qs.get().stride);
+
+ if (needsSampling) {
+ mapdesc.xformSampling(ps, qs.get().order, qs.get().stride, spts,
+ stride);
+ }
+ if (cullval == Subdivider.CULL_ACCEPT) {
+ // System.out.println("TODO curve.Curve-cullval");
+ // mapdesc.xformCulling(ps,qs.get().order,qs.get().stride,cpts,stride);
+ }
+
+ range = new float[3];
+ range[0] = qs.get().breakpoints[qs.get().index];
+ range[1] = qs.get().breakpoints[qs.get().index + 1];
+ range[2] = range[1] - range[0];
+ // TODO it is necessary to solve problem with "this" pointer here
+ if (range[0] != pta[0]) {
+ // System.out.println("TODO curve.Curve-range0");
+ // Curve lower=new Curve(this,pta,0);
+ // lower.next=next;
+ // this=lower;
+ }
+ if (range[1] != ptb[0]) {
+ // System.out.println("TODO curve.Curve-range1");
+ // Curve lower=new Curve(this,ptb,0);
+ }
+ }
+
+ /**
+ * Checks culling type
+ * @return Subdivider.CULL_ACCEPT
+ */
+ public int cullCheck() {
+ if (cullval == Subdivider.CULL_ACCEPT) {
+ // System.out.println("TODO curve.cullval");
+ // cullval=mapdesc.cullCheck(cpts,order,stride);
+ }
+ // TODO compute cullval and return the computed value
+ // return cullval;
+ return Subdivider.CULL_ACCEPT;
+ }
+
+ /**
+ * Computes subdivision step size
+ */
+ public void getStepSize() {
+ minstepsize = 0;
+ if (mapdesc.isConstantSampling()) {
+ setstepsize(mapdesc.maxrate);
+ } else if (mapdesc.isDomainSampling()) {
+ setstepsize(mapdesc.maxrate * range[2]);
+ } else {
+ assert (order <= MAXORDER);
+
+ float tmp[][] = new float[MAXORDER][MAXCOORDS];
+
+ int tstride = (MAXORDER);
+
+ int val = 0;
+ // mapdesc.project(spts,stride,tmp,tstride,order);
+
+ // System.out.println("TODO curve.getsptepsize mapdesc.project");
+
+ if (val == 0) {
+ setstepsize(mapdesc.maxrate);
+ } else {
+ float t = mapdesc.getProperty(NurbsConsts.N_PIXEL_TOLERANCE);
+ if (mapdesc.isParametricDistanceSampling()) {
+ // System.out.println("TODO curve.getstepsize - parametric");
+ } else if (mapdesc.isPathLengthSampling()) {
+ // System.out.println("TODO curve.getstepsize - pathlength");
+ } else {
+ setstepsize(mapdesc.maxrate);
+ }
+ }
+
+ }
+
+ }
+
+ /**
+ * Sets maximum subdivision step size
+ * @param max maximum subdivision step size
+ */
+ private void setstepsize(float max) {
+ // DONE
+ stepsize = (max >= 1) ? (range[2] / max) : range[2];
+ minstepsize = stepsize;
+ }
+
+ /**
+ * Clamps the curve
+ */
+ public void clamp() {
+ // DONE
+ if (stepsize < minstepsize)
+ stepsize = mapdesc.clampfactor * minstepsize;
+ }
+
+ /**
+ * Tells whether curve needs subdivision
+ *
+ * @return curve needs subdivison
+ */
+ public boolean needsSamplingSubdivision() {
+ return (stepsize < minstepsize);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CurveEvaluator.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CurveEvaluator.java
new file mode 100755
index 000000000..c27ffd4c4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/CurveEvaluator.java
@@ -0,0 +1,86 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class rendering curves with OpenGL
+ * @author Tomáš Hráský
+ *
+ */
+public interface CurveEvaluator {
+ /**
+ * Pushes eval bit
+ */
+ public void bgnmap1f();
+
+ /**
+ * Pops all OpenGL attributes
+ */
+ public void endmap1f() ;
+
+ /**
+ * Initializes opengl evaluator
+ * @param type curve type
+ * @param ulo lowest u
+ * @param uhi highest u
+ * @param stride control point coords
+ * @param order curve order
+ * @param ps control points
+ */
+ public void map1f(int type, float ulo, float uhi, int stride, int order,
+ CArrayOfFloats ps) ;
+
+ /**
+ * Calls opengl enable
+ * @param type what to enable
+ */
+ public void enable(int type) ;
+
+ /**
+ * Calls glMapGrid1f
+ * @param nu steps
+ * @param u1 low u
+ * @param u2 high u
+ */
+ public void mapgrid1f(int nu, float u1, float u2) ;
+
+ /**
+ * Evaluates a curve using glEvalMesh1f
+ * @param style Backend.N_MESHFILL/N_MESHLINE/N_MESHPOINT
+ * @param from lowest param
+ * @param to highest param
+ */
+ public void mapmesh1f(int style, int from, int to) ;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Curvelist.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Curvelist.java
new file mode 100755
index 000000000..fc3018833
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Curvelist.java
@@ -0,0 +1,121 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class for woking with linked list of curves
+ * @author Tomas Hrasky
+ *
+ */
+public class Curvelist {
+
+ /**
+ * Head of linked list
+ */
+ private Curve curve;
+
+ /**
+ * Holds conversion range borders
+ */
+ float[] range;
+
+ /**
+ * Subdivision step size
+ */
+ public float stepsize;
+
+ /**
+ * Do curves need subdivision?
+ */
+ private boolean needsSubdivision;
+
+ /**
+ * Makes new instance on top of specified lis of Quilts
+ * @param qlist underlaying list of quilts
+ * @param pta range start
+ * @param ptb range end
+ */
+ public Curvelist(Quilt qlist, float[] pta, float[] ptb) {
+ // DONE
+ curve = null;
+ range = new float[3];
+
+ for (Quilt q = qlist; q != null; q = q.next) {
+ curve = new Curve(q, pta, ptb, curve);
+ }
+ range[0] = pta[0];
+ range[1] = ptb[0];
+ range[2] = range[1] - range[0];
+ }
+
+ /**
+ * Compute step size
+ */
+ public void getstepsize() {
+ // DONE
+ stepsize = range[2];
+ Curve c;
+ for (c = curve; c != null; c = c.next) {
+ c.getStepSize();
+ c.clamp();
+ stepsize = (c.stepsize < stepsize) ? c.stepsize : stepsize;
+ if (c.needsSamplingSubdivision())
+ break;
+ }
+ needsSubdivision = (c != null) ? true : false;
+
+ }
+
+ /**
+ * Indicates whether curves need subdivision
+ * @return curves need subdivision
+ */
+ public boolean needsSamplingSubdivision() {
+ // DONE
+ return needsSubdivision;
+ }
+
+ /**
+ * Checks for culling
+ * @return Subdivider.CULL_TRIVIAL_REJECT or Subdivider.CULL_ACCEPT
+ */
+ public int cullCheck() {
+ // DONE
+ for (Curve c = curve; c != null; c = c.next)
+ if (c.cullCheck() == Subdivider.CULL_TRIVIAL_REJECT)
+ return Subdivider.CULL_TRIVIAL_REJECT;
+ return Subdivider.CULL_ACCEPT;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/DisplayList.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/DisplayList.java
new file mode 100755
index 000000000..39a3a28f4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/DisplayList.java
@@ -0,0 +1,56 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+import java.lang.reflect.Method;
+
+/**
+ * Display list
+ * @author Tomas Hrasky
+ *
+ */
+public class DisplayList {
+
+ /**
+ * Append action to the display list
+ * @param src source object to invoke method on
+ * @param m invoked method
+ * @param arg method argument
+ */
+ public void append(Object src, Method m, Object arg) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO displaylist append");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Flist.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Flist.java
new file mode 100755
index 000000000..00757ed7e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Flist.java
@@ -0,0 +1,130 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+import java.util.Arrays;
+
+/**
+ * List of breakpoints
+ * @author Tomas Hrasky
+ *
+ */
+public class Flist {
+
+ /**
+ * Data elements end index
+ *
+ */
+ public int end;
+
+ /**
+ *Data elements start index
+ */
+ public int start;
+
+ /**
+ * Breakpoint values
+ */
+ public float[] pts;
+
+ /**
+ * Number of array fields
+ */
+ private int npts;
+
+ /**
+ * Grows list
+ * @param maxpts maximum desired size
+ */
+ public void grow(int maxpts) {
+ // DONE
+ if (npts < maxpts) {
+ // npts=2*maxpts;
+ npts = maxpts;
+ pts = new float[npts];
+ }
+ start = 0;
+ end = 0;
+ }
+
+ /**
+ * Removes duplicate array elemnts
+ */
+ public void filter() {
+ // INFO the aim of this method is to remove duplicates from array
+
+ Arrays.sort(pts);
+
+ start = 0;
+
+ int j = 0;
+
+ for (int i = 1; i < end; i++) {
+ if (pts[i] == pts[i - j - 1])
+ j++;
+ pts[i - j] = pts[i];
+ }
+
+ end -= j;
+
+ }
+
+ /**
+ * Sets start and and to real start and end of array elements
+ * @param from start from
+ * @param to end at
+ */
+ public void taper(float from, float to) {
+ // DONE
+
+ while (pts[start] != from) {
+ start++;
+ }
+
+ while (pts[end - 1] != to) {
+ end--;
+ }
+
+ }
+
+ /**
+ * Adds breakpoint value
+ * @param f value
+ */
+ public void add(float f) {
+ //DONE
+ pts[end++] = f;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Knotspec.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Knotspec.java
new file mode 100755
index 000000000..9251aa231
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Knotspec.java
@@ -0,0 +1,557 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Knot vector specification
+ *
+ * @author Tomas Hrasky
+ *
+ */
+public class Knotspec {
+
+ /**
+ * Begin of input knots
+ */
+ public CArrayOfFloats inkbegin;
+
+ /**
+ * End of input knots
+ */
+ public CArrayOfFloats inkend;
+
+ /**
+ * Stride before knot operations
+ */
+ public int prestride;
+
+ /**
+ * Curve order
+ */
+ public int order;
+
+ /**
+ * Next knot specification in linked list (used in surfaces)
+ */
+ public Knotspec next;
+
+ /**
+ * Last knot
+ */
+ public CArrayOfFloats klast;
+
+ /**
+ * First knot
+ */
+ CArrayOfFloats kfirst;
+
+ /**
+ * Beginning of breakpoints
+ */
+ CArrayOfBreakpts bbegin;
+
+ /**
+ * End of breakpoints
+ */
+ CArrayOfBreakpts bend;
+
+ /**
+ * Considered left end knot
+ */
+ CArrayOfFloats kleft;
+
+ /**
+ * Considered right end knot
+ */
+ CArrayOfFloats kright;
+
+ /**
+ * Offset before knot operations
+ */
+ int preoffset;
+
+ /**
+ * Control points array Length after knot operations
+ */
+ int postwidth;
+
+ /**
+ * Beginning of coeficients array
+ */
+ private CArrayOfFloats sbegin;
+
+ /**
+ * Beginning of output knots
+ */
+ private CArrayOfFloats outkbegin;
+
+ /**
+ * End of output knots
+ */
+ private CArrayOfFloats outkend;
+
+ /**
+ * Control points aray length before knot operations
+ */
+ int prewidth;
+
+ /**
+ * Offset after knot operations
+ */
+ int postoffset;
+
+ /**
+ * Number of control points' coordinates after knot operations
+ */
+ public int poststride;
+
+ /**
+ * Number of control points' coordinates
+ */
+ public int ncoords;
+
+ /**
+ * Tell whether knotspec has already benn transformed
+ */
+ public boolean istransformed;
+
+ /**
+ * Knotspec to be transformed
+ */
+ public Knotspec kspectotrans;
+
+ /**
+ * Finds knot border of knot insertion and required multiplicities
+ */
+ public void preselect() {
+ // DONE
+ float kval;
+
+ klast = new CArrayOfFloats(inkend);
+ klast.lessenPointerBy(order);
+ for (kval = klast.get(); klast.getPointer() != inkend.getPointer(); klast
+ .pp()) {
+ if (!Knotvector.identical(klast.get(), kval))
+ break;
+ }
+
+ kfirst = new CArrayOfFloats(inkbegin);
+ kfirst.raisePointerBy(order - 1);
+ for (kval = kfirst.get(); kfirst.getPointer() != inkend.getPointer(); kfirst
+ .pp()) {
+ if (!Knotvector.identical(kfirst.get(), kval))
+ break;
+ }
+
+ CArrayOfFloats k = new CArrayOfFloats(kfirst);
+ k.mm();
+
+ for (; k.getPointer() >= inkbegin.getPointer(); k.mm())
+ if (!Knotvector.identical(kval, k.get()))
+ break;
+ k.pp();
+
+ Breakpt[] bbeginArray = new Breakpt[(klast.getPointer() - kfirst
+ .getPointer()) + 1];
+ for (int i = 0; i < bbeginArray.length; i++)
+ bbeginArray[i] = new Breakpt();
+ bbegin = new CArrayOfBreakpts(bbeginArray, 0);
+ bbegin.get().multi = kfirst.getPointer() - k.getPointer();
+ bbegin.get().value = kval;
+
+ bend = new CArrayOfBreakpts(bbegin);
+ kleft = new CArrayOfFloats(kfirst);
+ kright = new CArrayOfFloats(kfirst);
+
+ }
+
+ /**
+ * Perpares knotspec for transformation
+ */
+ public void select() {
+ // DONE
+ breakpoints();
+ knots();
+ factors();
+
+ preoffset = kleft.getPointer() - (inkbegin.getPointer() + order);
+ postwidth = ((bend.getPointer() - bbegin.getPointer()) * order);
+ prewidth = (outkend.getPointer() - outkbegin.getPointer()) - order;
+ postoffset = (bbegin.get().def > 1) ? (bbegin.get().def - 1) : 0;
+
+ }
+
+ /**
+ * Computes alpha factors for computing new control points
+ */
+ private void factors() {
+ // DONE
+ CArrayOfFloats mid = new CArrayOfFloats(outkend.getArray(), (outkend
+ .getPointer() - 1)
+ - order + bend.get().multi);
+
+ CArrayOfFloats fptr = null;
+ if (sbegin != null)
+ fptr = new CArrayOfFloats(sbegin);
+
+ for (CArrayOfBreakpts bpt = new CArrayOfBreakpts(bend); bpt
+ .getPointer() >= bbegin.getPointer(); bpt.mm()) {
+ mid.lessenPointerBy(bpt.get().multi);
+ int def = bpt.get().def - 1;
+ if (def < 0)
+ continue;
+ float kv = bpt.get().value;
+
+ CArrayOfFloats kf = new CArrayOfFloats(mid.getArray(), (mid
+ .getPointer() - def)
+ + (order - 1));
+ for (CArrayOfFloats kl = new CArrayOfFloats(kf.getArray(), kf
+ .getPointer()
+ + def); kl.getPointer() != kf.getPointer(); kl.mm()) {
+ CArrayOfFloats kh, kt;
+ for (kt = new CArrayOfFloats(kl), kh = new CArrayOfFloats(mid); kt
+ .getPointer() != kf.getPointer(); kh.mm(), kt.mm()) {
+ fptr.set((kv - kh.get()) / (kt.get() - kh.get()));
+ fptr.pp();
+ }
+ kl.set(kv);
+ }
+ }
+
+ }
+
+ /**
+ * Makes new knot vector
+ */
+ private void knots() {
+ // DONE
+ CArrayOfFloats inkpt = new CArrayOfFloats(kleft.getArray(), kleft
+ .getPointer()
+ - order);
+ CArrayOfFloats inkend = new CArrayOfFloats(kright.getArray(), kright
+ .getPointer()
+ + bend.get().def);
+
+ outkbegin = new CArrayOfFloats(new float[inkend.getPointer()
+ - inkpt.getPointer()], 0);
+ CArrayOfFloats outkpt;
+ for (outkpt = new CArrayOfFloats(outkbegin); inkpt.getPointer() != inkend
+ .getPointer(); inkpt.pp(), outkpt.pp()) {
+ outkpt.set(inkpt.get());
+ }
+ outkend = new CArrayOfFloats(outkpt);
+ }
+
+ /**
+ * Analyzes breakpoints
+ */
+ private void breakpoints() {
+ // DONE
+ CArrayOfBreakpts ubpt = new CArrayOfBreakpts(bbegin);
+ CArrayOfBreakpts ubend = new CArrayOfBreakpts(bend);
+ int nfactors = 0;
+
+ ubpt.get().value = ubend.get().value;
+ ubpt.get().multi = ubend.get().multi;
+
+ kleft = new CArrayOfFloats(kright);
+
+ for (; kright.getPointer() != klast.getPointer(); kright.pp()) {
+ if (Knotvector.identical(kright.get(), ubpt.get().value)) {
+ ubpt.get().multi++;
+ } else {
+ ubpt.get().def = order - ubpt.get().multi;
+ nfactors += (ubpt.get().def * (ubpt.get().def - 1)) / 2;
+ ubpt.pp();
+ ubpt.get().value = kright.get();
+ ubpt.get().multi = 1;
+ }
+ }
+ ubpt.get().def = order - ubpt.get().multi;
+ nfactors += (ubpt.get().def * (ubpt.get().def - 1)) / 2;
+
+ bend = new CArrayOfBreakpts(ubpt);
+
+ if (nfactors > 0) {
+ sbegin = new CArrayOfFloats(new float[nfactors], 0);
+ } else {
+ sbegin = null;
+ }
+
+ }
+
+ /**
+ * Copies control points
+ *
+ * @param _inpt
+ * input control points
+ * @param _outpt
+ * output control points
+ */
+ public void copy(CArrayOfFloats _inpt, CArrayOfFloats _outpt) {
+ CArrayOfFloats inpt = new CArrayOfFloats(_inpt);
+ CArrayOfFloats outpt = new CArrayOfFloats(_outpt);
+
+ inpt.raisePointerBy(preoffset);
+ if (next != null) {
+ for (CArrayOfFloats lpt = new CArrayOfFloats(outpt.getArray(),
+ outpt.getPointer() + prewidth); outpt.getPointer() != lpt
+ .getPointer(); outpt.raisePointerBy(poststride)) {
+ next.copy(inpt, outpt);
+ inpt.raisePointerBy(prestride);
+ }
+
+ } else {
+ for (CArrayOfFloats lpt = new CArrayOfFloats(outpt.getArray(),
+ outpt.getPointer() + prewidth); outpt.getPointer() != lpt
+ .getPointer(); outpt.raisePointerBy(poststride)) {
+ pt_io_copy(outpt, inpt);
+ inpt.raisePointerBy(prestride);
+ }
+ }
+
+ }
+
+ /**
+ * Copies one control point to other
+ *
+ * @param topt
+ * source control point
+ * @param frompt
+ * destination control point
+ */
+ private void pt_io_copy(CArrayOfFloats topt, CArrayOfFloats frompt) {
+ // DONE
+ switch (ncoords) {
+ case 4:
+ topt.setRelative(3, frompt.getRelative(3));
+ case 3:
+ topt.setRelative(2, frompt.getRelative(2));
+ case 2:
+ topt.setRelative(1, frompt.getRelative(1));
+ case 1:
+ topt.set(frompt.get());
+ break;
+ default:
+ // TODO break with copying in general case
+ // System.out.println("TODO knotspec.pt_io_copy");
+ break;
+ }
+
+ }
+
+ /**
+ * Inserts a knot
+ *
+ * @param _p
+ * inserted knot
+ */
+ public void transform(CArrayOfFloats _p) {
+ CArrayOfFloats p = new CArrayOfFloats(_p);
+ // DONE
+ if (next != null) {//surface code
+ if (this.equals(kspectotrans)) {
+ next.transform(p);
+ } else {
+ if (istransformed) {
+ p.raisePointerBy(postoffset);
+ for (CArrayOfFloats pend = new CArrayOfFloats(p.getArray(),
+ p.getPointer() + postwidth); p.getPointer() != pend
+ .getPointer(); p.raisePointerBy(poststride))
+ next.transform(p);
+
+ } else {
+ CArrayOfFloats pend = new CArrayOfFloats(p.getArray(), p
+ .getPointer()
+ + prewidth);
+ for (; p.getPointer() != pend.getPointer(); p
+ .raisePointerBy(poststride))
+ next.transform(p);
+ }
+ }
+
+ } else {//code for curve
+ if (this.equals(kspectotrans)) {
+ insert(p);
+ } else {
+ if (istransformed) {
+ p.raisePointerBy(postoffset);
+ for (CArrayOfFloats pend = new CArrayOfFloats(p.getArray(),
+ p.getPointer() + postwidth); p.getPointer() != pend
+ .getPointer(); p.raisePointerBy(poststride)) {
+ kspectotrans.insert(p);
+ }
+ } else {
+ CArrayOfFloats pend = new CArrayOfFloats(p.getArray(), p
+ .getPointer()
+ + prewidth);
+ for (; p.getPointer() != pend.getPointer(); p
+ .raisePointerBy(poststride))
+ kspectotrans.insert(p);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Inserts a knot and computes new control points
+ *
+ * @param p
+ * inserted knot
+ */
+ private void insert(CArrayOfFloats p) {
+ // DONE
+ CArrayOfFloats fptr = null;
+ if (sbegin != null)
+ fptr = new CArrayOfFloats(sbegin);
+ CArrayOfFloats srcpt = new CArrayOfFloats(p.getArray(), p.getPointer()
+ + prewidth - poststride);
+ // CArrayOfFloats srcpt = new CArrayOfFloats(p.getArray(), prewidth -
+ // poststride);
+ CArrayOfFloats dstpt = new CArrayOfFloats(p.getArray(), p.getPointer()
+ + postwidth + postoffset - poststride);
+ // CArrayOfFloats dstpt = new CArrayOfFloats(p.getArray(), postwidth +
+ // postoffset - poststride);
+ CArrayOfBreakpts bpt = new CArrayOfBreakpts(bend);
+
+ for (CArrayOfFloats pend = new CArrayOfFloats(srcpt.getArray(), srcpt
+ .getPointer()
+ - poststride * bpt.get().def); srcpt.getPointer() != pend
+ .getPointer(); pend.raisePointerBy(poststride)) {
+ CArrayOfFloats p1 = new CArrayOfFloats(srcpt);
+ for (CArrayOfFloats p2 = new CArrayOfFloats(srcpt.getArray(), srcpt
+ .getPointer()
+ - poststride); p2.getPointer() != pend.getPointer(); p1
+ .setPointer(p2.getPointer()), p2
+ .lessenPointerBy(poststride)) {
+ pt_oo_sum(p1, p1, p2, fptr.get(), 1.0 - fptr.get());
+ fptr.pp();
+ }
+ }
+ bpt.mm();
+ for (; bpt.getPointer() >= bbegin.getPointer(); bpt.mm()) {
+
+ for (int multi = bpt.get().multi; multi > 0; multi--) {
+ pt_oo_copy(dstpt, srcpt);
+ dstpt.lessenPointerBy(poststride);
+ srcpt.lessenPointerBy(poststride);
+ }
+ for (CArrayOfFloats pend = new CArrayOfFloats(srcpt.getArray(),
+ srcpt.getPointer() - poststride * bpt.get().def); srcpt
+ .getPointer() != pend.getPointer(); pend
+ .raisePointerBy(poststride), dstpt
+ .lessenPointerBy(poststride)) {
+ pt_oo_copy(dstpt, srcpt);
+ CArrayOfFloats p1 = new CArrayOfFloats(srcpt);
+
+ for (CArrayOfFloats p2 = new CArrayOfFloats(srcpt.getArray(),
+ srcpt.getPointer() - poststride); p2.getPointer() != pend
+ .getPointer(); p1.setPointer(p2.getPointer()), p2
+ .lessenPointerBy(poststride)) {
+ pt_oo_sum(p1, p1, p2, fptr.get(), 1.0 - fptr.get());
+ fptr.pp();
+ }
+ }
+ }
+ }
+
+ /**
+ * Copies one control point to another
+ *
+ * @param topt
+ * source ctrl point
+ * @param frompt
+ * distance ctrl point
+ */
+ private void pt_oo_copy(CArrayOfFloats topt, CArrayOfFloats frompt) {
+ // DONE
+ // this is a "trick" with case - "break" is omitted so it comes through all cases
+ switch (ncoords) {
+ case 4:
+ topt.setRelative(3, frompt.getRelative(3));
+ case 3:
+ topt.setRelative(2, frompt.getRelative(2));
+ case 2:
+ topt.setRelative(1, frompt.getRelative(1));
+ case 1:
+ topt.setRelative(0, frompt.getRelative(0));
+ break;
+ default:
+ // default uses memcpy but it is not needed (we probably won't have more than 4 coords)
+ // TODO not sure about it
+ break;
+ }
+
+ }
+
+ /**
+ * Computes new control point
+ *
+ * @param x
+ * first point
+ * @param y
+ * second point
+ * @param z
+ * third pont
+ * @param a
+ * alpha
+ * @param b
+ * 1 - alpha
+ */
+ private void pt_oo_sum(CArrayOfFloats x, CArrayOfFloats y,
+ CArrayOfFloats z, float a, double b) {
+ // DONE
+ switch (ncoords) {
+ case 4:
+ x.setRelative(3, (float) (a * y.getRelative(3) + b
+ * z.getRelative(3)));
+ case 3:
+ x.setRelative(2, (float) (a * y.getRelative(2) + b
+ * z.getRelative(2)));
+ case 2:
+ x.setRelative(1, (float) (a * y.getRelative(1) + b
+ * z.getRelative(1)));
+ case 1:
+ x.setRelative(0, (float) (a * y.getRelative(0) + b
+ * z.getRelative(0)));
+ break;
+ default:
+ //no need of default - see previous method and its case statement
+ // System.out.println("TODO pt_oo_sum default");
+ break;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Knotvector.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Knotvector.java
new file mode 100755
index 000000000..658a1cbda
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Knotvector.java
@@ -0,0 +1,179 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Knot vector used in curve specification
+ *
+ * @author Tomas Hrasky
+ *
+ */
+public class Knotvector {
+
+ /**
+ * Tolerance used when comparing knots - when difference is smaller, knots
+ * are considered equal
+ */
+ public static final float TOLERANCE = 1.0e-5f;
+
+ /**
+ * Maximum curve order
+ */
+ private static final int MAXORDER = 24;
+
+ /**
+ * Number of knots
+ */
+ int knotcount;
+
+ /**
+ * Number of control points' coordinates
+ */
+ int stride;
+
+ /**
+ * Curve order
+ */
+ int order;
+
+ /**
+ * Knots
+ */
+ float[] knotlist;
+
+ /**
+ * Makes new knotvector
+ *
+ * @param nknots
+ * number of knots
+ * @param stride
+ * number of ctrl points' corrdinates
+ * @param order
+ * curve order
+ * @param knot
+ * knots
+ */
+ public Knotvector(int nknots, int stride, int order, float[] knot) {
+ // DONE
+ init(nknots, stride, order, knot);
+ }
+
+ /**
+ * Initializes knotvector
+ *
+ * @param nknots
+ * number of knots
+ * @param stride
+ * number of ctrl points' corrdinates
+ * @param order
+ * curve order
+ * @param knot
+ * knots
+ */
+ public void init(int nknots, int stride, int order, float[] knot) {
+ // DONE
+ this.knotcount = nknots;
+ this.stride = stride;
+ this.order = order;
+ this.knotlist = new float[nknots];
+ for (int i = 0; i < nknots; i++) {
+ this.knotlist[i] = knot[i];
+ }
+
+ }
+
+ /**
+ * Validates knot vector parameters
+ *
+ * @return knot vector validity
+ */
+ public int validate() {
+ int kindex = knotcount - 1;
+ if (order < 1 || order > MAXORDER) {
+ return 1;
+ }
+ if (knotcount < 2 * order) {
+ return 2;
+ }
+ if (identical(knotlist[kindex - (order - 1)], knotlist[order - 1])) {
+ return 3;
+ }
+ for (int i = 0; i < kindex; i++) {
+ if (knotlist[i] > knotlist[i + 1])
+ return 4;
+ }
+ int multi = 1;
+ for (; kindex >= 1; kindex--) {
+ if (knotlist[kindex] - knotlist[kindex - 1] < TOLERANCE) {
+ multi++;
+ continue;
+ }
+ if (multi > order) {
+ return 5;
+ }
+ multi = 1;
+ }
+ if (multi > order) {
+ return 5;
+ }
+
+ return 0;
+ }
+
+ /**
+ * Show specified message
+ *
+ * @param msg
+ * message to be shown
+ */
+ public void show(String msg) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO knotvector.show");
+
+ }
+
+ /**
+ * Compares two knots for equality
+ *
+ * @param a
+ * first knot
+ * @param b
+ * second knot
+ * @return knots are/are not equal
+ */
+ public static boolean identical(float a, float b) {
+ return ((a - b) < TOLERANCE) ? true : false;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Mapdesc.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Mapdesc.java
new file mode 100755
index 000000000..568eddc51
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Mapdesc.java
@@ -0,0 +1,442 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class holding properties of OpenGL map
+ * @author Tomas Hrasky
+ *
+ */
+public class Mapdesc {
+
+ /**
+ * Maximum control point coords
+ */
+ private static final int MAXCOORDS = 5;
+
+ /**
+ * Next description in list
+ */
+ public Mapdesc next;
+
+ /**
+ * Is map rational
+ */
+ public int isrational;
+
+ /**
+ * Number of control point coords
+ */
+ public int ncoords;
+
+ /**
+ * Map type
+ */
+ private int type;
+
+ /**
+ * Number of homogenous coords
+ */
+ private int hcoords;
+
+ /**
+ * Number of inhomogenous coords
+ */
+ private int inhcoords;
+
+ /**
+ * Not used
+ */
+ private int mask;
+
+ /**
+ * Value of N_PIXEL_TOLERANCE property
+ */
+ private float pixel_tolerance;
+
+ /**
+ * Value of N_ERROR_TOLERANCE property
+ */
+ private float error_tolerance;
+
+ /**
+ * Value of N_BBOX_SUBDIVIDING property
+ */
+ private float bbox_subdividing;
+
+ /**
+ * Value of N_CULLING property
+ */
+ private float culling_method;
+
+ /**
+ * Value of N_SAMPLINGMETHOD property
+ */
+ private float sampling_method;
+
+ /**
+ * Value of N_CLAMPFACTOR property
+ */
+ float clampfactor;
+
+ /**
+ * Value of N_MINSAVINGS property
+ */
+ private float minsavings;
+
+ /**
+ * Steps in u direction
+ */
+ private float s_steps;
+
+ /**
+ * Steps in v direction
+ */
+ private float t_steps;
+
+ /**
+ * Maximal step
+ */
+ float maxrate;
+
+ /**
+ * Maximal u direction step
+ */
+ private float maxsrate;
+
+ /**
+ * Maximal v direction step
+ */
+ private float maxtrate;
+
+ /**
+ * Not used
+ */
+ private float[][] bmat;
+
+ /**
+ * Sampling matrix
+ */
+ private float[][] smat;
+
+ /**
+ * Not used
+ */
+ private float[][] cmat;
+
+ /**
+ * Not used
+ */
+ private float[] bboxsize;
+
+ /**
+ * Makes new mapdesc
+ * @param type map type
+ * @param rational is rational
+ * @param ncoords number of control points coords
+ * @param backend backend object
+ */
+ public Mapdesc(int type, int rational, int ncoords, Backend backend) {
+ // DONE
+ this.type = type;
+ this.isrational = rational;
+ this.ncoords = ncoords;
+ this.hcoords = ncoords + (isrational > 0 ? 0 : 1);
+ this.inhcoords = ncoords - (isrational > 0 ? 1 : 0);
+ this.mask = ((1 << (inhcoords * 2)) - 1);
+ next = null;
+
+ assert (hcoords <= MAXCOORDS);
+ assert (inhcoords >= 1);
+
+ pixel_tolerance = 1f;
+ error_tolerance = 1f;
+ bbox_subdividing = NurbsConsts.N_NOBBOXSUBDIVISION;
+ culling_method = NurbsConsts.N_NOCULLING;
+ sampling_method = NurbsConsts.N_NOSAMPLING;
+ clampfactor = NurbsConsts.N_NOCLAMPING;
+ minsavings = NurbsConsts.N_NOSAVINGSSUBDIVISION;
+ s_steps = 0f;
+ t_steps = 0f;
+
+ maxrate = (s_steps < 0) ? 0 : s_steps;
+ maxsrate = (s_steps < 0) ? 0 : s_steps;
+ maxtrate = (t_steps < 0) ? 0 : t_steps;
+ bmat = new float[MAXCOORDS][MAXCOORDS];
+ cmat = new float[MAXCOORDS][MAXCOORDS];
+ smat = new float[MAXCOORDS][MAXCOORDS];
+
+ identify(bmat);
+ identify(cmat);
+ identify(smat);
+ bboxsize = new float[MAXCOORDS];
+ for (int i = 0; i < inhcoords; i++)
+ bboxsize[i] = 1;
+ }
+
+ /**
+ * Make matrix identity matrix
+ * @param arr matrix
+ */
+ private void identify(float[][] arr) {
+ // DONE
+ for (int i = 0; i < MAXCOORDS; i++)
+ for (int j = 0; j < MAXCOORDS; j++)
+ arr[i][j] = 0;
+ for (int i = 0; i < MAXCOORDS; i++)
+ arr[i][i] = 1;
+
+ }
+
+ /**
+ * Tells whether tag is property tag
+ * @param tag property tag
+ * @return is/is not property
+ */
+ public boolean isProperty(int tag) {
+ boolean ret;
+ switch (tag) {
+ case NurbsConsts.N_PIXEL_TOLERANCE:
+ case NurbsConsts.N_ERROR_TOLERANCE:
+ case NurbsConsts.N_CULLING:
+ case NurbsConsts.N_BBOX_SUBDIVIDING:
+ case NurbsConsts.N_S_STEPS:
+ case NurbsConsts.N_T_STEPS:
+ case NurbsConsts.N_SAMPLINGMETHOD:
+ case NurbsConsts.N_CLAMPFACTOR:
+ case NurbsConsts.N_MINSAVINGS:
+ ret = true;
+ break;
+ default:
+ ret = false;
+ break;
+ }
+ return ret;
+ }
+
+ /**
+ * Returns number of control points' coords
+ * @return number of control points' coords
+ */
+ public int getNCoords() {
+ return ncoords;
+ }
+
+ /**
+ * Returns map type
+ * @return map type
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Tells whether map is range sampling
+ * @return is map range sampling
+ */
+ public boolean isRangeSampling() {
+ // DONE
+ return (isParametricDistanceSampling() || isPathLengthSampling()
+ || isSurfaceAreaSampling() || isObjectSpaceParaSampling() || isObjectSpacePathSampling());
+ }
+
+ /**
+ * Tells whether map is object space sampling
+ * @return is map object space sampling
+ */
+ private boolean isObjectSpacePathSampling() {
+ // DONE
+ return sampling_method == NurbsConsts.N_OBJECTSPACE_PATH;
+ }
+
+ /**
+ * Tells whether map is object space parasampling
+ * @return is map object space parasampling
+ */
+ private boolean isObjectSpaceParaSampling() {
+ // DONE
+ return sampling_method == NurbsConsts.N_OBJECTSPACE_PARA;
+ }
+
+ /**
+ * Tells whether map is area sampling surface
+ * @return is map area sampling surface
+ */
+ private boolean isSurfaceAreaSampling() {
+ // DONE
+ return sampling_method == NurbsConsts.N_SURFACEAREA;
+ }
+
+ /**
+ * Tells whether map is path length sampling
+ * @return is map path length sampling
+ */
+ boolean isPathLengthSampling() {
+ // DONE
+ return sampling_method == NurbsConsts.N_PATHLENGTH;
+ }
+
+ /**
+ * Tells whether map is parametric distance sampling
+ * @return is map parametric distance sampling
+ */
+ boolean isParametricDistanceSampling() {
+ // DONE
+ return sampling_method == NurbsConsts.N_PARAMETRICDISTANCE;
+ }
+
+ /**
+ * Tells whether map is culling
+ * @return is map culling
+ */
+ public boolean isCulling() {
+ // DONE
+ return culling_method != NurbsConsts.N_NOCULLING ? true : false;
+ }
+
+ /**
+ * Tells whether map is constantly sampling
+ * @return is map constant sampling
+ */
+ public boolean isConstantSampling() {
+ return (sampling_method == NurbsConsts.N_FIXEDRATE) ? true : false;
+ }
+
+ /**
+ * Tells whether map is domain sampling
+ * @return is map domain sampling
+ */
+ public boolean isDomainSampling() {
+ return (sampling_method == NurbsConsts.N_DOMAINDISTANCE) ? true : false;
+ }
+
+ /**
+ * Returns property of specified tag value
+ * @param tag property tag
+ * @return property value
+ */
+ public float getProperty(int tag) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO mapdesc.getproperty");
+ return 0;
+ }
+
+ /**
+ * Sets property with given tag
+ * @param tag property tag
+ * @param value desired value
+ */
+ public void setProperty(int tag, float value) {
+ // TODO Auto-generated method stub
+ switch (tag) {
+ case NurbsConsts.N_PIXEL_TOLERANCE:
+ pixel_tolerance = value;
+ break;
+ case NurbsConsts.N_ERROR_TOLERANCE:
+ error_tolerance = value;
+ break;
+ case NurbsConsts.N_CULLING:
+ culling_method = value;
+ break;
+ case NurbsConsts.N_BBOX_SUBDIVIDING:
+ if (value <= 0)
+ value = NurbsConsts.N_NOBBOXSUBDIVISION;
+ bbox_subdividing = value;
+ break;
+ case NurbsConsts.N_S_STEPS:
+ if (value < 0)
+ value = 0;
+ s_steps = value;
+ maxrate = value;
+ maxsrate = value;
+ break;
+ case NurbsConsts.N_T_STEPS:
+ if (value < 0)
+ value = 0;
+ t_steps = value;
+ maxtrate = value;
+ break;
+ case NurbsConsts.N_SAMPLINGMETHOD:
+ sampling_method = value;
+ break;
+ case NurbsConsts.N_CLAMPFACTOR:
+ if (value < 0)
+ value = 0;
+ clampfactor = value;
+ break;
+ case NurbsConsts.N_MINSAVINGS:
+ if (value <= 0)
+ value = NurbsConsts.N_NOSAVINGSSUBDIVISION;
+ minsavings = value;
+ break;
+ }
+ }
+
+ /**
+ * Samples curve
+ * @param pts control points
+ * @param order curve order
+ * @param stride number of control points' coordinates
+ * @param sp breakpoints
+ * @param outstride output number of control points' coordinates
+ */
+ public void xformSampling(CArrayOfFloats pts, int order, int stride,
+ float[] sp, int outstride) {
+ // DONE
+ xFormMat(smat, pts, order, stride, sp, outstride);
+ }
+
+ /**
+ * Empty method
+ * @param mat sampling matrix
+ * @param pts ontrol points
+ * @param order curve order
+ * @param stride number of control points' coordinates
+ * @param cp breakpoints
+ * @param outstride output number of control points' coordinates
+ */
+ private void xFormMat(float[][] mat, CArrayOfFloats pts, int order,
+ int stride, float[] cp, int outstride) {
+ // TODO Auto-generated method stub
+
+ // System.out.println("TODO mapdsc.xformmat ; change cp from float[] to carrayoffloats");
+
+ if (isrational > 0) {
+
+ } else {
+
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Maplist.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Maplist.java
new file mode 100755
index 000000000..b23a1f665
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Maplist.java
@@ -0,0 +1,122 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class holding list of Mapdescs
+ * @author Tomáš Hráský
+ *
+ */
+public class Maplist {
+ /**
+ * Head of linked list
+ */
+ private Mapdesc maps;
+
+ /**
+ * Backend class
+ */
+ private Backend backend;
+
+ /**
+ * Makes new Maplist
+ * @param backend Backend class
+ */
+ public Maplist(Backend backend) {
+ this.backend = backend;
+ }
+
+ /**
+ * Sets linked list beginning to null
+ */
+ public void initialize() {
+ // TODO mapdespool.clear ?
+ maps = null;
+ }
+
+ /**
+ * Defines new Mapdesc if it is not defined and appends it to linked list
+ * @param type map type
+ * @param rational is map rational
+ * @param ncoords number of coords
+ */
+ public void define(int type, int rational, int ncoords) {
+ // DONE
+ Mapdesc m = locate(type);
+ assert (m == null || (m.isrational == rational && m.ncoords == ncoords));
+ add(type, rational, ncoords);
+
+ }
+
+ /**
+ * Adds new Mapdesc to linked list
+ * @param type map type
+ * @param rational is map rational
+ * @param ncoords number of coords
+ */
+ private void add(int type, int rational, int ncoords) {
+ // DONE
+ Mapdesc map = new Mapdesc(type, rational, ncoords, backend);
+ if (maps == null) {
+ maps = map;
+ } else {
+ map.next = maps;
+ maps = map;
+ }
+ }
+
+ /**
+ * Tries to find Mapdesc in linked list
+ * @param type map type
+ * @return Mapdesc of type or null if there is no such map
+ */
+ public Mapdesc locate(int type) {
+ // DONE
+ Mapdesc m = null;
+ for (m = maps; m != null; m = m.next)
+ if (m.getType() == type)
+ break;
+ return m;
+ }
+
+ /**
+ * Alias for locate
+ * @param type maptype
+ * @return Mapdesc of type or null if there is no such map
+ */
+ public Mapdesc find(int type) {
+ return locate(type);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/NurbsConsts.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/NurbsConsts.java
new file mode 100755
index 000000000..ee7f3b31b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/NurbsConsts.java
@@ -0,0 +1,184 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class hodling NURBS constants as seen in OpenGL GLU documentation
+ * @author JOGL project
+ *
+ */
+public class NurbsConsts {
+ /*
+ * NURBS Properties - one set per map, each takes a single INREAL arg
+ */
+ public static final int N_SAMPLING_TOLERANCE = 1;
+
+ public static final int N_S_RATE = 6;
+
+ public static final int N_T_RATE = 7;
+
+ public static final int N_CLAMPFACTOR = 13;
+
+ public static final float N_NOCLAMPING = 0.0f;
+
+ public static final int N_MINSAVINGS = 14;
+
+ public static final float N_NOSAVINGSSUBDIVISION = 0.0f;
+
+ /*
+ * NURBS Properties - one set per map, each takes an enumerated value
+ */
+ public static final int N_CULLING = 2;
+
+ public static final float N_NOCULLING = 0.0f;
+
+ public static final float N_CULLINGON = 1.0f;
+
+ public static final int N_SAMPLINGMETHOD = 10;
+
+ public static final float N_NOSAMPLING = 0.0f;
+
+ public static final float N_FIXEDRATE = 3.0f;
+
+ public static final float N_DOMAINDISTANCE = 2.0f;
+
+ public static final float N_PARAMETRICDISTANCE = 5.0f;
+
+ public static final float N_PATHLENGTH = 6.0f;
+
+ public static final float N_SURFACEAREA = 7.0f;
+
+ public static final float N_OBJECTSPACE_PARA = 8.0f;
+
+ public static final float N_OBJECTSPACE_PATH = 9.0f;
+
+ public static final int N_BBOX_SUBDIVIDING = 17;
+
+ public static final float N_NOBBOXSUBDIVISION = 0.0f;
+
+ public static final float N_BBOXTIGHT = 1.0f;
+
+ public static final float N_BBOXROUND = 2.0f;
+
+ /*
+ * NURBS Rendering Properties - one set per renderer each takes an
+ * enumerated value
+ */
+ public static final int N_DISPLAY = 3;
+
+ public static final int N_FILL = 1;
+
+ public static final int N_OUTLINE_POLY = 2;
+
+ public static final int N_OUTLINE_TRI = 3;
+
+ public static final int N_OUTLINE_QUAD = 4;
+
+ public static final int N_OUTLINE_PATCH = 5;
+
+ public static final int N_OUTLINE_PARAM = 6;
+
+ public static final int N_OUTLINE_PARAM_S = 7;
+
+ public static final int N_OUTLINE_PARAM_ST = 8;
+
+ public static final int N_OUTLINE_SUBDIV = 9;
+
+ public static final int N_OUTLINE_SUBDIV_S = 10;
+
+ public static final int N_OUTLINE_SUBDIV_ST = 11;
+
+ public static final int N_ISOLINE_S = 12;
+
+ public static final int N_ERRORCHECKING = 4;
+
+ public static final int N_NOMSG = 0;
+
+ public static final int N_MSG = 1;
+
+ /* GL 4.0 propeties not defined above */
+
+ public static final int N_PIXEL_TOLERANCE = N_SAMPLING_TOLERANCE;
+
+ public static final int N_ERROR_TOLERANCE = 20;
+
+ public static final int N_SUBDIVISIONS = 5;
+
+ public static final int N_TILES = 8;
+
+ public static final int N_TMP1 = 9;
+
+ public static final int N_TMP2 = N_SAMPLINGMETHOD;
+
+ public static final int N_TMP3 = 11;
+
+ public static final int N_TMP4 = 12;
+
+ public static final int N_TMP5 = N_CLAMPFACTOR;
+
+ public static final int N_TMP6 = N_MINSAVINGS;
+
+ public static final int N_S_STEPS = N_S_RATE;
+
+ public static final int N_T_STEPS = N_T_RATE;
+
+ /*
+ * NURBS Rendering Properties - one set per map, each takes an INREAL matrix
+ * argument
+ */
+ public static final int N_CULLINGMATRIX = 1;
+
+ public static final int N_SAMPLINGMATRIX = 2;
+
+ public static final int N_BBOXMATRIX = 3;
+
+ /*
+ * NURBS Rendering Properties - one set per map, each takes an INREAL vector
+ * argument
+ */
+ public static final int N_BBOXSIZE = 4;
+
+ /* type argument for trimming curves */
+
+ public static final int N_P2D = 0x8;
+
+ public static final int N_P2DR = 0xd;
+
+ public static final int N_MESHLINE = 1;
+
+ public static final int N_MESHFILL = 0;
+
+ public static final int N_MESHPOINT = 2;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_curve.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_curve.java
new file mode 100755
index 000000000..900f8e56f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_curve.java
@@ -0,0 +1,63 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Struct holding curve links
+ * @author Tomáš Hráský
+ *
+ */
+public class O_curve {
+
+ /**
+ * Curve type
+ */
+ public int curvetype;
+
+ /**
+ * Next curve in linked list
+ */
+ public O_curve next;
+
+ /**
+ * Curve of picewiselinear type
+ */
+ public O_pwlcurve o_pwlcurve;
+
+ /**
+ * NURBS curve
+ */
+ public O_nurbscurve o_nurbscurve;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_nurbscurve.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_nurbscurve.java
new file mode 100755
index 000000000..81110813f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_nurbscurve.java
@@ -0,0 +1,80 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * NURBS curve object
+ * @author Tomáš Hráský
+ *
+ */
+public class O_nurbscurve {
+
+ /**
+ * List of bezier curves
+ */
+ public Quilt bezier_curves;
+
+ /**
+ * Curve type
+ */
+ public int type;
+
+ /**
+ * Was curve used ?
+ */
+ public boolean used;
+
+ /**
+ * Parent curve
+ */
+ public O_curve owner;
+
+ /**
+ * Next curve in list
+ */
+ public O_nurbscurve next;
+
+ /**
+ * Makes new O_nurbscurve
+ * @param realType type of curve
+ */
+ public O_nurbscurve(int realType) {
+ // DONE
+ this.type = realType;
+ this.owner = null;
+ this.next = null;
+ this.used = false;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_nurbssurface.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_nurbssurface.java
new file mode 100755
index 000000000..b598f525d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_nurbssurface.java
@@ -0,0 +1,79 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * NURBS surface object
+ * @author Tomáš Hráský
+ *
+ */
+public class O_nurbssurface {
+
+ /**
+ * List of bezier patches forming NURBS surface
+ */
+ public Quilt bezier_patches;
+
+ /**
+ * Was surface used
+ */
+ public boolean used;
+
+ /**
+ * Parent O_surface
+ */
+ public O_surface owner;
+
+ /**
+ * Next surface in list
+ */
+ public O_nurbssurface next;
+
+ /**
+ * Surface type
+ */
+ private int type;
+
+ /**
+ * Makes new O_nurbssurface of type
+ * @param type surface type
+ */
+ public O_nurbssurface(int type) {
+ this.type = type;
+ this.owner = null;
+ this.next = null;
+ this.used = false;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_pwlcurve.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_pwlcurve.java
new file mode 100755
index 000000000..e50f41d81
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_pwlcurve.java
@@ -0,0 +1,44 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Empty class
+ * @author Tomáš Hráský
+ *
+ */
+public class O_pwlcurve {
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_surface.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_surface.java
new file mode 100755
index 000000000..76ac79f0a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_surface.java
@@ -0,0 +1,52 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Surface object
+ * @author Tomáš Hráský
+ *
+ */
+public class O_surface {
+ /**
+ * NURBS surface
+ */
+ public O_nurbssurface o_nurbssurface;
+
+ /**
+ * Trims
+ */
+ public O_trim o_trim;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_trim.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_trim.java
new file mode 100755
index 000000000..17e5002df
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/O_trim.java
@@ -0,0 +1,44 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Empty class
+ * @author Tomáš Hráský
+ *
+ */
+public class O_trim {
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Patch.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Patch.java
new file mode 100755
index 000000000..d3066cc84
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Patch.java
@@ -0,0 +1,54 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Empty class
+ * @author Tomas Hrasky
+ *
+ */
+public class Patch {
+
+ /**
+ * Empty constructor
+ * @param q
+ * @param pta
+ * @param ptb
+ * @param patch
+ */
+ public Patch(Quilt q, float[] pta, float[] ptb, Patch patch) {
+ // System.out.println("TODO patch.constructor");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Patchlist.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Patchlist.java
new file mode 100755
index 000000000..8b439a02f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Patchlist.java
@@ -0,0 +1,145 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * List of patches
+ * @author Tomáš Hráský
+ *
+ */
+public class Patchlist {
+
+ /**
+ * Array of ranges
+ */
+ public Pspec[] pspec;
+
+ /**
+ * head of list of patches
+ */
+ private Patch patch;
+
+ /**
+ * Makes new list of patches
+ * @param quilts list of quilts
+ * @param pta low border
+ * @param ptb high border
+ */
+ public Patchlist(Quilt quilts, float[] pta, float[] ptb) {
+ // DONE
+ patch = null;
+
+ for (Quilt q = quilts; q != null; q = q.next)
+ patch = new Patch(q, pta, ptb, patch);
+ pspec[0] = new Pspec();
+ pspec[0].range[0] = pta[0];
+ pspec[0].range[1] = ptb[0];
+ pspec[0].range[2] = ptb[0] - pta[0];
+ pspec[1] = new Pspec();
+ pspec[1].range[0] = pta[1];
+ pspec[1].range[1] = ptb[1];
+ pspec[1].range[2] = ptb[1] - pta[1];
+
+ }
+
+ /**
+ * Empty constructor
+ * @param patchlist
+ * @param param
+ * @param mid
+ */
+ public Patchlist(Patchlist patchlist, int param, float mid) {
+ // TODO Auto-generated constructor stub
+ // System.out.println("TODO patchlist.konstruktor 2");
+ }
+
+ /**
+ * Empty method
+ * @return 0
+ */
+ public int cullCheck() {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO patchlist.cullcheck");
+ return 0;
+ }
+
+ /**
+ * Empty method
+ */
+ public void getstepsize() {
+ // System.out.println("TODO patchlist.getsptepsize");
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * Empty method
+ * @return false
+ */
+ public boolean needsSamplingSubdivision() {
+ // TODO Auto-generated method stub
+ // System.out.println("patchlist.needsSamplingSubdivision");
+ return false;
+ }
+
+ /**
+ * Empty method
+ * @param i
+ * @return false
+ */
+ public boolean needsSubdivision(int i) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO patchlist.needsSubdivision");
+ return false;
+ }
+
+ /**
+ * Empty method
+ * @return false
+ */
+ public boolean needsNonSamplingSubdivision() {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO patchlist.needsNonSamplingSubdivision");
+ return false;
+ }
+
+ /**
+ * Empty method
+ */
+ public void bbox() {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO patchlist.bbox");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Property.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Property.java
new file mode 100755
index 000000000..b486a0ead
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Property.java
@@ -0,0 +1,75 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class representing property
+ *
+ * @author Tomas Hrasky
+ *
+ */
+public class Property {
+
+ /**
+ * Property type
+ */
+ public int type;
+
+ /**
+ * Property id
+ */
+ public int tag;
+
+ /**
+ * Property value
+ */
+ public float value;
+
+ /**
+ * Makes new property with given parameters
+ *
+ * @param type
+ * property type
+ * @param tag
+ * property id
+ * @param value
+ * property value
+ */
+ public Property(int type, int tag, float value) {
+ this.type = type;
+ this.tag = tag;
+ this.value = value;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Pspec.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Pspec.java
new file mode 100755
index 000000000..1e60ed335
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Pspec.java
@@ -0,0 +1,47 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class holding range
+ * @author Tomáš Hráský
+ *
+ */
+public class Pspec {
+ /**
+ * Range
+ */
+ public float[] range;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/PwlArc.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/PwlArc.java
new file mode 100755
index 000000000..0c9eca91e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/PwlArc.java
@@ -0,0 +1,71 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Picewiselinar trimming arc
+ * @author Tomáš Hráský
+ *
+ */
+public class PwlArc {
+
+ /**
+ * Number of points
+ */
+ private int npts;
+
+ /**
+ * Vertexes
+ */
+ public TrimVertex[] pts;
+
+ /**
+ * Arc type
+ */
+ private int type;
+
+ /**
+ * Makes new trimming arc
+ * @param i num ber of vertexes
+ * @param p trimming vertexes array
+ */
+ public PwlArc(int i, TrimVertex[] p) {
+ // DONE
+ this.npts = i;
+ this.pts = p;
+ type = NurbsConsts.N_P2D;
+
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Quilt.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Quilt.java
new file mode 100755
index 000000000..03e809d23
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Quilt.java
@@ -0,0 +1,282 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class for converting NURBS curves and surfaces to list of bezier arcs or patches repectively
+ * @author Tomáš Hráský
+ *
+ */
+public class Quilt {
+ /**
+ * Maximum quilt dimension
+ */
+ private static final int MAXDIM = 2;
+
+ /**
+ * List of map descriptions
+ */
+ Mapdesc mapdesc;
+
+ /**
+ * Array of quiltspecs pointer
+ */
+ public CArrayOfQuiltspecs qspec;
+
+ /**
+ * End array of quilt specs pointer
+ */
+ public CArrayOfQuiltspecs eqspec;
+
+ /**
+ * Control points
+ */
+ public CArrayOfFloats cpts;
+
+ /**
+ * Next quilt in list
+ */
+ public Quilt next;
+
+ /**
+ * Makes new quilt with mapdesc
+ * @param mapdesc map description
+ */
+ public Quilt(Mapdesc mapdesc) {
+ // DONE
+ this.mapdesc = mapdesc;
+ Quiltspec[] tmpquilts = new Quiltspec[MAXDIM];
+ for (int i = 0; i < tmpquilts.length; i++)
+ tmpquilts[i] = new Quiltspec();
+ this.qspec = new CArrayOfQuiltspecs(tmpquilts);
+
+ }
+
+ /**
+ * Converts NURBS surface to bezier patches
+ * @param sknotvector knots in u direction
+ * @param tknotvector knots in v direction
+ * @param ctrlarr control points
+ * @param coords control points coords
+ */
+ public void toBezier(Knotvector sknotvector, Knotvector tknotvector,
+ CArrayOfFloats ctrlarr, int coords) {
+ Splinespec spline = new Splinespec(2);
+ spline.kspecinit(sknotvector, tknotvector);
+ spline.select();
+ spline.layout(coords);
+ spline.setupquilt(this);
+ spline.copy(ctrlarr);
+ spline.transform();
+ }
+
+ /**
+ * Converts NURBS curve to list of bezier curves
+ * @param knots knot vector
+ * @param ctlarray control points
+ * @param ncoords number of coordinates
+ */
+ public void toBezier(Knotvector knots, CArrayOfFloats ctlarray, int ncoords) {
+ // DONE
+ Splinespec spline = new Splinespec(1);
+ spline.kspecinit(knots);
+ spline.select();
+ spline.layout(ncoords);
+ spline.setupquilt(this);
+ spline.copy(ctlarray);
+ spline.transform();
+ }
+
+ /**
+ * Walks thru all arcs/patches
+ * @param pta low border
+ * @param ptb high border
+ * @param backend Backend
+ */
+ public void downloadAll(float[] pta, float[] ptb, Backend backend) {
+ // DONE
+ for (Quilt m = this; m != null; m = m.next) {
+ m.select(pta, ptb);
+ m.download(backend);
+ }
+
+ }
+
+ /**
+ * Renders arcs/patches
+ * @param backend Backend for rendering
+ */
+ private void download(Backend backend) {
+ // DONE
+ if (getDimension() == 2) {
+
+ CArrayOfFloats ps = new CArrayOfFloats(cpts);
+ ps.raisePointerBy(qspec.get(0).offset);
+ ps.raisePointerBy(qspec.get(1).offset);
+ ps.raisePointerBy(qspec.get(0).index * qspec.get(0).order
+ * qspec.get(0).stride);
+ ps.raisePointerBy(qspec.get(1).index * qspec.get(1).order
+ * qspec.get(1).stride);
+
+ backend.surfpts(mapdesc.getType(), ps, qspec.get(0).stride, qspec
+ .get(1).stride, qspec.get(0).order, qspec.get(1).order,
+ qspec.get(0).breakpoints[qspec.get(0).index],
+ qspec.get(0).breakpoints[qspec.get(0).index + 1], qspec
+ .get(1).breakpoints[qspec.get(1).index], qspec
+ .get(1).breakpoints[qspec.get(1).index + 1]);
+
+ } else {// code for curves
+ // CArrayOfFloats ps=new CArrayOfFloats(cpts);
+ CArrayOfFloats ps = new CArrayOfFloats(cpts.getArray(), 0);
+ ps.raisePointerBy(qspec.get(0).offset);
+ ps.raisePointerBy(qspec.get(0).index * qspec.get(0).order
+ * qspec.get(0).stride);
+ backend.curvpts(mapdesc.getType(), ps, qspec.get(0).stride, qspec
+ .get(0).order,
+ qspec.get(0).breakpoints[qspec.get(0).index],
+ qspec.get(0).breakpoints[qspec.get(0).index + 1]);
+ }
+
+ }
+
+ /**
+ * Returns quilt dimension
+ * @return quilt dimesion
+ */
+ private int getDimension() {
+ // DONE
+ return eqspec.getPointer() - qspec.getPointer();
+ }
+
+ /**
+ * Finds Quiltspec.index
+ * @param pta range
+ * @param ptb range
+ */
+ private void select(float[] pta, float[] ptb) {
+ // DONE
+ int dim = eqspec.getPointer() - qspec.getPointer();
+ int i, j;
+ for (i = 0; i < dim; i++) {
+ for (j = qspec.get(i).width - 1; j >= 0; j--)
+ if (qspec.get(i).breakpoints[j] <= pta[i]
+ && ptb[i] <= qspec.get(i).breakpoints[j + 1])
+ break;
+ assert (j != -1);
+ qspec.get(i).index = j;
+ }
+ }
+
+ /**
+ * Find range according to breakpoints
+ * @param from low param
+ * @param to high param
+ * @param bpts breakpoints
+ */
+ public void getRange(float[] from, float[] to, Flist bpts) {
+ // DONE
+ getRange(from, to, 0, bpts);
+
+ }
+
+ /**
+ * Find range according to breakpoints
+ * @param from low param
+ * @param to high param
+ * @param i from/to array index
+ * @param list breakpoints
+ */
+ private void getRange(float[] from, float[] to, int i, Flist list) {
+ // DONE
+ Quilt maps = this;
+ from[i] = maps.qspec.get(i).breakpoints[0];
+ to[i] = maps.qspec.get(i).breakpoints[maps.qspec.get(i).width];
+ int maxpts = 0;
+ Quilt m;
+ for (m = maps; m != null; m = m.next) {
+ if (m.qspec.get(i).breakpoints[0] > from[i])
+ from[i] = m.qspec.get(i).breakpoints[0];
+ if (m.qspec.get(i).breakpoints[m.qspec.get(i).width] < to[i])
+ to[i] = m.qspec.get(i).breakpoints[m.qspec.get(i).width];
+ maxpts += m.qspec.get(i).width + 1;
+ }
+ list.grow(maxpts);
+ for (m = maps; m != null; m = m.next) {
+ for (int j = 0; j <= m.qspec.get(i).width; j++) {
+ list.add(m.qspec.get(i).breakpoints[j]);
+ }
+ }
+ list.filter();
+ list.taper(from[i], to[i]);
+ }
+
+ /**
+ * Is this quilt culled
+ * @return 0 or Subdivider.CULL_ACCEPT
+ */
+ public int isCulled() {
+ if (mapdesc.isCulling()) {
+ // System.out.println("TODO quilt.isculled mapdesc.isculling");
+ return 0;
+ } else {
+ return Subdivider.CULL_ACCEPT;
+ }
+ }
+
+ /**
+ * Finds range for surface
+ * @param from low param
+ * @param to high param
+ * @param slist u direction breakpoints
+ * @param tlist v direction breakpoints
+ */
+ public void getRange(float[] from, float[] to, Flist slist, Flist tlist) {
+ // DONE
+ getRange(from, to, 0, slist);
+ getRange(from, to, 1, tlist);
+
+ }
+
+ /**
+ * Empty method
+ * @param sbrkpts
+ * @param tbrkpts
+ * @param rate
+ */
+ public void findRates(Flist sbrkpts, Flist tbrkpts, float[] rate) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO quilt.findrates");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Quiltspec.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Quiltspec.java
new file mode 100755
index 000000000..6c8e55e06
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Quiltspec.java
@@ -0,0 +1,85 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Quilt definition
+ * @author Tomas Hrasky
+ *
+ */
+public class Quiltspec {
+
+ /**
+ * Stride between control points
+ */
+ public int stride;
+
+ /**
+ * Quilt width in breakpoints
+ */
+ public int width;
+
+ /**
+ * Quilt order
+ */
+ public int order;
+
+ /**
+ * Start offset
+ */
+ public int offset;
+
+ /**
+ * Breakpoint index
+ */
+ public int index;
+
+ /**
+ * Boundary
+ */
+ public int[] bdry;
+
+ /**
+ * Breakpoints
+ */
+ public float[] breakpoints;
+
+ /**
+ * Makes new quiltspec
+ */
+ public Quiltspec() {
+ this.bdry = new int[2];
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/README.txt b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/README.txt
new file mode 100755
index 000000000..89630c71e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/README.txt
@@ -0,0 +1,59 @@
+Unimplemented functionality
+ - tesselation and callbacks
+ - trimming
+ - setting NURBS properties (-> sampling etc.)
+Differences from C++ source
+ - no pooling
+ - pointers to arrays are replaced by CArrayOf... classes and their methods
+Unimplemented or incomplete "calltree top" methods (according to glu.def in Mesa 6.5)
+ gluBeginTrim
+ gluDeleteNurbsRenderer - won't be needed
+ gluEndTrim
+ gluGetNurbsProperty
+ gluLoadSamplingMatrices
+ gluNurbsCallback
+ gluNurbsCallbackData
+ gluNurbsCallbackDataEXT
+ gluNurbsCurve - TODO type switch
+ gluNurbsProperty
+ gluPwlCurve
+ gluQuadricCallback - not a NURBS method
+As of files
+ - Arc[ST]dirSorter.java - unimplemented (part of tesselation)
+ - Backend.java:194 - wireframe quads - part of tesselation/callback
+ - Curve.java:141-204 - culling
+ - DisplayList.java:57 - append to DL - not sure whether it will be needed
+ - GLUnurbs.java :443,484 - error values
+ :445 - trimming
+ :512 - error handling (callback)
+ :530 - loadGLmatrices
+ :786 - nuid - nurbs object id - won't be needed I think
+ :803 - end trim
+ - GLUwNURBS.java:68,176 - NUBRS properties
+ - Knotspec.java :371 - copying in general case (more than 4 coords)
+ :517 - copying with more than 4 coords
+ :556 - pt_oo_sum default
+ - Knotvector.java:165 - show method (probably debugging)
+ - Mapdesc.java :354 - get property
+ :435 - xFormMat - change param cp to CArrayOfFloats; probably sampling functionality
+ - Maplist.java:68 - clear ?
+ - OpenGLCurveEvaluator.java :132 - tess./callback code
+ :168 - mapgrid1f
+ :190 - tess./callback code (output triangles)
+ - OpenGLSurfaceEvaluator.java :77 . tess./callback code
+ :81 - glGetIntegerValue
+ :114 - tess./callback code
+ :117 - Level of detail
+ :144,161,201 - tess./callback code - output triangles
+ - Patch.java:55 - constructor stuff ?
+ - Patchlist.java:55 - constructor stuff ?
+ :97 - cull check
+ :105 - step size
+ :115 - need of sampling subdivision
+ :126 - need of subdivision
+ :137 - need of non sampling subd.
+ :146 - bbox (??)
+ -Quilt.java :254 - culling
+ :282 - rates
+ -Subdivider.java - all TODOs - it's stuff about trimming probably
+ :545 - jumpbuffer - not sure purpose it exactly served in original source
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Renderhints.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Renderhints.java
new file mode 100755
index 000000000..d1a23fbab
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Renderhints.java
@@ -0,0 +1,128 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class holding rendering params
+ * @author Tomas Hrasky
+ *
+ */
+public class Renderhints {
+
+ /**
+ * Check for errors
+ */
+ public int errorchecking;
+
+ /**
+ * Maximum subdivisions
+ */
+ public int maxsubdivisions;
+
+ /**
+ * Number of subdivisions
+ */
+ private int subdivisions;
+
+ /**
+ * Display method
+ */
+ int display_method;
+
+ /**
+ * Output triangles
+ */
+ int wiretris;
+
+ /**
+ * Output quads
+ */
+ int wirequads;
+
+ /**
+ * Makes new Renderinghints
+ */
+ public Renderhints() {
+ display_method = NurbsConsts.N_FILL;
+ errorchecking = NurbsConsts.N_MSG;
+ subdivisions = 6;
+ // tmp1=0;
+ }
+
+ /**
+ * Set property value
+ * @param prop property
+ */
+ public void setProperty(Property prop) {
+ switch (prop.type) {
+ case NurbsConsts.N_DISPLAY:
+ display_method = (int) prop.value;
+ break;
+ case NurbsConsts.N_ERRORCHECKING:
+ errorchecking = (int) prop.value;
+ break;
+ case NurbsConsts.N_SUBDIVISIONS:
+ subdivisions = (int) prop.value;
+ break;
+ default:
+ // abort - end program
+ break;
+ }
+ }
+
+ /**
+ * Initialization
+ */
+ public void init() {
+ // DONE
+ maxsubdivisions = subdivisions;
+ if (maxsubdivisions < 0)
+ maxsubdivisions = 0;
+
+ if (display_method == NurbsConsts.N_FILL) {
+ wiretris = 0;
+ wirequads = 0;
+ } else if (display_method == NurbsConsts.N_OUTLINE_TRI) {
+ wiretris = 1;
+ wirequads = 0;
+ } else if (display_method == NurbsConsts.N_OUTLINE_QUAD) {
+ wiretris = 0;
+ wirequads = 1;
+ } else {
+ wiretris = 1;
+ wirequads = 1;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Splinespec.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Splinespec.java
new file mode 100755
index 000000000..487b47f2d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Splinespec.java
@@ -0,0 +1,204 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * NURBS definition
+ * @author Tomas Hrasky
+ *
+ */
+public class Splinespec {
+
+ /**
+ * Dimension
+ */
+ private int dim;
+
+ /**
+ * Knot vector specs
+ */
+ private Knotspec kspec;
+
+ /**
+ * Control points after conversion
+ */
+ private CArrayOfFloats outcpts;
+
+ /**
+ * Makes new Splinespec with given dimension
+ * @param i dimension
+ */
+ public Splinespec(int i) {
+ // DONE
+ this.dim = i;
+ }
+
+ /**
+ * Initializes knotspec according to knotvector
+ * @param knotvector basic knotvector
+ */
+ public void kspecinit(Knotvector knotvector) {
+ // DONE
+ this.kspec = new Knotspec();
+ kspec.inkbegin = new CArrayOfFloats(knotvector.knotlist, 0);
+ kspec.inkend = new CArrayOfFloats(knotvector.knotlist,
+ knotvector.knotcount);
+ kspec.prestride = knotvector.stride;
+ kspec.order = knotvector.order;
+ kspec.next = null;
+ }
+
+ /**
+ * Initializes knotspec according to knotvector - SURFACE
+ * @param sknotvector knotvector in u dir
+ * @param tknotvector knotvector in v dir
+ */
+ public void kspecinit(Knotvector sknotvector, Knotvector tknotvector) {
+ // DONE
+ this.kspec = new Knotspec();
+ Knotspec tkspec = new Knotspec();
+
+ kspec.inkbegin = new CArrayOfFloats(sknotvector.knotlist, 0);
+ kspec.inkend = new CArrayOfFloats(sknotvector.knotlist,
+ sknotvector.knotcount);
+ kspec.prestride = sknotvector.stride;
+ kspec.order = sknotvector.order;
+ kspec.next = tkspec;
+
+ tkspec.inkbegin = new CArrayOfFloats(tknotvector.knotlist, 0);
+ tkspec.inkend = new CArrayOfFloats(tknotvector.knotlist,
+ tknotvector.knotcount);
+ tkspec.prestride = tknotvector.stride;
+ tkspec.order = tknotvector.order;
+ tkspec.next = null;
+ }
+
+ /**
+ * Preselect and select knotspecs
+ */
+ public void select() {
+ // DONE
+ for (Knotspec knotspec = kspec; knotspec != null; knotspec = knotspec.next) {
+ knotspec.preselect();
+ knotspec.select();
+ }
+
+ }
+
+ /**
+ * Prepares for conversion
+ * @param ncoords number of coords
+ */
+ public void layout(int ncoords) {
+ // DONE
+ int stride = ncoords;
+ for (Knotspec knotspec = kspec; knotspec != null; knotspec = knotspec.next) {
+ knotspec.poststride = stride;
+ stride *= (knotspec.bend.getPointer() - knotspec.bbegin
+ .getPointer())
+ * knotspec.order + knotspec.postoffset;
+ knotspec.preoffset *= knotspec.prestride;
+ knotspec.prewidth *= knotspec.poststride;
+ knotspec.postwidth *= knotspec.poststride;
+ knotspec.postoffset *= knotspec.poststride;
+ knotspec.ncoords = ncoords;
+ }
+ outcpts = new CArrayOfFloats(new float[stride]);
+
+ }
+
+ /**
+ * Prepares quilt for conversion
+ * @param quilt quilt to work with
+ */
+ public void setupquilt(Quilt quilt) {
+ // DONE
+ CArrayOfQuiltspecs qspec = new CArrayOfQuiltspecs(quilt.qspec);
+ quilt.eqspec = new CArrayOfQuiltspecs(qspec.getArray(), dim);
+ for (Knotspec knotspec = kspec; knotspec != null;) {
+ qspec.get().stride = knotspec.poststride;
+ qspec.get().width = knotspec.bend.getPointer()
+ - knotspec.bbegin.getPointer();
+ qspec.get().order = knotspec.order;
+ qspec.get().offset = knotspec.postoffset;
+ qspec.get().index = 0;
+ qspec.get().bdry[0] = (knotspec.kleft.getPointer() == knotspec.kfirst
+ .getPointer()) ? 1 : 0;
+ qspec.get().bdry[1] = (knotspec.kright.getPointer() == knotspec.klast
+ .getPointer()) ? 1 : 0;
+ qspec.get().breakpoints = new float[qspec.get().width + 1];
+ CArrayOfFloats k = new CArrayOfFloats(qspec.get().breakpoints, 0);
+ for (CArrayOfBreakpts bk = new CArrayOfBreakpts(knotspec.bbegin); bk
+ .getPointer() <= knotspec.bend.getPointer(); bk.pp()) {
+ k.set(bk.get().value);
+ k.pp();
+ }
+ knotspec = knotspec.next;
+ if (knotspec != null)
+ qspec.pp();
+ }
+ quilt.cpts = new CArrayOfFloats(outcpts);
+ quilt.next = null;
+ }
+
+ /**
+ * Copies array of control points to output array
+ * @param ctlarray control points array
+ */
+ public void copy(CArrayOfFloats ctlarray) {
+ // DONE
+ kspec.copy(ctlarray, outcpts);
+
+ }
+
+ /**
+ * Transforms knotspecs - conversion
+ */
+ public void transform() {
+ // DONE
+ Knotspec knotspec;
+ outcpts.setPointer(0);
+ for (knotspec = kspec; knotspec != null; knotspec = knotspec.next)
+ knotspec.istransformed = false;
+
+ for (knotspec = kspec; knotspec != null; knotspec = knotspec.next) {
+ for (Knotspec kspec2 = kspec; kspec2 != null; kspec2 = kspec2.next)
+ kspec2.kspectotrans = knotspec;
+ kspec.transform(outcpts);
+ knotspec.istransformed = true;
+ }
+
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Subdivider.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Subdivider.java
new file mode 100755
index 000000000..99c1b740b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/Subdivider.java
@@ -0,0 +1,1167 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class working with curves and surfaces
+ * @author Tomas Hrasky
+ *
+ */
+public class Subdivider {
+ /**
+ * Cull type
+ */
+ public static final int CULL_TRIVIAL_REJECT = 0;
+
+ /**
+ * Cull type
+ */
+ public static final int CULL_ACCEPT = 1;
+
+ /**
+ * Maximum trimming arcs
+ */
+ private static final int MAXARCS = 10;
+
+ /**
+ * Linked list of Quilts
+ */
+ Quilt qlist;
+
+ /**
+ * Object holding rendering honts information
+ */
+ private Renderhints renderhints;
+
+ /**
+ * Backend object
+ */
+ private Backend backend;
+
+ /**
+ * Number of subdivisions
+ */
+ private int subdivisions;
+
+ /**
+ * U step when using domain distance sampling
+ */
+ private float domain_distance_u_rate;
+
+ /**
+ * Use domain distance sampling
+ */
+ private int is_domain_distance_sampling;
+
+ /**
+ * Initial class holding trimming arcs
+ */
+ private Bin initialbin;
+
+ /**
+ * Not used
+ */
+ private boolean showDegenerate;
+
+ /**
+ * Is triming arc type bezier arc
+ */
+ private boolean isArcTypeBezier;
+
+ /**
+ * Breakpoints in v direction
+ */
+ private Flist tpbrkpts;
+
+ /**
+ * Breakpoints in u direction
+ */
+ private Flist spbrkpts;
+
+ /**
+ * Unused
+ */
+ private int s_index;
+
+ /**
+ * Head of linked list of trimming arcs
+ */
+ private Arc pjarc;
+
+ /**
+ * Class tesselating trimming arcs
+ */
+ private ArcTesselator arctesselator;
+
+ /**
+ * Unused
+ */
+ private int t_index;
+
+ /**
+ * Breakpoints
+ */
+ private Flist smbrkpts;
+
+ /**
+ * Not used
+ */
+ private float[] stepsizes;
+
+ /**
+ * Domain distance in V direction
+ */
+ private float domain_distance_v_rate;
+
+ /**
+ * Initializes quilt list
+ */
+ public void beginQuilts(Backend backend) {
+ // DONE
+ qlist = null;
+ renderhints = new Renderhints();
+ this.backend = backend;
+
+ initialbin = new Bin();
+ arctesselator = new ArcTesselator();
+ }
+
+ /**
+ * Adds quilt to linked list
+ * @param quilt added quilt
+ */
+ public void addQuilt(Quilt quilt) {
+ // DONE
+ if (qlist == null)
+ qlist = quilt;
+ else {
+ quilt.next = qlist;
+ qlist = quilt;
+ }
+
+ }
+
+ /**
+ * Empty method
+ */
+ public void endQuilts() {
+ // DONE
+ }
+
+ /**
+ * Draws a surface
+ */
+ public void drawSurfaces() {
+ renderhints.init();
+
+ if (qlist == null) {
+ // System.out.println("qlist is null");
+ return;
+ }
+
+ for (Quilt q = qlist; q != null; q = q.next) {
+ if (q.isCulled() == CULL_TRIVIAL_REJECT) {
+ freejarcs(initialbin);
+ return;
+ }
+ }
+
+ float[] from = new float[2];
+ float[] to = new float[2];
+
+ spbrkpts = new Flist();
+ tpbrkpts = new Flist();
+ qlist.getRange(from, to, spbrkpts, tpbrkpts);
+
+ boolean optimize = (is_domain_distance_sampling > 0 && (renderhints.display_method != NurbsConsts.N_OUTLINE_PATCH));
+
+ // TODO decide whether to optimize (when there is gluNurbsProperty implemented)
+ optimize = true;
+
+ if (!initialbin.isnonempty()) {
+ if (!optimize) {
+ makeBorderTrim(from, to);
+ }
+ } else {
+ float[] rate = new float[2];
+ qlist.findRates(spbrkpts, tpbrkpts, rate);
+ // System.out.println("subdivider.drawsurfaces decompose");
+ }
+
+ backend.bgnsurf(renderhints.wiretris, renderhints.wirequads);
+
+ // TODO partition test
+
+ if (!initialbin.isnonempty() && optimize) {
+
+ int i, j;
+ int num_u_steps;
+ int num_v_steps;
+ for (i = spbrkpts.start; i < spbrkpts.end - 1; i++) {
+ for (j = tpbrkpts.start; j < tpbrkpts.end - 1; j++) {
+ float[] pta = new float[2];
+ float[] ptb = new float[2];
+
+ pta[0] = spbrkpts.pts[i];
+ ptb[0] = spbrkpts.pts[i + 1];
+ pta[1] = tpbrkpts.pts[j];
+ ptb[1] = tpbrkpts.pts[j + 1];
+ qlist.downloadAll(pta, ptb, backend);
+
+ num_u_steps = (int) (domain_distance_u_rate * (ptb[0] - pta[0]));
+ num_v_steps = (int) (domain_distance_v_rate * (ptb[1] - pta[1]));
+
+ if (num_u_steps <= 0)
+ num_u_steps = 1;
+ if (num_v_steps <= 0)
+ num_v_steps = 1;
+
+ backend.surfgrid(pta[0], ptb[0], num_u_steps, ptb[1],
+ pta[1], num_v_steps);
+ backend.surfmesh(0, 0, num_u_steps, num_v_steps);
+
+ }
+ }
+
+ } else
+
+ subdivideInS(initialbin);
+
+ backend.endsurf();
+ }
+
+ /**
+ * Empty method
+ * @param initialbin2
+ */
+ private void freejarcs(Bin initialbin2) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.freejarcs");
+ }
+
+ /**
+ * Subdivide in U direction
+ * @param source Trimming arcs source
+ */
+ private void subdivideInS(Bin source) {
+ // DONE
+ if (renderhints.display_method == NurbsConsts.N_OUTLINE_PARAM) {
+ outline(source);
+ freejarcs(source);
+ } else {
+ setArcTypeBezier();
+ setNonDegenerate();
+ splitInS(source, spbrkpts.start, spbrkpts.end);
+ }
+
+ }
+
+ /**
+ * Split in U direction
+ * @param source Trimming arcs source
+ * @param start breakpoints start
+ * @param end breakpoints end
+ */
+ private void splitInS(Bin source, int start, int end) {
+ // DONE
+ if (source.isnonempty()) {
+ if (start != end) {
+ int i = start + (end - start) / 2;
+ Bin left = new Bin();
+ Bin right = new Bin();
+
+ split(source, left, right, 0, spbrkpts.pts[i]);
+ splitInS(left, start, i);
+ splitInS(right, i + 1, end);
+ } else {
+ if (start == spbrkpts.start || start == spbrkpts.end) {
+ freejarcs(source);
+ } else if (renderhints.display_method == NurbsConsts.N_OUTLINE_PARAM_S) {
+ outline(source);
+ freejarcs(source);
+ } else {
+ setArcTypeBezier();
+ setNonDegenerate();
+ s_index = start;
+ splitInT(source, tpbrkpts.start, tpbrkpts.end);
+ }
+ }
+ } else{
+ // System.out.println("Source is empty - subdivider.splitins");
+ }
+ }
+
+ /**
+ * Split in V direction
+ * @param source
+ * @param start
+ * @param end
+ */
+ private void splitInT(Bin source, int start, int end) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.splitint");
+
+ if (source.isnonempty()) {
+ if (start != end) {
+ int i = start + (end - start) / 2;
+ Bin left = new Bin();
+ Bin right = new Bin();
+ split(source, left, right, 1, tpbrkpts.pts[i + 1]);
+ splitInT(left, start, i);
+ splitInT(right, i + 1, end);
+ } else {
+ if (start == tpbrkpts.start || start == tpbrkpts.end) {
+ freejarcs(source);
+ } else if (renderhints.display_method == NurbsConsts.N_OUTLINE_PARAM_ST) {
+ outline(source);
+ freejarcs(source);
+ } else {
+ t_index = start;
+ setArcTypeBezier();
+ setDegenerate();
+
+ float[] pta = new float[2];
+ float[] ptb = new float[2];
+
+ pta[0] = spbrkpts.pts[s_index - 1];
+ pta[1] = tpbrkpts.pts[t_index - 1];
+
+ ptb[0] = spbrkpts.pts[s_index];
+ ptb[1] = tpbrkpts.pts[t_index];
+ qlist.downloadAll(pta, ptb, backend);
+
+ Patchlist patchlist = new Patchlist(qlist, pta, ptb);
+
+ samplingSplit(source, patchlist,
+ renderhints.maxsubdivisions, 0);
+ setNonDegenerate();
+ setArcTypeBezier();
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Sample
+ * @param source
+ * @param patchlist
+ * @param subdivisions
+ * @param param
+ */
+ private void samplingSplit(Bin source, Patchlist patchlist,
+ int subdivisions, int param) {
+ // DONE
+ if (!source.isnonempty())
+ return;
+ if (patchlist.cullCheck() == CULL_TRIVIAL_REJECT) {
+ freejarcs(source);
+ return;
+ }
+
+ patchlist.getstepsize();
+ if (renderhints.display_method == NurbsConsts.N_OUTLINE_PATCH) {
+ tesselation(source, patchlist);
+ outline(source);
+ freejarcs(source);
+ return;
+ }
+
+ tesselation(source, patchlist);
+ if (patchlist.needsSamplingSubdivision() && subdivisions > 0) {
+ if (!patchlist.needsSubdivision(0)) {
+ param = 1;
+ } else if (patchlist.needsSubdivision(1))
+ param = 0;
+ else
+ param = 1 - param;
+
+ Bin left = new Bin();
+ Bin right = new Bin();
+
+ float mid = (float) ((patchlist.pspec[param].range[0] + patchlist.pspec[param].range[1]) * .5);
+
+ split(source, left, right, param, mid);
+ Patchlist subpatchlist = new Patchlist(patchlist, param, mid);
+ samplingSplit(left, subpatchlist, subdivisions - 1, param);
+ samplingSplit(right, subpatchlist, subdivisions - 1, param);
+ } else {
+ setArcTypePwl();
+ setDegenerate();
+ nonSamplingSplit(source, patchlist, subdivisions, param);
+ setDegenerate();
+ setArcTypeBezier();
+ }
+ }
+
+ /**
+ * Not used
+ * @param source
+ * @param patchlist
+ * @param subdivisions
+ * @param param
+ */
+ private void nonSamplingSplit(Bin source, Patchlist patchlist,
+ int subdivisions, int param) {
+ // DONE
+ if (patchlist.needsNonSamplingSubdivision() && subdivisions > 0) {
+ param = 1 - param;
+
+ Bin left = new Bin();
+ Bin right = new Bin();
+
+ float mid = (float) ((patchlist.pspec[param].range[0] + patchlist.pspec[param].range[1]) * .5);
+ split(source, left, right, param, mid);
+ Patchlist subpatchlist = new Patchlist(patchlist, param, mid);
+ if (left.isnonempty()) {
+ if (subpatchlist.cullCheck() == CULL_TRIVIAL_REJECT)
+ freejarcs(left);
+ else
+ nonSamplingSplit(left, subpatchlist, subdivisions - 1,
+ param);
+ }
+ if (right.isnonempty()) {
+ if (patchlist.cullCheck() == CULL_TRIVIAL_REJECT)
+ freejarcs(right);
+ else
+ nonSamplingSplit(right, subpatchlist, subdivisions - 1,
+ param);
+ }
+ } else {
+ patchlist.bbox();
+ backend.patch(patchlist.pspec[0].range[0],
+ patchlist.pspec[0].range[1], patchlist.pspec[1].range[0],
+ patchlist.pspec[1].range[1]);
+ if (renderhints.display_method == NurbsConsts.N_OUTLINE_SUBDIV) {
+ outline(source);
+ freejarcs(source);
+ } else {
+ setArcTypePwl();
+ setDegenerate();
+ findIrregularS(source);
+ monosplitInS(source, smbrkpts.start, smbrkpts.end);
+ }
+ }
+
+ }
+
+ /**
+ * Not used
+ * @param source
+ * @param start
+ * @param end
+ */
+ private void monosplitInS(Bin source, int start, int end) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.monosplitins");
+ }
+
+ /**
+ * Not used
+ * @param source
+ */
+ private void findIrregularS(Bin source) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.findIrregularS");
+ }
+
+ /**
+ * Not used
+ */
+ private void setArcTypePwl() {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.setarctypepwl");
+ }
+
+ /**
+ * Not used
+ * @param source
+ * @param patchlist
+ */
+ private void tesselation(Bin source, Patchlist patchlist) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.tesselation");
+ }
+
+ /**
+ * Not used
+ */
+ private void setDegenerate() {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.setdegenerate");
+ }
+
+ /**
+ * Not used
+ * @param bin
+ * @param left
+ * @param right
+ * @param param
+ * @param value
+ */
+ private void split(Bin bin, Bin left, Bin right, int param, float value) {
+ // DONE
+ Bin intersections = new Bin();
+ Bin unknown = new Bin();
+
+ partition(bin, left, intersections, right, unknown, param, value);
+
+ int count = intersections.numarcs();
+ // TODO jumpbuffer ??
+
+ if (count % 2 == 0) {
+
+ Arc[] arclist = new Arc[MAXARCS];
+ CArrayOfArcs list;
+ if (count >= MAXARCS) {
+ list = new CArrayOfArcs(new Arc[count]);
+ } else {
+ list = new CArrayOfArcs(arclist);
+ }
+
+ CArrayOfArcs last, lptr;
+ Arc jarc;
+
+ for (last = new CArrayOfArcs(list); (jarc = intersections
+ .removearc()) != null; last.pp())
+ last.set(jarc);
+
+ if (param == 0) {// sort into incrasing t order
+ ArcSdirSorter sorter = new ArcSdirSorter(this);
+ sorter.qsort(list, count);
+
+ for (lptr = new CArrayOfArcs(list); lptr.getPointer() < last
+ .getPointer(); lptr.raisePointerBy(2))
+ check_s(lptr.get(), lptr.getRelative(1));
+ for (lptr = new CArrayOfArcs(list); lptr.getPointer() < last
+ .getPointer(); lptr.raisePointerBy(2))
+ join_s(left, right, lptr.get(), lptr.getRelative(1));
+ for (lptr = new CArrayOfArcs(list); lptr.getPointer() != last
+ .getPointer(); lptr.pp()) {
+ if (lptr.get().head()[0] <= value
+ && lptr.get().tail()[0] <= value)
+ left.addarc(lptr.get());
+ else
+ right.addarc(lptr.get());
+ }
+
+ } else {// sort into decreasing s order
+ ArcTdirSorter sorter = new ArcTdirSorter(this);
+ sorter.qsort(list, count);
+
+ for (lptr = new CArrayOfArcs(list); lptr.getPointer() < last
+ .getPointer(); lptr.raisePointerBy(2))
+ check_t(lptr.get(), lptr.getRelative(1));
+ for (lptr = new CArrayOfArcs(list); lptr.getPointer() < last
+ .getPointer(); lptr.raisePointerBy(2))
+ join_t(left, right, lptr.get(), lptr.getRelative(1));
+ for (lptr = new CArrayOfArcs(list); lptr.getPointer() != last
+ .getPointer(); lptr.raisePointerBy(2)) {
+ if (lptr.get().head()[0] <= value
+ && lptr.get().tail()[0] <= value)
+ left.addarc(lptr.get());
+ else
+ right.addarc(lptr.get());
+ }
+
+ }
+
+ unknown.adopt();
+ }
+ }
+
+ /**
+ * Not used
+ * @param left
+ * @param right
+ * @param arc
+ * @param relative
+ */
+ private void join_t(Bin left, Bin right, Arc arc, Arc relative) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.join_t");
+ }
+
+ /**
+ * Not used
+ * @param arc
+ * @param relative
+ */
+ private void check_t(Arc arc, Arc relative) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.check_t");
+ }
+
+ /**
+ * Not used
+ * @param left
+ * @param right
+ * @param jarc1
+ * @param jarc2
+ */
+ private void join_s(Bin left, Bin right, Arc jarc1, Arc jarc2) {
+ // DONE
+ if (!jarc1.getitail())
+ jarc1 = jarc1.next;
+ if (!jarc2.getitail())
+ jarc2 = jarc2.next;
+
+ float s = jarc1.tail()[0];
+ float t1 = jarc1.tail()[1];
+ float t2 = jarc2.tail()[1];
+
+ if (t1 == t2) {
+ simplelink(jarc1, jarc2);
+ } else {
+ Arc newright = new Arc(Arc.ARC_RIGHT);
+ Arc newleft = new Arc(Arc.ARC_LEFT);
+ if (isBezierArcType()) {
+ arctesselator.bezier(newright, s, s, t1, t2);
+ arctesselator.bezier(newleft, s, s, t2, t1);
+ } else {
+ arctesselator.pwl_right(newright, s, t1, t2, stepsizes[0]);
+ arctesselator.pwl_left(newright, s, t2, t1, stepsizes[2]);
+ }
+ link(jarc1, jarc2, newright, newleft);
+ left.addarc(newright);
+ right.addarc(newleft);
+ }
+
+ }
+
+ /**
+ * Not used
+ * @param jarc1
+ * @param jarc2
+ * @param newright
+ * @param newleft
+ */
+ private void link(Arc jarc1, Arc jarc2, Arc newright, Arc newleft) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.link");
+ }
+
+ /**
+ * Not used
+ * @return true
+ */
+ private boolean isBezierArcType() {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.isbezierarc");
+ return true;
+ }
+
+ /**
+ * Not used
+ * @param jarc1
+ * @param jarc2
+ */
+ private void simplelink(Arc jarc1, Arc jarc2) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.simplelink");
+ }
+
+ /**
+ * Not used
+ * @param arc
+ * @param relative
+ */
+ private void check_s(Arc arc, Arc relative) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.check_s");
+
+ }
+
+ /**
+ * Not used
+ * @param bin
+ * @param left
+ * @param intersections
+ * @param right
+ * @param unknown
+ * @param param
+ * @param value
+ */
+ private void partition(Bin bin, Bin left, Bin intersections, Bin right,
+ Bin unknown, int param, float value) {
+
+ Bin headonleft = new Bin();
+ Bin headonright = new Bin();
+ Bin tailonleft = new Bin();
+ Bin tailonright = new Bin();
+
+ for (Arc jarc = bin.removearc(); jarc != null; jarc = bin.removearc()) {
+ float tdiff = jarc.tail()[param] - value;
+ float hdiff = jarc.head()[param] - value;
+
+ if (tdiff > 0) {
+ if (hdiff > 0) {
+ right.addarc(jarc);
+ } else if (hdiff == 0) {
+ tailonright.addarc(jarc);
+ } else {
+ Arc jtemp;
+ switch (arc_split(jarc, param, value, 0)) {
+ case 2:
+ tailonright.addarc(jarc);
+ headonleft.addarc(jarc.next);
+ break;
+ // TODO rest cases
+ default:
+ System.out
+ .println("TODO subdivider.partition rest cases");
+ break;
+ }
+ }
+ } else if (tdiff == 0) {
+ if (hdiff > 0) {
+ headonright.addarc(jarc);
+ } else if (hdiff == 0) {
+ unknown.addarc(jarc);
+ } else {
+ headonright.addarc(jarc);
+ }
+ } else {
+ if (hdiff > 0) {
+ // TODO rest
+ // System.out.println("TODO subdivider.partition rest of else");
+ } else if (hdiff == 0) {
+ tailonleft.addarc(jarc);
+ } else {
+ left.addarc(jarc);
+ }
+ }
+
+ }
+ if (param == 0) {
+ classify_headonleft_s(headonleft, intersections, left, value);
+ classify_tailonleft_s(tailonleft, intersections, left, value);
+ classify_headonright_s(headonright, intersections, right, value);
+ classify_tailonright_s(tailonright, intersections, right, value);
+ } else {
+ classify_headonleft_t(headonleft, intersections, left, value);
+ classify_tailonleft_t(tailonleft, intersections, left, value);
+ classify_headonright_t(headonright, intersections, right, value);
+ classify_tailonright_t(tailonright, intersections, right, value);
+ }
+ }
+
+ /**
+ * Not used
+ * @param tailonright
+ * @param intersections
+ * @param right
+ * @param value
+ */
+ private void classify_tailonright_t(Bin tailonright, Bin intersections,
+ Bin right, float value) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.classify_tailonright_t");
+
+ }
+
+ /**
+ * Not used
+ * @param bin
+ * @param in
+ * @param out
+ * @param val
+ */
+ private void classify_tailonleft_s(Bin bin, Bin in, Bin out, float val) {
+
+ // DONE
+ Arc j;
+ while ((j = bin.removearc()) != null) {
+ j.clearitail();
+
+ float diff = j.next.head()[0] - val;
+ if (diff > 0) {
+ in.addarc(j);
+ } else if (diff < 0) {
+ if (ccwTurn_sl(j, j.next))
+ out.addarc(j);
+ else
+ in.addarc(j);
+ } else {
+ if (j.next.tail()[1] > j.next.head()[1])
+ in.addarc(j);
+ else
+ out.addarc(j);
+ }
+ }
+
+ }
+
+ /**
+ * Not used
+ * @param bin
+ * @param in
+ * @param out
+ * @param val
+ */
+ private void classify_headonright_s(Bin bin, Bin in, Bin out, float val) {
+ // DONE
+ Arc j;
+ while ((j = bin.removearc()) != null) {
+ j.setitail();
+
+ float diff = j.prev.tail()[0] - val;
+ if (diff > 0) {
+ if (ccwTurn_sr(j.prev, j))
+ out.addarc(j);
+ else
+ in.addarc(j);
+ } else if (diff < 0) {
+ out.addarc(j);
+ } else {
+ if (j.prev.tail()[1] > j.prev.head()[1])
+ out.addarc(j);
+ else
+ in.addarc(j);
+ }
+ }
+ }
+
+ /**
+ * Not used
+ * @param prev
+ * @param j
+ * @return false
+ */
+ private boolean ccwTurn_sr(Arc prev, Arc j) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO ccwTurn_sr");
+ return false;
+ }
+
+ /**
+ * Not used
+ * @param headonright
+ * @param intersections
+ * @param right
+ * @param value
+ */
+ private void classify_headonright_t(Bin headonright, Bin intersections,
+ Bin right, float value) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.classify_headonright_t");
+ }
+
+ /**
+ * Not used
+ * @param tailonleft
+ * @param intersections
+ * @param left
+ * @param value
+ */
+ private void classify_tailonleft_t(Bin tailonleft, Bin intersections,
+ Bin left, float value) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.classify_tailonleft_t");
+ }
+
+ /**
+ * Not used
+ * @param bin
+ * @param in
+ * @param out
+ * @param val
+ */
+ private void classify_headonleft_t(Bin bin, Bin in, Bin out, float val) {
+ // DONE
+ Arc j;
+ while ((j = bin.removearc()) != null) {
+ j.setitail();
+
+ float diff = j.prev.tail()[1] - val;
+ if (diff > 0) {
+ out.addarc(j);
+ } else if (diff < 0) {
+ if (ccwTurn_tl(j.prev, j))
+ out.addarc(j);
+ else
+ in.addarc(j);
+ } else {
+ if (j.prev.tail()[0] > j.prev.head()[0])
+ out.addarc(j);
+ else
+ in.addarc(j);
+ }
+ }
+ }
+
+ /**
+ * Not used
+ * @param prev
+ * @param j
+ * @return false
+ */
+ private boolean ccwTurn_tl(Arc prev, Arc j) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.ccwTurn_tl");
+ return false;
+ }
+
+ /**
+ * Not used
+ * @param bin
+ * @param in
+ * @param out
+ * @param val
+ */
+ private void classify_tailonright_s(Bin bin, Bin in, Bin out, float val) {
+ // DONE
+ Arc j;
+ while ((j = bin.removearc()) != null) {
+ j.clearitail();
+
+ float diff = j.next.head()[0] - val;
+ if (diff > 0) {
+ if (ccwTurn_sr(j, j.next))
+ out.addarc(j);
+ else
+ in.addarc(j);
+ } else if (diff < 0) {
+ in.addarc(j);
+ } else {
+ if (j.next.tail()[1] > j.next.head()[1])
+ out.addarc(j);
+ else
+ in.addarc(j);
+ }
+ }
+
+ }
+
+ /**
+ * Not used
+ * @param bin
+ * @param in
+ * @param out
+ * @param val
+ */
+ private void classify_headonleft_s(Bin bin, Bin in, Bin out, float val) {
+ // DONE
+ Arc j;
+ while ((j = bin.removearc()) != null) {
+ j.setitail();
+
+ float diff = j.prev.tail()[0] - val;
+ if (diff > 0) {
+ out.addarc(j);
+ } else if (diff < 0) {
+ if (ccwTurn_sl(j.prev, j))
+ out.addarc(j);
+ else
+ in.addarc(j);
+ } else {
+ if (j.prev.tail()[1] > j.prev.head()[1])
+ in.addarc(j);
+ else
+ out.addarc(j);
+ }
+ }
+
+ }
+
+ /**
+ * Not used
+ * @param prev
+ * @param j
+ * @return false
+ */
+ private boolean ccwTurn_sl(Arc prev, Arc j) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.ccwTurn_sl");
+ return false;
+ }
+
+ /**
+ * Not used
+ * @param jarc
+ * @param param
+ * @param value
+ * @param i
+ * @return 0
+ */
+ private int arc_split(Arc jarc, int param, float value, int i) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.arc_split");
+ return 0;
+ }
+
+ /**
+ * Not used
+ */
+ private void setNonDegenerate() {
+ // DONE
+ this.showDegenerate = false;
+
+ }
+
+ /**
+ * sets trimming arc default type to bezier
+ */
+ private void setArcTypeBezier() {
+ // DONE
+ isArcTypeBezier = true;
+ }
+
+ /**
+ * Not used
+ * @param source
+ */
+ private void outline(Bin source) {
+ // TODO Auto-generated method stub
+ // System.out.println("TODO subdivider.outline");
+ }
+
+ /**
+ * Makes default trim along surface borders
+ * @param from range beginnings
+ * @param to range ends
+ */
+ private void makeBorderTrim(float[] from, float[] to) {
+ // DONE
+ float smin = from[0];
+ float smax = to[0];
+
+ float tmin = from[1];
+ float tmax = to[1];
+
+ pjarc = null;
+ Arc jarc = null;
+
+ jarc = new Arc(Arc.ARC_BOTTOM);
+ arctesselator.bezier(jarc, smin, smax, tmin, tmin);
+ initialbin.addarc(jarc);
+ pjarc = jarc.append(pjarc);
+
+ jarc = new Arc(Arc.ARC_RIGHT);
+ arctesselator.bezier(jarc, smax, smax, tmin, tmax);
+ initialbin.addarc(jarc);
+ pjarc = jarc.append(pjarc);
+
+ jarc = new Arc(Arc.ARC_TOP);
+ arctesselator.bezier(jarc, smax, smin, tmax, tmax);
+ initialbin.addarc(jarc);
+ pjarc = jarc.append(pjarc);
+
+ jarc = new Arc(Arc.ARC_LEFT);
+ arctesselator.bezier(jarc, smin, smin, tmax, tmin);
+ initialbin.addarc(jarc);
+ jarc = jarc.append(pjarc);
+
+ // assert (jarc.check() == true);
+ }
+
+ /**
+ * Draws NURBS curve
+ */
+ public void drawCurves() {
+ // DONE
+ float[] from = new float[1];
+ float[] to = new float[1];
+
+ Flist bpts = new Flist();
+ qlist.getRange(from, to, bpts);
+
+ renderhints.init();
+
+ backend.bgncurv();
+
+ for (int i = bpts.start; i < bpts.end - 1; i++) {
+ float[] pta = new float[1];
+ float[] ptb = new float[1];
+ pta[0] = bpts.pts[i];
+ ptb[0] = bpts.pts[i + 1];
+
+ qlist.downloadAll(pta, ptb, backend);
+ Curvelist curvelist = new Curvelist(qlist, pta, ptb);
+ samplingSplit(curvelist, renderhints.maxsubdivisions);
+ }
+ backend.endcurv();
+ }
+
+ /**
+ * Samples a curve in case of need, or sends curve to backend
+ * @param curvelist list of curves
+ * @param maxsubdivisions maximum number of subdivisions
+ */
+ private void samplingSplit(Curvelist curvelist, int maxsubdivisions) {
+ if (curvelist.cullCheck() == CULL_TRIVIAL_REJECT)
+ return;
+
+ curvelist.getstepsize();
+
+ if (curvelist.needsSamplingSubdivision() && (subdivisions > 0)) {
+ // TODO kód
+ // System.out.println("TODO subdivider-needsSamplingSubdivision");
+ } else {
+ int nu = (int) (1 + curvelist.range[2] / curvelist.stepsize);
+ backend.curvgrid(curvelist.range[0], curvelist.range[1], nu);
+ backend.curvmesh(0, nu);
+ }
+
+ }
+
+ /**
+ * Sets new domain_distance_u_rate value
+ * @param d new domain_distance_u_rate value
+
+ */
+ public void set_domain_distance_u_rate(double d) {
+ // DONE
+ domain_distance_u_rate = (float) d;
+ }
+
+ /**
+ * Sets new domain_distance_v_rate value
+ * @param d new domain_distance_v_rate value
+ */
+ public void set_domain_distance_v_rate(double d) {
+ // DONE
+ domain_distance_v_rate = (float) d;
+ }
+
+ /**
+ * Sets new is_domain_distance_sampling value
+ * @param i new is_domain_distance_sampling value
+ */
+ public void set_is_domain_distance_sampling(int i) {
+ // DONE
+ this.is_domain_distance_sampling = i;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/SurfaceEvaluator.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/SurfaceEvaluator.java
new file mode 100755
index 000000000..fe23f9c08
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/SurfaceEvaluator.java
@@ -0,0 +1,111 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Class rendering surfaces with OpenGL
+ * @author Tomas Hrasky
+ *
+ */
+public interface SurfaceEvaluator {
+
+ /**
+ * Pushes eval bit
+ */
+ public void bgnmap2f() ;
+
+ /**
+ * Sets glPolygonMode
+ * @param style polygon mode (N_MESHFILL/N_MESHLINE/N_MESHPOINT)
+ */
+ public void polymode(int style) ;
+
+ /**
+ * Pops all attributes
+ */
+ public void endmap2f() ;
+
+ /**
+ * Empty method
+ * @param ulo
+ * @param uhi
+ * @param vlo
+ * @param vhi
+ */
+ public void domain2f(float ulo, float uhi, float vlo, float vhi) ;
+
+ /**
+ * Defines 2D mesh
+ * @param nu number of steps in u direction
+ * @param u0 lowest u
+ * @param u1 highest u
+ * @param nv number of steps in v direction
+ * @param v0 lowest v
+ * @param v1 highest v
+ */
+ public void mapgrid2f(int nu, float u0, float u1, int nv, float v0, float v1) ;
+
+ /**
+ * Evaluates surface
+ * @param style surface style
+ * @param umin minimum U
+ * @param umax maximum U
+ * @param vmin minimum V
+ * @param vmax maximum V
+ */
+ public void mapmesh2f(int style, int umin, int umax, int vmin, int vmax) ;
+
+ /**
+ * Initializes evaluator
+ * @param type surface type
+ * @param ulo lowest u
+ * @param uhi highest u
+ * @param ustride number of objects between control points in u direction
+ * @param uorder surface order in u direction
+ * @param vlo lowest v
+ * @param vhi highest v
+ * @param vstride number of control points' coords
+ * @param vorder surface order in v direction
+ * @param pts control points
+ */
+ public void map2f(int type, float ulo, float uhi, int ustride, int uorder,
+ float vlo, float vhi, int vstride, int vorder, CArrayOfFloats pts) ;
+
+ /**
+ * Calls opengl enable
+ * @param type what to enable
+ */
+ public void enable(int type) ;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/TrimVertex.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/TrimVertex.java
new file mode 100755
index 000000000..6608f8f40
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/nurbs/TrimVertex.java
@@ -0,0 +1,56 @@
+package com.jogamp.opengl.impl.glu.nurbs;
+
+/*
+ ** License Applicability. Except to the extent portions of this file are
+ ** made subject to an alternative license as permitted in the SGI Free
+ ** Software License B, Version 2.0 (the "License"), the contents of this
+ ** file are subject only to the provisions of the License. You may not use
+ ** this file except in compliance with the License. You may obtain a copy
+ ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ **
+ ** http://oss.sgi.com/projects/FreeB
+ **
+ ** Note that, as provided in the License, the Software is distributed on an
+ ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ **
+ ** Original Code. The Original Code is: OpenGL Sample Implementation,
+ ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ ** Copyright in any portions created by third parties is as indicated
+ ** elsewhere herein. All Rights Reserved.
+ **
+ ** Additional Notice Provisions: The application programming interfaces
+ ** established by SGI in conjunction with the Original Code are The
+ ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ ** Window System(R) (Version 1.3), released October 19, 1998. This software
+ ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ ** published by SGI, but has not been independently verified as being
+ ** compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+/**
+ * Holds vertex used in trim
+ *
+ * @author Tomas Hrasky
+ *
+ */
+public class TrimVertex {
+
+ /**
+ * Trim vertex coords
+ */
+ public float[] param;
+
+ /**
+ * Makes new empty trim vertex
+ */
+ public TrimVertex() {
+ param = new float[2];
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/registry/Registry.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/registry/Registry.java
new file mode 100644
index 000000000..21b15f4d4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/registry/Registry.java
@@ -0,0 +1,79 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 2.0 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.jogamp.opengl.impl.glu.registry;
+
+import javax.media.opengl.glu.GLU;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Registry {
+
+ /** Creates a new instance of Registry */
+ public Registry() {
+ }
+
+ public static String gluGetString(int name) {
+ if( name == GLU.GLU_VERSION ) {
+ return( "1.3" );
+ } else if( name == GLU.GLU_EXTENSIONS ) {
+ return( "GLU_EXT_nurbs_tessellator GLU_EXT_object_space_tess " );
+ }
+ return( null );
+ }
+
+ public static boolean gluCheckExtension( String extName, String extString ) {
+ if( extName == null || extString == null ) {
+ return( false );
+ }
+ if ((extString.indexOf(extName + " ") >= 0) ||
+ extString.endsWith(extName) ||
+ extString.equals(extName)) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/ActiveRegion.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/ActiveRegion.java
new file mode 100644
index 000000000..85397dd6a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/ActiveRegion.java
@@ -0,0 +1,69 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+
+class ActiveRegion {
+ GLUhalfEdge eUp; /* upper edge, directed right to left */
+ DictNode nodeUp; /* dictionary node corresponding to eUp */
+ int windingNumber; /* used to determine which regions are
+ * inside the polygon */
+ boolean inside; /* is this region inside the polygon? */
+ boolean sentinel; /* marks fake edges at t = +/-infinity */
+ boolean dirty; /* marks regions where the upper or lower
+ * edge has changed, but we haven't checked
+ * whether they intersect yet */
+ boolean fixUpperEdge; /* marks temporary edges introduced when
+ * we process a "right vertex" (one without
+ * any edges leaving to the right) */
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/CachedVertex.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/CachedVertex.java
new file mode 100644
index 000000000..8948acfec
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/CachedVertex.java
@@ -0,0 +1,58 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class CachedVertex {
+ public double[] coords = new double[3];
+ public Object data;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Dict.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Dict.java
new file mode 100644
index 000000000..d26948e7f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Dict.java
@@ -0,0 +1,140 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class Dict {
+ DictNode head;
+ Object frame;
+ DictLeq leq;
+
+ private Dict() {
+ }
+
+ static Dict dictNewDict(Object frame, DictLeq leq) {
+ Dict dict = new Dict();
+ dict.head = new DictNode();
+
+ dict.head.key = null;
+ dict.head.next = dict.head;
+ dict.head.prev = dict.head;
+
+ dict.frame = frame;
+ dict.leq = leq;
+
+ return dict;
+ }
+
+ static void dictDeleteDict(Dict dict) {
+ dict.head = null;
+ dict.frame = null;
+ dict.leq = null;
+ }
+
+ static DictNode dictInsert(Dict dict, Object key) {
+ return dictInsertBefore(dict, dict.head, key);
+ }
+
+ static DictNode dictInsertBefore(Dict dict, DictNode node, Object key) {
+ do {
+ node = node.prev;
+ } while (node.key != null && !dict.leq.leq(dict.frame, node.key, key));
+
+ DictNode newNode = new DictNode();
+ newNode.key = key;
+ newNode.next = node.next;
+ node.next.prev = newNode;
+ newNode.prev = node;
+ node.next = newNode;
+
+ return newNode;
+ }
+
+ static Object dictKey(DictNode aNode) {
+ return aNode.key;
+ }
+
+ static DictNode dictSucc(DictNode aNode) {
+ return aNode.next;
+ }
+
+ static DictNode dictPred(DictNode aNode) {
+ return aNode.prev;
+ }
+
+ static DictNode dictMin(Dict aDict) {
+ return aDict.head.next;
+ }
+
+ static DictNode dictMax(Dict aDict) {
+ return aDict.head.prev;
+ }
+
+ static void dictDelete(Dict dict, DictNode node) {
+ node.next.prev = node.prev;
+ node.prev.next = node.next;
+ }
+
+ static DictNode dictSearch(Dict dict, Object key) {
+ DictNode node = dict.head;
+
+ do {
+ node = node.next;
+ } while (node.key != null && !(dict.leq.leq(dict.frame, key, node.key)));
+
+ return node;
+ }
+
+ public interface DictLeq {
+ boolean leq(Object frame, Object key1, Object key2);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/DictNode.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/DictNode.java
new file mode 100644
index 000000000..8864de127
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/DictNode.java
@@ -0,0 +1,59 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class DictNode {
+ Object key;
+ DictNode next;
+ DictNode prev;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUface.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUface.java
new file mode 100644
index 000000000..2ff4aae59
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUface.java
@@ -0,0 +1,65 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class GLUface {
+ public GLUface next; /* next face (never NULL) */
+ public GLUface prev; /* previous face (never NULL) */
+ public GLUhalfEdge anEdge; /* a half edge with this left face */
+ public Object data; /* room for client's data */
+
+ /* Internal data (keep hidden) */
+ public GLUface trail; /* "stack" for conversion to strips */
+ public boolean marked; /* flag for conversion to strips */
+ public boolean inside; /* this face is in the polygon interior */
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUhalfEdge.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUhalfEdge.java
new file mode 100644
index 000000000..c2128b616
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUhalfEdge.java
@@ -0,0 +1,71 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class GLUhalfEdge {
+ public GLUhalfEdge next; /* doubly-linked list (prev==Sym->next) */
+ public GLUhalfEdge Sym; /* same edge, opposite direction */
+ public GLUhalfEdge Onext; /* next edge CCW around origin */
+ public GLUhalfEdge Lnext; /* next edge CCW around left face */
+ public GLUvertex Org; /* origin vertex (Overtex too long) */
+ public com.jogamp.opengl.impl.glu.tessellator.GLUface Lface; /* left face */
+
+ /* Internal data (keep hidden) */
+ public com.jogamp.opengl.impl.glu.tessellator.ActiveRegion activeRegion; /* a region with this upper edge (sweep.c) */
+ public int winding; /* change in winding number when crossing */
+ public boolean first;
+
+ public GLUhalfEdge(boolean first) {
+ this.first = first;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUmesh.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUmesh.java
new file mode 100644
index 000000000..493eb20f4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUmesh.java
@@ -0,0 +1,60 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class GLUmesh {
+ GLUvertex vHead = new GLUvertex(); /* dummy header for vertex list */
+ com.jogamp.opengl.impl.glu.tessellator.GLUface fHead = new GLUface(); /* dummy header for face list */
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eHead = new GLUhalfEdge(true); /* dummy header for edge list */
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eHeadSym = new GLUhalfEdge(false); /* and its symmetric counterpart */
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUtessellatorImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUtessellatorImpl.java
new file mode 100644
index 000000000..b21998355
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUtessellatorImpl.java
@@ -0,0 +1,646 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+import com.jogamp.opengl.impl.glu.tessellator.*;
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+public class GLUtessellatorImpl implements GLUtessellator {
+ public static final int TESS_MAX_CACHE = 100;
+
+ private int state; /* what begin/end calls have we seen? */
+
+ private GLUhalfEdge lastEdge; /* lastEdge->Org is the most recent vertex */
+ GLUmesh mesh; /* stores the input contours, and eventually
+ the tessellation itself */
+
+ /*** state needed for projecting onto the sweep plane ***/
+
+ double[] normal = new double[3]; /* user-specified normal (if provided) */
+ double[] sUnit = new double[3]; /* unit vector in s-direction (debugging) */
+ double[] tUnit = new double[3]; /* unit vector in t-direction (debugging) */
+
+ /*** state needed for the line sweep ***/
+
+ private double relTolerance; /* tolerance for merging features */
+ int windingRule; /* rule for determining polygon interior */
+ boolean fatalError; /* fatal error: needed combine callback */
+
+ Dict dict; /* edge dictionary for sweep line */
+ PriorityQ pq; /* priority queue of vertex events */
+ GLUvertex event; /* current sweep event being processed */
+
+ /*** state needed for rendering callbacks (see render.c) ***/
+
+ boolean flagBoundary; /* mark boundary edges (use EdgeFlag) */
+ boolean boundaryOnly; /* Extract contours, not triangles */
+ boolean avoidDegenerateTris; /* JOGL-specific hint to try to improve triangulation
+ by avoiding producing degenerate (zero-area) triangles;
+ has not been tested exhaustively and is therefore an option */
+
+ GLUface lonelyTriList;
+ /* list of triangles which could not be rendered as strips or fans */
+
+
+
+ /*** state needed to cache single-contour polygons for renderCache() */
+
+ private boolean flushCacheOnNextVertex; /* empty cache on next vertex() call */
+ int cacheCount; /* number of cached vertices */
+ CachedVertex[] cache = new CachedVertex[TESS_MAX_CACHE]; /* the vertex data */
+
+ /*** rendering callbacks that also pass polygon data ***/
+ private Object polygonData; /* client data for current polygon */
+
+ private GLUtessellatorCallback callBegin;
+ private GLUtessellatorCallback callEdgeFlag;
+ private GLUtessellatorCallback callVertex;
+ private GLUtessellatorCallback callEnd;
+// private GLUtessellatorCallback callMesh;
+ private GLUtessellatorCallback callError;
+ private GLUtessellatorCallback callCombine;
+
+ private GLUtessellatorCallback callBeginData;
+ private GLUtessellatorCallback callEdgeFlagData;
+ private GLUtessellatorCallback callVertexData;
+ private GLUtessellatorCallback callEndData;
+// private GLUtessellatorCallback callMeshData;
+ private GLUtessellatorCallback callErrorData;
+ private GLUtessellatorCallback callCombineData;
+
+ private static final double GLU_TESS_DEFAULT_TOLERANCE = 0.0;
+// private static final int GLU_TESS_MESH = 100112; /* void (*)(GLUmesh *mesh) */
+ private static GLUtessellatorCallback NULL_CB = new GLUtessellatorCallbackAdapter();
+
+// #define MAX_FAST_ALLOC (MAX(sizeof(EdgePair), \
+// MAX(sizeof(GLUvertex),sizeof(GLUface))))
+
+ private GLUtessellatorImpl() {
+ state = TessState.T_DORMANT;
+
+ normal[0] = 0;
+ normal[1] = 0;
+ normal[2] = 0;
+
+ relTolerance = GLU_TESS_DEFAULT_TOLERANCE;
+ windingRule = GLU.GLU_TESS_WINDING_ODD;
+ flagBoundary = false;
+ boundaryOnly = false;
+
+ callBegin = NULL_CB;
+ callEdgeFlag = NULL_CB;
+ callVertex = NULL_CB;
+ callEnd = NULL_CB;
+ callError = NULL_CB;
+ callCombine = NULL_CB;
+// callMesh = NULL_CB;
+
+ callBeginData = NULL_CB;
+ callEdgeFlagData = NULL_CB;
+ callVertexData = NULL_CB;
+ callEndData = NULL_CB;
+ callErrorData = NULL_CB;
+ callCombineData = NULL_CB;
+
+ polygonData = null;
+
+ for (int i = 0; i < cache.length; i++) {
+ cache[i] = new CachedVertex();
+ }
+ }
+
+ static public GLUtessellator gluNewTess()
+ {
+ return new GLUtessellatorImpl();
+ }
+
+
+ private void makeDormant() {
+ /* Return the tessellator to its original dormant state. */
+
+ if (mesh != null) {
+ Mesh.__gl_meshDeleteMesh(mesh);
+ }
+ state = TessState.T_DORMANT;
+ lastEdge = null;
+ mesh = null;
+ }
+
+ private void requireState(int newState) {
+ if (state != newState) gotoState(newState);
+ }
+
+ private void gotoState(int newState) {
+ while (state != newState) {
+ /* We change the current state one level at a time, to get to
+ * the desired state.
+ */
+ if (state < newState) {
+ if (state == TessState.T_DORMANT) {
+ callErrorOrErrorData(GLU.GLU_TESS_MISSING_BEGIN_POLYGON);
+ gluTessBeginPolygon(null);
+ } else if (state == TessState.T_IN_POLYGON) {
+ callErrorOrErrorData(GLU.GLU_TESS_MISSING_BEGIN_CONTOUR);
+ gluTessBeginContour();
+ }
+ } else {
+ if (state == TessState.T_IN_CONTOUR) {
+ callErrorOrErrorData(GLU.GLU_TESS_MISSING_END_CONTOUR);
+ gluTessEndContour();
+ } else if (state == TessState.T_IN_POLYGON) {
+ callErrorOrErrorData(GLU.GLU_TESS_MISSING_END_POLYGON);
+ /* gluTessEndPolygon( tess ) is too much work! */
+ makeDormant();
+ }
+ }
+ }
+ }
+
+ public void gluDeleteTess() {
+ requireState(TessState.T_DORMANT);
+ }
+
+ public void gluTessProperty(int which, double value) {
+ switch (which) {
+ case GLU.GLU_TESS_TOLERANCE:
+ if (value < 0.0 || value > 1.0) break;
+ relTolerance = value;
+ return;
+
+ case GLU.GLU_TESS_WINDING_RULE:
+ int windingRule = (int) value;
+ if (windingRule != value) break; /* not an integer */
+
+ switch (windingRule) {
+ case GLU.GLU_TESS_WINDING_ODD:
+ case GLU.GLU_TESS_WINDING_NONZERO:
+ case GLU.GLU_TESS_WINDING_POSITIVE:
+ case GLU.GLU_TESS_WINDING_NEGATIVE:
+ case GLU.GLU_TESS_WINDING_ABS_GEQ_TWO:
+ this.windingRule = windingRule;
+ return;
+ default:
+ break;
+ }
+
+ case GLU.GLU_TESS_BOUNDARY_ONLY:
+ boundaryOnly = (value != 0);
+ return;
+
+ case GLU.GLU_TESS_AVOID_DEGENERATE_TRIANGLES:
+ avoidDegenerateTris = (value != 0);
+ return;
+
+ default:
+ callErrorOrErrorData(GLU.GLU_INVALID_ENUM);
+ return;
+ }
+ callErrorOrErrorData(GLU.GLU_INVALID_VALUE);
+ }
+
+/* Returns tessellator property */
+ public void gluGetTessProperty(int which, double[] value, int value_offset) {
+ switch (which) {
+ case GLU.GLU_TESS_TOLERANCE:
+/* tolerance should be in range [0..1] */
+ assert (0.0 <= relTolerance && relTolerance <= 1.0);
+ value[value_offset] = relTolerance;
+ break;
+ case GLU.GLU_TESS_WINDING_RULE:
+ assert (windingRule == GLU.GLU_TESS_WINDING_ODD ||
+ windingRule == GLU.GLU_TESS_WINDING_NONZERO ||
+ windingRule == GLU.GLU_TESS_WINDING_POSITIVE ||
+ windingRule == GLU.GLU_TESS_WINDING_NEGATIVE ||
+ windingRule == GLU.GLU_TESS_WINDING_ABS_GEQ_TWO);
+ value[value_offset] = windingRule;
+ break;
+ case GLU.GLU_TESS_BOUNDARY_ONLY:
+ assert (boundaryOnly == true || boundaryOnly == false);
+ value[value_offset] = boundaryOnly ? 1 : 0;
+ break;
+ case GLU.GLU_TESS_AVOID_DEGENERATE_TRIANGLES:
+ value[value_offset] = avoidDegenerateTris ? 1 : 0;
+ break;
+ default:
+ value[value_offset] = 0.0;
+ callErrorOrErrorData(GLU.GLU_INVALID_ENUM);
+ break;
+ }
+ } /* gluGetTessProperty() */
+
+ public void gluTessNormal(double x, double y, double z) {
+ normal[0] = x;
+ normal[1] = y;
+ normal[2] = z;
+ }
+
+ public void gluTessCallback(int which, GLUtessellatorCallback aCallback) {
+ switch (which) {
+ case GLU.GLU_TESS_BEGIN:
+ callBegin = aCallback == null ? NULL_CB : aCallback;
+ return;
+ case GLU.GLU_TESS_BEGIN_DATA:
+ callBeginData = aCallback == null ? NULL_CB : aCallback;
+ return;
+ case GLU.GLU_TESS_EDGE_FLAG:
+ callEdgeFlag = aCallback == null ? NULL_CB : aCallback;
+/* If the client wants boundary edges to be flagged,
+ * we render everything as separate triangles (no strips or fans).
+ */
+ flagBoundary = aCallback != null;
+ return;
+ case GLU.GLU_TESS_EDGE_FLAG_DATA:
+ callEdgeFlagData = callBegin = aCallback == null ? NULL_CB : aCallback;
+/* If the client wants boundary edges to be flagged,
+ * we render everything as separate triangles (no strips or fans).
+ */
+ flagBoundary = (aCallback != null);
+ return;
+ case GLU.GLU_TESS_VERTEX:
+ callVertex = aCallback == null ? NULL_CB : aCallback;
+ return;
+ case GLU.GLU_TESS_VERTEX_DATA:
+ callVertexData = aCallback == null ? NULL_CB : aCallback;
+ return;
+ case GLU.GLU_TESS_END:
+ callEnd = aCallback == null ? NULL_CB : aCallback;
+ return;
+ case GLU.GLU_TESS_END_DATA:
+ callEndData = aCallback == null ? NULL_CB : aCallback;
+ return;
+ case GLU.GLU_TESS_ERROR:
+ callError = aCallback == null ? NULL_CB : aCallback;
+ return;
+ case GLU.GLU_TESS_ERROR_DATA:
+ callErrorData = aCallback == null ? NULL_CB : aCallback;
+ return;
+ case GLU.GLU_TESS_COMBINE:
+ callCombine = aCallback == null ? NULL_CB : aCallback;
+ return;
+ case GLU.GLU_TESS_COMBINE_DATA:
+ callCombineData = aCallback == null ? NULL_CB : aCallback;
+ return;
+// case GLU_TESS_MESH:
+// callMesh = aCallback == null ? NULL_CB : aCallback;
+// return;
+ default:
+ callErrorOrErrorData(GLU.GLU_INVALID_ENUM);
+ return;
+ }
+ }
+
+ private boolean addVertex(double[] coords, Object vertexData) {
+ GLUhalfEdge e;
+
+ e = lastEdge;
+ if (e == null) {
+/* Make a self-loop (one vertex, one edge). */
+
+ e = Mesh.__gl_meshMakeEdge(mesh);
+ if (e == null) return false;
+ if (!Mesh.__gl_meshSplice(e, e.Sym)) return false;
+ } else {
+/* Create a new vertex and edge which immediately follow e
+ * in the ordering around the left face.
+ */
+ if (Mesh.__gl_meshSplitEdge(e) == null) return false;
+ e = e.Lnext;
+ }
+
+/* The new vertex is now e.Org. */
+ e.Org.data = vertexData;
+ e.Org.coords[0] = coords[0];
+ e.Org.coords[1] = coords[1];
+ e.Org.coords[2] = coords[2];
+
+/* The winding of an edge says how the winding number changes as we
+ * cross from the edge''s right face to its left face. We add the
+ * vertices in such an order that a CCW contour will add +1 to
+ * the winding number of the region inside the contour.
+ */
+ e.winding = 1;
+ e.Sym.winding = -1;
+
+ lastEdge = e;
+
+ return true;
+ }
+
+ private void cacheVertex(double[] coords, Object vertexData) {
+ if (cache[cacheCount] == null) {
+ cache[cacheCount] = new CachedVertex();
+ }
+
+ CachedVertex v = cache[cacheCount];
+
+ v.data = vertexData;
+ v.coords[0] = coords[0];
+ v.coords[1] = coords[1];
+ v.coords[2] = coords[2];
+ ++cacheCount;
+ }
+
+
+ private boolean flushCache() {
+ CachedVertex[] v = cache;
+
+ mesh = Mesh.__gl_meshNewMesh();
+ if (mesh == null) return false;
+
+ for (int i = 0; i < cacheCount; i++) {
+ CachedVertex vertex = v[i];
+ if (!addVertex(vertex.coords, vertex.data)) return false;
+ }
+ cacheCount = 0;
+ flushCacheOnNextVertex = false;
+
+ return true;
+ }
+
+ public void gluTessVertex(double[] coords, int coords_offset, Object vertexData) {
+ int i;
+ boolean tooLarge = false;
+ double x;
+ double[] clamped = new double[3];
+
+ requireState(TessState.T_IN_CONTOUR);
+
+ if (flushCacheOnNextVertex) {
+ if (!flushCache()) {
+ callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
+ return;
+ }
+ lastEdge = null;
+ }
+ for (i = 0; i < 3; ++i) {
+ x = coords[i+coords_offset];
+ if (x < -GLU.GLU_TESS_MAX_COORD) {
+ x = -GLU.GLU_TESS_MAX_COORD;
+ tooLarge = true;
+ }
+ if (x > GLU.GLU_TESS_MAX_COORD) {
+ x = GLU.GLU_TESS_MAX_COORD;
+ tooLarge = true;
+ }
+ clamped[i] = x;
+ }
+ if (tooLarge) {
+ callErrorOrErrorData(GLU.GLU_TESS_COORD_TOO_LARGE);
+ }
+
+ if (mesh == null) {
+ if (cacheCount < TESS_MAX_CACHE) {
+ cacheVertex(clamped, vertexData);
+ return;
+ }
+ if (!flushCache()) {
+ callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
+ return;
+ }
+ }
+
+ if (!addVertex(clamped, vertexData)) {
+ callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
+ }
+ }
+
+
+ public void gluTessBeginPolygon(Object data) {
+ requireState(TessState.T_DORMANT);
+
+ state = TessState.T_IN_POLYGON;
+ cacheCount = 0;
+ flushCacheOnNextVertex = false;
+ mesh = null;
+
+ polygonData = data;
+ }
+
+
+ public void gluTessBeginContour() {
+ requireState(TessState.T_IN_POLYGON);
+
+ state = TessState.T_IN_CONTOUR;
+ lastEdge = null;
+ if (cacheCount > 0) {
+/* Just set a flag so we don't get confused by empty contours
+ * -- these can be generated accidentally with the obsolete
+ * NextContour() interface.
+ */
+ flushCacheOnNextVertex = true;
+ }
+ }
+
+
+ public void gluTessEndContour() {
+ requireState(TessState.T_IN_CONTOUR);
+ state = TessState.T_IN_POLYGON;
+ }
+
+ public void gluTessEndPolygon() {
+ GLUmesh mesh;
+
+ try {
+ requireState(TessState.T_IN_POLYGON);
+ state = TessState.T_DORMANT;
+
+ if (this.mesh == null) {
+ if (!flagBoundary /*&& callMesh == NULL_CB*/) {
+
+/* Try some special code to make the easy cases go quickly
+ * (eg. convex polygons). This code does NOT handle multiple contours,
+ * intersections, edge flags, and of course it does not generate
+ * an explicit mesh either.
+ */
+ if (Render.__gl_renderCache(this)) {
+ polygonData = null;
+ return;
+ }
+ }
+ if (!flushCache()) throw new RuntimeException(); /* could've used a label*/
+ }
+
+/* Determine the polygon normal and project vertices onto the plane
+ * of the polygon.
+ */
+ Normal.__gl_projectPolygon(this);
+
+/* __gl_computeInterior( tess ) computes the planar arrangement specified
+ * by the given contours, and further subdivides this arrangement
+ * into regions. Each region is marked "inside" if it belongs
+ * to the polygon, according to the rule given by windingRule.
+ * Each interior region is guaranteed be monotone.
+ */
+ if (!Sweep.__gl_computeInterior(this)) {
+ throw new RuntimeException(); /* could've used a label */
+ }
+
+ mesh = this.mesh;
+ if (!fatalError) {
+ boolean rc = true;
+
+/* If the user wants only the boundary contours, we throw away all edges
+ * except those which separate the interior from the exterior.
+ * Otherwise we tessellate all the regions marked "inside".
+ */
+ if (boundaryOnly) {
+ rc = TessMono.__gl_meshSetWindingNumber(mesh, 1, true);
+ } else {
+ rc = TessMono.__gl_meshTessellateInterior(mesh, avoidDegenerateTris);
+ }
+ if (!rc) throw new RuntimeException(); /* could've used a label */
+
+ Mesh.__gl_meshCheckMesh(mesh);
+
+ if (callBegin != NULL_CB || callEnd != NULL_CB
+ || callVertex != NULL_CB || callEdgeFlag != NULL_CB
+ || callBeginData != NULL_CB
+ || callEndData != NULL_CB
+ || callVertexData != NULL_CB
+ || callEdgeFlagData != NULL_CB) {
+ if (boundaryOnly) {
+ Render.__gl_renderBoundary(this, mesh); /* output boundary contours */
+ } else {
+ Render.__gl_renderMesh(this, mesh); /* output strips and fans */
+ }
+ }
+// if (callMesh != NULL_CB) {
+//
+///* Throw away the exterior faces, so that all faces are interior.
+// * This way the user doesn't have to check the "inside" flag,
+// * and we don't need to even reveal its existence. It also leaves
+// * the freedom for an implementation to not generate the exterior
+// * faces in the first place.
+// */
+// TessMono.__gl_meshDiscardExterior(mesh);
+// callMesh.mesh(mesh); /* user wants the mesh itself */
+// mesh = null;
+// polygonData = null;
+// return;
+// }
+ }
+ Mesh.__gl_meshDeleteMesh(mesh);
+ polygonData = null;
+ mesh = null;
+ } catch (Exception e) {
+ e.printStackTrace();
+ callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
+ }
+ }
+
+ /*******************************************************/
+
+/* Obsolete calls -- for backward compatibility */
+
+ public void gluBeginPolygon() {
+ gluTessBeginPolygon(null);
+ gluTessBeginContour();
+ }
+
+
+/*ARGSUSED*/
+ public void gluNextContour(int type) {
+ gluTessEndContour();
+ gluTessBeginContour();
+ }
+
+
+ public void gluEndPolygon() {
+ gluTessEndContour();
+ gluTessEndPolygon();
+ }
+
+ void callBeginOrBeginData(int a) {
+ if (callBeginData != NULL_CB)
+ callBeginData.beginData(a, polygonData);
+ else
+ callBegin.begin(a);
+ }
+
+ void callVertexOrVertexData(Object a) {
+ if (callVertexData != NULL_CB)
+ callVertexData.vertexData(a, polygonData);
+ else
+ callVertex.vertex(a);
+ }
+
+ void callEdgeFlagOrEdgeFlagData(boolean a) {
+ if (callEdgeFlagData != NULL_CB)
+ callEdgeFlagData.edgeFlagData(a, polygonData);
+ else
+ callEdgeFlag.edgeFlag(a);
+ }
+
+ void callEndOrEndData() {
+ if (callEndData != NULL_CB)
+ callEndData.endData(polygonData);
+ else
+ callEnd.end();
+ }
+
+ void callCombineOrCombineData(double[] coords, Object[] vertexData, float[] weights, Object[] outData) {
+ if (callCombineData != NULL_CB)
+ callCombineData.combineData(coords, vertexData, weights, outData, polygonData);
+ else
+ callCombine.combine(coords, vertexData, weights, outData);
+ }
+
+ void callErrorOrErrorData(int a) {
+ if (callErrorData != NULL_CB)
+ callErrorData.errorData(a, polygonData);
+ else
+ callError.error(a);
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUvertex.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUvertex.java
new file mode 100644
index 000000000..af294caad
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/GLUvertex.java
@@ -0,0 +1,65 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class GLUvertex {
+ public GLUvertex next; /* next vertex (never NULL) */
+ public GLUvertex prev; /* previous vertex (never NULL) */
+ public com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge anEdge; /* a half-edge with this origin */
+ public Object data; /* client's data */
+
+ /* Internal data (keep hidden) */
+ public double[] coords = new double[3]; /* vertex location in 3D */
+ public double s, t; /* projection onto the sweep plane */
+ public int pqHandle; /* to allow deletion from priority queue */
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Geom.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Geom.java
new file mode 100644
index 000000000..2710346d1
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Geom.java
@@ -0,0 +1,338 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class Geom {
+ private Geom() {
+ }
+
+ /* Given three vertices u,v,w such that VertLeq(u,v) && VertLeq(v,w),
+ * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
+ * Returns v->t - (uw)(v->s), ie. the signed distance from uw to v.
+ * If uw is vertical (and thus passes thru v), the result is zero.
+ *
+ * The calculation is extremely accurate and stable, even when v
+ * is very close to u or w. In particular if we set v->t = 0 and
+ * let r be the negated result (this evaluates (uw)(v->s)), then
+ * r is guaranteed to satisfy MIN(u->t,w->t) <= r <= MAX(u->t,w->t).
+ */
+ static double EdgeEval(GLUvertex u, GLUvertex v, GLUvertex w) {
+ double gapL, gapR;
+
+ assert (VertLeq(u, v) && VertLeq(v, w));
+
+ gapL = v.s - u.s;
+ gapR = w.s - v.s;
+
+ if (gapL + gapR > 0) {
+ if (gapL < gapR) {
+ return (v.t - u.t) + (u.t - w.t) * (gapL / (gapL + gapR));
+ } else {
+ return (v.t - w.t) + (w.t - u.t) * (gapR / (gapL + gapR));
+ }
+ }
+ /* vertical line */
+ return 0;
+ }
+
+ static double EdgeSign(GLUvertex u, GLUvertex v, GLUvertex w) {
+ double gapL, gapR;
+
+ assert (VertLeq(u, v) && VertLeq(v, w));
+
+ gapL = v.s - u.s;
+ gapR = w.s - v.s;
+
+ if (gapL + gapR > 0) {
+ return (v.t - w.t) * gapL + (v.t - u.t) * gapR;
+ }
+ /* vertical line */
+ return 0;
+ }
+
+
+ /***********************************************************************
+ * Define versions of EdgeSign, EdgeEval with s and t transposed.
+ */
+
+ static double TransEval(GLUvertex u, GLUvertex v, GLUvertex w) {
+ /* Given three vertices u,v,w such that TransLeq(u,v) && TransLeq(v,w),
+ * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
+ * Returns v->s - (uw)(v->t), ie. the signed distance from uw to v.
+ * If uw is vertical (and thus passes thru v), the result is zero.
+ *
+ * The calculation is extremely accurate and stable, even when v
+ * is very close to u or w. In particular if we set v->s = 0 and
+ * let r be the negated result (this evaluates (uw)(v->t)), then
+ * r is guaranteed to satisfy MIN(u->s,w->s) <= r <= MAX(u->s,w->s).
+ */
+ double gapL, gapR;
+
+ assert (TransLeq(u, v) && TransLeq(v, w));
+
+ gapL = v.t - u.t;
+ gapR = w.t - v.t;
+
+ if (gapL + gapR > 0) {
+ if (gapL < gapR) {
+ return (v.s - u.s) + (u.s - w.s) * (gapL / (gapL + gapR));
+ } else {
+ return (v.s - w.s) + (w.s - u.s) * (gapR / (gapL + gapR));
+ }
+ }
+ /* vertical line */
+ return 0;
+ }
+
+ static double TransSign(GLUvertex u, GLUvertex v, GLUvertex w) {
+ /* Returns a number whose sign matches TransEval(u,v,w) but which
+ * is cheaper to evaluate. Returns > 0, == 0 , or < 0
+ * as v is above, on, or below the edge uw.
+ */
+ double gapL, gapR;
+
+ assert (TransLeq(u, v) && TransLeq(v, w));
+
+ gapL = v.t - u.t;
+ gapR = w.t - v.t;
+
+ if (gapL + gapR > 0) {
+ return (v.s - w.s) * gapL + (v.s - u.s) * gapR;
+ }
+ /* vertical line */
+ return 0;
+ }
+
+
+ static boolean VertCCW(GLUvertex u, GLUvertex v, GLUvertex w) {
+ /* For almost-degenerate situations, the results are not reliable.
+ * Unless the floating-point arithmetic can be performed without
+ * rounding errors, *any* implementation will give incorrect results
+ * on some degenerate inputs, so the client must have some way to
+ * handle this situation.
+ */
+ return (u.s * (v.t - w.t) + v.s * (w.t - u.t) + w.s * (u.t - v.t)) >= 0;
+ }
+
+/* Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b),
+ * or (x+y)/2 if a==b==0. It requires that a,b >= 0, and enforces
+ * this in the rare case that one argument is slightly negative.
+ * The implementation is extremely stable numerically.
+ * In particular it guarantees that the result r satisfies
+ * MIN(x,y) <= r <= MAX(x,y), and the results are very accurate
+ * even when a and b differ greatly in magnitude.
+ */
+ static double Interpolate(double a, double x, double b, double y) {
+ a = (a < 0) ? 0 : a;
+ b = (b < 0) ? 0 : b;
+ if (a <= b) {
+ if (b == 0) {
+ return (x + y) / 2.0;
+ } else {
+ return (x + (y - x) * (a / (a + b)));
+ }
+ } else {
+ return (y + (x - y) * (b / (a + b)));
+ }
+ }
+
+ static void EdgeIntersect(GLUvertex o1, GLUvertex d1,
+ GLUvertex o2, GLUvertex d2,
+ GLUvertex v)
+/* Given edges (o1,d1) and (o2,d2), compute their point of intersection.
+ * The computed point is guaranteed to lie in the intersection of the
+ * bounding rectangles defined by each edge.
+ */ {
+ double z1, z2;
+
+ /* This is certainly not the most efficient way to find the intersection
+ * of two line segments, but it is very numerically stable.
+ *
+ * Strategy: find the two middle vertices in the VertLeq ordering,
+ * and interpolate the intersection s-value from these. Then repeat
+ * using the TransLeq ordering to find the intersection t-value.
+ */
+
+ if (!VertLeq(o1, d1)) {
+ GLUvertex temp = o1;
+ o1 = d1;
+ d1 = temp;
+ }
+ if (!VertLeq(o2, d2)) {
+ GLUvertex temp = o2;
+ o2 = d2;
+ d2 = temp;
+ }
+ if (!VertLeq(o1, o2)) {
+ GLUvertex temp = o1;
+ o1 = o2;
+ o2 = temp;
+ temp = d1;
+ d1 = d2;
+ d2 = temp;
+ }
+
+ if (!VertLeq(o2, d1)) {
+ /* Technically, no intersection -- do our best */
+ v.s = (o2.s + d1.s) / 2.0;
+ } else if (VertLeq(d1, d2)) {
+ /* Interpolate between o2 and d1 */
+ z1 = EdgeEval(o1, o2, d1);
+ z2 = EdgeEval(o2, d1, d2);
+ if (z1 + z2 < 0) {
+ z1 = -z1;
+ z2 = -z2;
+ }
+ v.s = Interpolate(z1, o2.s, z2, d1.s);
+ } else {
+ /* Interpolate between o2 and d2 */
+ z1 = EdgeSign(o1, o2, d1);
+ z2 = -EdgeSign(o1, d2, d1);
+ if (z1 + z2 < 0) {
+ z1 = -z1;
+ z2 = -z2;
+ }
+ v.s = Interpolate(z1, o2.s, z2, d2.s);
+ }
+
+ /* Now repeat the process for t */
+
+ if (!TransLeq(o1, d1)) {
+ GLUvertex temp = o1;
+ o1 = d1;
+ d1 = temp;
+ }
+ if (!TransLeq(o2, d2)) {
+ GLUvertex temp = o2;
+ o2 = d2;
+ d2 = temp;
+ }
+ if (!TransLeq(o1, o2)) {
+ GLUvertex temp = o2;
+ o2 = o1;
+ o1 = temp;
+ temp = d2;
+ d2 = d1;
+ d1 = temp;
+ }
+
+ if (!TransLeq(o2, d1)) {
+ /* Technically, no intersection -- do our best */
+ v.t = (o2.t + d1.t) / 2.0;
+ } else if (TransLeq(d1, d2)) {
+ /* Interpolate between o2 and d1 */
+ z1 = TransEval(o1, o2, d1);
+ z2 = TransEval(o2, d1, d2);
+ if (z1 + z2 < 0) {
+ z1 = -z1;
+ z2 = -z2;
+ }
+ v.t = Interpolate(z1, o2.t, z2, d1.t);
+ } else {
+ /* Interpolate between o2 and d2 */
+ z1 = TransSign(o1, o2, d1);
+ z2 = -TransSign(o1, d2, d1);
+ if (z1 + z2 < 0) {
+ z1 = -z1;
+ z2 = -z2;
+ }
+ v.t = Interpolate(z1, o2.t, z2, d2.t);
+ }
+ }
+
+ static boolean VertEq(GLUvertex u, GLUvertex v) {
+ return u.s == v.s && u.t == v.t;
+ }
+
+ static boolean VertLeq(GLUvertex u, GLUvertex v) {
+ return u.s < v.s || (u.s == v.s && u.t <= v.t);
+ }
+
+/* Versions of VertLeq, EdgeSign, EdgeEval with s and t transposed. */
+
+ static boolean TransLeq(GLUvertex u, GLUvertex v) {
+ return u.t < v.t || (u.t == v.t && u.s <= v.s);
+ }
+
+ static boolean EdgeGoesLeft(GLUhalfEdge e) {
+ return VertLeq(e.Sym.Org, e.Org);
+ }
+
+ static boolean EdgeGoesRight(GLUhalfEdge e) {
+ return VertLeq(e.Org, e.Sym.Org);
+ }
+
+ static double VertL1dist(GLUvertex u, GLUvertex v) {
+ return Math.abs(u.s - v.s) + Math.abs(u.t - v.t);
+ }
+
+ /***********************************************************************/
+
+ // Compute the cosine of the angle between the edges between o and
+ // v1 and between o and v2
+ static double EdgeCos(GLUvertex o, GLUvertex v1, GLUvertex v2) {
+ double ov1s = v1.s - o.s;
+ double ov1t = v1.t - o.t;
+ double ov2s = v2.s - o.s;
+ double ov2t = v2.t - o.t;
+ double dotp = ov1s * ov2s + ov1t * ov2t;
+ double len = Math.sqrt(ov1s * ov1s + ov1t * ov1t) * Math.sqrt(ov2s * ov2s + ov2t * ov2t);
+ if (len > 0.0) {
+ dotp /= len;
+ }
+ return dotp;
+ }
+
+ static final double EPSILON = 1.0e-5;
+ static final double ONE_MINUS_EPSILON = 1.0 - EPSILON;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Mesh.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Mesh.java
new file mode 100644
index 000000000..b8be9f80f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Mesh.java
@@ -0,0 +1,734 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class Mesh {
+ private Mesh() {
+ }
+
+ /************************ Utility Routines ************************/
+/* MakeEdge creates a new pair of half-edges which form their own loop.
+ * No vertex or face structures are allocated, but these must be assigned
+ * before the current edge operation is completed.
+ */
+ static com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge MakeEdge(com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eNext) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eSym;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge ePrev;
+
+// EdgePair * pair = (EdgePair *)
+// memAlloc(sizeof(EdgePair));
+// if (pair == NULL) return NULL;
+//
+// e = &pair - > e;
+ e = new com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge(true);
+// eSym = &pair - > eSym;
+ eSym = new com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge(false);
+
+
+ /* Make sure eNext points to the first edge of the edge pair */
+ if (!eNext.first) {
+ eNext = eNext.Sym;
+ }
+
+ /* Insert in circular doubly-linked list before eNext.
+ * Note that the prev pointer is stored in Sym->next.
+ */
+ ePrev = eNext.Sym.next;
+ eSym.next = ePrev;
+ ePrev.Sym.next = e;
+ e.next = eNext;
+ eNext.Sym.next = eSym;
+
+ e.Sym = eSym;
+ e.Onext = e;
+ e.Lnext = eSym;
+ e.Org = null;
+ e.Lface = null;
+ e.winding = 0;
+ e.activeRegion = null;
+
+ eSym.Sym = e;
+ eSym.Onext = eSym;
+ eSym.Lnext = e;
+ eSym.Org = null;
+ eSym.Lface = null;
+ eSym.winding = 0;
+ eSym.activeRegion = null;
+
+ return e;
+ }
+
+/* Splice( a, b ) is best described by the Guibas/Stolfi paper or the
+ * CS348a notes (see mesh.h). Basically it modifies the mesh so that
+ * a->Onext and b->Onext are exchanged. This can have various effects
+ * depending on whether a and b belong to different face or vertex rings.
+ * For more explanation see __gl_meshSplice() below.
+ */
+ static void Splice(com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge a, com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge b) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge aOnext = a.Onext;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge bOnext = b.Onext;
+
+ aOnext.Sym.Lnext = b;
+ bOnext.Sym.Lnext = a;
+ a.Onext = bOnext;
+ b.Onext = aOnext;
+ }
+
+/* MakeVertex( newVertex, eOrig, vNext ) attaches a new vertex and makes it the
+ * origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives
+ * a place to insert the new vertex in the global vertex list. We insert
+ * the new vertex *before* vNext so that algorithms which walk the vertex
+ * list will not see the newly created vertices.
+ */
+ static void MakeVertex(com.jogamp.opengl.impl.glu.tessellator.GLUvertex newVertex,
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eOrig, com.jogamp.opengl.impl.glu.tessellator.GLUvertex vNext) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex vPrev;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex vNew = newVertex;
+
+ assert (vNew != null);
+
+ /* insert in circular doubly-linked list before vNext */
+ vPrev = vNext.prev;
+ vNew.prev = vPrev;
+ vPrev.next = vNew;
+ vNew.next = vNext;
+ vNext.prev = vNew;
+
+ vNew.anEdge = eOrig;
+ vNew.data = null;
+ /* leave coords, s, t undefined */
+
+ /* fix other edges on this vertex loop */
+ e = eOrig;
+ do {
+ e.Org = vNew;
+ e = e.Onext;
+ } while (e != eOrig);
+ }
+
+/* MakeFace( newFace, eOrig, fNext ) attaches a new face and makes it the left
+ * face of all edges in the face loop to which eOrig belongs. "fNext" gives
+ * a place to insert the new face in the global face list. We insert
+ * the new face *before* fNext so that algorithms which walk the face
+ * list will not see the newly created faces.
+ */
+ static void MakeFace(com.jogamp.opengl.impl.glu.tessellator.GLUface newFace, com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eOrig, com.jogamp.opengl.impl.glu.tessellator.GLUface fNext) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e;
+ com.jogamp.opengl.impl.glu.tessellator.GLUface fPrev;
+ com.jogamp.opengl.impl.glu.tessellator.GLUface fNew = newFace;
+
+ assert (fNew != null);
+
+ /* insert in circular doubly-linked list before fNext */
+ fPrev = fNext.prev;
+ fNew.prev = fPrev;
+ fPrev.next = fNew;
+ fNew.next = fNext;
+ fNext.prev = fNew;
+
+ fNew.anEdge = eOrig;
+ fNew.data = null;
+ fNew.trail = null;
+ fNew.marked = false;
+
+ /* The new face is marked "inside" if the old one was. This is a
+ * convenience for the common case where a face has been split in two.
+ */
+ fNew.inside = fNext.inside;
+
+ /* fix other edges on this face loop */
+ e = eOrig;
+ do {
+ e.Lface = fNew;
+ e = e.Lnext;
+ } while (e != eOrig);
+ }
+
+/* KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym),
+ * and removes from the global edge list.
+ */
+ static void KillEdge(com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eDel) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge ePrev, eNext;
+
+ /* Half-edges are allocated in pairs, see EdgePair above */
+ if (!eDel.first) {
+ eDel = eDel.Sym;
+ }
+
+ /* delete from circular doubly-linked list */
+ eNext = eDel.next;
+ ePrev = eDel.Sym.next;
+ eNext.Sym.next = ePrev;
+ ePrev.Sym.next = eNext;
+ }
+
+
+/* KillVertex( vDel ) destroys a vertex and removes it from the global
+ * vertex list. It updates the vertex loop to point to a given new vertex.
+ */
+ static void KillVertex(com.jogamp.opengl.impl.glu.tessellator.GLUvertex vDel, com.jogamp.opengl.impl.glu.tessellator.GLUvertex newOrg) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e, eStart = vDel.anEdge;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex vPrev, vNext;
+
+ /* change the origin of all affected edges */
+ e = eStart;
+ do {
+ e.Org = newOrg;
+ e = e.Onext;
+ } while (e != eStart);
+
+ /* delete from circular doubly-linked list */
+ vPrev = vDel.prev;
+ vNext = vDel.next;
+ vNext.prev = vPrev;
+ vPrev.next = vNext;
+ }
+
+/* KillFace( fDel ) destroys a face and removes it from the global face
+ * list. It updates the face loop to point to a given new face.
+ */
+ static void KillFace(com.jogamp.opengl.impl.glu.tessellator.GLUface fDel, com.jogamp.opengl.impl.glu.tessellator.GLUface newLface) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e, eStart = fDel.anEdge;
+ com.jogamp.opengl.impl.glu.tessellator.GLUface fPrev, fNext;
+
+ /* change the left face of all affected edges */
+ e = eStart;
+ do {
+ e.Lface = newLface;
+ e = e.Lnext;
+ } while (e != eStart);
+
+ /* delete from circular doubly-linked list */
+ fPrev = fDel.prev;
+ fNext = fDel.next;
+ fNext.prev = fPrev;
+ fPrev.next = fNext;
+ }
+
+
+ /****************** Basic Edge Operations **********************/
+
+/* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face).
+ * The loop consists of the two new half-edges.
+ */
+ public static com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge __gl_meshMakeEdge(com.jogamp.opengl.impl.glu.tessellator.GLUmesh mesh) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex newVertex1 = new com.jogamp.opengl.impl.glu.tessellator.GLUvertex();
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex newVertex2 = new com.jogamp.opengl.impl.glu.tessellator.GLUvertex();
+ com.jogamp.opengl.impl.glu.tessellator.GLUface newFace = new com.jogamp.opengl.impl.glu.tessellator.GLUface();
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e;
+
+ e = MakeEdge(mesh.eHead);
+ if (e == null) return null;
+
+ MakeVertex(newVertex1, e, mesh.vHead);
+ MakeVertex(newVertex2, e.Sym, mesh.vHead);
+ MakeFace(newFace, e, mesh.fHead);
+ return e;
+ }
+
+
+/* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
+ * mesh connectivity and topology. It changes the mesh so that
+ * eOrg->Onext <- OLD( eDst->Onext )
+ * eDst->Onext <- OLD( eOrg->Onext )
+ * where OLD(...) means the value before the meshSplice operation.
+ *
+ * This can have two effects on the vertex structure:
+ * - if eOrg->Org != eDst->Org, the two vertices are merged together
+ * - if eOrg->Org == eDst->Org, the origin is split into two vertices
+ * In both cases, eDst->Org is changed and eOrg->Org is untouched.
+ *
+ * Similarly (and independently) for the face structure,
+ * - if eOrg->Lface == eDst->Lface, one loop is split into two
+ * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
+ * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
+ *
+ * Some special cases:
+ * If eDst == eOrg, the operation has no effect.
+ * If eDst == eOrg->Lnext, the new face will have a single edge.
+ * If eDst == eOrg->Lprev, the old face will have a single edge.
+ * If eDst == eOrg->Onext, the new vertex will have a single edge.
+ * If eDst == eOrg->Oprev, the old vertex will have a single edge.
+ */
+ public static boolean __gl_meshSplice(com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eOrg, com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eDst) {
+ boolean joiningLoops = false;
+ boolean joiningVertices = false;
+
+ if (eOrg == eDst) return true;
+
+ if (eDst.Org != eOrg.Org) {
+ /* We are merging two disjoint vertices -- destroy eDst->Org */
+ joiningVertices = true;
+ KillVertex(eDst.Org, eOrg.Org);
+ }
+ if (eDst.Lface != eOrg.Lface) {
+ /* We are connecting two disjoint loops -- destroy eDst.Lface */
+ joiningLoops = true;
+ KillFace(eDst.Lface, eOrg.Lface);
+ }
+
+ /* Change the edge structure */
+ Splice(eDst, eOrg);
+
+ if (!joiningVertices) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex newVertex = new com.jogamp.opengl.impl.glu.tessellator.GLUvertex();
+
+ /* We split one vertex into two -- the new vertex is eDst.Org.
+ * Make sure the old vertex points to a valid half-edge.
+ */
+ MakeVertex(newVertex, eDst, eOrg.Org);
+ eOrg.Org.anEdge = eOrg;
+ }
+ if (!joiningLoops) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUface newFace = new com.jogamp.opengl.impl.glu.tessellator.GLUface();
+
+ /* We split one loop into two -- the new loop is eDst.Lface.
+ * Make sure the old face points to a valid half-edge.
+ */
+ MakeFace(newFace, eDst, eOrg.Lface);
+ eOrg.Lface.anEdge = eOrg;
+ }
+
+ return true;
+ }
+
+
+/* __gl_meshDelete( eDel ) removes the edge eDel. There are several cases:
+ * if (eDel.Lface != eDel.Rface), we join two loops into one; the loop
+ * eDel.Lface is deleted. Otherwise, we are splitting one loop into two;
+ * the newly created loop will contain eDel.Dst. If the deletion of eDel
+ * would create isolated vertices, those are deleted as well.
+ *
+ * This function could be implemented as two calls to __gl_meshSplice
+ * plus a few calls to memFree, but this would allocate and delete
+ * unnecessary vertices and faces.
+ */
+ static boolean __gl_meshDelete(com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eDel) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eDelSym = eDel.Sym;
+ boolean joiningLoops = false;
+
+ /* First step: disconnect the origin vertex eDel.Org. We make all
+ * changes to get a consistent mesh in this "intermediate" state.
+ */
+ if (eDel.Lface != eDel.Sym.Lface) {
+ /* We are joining two loops into one -- remove the left face */
+ joiningLoops = true;
+ KillFace(eDel.Lface, eDel.Sym.Lface);
+ }
+
+ if (eDel.Onext == eDel) {
+ KillVertex(eDel.Org, null);
+ } else {
+ /* Make sure that eDel.Org and eDel.Sym.Lface point to valid half-edges */
+ eDel.Sym.Lface.anEdge = eDel.Sym.Lnext;
+ eDel.Org.anEdge = eDel.Onext;
+
+ Splice(eDel, eDel.Sym.Lnext);
+ if (!joiningLoops) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUface newFace = new com.jogamp.opengl.impl.glu.tessellator.GLUface();
+
+ /* We are splitting one loop into two -- create a new loop for eDel. */
+ MakeFace(newFace, eDel, eDel.Lface);
+ }
+ }
+
+ /* Claim: the mesh is now in a consistent state, except that eDel.Org
+ * may have been deleted. Now we disconnect eDel.Dst.
+ */
+ if (eDelSym.Onext == eDelSym) {
+ KillVertex(eDelSym.Org, null);
+ KillFace(eDelSym.Lface, null);
+ } else {
+ /* Make sure that eDel.Dst and eDel.Lface point to valid half-edges */
+ eDel.Lface.anEdge = eDelSym.Sym.Lnext;
+ eDelSym.Org.anEdge = eDelSym.Onext;
+ Splice(eDelSym, eDelSym.Sym.Lnext);
+ }
+
+ /* Any isolated vertices or faces have already been freed. */
+ KillEdge(eDel);
+
+ return true;
+ }
+
+
+ /******************** Other Edge Operations **********************/
+
+/* All these routines can be implemented with the basic edge
+ * operations above. They are provided for convenience and efficiency.
+ */
+
+
+/* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
+ * eNew == eOrg.Lnext, and eNew.Dst is a newly created vertex.
+ * eOrg and eNew will have the same left face.
+ */
+ static com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge __gl_meshAddEdgeVertex(com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eOrg) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eNewSym;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eNew = MakeEdge(eOrg);
+
+ eNewSym = eNew.Sym;
+
+ /* Connect the new edge appropriately */
+ Splice(eNew, eOrg.Lnext);
+
+ /* Set the vertex and face information */
+ eNew.Org = eOrg.Sym.Org;
+ {
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex newVertex = new com.jogamp.opengl.impl.glu.tessellator.GLUvertex();
+
+ MakeVertex(newVertex, eNewSym, eNew.Org);
+ }
+ eNew.Lface = eNewSym.Lface = eOrg.Lface;
+
+ return eNew;
+ }
+
+
+/* __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,
+ * such that eNew == eOrg.Lnext. The new vertex is eOrg.Sym.Org == eNew.Org.
+ * eOrg and eNew will have the same left face.
+ */
+ public static com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge __gl_meshSplitEdge(com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eOrg) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eNew;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge tempHalfEdge = __gl_meshAddEdgeVertex(eOrg);
+
+ eNew = tempHalfEdge.Sym;
+
+ /* Disconnect eOrg from eOrg.Sym.Org and connect it to eNew.Org */
+ Splice(eOrg.Sym, eOrg.Sym.Sym.Lnext);
+ Splice(eOrg.Sym, eNew);
+
+ /* Set the vertex and face information */
+ eOrg.Sym.Org = eNew.Org;
+ eNew.Sym.Org.anEdge = eNew.Sym; /* may have pointed to eOrg.Sym */
+ eNew.Sym.Lface = eOrg.Sym.Lface;
+ eNew.winding = eOrg.winding; /* copy old winding information */
+ eNew.Sym.winding = eOrg.Sym.winding;
+
+ return eNew;
+ }
+
+
+/* __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg.Sym.Org
+ * to eDst.Org, and returns the corresponding half-edge eNew.
+ * If eOrg.Lface == eDst.Lface, this splits one loop into two,
+ * and the newly created loop is eNew.Lface. Otherwise, two disjoint
+ * loops are merged into one, and the loop eDst.Lface is destroyed.
+ *
+ * If (eOrg == eDst), the new face will have only two edges.
+ * If (eOrg.Lnext == eDst), the old face is reduced to a single edge.
+ * If (eOrg.Lnext.Lnext == eDst), the old face is reduced to two edges.
+ */
+ static com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge __gl_meshConnect(com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eOrg, com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eDst) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eNewSym;
+ boolean joiningLoops = false;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eNew = MakeEdge(eOrg);
+
+ eNewSym = eNew.Sym;
+
+ if (eDst.Lface != eOrg.Lface) {
+ /* We are connecting two disjoint loops -- destroy eDst.Lface */
+ joiningLoops = true;
+ KillFace(eDst.Lface, eOrg.Lface);
+ }
+
+ /* Connect the new edge appropriately */
+ Splice(eNew, eOrg.Lnext);
+ Splice(eNewSym, eDst);
+
+ /* Set the vertex and face information */
+ eNew.Org = eOrg.Sym.Org;
+ eNewSym.Org = eDst.Org;
+ eNew.Lface = eNewSym.Lface = eOrg.Lface;
+
+ /* Make sure the old face points to a valid half-edge */
+ eOrg.Lface.anEdge = eNewSym;
+
+ if (!joiningLoops) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUface newFace = new com.jogamp.opengl.impl.glu.tessellator.GLUface();
+
+ /* We split one loop into two -- the new loop is eNew.Lface */
+ MakeFace(newFace, eNew, eOrg.Lface);
+ }
+ return eNew;
+ }
+
+
+ /******************** Other Operations **********************/
+
+/* __gl_meshZapFace( fZap ) destroys a face and removes it from the
+ * global face list. All edges of fZap will have a null pointer as their
+ * left face. Any edges which also have a null pointer as their right face
+ * are deleted entirely (along with any isolated vertices this produces).
+ * An entire mesh can be deleted by zapping its faces, one at a time,
+ * in any order. Zapped faces cannot be used in further mesh operations!
+ */
+ static void __gl_meshZapFace(com.jogamp.opengl.impl.glu.tessellator.GLUface fZap) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eStart = fZap.anEdge;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e, eNext, eSym;
+ com.jogamp.opengl.impl.glu.tessellator.GLUface fPrev, fNext;
+
+ /* walk around face, deleting edges whose right face is also null */
+ eNext = eStart.Lnext;
+ do {
+ e = eNext;
+ eNext = e.Lnext;
+
+ e.Lface = null;
+ if (e.Sym.Lface == null) {
+ /* delete the edge -- see __gl_MeshDelete above */
+
+ if (e.Onext == e) {
+ KillVertex(e.Org, null);
+ } else {
+ /* Make sure that e.Org points to a valid half-edge */
+ e.Org.anEdge = e.Onext;
+ Splice(e, e.Sym.Lnext);
+ }
+ eSym = e.Sym;
+ if (eSym.Onext == eSym) {
+ KillVertex(eSym.Org, null);
+ } else {
+ /* Make sure that eSym.Org points to a valid half-edge */
+ eSym.Org.anEdge = eSym.Onext;
+ Splice(eSym, eSym.Sym.Lnext);
+ }
+ KillEdge(e);
+ }
+ } while (e != eStart);
+
+ /* delete from circular doubly-linked list */
+ fPrev = fZap.prev;
+ fNext = fZap.next;
+ fNext.prev = fPrev;
+ fPrev.next = fNext;
+ }
+
+
+/* __gl_meshNewMesh() creates a new mesh with no edges, no vertices,
+ * and no loops (what we usually call a "face").
+ */
+ public static com.jogamp.opengl.impl.glu.tessellator.GLUmesh __gl_meshNewMesh() {
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex v;
+ com.jogamp.opengl.impl.glu.tessellator.GLUface f;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eSym;
+ com.jogamp.opengl.impl.glu.tessellator.GLUmesh mesh = new com.jogamp.opengl.impl.glu.tessellator.GLUmesh();
+
+ v = mesh.vHead;
+ f = mesh.fHead;
+ e = mesh.eHead;
+ eSym = mesh.eHeadSym;
+
+ v.next = v.prev = v;
+ v.anEdge = null;
+ v.data = null;
+
+ f.next = f.prev = f;
+ f.anEdge = null;
+ f.data = null;
+ f.trail = null;
+ f.marked = false;
+ f.inside = false;
+
+ e.next = e;
+ e.Sym = eSym;
+ e.Onext = null;
+ e.Lnext = null;
+ e.Org = null;
+ e.Lface = null;
+ e.winding = 0;
+ e.activeRegion = null;
+
+ eSym.next = eSym;
+ eSym.Sym = e;
+ eSym.Onext = null;
+ eSym.Lnext = null;
+ eSym.Org = null;
+ eSym.Lface = null;
+ eSym.winding = 0;
+ eSym.activeRegion = null;
+
+ return mesh;
+ }
+
+
+/* __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
+ * both meshes, and returns the new mesh (the old meshes are destroyed).
+ */
+ static com.jogamp.opengl.impl.glu.tessellator.GLUmesh __gl_meshUnion(com.jogamp.opengl.impl.glu.tessellator.GLUmesh mesh1, com.jogamp.opengl.impl.glu.tessellator.GLUmesh mesh2) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUface f1 = mesh1.fHead;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex v1 = mesh1.vHead;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e1 = mesh1.eHead;
+ com.jogamp.opengl.impl.glu.tessellator.GLUface f2 = mesh2.fHead;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex v2 = mesh2.vHead;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e2 = mesh2.eHead;
+
+ /* Add the faces, vertices, and edges of mesh2 to those of mesh1 */
+ if (f2.next != f2) {
+ f1.prev.next = f2.next;
+ f2.next.prev = f1.prev;
+ f2.prev.next = f1;
+ f1.prev = f2.prev;
+ }
+
+ if (v2.next != v2) {
+ v1.prev.next = v2.next;
+ v2.next.prev = v1.prev;
+ v2.prev.next = v1;
+ v1.prev = v2.prev;
+ }
+
+ if (e2.next != e2) {
+ e1.Sym.next.Sym.next = e2.next;
+ e2.next.Sym.next = e1.Sym.next;
+ e2.Sym.next.Sym.next = e1;
+ e1.Sym.next = e2.Sym.next;
+ }
+
+ return mesh1;
+ }
+
+
+/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
+ */
+ static void __gl_meshDeleteMeshZap(com.jogamp.opengl.impl.glu.tessellator.GLUmesh mesh) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUface fHead = mesh.fHead;
+
+ while (fHead.next != fHead) {
+ __gl_meshZapFace(fHead.next);
+ }
+ assert (mesh.vHead.next == mesh.vHead);
+ }
+
+/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
+ */
+ public static void __gl_meshDeleteMesh(com.jogamp.opengl.impl.glu.tessellator.GLUmesh mesh) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUface f, fNext;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex v, vNext;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e, eNext;
+
+ for (f = mesh.fHead.next; f != mesh.fHead; f = fNext) {
+ fNext = f.next;
+ }
+
+ for (v = mesh.vHead.next; v != mesh.vHead; v = vNext) {
+ vNext = v.next;
+ }
+
+ for (e = mesh.eHead.next; e != mesh.eHead; e = eNext) {
+ /* One call frees both e and e.Sym (see EdgePair above) */
+ eNext = e.next;
+ }
+ }
+
+/* __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
+ */
+ public static void __gl_meshCheckMesh(com.jogamp.opengl.impl.glu.tessellator.GLUmesh mesh) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUface fHead = mesh.fHead;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex vHead = mesh.vHead;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eHead = mesh.eHead;
+ com.jogamp.opengl.impl.glu.tessellator.GLUface f, fPrev;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex v, vPrev;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e, ePrev;
+
+ fPrev = fHead;
+ for (fPrev = fHead; (f = fPrev.next) != fHead; fPrev = f) {
+ assert (f.prev == fPrev);
+ e = f.anEdge;
+ do {
+ assert (e.Sym != e);
+ assert (e.Sym.Sym == e);
+ assert (e.Lnext.Onext.Sym == e);
+ assert (e.Onext.Sym.Lnext == e);
+ assert (e.Lface == f);
+ e = e.Lnext;
+ } while (e != f.anEdge);
+ }
+ assert (f.prev == fPrev && f.anEdge == null && f.data == null);
+
+ vPrev = vHead;
+ for (vPrev = vHead; (v = vPrev.next) != vHead; vPrev = v) {
+ assert (v.prev == vPrev);
+ e = v.anEdge;
+ do {
+ assert (e.Sym != e);
+ assert (e.Sym.Sym == e);
+ assert (e.Lnext.Onext.Sym == e);
+ assert (e.Onext.Sym.Lnext == e);
+ assert (e.Org == v);
+ e = e.Onext;
+ } while (e != v.anEdge);
+ }
+ assert (v.prev == vPrev && v.anEdge == null && v.data == null);
+
+ ePrev = eHead;
+ for (ePrev = eHead; (e = ePrev.next) != eHead; ePrev = e) {
+ assert (e.Sym.next == ePrev.Sym);
+ assert (e.Sym != e);
+ assert (e.Sym.Sym == e);
+ assert (e.Org != null);
+ assert (e.Sym.Org != null);
+ assert (e.Lnext.Onext.Sym == e);
+ assert (e.Onext.Sym.Lnext == e);
+ }
+ assert (e.Sym.next == ePrev.Sym
+ && e.Sym == mesh.eHeadSym
+ && e.Sym.Sym == e
+ && e.Org == null && e.Sym.Org == null
+ && e.Lface == null && e.Sym.Lface == null);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Normal.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Normal.java
new file mode 100644
index 000000000..fe1a20c49
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Normal.java
@@ -0,0 +1,288 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+class Normal {
+ private Normal() {
+ }
+
+ static boolean SLANTED_SWEEP = false;
+ static double S_UNIT_X; /* Pre-normalized */
+ static double S_UNIT_Y;
+ private static final boolean TRUE_PROJECT = false;
+
+ static {
+ if (SLANTED_SWEEP) {
+/* The "feature merging" is not intended to be complete. There are
+ * special cases where edges are nearly parallel to the sweep line
+ * which are not implemented. The algorithm should still behave
+ * robustly (ie. produce a reasonable tesselation) in the presence
+ * of such edges, however it may miss features which could have been
+ * merged. We could minimize this effect by choosing the sweep line
+ * direction to be something unusual (ie. not parallel to one of the
+ * coordinate axes).
+ */
+ S_UNIT_X = 0.50941539564955385; /* Pre-normalized */
+ S_UNIT_Y = 0.86052074622010633;
+ } else {
+ S_UNIT_X = 1.0;
+ S_UNIT_Y = 0.0;
+ }
+ }
+
+ private static double Dot(double[] u, double[] v) {
+ return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]);
+ }
+
+ static void Normalize(double[] v) {
+ double len = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
+
+ assert (len > 0);
+ len = Math.sqrt(len);
+ v[0] /= len;
+ v[1] /= len;
+ v[2] /= len;
+ }
+
+ static int LongAxis(double[] v) {
+ int i = 0;
+
+ if (Math.abs(v[1]) > Math.abs(v[0])) {
+ i = 1;
+ }
+ if (Math.abs(v[2]) > Math.abs(v[i])) {
+ i = 2;
+ }
+ return i;
+ }
+
+ static void ComputeNormal(GLUtessellatorImpl tess, double[] norm) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex v, v1, v2;
+ double c, tLen2, maxLen2;
+ double[] maxVal, minVal, d1, d2, tNorm;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex[] maxVert, minVert;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex vHead = tess.mesh.vHead;
+ int i;
+
+ maxVal = new double[3];
+ minVal = new double[3];
+ minVert = new com.jogamp.opengl.impl.glu.tessellator.GLUvertex[3];
+ maxVert = new com.jogamp.opengl.impl.glu.tessellator.GLUvertex[3];
+ d1 = new double[3];
+ d2 = new double[3];
+ tNorm = new double[3];
+
+ maxVal[0] = maxVal[1] = maxVal[2] = -2 * GLU.GLU_TESS_MAX_COORD;
+ minVal[0] = minVal[1] = minVal[2] = 2 * GLU.GLU_TESS_MAX_COORD;
+
+ for (v = vHead.next; v != vHead; v = v.next) {
+ for (i = 0; i < 3; ++i) {
+ c = v.coords[i];
+ if (c < minVal[i]) {
+ minVal[i] = c;
+ minVert[i] = v;
+ }
+ if (c > maxVal[i]) {
+ maxVal[i] = c;
+ maxVert[i] = v;
+ }
+ }
+ }
+
+/* Find two vertices separated by at least 1/sqrt(3) of the maximum
+ * distance between any two vertices
+ */
+ i = 0;
+ if (maxVal[1] - minVal[1] > maxVal[0] - minVal[0]) {
+ i = 1;
+ }
+ if (maxVal[2] - minVal[2] > maxVal[i] - minVal[i]) {
+ i = 2;
+ }
+ if (minVal[i] >= maxVal[i]) {
+/* All vertices are the same -- normal doesn't matter */
+ norm[0] = 0;
+ norm[1] = 0;
+ norm[2] = 1;
+ return;
+ }
+
+/* Look for a third vertex which forms the triangle with maximum area
+ * (Length of normal == twice the triangle area)
+ */
+ maxLen2 = 0;
+ v1 = minVert[i];
+ v2 = maxVert[i];
+ d1[0] = v1.coords[0] - v2.coords[0];
+ d1[1] = v1.coords[1] - v2.coords[1];
+ d1[2] = v1.coords[2] - v2.coords[2];
+ for (v = vHead.next; v != vHead; v = v.next) {
+ d2[0] = v.coords[0] - v2.coords[0];
+ d2[1] = v.coords[1] - v2.coords[1];
+ d2[2] = v.coords[2] - v2.coords[2];
+ tNorm[0] = d1[1] * d2[2] - d1[2] * d2[1];
+ tNorm[1] = d1[2] * d2[0] - d1[0] * d2[2];
+ tNorm[2] = d1[0] * d2[1] - d1[1] * d2[0];
+ tLen2 = tNorm[0] * tNorm[0] + tNorm[1] * tNorm[1] + tNorm[2] * tNorm[2];
+ if (tLen2 > maxLen2) {
+ maxLen2 = tLen2;
+ norm[0] = tNorm[0];
+ norm[1] = tNorm[1];
+ norm[2] = tNorm[2];
+ }
+ }
+
+ if (maxLen2 <= 0) {
+/* All points lie on a single line -- any decent normal will do */
+ norm[0] = norm[1] = norm[2] = 0;
+ norm[LongAxis(d1)] = 1;
+ }
+ }
+
+ static void CheckOrientation(GLUtessellatorImpl tess) {
+ double area;
+ com.jogamp.opengl.impl.glu.tessellator.GLUface f, fHead = tess.mesh.fHead;
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex v, vHead = tess.mesh.vHead;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e;
+
+/* When we compute the normal automatically, we choose the orientation
+ * so that the the sum of the signed areas of all contours is non-negative.
+ */
+ area = 0;
+ for (f = fHead.next; f != fHead; f = f.next) {
+ e = f.anEdge;
+ if (e.winding <= 0) continue;
+ do {
+ area += (e.Org.s - e.Sym.Org.s) * (e.Org.t + e.Sym.Org.t);
+ e = e.Lnext;
+ } while (e != f.anEdge);
+ }
+ if (area < 0) {
+/* Reverse the orientation by flipping all the t-coordinates */
+ for (v = vHead.next; v != vHead; v = v.next) {
+ v.t = -v.t;
+ }
+ tess.tUnit[0] = -tess.tUnit[0];
+ tess.tUnit[1] = -tess.tUnit[1];
+ tess.tUnit[2] = -tess.tUnit[2];
+ }
+ }
+
+/* Determine the polygon normal and project vertices onto the plane
+ * of the polygon.
+ */
+ public static void __gl_projectPolygon(GLUtessellatorImpl tess) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUvertex v, vHead = tess.mesh.vHead;
+ double w;
+ double[] norm = new double[3];
+ double[] sUnit, tUnit;
+ int i;
+ boolean computedNormal = false;
+
+ norm[0] = tess.normal[0];
+ norm[1] = tess.normal[1];
+ norm[2] = tess.normal[2];
+ if (norm[0] == 0 && norm[1] == 0 && norm[2] == 0) {
+ ComputeNormal(tess, norm);
+ computedNormal = true;
+ }
+ sUnit = tess.sUnit;
+ tUnit = tess.tUnit;
+ i = LongAxis(norm);
+
+ if (TRUE_PROJECT) {
+/* Choose the initial sUnit vector to be approximately perpendicular
+ * to the normal.
+ */
+ Normalize(norm);
+
+ sUnit[i] = 0;
+ sUnit[(i + 1) % 3] = S_UNIT_X;
+ sUnit[(i + 2) % 3] = S_UNIT_Y;
+
+/* Now make it exactly perpendicular */
+ w = Dot(sUnit, norm);
+ sUnit[0] -= w * norm[0];
+ sUnit[1] -= w * norm[1];
+ sUnit[2] -= w * norm[2];
+ Normalize(sUnit);
+
+/* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */
+ tUnit[0] = norm[1] * sUnit[2] - norm[2] * sUnit[1];
+ tUnit[1] = norm[2] * sUnit[0] - norm[0] * sUnit[2];
+ tUnit[2] = norm[0] * sUnit[1] - norm[1] * sUnit[0];
+ Normalize(tUnit);
+ } else {
+/* Project perpendicular to a coordinate axis -- better numerically */
+ sUnit[i] = 0;
+ sUnit[(i + 1) % 3] = S_UNIT_X;
+ sUnit[(i + 2) % 3] = S_UNIT_Y;
+
+ tUnit[i] = 0;
+ tUnit[(i + 1) % 3] = (norm[i] > 0) ? -S_UNIT_Y : S_UNIT_Y;
+ tUnit[(i + 2) % 3] = (norm[i] > 0) ? S_UNIT_X : -S_UNIT_X;
+ }
+
+/* Project the vertices onto the sweep plane */
+ for (v = vHead.next; v != vHead; v = v.next) {
+ v.s = Dot(v.coords, sUnit);
+ v.t = Dot(v.coords, tUnit);
+ }
+ if (computedNormal) {
+ CheckOrientation(tess);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQ.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQ.java
new file mode 100644
index 000000000..b77305ae2
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQ.java
@@ -0,0 +1,100 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+abstract class PriorityQ {
+ public static final int INIT_SIZE = 32;
+
+ public static class PQnode {
+ int handle;
+ }
+
+ public static class PQhandleElem {
+ Object key;
+ int node;
+ }
+
+ public static interface Leq {
+ boolean leq(Object key1, Object key2);
+ }
+
+ // #ifdef FOR_TRITE_TEST_PROGRAM
+// private static boolean LEQ(PriorityQCommon.Leq leq, Object x,Object y) {
+// return pq.leq.leq(x,y);
+// }
+// #else
+/* Violates modularity, but a little faster */
+// #include "geom.h"
+ public static boolean LEQ(Leq leq, Object x, Object y) {
+ return com.jogamp.opengl.impl.glu.tessellator.Geom.VertLeq((com.jogamp.opengl.impl.glu.tessellator.GLUvertex) x, (com.jogamp.opengl.impl.glu.tessellator.GLUvertex) y);
+ }
+
+ static PriorityQ pqNewPriorityQ(Leq leq) {
+ return new PriorityQSort(leq);
+ }
+
+ abstract void pqDeletePriorityQ();
+
+ abstract boolean pqInit();
+
+ abstract int pqInsert(Object keyNew);
+
+ abstract Object pqExtractMin();
+
+ abstract void pqDelete(int hCurr);
+
+ abstract Object pqMinimum();
+
+ abstract boolean pqIsEmpty();
+// #endif
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQHeap.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQHeap.java
new file mode 100644
index 000000000..61aa9574f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQHeap.java
@@ -0,0 +1,262 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class PriorityQHeap extends com.jogamp.opengl.impl.glu.tessellator.PriorityQ {
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQnode[] nodes;
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQhandleElem[] handles;
+ int size, max;
+ int freeList;
+ boolean initialized;
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.Leq leq;
+
+/* really __gl_pqHeapNewPriorityQ */
+ public PriorityQHeap(com.jogamp.opengl.impl.glu.tessellator.PriorityQ.Leq leq) {
+ size = 0;
+ max = com.jogamp.opengl.impl.glu.tessellator.PriorityQ.INIT_SIZE;
+ nodes = new com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQnode[com.jogamp.opengl.impl.glu.tessellator.PriorityQ.INIT_SIZE + 1];
+ for (int i = 0; i < nodes.length; i++) {
+ nodes[i] = new PQnode();
+ }
+ handles = new com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQhandleElem[com.jogamp.opengl.impl.glu.tessellator.PriorityQ.INIT_SIZE + 1];
+ for (int i = 0; i < handles.length; i++) {
+ handles[i] = new PQhandleElem();
+ }
+ initialized = false;
+ freeList = 0;
+ this.leq = leq;
+
+ nodes[1].handle = 1; /* so that Minimum() returns NULL */
+ handles[1].key = null;
+ }
+
+/* really __gl_pqHeapDeletePriorityQ */
+ void pqDeletePriorityQ() {
+ handles = null;
+ nodes = null;
+ }
+
+ void FloatDown(int curr) {
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQnode[] n = nodes;
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQhandleElem[] h = handles;
+ int hCurr, hChild;
+ int child;
+
+ hCurr = n[curr].handle;
+ for (; ;) {
+ child = curr << 1;
+ if (child < size && LEQ(leq, h[n[child + 1].handle].key,
+ h[n[child].handle].key)) {
+ ++child;
+ }
+
+ assert (child <= max);
+
+ hChild = n[child].handle;
+ if (child > size || LEQ(leq, h[hCurr].key, h[hChild].key)) {
+ n[curr].handle = hCurr;
+ h[hCurr].node = curr;
+ break;
+ }
+ n[curr].handle = hChild;
+ h[hChild].node = curr;
+ curr = child;
+ }
+ }
+
+
+ void FloatUp(int curr) {
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQnode[] n = nodes;
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQhandleElem[] h = handles;
+ int hCurr, hParent;
+ int parent;
+
+ hCurr = n[curr].handle;
+ for (; ;) {
+ parent = curr >> 1;
+ hParent = n[parent].handle;
+ if (parent == 0 || LEQ(leq, h[hParent].key, h[hCurr].key)) {
+ n[curr].handle = hCurr;
+ h[hCurr].node = curr;
+ break;
+ }
+ n[curr].handle = hParent;
+ h[hParent].node = curr;
+ curr = parent;
+ }
+ }
+
+/* really __gl_pqHeapInit */
+ boolean pqInit() {
+ int i;
+
+ /* This method of building a heap is O(n), rather than O(n lg n). */
+
+ for (i = size; i >= 1; --i) {
+ FloatDown(i);
+ }
+ initialized = true;
+
+ return true;
+ }
+
+/* really __gl_pqHeapInsert */
+/* returns LONG_MAX iff out of memory */
+ int pqInsert(Object keyNew) {
+ int curr;
+ int free;
+
+ curr = ++size;
+ if ((curr * 2) > max) {
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQnode[] saveNodes = nodes;
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQhandleElem[] saveHandles = handles;
+
+ /* If the heap overflows, double its size. */
+ max <<= 1;
+// pq->nodes = (PQnode *)memRealloc( pq->nodes, (size_t) ((pq->max + 1) * sizeof( pq->nodes[0] )));
+ PriorityQ.PQnode[] pqNodes = new PriorityQ.PQnode[max + 1];
+ System.arraycopy( nodes, 0, pqNodes, 0, nodes.length );
+ for (int i = nodes.length; i < pqNodes.length; i++) {
+ pqNodes[i] = new PQnode();
+ }
+ nodes = pqNodes;
+ if (nodes == null) {
+ nodes = saveNodes; /* restore ptr to free upon return */
+ return Integer.MAX_VALUE;
+ }
+
+// pq->handles = (PQhandleElem *)memRealloc( pq->handles,(size_t)((pq->max + 1) * sizeof( pq->handles[0] )));
+ PriorityQ.PQhandleElem[] pqHandles = new PriorityQ.PQhandleElem[max + 1];
+ System.arraycopy( handles, 0, pqHandles, 0, handles.length );
+ for (int i = handles.length; i < pqHandles.length; i++) {
+ pqHandles[i] = new PQhandleElem();
+ }
+ handles = pqHandles;
+ if (handles == null) {
+ handles = saveHandles; /* restore ptr to free upon return */
+ return Integer.MAX_VALUE;
+ }
+ }
+
+ if (freeList == 0) {
+ free = curr;
+ } else {
+ free = freeList;
+ freeList = handles[free].node;
+ }
+
+ nodes[curr].handle = free;
+ handles[free].node = curr;
+ handles[free].key = keyNew;
+
+ if (initialized) {
+ FloatUp(curr);
+ }
+ assert (free != Integer.MAX_VALUE);
+ return free;
+ }
+
+/* really __gl_pqHeapExtractMin */
+ Object pqExtractMin() {
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQnode[] n = nodes;
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQhandleElem[] h = handles;
+ int hMin = n[1].handle;
+ Object min = h[hMin].key;
+
+ if (size > 0) {
+ n[1].handle = n[size].handle;
+ h[n[1].handle].node = 1;
+
+ h[hMin].key = null;
+ h[hMin].node = freeList;
+ freeList = hMin;
+
+ if (--size > 0) {
+ FloatDown(1);
+ }
+ }
+ return min;
+ }
+
+/* really __gl_pqHeapDelete */
+ void pqDelete(int hCurr) {
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQnode[] n = nodes;
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.PQhandleElem[] h = handles;
+ int curr;
+
+ assert (hCurr >= 1 && hCurr <= max && h[hCurr].key != null);
+
+ curr = h[hCurr].node;
+ n[curr].handle = n[size].handle;
+ h[n[curr].handle].node = curr;
+
+ if (curr <= --size) {
+ if (curr <= 1 || LEQ(leq, h[n[curr >> 1].handle].key, h[n[curr].handle].key)) {
+ FloatDown(curr);
+ } else {
+ FloatUp(curr);
+ }
+ }
+ h[hCurr].key = null;
+ h[hCurr].node = freeList;
+ freeList = hCurr;
+ }
+
+ Object pqMinimum() {
+ return handles[nodes[1].handle].key;
+ }
+
+ boolean pqIsEmpty() {
+ return size == 0;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQSort.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQSort.java
new file mode 100644
index 000000000..f115b8f49
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/PriorityQSort.java
@@ -0,0 +1,278 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class PriorityQSort extends com.jogamp.opengl.impl.glu.tessellator.PriorityQ {
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQHeap heap;
+ Object[] keys;
+
+ // JAVA: 'order' contains indices into the keys array.
+ // This simulates the indirect pointers used in the original C code
+ // (from Frank Suykens, Luciad.com).
+ int[] order;
+ int size, max;
+ boolean initialized;
+ com.jogamp.opengl.impl.glu.tessellator.PriorityQ.Leq leq;
+
+ public PriorityQSort(com.jogamp.opengl.impl.glu.tessellator.PriorityQ.Leq leq) {
+ heap = new com.jogamp.opengl.impl.glu.tessellator.PriorityQHeap(leq);
+
+ keys = new Object[com.jogamp.opengl.impl.glu.tessellator.PriorityQ.INIT_SIZE];
+
+ size = 0;
+ max = com.jogamp.opengl.impl.glu.tessellator.PriorityQ.INIT_SIZE;
+ initialized = false;
+ this.leq = leq;
+ }
+
+/* really __gl_pqSortDeletePriorityQ */
+ void pqDeletePriorityQ() {
+ if (heap != null) heap.pqDeletePriorityQ();
+ order = null;
+ keys = null;
+ }
+
+ private static boolean LT(com.jogamp.opengl.impl.glu.tessellator.PriorityQ.Leq leq, Object x, Object y) {
+ return (!com.jogamp.opengl.impl.glu.tessellator.PriorityQHeap.LEQ(leq, y, x));
+ }
+
+ private static boolean GT(com.jogamp.opengl.impl.glu.tessellator.PriorityQ.Leq leq, Object x, Object y) {
+ return (!com.jogamp.opengl.impl.glu.tessellator.PriorityQHeap.LEQ(leq, x, y));
+ }
+
+ private static void Swap(int[] array, int a, int b) {
+ if (true) {
+ int tmp = array[a];
+ array[a] = array[b];
+ array[b] = tmp;
+ } else {
+
+ }
+ }
+
+ private static class Stack {
+ int p, r;
+ }
+
+/* really __gl_pqSortInit */
+ boolean pqInit() {
+ int p, r, i, j;
+ int piv;
+ Stack[] stack = new Stack[50];
+ for (int k = 0; k < stack.length; k++) {
+ stack[k] = new Stack();
+ }
+ int top = 0;
+
+ int seed = 2016473283;
+
+ /* Create an array of indirect pointers to the keys, so that we
+ * the handles we have returned are still valid.
+ */
+ order = new int[size + 1];
+/* the previous line is a patch to compensate for the fact that IBM */
+/* machines return a null on a malloc of zero bytes (unlike SGI), */
+/* so we have to put in this defense to guard against a memory */
+/* fault four lines down. from [email protected]. */
+ p = 0;
+ r = size - 1;
+ for (piv = 0, i = p; i <= r; ++piv, ++i) {
+ // indirect pointers: keep an index into the keys array, not a direct pointer to its contents
+ order[i] = piv;
+ }
+
+ /* Sort the indirect pointers in descending order,
+ * using randomized Quicksort
+ */
+ stack[top].p = p;
+ stack[top].r = r;
+ ++top;
+ while (--top >= 0) {
+ p = stack[top].p;
+ r = stack[top].r;
+ while (r > p + 10) {
+ seed = Math.abs( seed * 1539415821 + 1 );
+ i = p + seed % (r - p + 1);
+ piv = order[i];
+ order[i] = order[p];
+ order[p] = piv;
+ i = p - 1;
+ j = r + 1;
+ do {
+ do {
+ ++i;
+ } while (GT(leq, keys[order[i]], keys[piv]));
+ do {
+ --j;
+ } while (LT(leq, keys[order[j]], keys[piv]));
+ Swap(order, i, j);
+ } while (i < j);
+ Swap(order, i, j); /* Undo last swap */
+ if (i - p < r - j) {
+ stack[top].p = j + 1;
+ stack[top].r = r;
+ ++top;
+ r = i - 1;
+ } else {
+ stack[top].p = p;
+ stack[top].r = i - 1;
+ ++top;
+ p = j + 1;
+ }
+ }
+ /* Insertion sort small lists */
+ for (i = p + 1; i <= r; ++i) {
+ piv = order[i];
+ for (j = i; j > p && LT(leq, keys[order[j - 1]], keys[piv]); --j) {
+ order[j] = order[j - 1];
+ }
+ order[j] = piv;
+ }
+ }
+ max = size;
+ initialized = true;
+ heap.pqInit(); /* always succeeds */
+
+/* #ifndef NDEBUG
+ p = order;
+ r = p + size - 1;
+ for (i = p; i < r; ++i) {
+ Assertion.doAssert(LEQ( * * (i + 1), **i ));
+ }
+ #endif*/
+
+ return true;
+ }
+
+/* really __gl_pqSortInsert */
+/* returns LONG_MAX iff out of memory */
+ int pqInsert(Object keyNew) {
+ int curr;
+
+ if (initialized) {
+ return heap.pqInsert(keyNew);
+ }
+ curr = size;
+ if (++size >= max) {
+ Object[] saveKey = keys;
+
+ /* If the heap overflows, double its size. */
+ max <<= 1;
+// pq->keys = (PQHeapKey *)memRealloc( pq->keys,(size_t)(pq->max * sizeof( pq->keys[0] )));
+ Object[] pqKeys = new Object[max];
+ System.arraycopy( keys, 0, pqKeys, 0, keys.length );
+ keys = pqKeys;
+ if (keys == null) {
+ keys = saveKey; /* restore ptr to free upon return */
+ return Integer.MAX_VALUE;
+ }
+ }
+ assert curr != Integer.MAX_VALUE;
+ keys[curr] = keyNew;
+
+ /* Negative handles index the sorted array. */
+ return -(curr + 1);
+ }
+
+/* really __gl_pqSortExtractMin */
+ Object pqExtractMin() {
+ Object sortMin, heapMin;
+
+ if (size == 0) {
+ return heap.pqExtractMin();
+ }
+ sortMin = keys[order[size - 1]];
+ if (!heap.pqIsEmpty()) {
+ heapMin = heap.pqMinimum();
+ if (LEQ(leq, heapMin, sortMin)) {
+ return heap.pqExtractMin();
+ }
+ }
+ do {
+ --size;
+ } while (size > 0 && keys[order[size - 1]] == null);
+ return sortMin;
+ }
+
+/* really __gl_pqSortMinimum */
+ Object pqMinimum() {
+ Object sortMin, heapMin;
+
+ if (size == 0) {
+ return heap.pqMinimum();
+ }
+ sortMin = keys[order[size - 1]];
+ if (!heap.pqIsEmpty()) {
+ heapMin = heap.pqMinimum();
+ if (com.jogamp.opengl.impl.glu.tessellator.PriorityQHeap.LEQ(leq, heapMin, sortMin)) {
+ return heapMin;
+ }
+ }
+ return sortMin;
+ }
+
+/* really __gl_pqSortIsEmpty */
+ boolean pqIsEmpty() {
+ return (size == 0) && heap.pqIsEmpty();
+ }
+
+/* really __gl_pqSortDelete */
+ void pqDelete(int curr) {
+ if (curr >= 0) {
+ heap.pqDelete(curr);
+ return;
+ }
+ curr = -(curr + 1);
+ assert curr < max && keys[curr] != null;
+
+ keys[curr] = null;
+ while (size > 0 && keys[order[size - 1]] == null) {
+ --size;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Render.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Render.java
new file mode 100644
index 000000000..9761200e0
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Render.java
@@ -0,0 +1,557 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+class Render {
+ private static final boolean USE_OPTIMIZED_CODE_PATH = false;
+
+ private Render() {
+ }
+
+ private static final RenderFan renderFan = new RenderFan();
+ private static final RenderStrip renderStrip = new RenderStrip();
+ private static final RenderTriangle renderTriangle = new RenderTriangle();
+
+/* This structure remembers the information we need about a primitive
+ * to be able to render it later, once we have determined which
+ * primitive is able to use the most triangles.
+ */
+ private static class FaceCount {
+ public FaceCount() {
+ }
+
+ public FaceCount(long size, com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eStart, renderCallBack render) {
+ this.size = size;
+ this.eStart = eStart;
+ this.render = render;
+ }
+
+ long size; /* number of triangles used */
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eStart; /* edge where this primitive starts */
+ renderCallBack render;
+ };
+
+ private static interface renderCallBack {
+ void render(GLUtessellatorImpl tess, com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e, long size);
+ }
+
+ /************************ Strips and Fans decomposition ******************/
+
+/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle
+ * fans, strips, and separate triangles. A substantial effort is made
+ * to use as few rendering primitives as possible (ie. to make the fans
+ * and strips as large as possible).
+ *
+ * The rendering output is provided as callbacks (see the api).
+ */
+ public static void __gl_renderMesh(GLUtessellatorImpl tess, com.jogamp.opengl.impl.glu.tessellator.GLUmesh mesh) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUface f;
+
+ /* Make a list of separate triangles so we can render them all at once */
+ tess.lonelyTriList = null;
+
+ for (f = mesh.fHead.next; f != mesh.fHead; f = f.next) {
+ f.marked = false;
+ }
+ for (f = mesh.fHead.next; f != mesh.fHead; f = f.next) {
+
+ /* We examine all faces in an arbitrary order. Whenever we find
+ * an unprocessed face F, we output a group of faces including F
+ * whose size is maximum.
+ */
+ if (f.inside && !f.marked) {
+ RenderMaximumFaceGroup(tess, f);
+ assert (f.marked);
+ }
+ }
+ if (tess.lonelyTriList != null) {
+ RenderLonelyTriangles(tess, tess.lonelyTriList);
+ tess.lonelyTriList = null;
+ }
+ }
+
+
+ static void RenderMaximumFaceGroup(GLUtessellatorImpl tess, com.jogamp.opengl.impl.glu.tessellator.GLUface fOrig) {
+ /* We want to find the largest triangle fan or strip of unmarked faces
+ * which includes the given face fOrig. There are 3 possible fans
+ * passing through fOrig (one centered at each vertex), and 3 possible
+ * strips (one for each CCW permutation of the vertices). Our strategy
+ * is to try all of these, and take the primitive which uses the most
+ * triangles (a greedy approach).
+ */
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e = fOrig.anEdge;
+ FaceCount max = new FaceCount();
+ FaceCount newFace = new FaceCount();
+
+ max.size = 1;
+ max.eStart = e;
+ max.render = renderTriangle;
+
+ if (!tess.flagBoundary) {
+ newFace = MaximumFan(e);
+ if (newFace.size > max.size) {
+ max = newFace;
+ }
+ newFace = MaximumFan(e.Lnext);
+ if (newFace.size > max.size) {
+ max = newFace;
+ }
+ newFace = MaximumFan(e.Onext.Sym);
+ if (newFace.size > max.size) {
+ max = newFace;
+ }
+
+ newFace = MaximumStrip(e);
+ if (newFace.size > max.size) {
+ max = newFace;
+ }
+ newFace = MaximumStrip(e.Lnext);
+ if (newFace.size > max.size) {
+ max = newFace;
+ }
+ newFace = MaximumStrip(e.Onext.Sym);
+ if (newFace.size > max.size) {
+ max = newFace;
+ }
+ }
+ max.render.render(tess, max.eStart, max.size);
+ }
+
+
+/* Macros which keep track of faces we have marked temporarily, and allow
+ * us to backtrack when necessary. With triangle fans, this is not
+ * really necessary, since the only awkward case is a loop of triangles
+ * around a single origin vertex. However with strips the situation is
+ * more complicated, and we need a general tracking method like the
+ * one here.
+ */
+ private static boolean Marked(com.jogamp.opengl.impl.glu.tessellator.GLUface f) {
+ return !f.inside || f.marked;
+ }
+
+ private static GLUface AddToTrail(com.jogamp.opengl.impl.glu.tessellator.GLUface f, com.jogamp.opengl.impl.glu.tessellator.GLUface t) {
+ f.trail = t;
+ f.marked = true;
+ return f;
+ }
+
+ private static void FreeTrail(com.jogamp.opengl.impl.glu.tessellator.GLUface t) {
+ if (true) {
+ while (t != null) {
+ t.marked = false;
+ t = t.trail;
+ }
+ } else {
+ /* absorb trailing semicolon */
+ }
+ }
+
+ static FaceCount MaximumFan(com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eOrig) {
+ /* eOrig.Lface is the face we want to render. We want to find the size
+ * of a maximal fan around eOrig.Org. To do this we just walk around
+ * the origin vertex as far as possible in both directions.
+ */
+ FaceCount newFace = new FaceCount(0, null, renderFan);
+ com.jogamp.opengl.impl.glu.tessellator.GLUface trail = null;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e;
+
+ for (e = eOrig; !Marked(e.Lface); e = e.Onext) {
+ trail = AddToTrail(e.Lface, trail);
+ ++newFace.size;
+ }
+ for (e = eOrig; !Marked(e.Sym.Lface); e = e.Sym.Lnext) {
+ trail = AddToTrail(e.Sym.Lface, trail);
+ ++newFace.size;
+ }
+ newFace.eStart = e;
+ /*LINTED*/
+ FreeTrail(trail);
+ return newFace;
+ }
+
+
+ private static boolean IsEven(long n) {
+ return (n & 0x1L) == 0;
+ }
+
+ static FaceCount MaximumStrip(com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge eOrig) {
+ /* Here we are looking for a maximal strip that contains the vertices
+ * eOrig.Org, eOrig.Dst, eOrig.Lnext.Dst (in that order or the
+ * reverse, such that all triangles are oriented CCW).
+ *
+ * Again we walk forward and backward as far as possible. However for
+ * strips there is a twist: to get CCW orientations, there must be
+ * an *even* number of triangles in the strip on one side of eOrig.
+ * We walk the strip starting on a side with an even number of triangles;
+ * if both side have an odd number, we are forced to shorten one side.
+ */
+ FaceCount newFace = new FaceCount(0, null, renderStrip);
+ long headSize = 0, tailSize = 0;
+ com.jogamp.opengl.impl.glu.tessellator.GLUface trail = null;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e, eTail, eHead;
+
+ for (e = eOrig; !Marked(e.Lface); ++tailSize, e = e.Onext) {
+ trail = AddToTrail(e.Lface, trail);
+ ++tailSize;
+ e = e.Lnext.Sym;
+ if (Marked(e.Lface)) break;
+ trail = AddToTrail(e.Lface, trail);
+ }
+ eTail = e;
+
+ for (e = eOrig; !Marked(e.Sym.Lface); ++headSize, e = e.Sym.Onext.Sym) {
+ trail = AddToTrail(e.Sym.Lface, trail);
+ ++headSize;
+ e = e.Sym.Lnext;
+ if (Marked(e.Sym.Lface)) break;
+ trail = AddToTrail(e.Sym.Lface, trail);
+ }
+ eHead = e;
+
+ newFace.size = tailSize + headSize;
+ if (IsEven(tailSize)) {
+ newFace.eStart = eTail.Sym;
+ } else if (IsEven(headSize)) {
+ newFace.eStart = eHead;
+ } else {
+ /* Both sides have odd length, we must shorten one of them. In fact,
+ * we must start from eHead to guarantee inclusion of eOrig.Lface.
+ */
+ --newFace.size;
+ newFace.eStart = eHead.Onext;
+ }
+ /*LINTED*/
+ FreeTrail(trail);
+ return newFace;
+ }
+
+ private static class RenderTriangle implements renderCallBack {
+ public void render(GLUtessellatorImpl tess, com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e, long size) {
+ /* Just add the triangle to a triangle list, so we can render all
+ * the separate triangles at once.
+ */
+ assert (size == 1);
+ tess.lonelyTriList = AddToTrail(e.Lface, tess.lonelyTriList);
+ }
+ }
+
+
+ static void RenderLonelyTriangles(GLUtessellatorImpl tess, com.jogamp.opengl.impl.glu.tessellator.GLUface f) {
+ /* Now we render all the separate triangles which could not be
+ * grouped into a triangle fan or strip.
+ */
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e;
+ int newState;
+ int edgeState = -1; /* force edge state output for first vertex */
+
+ tess.callBeginOrBeginData(GL.GL_TRIANGLES);
+
+ for (; f != null; f = f.trail) {
+ /* Loop once for each edge (there will always be 3 edges) */
+
+ e = f.anEdge;
+ do {
+ if (tess.flagBoundary) {
+ /* Set the "edge state" to true just before we output the
+ * first vertex of each edge on the polygon boundary.
+ */
+ newState = (!e.Sym.Lface.inside) ? 1 : 0;
+ if (edgeState != newState) {
+ edgeState = newState;
+ tess.callEdgeFlagOrEdgeFlagData( edgeState != 0);
+ }
+ }
+ tess.callVertexOrVertexData( e.Org.data);
+
+ e = e.Lnext;
+ } while (e != f.anEdge);
+ }
+ tess.callEndOrEndData();
+ }
+
+ private static class RenderFan implements renderCallBack {
+ public void render(GLUtessellatorImpl tess, com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e, long size) {
+ /* Render as many CCW triangles as possible in a fan starting from
+ * edge "e". The fan *should* contain exactly "size" triangles
+ * (otherwise we've goofed up somewhere).
+ */
+ tess.callBeginOrBeginData( GL.GL_TRIANGLE_FAN);
+ tess.callVertexOrVertexData( e.Org.data);
+ tess.callVertexOrVertexData( e.Sym.Org.data);
+
+ while (!Marked(e.Lface)) {
+ e.Lface.marked = true;
+ --size;
+ e = e.Onext;
+ tess.callVertexOrVertexData( e.Sym.Org.data);
+ }
+
+ assert (size == 0);
+ tess.callEndOrEndData();
+ }
+ }
+
+ private static class RenderStrip implements renderCallBack {
+ public void render(GLUtessellatorImpl tess, com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e, long size) {
+ /* Render as many CCW triangles as possible in a strip starting from
+ * edge "e". The strip *should* contain exactly "size" triangles
+ * (otherwise we've goofed up somewhere).
+ */
+ tess.callBeginOrBeginData( GL.GL_TRIANGLE_STRIP);
+ tess.callVertexOrVertexData( e.Org.data);
+ tess.callVertexOrVertexData( e.Sym.Org.data);
+
+ while (!Marked(e.Lface)) {
+ e.Lface.marked = true;
+ --size;
+ e = e.Lnext.Sym;
+ tess.callVertexOrVertexData( e.Org.data);
+ if (Marked(e.Lface)) break;
+
+ e.Lface.marked = true;
+ --size;
+ e = e.Onext;
+ tess.callVertexOrVertexData( e.Sym.Org.data);
+ }
+
+ assert (size == 0);
+ tess.callEndOrEndData();
+ }
+ }
+
+ /************************ Boundary contour decomposition ******************/
+
+/* __gl_renderBoundary( tess, mesh ) takes a mesh, and outputs one
+ * contour for each face marked "inside". The rendering output is
+ * provided as callbacks (see the api).
+ */
+ public static void __gl_renderBoundary(GLUtessellatorImpl tess, com.jogamp.opengl.impl.glu.tessellator.GLUmesh mesh) {
+ com.jogamp.opengl.impl.glu.tessellator.GLUface f;
+ com.jogamp.opengl.impl.glu.tessellator.GLUhalfEdge e;
+
+ for (f = mesh.fHead.next; f != mesh.fHead; f = f.next) {
+ if (f.inside) {
+ tess.callBeginOrBeginData( GL.GL_LINE_LOOP);
+ e = f.anEdge;
+ do {
+ tess.callVertexOrVertexData( e.Org.data);
+ e = e.Lnext;
+ } while (e != f.anEdge);
+ tess.callEndOrEndData();
+ }
+ }
+ }
+
+
+ /************************ Quick-and-dirty decomposition ******************/
+
+ private static final int SIGN_INCONSISTENT = 2;
+
+ static int ComputeNormal(GLUtessellatorImpl tess, double[] norm, boolean check)
+/*
+ * If check==false, we compute the polygon normal and place it in norm[].
+ * If check==true, we check that each triangle in the fan from v0 has a
+ * consistent orientation with respect to norm[]. If triangles are
+ * consistently oriented CCW, return 1; if CW, return -1; if all triangles
+ * are degenerate return 0; otherwise (no consistent orientation) return
+ * SIGN_INCONSISTENT.
+ */ {
+ com.jogamp.opengl.impl.glu.tessellator.CachedVertex[] v = tess.cache;
+// CachedVertex vn = v0 + tess.cacheCount;
+ int vn = tess.cacheCount;
+// CachedVertex vc;
+ int vc;
+ double dot, xc, yc, zc, xp, yp, zp;
+ double[] n = new double[3];
+ int sign = 0;
+
+ /* Find the polygon normal. It is important to get a reasonable
+ * normal even when the polygon is self-intersecting (eg. a bowtie).
+ * Otherwise, the computed normal could be very tiny, but perpendicular
+ * to the true plane of the polygon due to numerical noise. Then all
+ * the triangles would appear to be degenerate and we would incorrectly
+ * decompose the polygon as a fan (or simply not render it at all).
+ *
+ * We use a sum-of-triangles normal algorithm rather than the more
+ * efficient sum-of-trapezoids method (used in CheckOrientation()
+ * in normal.c). This lets us explicitly reverse the signed area
+ * of some triangles to get a reasonable normal in the self-intersecting
+ * case.
+ */
+ if (!check) {
+ norm[0] = norm[1] = norm[2] = 0.0;
+ }
+
+ vc = 1;
+ xc = v[vc].coords[0] - v[0].coords[0];
+ yc = v[vc].coords[1] - v[0].coords[1];
+ zc = v[vc].coords[2] - v[0].coords[2];
+ while (++vc < vn) {
+ xp = xc;
+ yp = yc;
+ zp = zc;
+ xc = v[vc].coords[0] - v[0].coords[0];
+ yc = v[vc].coords[1] - v[0].coords[1];
+ zc = v[vc].coords[2] - v[0].coords[2];
+
+ /* Compute (vp - v0) cross (vc - v0) */
+ n[0] = yp * zc - zp * yc;
+ n[1] = zp * xc - xp * zc;
+ n[2] = xp * yc - yp * xc;
+
+ dot = n[0] * norm[0] + n[1] * norm[1] + n[2] * norm[2];
+ if (!check) {
+ /* Reverse the contribution of back-facing triangles to get
+ * a reasonable normal for self-intersecting polygons (see above)
+ */
+ if (dot >= 0) {
+ norm[0] += n[0];
+ norm[1] += n[1];
+ norm[2] += n[2];
+ } else {
+ norm[0] -= n[0];
+ norm[1] -= n[1];
+ norm[2] -= n[2];
+ }
+ } else if (dot != 0) {
+ /* Check the new orientation for consistency with previous triangles */
+ if (dot > 0) {
+ if (sign < 0) return SIGN_INCONSISTENT;
+ sign = 1;
+ } else {
+ if (sign > 0) return SIGN_INCONSISTENT;
+ sign = -1;
+ }
+ }
+ }
+ return sign;
+ }
+
+/* __gl_renderCache( tess ) takes a single contour and tries to render it
+ * as a triangle fan. This handles convex polygons, as well as some
+ * non-convex polygons if we get lucky.
+ *
+ * Returns true if the polygon was successfully rendered. The rendering
+ * output is provided as callbacks (see the api).
+ */
+ public static boolean __gl_renderCache(GLUtessellatorImpl tess) {
+ com.jogamp.opengl.impl.glu.tessellator.CachedVertex[] v = tess.cache;
+// CachedVertex vn = v0 + tess.cacheCount;
+ int vn = tess.cacheCount;
+// CachedVertex vc;
+ int vc;
+ double[] norm = new double[3];
+ int sign;
+
+ if (tess.cacheCount < 3) {
+ /* Degenerate contour -- no output */
+ return true;
+ }
+
+ norm[0] = tess.normal[0];
+ norm[1] = tess.normal[1];
+ norm[2] = tess.normal[2];
+ if (norm[0] == 0 && norm[1] == 0 && norm[2] == 0) {
+ ComputeNormal( tess, norm, false);
+ }
+
+ sign = ComputeNormal( tess, norm, true);
+ if (sign == SIGN_INCONSISTENT) {
+ /* Fan triangles did not have a consistent orientation */
+ return false;
+ }
+ if (sign == 0) {
+ /* All triangles were degenerate */
+ return true;
+ }
+
+ if ( !USE_OPTIMIZED_CODE_PATH ) {
+ return false;
+ } else {
+ /* Make sure we do the right thing for each winding rule */
+ switch (tess.windingRule) {
+ case GLU.GLU_TESS_WINDING_ODD:
+ case GLU.GLU_TESS_WINDING_NONZERO:
+ break;
+ case GLU.GLU_TESS_WINDING_POSITIVE:
+ if (sign < 0) return true;
+ break;
+ case GLU.GLU_TESS_WINDING_NEGATIVE:
+ if (sign > 0) return true;
+ break;
+ case GLU.GLU_TESS_WINDING_ABS_GEQ_TWO:
+ return true;
+ }
+
+ tess.callBeginOrBeginData( tess.boundaryOnly ? GL.GL_LINE_LOOP
+ : (tess.cacheCount > 3) ? GL.GL_TRIANGLE_FAN
+ : GL.GL_TRIANGLES);
+
+ tess.callVertexOrVertexData( v[0].data);
+ if (sign > 0) {
+ for (vc = 1; vc < vn; ++vc) {
+ tess.callVertexOrVertexData( v[vc].data);
+ }
+ } else {
+ for (vc = vn - 1; vc > 0; --vc) {
+ tess.callVertexOrVertexData( v[vc].data);
+ }
+ }
+ tess.callEndOrEndData();
+ return true;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Sweep.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Sweep.java
new file mode 100644
index 000000000..8ffeadb67
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/Sweep.java
@@ -0,0 +1,1353 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+class Sweep {
+ private Sweep() {
+ }
+
+// #ifdef FOR_TRITE_TEST_PROGRAM
+// extern void DebugEvent( GLUtessellator *tess );
+// #else
+ private static void DebugEvent(GLUtessellatorImpl tess) {
+
+ }
+// #endif
+
+/*
+ * Invariants for the Edge Dictionary.
+ * - each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2)
+ * at any valid location of the sweep event
+ * - if EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2
+ * share a common endpoint
+ * - for each e, e.Dst has been processed, but not e.Org
+ * - each edge e satisfies VertLeq(e.Dst,event) && VertLeq(event,e.Org)
+ * where "event" is the current sweep line event.
+ * - no edge e has zero length
+ *
+ * Invariants for the Mesh (the processed portion).
+ * - the portion of the mesh left of the sweep line is a planar graph,
+ * ie. there is *some* way to embed it in the plane
+ * - no processed edge has zero length
+ * - no two processed vertices have identical coordinates
+ * - each "inside" region is monotone, ie. can be broken into two chains
+ * of monotonically increasing vertices according to VertLeq(v1,v2)
+ * - a non-invariant: these chains may intersect (very slightly)
+ *
+ * Invariants for the Sweep.
+ * - if none of the edges incident to the event vertex have an activeRegion
+ * (ie. none of these edges are in the edge dictionary), then the vertex
+ * has only right-going edges.
+ * - if an edge is marked "fixUpperEdge" (it is a temporary edge introduced
+ * by ConnectRightVertex), then it is the only right-going edge from
+ * its associated vertex. (This says that these edges exist only
+ * when it is necessary.)
+ */
+
+/* When we merge two edges into one, we need to compute the combined
+ * winding of the new edge.
+ */
+ private static void AddWinding(GLUhalfEdge eDst, GLUhalfEdge eSrc) {
+ eDst.winding += eSrc.winding;
+ eDst.Sym.winding += eSrc.Sym.winding;
+ }
+
+
+ private static ActiveRegion RegionBelow(ActiveRegion r) {
+ return ((ActiveRegion) Dict.dictKey(Dict.dictPred(r.nodeUp)));
+ }
+
+ private static ActiveRegion RegionAbove(ActiveRegion r) {
+ return ((ActiveRegion) Dict.dictKey(Dict.dictSucc(r.nodeUp)));
+ }
+
+ static boolean EdgeLeq(GLUtessellatorImpl tess, ActiveRegion reg1, ActiveRegion reg2)
+/*
+ * Both edges must be directed from right to left (this is the canonical
+ * direction for the upper edge of each region).
+ *
+ * The strategy is to evaluate a "t" value for each edge at the
+ * current sweep line position, given by tess.event. The calculations
+ * are designed to be very stable, but of course they are not perfect.
+ *
+ * Special case: if both edge destinations are at the sweep event,
+ * we sort the edges by slope (they would otherwise compare equally).
+ */ {
+ GLUvertex event = tess.event;
+ GLUhalfEdge e1, e2;
+ double t1, t2;
+
+ e1 = reg1.eUp;
+ e2 = reg2.eUp;
+
+ if (e1.Sym.Org == event) {
+ if (e2.Sym.Org == event) {
+ /* Two edges right of the sweep line which meet at the sweep event.
+ * Sort them by slope.
+ */
+ if (Geom.VertLeq(e1.Org, e2.Org)) {
+ return Geom.EdgeSign(e2.Sym.Org, e1.Org, e2.Org) <= 0;
+ }
+ return Geom.EdgeSign(e1.Sym.Org, e2.Org, e1.Org) >= 0;
+ }
+ return Geom.EdgeSign(e2.Sym.Org, event, e2.Org) <= 0;
+ }
+ if (e2.Sym.Org == event) {
+ return Geom.EdgeSign(e1.Sym.Org, event, e1.Org) >= 0;
+ }
+
+ /* General case - compute signed distance *from* e1, e2 to event */
+ t1 = Geom.EdgeEval(e1.Sym.Org, event, e1.Org);
+ t2 = Geom.EdgeEval(e2.Sym.Org, event, e2.Org);
+ return (t1 >= t2);
+ }
+
+
+ static void DeleteRegion(GLUtessellatorImpl tess, ActiveRegion reg) {
+ if (reg.fixUpperEdge) {
+ /* It was created with zero winding number, so it better be
+ * deleted with zero winding number (ie. it better not get merged
+ * with a real edge).
+ */
+ assert (reg.eUp.winding == 0);
+ }
+ reg.eUp.activeRegion = null;
+ Dict.dictDelete(tess.dict, reg.nodeUp); /* __gl_dictListDelete */
+ }
+
+
+ static boolean FixUpperEdge(ActiveRegion reg, GLUhalfEdge newEdge)
+/*
+ * Replace an upper edge which needs fixing (see ConnectRightVertex).
+ */ {
+ assert (reg.fixUpperEdge);
+ if (!Mesh.__gl_meshDelete(reg.eUp)) return false;
+ reg.fixUpperEdge = false;
+ reg.eUp = newEdge;
+ newEdge.activeRegion = reg;
+
+ return true;
+ }
+
+ static ActiveRegion TopLeftRegion(ActiveRegion reg) {
+ GLUvertex org = reg.eUp.Org;
+ GLUhalfEdge e;
+
+ /* Find the region above the uppermost edge with the same origin */
+ do {
+ reg = RegionAbove(reg);
+ } while (reg.eUp.Org == org);
+
+ /* If the edge above was a temporary edge introduced by ConnectRightVertex,
+ * now is the time to fix it.
+ */
+ if (reg.fixUpperEdge) {
+ e = Mesh.__gl_meshConnect(RegionBelow(reg).eUp.Sym, reg.eUp.Lnext);
+ if (e == null) return null;
+ if (!FixUpperEdge(reg, e)) return null;
+ reg = RegionAbove(reg);
+ }
+ return reg;
+ }
+
+ static ActiveRegion TopRightRegion(ActiveRegion reg) {
+ GLUvertex dst = reg.eUp.Sym.Org;
+
+ /* Find the region above the uppermost edge with the same destination */
+ do {
+ reg = RegionAbove(reg);
+ } while (reg.eUp.Sym.Org == dst);
+ return reg;
+ }
+
+ static ActiveRegion AddRegionBelow(GLUtessellatorImpl tess,
+ ActiveRegion regAbove,
+ GLUhalfEdge eNewUp)
+/*
+ * Add a new active region to the sweep line, *somewhere* below "regAbove"
+ * (according to where the new edge belongs in the sweep-line dictionary).
+ * The upper edge of the new region will be "eNewUp".
+ * Winding number and "inside" flag are not updated.
+ */ {
+ ActiveRegion regNew = new ActiveRegion();
+ if (regNew == null) throw new RuntimeException();
+
+ regNew.eUp = eNewUp;
+ /* __gl_dictListInsertBefore */
+ regNew.nodeUp = Dict.dictInsertBefore(tess.dict, regAbove.nodeUp, regNew);
+ if (regNew.nodeUp == null) throw new RuntimeException();
+ regNew.fixUpperEdge = false;
+ regNew.sentinel = false;
+ regNew.dirty = false;
+
+ eNewUp.activeRegion = regNew;
+ return regNew;
+ }
+
+ static boolean IsWindingInside(GLUtessellatorImpl tess, int n) {
+ switch (tess.windingRule) {
+ case GLU.GLU_TESS_WINDING_ODD:
+ return (n & 1) != 0;
+ case GLU.GLU_TESS_WINDING_NONZERO:
+ return (n != 0);
+ case GLU.GLU_TESS_WINDING_POSITIVE:
+ return (n > 0);
+ case GLU.GLU_TESS_WINDING_NEGATIVE:
+ return (n < 0);
+ case GLU.GLU_TESS_WINDING_ABS_GEQ_TWO:
+ return (n >= 2) || (n <= -2);
+ }
+ /*LINTED*/
+// assert (false);
+ throw new InternalError();
+ /*NOTREACHED*/
+ }
+
+
+ static void ComputeWinding(GLUtessellatorImpl tess, ActiveRegion reg) {
+ reg.windingNumber = RegionAbove(reg).windingNumber + reg.eUp.winding;
+ reg.inside = IsWindingInside(tess, reg.windingNumber);
+ }
+
+
+ static void FinishRegion(GLUtessellatorImpl tess, ActiveRegion reg)
+/*
+ * Delete a region from the sweep line. This happens when the upper
+ * and lower chains of a region meet (at a vertex on the sweep line).
+ * The "inside" flag is copied to the appropriate mesh face (we could
+ * not do this before -- since the structure of the mesh is always
+ * changing, this face may not have even existed until now).
+ */ {
+ GLUhalfEdge e = reg.eUp;
+ GLUface f = e.Lface;
+
+ f.inside = reg.inside;
+ f.anEdge = e; /* optimization for __gl_meshTessellateMonoRegion() */
+ DeleteRegion(tess, reg);
+ }
+
+
+ static GLUhalfEdge FinishLeftRegions(GLUtessellatorImpl tess,
+ ActiveRegion regFirst, ActiveRegion regLast)
+/*
+ * We are given a vertex with one or more left-going edges. All affected
+ * edges should be in the edge dictionary. Starting at regFirst.eUp,
+ * we walk down deleting all regions where both edges have the same
+ * origin vOrg. At the same time we copy the "inside" flag from the
+ * active region to the face, since at this point each face will belong
+ * to at most one region (this was not necessarily true until this point
+ * in the sweep). The walk stops at the region above regLast; if regLast
+ * is null we walk as far as possible. At the same time we relink the
+ * mesh if necessary, so that the ordering of edges around vOrg is the
+ * same as in the dictionary.
+ */ {
+ ActiveRegion reg, regPrev;
+ GLUhalfEdge e, ePrev;
+
+ regPrev = regFirst;
+ ePrev = regFirst.eUp;
+ while (regPrev != regLast) {
+ regPrev.fixUpperEdge = false; /* placement was OK */
+ reg = RegionBelow(regPrev);
+ e = reg.eUp;
+ if (e.Org != ePrev.Org) {
+ if (!reg.fixUpperEdge) {
+ /* Remove the last left-going edge. Even though there are no further
+ * edges in the dictionary with this origin, there may be further
+ * such edges in the mesh (if we are adding left edges to a vertex
+ * that has already been processed). Thus it is important to call
+ * FinishRegion rather than just DeleteRegion.
+ */
+ FinishRegion(tess, regPrev);
+ break;
+ }
+ /* If the edge below was a temporary edge introduced by
+ * ConnectRightVertex, now is the time to fix it.
+ */
+ e = Mesh.__gl_meshConnect(ePrev.Onext.Sym, e.Sym);
+ if (e == null) throw new RuntimeException();
+ if (!FixUpperEdge(reg, e)) throw new RuntimeException();
+ }
+
+ /* Relink edges so that ePrev.Onext == e */
+ if (ePrev.Onext != e) {
+ if (!Mesh.__gl_meshSplice(e.Sym.Lnext, e)) throw new RuntimeException();
+ if (!Mesh.__gl_meshSplice(ePrev, e)) throw new RuntimeException();
+ }
+ FinishRegion(tess, regPrev); /* may change reg.eUp */
+ ePrev = reg.eUp;
+ regPrev = reg;
+ }
+ return ePrev;
+ }
+
+
+ static void AddRightEdges(GLUtessellatorImpl tess, ActiveRegion regUp,
+ GLUhalfEdge eFirst, GLUhalfEdge eLast, GLUhalfEdge eTopLeft,
+ boolean cleanUp)
+/*
+ * Purpose: insert right-going edges into the edge dictionary, and update
+ * winding numbers and mesh connectivity appropriately. All right-going
+ * edges share a common origin vOrg. Edges are inserted CCW starting at
+ * eFirst; the last edge inserted is eLast.Sym.Lnext. If vOrg has any
+ * left-going edges already processed, then eTopLeft must be the edge
+ * such that an imaginary upward vertical segment from vOrg would be
+ * contained between eTopLeft.Sym.Lnext and eTopLeft; otherwise eTopLeft
+ * should be null.
+ */ {
+ ActiveRegion reg, regPrev;
+ GLUhalfEdge e, ePrev;
+ boolean firstTime = true;
+
+ /* Insert the new right-going edges in the dictionary */
+ e = eFirst;
+ do {
+ assert (Geom.VertLeq(e.Org, e.Sym.Org));
+ AddRegionBelow(tess, regUp, e.Sym);
+ e = e.Onext;
+ } while (e != eLast);
+
+ /* Walk *all* right-going edges from e.Org, in the dictionary order,
+ * updating the winding numbers of each region, and re-linking the mesh
+ * edges to match the dictionary ordering (if necessary).
+ */
+ if (eTopLeft == null) {
+ eTopLeft = RegionBelow(regUp).eUp.Sym.Onext;
+ }
+ regPrev = regUp;
+ ePrev = eTopLeft;
+ for (; ;) {
+ reg = RegionBelow(regPrev);
+ e = reg.eUp.Sym;
+ if (e.Org != ePrev.Org) break;
+
+ if (e.Onext != ePrev) {
+ /* Unlink e from its current position, and relink below ePrev */
+ if (!Mesh.__gl_meshSplice(e.Sym.Lnext, e)) throw new RuntimeException();
+ if (!Mesh.__gl_meshSplice(ePrev.Sym.Lnext, e)) throw new RuntimeException();
+ }
+ /* Compute the winding number and "inside" flag for the new regions */
+ reg.windingNumber = regPrev.windingNumber - e.winding;
+ reg.inside = IsWindingInside(tess, reg.windingNumber);
+
+ /* Check for two outgoing edges with same slope -- process these
+ * before any intersection tests (see example in __gl_computeInterior).
+ */
+ regPrev.dirty = true;
+ if (!firstTime && CheckForRightSplice(tess, regPrev)) {
+ AddWinding(e, ePrev);
+ DeleteRegion(tess, regPrev);
+ if (!Mesh.__gl_meshDelete(ePrev)) throw new RuntimeException();
+ }
+ firstTime = false;
+ regPrev = reg;
+ ePrev = e;
+ }
+ regPrev.dirty = true;
+ assert (regPrev.windingNumber - e.winding == reg.windingNumber);
+
+ if (cleanUp) {
+ /* Check for intersections between newly adjacent edges. */
+ WalkDirtyRegions(tess, regPrev);
+ }
+ }
+
+
+ static void CallCombine(GLUtessellatorImpl tess, GLUvertex isect,
+ Object[] data, float[] weights, boolean needed) {
+ double[] coords = new double[3];
+
+ /* Copy coord data in case the callback changes it. */
+ coords[0] = isect.coords[0];
+ coords[1] = isect.coords[1];
+ coords[2] = isect.coords[2];
+
+ Object[] outData = new Object[1];
+ tess.callCombineOrCombineData(coords, data, weights, outData);
+ isect.data = outData[0];
+ if (isect.data == null) {
+ if (!needed) {
+ isect.data = data[0];
+ } else if (!tess.fatalError) {
+ /* The only way fatal error is when two edges are found to intersect,
+ * but the user has not provided the callback necessary to handle
+ * generated intersection points.
+ */
+ tess.callErrorOrErrorData(GLU.GLU_TESS_NEED_COMBINE_CALLBACK);
+ tess.fatalError = true;
+ }
+ }
+ }
+
+ static void SpliceMergeVertices(GLUtessellatorImpl tess, GLUhalfEdge e1,
+ GLUhalfEdge e2)
+/*
+ * Two vertices with idential coordinates are combined into one.
+ * e1.Org is kept, while e2.Org is discarded.
+ */ {
+ Object[] data = new Object[4];
+ float[] weights = new float[]{0.5f, 0.5f, 0.0f, 0.0f};
+
+ data[0] = e1.Org.data;
+ data[1] = e2.Org.data;
+ CallCombine(tess, e1.Org, data, weights, false);
+ if (!Mesh.__gl_meshSplice(e1, e2)) throw new RuntimeException();
+ }
+
+ static void VertexWeights(GLUvertex isect, GLUvertex org, GLUvertex dst,
+ float[] weights)
+/*
+ * Find some weights which describe how the intersection vertex is
+ * a linear combination of "org" and "dest". Each of the two edges
+ * which generated "isect" is allocated 50% of the weight; each edge
+ * splits the weight between its org and dst according to the
+ * relative distance to "isect".
+ */ {
+ double t1 = Geom.VertL1dist(org, isect);
+ double t2 = Geom.VertL1dist(dst, isect);
+
+ weights[0] = (float) (0.5 * t2 / (t1 + t2));
+ weights[1] = (float) (0.5 * t1 / (t1 + t2));
+ isect.coords[0] += weights[0] * org.coords[0] + weights[1] * dst.coords[0];
+ isect.coords[1] += weights[0] * org.coords[1] + weights[1] * dst.coords[1];
+ isect.coords[2] += weights[0] * org.coords[2] + weights[1] * dst.coords[2];
+ }
+
+
+ static void GetIntersectData(GLUtessellatorImpl tess, GLUvertex isect,
+ GLUvertex orgUp, GLUvertex dstUp,
+ GLUvertex orgLo, GLUvertex dstLo)
+/*
+ * We've computed a new intersection point, now we need a "data" pointer
+ * from the user so that we can refer to this new vertex in the
+ * rendering callbacks.
+ */ {
+ Object[] data = new Object[4];
+ float[] weights = new float[4];
+ float[] weights1 = new float[2];
+ float[] weights2 = new float[2];
+
+ data[0] = orgUp.data;
+ data[1] = dstUp.data;
+ data[2] = orgLo.data;
+ data[3] = dstLo.data;
+
+ isect.coords[0] = isect.coords[1] = isect.coords[2] = 0;
+ VertexWeights(isect, orgUp, dstUp, weights1);
+ VertexWeights(isect, orgLo, dstLo, weights2);
+ System.arraycopy(weights1, 0, weights, 0, 2);
+ System.arraycopy(weights2, 0, weights, 2, 2);
+
+ CallCombine(tess, isect, data, weights, true);
+ }
+
+ static boolean CheckForRightSplice(GLUtessellatorImpl tess, ActiveRegion regUp)
+/*
+ * Check the upper and lower edge of "regUp", to make sure that the
+ * eUp.Org is above eLo, or eLo.Org is below eUp (depending on which
+ * origin is leftmost).
+ *
+ * The main purpose is to splice right-going edges with the same
+ * dest vertex and nearly identical slopes (ie. we can't distinguish
+ * the slopes numerically). However the splicing can also help us
+ * to recover from numerical errors. For example, suppose at one
+ * point we checked eUp and eLo, and decided that eUp.Org is barely
+ * above eLo. Then later, we split eLo into two edges (eg. from
+ * a splice operation like this one). This can change the result of
+ * our test so that now eUp.Org is incident to eLo, or barely below it.
+ * We must correct this condition to maintain the dictionary invariants.
+ *
+ * One possibility is to check these edges for intersection again
+ * (ie. CheckForIntersect). This is what we do if possible. However
+ * CheckForIntersect requires that tess.event lies between eUp and eLo,
+ * so that it has something to fall back on when the intersection
+ * calculation gives us an unusable answer. So, for those cases where
+ * we can't check for intersection, this routine fixes the problem
+ * by just splicing the offending vertex into the other edge.
+ * This is a guaranteed solution, no matter how degenerate things get.
+ * Basically this is a combinatorial solution to a numerical problem.
+ */ {
+ ActiveRegion regLo = RegionBelow(regUp);
+ GLUhalfEdge eUp = regUp.eUp;
+ GLUhalfEdge eLo = regLo.eUp;
+
+ if (Geom.VertLeq(eUp.Org, eLo.Org)) {
+ if (Geom.EdgeSign(eLo.Sym.Org, eUp.Org, eLo.Org) > 0) return false;
+
+ /* eUp.Org appears to be below eLo */
+ if (!Geom.VertEq(eUp.Org, eLo.Org)) {
+ /* Splice eUp.Org into eLo */
+ if (Mesh.__gl_meshSplitEdge(eLo.Sym) == null) throw new RuntimeException();
+ if (!Mesh.__gl_meshSplice(eUp, eLo.Sym.Lnext)) throw new RuntimeException();
+ regUp.dirty = regLo.dirty = true;
+
+ } else if (eUp.Org != eLo.Org) {
+ /* merge the two vertices, discarding eUp.Org */
+ tess.pq.pqDelete(eUp.Org.pqHandle); /* __gl_pqSortDelete */
+ SpliceMergeVertices(tess, eLo.Sym.Lnext, eUp);
+ }
+ } else {
+ if (Geom.EdgeSign(eUp.Sym.Org, eLo.Org, eUp.Org) < 0) return false;
+
+ /* eLo.Org appears to be above eUp, so splice eLo.Org into eUp */
+ RegionAbove(regUp).dirty = regUp.dirty = true;
+ if (Mesh.__gl_meshSplitEdge(eUp.Sym) == null) throw new RuntimeException();
+ if (!Mesh.__gl_meshSplice(eLo.Sym.Lnext, eUp)) throw new RuntimeException();
+ }
+ return true;
+ }
+
+ static boolean CheckForLeftSplice(GLUtessellatorImpl tess, ActiveRegion regUp)
+/*
+ * Check the upper and lower edge of "regUp", to make sure that the
+ * eUp.Sym.Org is above eLo, or eLo.Sym.Org is below eUp (depending on which
+ * destination is rightmost).
+ *
+ * Theoretically, this should always be true. However, splitting an edge
+ * into two pieces can change the results of previous tests. For example,
+ * suppose at one point we checked eUp and eLo, and decided that eUp.Sym.Org
+ * is barely above eLo. Then later, we split eLo into two edges (eg. from
+ * a splice operation like this one). This can change the result of
+ * the test so that now eUp.Sym.Org is incident to eLo, or barely below it.
+ * We must correct this condition to maintain the dictionary invariants
+ * (otherwise new edges might get inserted in the wrong place in the
+ * dictionary, and bad stuff will happen).
+ *
+ * We fix the problem by just splicing the offending vertex into the
+ * other edge.
+ */ {
+ ActiveRegion regLo = RegionBelow(regUp);
+ GLUhalfEdge eUp = regUp.eUp;
+ GLUhalfEdge eLo = regLo.eUp;
+ GLUhalfEdge e;
+
+ assert (!Geom.VertEq(eUp.Sym.Org, eLo.Sym.Org));
+
+ if (Geom.VertLeq(eUp.Sym.Org, eLo.Sym.Org)) {
+ if (Geom.EdgeSign(eUp.Sym.Org, eLo.Sym.Org, eUp.Org) < 0) return false;
+
+ /* eLo.Sym.Org is above eUp, so splice eLo.Sym.Org into eUp */
+ RegionAbove(regUp).dirty = regUp.dirty = true;
+ e = Mesh.__gl_meshSplitEdge(eUp);
+ if (e == null) throw new RuntimeException();
+ if (!Mesh.__gl_meshSplice(eLo.Sym, e)) throw new RuntimeException();
+ e.Lface.inside = regUp.inside;
+ } else {
+ if (Geom.EdgeSign(eLo.Sym.Org, eUp.Sym.Org, eLo.Org) > 0) return false;
+
+ /* eUp.Sym.Org is below eLo, so splice eUp.Sym.Org into eLo */
+ regUp.dirty = regLo.dirty = true;
+ e = Mesh.__gl_meshSplitEdge(eLo);
+ if (e == null) throw new RuntimeException();
+ if (!Mesh.__gl_meshSplice(eUp.Lnext, eLo.Sym)) throw new RuntimeException();
+ e.Sym.Lface.inside = regUp.inside;
+ }
+ return true;
+ }
+
+
+ static boolean CheckForIntersect(GLUtessellatorImpl tess, ActiveRegion regUp)
+/*
+ * Check the upper and lower edges of the given region to see if
+ * they intersect. If so, create the intersection and add it
+ * to the data structures.
+ *
+ * Returns true if adding the new intersection resulted in a recursive
+ * call to AddRightEdges(); in this case all "dirty" regions have been
+ * checked for intersections, and possibly regUp has been deleted.
+ */ {
+ ActiveRegion regLo = RegionBelow(regUp);
+ GLUhalfEdge eUp = regUp.eUp;
+ GLUhalfEdge eLo = regLo.eUp;
+ GLUvertex orgUp = eUp.Org;
+ GLUvertex orgLo = eLo.Org;
+ GLUvertex dstUp = eUp.Sym.Org;
+ GLUvertex dstLo = eLo.Sym.Org;
+ double tMinUp, tMaxLo;
+ GLUvertex isect = new GLUvertex();
+ GLUvertex orgMin;
+ GLUhalfEdge e;
+
+ assert (!Geom.VertEq(dstLo, dstUp));
+ assert (Geom.EdgeSign(dstUp, tess.event, orgUp) <= 0);
+ assert (Geom.EdgeSign(dstLo, tess.event, orgLo) >= 0);
+ assert (orgUp != tess.event && orgLo != tess.event);
+ assert (!regUp.fixUpperEdge && !regLo.fixUpperEdge);
+
+ if (orgUp == orgLo) return false; /* right endpoints are the same */
+
+ tMinUp = Math.min(orgUp.t, dstUp.t);
+ tMaxLo = Math.max(orgLo.t, dstLo.t);
+ if (tMinUp > tMaxLo) return false; /* t ranges do not overlap */
+
+ if (Geom.VertLeq(orgUp, orgLo)) {
+ if (Geom.EdgeSign(dstLo, orgUp, orgLo) > 0) return false;
+ } else {
+ if (Geom.EdgeSign(dstUp, orgLo, orgUp) < 0) return false;
+ }
+
+ /* At this point the edges intersect, at least marginally */
+ DebugEvent(tess);
+
+ Geom.EdgeIntersect(dstUp, orgUp, dstLo, orgLo, isect);
+ /* The following properties are guaranteed: */
+ assert (Math.min(orgUp.t, dstUp.t) <= isect.t);
+ assert (isect.t <= Math.max(orgLo.t, dstLo.t));
+ assert (Math.min(dstLo.s, dstUp.s) <= isect.s);
+ assert (isect.s <= Math.max(orgLo.s, orgUp.s));
+
+ if (Geom.VertLeq(isect, tess.event)) {
+ /* The intersection point lies slightly to the left of the sweep line,
+ * so move it until it''s slightly to the right of the sweep line.
+ * (If we had perfect numerical precision, this would never happen
+ * in the first place). The easiest and safest thing to do is
+ * replace the intersection by tess.event.
+ */
+ isect.s = tess.event.s;
+ isect.t = tess.event.t;
+ }
+ /* Similarly, if the computed intersection lies to the right of the
+ * rightmost origin (which should rarely happen), it can cause
+ * unbelievable inefficiency on sufficiently degenerate inputs.
+ * (If you have the test program, try running test54.d with the
+ * "X zoom" option turned on).
+ */
+ orgMin = Geom.VertLeq(orgUp, orgLo) ? orgUp : orgLo;
+ if (Geom.VertLeq(orgMin, isect)) {
+ isect.s = orgMin.s;
+ isect.t = orgMin.t;
+ }
+
+ if (Geom.VertEq(isect, orgUp) || Geom.VertEq(isect, orgLo)) {
+ /* Easy case -- intersection at one of the right endpoints */
+ CheckForRightSplice(tess, regUp);
+ return false;
+ }
+
+ if ((!Geom.VertEq(dstUp, tess.event)
+ && Geom.EdgeSign(dstUp, tess.event, isect) >= 0)
+ || (!Geom.VertEq(dstLo, tess.event)
+ && Geom.EdgeSign(dstLo, tess.event, isect) <= 0)) {
+ /* Very unusual -- the new upper or lower edge would pass on the
+ * wrong side of the sweep event, or through it. This can happen
+ * due to very small numerical errors in the intersection calculation.
+ */
+ if (dstLo == tess.event) {
+ /* Splice dstLo into eUp, and process the new region(s) */
+ if (Mesh.__gl_meshSplitEdge(eUp.Sym) == null) throw new RuntimeException();
+ if (!Mesh.__gl_meshSplice(eLo.Sym, eUp)) throw new RuntimeException();
+ regUp = TopLeftRegion(regUp);
+ if (regUp == null) throw new RuntimeException();
+ eUp = RegionBelow(regUp).eUp;
+ FinishLeftRegions(tess, RegionBelow(regUp), regLo);
+ AddRightEdges(tess, regUp, eUp.Sym.Lnext, eUp, eUp, true);
+ return true;
+ }
+ if (dstUp == tess.event) {
+ /* Splice dstUp into eLo, and process the new region(s) */
+ if (Mesh.__gl_meshSplitEdge(eLo.Sym) == null) throw new RuntimeException();
+ if (!Mesh.__gl_meshSplice(eUp.Lnext, eLo.Sym.Lnext)) throw new RuntimeException();
+ regLo = regUp;
+ regUp = TopRightRegion(regUp);
+ e = RegionBelow(regUp).eUp.Sym.Onext;
+ regLo.eUp = eLo.Sym.Lnext;
+ eLo = FinishLeftRegions(tess, regLo, null);
+ AddRightEdges(tess, regUp, eLo.Onext, eUp.Sym.Onext, e, true);
+ return true;
+ }
+ /* Special case: called from ConnectRightVertex. If either
+ * edge passes on the wrong side of tess.event, split it
+ * (and wait for ConnectRightVertex to splice it appropriately).
+ */
+ if (Geom.EdgeSign(dstUp, tess.event, isect) >= 0) {
+ RegionAbove(regUp).dirty = regUp.dirty = true;
+ if (Mesh.__gl_meshSplitEdge(eUp.Sym) == null) throw new RuntimeException();
+ eUp.Org.s = tess.event.s;
+ eUp.Org.t = tess.event.t;
+ }
+ if (Geom.EdgeSign(dstLo, tess.event, isect) <= 0) {
+ regUp.dirty = regLo.dirty = true;
+ if (Mesh.__gl_meshSplitEdge(eLo.Sym) == null) throw new RuntimeException();
+ eLo.Org.s = tess.event.s;
+ eLo.Org.t = tess.event.t;
+ }
+ /* leave the rest for ConnectRightVertex */
+ return false;
+ }
+
+ /* General case -- split both edges, splice into new vertex.
+ * When we do the splice operation, the order of the arguments is
+ * arbitrary as far as correctness goes. However, when the operation
+ * creates a new face, the work done is proportional to the size of
+ * the new face. We expect the faces in the processed part of
+ * the mesh (ie. eUp.Lface) to be smaller than the faces in the
+ * unprocessed original contours (which will be eLo.Sym.Lnext.Lface).
+ */
+ if (Mesh.__gl_meshSplitEdge(eUp.Sym) == null) throw new RuntimeException();
+ if (Mesh.__gl_meshSplitEdge(eLo.Sym) == null) throw new RuntimeException();
+ if (!Mesh.__gl_meshSplice(eLo.Sym.Lnext, eUp)) throw new RuntimeException();
+ eUp.Org.s = isect.s;
+ eUp.Org.t = isect.t;
+ eUp.Org.pqHandle = tess.pq.pqInsert(eUp.Org); /* __gl_pqSortInsert */
+ if (eUp.Org.pqHandle == Long.MAX_VALUE) {
+ tess.pq.pqDeletePriorityQ(); /* __gl_pqSortDeletePriorityQ */
+ tess.pq = null;
+ throw new RuntimeException();
+ }
+ GetIntersectData(tess, eUp.Org, orgUp, dstUp, orgLo, dstLo);
+ RegionAbove(regUp).dirty = regUp.dirty = regLo.dirty = true;
+ return false;
+ }
+
+ static void WalkDirtyRegions(GLUtessellatorImpl tess, ActiveRegion regUp)
+/*
+ * When the upper or lower edge of any region changes, the region is
+ * marked "dirty". This routine walks through all the dirty regions
+ * and makes sure that the dictionary invariants are satisfied
+ * (see the comments at the beginning of this file). Of course
+ * new dirty regions can be created as we make changes to restore
+ * the invariants.
+ */ {
+ ActiveRegion regLo = RegionBelow(regUp);
+ GLUhalfEdge eUp, eLo;
+
+ for (; ;) {
+ /* Find the lowest dirty region (we walk from the bottom up). */
+ while (regLo.dirty) {
+ regUp = regLo;
+ regLo = RegionBelow(regLo);
+ }
+ if (!regUp.dirty) {
+ regLo = regUp;
+ regUp = RegionAbove(regUp);
+ if (regUp == null || !regUp.dirty) {
+ /* We've walked all the dirty regions */
+ return;
+ }
+ }
+ regUp.dirty = false;
+ eUp = regUp.eUp;
+ eLo = regLo.eUp;
+
+ if (eUp.Sym.Org != eLo.Sym.Org) {
+ /* Check that the edge ordering is obeyed at the Dst vertices. */
+ if (CheckForLeftSplice(tess, regUp)) {
+
+ /* If the upper or lower edge was marked fixUpperEdge, then
+ * we no longer need it (since these edges are needed only for
+ * vertices which otherwise have no right-going edges).
+ */
+ if (regLo.fixUpperEdge) {
+ DeleteRegion(tess, regLo);
+ if (!Mesh.__gl_meshDelete(eLo)) throw new RuntimeException();
+ regLo = RegionBelow(regUp);
+ eLo = regLo.eUp;
+ } else if (regUp.fixUpperEdge) {
+ DeleteRegion(tess, regUp);
+ if (!Mesh.__gl_meshDelete(eUp)) throw new RuntimeException();
+ regUp = RegionAbove(regLo);
+ eUp = regUp.eUp;
+ }
+ }
+ }
+ if (eUp.Org != eLo.Org) {
+ if (eUp.Sym.Org != eLo.Sym.Org
+ && !regUp.fixUpperEdge && !regLo.fixUpperEdge
+ && (eUp.Sym.Org == tess.event || eLo.Sym.Org == tess.event)) {
+ /* When all else fails in CheckForIntersect(), it uses tess.event
+ * as the intersection location. To make this possible, it requires
+ * that tess.event lie between the upper and lower edges, and also
+ * that neither of these is marked fixUpperEdge (since in the worst
+ * case it might splice one of these edges into tess.event, and
+ * violate the invariant that fixable edges are the only right-going
+ * edge from their associated vertex).
+ */
+ if (CheckForIntersect(tess, regUp)) {
+ /* WalkDirtyRegions() was called recursively; we're done */
+ return;
+ }
+ } else {
+ /* Even though we can't use CheckForIntersect(), the Org vertices
+ * may violate the dictionary edge ordering. Check and correct this.
+ */
+ CheckForRightSplice(tess, regUp);
+ }
+ }
+ if (eUp.Org == eLo.Org && eUp.Sym.Org == eLo.Sym.Org) {
+ /* A degenerate loop consisting of only two edges -- delete it. */
+ AddWinding(eLo, eUp);
+ DeleteRegion(tess, regUp);
+ if (!Mesh.__gl_meshDelete(eUp)) throw new RuntimeException();
+ regUp = RegionAbove(regLo);
+ }
+ }
+ }
+
+
+ static void ConnectRightVertex(GLUtessellatorImpl tess, ActiveRegion regUp,
+ GLUhalfEdge eBottomLeft)
+/*
+ * Purpose: connect a "right" vertex vEvent (one where all edges go left)
+ * to the unprocessed portion of the mesh. Since there are no right-going
+ * edges, two regions (one above vEvent and one below) are being merged
+ * into one. "regUp" is the upper of these two regions.
+ *
+ * There are two reasons for doing this (adding a right-going edge):
+ * - if the two regions being merged are "inside", we must add an edge
+ * to keep them separated (the combined region would not be monotone).
+ * - in any case, we must leave some record of vEvent in the dictionary,
+ * so that we can merge vEvent with features that we have not seen yet.
+ * For example, maybe there is a vertical edge which passes just to
+ * the right of vEvent; we would like to splice vEvent into this edge.
+ *
+ * However, we don't want to connect vEvent to just any vertex. We don''t
+ * want the new edge to cross any other edges; otherwise we will create
+ * intersection vertices even when the input data had no self-intersections.
+ * (This is a bad thing; if the user's input data has no intersections,
+ * we don't want to generate any false intersections ourselves.)
+ *
+ * Our eventual goal is to connect vEvent to the leftmost unprocessed
+ * vertex of the combined region (the union of regUp and regLo).
+ * But because of unseen vertices with all right-going edges, and also
+ * new vertices which may be created by edge intersections, we don''t
+ * know where that leftmost unprocessed vertex is. In the meantime, we
+ * connect vEvent to the closest vertex of either chain, and mark the region
+ * as "fixUpperEdge". This flag says to delete and reconnect this edge
+ * to the next processed vertex on the boundary of the combined region.
+ * Quite possibly the vertex we connected to will turn out to be the
+ * closest one, in which case we won''t need to make any changes.
+ */ {
+ GLUhalfEdge eNew;
+ GLUhalfEdge eTopLeft = eBottomLeft.Onext;
+ ActiveRegion regLo = RegionBelow(regUp);
+ GLUhalfEdge eUp = regUp.eUp;
+ GLUhalfEdge eLo = regLo.eUp;
+ boolean degenerate = false;
+
+ if (eUp.Sym.Org != eLo.Sym.Org) {
+ CheckForIntersect(tess, regUp);
+ }
+
+ /* Possible new degeneracies: upper or lower edge of regUp may pass
+ * through vEvent, or may coincide with new intersection vertex
+ */
+ if (Geom.VertEq(eUp.Org, tess.event)) {
+ if (!Mesh.__gl_meshSplice(eTopLeft.Sym.Lnext, eUp)) throw new RuntimeException();
+ regUp = TopLeftRegion(regUp);
+ if (regUp == null) throw new RuntimeException();
+ eTopLeft = RegionBelow(regUp).eUp;
+ FinishLeftRegions(tess, RegionBelow(regUp), regLo);
+ degenerate = true;
+ }
+ if (Geom.VertEq(eLo.Org, tess.event)) {
+ if (!Mesh.__gl_meshSplice(eBottomLeft, eLo.Sym.Lnext)) throw new RuntimeException();
+ eBottomLeft = FinishLeftRegions(tess, regLo, null);
+ degenerate = true;
+ }
+ if (degenerate) {
+ AddRightEdges(tess, regUp, eBottomLeft.Onext, eTopLeft, eTopLeft, true);
+ return;
+ }
+
+ /* Non-degenerate situation -- need to add a temporary, fixable edge.
+ * Connect to the closer of eLo.Org, eUp.Org.
+ */
+ if (Geom.VertLeq(eLo.Org, eUp.Org)) {
+ eNew = eLo.Sym.Lnext;
+ } else {
+ eNew = eUp;
+ }
+ eNew = Mesh.__gl_meshConnect(eBottomLeft.Onext.Sym, eNew);
+ if (eNew == null) throw new RuntimeException();
+
+ /* Prevent cleanup, otherwise eNew might disappear before we've even
+ * had a chance to mark it as a temporary edge.
+ */
+ AddRightEdges(tess, regUp, eNew, eNew.Onext, eNew.Onext, false);
+ eNew.Sym.activeRegion.fixUpperEdge = true;
+ WalkDirtyRegions(tess, regUp);
+ }
+
+/* Because vertices at exactly the same location are merged together
+ * before we process the sweep event, some degenerate cases can't occur.
+ * However if someone eventually makes the modifications required to
+ * merge features which are close together, the cases below marked
+ * TOLERANCE_NONZERO will be useful. They were debugged before the
+ * code to merge identical vertices in the main loop was added.
+ */
+ private static final boolean TOLERANCE_NONZERO = false;
+
+ static void ConnectLeftDegenerate(GLUtessellatorImpl tess,
+ ActiveRegion regUp, GLUvertex vEvent)
+/*
+ * The event vertex lies exacty on an already-processed edge or vertex.
+ * Adding the new vertex involves splicing it into the already-processed
+ * part of the mesh.
+ */ {
+ GLUhalfEdge e, eTopLeft, eTopRight, eLast;
+ ActiveRegion reg;
+
+ e = regUp.eUp;
+ if (Geom.VertEq(e.Org, vEvent)) {
+ /* e.Org is an unprocessed vertex - just combine them, and wait
+ * for e.Org to be pulled from the queue
+ */
+ assert (TOLERANCE_NONZERO);
+ SpliceMergeVertices(tess, e, vEvent.anEdge);
+ return;
+ }
+
+ if (!Geom.VertEq(e.Sym.Org, vEvent)) {
+ /* General case -- splice vEvent into edge e which passes through it */
+ if (Mesh.__gl_meshSplitEdge(e.Sym) == null) throw new RuntimeException();
+ if (regUp.fixUpperEdge) {
+ /* This edge was fixable -- delete unused portion of original edge */
+ if (!Mesh.__gl_meshDelete(e.Onext)) throw new RuntimeException();
+ regUp.fixUpperEdge = false;
+ }
+ if (!Mesh.__gl_meshSplice(vEvent.anEdge, e)) throw new RuntimeException();
+ SweepEvent(tess, vEvent); /* recurse */
+ return;
+ }
+
+ /* vEvent coincides with e.Sym.Org, which has already been processed.
+ * Splice in the additional right-going edges.
+ */
+ assert (TOLERANCE_NONZERO);
+ regUp = TopRightRegion(regUp);
+ reg = RegionBelow(regUp);
+ eTopRight = reg.eUp.Sym;
+ eTopLeft = eLast = eTopRight.Onext;
+ if (reg.fixUpperEdge) {
+ /* Here e.Sym.Org has only a single fixable edge going right.
+ * We can delete it since now we have some real right-going edges.
+ */
+ assert (eTopLeft != eTopRight); /* there are some left edges too */
+ DeleteRegion(tess, reg);
+ if (!Mesh.__gl_meshDelete(eTopRight)) throw new RuntimeException();
+ eTopRight = eTopLeft.Sym.Lnext;
+ }
+ if (!Mesh.__gl_meshSplice(vEvent.anEdge, eTopRight)) throw new RuntimeException();
+ if (!Geom.EdgeGoesLeft(eTopLeft)) {
+ /* e.Sym.Org had no left-going edges -- indicate this to AddRightEdges() */
+ eTopLeft = null;
+ }
+ AddRightEdges(tess, regUp, eTopRight.Onext, eLast, eTopLeft, true);
+ }
+
+
+ static void ConnectLeftVertex(GLUtessellatorImpl tess, GLUvertex vEvent)
+/*
+ * Purpose: connect a "left" vertex (one where both edges go right)
+ * to the processed portion of the mesh. Let R be the active region
+ * containing vEvent, and let U and L be the upper and lower edge
+ * chains of R. There are two possibilities:
+ *
+ * - the normal case: split R into two regions, by connecting vEvent to
+ * the rightmost vertex of U or L lying to the left of the sweep line
+ *
+ * - the degenerate case: if vEvent is close enough to U or L, we
+ * merge vEvent into that edge chain. The subcases are:
+ * - merging with the rightmost vertex of U or L
+ * - merging with the active edge of U or L
+ * - merging with an already-processed portion of U or L
+ */ {
+ ActiveRegion regUp, regLo, reg;
+ GLUhalfEdge eUp, eLo, eNew;
+ ActiveRegion tmp = new ActiveRegion();
+
+ /* assert ( vEvent.anEdge.Onext.Onext == vEvent.anEdge ); */
+
+ /* Get a pointer to the active region containing vEvent */
+ tmp.eUp = vEvent.anEdge.Sym;
+ /* __GL_DICTLISTKEY */ /* __gl_dictListSearch */
+ regUp = (ActiveRegion) Dict.dictKey(Dict.dictSearch(tess.dict, tmp));
+ regLo = RegionBelow(regUp);
+ eUp = regUp.eUp;
+ eLo = regLo.eUp;
+
+ /* Try merging with U or L first */
+ if (Geom.EdgeSign(eUp.Sym.Org, vEvent, eUp.Org) == 0) {
+ ConnectLeftDegenerate(tess, regUp, vEvent);
+ return;
+ }
+
+ /* Connect vEvent to rightmost processed vertex of either chain.
+ * e.Sym.Org is the vertex that we will connect to vEvent.
+ */
+ reg = Geom.VertLeq(eLo.Sym.Org, eUp.Sym.Org) ? regUp : regLo;
+
+ if (regUp.inside || reg.fixUpperEdge) {
+ if (reg == regUp) {
+ eNew = Mesh.__gl_meshConnect(vEvent.anEdge.Sym, eUp.Lnext);
+ if (eNew == null) throw new RuntimeException();
+ } else {
+ GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(eLo.Sym.Onext.Sym, vEvent.anEdge);
+ if (tempHalfEdge == null) throw new RuntimeException();
+
+ eNew = tempHalfEdge.Sym;
+ }
+ if (reg.fixUpperEdge) {
+ if (!FixUpperEdge(reg, eNew)) throw new RuntimeException();
+ } else {
+ ComputeWinding(tess, AddRegionBelow(tess, regUp, eNew));
+ }
+ SweepEvent(tess, vEvent);
+ } else {
+ /* The new vertex is in a region which does not belong to the polygon.
+ * We don''t need to connect this vertex to the rest of the mesh.
+ */
+ AddRightEdges(tess, regUp, vEvent.anEdge, vEvent.anEdge, null, true);
+ }
+ }
+
+
+ static void SweepEvent(GLUtessellatorImpl tess, GLUvertex vEvent)
+/*
+ * Does everything necessary when the sweep line crosses a vertex.
+ * Updates the mesh and the edge dictionary.
+ */ {
+ ActiveRegion regUp, reg;
+ GLUhalfEdge e, eTopLeft, eBottomLeft;
+
+ tess.event = vEvent; /* for access in EdgeLeq() */
+ DebugEvent(tess);
+
+ /* Check if this vertex is the right endpoint of an edge that is
+ * already in the dictionary. In this case we don't need to waste
+ * time searching for the location to insert new edges.
+ */
+ e = vEvent.anEdge;
+ while (e.activeRegion == null) {
+ e = e.Onext;
+ if (e == vEvent.anEdge) {
+ /* All edges go right -- not incident to any processed edges */
+ ConnectLeftVertex(tess, vEvent);
+ return;
+ }
+ }
+
+ /* Processing consists of two phases: first we "finish" all the
+ * active regions where both the upper and lower edges terminate
+ * at vEvent (ie. vEvent is closing off these regions).
+ * We mark these faces "inside" or "outside" the polygon according
+ * to their winding number, and delete the edges from the dictionary.
+ * This takes care of all the left-going edges from vEvent.
+ */
+ regUp = TopLeftRegion(e.activeRegion);
+ if (regUp == null) throw new RuntimeException();
+ reg = RegionBelow(regUp);
+ eTopLeft = reg.eUp;
+ eBottomLeft = FinishLeftRegions(tess, reg, null);
+
+ /* Next we process all the right-going edges from vEvent. This
+ * involves adding the edges to the dictionary, and creating the
+ * associated "active regions" which record information about the
+ * regions between adjacent dictionary edges.
+ */
+ if (eBottomLeft.Onext == eTopLeft) {
+ /* No right-going edges -- add a temporary "fixable" edge */
+ ConnectRightVertex(tess, regUp, eBottomLeft);
+ } else {
+ AddRightEdges(tess, regUp, eBottomLeft.Onext, eTopLeft, eTopLeft, true);
+ }
+ }
+
+
+/* Make the sentinel coordinates big enough that they will never be
+ * merged with real input features. (Even with the largest possible
+ * input contour and the maximum tolerance of 1.0, no merging will be
+ * done with coordinates larger than 3 * GLU_TESS_MAX_COORD).
+ */
+ private static final double SENTINEL_COORD = (4.0 * GLU.GLU_TESS_MAX_COORD);
+
+ static void AddSentinel(GLUtessellatorImpl tess, double t)
+/*
+ * We add two sentinel edges above and below all other edges,
+ * to avoid special cases at the top and bottom.
+ */ {
+ GLUhalfEdge e;
+ ActiveRegion reg = new ActiveRegion();
+ if (reg == null) throw new RuntimeException();
+
+ e = Mesh.__gl_meshMakeEdge(tess.mesh);
+ if (e == null) throw new RuntimeException();
+
+ e.Org.s = SENTINEL_COORD;
+ e.Org.t = t;
+ e.Sym.Org.s = -SENTINEL_COORD;
+ e.Sym.Org.t = t;
+ tess.event = e.Sym.Org; /* initialize it */
+
+ reg.eUp = e;
+ reg.windingNumber = 0;
+ reg.inside = false;
+ reg.fixUpperEdge = false;
+ reg.sentinel = true;
+ reg.dirty = false;
+ reg.nodeUp = Dict.dictInsert(tess.dict, reg); /* __gl_dictListInsertBefore */
+ if (reg.nodeUp == null) throw new RuntimeException();
+ }
+
+
+ static void InitEdgeDict(final GLUtessellatorImpl tess)
+/*
+ * We maintain an ordering of edge intersections with the sweep line.
+ * This order is maintained in a dynamic dictionary.
+ */ {
+ /* __gl_dictListNewDict */
+ tess.dict = Dict.dictNewDict(tess, new Dict.DictLeq() {
+ public boolean leq(Object frame, Object key1, Object key2) {
+ return EdgeLeq(tess, (ActiveRegion) key1, (ActiveRegion) key2);
+ }
+ });
+ if (tess.dict == null) throw new RuntimeException();
+
+ AddSentinel(tess, -SENTINEL_COORD);
+ AddSentinel(tess, SENTINEL_COORD);
+ }
+
+
+ static void DoneEdgeDict(GLUtessellatorImpl tess) {
+ ActiveRegion reg;
+ int fixedEdges = 0;
+
+ /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */
+ while ((reg = (ActiveRegion) Dict.dictKey(Dict.dictMin(tess.dict))) != null) {
+ /*
+ * At the end of all processing, the dictionary should contain
+ * only the two sentinel edges, plus at most one "fixable" edge
+ * created by ConnectRightVertex().
+ */
+ if (!reg.sentinel) {
+ assert (reg.fixUpperEdge);
+ assert (++fixedEdges == 1);
+ }
+ assert (reg.windingNumber == 0);
+ DeleteRegion(tess, reg);
+/* __gl_meshDelete( reg.eUp );*/
+ }
+ Dict.dictDeleteDict(tess.dict); /* __gl_dictListDeleteDict */
+ }
+
+
+ static void RemoveDegenerateEdges(GLUtessellatorImpl tess)
+/*
+ * Remove zero-length edges, and contours with fewer than 3 vertices.
+ */ {
+ GLUhalfEdge e, eNext, eLnext;
+ GLUhalfEdge eHead = tess.mesh.eHead;
+
+ /*LINTED*/
+ for (e = eHead.next; e != eHead; e = eNext) {
+ eNext = e.next;
+ eLnext = e.Lnext;
+
+ if (Geom.VertEq(e.Org, e.Sym.Org) && e.Lnext.Lnext != e) {
+ /* Zero-length edge, contour has at least 3 edges */
+
+ SpliceMergeVertices(tess, eLnext, e); /* deletes e.Org */
+ if (!Mesh.__gl_meshDelete(e)) throw new RuntimeException(); /* e is a self-loop */
+ e = eLnext;
+ eLnext = e.Lnext;
+ }
+ if (eLnext.Lnext == e) {
+ /* Degenerate contour (one or two edges) */
+
+ if (eLnext != e) {
+ if (eLnext == eNext || eLnext == eNext.Sym) {
+ eNext = eNext.next;
+ }
+ if (!Mesh.__gl_meshDelete(eLnext)) throw new RuntimeException();
+ }
+ if (e == eNext || e == eNext.Sym) {
+ eNext = eNext.next;
+ }
+ if (!Mesh.__gl_meshDelete(e)) throw new RuntimeException();
+ }
+ }
+ }
+
+ static boolean InitPriorityQ(GLUtessellatorImpl tess)
+/*
+ * Insert all vertices into the priority queue which determines the
+ * order in which vertices cross the sweep line.
+ */ {
+ PriorityQ pq;
+ GLUvertex v, vHead;
+
+ /* __gl_pqSortNewPriorityQ */
+ pq = tess.pq = PriorityQ.pqNewPriorityQ(new PriorityQ.Leq() {
+ public boolean leq(Object key1, Object key2) {
+ return Geom.VertLeq(((GLUvertex) key1), (GLUvertex) key2);
+ }
+ });
+ if (pq == null) return false;
+
+ vHead = tess.mesh.vHead;
+ for (v = vHead.next; v != vHead; v = v.next) {
+ v.pqHandle = pq.pqInsert(v); /* __gl_pqSortInsert */
+ if (v.pqHandle == Long.MAX_VALUE) break;
+ }
+ if (v != vHead || !pq.pqInit()) { /* __gl_pqSortInit */
+ tess.pq.pqDeletePriorityQ(); /* __gl_pqSortDeletePriorityQ */
+ tess.pq = null;
+ return false;
+ }
+
+ return true;
+ }
+
+
+ static void DonePriorityQ(GLUtessellatorImpl tess) {
+ tess.pq.pqDeletePriorityQ(); /* __gl_pqSortDeletePriorityQ */
+ }
+
+
+ static boolean RemoveDegenerateFaces(GLUmesh mesh)
+/*
+ * Delete any degenerate faces with only two edges. WalkDirtyRegions()
+ * will catch almost all of these, but it won't catch degenerate faces
+ * produced by splice operations on already-processed edges.
+ * The two places this can happen are in FinishLeftRegions(), when
+ * we splice in a "temporary" edge produced by ConnectRightVertex(),
+ * and in CheckForLeftSplice(), where we splice already-processed
+ * edges to ensure that our dictionary invariants are not violated
+ * by numerical errors.
+ *
+ * In both these cases it is *very* dangerous to delete the offending
+ * edge at the time, since one of the routines further up the stack
+ * will sometimes be keeping a pointer to that edge.
+ */ {
+ GLUface f, fNext;
+ GLUhalfEdge e;
+
+ /*LINTED*/
+ for (f = mesh.fHead.next; f != mesh.fHead; f = fNext) {
+ fNext = f.next;
+ e = f.anEdge;
+ assert (e.Lnext != e);
+
+ if (e.Lnext.Lnext == e) {
+ /* A face with only two edges */
+ AddWinding(e.Onext, e);
+ if (!Mesh.__gl_meshDelete(e)) return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean __gl_computeInterior(GLUtessellatorImpl tess)
+/*
+ * __gl_computeInterior( tess ) computes the planar arrangement specified
+ * by the given contours, and further subdivides this arrangement
+ * into regions. Each region is marked "inside" if it belongs
+ * to the polygon, according to the rule given by tess.windingRule.
+ * Each interior region is guaranteed be monotone.
+ */ {
+ GLUvertex v, vNext;
+
+ tess.fatalError = false;
+
+ /* Each vertex defines an event for our sweep line. Start by inserting
+ * all the vertices in a priority queue. Events are processed in
+ * lexicographic order, ie.
+ *
+ * e1 < e2 iff e1.x < e2.x || (e1.x == e2.x && e1.y < e2.y)
+ */
+ RemoveDegenerateEdges(tess);
+ if (!InitPriorityQ(tess)) return false; /* if error */
+ InitEdgeDict(tess);
+
+ /* __gl_pqSortExtractMin */
+ while ((v = (GLUvertex) tess.pq.pqExtractMin()) != null) {
+ for (; ;) {
+ vNext = (GLUvertex) tess.pq.pqMinimum(); /* __gl_pqSortMinimum */
+ if (vNext == null || !Geom.VertEq(vNext, v)) break;
+
+ /* Merge together all vertices at exactly the same location.
+ * This is more efficient than processing them one at a time,
+ * simplifies the code (see ConnectLeftDegenerate), and is also
+ * important for correct handling of certain degenerate cases.
+ * For example, suppose there are two identical edges A and B
+ * that belong to different contours (so without this code they would
+ * be processed by separate sweep events). Suppose another edge C
+ * crosses A and B from above. When A is processed, we split it
+ * at its intersection point with C. However this also splits C,
+ * so when we insert B we may compute a slightly different
+ * intersection point. This might leave two edges with a small
+ * gap between them. This kind of error is especially obvious
+ * when using boundary extraction (GLU_TESS_BOUNDARY_ONLY).
+ */
+ vNext = (GLUvertex) tess.pq.pqExtractMin(); /* __gl_pqSortExtractMin*/
+ SpliceMergeVertices(tess, v.anEdge, vNext.anEdge);
+ }
+ SweepEvent(tess, v);
+ }
+
+ /* Set tess.event for debugging purposes */
+ /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */
+ tess.event = ((ActiveRegion) Dict.dictKey(Dict.dictMin(tess.dict))).eUp.Org;
+ DebugEvent(tess);
+ DoneEdgeDict(tess);
+ DonePriorityQ(tess);
+
+ if (!RemoveDegenerateFaces(tess.mesh)) return false;
+ Mesh.__gl_meshCheckMesh(tess.mesh);
+
+ return true;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/TessMono.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/TessMono.java
new file mode 100644
index 000000000..ef89b1613
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/TessMono.java
@@ -0,0 +1,241 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class TessMono {
+/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region
+ * (what else would it do??) The region must consist of a single
+ * loop of half-edges (see mesh.h) oriented CCW. "Monotone" in this
+ * case means that any vertical line intersects the interior of the
+ * region in a single interval.
+ *
+ * Tessellation consists of adding interior edges (actually pairs of
+ * half-edges), to split the region into non-overlapping triangles.
+ *
+ * The basic idea is explained in Preparata and Shamos (which I don''t
+ * have handy right now), although their implementation is more
+ * complicated than this one. The are two edge chains, an upper chain
+ * and a lower chain. We process all vertices from both chains in order,
+ * from right to left.
+ *
+ * The algorithm ensures that the following invariant holds after each
+ * vertex is processed: the untessellated region consists of two
+ * chains, where one chain (say the upper) is a single edge, and
+ * the other chain is concave. The left vertex of the single edge
+ * is always to the left of all vertices in the concave chain.
+ *
+ * Each step consists of adding the rightmost unprocessed vertex to one
+ * of the two chains, and forming a fan of triangles from the rightmost
+ * of two chain endpoints. Determining whether we can add each triangle
+ * to the fan is a simple orientation test. By making the fan as large
+ * as possible, we restore the invariant (check it yourself).
+ */
+ static boolean __gl_meshTessellateMonoRegion(GLUface face, boolean avoidDegenerateTris) {
+ GLUhalfEdge up, lo;
+
+ /* All edges are oriented CCW around the boundary of the region.
+ * First, find the half-edge whose origin vertex is rightmost.
+ * Since the sweep goes from left to right, face->anEdge should
+ * be close to the edge we want.
+ */
+ up = face.anEdge;
+ assert (up.Lnext != up && up.Lnext.Lnext != up);
+
+ for (; Geom.VertLeq(up.Sym.Org, up.Org); up = up.Onext.Sym)
+ ;
+ for (; Geom.VertLeq(up.Org, up.Sym.Org); up = up.Lnext)
+ ;
+ lo = up.Onext.Sym;
+
+ boolean mustConnect = false; // hack for avoidDegenerateTris
+
+ while (up.Lnext != lo) {
+ if (avoidDegenerateTris && !mustConnect) {
+ // Skip over regions where several vertices are collinear,
+ // to try to avoid producing degenerate (zero-area) triangles
+ //
+ // The "mustConnect" flag is a hack to try to avoid
+ // skipping too large regions and causing incorrect
+ // triangulations. This entire modification is overall
+ // not robust and needs more work
+ if (Geom.EdgeCos(lo.Lnext.Org, lo.Org, lo.Lnext.Lnext.Org) <= -Geom.ONE_MINUS_EPSILON) {
+ // Lines around lo
+ do {
+ lo = lo.Onext.Sym;
+ mustConnect = true;
+ } while (up.Lnext != lo &&
+ Geom.EdgeCos(lo.Lnext.Org, lo.Org, lo.Lnext.Lnext.Org) <= -Geom.ONE_MINUS_EPSILON);
+ } else if (Geom.EdgeCos(up.Onext.Sym.Org, up.Org, up.Onext.Sym.Onext.Sym.Org) <= -Geom.ONE_MINUS_EPSILON) {
+ // Lines around up
+ do {
+ up = up.Lnext;
+ mustConnect = true;
+ } while (up.Lnext != lo &&
+ Geom.EdgeCos(up.Onext.Sym.Org, up.Org, up.Onext.Sym.Onext.Sym.Org) <= -Geom.ONE_MINUS_EPSILON);
+ }
+
+ if (up.Lnext == lo)
+ break;
+ }
+
+ if (Geom.VertLeq(up.Sym.Org, lo.Org)) {
+ /* up.Sym.Org is on the left. It is safe to form triangles from lo.Org.
+ * The EdgeGoesLeft test guarantees progress even when some triangles
+ * are CW, given that the upper and lower chains are truly monotone.
+ */
+ while (lo.Lnext != up && (Geom.EdgeGoesLeft(lo.Lnext)
+ || Geom.EdgeSign(lo.Org, lo.Sym.Org, lo.Lnext.Sym.Org) <= 0)) {
+ GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(lo.Lnext, lo);
+ mustConnect = false;
+ if (tempHalfEdge == null) return false;
+ lo = tempHalfEdge.Sym;
+ }
+ lo = lo.Onext.Sym;
+ } else {
+ /* lo.Org is on the left. We can make CCW triangles from up.Sym.Org. */
+ while (lo.Lnext != up && (Geom.EdgeGoesRight(up.Onext.Sym)
+ || Geom.EdgeSign(up.Sym.Org, up.Org, up.Onext.Sym.Org) >= 0)) {
+ GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(up, up.Onext.Sym);
+ mustConnect = false;
+ if (tempHalfEdge == null) return false;
+ up = tempHalfEdge.Sym;
+ }
+ up = up.Lnext;
+ }
+ }
+
+ /* Now lo.Org == up.Sym.Org == the leftmost vertex. The remaining region
+ * can be tessellated in a fan from this leftmost vertex.
+ */
+ assert (lo.Lnext != up);
+ while (lo.Lnext.Lnext != up) {
+ GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(lo.Lnext, lo);
+ if (tempHalfEdge == null) return false;
+ lo = tempHalfEdge.Sym;
+ }
+
+ return true;
+ }
+
+
+/* __gl_meshTessellateInterior( mesh ) tessellates each region of
+ * the mesh which is marked "inside" the polygon. Each such region
+ * must be monotone.
+ */
+ public static boolean __gl_meshTessellateInterior(GLUmesh mesh, boolean avoidDegenerateTris) {
+ GLUface f, next;
+
+ /*LINTED*/
+ for (f = mesh.fHead.next; f != mesh.fHead; f = next) {
+ /* Make sure we don''t try to tessellate the new triangles. */
+ next = f.next;
+ if (f.inside) {
+ if (!__gl_meshTessellateMonoRegion(f, avoidDegenerateTris)) return false;
+ }
+ }
+
+ return true;
+ }
+
+
+/* __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces
+ * which are not marked "inside" the polygon. Since further mesh operations
+ * on NULL faces are not allowed, the main purpose is to clean up the
+ * mesh so that exterior loops are not represented in the data structure.
+ */
+ public static void __gl_meshDiscardExterior(GLUmesh mesh) {
+ GLUface f, next;
+
+ /*LINTED*/
+ for (f = mesh.fHead.next; f != mesh.fHead; f = next) {
+ /* Since f will be destroyed, save its next pointer. */
+ next = f.next;
+ if (!f.inside) {
+ Mesh.__gl_meshZapFace(f);
+ }
+ }
+ }
+
+ private static final int MARKED_FOR_DELETION = 0x7fffffff;
+
+/* __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the
+ * winding numbers on all edges so that regions marked "inside" the
+ * polygon have a winding number of "value", and regions outside
+ * have a winding number of 0.
+ *
+ * If keepOnlyBoundary is TRUE, it also deletes all edges which do not
+ * separate an interior region from an exterior one.
+ */
+ public static boolean __gl_meshSetWindingNumber(GLUmesh mesh, int value, boolean keepOnlyBoundary) {
+ GLUhalfEdge e, eNext;
+
+ for (e = mesh.eHead.next; e != mesh.eHead; e = eNext) {
+ eNext = e.next;
+ if (e.Sym.Lface.inside != e.Lface.inside) {
+
+ /* This is a boundary edge (one side is interior, one is exterior). */
+ e.winding = (e.Lface.inside) ? value : -value;
+ } else {
+
+ /* Both regions are interior, or both are exterior. */
+ if (!keepOnlyBoundary) {
+ e.winding = 0;
+ } else {
+ if (!Mesh.__gl_meshDelete(e)) return false;
+ }
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/TessState.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/TessState.java
new file mode 100644
index 000000000..a8aa41d9f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/tessellator/TessState.java
@@ -0,0 +1,59 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package com.jogamp.opengl.impl.glu.tessellator;
+
+class TessState {
+ public static final int T_DORMANT = 0;
+ public static final int T_IN_POLYGON = 1;
+ public static final int T_IN_CONTOUR = 2;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java
new file mode 100644
index 000000000..ebefaf466
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+
+public abstract class MacOSXCGLContext extends GLContextImpl
+{
+ protected long nsContext; // NSOpenGLContext
+ protected long cglContext; // CGLContextObj
+ private CGLExt cglExt;
+ // Table that holds the addresses of the native C-language entry points for
+ // CGL extension functions.
+ private CGLExtProcAddressTable cglExtProcAddressTable;
+
+ public MacOSXCGLContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead,
+ GLContext shareWith) {
+ super(drawable, drawableRead, shareWith);
+ }
+
+ public MacOSXCGLContext(GLDrawableImpl drawable,
+ GLContext shareWith) {
+ this(drawable, null, shareWith);
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getCGLExt();
+ }
+
+ public CGLExt getCGLExt() {
+ if (cglExt == null) {
+ cglExt = new CGLExtImpl(this);
+ }
+ return cglExt;
+ }
+
+ public final ProcAddressTable getPlatformExtProcAddressTable() {
+ return getCGLExtProcAddressTable();
+ }
+
+ public final CGLExtProcAddressTable getCGLExtProcAddressTable() {
+ return cglExtProcAddressTable;
+ }
+
+ protected Map/*<String, String>*/ getFunctionNameMap() { return null; }
+
+ protected Map/*<String, String>*/ getExtensionNameMap() { return null; }
+
+ protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) {
+ return 0; // FIXME
+ }
+
+ protected void destroyContextARBImpl(long _context) {
+ // FIXME
+ }
+
+ /**
+ * Creates and initializes an appropriate OpenGl nsContext. Should only be
+ * called by {@link makeCurrentImpl()}.
+ */
+ protected boolean create(boolean pbuffer, boolean floatingPoint) {
+ MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getNSContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+ MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilitiesRequested = (GLCapabilities)config.getRequestedCapabilities();
+ GLProfile glProfile = capabilitiesRequested.getGLProfile();
+ if(glProfile.isGL3()) {
+ throw new GLException("GL3 profile currently not supported on MacOSX, due to the lack of a OpenGL 3.1 implementation");
+ }
+ // HACK .. bring in OnScreen/PBuffer selection to the DrawableFactory !!
+ GLCapabilities capabilities = (GLCapabilities) capabilitiesRequested.clone();
+ capabilities.setPBuffer(pbuffer);
+ capabilities.setPbufferFloatingPointBuffers(floatingPoint);
+
+ long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(capabilities);
+ if (pixelFormat == 0) {
+ throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
+ }
+ config.setChosenPixelFormat(pixelFormat);
+ try {
+ int[] viewNotReady = new int[1];
+ // Try to allocate a context with this
+ nsContext = CGL.createContext(share,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ pixelFormat,
+ viewNotReady, 0);
+ if (nsContext == 0) {
+ if (viewNotReady[0] == 1) {
+ if (DEBUG) {
+ System.err.println("!!! View not ready for " + getClass().getName());
+ }
+ // View not ready at the window system level -- this is OK
+ return false;
+ }
+ throw new GLException("Error creating NSOpenGLContext with requested pixel format");
+ }
+
+ if (!pbuffer && !capabilities.isBackgroundOpaque()) {
+ // Set the context opacity
+ CGL.setContextOpacity(nsContext, 0);
+ }
+
+ GLCapabilities caps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(glProfile, pixelFormat);
+ config.setChosenCapabilities(caps);
+ } finally {
+ CGL.deletePixelFormat(pixelFormat);
+ }
+ if (!CGL.makeCurrentContext(nsContext)) {
+ throw new GLException("Error making nsContext current");
+ }
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+ GLContextShareSet.contextCreated(this);
+ return true;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (0 == cglContext && drawable.getNativeWindow().getSurfaceHandle() == 0) {
+ throw new GLException("drawable not properly initialized: "+drawable);
+ }
+ boolean created = false;
+ if ( 0 == cglContext && 0 == nsContext) {
+ create();
+ created = 0 != cglContext || 0 != nsContext ;
+ if(!created) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ if (DEBUG) {
+ System.err.println("!!! Created OpenGL context " + toHexString(nsContext) + " for " + getClass().getName());
+ }
+ }
+
+ if ( 0 != cglContext ) {
+ if (CGL.kCGLNoError != CGL.CGLSetCurrentContext(cglContext)) {
+ throw new GLException("Error making cglContext current");
+ }
+ } else {
+ if (!CGL.makeCurrentContext(nsContext)) {
+ throw new GLException("Error making nsContext current");
+ }
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ if ( 0 != cglContext ) {
+ CGL.CGLReleaseContext(cglContext);
+ } else {
+ if (!CGL.clearCurrentContext(nsContext)) {
+ throw new GLException("Error freeing OpenGL nsContext");
+ }
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ boolean hadContext = isCreated();
+ if ( 0 != cglContext ) {
+ if (CGL.kCGLNoError != CGL.CGLDestroyContext(cglContext)) {
+ throw new GLException("Unable to delete OpenGL cglContext");
+ }
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL cglContext " + cglContext);
+ }
+ cglContext = 0;
+ GLContextShareSet.contextDestroyed(this);
+ } else if ( 0 != nsContext ) {
+ if (!CGL.deleteContext(nsContext)) {
+ throw new GLException("Unable to delete OpenGL nsContext");
+ }
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL nsContext " + nsContext);
+ }
+ nsContext = 0;
+ }
+ if(hadContext) {
+ GLContextShareSet.contextDestroyed(this);
+ }
+ }
+
+ public boolean isCreated() {
+ return 0 != cglContext || 0 != nsContext ;
+ }
+
+ public void copy(GLContext source, int mask) throws GLException {
+ long dst = getCGLContext();
+ long src = 0;
+ if( 0 != dst ) {
+ src = ((MacOSXCGLContext) source).getCGLContext();
+ if (src == 0) {
+ throw new GLException("Source OpenGL cglContext has not been created ; Destination has a cglContext.");
+ }
+ CGL.CGLCopyContext(src, dst, mask);
+ } else {
+ dst = getNSContext();
+ src = ((MacOSXCGLContext) source).getNSContext();
+ if (src == 0) {
+ throw new GLException("Source OpenGL nsContext has not been created");
+ }
+ if (dst == 0) {
+ throw new GLException("Destination OpenGL nsContext has not been created");
+ }
+ CGL.copyContext(dst, src, mask);
+ }
+ }
+
+ protected void updateGLProcAddressTable(int major, int minor, int ctp) {
+ if (DEBUG) {
+ System.err.println("!!! Initializing CGL extension address table");
+ }
+ if (cglExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ cglExtProcAddressTable = new CGLExtProcAddressTable();
+ }
+ resetProcAddressTable(getCGLExtProcAddressTable());
+ super.updateGLProcAddressTable(major, minor, ctp);
+ }
+
+ public String getPlatformExtensionsString()
+ {
+ return "";
+ }
+
+ protected void setSwapIntervalImpl(int interval) {
+ if ( 0 != cglContext ) {
+ int[] lval = new int[] { (int) interval } ;
+ CGL.CGLSetParameter(cglContext, CGL.kCGLCPSwapInterval, lval, 0);
+ } else if ( 0 != nsContext ) {
+ CGL.setSwapInterval(nsContext, interval);
+ } else {
+ throw new GLException("OpenGL context not current");
+ }
+ currentSwapInterval = interval ;
+ }
+
+ public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+ // FIXME: apparently the Apple extension doesn't require a custom memory allocator
+ throw new GLException("Not yet implemented");
+ }
+
+ public boolean isFunctionAvailable(String glFunctionName)
+ {
+ return super.isFunctionAvailable(glFunctionName);
+ }
+
+ public boolean isExtensionAvailable(String glExtensionName) {
+ if (glExtensionName.equals("GL_ARB_pbuffer") ||
+ glExtensionName.equals("GL_ARB_pixel_format")) {
+ return true;
+ }
+ return super.isExtensionAvailable(glExtensionName);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ // Support for "mode switching" as described in MacOSXCGLDrawable
+ public abstract void setOpenGLMode(int mode);
+ public abstract int getOpenGLMode();
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ public long getCGLContext() {
+ return cglContext;
+ }
+ public long getNSContext() {
+ return nsContext;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java
new file mode 100644
index 000000000..cf29d214b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.common.os.DynamicLookupHelper;
+
+public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
+ // The Java2D/OpenGL pipeline on OS X uses low-level CGLContextObjs
+ // to represent the contexts for e.g. the Java2D back buffer. When
+ // the Java2D/JOGL bridge is active, this means that if we want to
+ // be able to share textures and display lists with the Java2D
+ // contexts, we need to use the CGL APIs rather than the NSOpenGL
+ // APIs on the JOGL side. For example, if we create a pbuffer using
+ // the NSOpenGL APIs and want to share textures and display lists
+ // between it and the Java2D back buffer, there is no way to do so,
+ // because the Java2D context is actually a CGLContextObj and the
+ // NSOpenGLContext's initWithFormat:shareContext: only accepts an
+ // NSOpenGLContext as its second argument. Of course there is no way
+ // to wrap an NSOpenGLContext around an arbitrary CGLContextObj.
+ //
+ // The situation we care most about is allowing a GLPbuffer to share
+ // textures, etc. with a GLJPanel when the Java2D/JOGL bridge is
+ // active; several of the demos rely on this functionality. We aim
+ // to get there by allowing a GLPBuffer to switch its implementation
+ // between using an NSOpenGLPixelBuffer and a CGLPBufferObj. In
+ // order to track whether this has been done we need to have the
+ // notion of a "mode" of both the MacOSXCGLDrawable and the
+ // MacOSXGLContext. Initially the mode is "unspecified", meaning it
+ // leans toward the default (NSOpenGL). If sharing is requested
+ // between either a GLJPanel and a GLPbuffer or a GLCanvas and a
+ // GLPbuffer, the GLPbuffer will be switched into the appropriate
+ // mode: CGL mode for a GLJPanel and NSOpenGL mode for a GLCanvas.
+ // To avoid thrashing we support exactly one such switch during the
+ // lifetime of a given GLPbuffer. This is not a fully general
+ // solution (for example, you can't share textures among a
+ // GLPbuffer, a GLJPanel and a GLCanvas simultaneously) but should
+ // be enough to get things off the ground.
+ public static final int NSOPENGL_MODE = 1;
+ public static final int CGL_MODE = 2;
+
+ public MacOSXCGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) {
+ super(factory, comp, realized);
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ if( NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface() ) {
+ throw new GLException("Couldn't lock surface");
+ }
+ // locking the surface is essential to update surface data
+ unlockSurface();
+ }
+ }
+
+ public DynamicLookupHelper getDynamicLookupHelper() {
+ return (MacOSXCGLDrawableFactory) getFactoryImpl() ;
+ }
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+
+ // Support for "mode switching" as per above
+ public abstract void setOpenGLMode(int mode);
+ public abstract int getOpenGLMode();
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java
new file mode 100644
index 000000000..d10434252
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import com.jogamp.common.os.DynamicLookupHelper;
+import java.nio.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.util.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+
+public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl implements DynamicLookupHelper {
+ public MacOSXCGLDrawableFactory() {
+ super();
+
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ new MacOSXCGLGraphicsConfigurationFactory();
+
+ try {
+ ReflectionUtil.createInstance("com.jogamp.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLGraphicsConfigurationFactory",
+ new Object[] {});
+ } catch (JogampRuntimeException jre) { /* n/a .. */ }
+ }
+
+ protected final GLDrawableImpl getSharedDrawable() { return null; }
+ protected final GLContextImpl getSharedContext() { return null; }
+
+ public GLDrawableImpl createOnscreenDrawable(NativeWindow target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ return new MacOSXOnscreenCGLDrawable(this, target);
+ }
+
+ protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) {
+ return new MacOSXOffscreenCGLDrawable(this, target);
+ }
+
+ public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+ return true;
+ }
+
+ protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeWindow target) {
+ /**
+ * FIXME: Think about this ..
+ * should not be necessary ? ..
+ final List returnList = new ArrayList();
+ final GLDrawableFactory factory = this;
+ Runnable r = new Runnable() {
+ public void run() {
+ returnList.add(new MacOSXPbufferCGLDrawable(factory, target));
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ return (GLDrawableImpl) returnList.get(0);
+ */
+ return new MacOSXPbufferCGLDrawable(this, target);
+ }
+
+ protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
+ AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault();
+ NullWindow nw = new NullWindow(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, screen, true));
+ nw.setSize(width, height);
+ return nw;
+ }
+
+ public GLContext createExternalGLContext() {
+ return MacOSXExternalCGLContext.create(this, null);
+ }
+
+ public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) {
+ return false;
+ }
+
+ public GLDrawable createExternalGLDrawable() {
+ // FIXME
+ throw new GLException("Not yet implemented");
+ }
+
+ public void loadGLULibrary() {
+ // Nothing to do; already loaded by native code; not much point in
+ // making it lazier on this platform
+ }
+
+ public long dynamicLookupFunction(String glFuncName) {
+ return CGL.getProcAddress(glFuncName);
+ }
+
+ public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) {
+ return false;
+ }
+
+ public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ throw new GLException("not supported in non AWT enviroment");
+ }
+
+ //------------------------------------------------------
+ // Gamma-related functionality
+ //
+
+ private static final int GAMMA_RAMP_LENGTH = 256;
+
+ /** Returns the length of the computed gamma ramp for this OS and
+ hardware. Returns 0 if gamma changes are not supported. */
+ protected int getGammaRampLength() {
+ return GAMMA_RAMP_LENGTH;
+ }
+
+ protected boolean setGammaRamp(float[] ramp) {
+ return CGL.setGammaRamp(ramp.length,
+ ramp, 0,
+ ramp, 0,
+ ramp, 0);
+ }
+
+ protected Buffer getGammaRamp() {
+ return null;
+ }
+
+ protected void resetGammaRamp(Buffer originalGammaRamp) {
+ CGL.resetGammaRamp();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
new file mode 100644
index 000000000..889d1c333
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+
+public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+ long pixelformat;
+
+ public MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilities capsChosen, GLCapabilities capsRequested,
+ long pixelformat) {
+ super(screen, capsChosen, capsRequested);
+ this.pixelformat=pixelformat;
+ }
+
+ public Object clone() {
+ return super.clone();
+ }
+
+ protected void setChosenPixelFormat(long pixelformat) {
+ this.pixelformat=pixelformat;
+ }
+
+ protected void setChosenCapabilities(GLCapabilities caps) {
+ super.setChosenCapabilities(caps);
+ }
+
+ protected static final int[] cglInternalAttributeToken = new int[] {
+ CGL.kCGLPFAColorFloat,
+ CGL.NSOpenGLPFAPixelBuffer,
+ CGL.NSOpenGLPFADoubleBuffer,
+ CGL.NSOpenGLPFAStereo,
+ CGL.NSOpenGLPFAColorSize,
+ CGL.NSOpenGLPFAAlphaSize,
+ CGL.NSOpenGLPFADepthSize,
+ CGL.NSOpenGLPFAAccumSize,
+ CGL.NSOpenGLPFAStencilSize,
+ CGL.NSOpenGLPFASampleBuffers,
+ CGL.NSOpenGLPFASamples };
+
+ protected static int[] GLCapabilities2AttribList(GLCapabilities caps) {
+ int[] ivalues = new int[cglInternalAttributeToken.length];
+
+ for (int idx = 0; idx < cglInternalAttributeToken.length; idx++) {
+ int attr = cglInternalAttributeToken[idx];
+ switch (attr) {
+ case CGL.kCGLPFAColorFloat:
+ ivalues[idx] = caps.getPbufferFloatingPointBuffers() ? 1 : 0;
+ break;
+
+ case CGL.NSOpenGLPFAPixelBuffer:
+ ivalues[idx] = caps.isPBuffer() ? 1 : 0;
+ break;
+
+ case CGL.NSOpenGLPFADoubleBuffer:
+ ivalues[idx] = (caps.getDoubleBuffered() ? 1 : 0);
+ break;
+
+ case CGL.NSOpenGLPFAStereo:
+ ivalues[idx] = (caps.getStereo() ? 1 : 0);
+ break;
+
+ case CGL.NSOpenGLPFAColorSize:
+ ivalues[idx] = (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits());
+ break;
+
+ case CGL.NSOpenGLPFAAlphaSize:
+ ivalues[idx] = caps.getAlphaBits();
+ break;
+
+ case CGL.NSOpenGLPFADepthSize:
+ ivalues[idx] = caps.getDepthBits();
+ break;
+
+ case CGL.NSOpenGLPFAAccumSize:
+ ivalues[idx] = (caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits() + caps.getAccumAlphaBits());
+ break;
+
+ case CGL.NSOpenGLPFAStencilSize:
+ ivalues[idx] = caps.getStencilBits();
+ break;
+
+ case CGL.NSOpenGLPFASampleBuffers:
+ ivalues[idx] = caps.getSampleBuffers() ? 1 : 0;
+ break;
+
+ case CGL.NSOpenGLPFASamples:
+ ivalues[idx] = caps.getSampleBuffers() ? ivalues[idx] = caps.getNumSamples() : 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+ return ivalues;
+ }
+
+ protected static long GLCapabilities2NSPixelFormat(GLCapabilities caps) {
+ int[] ivalues = GLCapabilities2AttribList(caps);
+ return CGL.createPixelFormat(cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0);
+ }
+
+ protected static GLCapabilities NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) {
+ return PixelFormat2GLCapabilities(glp, pixelFormat, true);
+ }
+
+ protected static GLCapabilities CGLPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) {
+ return PixelFormat2GLCapabilities(glp, pixelFormat, false);
+ }
+
+ private static GLCapabilities PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) {
+ int[] ivalues = new int[cglInternalAttributeToken.length];
+
+ // On this platform the pixel format is associated with the
+ // context and not the drawable. However it's a reasonable
+ // approximation to just store the chosen pixel format up in the
+ // NativeWindow's AbstractGraphicsConfiguration,
+ // since the public API doesn't provide for a different GLCapabilities per context.
+ // Note: These restrictions of the platform's API might be considered as a bug anyways.
+
+ // Figure out what attributes we really got
+ GLCapabilities caps = new GLCapabilities(glp);
+ if(nsUsage) {
+ CGL.queryPixelFormat(pixelFormat, cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0);
+ } else {
+ CGL.CGLQueryPixelFormat(pixelFormat, cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0);
+ }
+ for (int i = 0; i < cglInternalAttributeToken.length; i++) {
+ int attr = cglInternalAttributeToken[i];
+ switch (attr) {
+ case CGL.kCGLPFAColorFloat:
+ caps.setPbufferFloatingPointBuffers(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFAPixelBuffer:
+ caps.setPBuffer(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFADoubleBuffer:
+ caps.setDoubleBuffered(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFAStereo:
+ caps.setStereo(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFAColorSize:
+ {
+ int bitSize = ivalues[i];
+ if (bitSize == 32)
+ bitSize = 24;
+ bitSize /= 3;
+ caps.setRedBits(bitSize);
+ caps.setGreenBits(bitSize);
+ caps.setBlueBits(bitSize);
+ }
+ break;
+
+ case CGL.NSOpenGLPFAAlphaSize:
+ caps.setAlphaBits(ivalues[i]);
+ break;
+
+ case CGL.NSOpenGLPFADepthSize:
+ caps.setDepthBits(ivalues[i]);
+ break;
+
+ case CGL.NSOpenGLPFAAccumSize:
+ {
+ int bitSize = ivalues[i] / 4;
+ caps.setAccumRedBits(bitSize);
+ caps.setAccumGreenBits(bitSize);
+ caps.setAccumBlueBits(bitSize);
+ caps.setAccumAlphaBits(bitSize);
+ }
+ break;
+
+ case CGL.NSOpenGLPFAStencilSize:
+ caps.setStencilBits(ivalues[i]);
+ break;
+
+ case CGL.NSOpenGLPFASampleBuffers:
+ caps.setSampleBuffers(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFASamples:
+ caps.setNumSamples(ivalues[i]);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return caps;
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..ada5fb1a7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.macosx.*;
+import com.jogamp.nativewindow.impl.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
+ are used on OSX platforms. Toolkits will likely need to delegate
+ to this one to change the accepted and returned types of the
+ GraphicsDevice and GraphicsConfiguration abstractions. */
+
+public class MacOSXCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ public MacOSXCGLGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.macosx.MacOSXGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ return chooseGraphicsConfigurationStatic(capabilities, chooser, absScreen, false);
+ }
+
+ protected static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen, boolean usePBuffer) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+ }
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if (capabilities == null) {
+ capabilities = new GLCapabilities(null);
+ }
+
+ return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilities)capabilities, (GLCapabilities)capabilities, 0);
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java
new file mode 100644
index 000000000..eba3cf50e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+import javax.media.nativewindow.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+
+public class MacOSXExternalCGLContext extends MacOSXCGLContext {
+ private boolean firstMakeCurrent = true;
+ private boolean created = true;
+ private GLContext lastContext;
+
+ private MacOSXExternalCGLContext(Drawable drawable, long cglContext, long nsContext) {
+ super(drawable, null);
+ drawable.setExternalCGLContext(this);
+ this.cglContext = cglContext;
+ this.nsContext = nsContext;
+ GLContextShareSet.contextCreated(this);
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+ getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
+ }
+
+ protected static MacOSXExternalCGLContext create(GLDrawableFactory factory, GLProfile glp) {
+ ((GLDrawableFactoryImpl)factory).lockToolkit();
+ try {
+ long pixelFormat = 0;
+ long currentDrawable = 0;
+ long cglContext = 0;
+ long nsContext = CGL.getCurrentContext(); // Check: MacOSX 10.3 ..
+ if( 0 != nsContext ) {
+ currentDrawable = CGL.getNSView(nsContext);
+ long ctx = CGL.getCGLContext(nsContext);
+ if (ctx == 0) {
+ throw new GLException("Error: NULL cglContext of nsContext 0x" +Long.toHexString(nsContext));
+ }
+ pixelFormat = CGL.CGLGetPixelFormat(ctx);
+ if(DEBUG) {
+ System.err.println("MacOSXExternalCGLContext Create nsContext 0x"+Long.toHexString(nsContext)+
+ ", cglContext 0x"+Long.toHexString(ctx)+
+ ", pixelFormat 0x"+Long.toHexString(pixelFormat));
+ }
+ } else {
+ cglContext = CGL.CGLGetCurrentContext();
+ if (cglContext == 0) {
+ throw new GLException("Error: current cglContext null, no nsContext");
+ }
+ pixelFormat = CGL.CGLGetPixelFormat(cglContext);
+ if(DEBUG) {
+ System.err.println("MacOSXExternalCGLContext Create cglContext 0x"+Long.toHexString(cglContext)+
+ ", pixelFormat 0x"+Long.toHexString(pixelFormat));
+ }
+ }
+
+ if (0 == pixelFormat) {
+ throw new GLException("Error: current pixelformat of current cglContext 0x"+Long.toHexString(cglContext)+" is null");
+ }
+ GLCapabilities caps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(glp, pixelFormat);
+ if(DEBUG) {
+ System.err.println("MacOSXExternalCGLContext Create "+caps);
+ }
+
+ AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault();
+ MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps, pixelFormat);
+
+ NullWindow nw = new NullWindow(cfg);
+ nw.setSurfaceHandle(currentDrawable);
+ return new MacOSXExternalCGLContext(new Drawable(factory, nw), cglContext, nsContext);
+ } finally {
+ ((GLDrawableFactoryImpl)factory).unlockToolkit();
+ }
+ }
+
+ protected void create() {
+ }
+
+ public int makeCurrent() throws GLException {
+ // Save last context if necessary to allow external GLContexts to
+ // talk to other GLContexts created by this library
+ GLContext cur = getCurrent();
+ if (cur != null && cur != this) {
+ lastContext = cur;
+ setCurrent(null);
+ }
+ return super.makeCurrent();
+ }
+
+ protected void swapBuffers() {
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities caps = (GLCapabilities)config.getChosenCapabilities();
+ if(caps.isOnscreen()) {
+ if (CGL.kCGLNoError != CGL.CGLFlushDrawable(cglContext)) {
+ throw new GLException("Error swapping buffers");
+ }
+ }
+ }
+
+ public void release() throws GLException {
+ super.release();
+ setCurrent(lastContext);
+ lastContext = null;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ created = false;
+ GLContextShareSet.contextDestroyed(this);
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+
+ public void setOpenGLMode(int mode) {
+ if (mode != MacOSXCGLDrawable.CGL_MODE)
+ throw new GLException("OpenGL mode switching not supported for external GLContexts");
+ }
+
+ public int getOpenGLMode() {
+ return MacOSXCGLDrawable.CGL_MODE;
+ }
+
+ // Need to provide the display connection to extension querying APIs
+ static class Drawable extends MacOSXCGLDrawable {
+ MacOSXExternalCGLContext extCtx;
+
+ Drawable(GLDrawableFactory factory, NativeWindow comp) {
+ super(factory, comp, true);
+ }
+
+ void setExternalCGLContext(MacOSXExternalCGLContext externalContext) {
+ extCtx = externalContext;
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+
+ public void setSize(int width, int height) {
+ throw new GLException("Should not call this");
+ }
+
+ protected void swapBuffersImpl() {
+ if (extCtx != null) {
+ extCtx.swapBuffers();
+ }
+ }
+
+ public void setOpenGLMode(int mode) {
+ if (mode != CGL_MODE)
+ throw new GLException("OpenGL mode switching not supported for external GLContext's drawables");
+ }
+
+ public int getOpenGLMode() {
+ return CGL_MODE;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java
new file mode 100644
index 000000000..89e293665
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXOffscreenCGLContext extends MacOSXPbufferCGLContext
+{
+ public MacOSXOffscreenCGLContext(MacOSXPbufferCGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ GL gl = getGL();
+ return gl.isGL2GL3()?GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV:GL.GL_UNSIGNED_SHORT_5_5_5_1;
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ return GL.GL_FRONT;
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ return true;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java
new file mode 100644
index 000000000..adaa48f34
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXOffscreenCGLDrawable extends MacOSXPbufferCGLDrawable {
+
+ public MacOSXOffscreenCGLDrawable(GLDrawableFactory factory,
+ NativeWindow target) {
+ super(factory, target);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new MacOSXOffscreenCGLContext(this, shareWith);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java
new file mode 100644
index 000000000..c4eaee489
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import java.util.*;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
+ protected MacOSXOnscreenCGLDrawable drawable;
+
+ public MacOSXOnscreenCGLContext(MacOSXOnscreenCGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ int lockRes = drawable.lockSurface();
+ boolean exceptionOccurred = false;
+ try {
+ if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ int ret = super.makeCurrentImpl();
+ if ((ret == CONTEXT_CURRENT) ||
+ (ret == CONTEXT_CURRENT_NEW)) {
+ // Assume the canvas might have been resized or moved and tell the OpenGL
+ // context to update itself. This used to be done only upon receiving a
+ // reshape event but that doesn't appear to be sufficient. An experiment
+ // was also done to add a HierarchyBoundsListener to the GLCanvas and
+ // do this updating only upon reshape of this component or reshape or movement
+ // of an ancestor, but this also wasn't sufficient and left garbage on the
+ // screen in some situations.
+ CGL.updateContext(nsContext);
+ } else {
+ if (!isOptimizable()) {
+ // This can happen if the window currently is zero-sized, for example.
+ // Make sure we don't leave the surface locked in this case.
+ drawable.unlockSurface();
+ lockRes = NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
+ }
+ return ret;
+ } catch (RuntimeException e) {
+ exceptionOccurred = true;
+ throw e;
+ } finally {
+ if (exceptionOccurred ||
+ (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY)) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ protected void releaseImpl() throws GLException {
+ try {
+ super.releaseImpl();
+ } finally {
+ if (!isOptimizable() && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ protected void swapBuffers() {
+ if (!CGL.flushBuffer(nsContext)) {
+ throw new GLException("Error swapping buffers");
+ }
+ }
+
+ protected void update() throws GLException {
+ if (nsContext == 0) {
+ throw new GLException("Context not created");
+ }
+ CGL.updateContext(nsContext);
+ }
+
+ protected void create() {
+ create(false, false);
+ }
+
+ public void setOpenGLMode(int mode) {
+ if (mode != MacOSXCGLDrawable.NSOPENGL_MODE)
+ throw new GLException("OpenGL mode switching not supported for on-screen GLContexts");
+ }
+
+ public int getOpenGLMode() {
+ return MacOSXCGLDrawable.NSOPENGL_MODE;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
new file mode 100644
index 000000000..6ee023867
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import java.lang.ref.WeakReference;
+import java.security.*;
+import java.util.*;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable {
+ private List/*<WeakReference<GLContext>>*/ createdContexts =
+ new ArrayList();
+
+ protected MacOSXOnscreenCGLDrawable(GLDrawableFactory factory, NativeWindow component) {
+ super(factory, component, false);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ MacOSXOnscreenCGLContext context =
+ new MacOSXOnscreenCGLContext(this, shareWith);
+ // NOTE: we need to keep track of the created contexts in order to
+ // implement swapBuffers() because of how Mac OS X implements its
+ // OpenGL window interface
+ synchronized (this) {
+ List newContexts = new ArrayList();
+ newContexts.addAll(createdContexts);
+ newContexts.add(new WeakReference(context));
+ createdContexts = newContexts;
+ }
+ return context;
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+ protected void swapBuffersImpl() {
+ for (Iterator iter = createdContexts.iterator(); iter.hasNext(); ) {
+ WeakReference ref = (WeakReference) iter.next();
+ MacOSXOnscreenCGLContext ctx = (MacOSXOnscreenCGLContext) ref.get();
+ // FIXME: clear out unreachable contexts
+ if (ctx != null) {
+ ctx.swapBuffers();
+ }
+ }
+ }
+
+ public void setOpenGLMode(int mode) {
+ if (mode != NSOPENGL_MODE)
+ throw new GLException("OpenGL mode switching not supported for on-screen GLDrawables");
+ }
+
+ public int getOpenGLMode() {
+ return NSOPENGL_MODE;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java
new file mode 100644
index 000000000..52a892b70
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java
@@ -0,0 +1,359 @@
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import com.jogamp.common.nio.PointerBuffer;
+import java.security.*;
+import java.util.*;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
+ protected MacOSXPbufferCGLDrawable drawable;
+
+ // State for render-to-texture and render-to-texture-rectangle support
+ private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
+ private int texture; // actual texture object
+
+ private static boolean isTigerOrLater;
+
+ static {
+ String osVersion = Debug.getProperty("os.version", false, AccessController.getContext());
+ StringTokenizer tok = new StringTokenizer(osVersion, ". ");
+ int major = Integer.parseInt(tok.nextToken());
+ int minor = Integer.parseInt(tok.nextToken());
+ isTigerOrLater = ((major > 10) || (minor > 3));
+ }
+
+ public MacOSXPbufferCGLContext(MacOSXPbufferCGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ initOpenGLImpl();
+ }
+
+ public void bindPbufferToTexture() {
+ GL gl = getGL();
+ gl.glBindTexture(textureTarget, texture);
+ // FIXME: not clear whether this is really necessary, but since
+ // the API docs seem to imply it is and since it doesn't seem to
+ // impact performance, leaving it in
+ CGL.setContextTextureImageToPBuffer(nsContext, drawable.getPbuffer(), GL.GL_FRONT);
+ }
+
+ public void releasePbufferFromTexture() {
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (drawable.getPbuffer() == 0) {
+ if (DEBUG) {
+ System.err.println("Pbuffer not instantiated yet for " + this);
+ }
+ // pbuffer not instantiated yet
+ return CONTEXT_NOT_CURRENT;
+ }
+
+ if (getOpenGLMode() != drawable.getOpenGLMode()) {
+ setOpenGLMode(drawable.getOpenGLMode());
+ }
+
+ boolean created = false;
+ if (nsContext == 0) {
+ create();
+ created = 0 != nsContext ;
+ if(!created) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ if (DEBUG) {
+ System.err.println("!!! Created OpenGL context " + toHexString(nsContext) + " for " + getClass().getName());
+ }
+ }
+
+ if (!impl.makeCurrent(nsContext)) {
+ throw new GLException("Error making nsContext current");
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+
+ // Initialize render-to-texture support if requested
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+ GL gl = getGL();
+ boolean rect = gl.isGL2GL3() && capabilities.getPbufferRenderToTextureRectangle();
+ if (rect) {
+ if (!gl.isExtensionAvailable("GL_EXT_texture_rectangle")) {
+ System.err.println("MacOSXPbufferCGLContext: WARNING: GL_EXT_texture_rectangle extension not " +
+ "supported; skipping requested render_to_texture_rectangle support for pbuffer");
+ rect = false;
+ }
+ }
+ textureTarget = (rect ? GL2.GL_TEXTURE_RECTANGLE : GL.GL_TEXTURE_2D);
+ int[] tmp = new int[1];
+ gl.glGenTextures(1, tmp, 0);
+ texture = tmp[0];
+ gl.glBindTexture(textureTarget, texture);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
+ gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, drawable.getWidth(), drawable.getHeight(), 0);
+
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ if (!impl.release(nsContext)) {
+ throw new GLException("Error releasing OpenGL nsContext");
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ if (nsContext != 0) {
+ if (!impl.destroy(nsContext)) {
+ throw new GLException("Unable to delete OpenGL context");
+ }
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL context " + nsContext);
+ }
+ nsContext = 0;
+ GLContextShareSet.contextDestroyed(this);
+ }
+ }
+
+ protected void setSwapIntervalImpl(int interval) {
+ if (nsContext == 0) {
+ throw new GLException("OpenGL context not current");
+ }
+ impl.setSwapInterval(nsContext, interval);
+ currentSwapInterval = impl.getSwapInterval() ;
+ }
+
+ public int getFloatingPointMode() {
+ return GLPbuffer.APPLE_FLOAT;
+ }
+
+ protected void create() {
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+ if (capabilities.getPbufferFloatingPointBuffers() &&
+ !isTigerOrLater) {
+ throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later");
+ }
+ // Change our OpenGL mode to match that of any share context before we create ourselves
+ MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this);
+ if (other != null) {
+ setOpenGLMode(other.getOpenGLMode());
+ }
+ // Will throw exception upon error
+ nsContext = impl.create();
+
+ if (!impl.makeCurrent(nsContext)) {
+ throw new GLException("Error making nsContext current");
+ }
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+ }
+
+ //---------------------------------------------------------------------------
+ // OpenGL "mode switching" functionality
+ //
+ private boolean haveSetOpenGLMode = false;
+ // FIXME: should consider switching the default mode based on
+ // whether the Java2D/JOGL bridge is active -- need to ask ourselves
+ // whether it's more likely that we will share with a GLCanvas or a
+ // GLJPanel when the bridge is turned on
+ private int openGLMode = MacOSXCGLDrawable.NSOPENGL_MODE;
+ // Implementation object (either NSOpenGL-based or CGL-based)
+ protected Impl impl;
+
+ public void setOpenGLMode(int mode) {
+ if (mode == openGLMode) {
+ return;
+ }
+ if (haveSetOpenGLMode) {
+ throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once");
+ }
+ destroyImpl();
+ drawable.setOpenGLMode(mode);
+ openGLMode = mode;
+ haveSetOpenGLMode = true;
+ if (DEBUG) {
+ System.err.println("Switching PBuffer context mode to " +
+ ((mode == MacOSXCGLDrawable.NSOPENGL_MODE) ? "NSOPENGL_MODE" : "CGL_MODE"));
+ }
+ initOpenGLImpl();
+ }
+
+ public int getOpenGLMode() {
+ return openGLMode;
+ }
+
+ private void initOpenGLImpl() {
+ switch (openGLMode) {
+ case MacOSXCGLDrawable.NSOPENGL_MODE:
+ impl = new NSOpenGLImpl();
+ break;
+ case MacOSXCGLDrawable.CGL_MODE:
+ impl = new CGLImpl();
+ break;
+ default:
+ throw new InternalError("Illegal implementation mode " + openGLMode);
+ }
+ }
+
+ // Abstract interface for implementation of this context (either
+ // NSOpenGL-based or CGL-based)
+ interface Impl {
+ public long create();
+ public boolean destroy(long ctx);
+ public boolean makeCurrent(long ctx);
+ public boolean release(long ctx);
+ public void setSwapInterval(long ctx, int interval);
+ public int getSwapInterval();
+ }
+
+ // NSOpenGLContext-based implementation
+ class NSOpenGLImpl implements Impl {
+ public long create() {
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+ if (capabilities.getPbufferFloatingPointBuffers() &&
+ !isTigerOrLater) {
+ throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later");
+ }
+ if (!MacOSXPbufferCGLContext.this.create(true, capabilities.getPbufferFloatingPointBuffers())) {
+ throw new GLException("Error creating context for pbuffer");
+ }
+ // Must now associate the pbuffer with our newly-created context
+ CGL.setContextPBuffer(nsContext, drawable.getPbuffer());
+ return nsContext;
+ }
+
+ public boolean destroy(long ctx) {
+ return CGL.deleteContext(ctx);
+ }
+
+ public boolean makeCurrent(long ctx) {
+ return CGL.makeCurrentContext(ctx);
+ }
+
+ public boolean release(long ctx) {
+ return CGL.clearCurrentContext(ctx);
+ }
+
+ private int currentSwapInterval = 0 ;
+
+ public void setSwapInterval(long ctx, int interval) {
+ CGL.setSwapInterval(ctx, interval);
+ currentSwapInterval = interval ;
+ }
+ public int getSwapInterval() {
+ return currentSwapInterval;
+ }
+ }
+
+ class CGLImpl implements Impl {
+ public long create() {
+ // Find and configure share context
+ MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(MacOSXPbufferCGLContext.this);
+ long share = 0;
+ if (other != null) {
+ // Reconfigure pbuffer-based GLContexts
+ if (other instanceof MacOSXPbufferCGLContext) {
+ MacOSXPbufferCGLContext ctx = (MacOSXPbufferCGLContext) other;
+ ctx.setOpenGLMode(MacOSXCGLDrawable.CGL_MODE);
+ } else {
+ if (other.getOpenGLMode() != MacOSXCGLDrawable.CGL_MODE) {
+ throw new GLException("Can't share between NSOpenGLContexts and CGLContextObjs");
+ }
+ }
+ share = other.getNSContext();
+ // Note we don't check for a 0 return value, since switching
+ // the context's mode causes it to be destroyed and not
+ // re-initialized until the next makeCurrent
+ }
+
+ // Set up pixel format attributes
+ // FIXME: shall go into MacOSXCGLGraphicsConfiguration
+ int[] attrs = new int[256];
+ int i = 0;
+ attrs[i++] = CGL.kCGLPFAPBuffer;
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+ if (capabilities.getPbufferFloatingPointBuffers())
+ attrs[i++] = CGL.kCGLPFAColorFloat;
+ if (capabilities.getDoubleBuffered())
+ attrs[i++] = CGL.kCGLPFADoubleBuffer;
+ if (capabilities.getStereo())
+ attrs[i++] = CGL.kCGLPFAStereo;
+ attrs[i++] = CGL.kCGLPFAColorSize;
+ attrs[i++] = (capabilities.getRedBits() +
+ capabilities.getGreenBits() +
+ capabilities.getBlueBits());
+ attrs[i++] = CGL.kCGLPFAAlphaSize;
+ attrs[i++] = capabilities.getAlphaBits();
+ attrs[i++] = CGL.kCGLPFADepthSize;
+ attrs[i++] = capabilities.getDepthBits();
+ // FIXME: should validate stencil size as is done in MacOSXWindowSystemInterface.m
+ attrs[i++] = CGL.kCGLPFAStencilSize;
+ attrs[i++] = capabilities.getStencilBits();
+ attrs[i++] = CGL.kCGLPFAAccumSize;
+ attrs[i++] = (capabilities.getAccumRedBits() +
+ capabilities.getAccumGreenBits() +
+ capabilities.getAccumBlueBits() +
+ capabilities.getAccumAlphaBits());
+ if (capabilities.getSampleBuffers()) {
+ attrs[i++] = CGL.kCGLPFASampleBuffers;
+ attrs[i++] = 1;
+ attrs[i++] = CGL.kCGLPFASamples;
+ attrs[i++] = capabilities.getNumSamples();
+ }
+
+ // Use attribute array to select pixel format
+ PointerBuffer fmt = PointerBuffer.allocateDirect(1);
+ long[] numScreens = new long[1];
+ int res = CGL.CGLChoosePixelFormat(attrs, 0, fmt, numScreens, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while choosing pixel format");
+ }
+
+ // Create new context
+ PointerBuffer ctx = PointerBuffer.allocateDirect(1);
+ if (DEBUG) {
+ System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share));
+ }
+ res = CGL.CGLCreateContext(fmt.get(0), share, ctx);
+ CGL.CGLDestroyPixelFormat(fmt.get(0));
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while creating context");
+ }
+ // Attach newly-created context to the pbuffer
+ res = CGL.CGLSetPBuffer(ctx.get(0), drawable.getPbuffer(), 0, 0, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while attaching context to pbuffer");
+ }
+ return ctx.get(0);
+ }
+
+ public boolean destroy(long ctx) {
+ return (CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError);
+ }
+
+ public boolean makeCurrent(long ctx) {
+ return CGL.CGLSetCurrentContext(ctx) == CGL.kCGLNoError;
+ }
+
+ public boolean release(long ctx) {
+ return (CGL.CGLSetCurrentContext(0) == CGL.kCGLNoError);
+ }
+
+ public void setSwapInterval(long ctx, int interval) {
+ // For now not supported (not really relevant for off-screen contexts anyway)
+ }
+ public int getSwapInterval() {
+ return 0;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java
new file mode 100644
index 000000000..afdc40dbb
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import com.jogamp.common.nio.PointerBuffer;
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
+ private static final boolean DEBUG = Debug.debug("MacOSXPbufferCGLDrawable");
+
+ // State for render-to-texture and render-to-texture-rectangle support
+ private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
+ private int texture; // actual texture object
+
+ // NSOpenGLPbuffer (for normal mode)
+ // CGLPbufferObj (for CGL_MODE situation, i.e., when Java2D/JOGL bridge is active)
+ // Note that we can not store this in the NativeWindow because the
+ // semantic is that contains an NSView
+ protected long pBuffer;
+
+ public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, NativeWindow target) {
+ super(factory, target, true);
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration());
+ }
+
+ initOpenGLImpl();
+ createPbuffer();
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + this);
+ }
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ createPbuffer();
+ } else {
+ destroy();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new MacOSXPbufferCGLContext(this, shareWith);
+ }
+
+ public void destroy() {
+ if (this.pBuffer != 0) {
+ NativeWindow nw = getNativeWindow();
+ impl.destroy(pBuffer);
+ this.pBuffer = 0;
+ ((SurfaceChangeable)nw).setSurfaceHandle(0);
+ if (DEBUG) {
+ System.err.println("Destroyed pbuffer: " + pBuffer);
+ }
+ }
+ }
+
+ public long getPbuffer() {
+ return pBuffer;
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+
+ private void createPbuffer() {
+ NativeWindow nw = getNativeWindow();
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+ GLProfile glProfile = capabilities.getGLProfile();
+ int renderTarget;
+ if (glProfile.isGL2GL3() && capabilities.getPbufferRenderToTextureRectangle()) {
+ renderTarget = GL2.GL_TEXTURE_RECTANGLE;
+ } else {
+ int w = getNextPowerOf2(getWidth());
+ int h = getNextPowerOf2(getHeight());
+ ((SurfaceChangeable)nw).setSize(w, h);
+ renderTarget = GL.GL_TEXTURE_2D;
+ }
+
+ int internalFormat = GL.GL_RGBA;
+ if (capabilities.getPbufferFloatingPointBuffers()) {
+ // FIXME: want to check availability of GL_APPLE_float_pixels
+ // extension, but need valid OpenGL context in order to do so --
+ // in worst case would need to create dummy window / GLCanvas
+ // (undesirable) -- could maybe also do this with pbuffers
+ /*
+ if (!gl.isExtensionAvailable("GL_APPLE_float_pixels")) {
+ throw new GLException("Floating-point support (GL_APPLE_float_pixels) not available");
+ }
+ */
+ if(glProfile.isGL2GL3()) {
+ switch (capabilities.getRedBits()) {
+ case 16: internalFormat = GL2.GL_RGBA_FLOAT16_APPLE; break;
+ case 32: internalFormat = GL2.GL_RGBA_FLOAT32_APPLE; break;
+ default: throw new GLException("Invalid floating-point bit depth (only 16 and 32 supported)");
+ }
+ } else {
+ internalFormat = GL.GL_RGBA;
+ }
+ }
+
+ pBuffer = impl.create(renderTarget, internalFormat, getWidth(), getHeight());
+ if (pBuffer == 0) {
+ throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
+ }
+
+ ((SurfaceChangeable)nw).setSurfaceHandle(pBuffer);
+
+ }
+
+ private int getNextPowerOf2(int number) {
+ if (((number-1) & number) == 0) {
+ //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
+ return number;
+ }
+ int power = 0;
+ while (number > 0) {
+ number = number>>1;
+ power++;
+ }
+ return (1<<power);
+ }
+
+ //---------------------------------------------------------------------------
+ // OpenGL "mode switching" functionality
+ //
+ private boolean haveSetOpenGLMode = false;
+ // FIXME: should consider switching the default mode based on
+ // whether the Java2D/JOGL bridge is active -- need to ask ourselves
+ // whether it's more likely that we will share with a GLCanvas or a
+ // GLJPanel when the bridge is turned on
+ private int openGLMode = NSOPENGL_MODE;
+ // Implementation object (either NSOpenGL-based or CGL-based)
+ protected Impl impl;
+
+ public void setOpenGLMode(int mode) {
+ if (mode == openGLMode) {
+ return;
+ }
+ if (haveSetOpenGLMode) {
+ throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once");
+ }
+ destroy();
+ openGLMode = mode;
+ haveSetOpenGLMode = true;
+ if (DEBUG) {
+ System.err.println("Switching PBuffer drawable mode to " +
+ ((mode == MacOSXCGLDrawable.NSOPENGL_MODE) ? "NSOPENGL_MODE" : "CGL_MODE"));
+ }
+ initOpenGLImpl();
+ createPbuffer();
+ }
+
+ public int getOpenGLMode() {
+ return openGLMode;
+ }
+
+ private void initOpenGLImpl() {
+ switch (openGLMode) {
+ case NSOPENGL_MODE:
+ impl = new NSOpenGLImpl();
+ break;
+ case CGL_MODE:
+ impl = new CGLImpl();
+ break;
+ default:
+ throw new InternalError("Illegal implementation mode " + openGLMode);
+ }
+ }
+
+ // Abstract interface for implementation of this drawable (either
+ // NSOpenGL-based or CGL-based)
+ interface Impl {
+ public long create(int renderTarget, int internalFormat, int width, int height);
+ public void destroy(long pbuffer);
+ }
+
+ // NSOpenGLPixelBuffer implementation
+ class NSOpenGLImpl implements Impl {
+ public long create(int renderTarget, int internalFormat, int width, int height) {
+ return CGL.createPBuffer(renderTarget, internalFormat, width, height);
+ }
+
+ public void destroy(long pbuffer) {
+ CGL.destroyPBuffer(pbuffer);
+ }
+ }
+
+ // CGL implementation
+ class CGLImpl implements Impl {
+ public long create(int renderTarget, int internalFormat, int width, int height) {
+ PointerBuffer pbuffer = PointerBuffer.allocateDirect(1);
+ int res = CGL.CGLCreatePBuffer(width, height, renderTarget, internalFormat, 0, pbuffer);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error creating CGL-based pbuffer: error code " + res);
+ }
+ return pbuffer.get(0);
+ }
+
+ public void destroy(long pbuffer) {
+ int res = CGL.CGLDestroyPBuffer(pbuffer);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error destroying CGL-based pbuffer: error code " + res);
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java
new file mode 100644
index 000000000..eff01ca18
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl.awt;
+
+import java.lang.reflect.InvocationTargetException;
+import java.nio.*;
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.awt.*;
+import com.jogamp.opengl.impl.macosx.cgl.*;
+
+public class MacOSXAWTCGLDrawableFactory extends MacOSXCGLDrawableFactory {
+
+ public MacOSXAWTCGLDrawableFactory() {
+ super();
+ }
+
+ public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) {
+ return true;
+ }
+
+ public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ return new MacOSXJava2DCGLContext(shareWith);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..0d59da32e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl.awt;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.macosx.*;
+import javax.media.nativewindow.awt.*;
+import javax.media.opengl.*;
+import javax.media.opengl.awt.*;
+
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.macosx.cgl.*;
+import com.jogamp.nativewindow.impl.jawt.*;
+import com.jogamp.nativewindow.impl.jawt.macosx.*;
+
+public class MacOSXAWTCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ public MacOSXAWTCGLGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ GraphicsDevice device = null;
+ if (absScreen != null &&
+ !(absScreen instanceof AWTGraphicsScreen)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
+ }
+
+ if(null==absScreen) {
+ absScreen = AWTGraphicsScreen.createScreenDevice(-1);
+ }
+ AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen;
+ device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if(DEBUG) {
+ System.err.println("MacOSXAWTCGLGraphicsConfigurationFactory: got "+absScreen);
+ }
+
+ long displayHandle = 0;
+
+ MacOSXGraphicsDevice macDevice = new MacOSXGraphicsDevice();
+ DefaultGraphicsScreen macScreen = new DefaultGraphicsScreen(macDevice, awtScreen.getIndex());
+ if(DEBUG) {
+ System.err.println("MacOSXAWTCGLGraphicsConfigurationFactory: made "+macScreen);
+ }
+
+ GraphicsConfiguration gc = device.getDefaultConfiguration();
+ AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capabilities, gc);
+ if(DEBUG) {
+ System.err.println("AWT Colormodel compatible: "+capabilities);
+ }
+
+ MacOSXCGLGraphicsConfiguration macConfig = (MacOSXCGLGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(macDevice).chooseGraphicsConfiguration(capabilities,
+ chooser,
+ macScreen);
+
+ if (macConfig == null) {
+ throw new GLException("Unable to choose a GraphicsConfiguration: "+capabilities+",\n\t"+chooser+"\n\t"+macScreen);
+ }
+
+ // FIXME: we have nothing to match .. so choose the default
+ return new AWTGraphicsConfiguration(awtScreen, macConfig.getChosenCapabilities(), macConfig.getRequestedCapabilities(), gc, macConfig);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java
new file mode 100644
index 000000000..97a1435bc
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl.awt;
+
+import com.jogamp.opengl.impl.macosx.cgl.*;
+
+import java.awt.Graphics;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.awt.*;
+import com.jogamp.opengl.impl.macosx.cgl.*;
+
+/** MacOSXCGLContext implementation supporting the Java2D/JOGL bridge
+ * on Mac OS X. The external GLDrawable mechanism does not work on Mac
+ * OS X due to how drawables and contexts are operated upon on this
+ * platform, so it is necessary to supply an alternative means to
+ * create, make current, and destroy contexts on the Java2D "drawable"
+ * on the Mac platform.
+ */
+
+public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGLContext {
+ private Graphics graphics;
+
+ // FIXME: ignoring context sharing for the time being; will need to
+ // rethink this in particular if using FBOs to implement the
+ // Java2D/OpenGL pipeline on Mac OS X
+
+ public MacOSXJava2DCGLContext(GLContext shareWith) {
+ super(null, shareWith);
+ }
+
+ public void setGraphics(Graphics g) {
+ this.graphics = g;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ boolean created = false;
+ if (nsContext == 0) {
+ create();
+ created = 0 != nsContext ;
+ if(!created) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ if (DEBUG) {
+ System.err.println("!!! Created GL nsContext for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (!Java2D.makeOGLContextCurrentOnSurface(graphics, nsContext)) {
+ throw new GLException("Error making context current");
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void create() {
+ // Find and configure share context
+ MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ // Reconfigure pbuffer-based GLContexts
+ if (other instanceof MacOSXPbufferCGLContext) {
+ MacOSXPbufferCGLContext ctx = (MacOSXPbufferCGLContext) other;
+ ctx.setOpenGLMode(MacOSXCGLDrawable.CGL_MODE);
+ } else {
+ if (other.getOpenGLMode() != MacOSXCGLDrawable.CGL_MODE) {
+ throw new GLException("Can't share between NSOpenGLContexts and CGLContextObjs");
+ }
+ }
+ share = other.getNSContext();
+ // Note we don't check for a 0 return value, since switching
+ // the context's mode causes it to be destroyed and not
+ // re-initialized until the next makeCurrent
+ }
+
+ if (DEBUG) {
+ System.err.println("!!! Share context is " + toHexString(share) + " for " + getClass().getName());
+ }
+
+ long ctx = Java2D.createOGLContextOnSurface(graphics, share);
+ if (ctx == 0) {
+ return;
+ }
+ // FIXME: think about GLContext sharing
+ nsContext = ctx;
+ }
+
+ protected void releaseImpl() throws GLException {
+ // FIXME: would need another primitive in the Java2D class in
+ // order to implement this; hopefully should not matter for
+ // correctness
+ }
+
+ protected void destroyImpl() throws GLException {
+ if (nsContext != 0) {
+ Java2D.destroyOGLContext(nsContext);
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL context " + nsContext);
+ }
+ nsContext = 0;
+ // FIXME
+ // GLContextShareSet.contextDestroyed(this);
+ }
+ }
+
+ public void setOpenGLMode(int mode) {
+ if (mode != MacOSXCGLDrawable.CGL_MODE)
+ throw new GLException("OpenGL mode switching not supported for Java2D GLContexts");
+ }
+
+ public int getOpenGLMode() {
+ return MacOSXCGLDrawable.CGL_MODE;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java
new file mode 100644
index 000000000..87a37da04
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+
+public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
+ private long hwnd, hdc;
+
+ public WindowsDummyWGLDrawable(GLDrawableFactory factory, GLProfile glp) {
+ super(factory, new NullWindow(WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(glp, null, true, true)), true);
+ // All entries to CreateDummyWindow must synchronize on one object
+ // to avoid accidentally registering the dummy window class twice
+ synchronized (WindowsDummyWGLDrawable.class) {
+ hwnd = WGL.CreateDummyWindow(0, 0, 1, 1);
+ }
+ hdc = WGL.GetDC(hwnd);
+ NullWindow nw = (NullWindow) getNativeWindow();
+ nw.setSurfaceHandle(hdc);
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nw.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ // Choose a (hopefully hardware-accelerated) OpenGL pixel format for this device context
+ GLCapabilities caps = (GLCapabilities) config.getChosenCapabilities();
+ caps.setDepthBits(16);
+ PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps);
+ int pixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
+ if ((pixelFormat == 0) ||
+ (!WGL.SetPixelFormat(hdc, pixelFormat, pfd))) {
+ destroy();
+ }
+ }
+
+ public void setSize(int width, int height) {
+ }
+
+ public int getWidth() {
+ return 1;
+ }
+
+ public int getHeight() {
+ return 1;
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ if (hdc == 0) {
+ // Construction failed
+ return null;
+ }
+ // FIXME: figure out how to hook back in the Java 2D / JOGL bridge
+ return new WindowsWGLContext(this, shareWith);
+ }
+
+ public void destroy() {
+ if (hdc != 0) {
+ WGL.ReleaseDC(hwnd, hdc);
+ hdc = 0;
+ }
+ if (hwnd != 0) {
+ WGL.ShowWindow(hwnd, WGL.SW_HIDE);
+ WGL.DestroyWindow(hwnd);
+ hwnd = 0;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java
new file mode 100755
index 000000000..e712d8568
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+
+public class WindowsExternalWGLContext extends WindowsWGLContext {
+ private boolean firstMakeCurrent = true;
+ private boolean created = true;
+ private GLContext lastContext;
+
+ private WindowsExternalWGLContext(Drawable drawable, long hglrc, WindowsWGLGraphicsConfiguration cfg) {
+ super(drawable, null);
+ this.context = hglrc;
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created external OpenGL context " + toHexString(hglrc) + " for " + this);
+ }
+ GLContextShareSet.contextCreated(this);
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+ cfg.updateCapabilitiesByWGL(this);
+ getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
+ }
+
+ protected static WindowsExternalWGLContext create(GLDrawableFactory factory, GLProfile glp) {
+ long hdc = WGL.wglGetCurrentDC();
+ if (0==hdc) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable current");
+ }
+ long hglrc = WGL.wglGetCurrentContext();
+ if (hglrc == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a context current");
+ }
+ int pfdID = WGL.GetPixelFormat(hdc);
+ if (pfdID == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat");
+ }
+
+ AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault();
+ WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(hdc, pfdID, glp, aScreen, true, true);
+
+ NullWindow nw = new NullWindow(cfg);
+ nw.setSurfaceHandle(hdc);
+
+ return new WindowsExternalWGLContext(new Drawable(factory, nw), hglrc, cfg);
+ }
+
+ public int makeCurrent() throws GLException {
+ // Save last context if necessary to allow external GLContexts to
+ // talk to other GLContexts created by this library
+ GLContext cur = getCurrent();
+ if (cur != null && cur != this) {
+ lastContext = cur;
+ setCurrent(null);
+ }
+ return super.makeCurrent();
+ }
+
+ public void release() throws GLException {
+ super.release();
+ setCurrent(lastContext);
+ lastContext = null;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ created = false;
+ GLContextShareSet.contextDestroyed(this);
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+
+ // Need to provide the display connection to extension querying APIs
+ static class Drawable extends WindowsWGLDrawable {
+ Drawable(GLDrawableFactory factory, NativeWindow comp) {
+ super(factory, comp, true);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+
+ public void setSize(int width, int height) {
+ throw new GLException("Should not call this");
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java
new file mode 100755
index 000000000..74db45932
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+
+public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
+
+ private WindowsExternalWGLDrawable(GLDrawableFactory factory, NativeWindow component) {
+ super(factory, component, true);
+ }
+
+ protected static WindowsExternalWGLDrawable create(GLDrawableFactory factory, GLProfile glp) {
+ long hdc = WGL.wglGetCurrentDC();
+ if (0==hdc) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable current");
+ }
+ int pfdID = WGL.GetPixelFormat(hdc);
+ if (pfdID == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat");
+ }
+
+ AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault();
+ WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(hdc, pfdID, glp, aScreen, true, true);
+
+ NullWindow nw = new NullWindow(cfg);
+ nw.setSurfaceHandle(hdc);
+
+ cfg.updateGraphicsConfiguration(factory, nw);
+
+ return new WindowsExternalWGLDrawable(factory, nw);
+ }
+
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsWGLContext(this, shareWith);
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java
new file mode 100644
index 000000000..25d93b50e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsOffscreenWGLContext extends WindowsWGLContext {
+ public WindowsOffscreenWGLContext(WindowsOffscreenWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ return GL.GL_UNSIGNED_BYTE;
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ // On Windows these contexts are always single-buffered
+ return GL.GL_FRONT;
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ // We can take care of this in the DIB creation (see below)
+ return false;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java
new file mode 100644
index 000000000..bf466d455
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+
+public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable {
+ private long origbitmap;
+ private long hbitmap;
+
+ public WindowsOffscreenWGLDrawable(GLDrawableFactory factory, NativeWindow target) {
+ super(factory, target, true);
+ create();
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ create();
+ } else {
+ destroy();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsOffscreenWGLContext(this, shareWith);
+ }
+
+ private void create() {
+ NativeWindow nw = getNativeWindow();
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nw.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getRequestedCapabilities();
+ int width = getWidth();
+ int height = getHeight();
+ BITMAPINFO info = BITMAPINFO.create();
+ BITMAPINFOHEADER header = info.getBmiHeader();
+ int bitsPerPixel = (capabilities.getRedBits() +
+ capabilities.getGreenBits() +
+ capabilities.getBlueBits() +
+ capabilities.getAlphaBits());
+ header.setBiSize(header.size());
+ header.setBiWidth(width);
+ // NOTE: negating the height causes the DIB to be in top-down row
+ // order rather than bottom-up; ends up being correct during pixel
+ // readback
+ header.setBiHeight(-1 * height);
+ header.setBiPlanes((short) 1);
+ header.setBiBitCount((short) bitsPerPixel);
+ header.setBiXPelsPerMeter(0);
+ header.setBiYPelsPerMeter(0);
+ header.setBiClrUsed(0);
+ header.setBiClrImportant(0);
+ header.setBiCompression(WGL.BI_RGB);
+ header.setBiSizeImage(width * height * bitsPerPixel / 8);
+
+ long hdc = WGL.CreateCompatibleDC(0);
+ if (hdc == 0) {
+ System.out.println("LastError: " + WGL.GetLastError());
+ throw new GLException("Error creating device context for offscreen OpenGL context");
+ }
+ ((SurfaceChangeable)nw).setSurfaceHandle(hdc);
+
+ hbitmap = WGL.CreateDIBSection(hdc, info, WGL.DIB_RGB_COLORS, null, 0, 0);
+ if (hbitmap == 0) {
+ WGL.DeleteDC(hdc);
+ hdc = 0;
+ throw new GLException("Error creating offscreen bitmap of width " + width +
+ ", height " + height);
+ }
+ if ((origbitmap = WGL.SelectObject(hdc, hbitmap)) == 0) {
+ WGL.DeleteObject(hbitmap);
+ hbitmap = 0;
+ WGL.DeleteDC(hdc);
+ hdc = 0;
+ throw new GLException("Error selecting bitmap into new device context");
+ }
+
+ config.updateGraphicsConfiguration(getFactory(), nw);
+ }
+
+ public void destroy() {
+ NativeWindow nw = getNativeWindow();
+ if (nw.getSurfaceHandle() != 0) {
+ // Must destroy bitmap and device context
+ WGL.SelectObject(nw.getSurfaceHandle(), origbitmap);
+ WGL.DeleteObject(hbitmap);
+ WGL.DeleteDC(nw.getSurfaceHandle());
+ origbitmap = 0;
+ hbitmap = 0;
+ ((SurfaceChangeable)nw).setSurfaceHandle(0);
+ }
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java
new file mode 100644
index 000000000..aeb13110e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import java.util.*;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsOnscreenWGLContext extends WindowsWGLContext {
+ protected WindowsOnscreenWGLDrawable drawable;
+
+ public WindowsOnscreenWGLContext(WindowsOnscreenWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected int makeCurrentImpl() throws GLException {
+ int lockRes = drawable.lockSurface();
+ boolean exceptionOccurred = false;
+ try {
+ if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ int ret = super.makeCurrentImpl();
+ return ret;
+ } catch (RuntimeException e) {
+ exceptionOccurred = true;
+ throw e;
+ } finally {
+ if (exceptionOccurred ||
+ (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY) && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected void releaseImpl() throws GLException {
+ try {
+ super.releaseImpl();
+ } finally {
+ if (!isOptimizable() && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java
new file mode 100644
index 000000000..401b8c3c6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsOnscreenWGLDrawable extends WindowsWGLDrawable {
+ protected WindowsOnscreenWGLDrawable(GLDrawableFactory factory, NativeWindow component) {
+ super(factory, component, false);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsOnscreenWGLContext(this, shareWith);
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java
new file mode 100644
index 000000000..a9e02e11f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsPbufferWGLContext extends WindowsWGLContext {
+ private static final boolean DEBUG = Debug.debug("WindowsPbufferWGLContext");
+
+ // State for render-to-texture and render-to-texture-rectangle support
+ private WindowsPbufferWGLDrawable drawable;
+ private boolean rtt; // render-to-texture?
+ private boolean hasRTT; // render-to-texture extension available?
+ private boolean rect; // render-to-texture-rectangle?
+ private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
+ private int texture; // actual texture object
+
+ public WindowsPbufferWGLContext(WindowsPbufferWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ public void bindPbufferToTexture() {
+ if (!rtt) {
+ throw new GLException("Shouldn't try to bind a pbuffer to a texture if render-to-texture hasn't been " +
+ "specified in its GLCapabilities");
+ }
+ GL gl = getGL();
+ WGLExt wglExt = getWGLExt();
+ gl.glBindTexture(textureTarget, texture);
+ if (rtt && hasRTT) {
+ if (!wglExt.wglBindTexImageARB(drawable.getPbuffer(), WGLExt.WGL_FRONT_LEFT_ARB)) {
+ throw new GLException("Binding of pbuffer to texture failed: " + wglGetLastError());
+ }
+ }
+ // FIXME: comment is wrong now
+ // Note that if the render-to-texture extension is not supported,
+ // we perform a glCopyTexImage2D in swapBuffers().
+ }
+
+ public void releasePbufferFromTexture() {
+ if (!rtt) {
+ throw new GLException("Shouldn't try to bind a pbuffer to a texture if render-to-texture hasn't been " +
+ "specified in its GLCapabilities");
+ }
+ if (rtt && hasRTT) {
+ WGLExt wglExt = getWGLExt();
+ if (!wglExt.wglReleaseTexImageARB(drawable.getPbuffer(), WGLExt.WGL_FRONT_LEFT_ARB)) {
+ throw new GLException("Releasing of pbuffer from texture failed: " + wglGetLastError());
+ }
+ }
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ int res = super.makeCurrentImpl();
+ if (DEBUG && VERBOSE) {
+ System.err.println("WindowsPbufferWGLContext: super.makeCurrentImpl() = " + res);
+ }
+ if (res == CONTEXT_CURRENT_NEW) {
+ GLCapabilities capabilities = drawable.getChosenGLCapabilities();
+
+ // Initialize render-to-texture support if requested
+ GL gl = getGL();
+ rtt = capabilities.getPbufferRenderToTexture();
+ rect = gl.isGL2GL3() && capabilities.getPbufferRenderToTextureRectangle();
+
+ if (rtt) {
+ if (DEBUG) {
+ System.err.println("Initializing render-to-texture support");
+ }
+
+ if (!gl.isExtensionAvailable("WGL_ARB_render_texture")) {
+ System.err.println("WindowsPbufferWGLContext: WARNING: WGL_ARB_render_texture extension not " +
+ "supported; implementing render_to_texture support using slow texture readback");
+ } else {
+ hasRTT = true;
+
+ if (rect && !gl.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ System.err.println("WindowsPbufferWGLContext: WARNING: GL_NV_texture_rectangle extension not " +
+ "supported; skipping requested render_to_texture_rectangle support for pbuffer");
+ rect = false;
+ }
+ if (rect) {
+ if (DEBUG) {
+ System.err.println(" Using render-to-texture-rectangle");
+ }
+ textureTarget = GL2.GL_TEXTURE_RECTANGLE_ARB;
+ } else {
+ if (DEBUG) {
+ System.err.println(" Using vanilla render-to-texture");
+ }
+ textureTarget = GL.GL_TEXTURE_2D;
+ }
+ int[] tmp = new int[1];
+ gl.glGenTextures(1, tmp, 0);
+ texture = tmp[0];
+ gl.glBindTexture(textureTarget, texture);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
+ gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, drawable.getWidth(), drawable.getHeight(), 0);
+ }
+ }
+ }
+ return res;
+ }
+
+ public int getFloatingPointMode() {
+ return drawable.getFloatingPointMode();
+ }
+
+ private static String wglGetLastError() {
+ return WindowsWGLDrawableFactory.wglGetLastError();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java
new file mode 100644
index 000000000..c7034e93b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
+ private long cachedParentHdc;
+ private WGLExt cachedWGLExt; // cached WGLExt instance from parent GLCanvas,
+ // needed to destroy pbuffer
+ private long buffer; // pbuffer handle
+
+ private int floatMode;
+
+ public WindowsPbufferWGLDrawable(GLDrawableFactory factory, NativeWindow target,
+ WindowsWGLDrawable dummyDrawable,
+ WGLExt wglExt) {
+ super(factory, target, true);
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration());
+ }
+
+ createPbuffer(dummyDrawable.getNativeWindow().getSurfaceHandle(), wglExt);
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + this);
+ }
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ throw new GLException("Recreation via setRealized not supported.");
+ } else {
+ destroy();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsPbufferWGLContext(this, shareWith);
+ }
+
+ public void destroy() {
+ NativeWindow nw = getNativeWindow();
+ if(0!=buffer) {
+ WGLExt wglExt = cachedWGLExt;
+ if (nw.getSurfaceHandle() != 0) {
+ // Must release DC and pbuffer
+ // NOTE that since the context is not current, glGetError() can
+ // not be called here, so we skip the use of any composable
+ // pipelines (see WindowsOnscreenWGLContext.makeCurrentImpl)
+ if (wglExt.wglReleasePbufferDCARB(buffer, nw.getSurfaceHandle()) == 0) {
+ throw new GLException("Error releasing pbuffer device context: error code " + WGL.GetLastError());
+ }
+ ((SurfaceChangeable)nw).setSurfaceHandle(0);
+ }
+ if (!wglExt.wglDestroyPbufferARB(buffer)) {
+ throw new GLException("Error destroying pbuffer: error code " + WGL.GetLastError());
+ }
+ buffer = 0;
+ }
+ }
+
+ public long getPbuffer() {
+ return buffer;
+ }
+
+ public int getFloatingPointMode() {
+ return floatMode;
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+
+ private void createPbuffer(long parentHdc, WGLExt wglExt) {
+ int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
+ float[] fattributes = new float[1];
+ int[] floatModeTmp = new int[1];
+ int niattribs = 0;
+ int width, height;
+
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getRequestedCapabilities();
+ GLProfile glProfile = capabilities.getGLProfile();
+
+ if (DEBUG) {
+ System.out.println("Pbuffer parentHdc = " + toHexString(parentHdc));
+ System.out.println("Pbuffer caps: " + capabilities);
+ }
+
+ if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
+ iattributes,
+ wglExt,
+ true,
+ floatModeTmp)){
+ throw new GLException("Pbuffer-related extensions not supported");
+ }
+
+ floatMode = floatModeTmp[0];
+ boolean rtt = capabilities.getPbufferRenderToTexture();
+ boolean rect = capabilities.getPbufferRenderToTextureRectangle();
+ boolean useFloat = capabilities.getPbufferFloatingPointBuffers();
+ boolean ati = false;
+
+ if (useFloat) {
+ ati = (floatMode == GLPbuffer.ATI_FLOAT);
+ }
+
+ int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
+ int nformats;
+ int[] nformatsTmp = new int[1];
+ if (!wglExt.wglChoosePixelFormatARB(parentHdc,
+ iattributes, 0,
+ fattributes, 0,
+ WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+ pformats, 0,
+ nformatsTmp, 0)) {
+ throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed");
+ }
+ nformats = nformatsTmp[0];
+ if (nformats <= 0) {
+ throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
+ }
+
+ boolean haveMultisample = wglExt.isExtensionAvailable("WGL_ARB_multisample");
+
+ if (DEBUG) {
+ System.err.println("" + nformats + " suitable pixel formats found");
+ // query pixel format
+ iattributes[0] = WGLExt.WGL_RED_BITS_ARB;
+ iattributes[1] = WGLExt.WGL_GREEN_BITS_ARB;
+ iattributes[2] = WGLExt.WGL_BLUE_BITS_ARB;
+ iattributes[3] = WGLExt.WGL_ALPHA_BITS_ARB;
+ iattributes[4] = WGLExt.WGL_DEPTH_BITS_ARB;
+ iattributes[5] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[6] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[7] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[8] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ int[] ivalues = new int[9];
+ for (int i = 0; i < nformats; i++) {
+ if (!wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[i], 0, 9, iattributes, 0, ivalues, 0)) {
+ throw new GLException("Error while querying pixel format " + pformats[i] +
+ "'s (index " + i + "'s) capabilities for debugging");
+ }
+ System.err.print("pixel format " + pformats[i] + " (index " + i + "): ");
+ System.err.print( "r: " + ivalues[0]);
+ System.err.print(" g: " + ivalues[1]);
+ System.err.print(" b: " + ivalues[2]);
+ System.err.print(" a: " + ivalues[3]);
+ System.err.print(" depth: " + ivalues[4]);
+ if (haveMultisample) {
+ System.err.print(" multisample: " + ivalues[6]);
+ }
+ System.err.print(" samples: " + ivalues[7]);
+ if (useFloat) {
+ if (ati) {
+ if (ivalues[5] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) {
+ System.err.print(" [ati float]");
+ } else if (ivalues[5] != WGLExt.WGL_TYPE_RGBA_ARB) {
+ System.err.print(" [unknown pixel type " + ivalues[5] + "]");
+ }
+ } else {
+ if (ivalues[5] != 0) {
+ System.err.print(" [float]");
+ }
+ }
+ }
+
+ if (ivalues[8] != 0) {
+ System.err.print(" [pbuffer]");
+ }
+ System.err.println();
+ }
+ }
+
+ long tmpBuffer = 0;
+ int whichFormat = -1;
+ // Loop is a workaround for bugs in NVidia's recent drivers
+ for (whichFormat = 0; whichFormat < nformats; whichFormat++) {
+ int format = pformats[whichFormat];
+
+ // Create the p-buffer.
+ niattribs = 0;
+
+ if (rtt) {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB;
+ if (useFloat) {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV;
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB;
+ iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB;
+
+ iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+
+ iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = 0;
+
+ tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0);
+ if (tmpBuffer != 0) {
+ // Done
+ break;
+ }
+ }
+
+ if (tmpBuffer == 0) {
+ throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats +
+ " pixel formats, last error was: " + wglGetLastError());
+ }
+
+ // Get the device context.
+ long tmpHdc = wglExt.wglGetPbufferDCARB(tmpBuffer);
+ if (tmpHdc == 0) {
+ throw new GLException("pbuffer creation error: wglGetPbufferDC() failed");
+ }
+
+ NativeWindow nw = getNativeWindow();
+ // Set up instance variables
+ buffer = tmpBuffer;
+ ((SurfaceChangeable)nw).setSurfaceHandle(tmpHdc);
+ cachedWGLExt = wglExt;
+ cachedParentHdc = parentHdc;
+
+ // Re-query chosen pixel format
+ {
+ niattribs = 0;
+ iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB);
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ int[] ivalues = new int[niattribs];
+ if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) {
+ GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, true, false, true);
+ PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
+ if (WGL.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) {
+ if (DEBUG) {
+ System.err.println("Unable to describe pixel format (Continue: true) " + whichFormat + "/" + nformats + " pfdID " + pformats[whichFormat]+":\n\t"+newCaps);
+ }
+ }
+ if(newCaps.isOnscreen()) {
+ throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps+"\n\t"+newCaps);
+ }
+ config.setCapsPFD(newCaps, pfd, pformats[whichFormat], true);
+ } else {
+ PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
+ if (WGL.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) {
+ throw new GLException("Unable to describe pixel format " + pformats[whichFormat]);
+ }
+ GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, false, true);
+ if(newCaps.isOnscreen()) {
+ throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps+"\n\t"+newCaps);
+ }
+ config.setCapsPFD(newCaps, pfd, pformats[whichFormat], false);
+ }
+ }
+
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_WIDTH_ARB, tmp, 0 );
+ width = tmp[0];
+ wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 );
+ height = tmp[0];
+ ((SurfaceChangeable)nw).setSize(width, height);
+ }
+
+ private static String wglGetLastError() {
+ return WindowsWGLDrawableFactory.wglGetLastError();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java
new file mode 100644
index 000000000..0f1f9813f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+
+public class WindowsWGLContext extends GLContextImpl {
+ protected long hglrc;
+ private boolean wglGetExtensionsStringEXTInitialized;
+ private boolean wglGetExtensionsStringEXTAvailable;
+ private boolean wglMakeContextCurrentInitialized;
+ private boolean wglMakeContextCurrentARBAvailable;
+ private boolean wglMakeContextCurrentEXTAvailable;
+ private static final Map/*<String, String>*/ functionNameMap;
+ private static final Map/*<String, String>*/ extensionNameMap;
+ private WGLExt wglExt;
+ // Table that holds the addresses of the native C-language entry points for
+ // WGL extension functions.
+ private WGLExtProcAddressTable wglExtProcAddressTable;
+
+ static {
+ functionNameMap = new HashMap();
+ functionNameMap.put("glAllocateMemoryNV", "wglAllocateMemoryNV");
+ functionNameMap.put("glFreeMemoryNV", "wglFreeMemoryNV");
+
+ extensionNameMap = new HashMap();
+ extensionNameMap.put("GL_ARB_pbuffer", "WGL_ARB_pbuffer");
+ extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format");
+ }
+
+ // FIXME: figure out how to hook back in the Java 2D / JOGL bridge
+ public WindowsWGLContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead,
+ GLContext shareWith) {
+ super(drawable, drawableRead, shareWith);
+ }
+
+ public WindowsWGLContext(GLDrawableImpl drawable,
+ GLContext shareWith) {
+ this(drawable, null, shareWith);
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getWGLExt();
+ }
+
+ public WGLExt getWGLExt() {
+ if (wglExt == null) {
+ wglExt = new WGLExtImpl(this);
+ }
+ return wglExt;
+ }
+
+ public boolean wglMakeContextCurrent(long hDrawDC, long hReadDC, long hglrc) {
+ WGLExt wglExt = getWGLExt();
+ if (!wglMakeContextCurrentInitialized) {
+ wglMakeContextCurrentARBAvailable = isFunctionAvailable("wglMakeContextCurrentARB");
+ wglMakeContextCurrentEXTAvailable = isFunctionAvailable("wglMakeContextCurrentEXT");
+ wglMakeContextCurrentInitialized = true;
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.wglMakeContextCurrent: ARB "+wglMakeContextCurrentARBAvailable+", EXT "+wglMakeContextCurrentEXTAvailable);
+ }
+ }
+ if(wglMakeContextCurrentARBAvailable) {
+ return wglExt.wglMakeContextCurrentARB(hDrawDC, hReadDC, hglrc);
+ } else if(wglMakeContextCurrentEXTAvailable) {
+ return wglExt.wglMakeContextCurrentEXT(hDrawDC, hReadDC, hglrc);
+ }
+ return WGL.wglMakeCurrent(hDrawDC, hglrc);
+ }
+
+ public final ProcAddressTable getPlatformExtProcAddressTable() {
+ return getWGLExtProcAddressTable();
+ }
+
+ public final WGLExtProcAddressTable getWGLExtProcAddressTable() {
+ return wglExtProcAddressTable;
+ }
+
+ protected Map/*<String, String>*/ getFunctionNameMap() { return functionNameMap; }
+
+ protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; }
+
+ protected void destroyContextARBImpl(long context) {
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(context);
+ }
+
+ protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) {
+ WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
+ WGLExt wglExt;
+ if(null==factory.getSharedContext()) {
+ wglExt = getWGLExt();
+ } else {
+ wglExt = ((WindowsWGLContext)factory.getSharedContext()).getWGLExt();
+ }
+
+ boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
+ boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
+ boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
+
+ long _context=0;
+
+ int attribs[] = {
+ /* 0 */ WGLExt.WGL_CONTEXT_MAJOR_VERSION_ARB, major,
+ /* 2 */ WGLExt.WGL_CONTEXT_MINOR_VERSION_ARB, minor,
+ /* 4 */ WGLExt.WGL_CONTEXT_LAYER_PLANE_ARB, WGLExt.WGL_CONTEXT_LAYER_PLANE_ARB, // default
+ /* 6 */ WGLExt.WGL_CONTEXT_FLAGS_ARB, 0,
+ /* 8 */ 0, 0,
+ /* 10 */ 0
+ };
+
+ if ( major > 3 || major == 3 && minor >= 2 ) {
+ // FIXME: Verify with a None drawable binding (default framebuffer)
+ attribs[8+0] = WGLExt.WGL_CONTEXT_PROFILE_MASK_ARB;
+ if( ctBwdCompat ) {
+ attribs[8+1] = WGLExt.WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ } else {
+ attribs[8+1] = WGLExt.WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+ }
+ }
+
+ if ( major >= 3 ) {
+ if( !ctBwdCompat && ctFwdCompat ) {
+ attribs[6+1] |= WGLExt.WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+ }
+ if( ctDebug) {
+ attribs[6+1] |= WGLExt.WGL_CONTEXT_DEBUG_BIT_ARB;
+ }
+ }
+
+ _context = wglExt.wglCreateContextAttribsARB(drawable.getNativeWindow().getSurfaceHandle(), share, attribs, 0);
+ if(0==_context) {
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.createContextARB couldn't create "+getGLVersion(null, major, minor, ctp, "@creation"));
+ }
+ } else {
+ // In contrast to GLX no verification with a drawable binding, ie default framebuffer, is necessary,
+ // if no 3.2 is available creation fails already!
+ // Nevertheless .. we do it ..
+ if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), _context)) {
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.createContextARB couldn't make current "+getGLVersion(null, major, minor, ctp, "@creation"));
+ }
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(_context);
+ _context = 0;
+ }
+ }
+ return _context;
+ }
+
+ /**
+ * Creates and initializes an appropriate OpenGL context. Should only be
+ * called by {@link #makeCurrentImpl()}.
+ */
+ protected void create() {
+ if(0!=context) {
+ throw new GLException("context is not null: "+context);
+ }
+ WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
+ GLCapabilities glCaps = drawable.getChosenGLCapabilities();
+
+ if (drawable.getNativeWindow().getSurfaceHandle() == 0) {
+ throw new GLException("Internal error: attempted to create OpenGL context without an associated drawable");
+ }
+ // Windows can set up sharing of display lists after creation time
+ WindowsWGLContext other = (WindowsWGLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getHGLRC();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+
+ int minor[] = new int[1];
+ int major[] = new int[1];
+ int ctp[] = new int[1];
+ boolean createContextARBTried = false;
+
+ // utilize the shared context's GLXExt in case it was using the ARB method and it already exists
+ if(null!=factory.getSharedContext() && factory.getSharedContext().isCreatedWithARBMethod()) {
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.createContext using shared Context: "+factory.getSharedContext());
+ }
+ hglrc = createContextARB(share, true, major, minor, ctp);
+ createContextARBTried = true;
+ }
+
+ long temp_hglrc = 0;
+ if(0==hglrc) {
+ // To use WGL_ARB_create_context, we have to make a temp context current,
+ // so we are able to use GetProcAddress
+ temp_hglrc = WGL.wglCreateContext(drawable.getNativeWindow().getSurfaceHandle());
+ if (temp_hglrc == 0) {
+ throw new GLException("Unable to create temp OpenGL context for device context " + toHexString(drawable.getNativeWindow().getSurfaceHandle()));
+ }
+ if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), temp_hglrc)) {
+ throw new GLException("Error making temp context current: 0x" + Integer.toHexString(WGL.GetLastError()));
+ }
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+
+ if( createContextARBTried ||
+ !isFunctionAvailable("wglCreateContextAttribsARB") ||
+ !isExtensionAvailable("WGL_ARB_create_context") ) {
+ if(glCaps.getGLProfile().isGL3()) {
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(temp_hglrc);
+ throw new GLException("Unable to create OpenGL >= 3.1 context (no WGL_ARB_create_context)");
+ }
+
+ // continue with temp context for GL < 3.0
+ hglrc = temp_hglrc;
+ return;
+ }
+ hglrc = createContextARB(share, true, major, minor, ctp);
+ createContextARBTried=true;
+ }
+
+ if(0!=hglrc) {
+ share = 0; // mark as shared ..
+
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(temp_hglrc);
+
+ if (!wglMakeContextCurrent(drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), hglrc)) {
+ throw new GLException("Cannot make previous verified context current: 0x" + Integer.toHexString(WGL.GetLastError()));
+ }
+ } else {
+ if(glCaps.getGLProfile().isGL3()) {
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(temp_hglrc);
+ throw new GLException("WindowsWGLContext.createContext failed, but context > GL2 requested "+getGLVersion(null, major[0], minor[0], ctp[0], "@creation")+", ");
+ }
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.createContext failed, fall back to !ARB context "+getGLVersion(null, major[0], minor[0], ctp[0], "@creation"));
+ }
+
+ // continue with temp context for GL < 3.0
+ hglrc = temp_hglrc;
+ if (!wglMakeContextCurrent(drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), hglrc)) {
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(hglrc);
+ throw new GLException("Error making old context current: 0x" + Integer.toHexString(WGL.GetLastError()));
+ }
+ }
+
+ if(0!=share) {
+ if (!WGL.wglShareLists(share, hglrc)) {
+ throw new GLException("wglShareLists(" + toHexString(share) +
+ ", " + toHexString(hglrc) + ") failed: error code 0x" +
+ Integer.toHexString(WGL.GetLastError()));
+ }
+ }
+ GLContextShareSet.contextCreated(this);
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (drawable.getNativeWindow().getSurfaceHandle() == 0) {
+ throw new GLException("drawable not properly initialized: "+drawable);
+ }
+ boolean created = false;
+ if (hglrc == 0) {
+ create();
+ created = true;
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName());
+ }
+ }
+
+ if (WGL.wglGetCurrentContext() != hglrc) {
+ if (!wglMakeContextCurrent(drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), hglrc)) {
+ throw new GLException("Error making context current: 0x" + Integer.toHexString(WGL.GetLastError()) + ", " + this);
+ } else {
+ if (DEBUG && VERBOSE) {
+ System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) +
+ ", hglrc " + toHexString(hglrc) + ") succeeded");
+ }
+ }
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+
+ WindowsWGLGraphicsConfiguration config =
+ (WindowsWGLGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ config.updateCapabilitiesByWGL(this);
+
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ if (!wglMakeContextCurrent(0, 0, 0)) {
+ throw new GLException("Error freeing OpenGL context: 0x" + Integer.toHexString(WGL.GetLastError()));
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ if (DEBUG) {
+ Exception e = new Exception(getThreadName() + ": !!! Destroyed OpenGL context " + toHexString(hglrc));
+ e.printStackTrace();
+ }
+ if (hglrc != 0) {
+ if (!WGL.wglDeleteContext(hglrc)) {
+ throw new GLException("Unable to delete OpenGL context");
+ }
+ hglrc = 0;
+ GLContextShareSet.contextDestroyed(this);
+ }
+ }
+
+ public boolean isCreated() {
+ return (hglrc != 0);
+ }
+
+ public void copy(GLContext source, int mask) throws GLException {
+ long dst = getHGLRC();
+ long src = ((WindowsWGLContext) source).getHGLRC();
+ if (src == 0) {
+ throw new GLException("Source OpenGL context has not been created");
+ }
+ if (dst == 0) {
+ throw new GLException("Destination OpenGL context has not been created");
+ }
+ if (!WGL.wglCopyContext(src, dst, mask)) {
+ throw new GLException("wglCopyContext failed");
+ }
+ }
+
+ protected void updateGLProcAddressTable(int major, int minor, int ctp) {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing WGL extension address table for " + this);
+ }
+ wglGetExtensionsStringEXTInitialized=false;
+ wglGetExtensionsStringEXTAvailable=false;
+ wglMakeContextCurrentInitialized=false;
+ wglMakeContextCurrentARBAvailable=false;
+ wglMakeContextCurrentEXTAvailable=false;
+
+ if (wglExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ wglExtProcAddressTable = new WGLExtProcAddressTable();
+ }
+ resetProcAddressTable(getWGLExtProcAddressTable());
+ super.updateGLProcAddressTable(major, minor, ctp);
+ }
+
+ public String getPlatformExtensionsString() {
+ if (!wglGetExtensionsStringEXTInitialized) {
+ wglGetExtensionsStringEXTAvailable = (WGL.wglGetProcAddress("wglGetExtensionsStringEXT") != 0);
+ wglGetExtensionsStringEXTInitialized = true;
+ }
+ if (wglGetExtensionsStringEXTAvailable) {
+ return getWGLExt().wglGetExtensionsStringEXT();
+ } else {
+ return "";
+ }
+ }
+
+ protected void setSwapIntervalImpl(int interval) {
+ WGLExt wglExt = getWGLExt();
+ if (wglExt.isExtensionAvailable("WGL_EXT_swap_control")) {
+ if ( wglExt.wglSwapIntervalEXT(interval) ) {
+ currentSwapInterval = interval ;
+ }
+ }
+ }
+
+ public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+ return getWGLExt().wglAllocateMemoryNV(arg0, arg1, arg2, arg3);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ public long getHGLRC() {
+ return hglrc;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java
new file mode 100644
index 000000000..43c1ff5e0
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import com.jogamp.common.os.DynamicLookupHelper;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public abstract class WindowsWGLDrawable extends GLDrawableImpl {
+ private static final int MAX_SET_PIXEL_FORMAT_FAIL_COUNT = 5;
+ private static final boolean PROFILING = Debug.debug("WindowsWGLDrawable.profiling");
+ private static final int PROFILING_TICKS = 200;
+ private int profilingLockSurfaceTicks;
+ private long profilingLockSurfaceTime;
+ private int profilingUnlockSurfaceTicks;
+ private long profilingUnlockSurfaceTime;
+ private int profilingSwapBuffersTicks;
+ private long profilingSwapBuffersTime;
+
+
+ public WindowsWGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) {
+ super(factory, comp, realized);
+ }
+
+ protected void setRealizedImpl() {
+ if(!realized) {
+ return; // nothing todo ..
+ }
+
+ if(NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface()) {
+ throw new GLException("WindowsWGLDrawable.setRealized(true): lockSurface - surface not ready");
+ }
+ try {
+ NativeWindow nativeWindow = getNativeWindow();
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nativeWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ config.updateGraphicsConfiguration(getFactory(), nativeWindow);
+ if (DEBUG) {
+ System.err.println("!!! WindowsWGLDrawable.setRealized(true): "+config);
+ }
+ } finally {
+ unlockSurface();
+ }
+ }
+
+ protected void swapBuffersImpl() {
+ boolean didLock = false;
+
+ if ( !isSurfaceLocked() ) {
+ // Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return;
+ }
+ didLock = true;
+ }
+ try {
+
+ long startTime = 0;
+ if (PROFILING) {
+ startTime = System.currentTimeMillis();
+ }
+
+ if (!WGL.SwapBuffers(getNativeWindow().getSurfaceHandle()) && (WGL.GetLastError() != 0)) {
+ throw new GLException("Error swapping buffers");
+ }
+
+ if (PROFILING) {
+ long endTime = System.currentTimeMillis();
+ profilingSwapBuffersTime += (endTime - startTime);
+ int ticks = PROFILING_TICKS;
+ if (++profilingSwapBuffersTicks == ticks) {
+ System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + ticks + " calls (" +
+ ((float) profilingSwapBuffersTime / (float) ticks) + " ms/call)");
+ profilingSwapBuffersTime = 0;
+ profilingSwapBuffersTicks = 0;
+ }
+ }
+ } finally {
+ if (didLock) {
+ unlockSurface();
+ }
+ }
+ }
+
+ public DynamicLookupHelper getDynamicLookupHelper() {
+ return (WindowsWGLDrawableFactory) getFactoryImpl() ;
+ }
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
new file mode 100644
index 000000000..a4bf89b81
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import com.jogamp.common.os.DynamicLookupHelper;
+import java.nio.*;
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.windows.*;
+import javax.media.opengl.*;
+import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.util.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+
+public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl implements DynamicLookupHelper {
+ private static final boolean VERBOSE = Debug.verbose();
+
+ // Handle to GLU32.dll
+ // FIXME: this should go away once we delete support for the C GLU library
+ private long hglu32;
+
+ // Handle to core OpenGL32.dll
+ private long hopengl32;
+
+ public WindowsWGLDrawableFactory() {
+ super();
+
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ new WindowsWGLGraphicsConfigurationFactory();
+ try {
+ ReflectionUtil.createInstance("com.jogamp.opengl.impl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory",
+ new Object[] {});
+ } catch (JogampRuntimeException jre) { /* n/a .. */ }
+
+ loadOpenGL32Library();
+
+ sharedDrawable = new WindowsDummyWGLDrawable(this, null);
+ WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null);
+ ctx.makeCurrent();
+ canCreateGLPbuffer = ctx.getGL().isExtensionAvailable("GL_ARB_pbuffer");
+ ctx.release();
+ sharedContext = ctx;
+ if(null==sharedContext) {
+ throw new GLException("Couldn't init shared resources");
+ }
+ if (DEBUG) {
+ System.err.println("!!! SharedContext: "+sharedContext+", pbuffer supported "+canCreateGLPbuffer);
+ }
+ }
+
+ WindowsDummyWGLDrawable sharedDrawable=null;
+ WindowsWGLContext sharedContext=null;
+ boolean canCreateGLPbuffer = false;
+
+ protected final GLDrawableImpl getSharedDrawable() {
+ validate();
+ return sharedDrawable;
+ }
+
+ protected final GLContextImpl getSharedContext() {
+ validate();
+ return sharedContext;
+ }
+
+ public void shutdown() {
+ super.shutdown();
+ if (DEBUG) {
+ System.err.println("!!! Shutdown Shared:");
+ System.err.println("!!! CTX : "+sharedContext);
+ System.err.println("!!! Drawable: "+sharedDrawable);
+ Exception e = new Exception("Debug");
+ e.printStackTrace();
+ }
+ if(null!=sharedContext) {
+ sharedContext.destroy(); // implies release, if current
+ }
+ if(null!=sharedDrawable) {
+ sharedDrawable.destroy();
+ }
+ }
+
+ public GLDrawableImpl createOnscreenDrawable(NativeWindow target) {
+ validate();
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ return new WindowsOnscreenWGLDrawable(this, target);
+ }
+
+ protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) {
+ validate();
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ return new WindowsOffscreenWGLDrawable(this, target);
+ }
+
+ public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+ validate();
+ return canCreateGLPbuffer;
+ }
+
+ protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeWindow target) {
+ validate();
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ final List returnList = new ArrayList();
+ final GLDrawableFactory factory = this;
+ final WindowsWGLContext _sharedContext = sharedContext;
+ final WindowsDummyWGLDrawable _sharedDrawable = sharedDrawable;
+ Runnable r = new Runnable() {
+ public void run() {
+ GLContext lastContext = GLContext.getCurrent();
+ if (lastContext != null) {
+ lastContext.release();
+ }
+ _sharedContext.makeCurrent();
+ WGLExt wglExt = _sharedContext.getWGLExt();
+ try {
+ GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(factory, target,
+ _sharedDrawable,
+ wglExt);
+ returnList.add(pbufferDrawable);
+ } finally {
+ _sharedContext.release();
+ if (lastContext != null) {
+ lastContext.makeCurrent();
+ }
+ }
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ return (GLDrawableImpl) returnList.get(0);
+ }
+
+ protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
+ validate();
+ AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault();
+ NullWindow nw = new NullWindow(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+ capabilities, chooser, screen) );
+ nw.setSize(width, height);
+ return nw;
+ }
+
+ public GLContext createExternalGLContext() {
+ validate();
+ return WindowsExternalWGLContext.create(this, null);
+ }
+
+ public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) {
+ validate();
+ return true;
+ }
+
+ public GLDrawable createExternalGLDrawable() {
+ validate();
+ return WindowsExternalWGLDrawable.create(this, null);
+ }
+
+ public void loadOpenGL32Library() {
+ validate();
+ if (hopengl32 == 0) {
+ hopengl32 = WGL.LoadLibraryA("OpenGL32");
+ if (DEBUG) {
+ if (hopengl32 == 0) {
+ System.err.println("WindowsWGLDrawableFactory: Could not load OpenGL32.dll - maybe an embedded device");
+ }
+ }
+ }
+ }
+
+ public void loadGLULibrary() {
+ validate();
+ if (hglu32 == 0) {
+ hglu32 = WGL.LoadLibraryA("GLU32");
+ if (hglu32 == 0) {
+ throw new GLException("Error loading GLU32.DLL");
+ }
+ }
+ }
+
+ public long dynamicLookupFunction(String glFuncName) {
+ validate();
+ long res = WGL.wglGetProcAddress(glFuncName);
+ if (res == 0) {
+ // It may happen that a driver doesn't return the OpenGL32 core function pointer
+ // with wglGetProcAddress (e.g. NVidia GL 3.1) - hence we have to look harder.
+ if (hopengl32 != 0) {
+ res = WGL.GetProcAddress(hopengl32, glFuncName);
+ }
+ }
+ if (res == 0) {
+ // GLU routines aren't known to the OpenGL function lookup
+ if (hglu32 != 0) {
+ res = WGL.GetProcAddress(hglu32, glFuncName);
+ }
+ }
+ return res;
+ }
+
+ static String wglGetLastError() {
+ long err = WGL.GetLastError();
+ String detail = null;
+ switch ((int) err) {
+ case WGL.ERROR_INVALID_PIXEL_FORMAT: detail = "ERROR_INVALID_PIXEL_FORMAT"; break;
+ case WGL.ERROR_NO_SYSTEM_RESOURCES: detail = "ERROR_NO_SYSTEM_RESOURCES"; break;
+ case WGL.ERROR_INVALID_DATA: detail = "ERROR_INVALID_DATA"; break;
+ case WGL.ERROR_PROC_NOT_FOUND: detail = "ERROR_PROC_NOT_FOUND"; break;
+ case WGL.ERROR_INVALID_WINDOW_HANDLE:detail = "ERROR_INVALID_WINDOW_HANDLE"; break;
+ default: detail = "(Unknown error code " + err + ")"; break;
+ }
+ return detail;
+ }
+
+ public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) {
+ validate();
+ return false;
+ }
+
+ public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ validate();
+ throw new GLException("Unimplemented on this platform");
+ }
+
+ //------------------------------------------------------
+ // Gamma-related functionality
+ //
+
+ private static final int GAMMA_RAMP_LENGTH = 256;
+
+ protected int getGammaRampLength() {
+ return GAMMA_RAMP_LENGTH;
+ }
+
+ protected boolean setGammaRamp(float[] ramp) {
+ short[] rampData = new short[3 * GAMMA_RAMP_LENGTH];
+ for (int i = 0; i < GAMMA_RAMP_LENGTH; i++) {
+ short scaledValue = (short) (ramp[i] * 65535);
+ rampData[i] = scaledValue;
+ rampData[i + GAMMA_RAMP_LENGTH] = scaledValue;
+ rampData[i + 2 * GAMMA_RAMP_LENGTH] = scaledValue;
+ }
+
+ long screenDC = WGL.GetDC(0);
+ boolean res = WGL.SetDeviceGammaRamp(screenDC, ShortBuffer.wrap(rampData));
+ WGL.ReleaseDC(0, screenDC);
+ return res;
+ }
+
+ protected Buffer getGammaRamp() {
+ ShortBuffer rampData = ShortBuffer.wrap(new short[3 * GAMMA_RAMP_LENGTH]);
+ long screenDC = WGL.GetDC(0);
+ boolean res = WGL.GetDeviceGammaRamp(screenDC, rampData);
+ WGL.ReleaseDC(0, screenDC);
+ if (!res) {
+ return null;
+ }
+ return rampData;
+ }
+
+ protected void resetGammaRamp(Buffer originalGammaRamp) {
+ if (originalGammaRamp == null) {
+ // getGammaRamp failed earlier
+ return;
+ }
+ long screenDC = WGL.GetDC(0);
+ WGL.SetDeviceGammaRamp(screenDC, originalGammaRamp);
+ WGL.ReleaseDC(0, screenDC);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
new file mode 100644
index 000000000..aed4012a4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -0,0 +1,641 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+ // Keep this under the same debug flag as the drawable factory for convenience
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ protected static final int MAX_PFORMATS = 256;
+ protected static final int MAX_ATTRIBS = 256;
+
+ private PIXELFORMATDESCRIPTOR pixelfmt;
+ private int pixelfmtID;
+ private boolean isChosen = false;
+ private GLCapabilitiesChooser chooser;
+ private boolean choosenByWGLPixelFormat=false;
+
+ public WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilities capsChosen, GLCapabilities capsRequested,
+ PIXELFORMATDESCRIPTOR pixelfmt, int pixelfmtID, GLCapabilitiesChooser chooser) {
+ super(screen, capsChosen, capsRequested);
+ this.chooser=chooser;
+ this.pixelfmt = pixelfmt;
+ this.pixelfmtID = pixelfmtID;
+ }
+
+ public static WindowsWGLGraphicsConfiguration create(long hdc, int pfdID,
+ GLProfile glp, AbstractGraphicsScreen screen, boolean onscreen, boolean usePBuffer)
+ {
+ if(pfdID<=0) {
+ throw new GLException("Invalid pixelformat id "+pfdID);
+ }
+ if(null==glp) {
+ glp = GLProfile.getDefault();
+ }
+ PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
+ if (WGL.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
+ throw new GLException("Unable to describe pixel format " + pfdID);
+ }
+
+ GLCapabilities caps = PFD2GLCapabilities(glp, pfd, onscreen, usePBuffer);
+ if(null==caps) {
+ throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID);
+ }
+ WindowsWGLGraphicsConfiguration cfg = new WindowsWGLGraphicsConfiguration(screen, caps, caps, pfd, pfdID, new DefaultGLCapabilitiesChooser());
+ cfg.setCapsPFD(caps, pfd, pfdID, false);
+
+ return cfg;
+ }
+
+ public Object clone() {
+ return super.clone();
+ }
+
+ /** Update config - before having a valid context */
+ protected void updateGraphicsConfiguration(GLDrawableFactory factory, NativeWindow nativeWindow) {
+ WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, nativeWindow);
+ }
+
+ /** Update config - after having a valid and current context */
+ protected void updateCapabilitiesByWGL(GLContextImpl context) {
+ if(choosenByWGLPixelFormat) return; // already done ..
+
+ GLCapabilities capabilities = (GLCapabilities) getRequestedCapabilities();
+ boolean onscreen = capabilities.isOnscreen();
+ boolean usePBuffer = capabilities.isPBuffer();
+ GLProfile glp = capabilities.getGLProfile();
+
+ WGLExt wglExt = (WGLExt) context.getPlatformGLExtensions();
+ GLDrawable drawable = context.getGLDrawable();
+ NativeWindow nativeWindow = drawable.getNativeWindow();
+ long hdc = nativeWindow.getSurfaceHandle();
+
+ GLCapabilities[] caps = HDC2GLCapabilities(wglExt, hdc, getPixelFormatID(), glp, true, onscreen, usePBuffer);
+ if(null!=caps && null!=caps[0]) {
+ setCapsPFD(caps[0], getPixelFormat(), getPixelFormatID(), true);
+ }
+ }
+
+ protected void setCapsPFD(GLCapabilities caps, PIXELFORMATDESCRIPTOR pfd, int pfdID, boolean choosenByWGLPixelFormat) {
+ this.pixelfmt = pfd;
+ this.pixelfmtID = pfdID;
+ setChosenCapabilities(caps);
+ this.isChosen=true;
+ this.choosenByWGLPixelFormat=choosenByWGLPixelFormat;
+ if (DEBUG) {
+ System.err.println("*** setCapsPFD: WGL-Choosen "+choosenByWGLPixelFormat+", pfdID "+pfdID+", "+caps);
+ }
+ }
+
+ public boolean getCapabilitiesChosen() {
+ return isChosen;
+ }
+
+ public PIXELFORMATDESCRIPTOR getPixelFormat() { return pixelfmt; }
+ public int getPixelFormatID() { return pixelfmtID; }
+ public boolean isChoosenByWGL() { return choosenByWGLPixelFormat; }
+
+ private static int haveWGLChoosePixelFormatARB = -1;
+ private static int haveWGLARBMultisample = -1;
+
+ public static GLCapabilities[] HDC2GLCapabilities(WGLExt wglExt, long hdc, int pfdIDOnly,
+ GLProfile glp, boolean relaxed, boolean onscreen, boolean usePBuffer) {
+
+ if(haveWGLChoosePixelFormatARB<0) {
+ haveWGLChoosePixelFormatARB = wglExt.isExtensionAvailable("WGL_ARB_pixel_format")?1:0;
+ }
+ if(haveWGLARBMultisample<0) {
+ haveWGLARBMultisample = wglExt.isExtensionAvailable("WGL_ARB_multisample")?1:0;
+ }
+ if (0==haveWGLChoosePixelFormatARB) {
+ return null;
+ }
+
+ // Produce a list of GLCapabilities to give to the
+ // GLCapabilitiesChooser.
+ // Use wglGetPixelFormatAttribivARB instead of
+ // DescribePixelFormat to get higher-precision information
+ // about the pixel format (should make the GLCapabilities
+ // more precise as well...i.e., remove the
+ // "HardwareAccelerated" bit, which is basically
+ // meaningless, and put in whether it can render to a
+ // window, to a pbuffer, or to a pixmap)
+ GLCapabilities[] availableCaps = null;
+ int numFormats = 0;
+ int niattribs = 0;
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ int[] iresults = new int [2*MAX_ATTRIBS];
+
+ iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB;
+ if (wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
+ numFormats = iresults[0];
+
+ if (DEBUG) {
+ System.err.println("wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats);
+ }
+
+ if(pfdIDOnly>0 && pfdIDOnly>numFormats) {
+ throw new GLException("Invalid pixelformat ID " + pfdIDOnly + " (should be between 1 and " + numFormats + ")");
+ }
+
+ // Should we be filtering out the pixel formats which aren't
+ // applicable, as we are doing here?
+ // We don't have enough information in the GLCapabilities to
+ // represent those that aren't...
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
+ if (1==haveWGLARBMultisample) {
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
+ }
+
+ if(pfdIDOnly>0) {
+ availableCaps = new GLCapabilities[1];
+ if (!wglExt.wglGetPixelFormatAttribivARB(hdc, pfdIDOnly, 0, niattribs, iattributes, 0, iresults, 0)) {
+ throw new GLException("Error getting pixel format attributes for pixel format " + pfdIDOnly + " of device context");
+ }
+ availableCaps[0] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults,
+ relaxed, onscreen, usePBuffer);
+ } else {
+ availableCaps = new GLCapabilities[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ if (!wglExt.wglGetPixelFormatAttribivARB(hdc, i+1, 0, niattribs, iattributes, 0, iresults, 0)) {
+ throw new GLException("Error getting pixel format attributes for pixel format " + (i + 1) + " of device context");
+ }
+ availableCaps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults,
+ relaxed, onscreen, usePBuffer);
+ }
+ }
+ } else {
+ long lastErr = WGL.GetLastError();
+ // Intel Extreme graphics fails with a zero error code
+ if (lastErr != 0) {
+ throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + WGL.GetLastError());
+ }
+ }
+ return availableCaps;
+ }
+
+ public static boolean GLCapabilities2AttribList(GLCapabilities caps,
+ int[] iattributes,
+ WGLExt wglExt,
+ boolean pbuffer,
+ int[] floatMode) throws GLException {
+ if (!wglExt.isExtensionAvailable("WGL_ARB_pixel_format")) {
+ return false;
+ }
+
+ int niattribs = 0;
+
+ iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ if (pbuffer) {
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
+ if (caps.getDoubleBuffered()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
+ if (caps.getStereo()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = caps.getDepthBits();
+ iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = caps.getRedBits();
+ iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = caps.getGreenBits();
+ iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = caps.getBlueBits();
+ iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = caps.getAlphaBits();
+ iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
+ iattributes[niattribs++] = caps.getStencilBits();
+ if (caps.getAccumRedBits() > 0 ||
+ caps.getAccumGreenBits() > 0 ||
+ caps.getAccumBlueBits() > 0 ||
+ caps.getAccumAlphaBits() > 0) {
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BITS_ARB;
+ iattributes[niattribs++] = (caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits() +
+ caps.getAccumAlphaBits());
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumRedBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumGreenBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumBlueBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumAlphaBits();
+ }
+
+ if (wglExt.isExtensionAvailable("WGL_ARB_multisample")) {
+ if (caps.getSampleBuffers()) {
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
+ iattributes[niattribs++] = caps.getNumSamples();
+ }
+ }
+
+ boolean rtt = caps.getPbufferRenderToTexture();
+ boolean rect = caps.getPbufferRenderToTextureRectangle();
+ boolean useFloat = caps.getPbufferFloatingPointBuffers();
+ boolean ati = false;
+ if (pbuffer) {
+ // Check some invariants and set up some state
+ if (rect && !rtt) {
+ throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified");
+ }
+
+ if (rect) {
+ if (!wglExt.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension");
+ }
+ }
+
+ if (useFloat) {
+ if (!wglExt.isExtensionAvailable("WGL_ATI_pixel_format_float") &&
+ !wglExt.isExtensionAvailable("WGL_NV_float_buffer")) {
+ throw new GLException("Floating-point pbuffers not supported by this hardware");
+ }
+
+ // Prefer NVidia extension over ATI
+ if (wglExt.isExtensionAvailable("WGL_NV_float_buffer")) {
+ ati = false;
+ floatMode[0] = GLPbuffer.NV_FLOAT;
+ } else {
+ ati = true;
+ floatMode[0] = GLPbuffer.ATI_FLOAT;
+ }
+ if (DEBUG) {
+ System.err.println("Using " + (ati ? "ATI" : "NVidia") + " floating-point extension");
+ }
+ }
+
+ // See whether we need to change the pixel type to support ATI's
+ // floating-point pbuffers
+ if (useFloat && ati) {
+ if (rtt) {
+ throw new GLException("Render-to-floating-point-texture not supported on ATI hardware");
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_FLOAT_ARB;
+ }
+ } else {
+ if (!rtt) {
+ // Currently we don't support non-truecolor visuals in the
+ // GLCapabilities, so we don't offer the option of making
+ // color-index pbuffers.
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB;
+ }
+ }
+
+ if (useFloat && !ati) {
+ iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+
+ if (rtt) {
+ if (useFloat) {
+ assert(!ati);
+ if (!rect) {
+ throw new GLException("Render-to-floating-point-texture only supported on NVidia hardware with render-to-texture-rectangle");
+ }
+ iattributes[niattribs++] = WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = rect ? WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGLExt.WGL_BIND_TO_TEXTURE_RGB_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+ }
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB;
+ }
+ iattributes[niattribs++] = 0;
+
+ return true;
+ }
+
+ public static final int WINDOW_BIT = 1 << 0 ;
+ public static final int BITMAP_BIT = 1 << 1 ;
+ public static final int PBUFFER_BIT = 1 << 2 ;
+
+ public static int WGLConfig2DrawableTypeBits(int[] iattribs,
+ int niattribs,
+ int[] iresults) {
+ int val = 0;
+
+ for (int i = 0; i < niattribs; i++) {
+ int attr = iattribs[i];
+ switch (attr) {
+ case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
+ if(iresults[i] == GL.GL_TRUE) val |= WINDOW_BIT;
+ break;
+ case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
+ if(iresults[i] == GL.GL_TRUE) val |= BITMAP_BIT;
+ break;
+ case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
+ if(iresults[i] == GL.GL_TRUE) val |= PBUFFER_BIT;
+ break;
+ }
+ }
+ return val;
+ }
+
+ public static boolean WGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) {
+ boolean res;
+
+ if ( onscreen ) {
+ res = ( 0 != (val & WINDOW_BIT) ) ;
+ } else {
+ if ( usePBuffer ) {
+ res = ( 0 != (val & PBUFFER_BIT) ) ;
+ } else {
+ res = ( 0 != (val & BITMAP_BIT) ) ;
+ }
+ }
+
+ return res;
+ }
+
+ public static GLCapabilities AttribList2GLCapabilities(GLProfile glp, int[] iattribs,
+ int niattribs,
+ int[] iresults,
+ boolean relaxed, boolean onscreen, boolean usePBuffer) {
+ GLCapabilities res = new GLCapabilities(glp);
+ int drawableTypeBits = WGLConfig2DrawableTypeBits(iattribs, niattribs, iresults);
+ if(WGLConfigDrawableTypeVerify(drawableTypeBits, onscreen, usePBuffer)) {
+ res.setOnscreen(onscreen);
+ res.setPBuffer(usePBuffer);
+ } else if(relaxed) {
+ res.setOnscreen( 0 != (drawableTypeBits & WINDOW_BIT) );
+ res.setPBuffer ( 0 != (drawableTypeBits & PBUFFER_BIT) );
+ } else {
+ if(DEBUG) {
+ System.err.println("WGL DrawableType does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (drawableTypeBits & WINDOW_BIT) )+", pbuffer "+( 0 != (drawableTypeBits & PBUFFER_BIT) )+", pixmap "+( 0 != (drawableTypeBits & BITMAP_BIT))+")");
+ }
+ return null;
+ }
+
+ for (int i = 0; i < niattribs; i++) {
+ int attr = iattribs[i];
+ switch (attr) {
+ case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
+ case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
+ case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
+ break;
+
+ case WGLExt.WGL_ACCELERATION_ARB:
+ res.setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB);
+ break;
+
+ case WGLExt.WGL_SUPPORT_OPENGL_ARB:
+ if (iresults[i] != GL.GL_TRUE) {
+ return null;
+ }
+ break;
+
+ case WGLExt.WGL_DEPTH_BITS_ARB:
+ res.setDepthBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_STENCIL_BITS_ARB:
+ res.setStencilBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_DOUBLE_BUFFER_ARB:
+ res.setDoubleBuffered(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case WGLExt.WGL_STEREO_ARB:
+ res.setStereo(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case WGLExt.WGL_PIXEL_TYPE_ARB:
+ // Fail softly with unknown results here
+ if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB||
+ iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) {
+ res.setPbufferFloatingPointBuffers(true);
+ }
+ break;
+
+ case WGLExt.WGL_FLOAT_COMPONENTS_NV:
+ if (iresults[i] != 0) {
+ res.setPbufferFloatingPointBuffers(true);
+ }
+ break;
+
+ case WGLExt.WGL_RED_BITS_ARB:
+ res.setRedBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_GREEN_BITS_ARB:
+ res.setGreenBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_BLUE_BITS_ARB:
+ res.setBlueBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ALPHA_BITS_ARB:
+ res.setAlphaBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_RED_BITS_ARB:
+ res.setAccumRedBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_GREEN_BITS_ARB:
+ res.setAccumGreenBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_BLUE_BITS_ARB:
+ res.setAccumBlueBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB:
+ res.setAccumAlphaBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_SAMPLE_BUFFERS_ARB:
+ res.setSampleBuffers(iresults[i] != 0);
+ break;
+
+ case WGLExt.WGL_SAMPLES_ARB:
+ res.setNumSamples(iresults[i]);
+ break;
+
+ default:
+ throw new GLException("Unknown pixel format attribute " + iattribs[i]);
+ }
+ }
+ return res;
+ }
+
+ // PIXELFORMAT
+
+ public static GLCapabilities PFD2GLCapabilities(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, boolean onscreen, boolean usePBuffer) {
+ if ((pfd.getDwFlags() & WGL.PFD_SUPPORT_OPENGL) == 0) {
+ return null;
+ }
+ GLCapabilities res = new GLCapabilities(glp);
+ res.setRedBits (pfd.getCRedBits());
+ res.setGreenBits (pfd.getCGreenBits());
+ res.setBlueBits (pfd.getCBlueBits());
+ res.setAlphaBits (pfd.getCAlphaBits());
+ res.setAccumRedBits (pfd.getCAccumRedBits());
+ res.setAccumGreenBits(pfd.getCAccumGreenBits());
+ res.setAccumBlueBits (pfd.getCAccumBlueBits());
+ res.setAccumAlphaBits(pfd.getCAccumAlphaBits());
+ res.setDepthBits (pfd.getCDepthBits());
+ res.setStencilBits (pfd.getCStencilBits());
+ res.setDoubleBuffered((pfd.getDwFlags() & WGL.PFD_DOUBLEBUFFER) != 0);
+ res.setStereo ((pfd.getDwFlags() & WGL.PFD_STEREO) != 0);
+ res.setHardwareAccelerated( ((pfd.getDwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) ||
+ ((pfd.getDwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0) );
+ res.setOnscreen ( onscreen && ((pfd.getDwFlags() & WGL.PFD_DRAW_TO_WINDOW) != 0) );
+ res.setPBuffer ( usePBuffer );
+ /* FIXME: Missing ??
+ if (GLXUtil.isMultisampleAvailable()) {
+ res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
+ res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0));
+ }
+ res.setBackgroundOpaque(glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_TYPE, tmp, 0) != GLX.GLX_NONE);
+ try {
+ res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE);
+ } catch (Exception e) {}
+ */
+ return res;
+ }
+
+ public static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilities caps) {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
+ int pfdFlags = (WGL.PFD_SUPPORT_OPENGL |
+ WGL.PFD_GENERIC_ACCELERATED);
+ if (caps.getDoubleBuffered()) {
+ pfdFlags |= WGL.PFD_DOUBLEBUFFER;
+ }
+ if (caps.isOnscreen()) {
+ pfdFlags |= WGL.PFD_DRAW_TO_WINDOW;
+ } else {
+ pfdFlags |= WGL.PFD_DRAW_TO_BITMAP;
+ }
+ if (caps.getStereo()) {
+ pfdFlags |= WGL.PFD_STEREO;
+ }
+ pfd.setDwFlags(pfdFlags);
+ pfd.setIPixelType((byte) WGL.PFD_TYPE_RGBA);
+ pfd.setCColorBits((byte) colorDepth);
+ pfd.setCRedBits ((byte) caps.getRedBits());
+ pfd.setCGreenBits((byte) caps.getGreenBits());
+ pfd.setCBlueBits ((byte) caps.getBlueBits());
+ pfd.setCAlphaBits((byte) caps.getAlphaBits());
+ int accumDepth = (caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits());
+ pfd.setCAccumBits ((byte) accumDepth);
+ pfd.setCAccumRedBits ((byte) caps.getAccumRedBits());
+ pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits());
+ pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits());
+ pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits());
+ pfd.setCDepthBits((byte) caps.getDepthBits());
+ pfd.setCStencilBits((byte) caps.getStencilBits());
+ pfd.setILayerType((byte) WGL.PFD_MAIN_PLANE);
+
+ /* FIXME: Missing:
+ caps.getSampleBuffers()
+ caps.getNumSamples ()
+ }
+ caps.getBackgroundOpaque()
+ try {
+ caps.getPbufferFloatingPointBuffers()
+ } catch (Exception e) {}
+ */
+ return pfd;
+ }
+
+ public static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
+ PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
+ pfd.setNSize((short) pfd.size());
+ pfd.setNVersion((short) 1);
+ return pfd;
+ }
+
+ public String toString() {
+ return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + pixelfmtID + ", wglChoosen "+choosenByWGLPixelFormat+
+ ",\n\trequested " + getRequestedCapabilities() +
+ ",\n\tchosen " + getChosenCapabilities() +
+ "]";
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..ab3227257
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.windows.*;
+import com.jogamp.nativewindow.impl.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
+ are used on Windows platforms. Toolkits will likely need to delegate
+ to this one to change the accepted and returned types of the
+ GraphicsDevice and GraphicsConfiguration abstractions. */
+
+public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ public WindowsWGLGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ GLCapabilities caps = (GLCapabilities)capabilities;
+ return chooseGraphicsConfigurationStatic(caps, chooser, absScreen);
+ }
+
+ protected static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(GLProfile glp, AbstractGraphicsScreen absScreen, boolean onscreen, boolean usePBuffer) {
+ GLCapabilities caps = new GLCapabilities(glp);
+ caps.setDoubleBuffered(onscreen); // FIXME DBLBUFOFFSCRN
+ caps.setOnscreen (onscreen);
+ caps.setPBuffer (usePBuffer);
+
+ if(null==absScreen) {
+ absScreen = DefaultGraphicsScreen.createScreenDevice(0);
+ }
+ return new WindowsWGLGraphicsConfiguration(absScreen, caps, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps), -1, null);
+
+ }
+
+ protected static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilities caps,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ if(null==absScreen) {
+ absScreen = DefaultGraphicsScreen.createScreenDevice(0);
+ }
+ GLCapabilities caps2 = (GLCapabilities) caps.clone();
+ if(!caps2.isOnscreen()) {
+ // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN
+ caps2.setDoubleBuffered(false);
+ }
+ return new WindowsWGLGraphicsConfiguration(absScreen, caps2, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps2), -1,
+ (GLCapabilitiesChooser)chooser);
+ }
+
+ protected static void updateGraphicsConfiguration(CapabilitiesChooser chooser,
+ GLDrawableFactory _factory, NativeWindow nativeWindow) {
+ WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory;
+ if (nativeWindow == null) {
+ throw new IllegalArgumentException("NativeWindow is null");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ boolean choosenBywGLPixelFormat = false;
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) nativeWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities) config.getRequestedCapabilities();
+ boolean onscreen = capabilities.isOnscreen();
+ boolean usePBuffer = capabilities.isPBuffer();
+ GLProfile glProfile = capabilities.getGLProfile();
+ long hdc = nativeWindow.getSurfaceHandle();
+
+ if (DEBUG) {
+ Exception ex = new Exception("WindowsWGLGraphicsConfigurationFactory got HDC "+toHexString(hdc));
+ ex.printStackTrace();
+ System.err.println("WindowsWGLGraphicsConfigurationFactory got NW "+nativeWindow);
+ }
+
+ PIXELFORMATDESCRIPTOR pfd = null;
+ int pixelFormat = -1; // 1-based pixel format
+ boolean pixelFormatSet = false;
+ GLCapabilities chosenCaps = null;
+
+ if (onscreen) {
+ if ((pixelFormat = WGL.GetPixelFormat(hdc)) != 0) {
+ // Pixelformat already set by either
+ // - a previous updateGraphicsConfiguration() call on the same HDC,
+ // - the graphics driver, copying the HDC's pixelformat to the new one,
+ // - or the Java2D/OpenGL pipeline's configuration
+ if (DEBUG) {
+ System.err.println("!!!! NOTE: pixel format already chosen for HDC: " + toHexString(hdc)+
+ ", pixelformat "+pixelFormat);
+ }
+ pixelFormatSet = true;
+ }
+
+ GLCapabilities[] availableCaps = null;
+ int numFormats = 0;
+ pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
+ // Produce a recommended pixel format selection for the GLCapabilitiesChooser.
+ // Use wglChoosePixelFormatARB if user requested multisampling and if we have it available
+ factory.sharedContext.makeCurrent();
+ WGLExt wglExt = factory.sharedContext.getWGLExt();
+
+ int recommendedPixelFormat = pixelFormat; // 1-based pixel format
+ boolean haveWGLChoosePixelFormatARB = false;
+ boolean gotAvailableCaps = false;
+ if (wglExt != null) {
+ try {
+ haveWGLChoosePixelFormatARB = wglExt.isExtensionAvailable("WGL_ARB_pixel_format");
+ if (haveWGLChoosePixelFormatARB) {
+ if(pixelFormat<=0) {
+ int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
+ float[] fattributes = new float[1];
+
+ if(WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
+ iattributes,
+ wglExt,
+ false,
+ null)) {
+ int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
+ int[] numFormatsTmp = new int[1];
+ if (wglExt.wglChoosePixelFormatARB(hdc,
+ iattributes, 0,
+ fattributes, 0,
+ WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+ pformats, 0,
+ numFormatsTmp, 0)) {
+ numFormats = numFormatsTmp[0];
+ if (recommendedPixelFormat<=0 && numFormats > 0) {
+ recommendedPixelFormat = pformats[0];
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Used wglChoosePixelFormatARB to recommend pixel format " + recommendedPixelFormat);
+ }
+ }
+ } else {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + WGL.GetLastError() );
+ Thread.dumpStack();
+ }
+ }
+ if (DEBUG) {
+ if (recommendedPixelFormat <= 0) {
+ System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format: "+WGL.GetLastError());
+ if (capabilities.getSampleBuffers()) {
+ System.err.print(" for multisampled GLCapabilities");
+ }
+ System.err.println();
+ }
+ }
+ }
+ }
+
+ availableCaps = WindowsWGLGraphicsConfiguration.HDC2GLCapabilities(wglExt, hdc, -1, glProfile, pixelFormatSet, onscreen, usePBuffer);
+ gotAvailableCaps = null!=availableCaps ;
+ choosenBywGLPixelFormat = gotAvailableCaps ;
+ } else if (DEBUG) {
+ System.err.println(getThreadName() + ": wglChoosePixelFormatARB not available");
+ }
+ } finally {
+ factory.sharedContext.release();
+ }
+ }
+
+ if (!gotAvailableCaps) {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Using ChoosePixelFormat ... (LastError: "+WGL.GetLastError()+")");
+ }
+ pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities);
+ recommendedPixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": ChoosePixelFormat(HDC "+toHexString(hdc)+") = " + recommendedPixelFormat + " (LastError: "+WGL.GetLastError()+")");
+ System.err.println(getThreadName() + ": Used " + capabilities);
+ }
+
+ numFormats = WGL.DescribePixelFormat(hdc, 1, 0, null);
+ if (numFormats == 0) {
+ throw new GLException("Unable to enumerate pixel formats of window " +
+ toHexString(hdc) + " for GLCapabilitiesChooser (LastError: "+WGL.GetLastError()+")");
+ }
+ availableCaps = new GLCapabilities[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ if (WGL.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) {
+ throw new GLException("Error describing pixel format " + (1 + i) + " of device context");
+ }
+ availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer);
+ }
+ }
+
+ // NOTE: officially, should make a copy of all of these
+ // GLCapabilities to avoid mutation by the end user during the
+ // chooseCapabilities call, but for the time being, assume they
+ // won't be changed
+
+ if(pixelFormat<=0) {
+ if(null!=chooser) {
+ // Supply information to chooser
+ try {
+ pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, recommendedPixelFormat) + 1;
+ } catch (NativeWindowException e) {
+ if(DEBUG) {
+ e.printStackTrace();
+ }
+ pixelFormat = -1;
+ }
+ } else {
+ pixelFormat = recommendedPixelFormat;
+ }
+ if (pixelFormat <= 0) {
+ // keep on going ..
+ if(DEBUG) {
+ System.err.println("WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration .. unable to choose config, using first");
+ }
+ pixelFormat = 1; // default ..
+ } else if ( pixelFormat > numFormats ) {
+ // keep on going ..
+ if(DEBUG) {
+ System.err.println("GLCapabilitiesChooser specified invalid index (expected 1.." + numFormats + ", got "+pixelFormat+")");
+ }
+ pixelFormat = 1; // default ..
+ }
+ }
+ chosenCaps = availableCaps[pixelFormat-1];
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):");
+ System.err.println(chosenCaps);
+ }
+ if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) {
+ throw new GLException("Error re-describing the chosen pixel format: " + WGL.GetLastError());
+ }
+ } else {
+ // For now, use ChoosePixelFormat for offscreen surfaces until
+ // we figure out how to properly choose an offscreen-
+ // compatible pixel format
+ pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities);
+ pixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
+ }
+ if(!pixelFormatSet) {
+ if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) {
+ long lastError = WGL.GetLastError();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() +
+ ", current DC = " + WGL.wglGetCurrentDC());
+ System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + WGL.GetPixelFormat(hdc));
+ }
+ throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError);
+ }
+ pixelFormatSet=true;
+ }
+ // Reuse the previously-constructed GLCapabilities because it
+ // turns out that using DescribePixelFormat on some pixel formats
+ // (which, for example, support full-scene antialiasing) for some
+ // reason return that they are not OpenGL-capable
+ if (chosenCaps != null) {
+ capabilities = chosenCaps;
+ } else {
+ capabilities = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer);
+ }
+ config.setCapsPFD(capabilities, pfd, pixelFormat, choosenBywGLPixelFormat);
+ }
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+ public static String toHexString(long hex) {
+ return "0x" + Long.toHexString(hex);
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..02cfd14c3
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl.awt;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.windows.*;
+import javax.media.nativewindow.awt.*;
+import javax.media.opengl.*;
+import javax.media.opengl.awt.*;
+
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.windows.wgl.*;
+import com.jogamp.nativewindow.impl.jawt.*;
+import com.jogamp.nativewindow.impl.jawt.windows.*;
+
+public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ public WindowsAWTWGLGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ GraphicsDevice device = null;
+ if (absScreen != null &&
+ !(absScreen instanceof AWTGraphicsScreen)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
+ }
+
+ if(null==absScreen) {
+ absScreen = AWTGraphicsScreen.createScreenDevice(-1);
+ }
+ AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen;
+ device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: got "+absScreen);
+ }
+ GraphicsConfiguration gc = device.getDefaultConfiguration();
+ AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capabilities, gc);
+ if(DEBUG) {
+ System.err.println("AWT Colormodel compatible: "+capabilities);
+ }
+
+ long displayHandle = 0;
+
+ WindowsGraphicsDevice winDevice = new WindowsGraphicsDevice();
+ DefaultGraphicsScreen winScreen = new DefaultGraphicsScreen(winDevice, awtScreen.getIndex());
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: made "+winScreen);
+ }
+
+ WindowsWGLGraphicsConfiguration winConfig = (WindowsWGLGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(winDevice).chooseGraphicsConfiguration(capabilities,
+ chooser,
+ winScreen);
+
+ if (winConfig == null) {
+ throw new GLException("Unable to choose a GraphicsConfiguration: "+capabilities+",\n\t"+chooser+"\n\t"+winScreen);
+ }
+
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: chosen "+winConfig);
+ }
+
+ // FIXME: we have nothing to match .. so choose the default
+ return new AWTGraphicsConfiguration(awtScreen, winConfig.getChosenCapabilities(), winConfig.getRequestedCapabilities(), gc, winConfig);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java
new file mode 100644
index 000000000..ec0eaf94f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.opengl.*;
+
+import com.jogamp.nativewindow.impl.x11.*;
+
+public class GLXUtil {
+ public static boolean isMultisampleAvailable(long display) {
+ X11Lib.XLockDisplay(display);
+ try {
+ String exts = GLX.glXGetClientString(display, GLX.GLX_EXTENSIONS);
+ if (exts != null) {
+ return (exts.indexOf("GLX_ARB_multisample") >= 0);
+ }
+ return false;
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+
+ /** Workaround for apparent issue with ATI's proprietary drivers
+ where direct contexts still send GLX tokens for GL calls */
+ public static String getVendorName(long display) {
+ X11Lib.XLockDisplay(display);
+ try {
+ return GLX.glXGetClientString(display, GLX.GLX_VENDOR);
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+
+ public static boolean isVendorNVIDIA(String vendor) {
+ return vendor != null && vendor.startsWith("NVIDIA") ;
+ }
+
+ public static boolean isVendorATI(String vendor) {
+ return vendor != null && vendor.startsWith("ATI") ;
+ }
+
+ public static boolean isVendorATI(long display) {
+ return isVendorATI(getVendorName(display));
+ }
+
+ public static boolean isVendorNVIDIA(long display) {
+ return isVendorNVIDIA(getVendorName(display));
+ }
+
+ public static void getGLXVersion(long display, int major[], int minor[]) {
+ if(0 == display) {
+ throw new GLException("null display handle");
+ }
+ if(major.length<1||minor.length<1) {
+ throw new GLException("passed int arrays size is not >= 1");
+ }
+
+ if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
+ throw new GLException("glXQueryVersion failed");
+ }
+
+ // Work around bugs in ATI's Linux drivers where they report they
+ // only implement GLX version 1.2 on the server side
+ if (major[0] == 1 && minor[0] == 2) {
+ String str = GLX.glXGetClientString(display, GLX.GLX_VERSION);
+ try {
+ // e.g. "1.3"
+ major[0] = Integer.valueOf(str.substring(0, 1)).intValue();
+ minor[0] = Integer.valueOf(str.substring(2, 3)).intValue();
+ } catch (Exception e) {
+ major[0] = 1;
+ minor[0] = 2;
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java
new file mode 100644
index 000000000..1f148bead
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2010 Sven Gothel. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name Sven Gothel or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import com.jogamp.nativewindow.impl.*;
+import com.jogamp.nativewindow.impl.x11.*;
+
+public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
+
+ private long dummyWindow = 0;
+
+ /**
+ * Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
+ * we cannot switch the Display as we please,
+ * hence we reuse the target's screen configuration.
+ */
+ public X11DummyGLXDrawable(X11GraphicsScreen screen, GLDrawableFactory factory, GLProfile glp) {
+ super(factory,
+ new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+ new GLCapabilities(glp), null, screen)));
+ this.realized = true;
+
+ NullWindow nw = (NullWindow) getNativeWindow();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)nw.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities caps = (GLCapabilities) config.getChosenCapabilities();
+
+ X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
+ long dpy = device.getHandle();
+ int scrn = screen.getIndex();
+ long visualID = config.getVisualID();
+
+ X11Lib.XLockDisplay(dpy);
+ try{
+ dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID);
+ } finally {
+ X11Lib.XUnlockDisplay(dpy);
+ }
+ nw.setSurfaceHandle( dummyWindow );
+ }
+
+ public void setSize(int width, int height) {
+ }
+
+ public int getWidth() {
+ return 1;
+ }
+
+ public int getHeight() {
+ return 1;
+ }
+
+ public void destroy() {
+ if(0!=dummyWindow) {
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ long dpy = config.getScreen().getDevice().getHandle();
+ X11Lib.DestroyDummyWindow(dpy, dummyWindow);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java
new file mode 100755
index 000000000..139c0deed
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+import com.jogamp.nativewindow.impl.x11.*;
+
+public class X11ExternalGLXContext extends X11GLXContext {
+ private boolean firstMakeCurrent = true;
+ private boolean created = true;
+ private GLContext lastContext;
+
+ private X11ExternalGLXContext(Drawable drawable, long context) {
+ super(drawable, null);
+ this.context = context;
+ GLContextShareSet.contextCreated(this);
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+ getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
+ }
+
+ protected static X11ExternalGLXContext create(GLDrawableFactory factory, GLProfile glp) {
+ ((GLDrawableFactoryImpl)factory).lockToolkit();
+ try {
+ long context = GLX.glXGetCurrentContext();
+ if (context == 0) {
+ throw new GLException("Error: current context null");
+ }
+ long display = GLX.glXGetCurrentDisplay();
+ if (display == 0) {
+ throw new GLException("Error: current display null");
+ }
+ long drawable = GLX.glXGetCurrentDrawable();
+ if (drawable == 0) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current");
+ }
+ int[] val = new int[1];
+ GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0);
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]);
+
+ GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0);
+ X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
+
+ NullWindow nw = new NullWindow(cfg);
+ nw.setSurfaceHandle(drawable);
+ return new X11ExternalGLXContext(new Drawable(factory, nw), context);
+ } finally {
+ ((GLDrawableFactoryImpl)factory).unlockToolkit();
+ }
+ }
+
+ protected void create() {
+ }
+
+ public int makeCurrent() throws GLException {
+ // Save last context if necessary to allow external GLContexts to
+ // talk to other GLContexts created by this library
+ GLContext cur = getCurrent();
+ if (cur != null && cur != this) {
+ lastContext = cur;
+ setCurrent(null);
+ }
+ return super.makeCurrent();
+ }
+
+ public void release() throws GLException {
+ super.release();
+ setCurrent(lastContext);
+ lastContext = null;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ created = false;
+ GLContextShareSet.contextDestroyed(this);
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+
+ // Need to provide the display connection to extension querying APIs
+ static class Drawable extends X11GLXDrawable {
+ Drawable(GLDrawableFactory factory, NativeWindow comp) {
+ super(factory, comp, true);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+
+ public void setSize(int width, int height) {
+ throw new GLException("Should not call this");
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java
new file mode 100755
index 000000000..f10bd38c6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+
+
+public class X11ExternalGLXDrawable extends X11GLXDrawable {
+ private int fbConfigID;
+ private int renderType;
+
+ private X11ExternalGLXDrawable(GLDrawableFactory factory, NativeWindow component, int renderType) {
+ super(factory, component, true);
+
+ this.renderType = renderType;
+
+ // Need GLXFBConfig ID in order to properly create new contexts
+ // on this drawable
+ X11GLXGraphicsConfiguration cfg = (X11GLXGraphicsConfiguration) component.getGraphicsConfiguration();
+ fbConfigID = cfg.getFBConfigID();
+ }
+
+ protected static X11ExternalGLXDrawable create(GLDrawableFactory factory, GLProfile glp) {
+ ((GLDrawableFactoryImpl)factory).lockToolkit();
+ try {
+ long context = GLX.glXGetCurrentContext();
+ if (context == 0) {
+ throw new GLException("Error: current context null");
+ }
+ long display = GLX.glXGetCurrentDisplay();
+ if (display == 0) {
+ throw new GLException("Error: current display null");
+ }
+ long drawable = GLX.glXGetCurrentDrawable();
+ if (drawable == 0) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable current");
+ }
+ int[] val = new int[1];
+ GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0);
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]);
+
+ GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0);
+ X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
+
+ int w, h;
+ GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val, 0);
+ w=val[0];
+ GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val, 0);
+ h=val[0];
+
+ GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val, 0);
+ if ((val[0] & GLX.GLX_RGBA_TYPE) == 0) {
+ if (DEBUG) {
+ System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val[0])+")");
+ }
+ }
+ NullWindow nw = new NullWindow(cfg);
+ nw.setSurfaceHandle(drawable);
+ nw.setSize(w, h);
+ return new X11ExternalGLXDrawable(factory, nw, GLX.GLX_RGBA_TYPE);
+ } finally {
+ ((GLDrawableFactoryImpl)factory).unlockToolkit();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new Context(this, shareWith);
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ return getNativeWindow().getWidth();
+ }
+
+ public int getHeight() {
+ return getNativeWindow().getHeight();
+ }
+
+ class Context extends X11GLXContext {
+ Context(X11GLXDrawable drawable, GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ protected void create() {
+ createContext(true);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
new file mode 100644
index 000000000..dce25978c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.glx.*;
+import com.jogamp.nativewindow.impl.x11.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+
+public abstract class X11GLXContext extends GLContextImpl {
+ protected long context;
+ private boolean glXQueryExtensionsStringInitialized;
+ private boolean glXQueryExtensionsStringAvailable;
+ private static final Map/*<String, String>*/ functionNameMap;
+ private static final Map/*<String, String>*/ extensionNameMap;
+ private GLXExt glXExt;
+ // Table that holds the addresses of the native C-language entry points for
+ // GLX extension functions.
+ private GLXExtProcAddressTable glXExtProcAddressTable;
+
+ static {
+ functionNameMap = new HashMap();
+ functionNameMap.put("glAllocateMemoryNV", "glXAllocateMemoryNV");
+ functionNameMap.put("glFreeMemoryNV", "glXFreeMemoryNV");
+
+ extensionNameMap = new HashMap();
+ extensionNameMap.put("GL_ARB_pbuffer", "GLX_SGIX_pbuffer");
+ extensionNameMap.put("GL_ARB_pixel_format", "GLX_SGIX_pbuffer"); // good enough
+ }
+
+ public X11GLXContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead,
+ GLContext shareWith) {
+ super(drawable, drawableRead, shareWith);
+ }
+
+ public X11GLXContext(GLDrawableImpl drawable,
+ GLContext shareWith) {
+ this(drawable, null, shareWith);
+ }
+
+ public final ProcAddressTable getPlatformExtProcAddressTable() {
+ return getGLXExtProcAddressTable();
+ }
+
+ public final GLXExtProcAddressTable getGLXExtProcAddressTable() {
+ return glXExtProcAddressTable;
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getGLXExt();
+ }
+
+ public GLXExt getGLXExt() {
+ if (glXExt == null) {
+ glXExt = new GLXExtImpl(this);
+ }
+ return glXExt;
+ }
+
+ protected Map/*<String, String>*/ getFunctionNameMap() { return functionNameMap; }
+
+ protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; }
+
+ protected boolean glXMakeContextCurrent(long dpy, long writeDrawable, long readDrawable, long ctx) {
+ boolean res = false;
+
+ try {
+ res = GLX.glXMakeContextCurrent(dpy, writeDrawable, readDrawable, ctx);
+ } catch (RuntimeException re) {
+ if(DEBUG) {
+ System.err.println("X11GLXContext.glXMakeContextCurrent failed: "+re+", with "+
+ "dpy "+toHexString(dpy)+
+ ", write "+toHexString(writeDrawable)+
+ ", read "+toHexString(readDrawable)+
+ ", ctx "+toHexString(ctx));
+ re.printStackTrace();
+ }
+ }
+ return res;
+ }
+
+ protected void destroyContextARBImpl(long _context) {
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ long display = config.getScreen().getDevice().getHandle();
+
+ glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, _context);
+ }
+
+ protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) {
+ X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ long display = config.getScreen().getDevice().getHandle();
+
+ GLXExt glXExt;
+ if(null==factory.getSharedContext()) {
+ glXExt = getGLXExt();
+ } else {
+ glXExt = ((X11GLXContext)factory.getSharedContext()).getGLXExt();
+ }
+
+ boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
+ boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
+ boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
+
+ long _context=0;
+
+ int attribs[] = {
+ /* 0 */ GLX.GLX_CONTEXT_MAJOR_VERSION_ARB, major,
+ /* 2 */ GLX.GLX_CONTEXT_MINOR_VERSION_ARB, minor,
+ /* 4 */ GLX.GLX_RENDER_TYPE, GLX.GLX_RGBA_TYPE, // default
+ /* 6 */ GLX.GLX_CONTEXT_FLAGS_ARB, 0,
+ /* 8 */ 0, 0,
+ /* 10 */ 0
+ };
+
+ if ( major > 3 || major == 3 && minor >= 2 ) {
+ // FIXME: Verify with a None drawable binding (default framebuffer)
+ attribs[8+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB;
+ if( ctBwdCompat ) {
+ attribs[8+1] = GLX.GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ } else {
+ attribs[8+1] = GLX.GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+ }
+ }
+
+ if ( major >= 3 ) {
+ if( !ctBwdCompat && ctFwdCompat ) {
+ attribs[6+1] |= GLX.GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+ }
+ if( ctDebug) {
+ attribs[6+1] |= GLX.GLX_CONTEXT_DEBUG_BIT_ARB;
+ }
+ }
+
+ try {
+ _context = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0);
+ } catch (RuntimeException re) {
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContextARB glXCreateContextAttribsARB failed: "+re+", with "+getGLVersion(null, major, minor, ctp, "@creation"));
+ re.printStackTrace();
+ }
+ }
+ if(0==_context) {
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContextARB couldn't create "+getGLVersion(null, major, minor, ctp, "@creation"));
+ }
+ } else {
+ if (!glXMakeContextCurrent(display,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ _context)) {
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContextARB couldn't make current "+getGLVersion(null, major, minor, ctp, "@creation"));
+ }
+ glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, _context);
+ _context = 0;
+ }
+ }
+ return _context;
+ }
+
+ /**
+ * Creates and initializes an appropriate OpenGL context. Should only be
+ * called by {@link #create()}.
+ * Note: The direct parameter may be overwritten by the direct state of a shared context.
+ */
+ protected void createContext(boolean direct) {
+ if(0!=context) {
+ throw new GLException("context is not null: "+context);
+ }
+ X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ long display = config.getScreen().getDevice().getHandle();
+
+ X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ direct = GLX.glXIsDirect(display, share);
+ }
+
+ GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities();
+ GLProfile glp = glCaps.getGLProfile();
+ isVendorATI = factory.isVendorATI();
+
+ if(config.getFBConfigID()<0) {
+ // not able to use FBConfig
+ if(glp.isGL3()) {
+ throw new GLException("Unable to create OpenGL >= 3.1 context");
+ }
+ context = GLX.glXCreateContext(display, config.getXVisualInfo(), share, direct);
+ if (context == 0) {
+ throw new GLException("Unable to create context(0)");
+ }
+ if (!glXMakeContextCurrent(display,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ context)) {
+ throw new GLException("Error making temp context(0) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable);
+ }
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+ return;
+ }
+
+ int minor[] = new int[1];
+ int major[] = new int[1];
+ int ctp[] = new int[1];
+ boolean createContextARBTried = false;
+
+ // utilize the shared context's GLXExt in case it was using the ARB method and it already exists
+ if(null!=factory.getSharedContext() && factory.getSharedContext().isCreatedWithARBMethod()) {
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext using shared Context: "+factory.getSharedContext());
+ }
+ context = createContextARB(share, direct, major, minor, ctp);
+ createContextARBTried = true;
+ }
+
+ long temp_context = 0;
+ if(0==context) {
+ // To use GLX_ARB_create_context, we have to make a temp context current,
+ // so we are able to use GetProcAddress
+ temp_context = GLX.glXCreateNewContext(display, config.getFBConfig(), GLX.GLX_RGBA_TYPE, share, direct);
+ if (temp_context == 0) {
+ throw new GLException("Unable to create temp OpenGL context(1)");
+ }
+ if (!glXMakeContextCurrent(display,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ temp_context)) {
+ throw new GLException("Error making temp context(1) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable);
+ }
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+
+ if( createContextARBTried ||
+ !isFunctionAvailable("glXCreateContextAttribsARB") ||
+ !isExtensionAvailable("GLX_ARB_create_context") ) {
+ if(glp.isGL3()) {
+ glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, temp_context);
+ throw new GLException("Unable to create OpenGL >= 3.1 context (failed GLX_ARB_create_context), GLProfile "+glp+", Drawable "+drawable);
+ }
+
+ // continue with temp context for GL < 3.0
+ context = temp_context;
+ return;
+ }
+ context = createContextARB(share, direct, major, minor, ctp);
+ createContextARBTried=true;
+ }
+
+ if(0!=context) {
+ if(0!=temp_context) {
+ glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, temp_context);
+ if (!glXMakeContextCurrent(display,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ context)) {
+ throw new GLException("Cannot make previous verified context current");
+ }
+ }
+ } else {
+ if(glp.isGL3()) {
+ glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, temp_context);
+ throw new GLException("X11GLXContext.createContext failed, but context > GL2 requested "+getGLVersion(null, major[0], minor[0], ctp[0], "@creation")+", ");
+ }
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext failed, fall back to !ARB context "+getGLVersion(null, major[0], minor[0], ctp[0], "@creation"));
+ }
+
+ // continue with temp context for GL <= 3.0
+ context = temp_context;
+ if (!glXMakeContextCurrent(display,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ context)) {
+ glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, temp_context);
+ throw new GLException("Error making context(1) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable);
+ }
+ }
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected int makeCurrentImpl() throws GLException {
+ int lockRes = drawable.lockSurface();
+ boolean exceptionOccurred = false;
+ try {
+ if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ return makeCurrentImplAfterLock();
+ } catch (RuntimeException e) {
+ exceptionOccurred = true;
+ throw e;
+ } finally {
+ if (exceptionOccurred ||
+ (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY) && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected void releaseImpl() throws GLException {
+ try {
+ releaseImplAfterLock();
+ } finally {
+ if (!isOptimizable() && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ protected int makeCurrentImplAfterLock() throws GLException {
+ long dpy = drawable.getNativeWindow().getDisplayHandle();
+
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ if (drawable.getNativeWindow().getSurfaceHandle() == 0) {
+ throw new GLException("drawable not properly initialized: "+drawable);
+ }
+ boolean created = false;
+ if (context == 0) {
+ create();
+ created = true;
+ GLContextShareSet.contextCreated(this);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName());
+ }
+ }
+
+ if (GLX.glXGetCurrentContext() != context) {
+
+ if (!glXMakeContextCurrent(dpy,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ context)) {
+ throw new GLException("Error making context current: "+this);
+ }
+ if (DEBUG && (VERBOSE || created)) {
+ System.err.println(getThreadName() + ": glXMakeCurrent(display " +
+ toHexString(dpy)+
+ ", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) +
+ ", drawableRead " + toHexString(drawableRead.getNativeWindow().getSurfaceHandle()) +
+ ", context " + toHexString(context) + ") succeeded");
+ }
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ protected void releaseImplAfterLock() throws GLException {
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ if (!glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(), 0, 0, 0)) {
+ throw new GLException("Error freeing OpenGL context");
+ }
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ if (context != 0) {
+ if (DEBUG) {
+ System.err.println("glXDestroyContext(" +
+ toHexString(drawable.getNativeWindow().getDisplayHandle()) +
+ ", " +
+ toHexString(context) + ")");
+ }
+ GLX.glXDestroyContext(drawable.getNativeWindow().getDisplayHandle(), context);
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL context " + context);
+ }
+ context = 0;
+ GLContextShareSet.contextDestroyed(this);
+ }
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ public boolean isCreated() {
+ return (context != 0);
+ }
+
+ public void copy(GLContext source, int mask) throws GLException {
+ long dst = getContext();
+ long src = ((X11GLXContext) source).getContext();
+ if (src == 0) {
+ throw new GLException("Source OpenGL context has not been created");
+ }
+ if (dst == 0) {
+ throw new GLException("Destination OpenGL context has not been created");
+ }
+ if (drawable.getNativeWindow().getDisplayHandle() == 0) {
+ throw new GLException("Connection to X display not yet set up");
+ }
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ GLX.glXCopyContext(drawable.getNativeWindow().getDisplayHandle(), src, dst, mask);
+ // Should check for X errors and raise GLException
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ protected void updateGLProcAddressTable(int major, int minor, int ctp) {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing GLX extension address table");
+ }
+ glXQueryExtensionsStringInitialized = false;
+ glXQueryExtensionsStringAvailable = false;
+
+ if (glXExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ glXExtProcAddressTable = new GLXExtProcAddressTable();
+ }
+ resetProcAddressTable(getGLXExtProcAddressTable());
+ super.updateGLProcAddressTable(major, minor, ctp);
+ }
+
+ public synchronized String getPlatformExtensionsString() {
+ if (!glXQueryExtensionsStringInitialized) {
+ glXQueryExtensionsStringAvailable =
+ getDrawableImpl().getDynamicLookupHelper().dynamicLookupFunction("glXQueryExtensionsString") != 0;
+ glXQueryExtensionsStringInitialized = true;
+ }
+ if (glXQueryExtensionsStringAvailable) {
+ GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl();
+ factory.lockToolkit();
+ try {
+ String ret = GLX.glXQueryExtensionsString(drawable.getNativeWindow().getDisplayHandle(),
+ drawable.getNativeWindow().getScreenIndex());
+ if (DEBUG) {
+ System.err.println("!!! GLX extensions: " + ret);
+ }
+ return ret;
+ } finally {
+ factory.unlockToolkit();
+ }
+ } else {
+ return "";
+ }
+ }
+
+ public boolean isExtensionAvailable(String glExtensionName) {
+ if (glExtensionName.equals("GL_ARB_pbuffer") ||
+ glExtensionName.equals("GL_ARB_pixel_format")) {
+ return getGLDrawable().getFactory().canCreateGLPbuffer(
+ drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice() );
+ }
+ return super.isExtensionAvailable(glExtensionName);
+ }
+
+
+ private int hasSwapIntervalSGI = 0;
+
+ protected void setSwapIntervalImpl(int interval) {
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities();
+ if(!glCaps.isOnscreen()) return;
+
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ GLXExt glXExt = getGLXExt();
+ if(0==hasSwapIntervalSGI) {
+ try {
+ hasSwapIntervalSGI = glXExt.isExtensionAvailable("GLX_SGI_swap_control")?1:-1;
+ } catch (Throwable t) { hasSwapIntervalSGI=1; }
+ }
+ if (hasSwapIntervalSGI>0) {
+ try {
+ if( 0 == glXExt.glXSwapIntervalSGI(interval) ) {
+ currentSwapInterval = interval;
+ }
+ } catch (Throwable t) { hasSwapIntervalSGI=-1; }
+ }
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+ return getGLXExt().glXAllocateMemoryNV(arg0, arg1, arg2, arg3);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean isOptimizable() {
+ return (super.isOptimizable() && !isVendorATI);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ public long getContext() {
+ return context;
+ }
+
+ private boolean isVendorATI = false;
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java
new file mode 100644
index 000000000..95dfc0a1c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.common.os.DynamicLookupHelper;
+
+public abstract class X11GLXDrawable extends GLDrawableImpl {
+ protected X11GLXDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) {
+ super(factory, comp, realized);
+ }
+
+ public DynamicLookupHelper getDynamicLookupHelper() {
+ return (X11GLXDrawableFactory) getFactoryImpl() ;
+ }
+
+ protected void setRealizedImpl() {
+ if(!realized) {
+ return; // nothing to do
+ }
+
+ if(NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface()) {
+ throw new GLException("X11GLXDrawable.setRealized(true): lockSurface - surface not ready");
+ }
+ try {
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ config.updateGraphicsConfiguration();
+
+ if (DEBUG) {
+ System.err.println("!!! X11GLXDrawable.setRealized(true): "+config);
+ }
+ } finally {
+ unlockSurface();
+ }
+ }
+
+ protected void swapBuffersImpl() {
+ boolean didLock = false;
+ if (!isSurfaceLocked()) {
+ // Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return;
+ }
+ didLock = true;
+ }
+ try {
+ GLX.glXSwapBuffers(component.getDisplayHandle(), component.getSurfaceHandle());
+ } finally {
+ if (didLock) {
+ unlockSurface();
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------------
+ // Internals only below this point
+ //
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
new file mode 100644
index 000000000..d8e5f7646
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import com.jogamp.common.os.DynamicLookupHelper;
+import java.nio.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.opengl.*;
+import com.jogamp.gluegen.runtime.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.util.*;
+import com.jogamp.nativewindow.impl.NullWindow;
+import com.jogamp.nativewindow.impl.x11.*;
+
+public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements DynamicLookupHelper {
+
+ public X11GLXDrawableFactory() {
+ super();
+ // Must initialize GLX support eagerly in case a pbuffer is the
+ // first thing instantiated
+ GLProcAddressHelper.resetProcAddressTable(GLX.getGLXProcAddressTable(), this);
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ new X11GLXGraphicsConfigurationFactory();
+ try {
+ ReflectionUtil.createInstance("com.jogamp.opengl.impl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory",
+ new Object[] {});
+ } catch (JogampRuntimeException jre) { /* n/a .. */ }
+
+ X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createThreadLocalDisplay(null));
+ vendorName = GLXUtil.getVendorName(sharedDevice.getHandle());
+ isVendorATI = GLXUtil.isVendorATI(vendorName);
+ isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName);
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(sharedDevice.getHandle()); // ATI hack ..
+ }
+ sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
+ X11Lib.XLockDisplay(sharedScreen.getDevice().getHandle());
+ try{
+ sharedDrawable = new X11DummyGLXDrawable(sharedScreen, this, null);
+ X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null);
+ ctx.makeCurrent();
+ ctx.release();
+ sharedContext = ctx;
+ }finally{
+ X11Lib.XUnlockDisplay(sharedScreen.getDevice().getHandle());
+ }
+ if(null==sharedContext) {
+ throw new GLException("Couldn't init shared resources");
+ }
+ if (DEBUG) {
+ System.err.println("!!! Vendor: "+vendorName+", ATI: "+isVendorATI+", NV: "+isVendorNVIDIA);
+ System.err.println("!!! SharedScreen: "+sharedScreen);
+ System.err.println("!!! SharedContext: "+sharedContext);
+ }
+ }
+
+ private X11GraphicsScreen sharedScreen;
+ private String vendorName;
+ private boolean isVendorATI;
+ private boolean isVendorNVIDIA;
+
+ public String getVendorName() { return vendorName; }
+ public boolean isVendorATI() { return isVendorATI; }
+ public boolean isVendorNVIDIA() { return isVendorNVIDIA; }
+
+ private X11DummyGLXDrawable sharedDrawable=null;
+ private X11GLXContext sharedContext=null;
+
+ protected final GLDrawableImpl getSharedDrawable() {
+ validate();
+ return sharedDrawable;
+ }
+
+ protected final GLContextImpl getSharedContext() {
+ validate();
+ return sharedContext;
+ }
+
+ public void shutdown() {
+ super.shutdown();
+ if (DEBUG) {
+ System.err.println("!!! Shutdown Shared:");
+ System.err.println("!!! CTX : "+sharedContext);
+ System.err.println("!!! Drawable: "+sharedDrawable);
+ System.err.println("!!! Screen : "+sharedScreen);
+ Exception e = new Exception("Debug");
+ e.printStackTrace();
+ }
+ if(null!=sharedContext) {
+ sharedContext.destroy(); // implies release, if current
+ }
+ if(null!=sharedDrawable) {
+ sharedDrawable.destroy();
+ }
+ if(null!=sharedScreen) {
+ X11GraphicsDevice sharedDevice = (X11GraphicsDevice) sharedScreen.getDevice();
+ if(null!=sharedDevice) {
+ X11Util.closeThreadLocalDisplay(null);
+ }
+ sharedScreen = null;
+ }
+ X11Util.shutdown( !isVendorATI(), DEBUG );
+ }
+
+ public GLDrawableImpl createOnscreenDrawable(NativeWindow target) {
+ validate();
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack ..
+ }
+ return new X11OnscreenGLXDrawable(this, target);
+ }
+
+ protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) {
+ validate();
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack ..
+ }
+ return new X11OffscreenGLXDrawable(this, target);
+ }
+
+ public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+ validate();
+ return glxVersionGreaterEqualThan(device, 1, 3);
+ }
+
+ private boolean glxVersionsQueried = false;
+ private int glxVersionMajor=0, glxVersionMinor=0;
+ public boolean glxVersionGreaterEqualThan(AbstractGraphicsDevice device, int majorReq, int minorReq) {
+ validate();
+ if (!glxVersionsQueried) {
+ if(null == device) {
+ device = (X11GraphicsDevice) sharedScreen.getDevice();
+ }
+ if(null == device) {
+ throw new GLException("FIXME: No AbstractGraphicsDevice (passed or shared-device");
+ }
+ long display = device.getHandle();
+ int[] major = new int[1];
+ int[] minor = new int[1];
+
+ GLXUtil.getGLXVersion(display, major, minor);
+ if (DEBUG) {
+ System.err.println("!!! GLX version: major " + major[0] +
+ ", minor " + minor[0]);
+ }
+
+ glxVersionMajor = major[0];
+ glxVersionMinor = minor[0];
+ glxVersionsQueried = true;
+ }
+ return ( glxVersionMajor > majorReq ) || ( glxVersionMajor == majorReq && glxVersionMinor >= minorReq ) ;
+ }
+
+ protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeWindow target) {
+ validate();
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+
+ GLDrawableImpl pbufferDrawable;
+
+ /**
+ * Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
+ * we need to have a context current on the same Display to create a PBuffer.
+ * The dummy context shall also use the same Display,
+ * since switching Display in this regard is another ATI bug.
+ */
+ boolean usedSharedContext=false;
+ if( isVendorATI() && null == GLContext.getCurrent() ) {
+ sharedContext.makeCurrent();
+ usedSharedContext=true;
+ }
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack ..
+ }
+ try {
+ pbufferDrawable = new X11PbufferGLXDrawable(this, target);
+ } finally {
+ if(usedSharedContext) {
+ sharedContext.release();
+ }
+ }
+ return pbufferDrawable;
+ }
+
+
+ protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
+ validate();
+ NullWindow nw = null;
+ X11Lib.XLockDisplay(sharedScreen.getDevice().getHandle());
+ try{
+ nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, sharedScreen));
+ }finally{
+ X11Lib.XUnlockDisplay(sharedScreen.getDevice().getHandle());
+ }
+ if(nw != null) {
+ nw.setSize(width, height);
+ }
+ return nw;
+ }
+
+ public GLContext createExternalGLContext() {
+ validate();
+ return X11ExternalGLXContext.create(this, null);
+ }
+
+ public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) {
+ validate();
+ return canCreateGLPbuffer(device);
+ }
+
+ public GLDrawable createExternalGLDrawable() {
+ validate();
+ return X11ExternalGLXDrawable.create(this, null);
+ }
+
+ public void loadGLULibrary() {
+ validate();
+ X11Lib.dlopen("/usr/lib/libGLU.so");
+ }
+
+ public long dynamicLookupFunction(String glFuncName) {
+ long res = 0;
+ res = GLX.glXGetProcAddressARB(glFuncName);
+ if (res == 0) {
+ // GLU routines aren't known to the OpenGL function lookup
+ res = X11Lib.dlsym(glFuncName);
+ }
+ return res;
+ }
+
+ public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) {
+ validate();
+ return false;
+ }
+
+ public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ throw new GLException("Unimplemented on this platform");
+ }
+
+ //----------------------------------------------------------------------
+ // Gamma-related functionality
+ //
+
+ private boolean gotGammaRampLength;
+ private int gammaRampLength;
+ protected synchronized int getGammaRampLength() {
+ if (gotGammaRampLength) {
+ return gammaRampLength;
+ }
+
+ long display = sharedScreen.getDevice().getHandle();
+
+ X11Lib.XLockDisplay(display);
+ try {
+ int[] size = new int[1];
+ boolean res = X11Lib.XF86VidModeGetGammaRampSize(display,
+ X11Lib.DefaultScreen(display),
+ size, 0);
+ if (!res) {
+ return 0;
+ }
+ gotGammaRampLength = true;
+ gammaRampLength = size[0];
+ return gammaRampLength;
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+
+ protected boolean setGammaRamp(float[] ramp) {
+ int len = ramp.length;
+ short[] rampData = new short[len];
+ for (int i = 0; i < len; i++) {
+ rampData[i] = (short) (ramp[i] * 65535);
+ }
+
+ long display = sharedScreen.getDevice().getHandle();
+ X11Lib.XLockDisplay(display);
+ try {
+ boolean res = X11Lib.XF86VidModeSetGammaRamp(display,
+ X11Lib.DefaultScreen(display),
+ rampData.length,
+ rampData, 0,
+ rampData, 0,
+ rampData, 0);
+ return res;
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+
+ protected Buffer getGammaRamp() {
+ int size = getGammaRampLength();
+ ShortBuffer rampData = ShortBuffer.wrap(new short[3 * size]);
+ rampData.position(0);
+ rampData.limit(size);
+ ShortBuffer redRampData = rampData.slice();
+ rampData.position(size);
+ rampData.limit(2 * size);
+ ShortBuffer greenRampData = rampData.slice();
+ rampData.position(2 * size);
+ rampData.limit(3 * size);
+ ShortBuffer blueRampData = rampData.slice();
+ long display = sharedScreen.getDevice().getHandle();
+ X11Lib.XLockDisplay(display);
+ try {
+ boolean res = X11Lib.XF86VidModeGetGammaRamp(display,
+ X11Lib.DefaultScreen(display),
+ size,
+ redRampData,
+ greenRampData,
+ blueRampData);
+ if (!res) {
+ return null;
+ }
+ return rampData;
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+
+ protected void resetGammaRamp(Buffer originalGammaRamp) {
+ if (originalGammaRamp == null)
+ return; // getGammaRamp failed originally
+ ShortBuffer rampData = (ShortBuffer) originalGammaRamp;
+ int capacity = rampData.capacity();
+ if ((capacity % 3) != 0) {
+ throw new IllegalArgumentException("Must not be the original gamma ramp");
+ }
+ int size = capacity / 3;
+ rampData.position(0);
+ rampData.limit(size);
+ ShortBuffer redRampData = rampData.slice();
+ rampData.position(size);
+ rampData.limit(2 * size);
+ ShortBuffer greenRampData = rampData.slice();
+ rampData.position(2 * size);
+ rampData.limit(3 * size);
+ ShortBuffer blueRampData = rampData.slice();
+ long display = sharedScreen.getDevice().getHandle();
+ X11Lib.XLockDisplay(display);
+ try {
+ X11Lib.XF86VidModeSetGammaRamp(display,
+ X11Lib.DefaultScreen(display),
+ size,
+ redRampData,
+ greenRampData,
+ blueRampData);
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
new file mode 100644
index 000000000..35daf0ae0
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import com.jogamp.common.nio.PointerBuffer;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.x11.*;
+
+public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implements Cloneable {
+ protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+
+ public static final int MAX_ATTRIBS = 128;
+ private long fbConfig;
+ private int fbConfigID;
+ private GLCapabilitiesChooser chooser;
+
+ public X11GLXGraphicsConfiguration(X11GraphicsScreen screen,
+ GLCapabilities capsChosen, GLCapabilities capsRequested, GLCapabilitiesChooser chooser,
+ XVisualInfo info, long fbcfg, int fbcfgID) {
+ super(screen, capsChosen, capsRequested, info);
+ this.chooser=chooser;
+ fbConfig = fbcfg;
+ fbConfigID = fbcfgID;
+ }
+
+ public static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
+ long display = x11Screen.getDevice().getHandle();
+ if(0==display) {
+ throw new GLException("Display null of "+x11Screen);
+ }
+ int screen = x11Screen.getIndex();
+ long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
+ if(0==fbcfg) {
+ throw new GLException("FBConfig null of "+toHexString(fbcfgID));
+ }
+ if(null==glp) {
+ glp = GLProfile.getDefault();
+ }
+ GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display));
+ if(null==caps) {
+ throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
+ }
+ XVisualInfo xvi = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg);
+ if(null==xvi) {
+ throw new GLException("XVisualInfo null of "+toHexString(fbcfg));
+ }
+ return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID);
+ }
+
+ public Object clone() {
+ return super.clone();
+ }
+
+ public long getFBConfig() { return fbConfig; }
+ public int getFBConfigID() { return fbConfigID; }
+
+ protected void updateGraphicsConfiguration() {
+ X11GLXGraphicsConfiguration newConfig = (X11GLXGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(getScreen().getDevice()).chooseGraphicsConfiguration(getRequestedCapabilities(),
+ chooser,
+ getScreen());
+ if(null!=newConfig) {
+ // FIXME: setScreen( ... );
+ setXVisualInfo(newConfig.getXVisualInfo());
+ setChosenCapabilities(newConfig.getChosenCapabilities());
+ fbConfig = newConfig.getFBConfig();
+ fbConfigID = newConfig.getFBConfigID();
+ if(DEBUG) {
+ System.err.println("!!! updateGraphicsConfiguration: "+this);
+ }
+ }
+ }
+
+ private static int nonZeroOrDontCare(int value) {
+ return value != 0 ? value : (int)GLX.GLX_DONT_CARE ;
+ }
+
+ public static int[] GLCapabilities2AttribList(GLCapabilities caps,
+ boolean forFBAttr,
+ boolean isMultisampleAvailable,
+ long display,
+ int screen)
+ {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ int[] res = new int[MAX_ATTRIBS];
+ int idx = 0;
+
+ if (forFBAttr) {
+ res[idx++] = GLX.GLX_DRAWABLE_TYPE;
+ res[idx++] = caps.isOnscreen() ? ( GLX.GLX_WINDOW_BIT ) : ( caps.isPBuffer() ? GLX.GLX_PBUFFER_BIT : GLX.GLX_PIXMAP_BIT ) ;
+ }
+
+ if (forFBAttr) {
+ res[idx++] = GLX.GLX_RENDER_TYPE;
+ res[idx++] = GLX.GLX_RGBA_BIT;
+ } else {
+ res[idx++] = GLX.GLX_RGBA;
+ }
+
+ // FIXME: Still a bug is Mesa: PBUFFER && GLX_STEREO==GL_FALSE ?
+ if (forFBAttr) {
+ res[idx++] = GLX.GLX_DOUBLEBUFFER;
+ res[idx++] = caps.getDoubleBuffered()?GL.GL_TRUE:GL.GL_FALSE;
+ res[idx++] = GLX.GLX_STEREO;
+ res[idx++] = caps.getStereo()?GL.GL_TRUE:GL.GL_FALSE;
+ res[idx++] = GLX.GLX_TRANSPARENT_TYPE;
+ res[idx++] = caps.isBackgroundOpaque()?GLX.GLX_NONE:GLX.GLX_TRANSPARENT_RGB;
+ if(!caps.isBackgroundOpaque()) {
+ res[idx++] = GLX.GLX_TRANSPARENT_RED_VALUE;
+ res[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():(int)GLX.GLX_DONT_CARE;
+ res[idx++] = GLX.GLX_TRANSPARENT_GREEN_VALUE;
+ res[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():(int)GLX.GLX_DONT_CARE;
+ res[idx++] = GLX.GLX_TRANSPARENT_BLUE_VALUE;
+ res[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():(int)GLX.GLX_DONT_CARE;
+ res[idx++] = GLX.GLX_TRANSPARENT_ALPHA_VALUE;
+ res[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():(int)GLX.GLX_DONT_CARE;
+ }
+ } else {
+ if (caps.getDoubleBuffered()) {
+ res[idx++] = GLX.GLX_DOUBLEBUFFER;
+ }
+ if (caps.getStereo()) {
+ res[idx++] = GLX.GLX_STEREO;
+ }
+ }
+
+ res[idx++] = GLX.GLX_RED_SIZE;
+ res[idx++] = caps.getRedBits();
+ res[idx++] = GLX.GLX_GREEN_SIZE;
+ res[idx++] = caps.getGreenBits();
+ res[idx++] = GLX.GLX_BLUE_SIZE;
+ res[idx++] = caps.getBlueBits();
+ res[idx++] = GLX.GLX_ALPHA_SIZE;
+ res[idx++] = caps.getAlphaBits();
+ res[idx++] = GLX.GLX_DEPTH_SIZE;
+ res[idx++] = caps.getDepthBits();
+ if (caps.getStencilBits() > 0) {
+ res[idx++] = GLX.GLX_STENCIL_SIZE;
+ res[idx++] = caps.getStencilBits();
+ }
+ if (caps.getAccumRedBits() > 0 ||
+ caps.getAccumGreenBits() > 0 ||
+ caps.getAccumBlueBits() > 0 ||
+ caps.getAccumAlphaBits() > 0) {
+ res[idx++] = GLX.GLX_ACCUM_RED_SIZE;
+ res[idx++] = caps.getAccumRedBits();
+ res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE;
+ res[idx++] = caps.getAccumGreenBits();
+ res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE;
+ res[idx++] = caps.getAccumBlueBits();
+ res[idx++] = GLX.GLX_ACCUM_ALPHA_SIZE;
+ res[idx++] = caps.getAccumAlphaBits();
+ }
+ if (isMultisampleAvailable && caps.getSampleBuffers()) {
+ res[idx++] = GLX.GLX_SAMPLE_BUFFERS;
+ res[idx++] = GL.GL_TRUE;
+ res[idx++] = GLX.GLX_SAMPLES;
+ res[idx++] = caps.getNumSamples();
+ }
+ if (caps.isPBuffer()) {
+ if (caps.getPbufferFloatingPointBuffers()) {
+ String glXExtensions = GLX.glXQueryExtensionsString(display, screen);
+ if (glXExtensions == null ||
+ glXExtensions.indexOf("GLX_NV_float_buffer") < 0) {
+ throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware: "+glXExtensions);
+ }
+ res[idx++] = GLXExt.GLX_FLOAT_COMPONENTS_NV;
+ res[idx++] = GL.GL_TRUE;
+ }
+ }
+ res[idx++] = 0;
+ return res;
+ }
+
+ // FBConfig
+
+ public static boolean GLXFBConfigValid(long display, long fbcfg) {
+ int[] tmp = new int[1];
+ if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean GLXFBConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) {
+ boolean res;
+
+ if ( onscreen ) {
+ res = ( 0 != (val & GLX.GLX_WINDOW_BIT) ) ;
+ } else {
+ if ( usePBuffer ) {
+ res = ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ;
+ } else {
+ res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) ;
+ }
+ }
+
+ return res;
+ }
+
+ public static GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg,
+ boolean relaxed, boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) {
+ int[] tmp = new int[1];
+ int val;
+ val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0);
+ if (val != GLX.GLX_RGBA_BIT) {
+ if(DEBUG) {
+ System.err.println("FBConfig ("+toHexString(fbcfg)+") does not support RGBA: "+toHexString(val));
+ }
+ return null;
+ }
+ GLCapabilities res = new GLCapabilities(glp);
+
+ val = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0);
+ if(GLXFBConfigDrawableTypeVerify(val, onscreen, usePBuffer)) {
+ res.setOnscreen(onscreen);
+ res.setPBuffer(usePBuffer);
+ } else if(relaxed) {
+ res.setOnscreen( 0 != (val & GLX.GLX_WINDOW_BIT) );
+ res.setPBuffer ( 0 != (val & GLX.GLX_PBUFFER_BIT) );
+ } else {
+ if(DEBUG) {
+ System.err.println("FBConfig ("+toHexString(fbcfg)+") GLX_DRAWABLE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val & GLX.GLX_WINDOW_BIT) )+", pbuffer "+( 0 != (val & GLX.GLX_PBUFFER_BIT) )+", pixmap "+( 0 != (val & GLX.GLX_PIXMAP_BIT) )+")");
+ }
+ return null;
+ }
+ res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
+ res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0);
+ res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG);
+ res.setDepthBits (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE, tmp, 0));
+ res.setStencilBits (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE, tmp, 0));
+ res.setRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE, tmp, 0));
+ res.setGreenBits (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE, tmp, 0));
+ res.setBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE, tmp, 0));
+ res.setAlphaBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE, tmp, 0));
+ res.setAccumRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
+ res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
+ res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
+ res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
+ if (isMultisampleEnabled) {
+ res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
+ res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0));
+ }
+ res.setBackgroundOpaque(glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_TYPE, tmp, 0) == GLX.GLX_NONE);
+ if(!res.isBackgroundOpaque()) {
+ glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_RED_VALUE, tmp, 0);
+ res.setTransparentRedValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]);
+
+ glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_GREEN_VALUE, tmp, 0);
+ res.setTransparentGreenValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]);
+
+ glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_BLUE_VALUE, tmp, 0);
+ res.setTransparentBlueValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]);
+
+ glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_ALPHA_VALUE, tmp, 0);
+ res.setTransparentAlphaValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]);
+ }
+ try {
+ res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE);
+ } catch (Exception e) {}
+ return res;
+ }
+
+ private static String glXGetFBConfigErrorCode(int err) {
+ switch (err) {
+ case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION";
+ case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE";
+ default: return "Unknown error code " + err;
+ }
+ }
+
+ public static int glXGetFBConfig(long display, long cfg, int attrib, int[] tmp, int tmp_offset) {
+ if (display == 0) {
+ throw new GLException("No display connection");
+ }
+ int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp, tmp_offset);
+ if (res != 0) {
+ throw new GLException("glXGetFBConfig("+toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res));
+ }
+ return tmp[tmp_offset];
+ }
+
+ public static int glXFBConfig2FBConfigID(long display, long cfg) {
+ int[] tmpID = new int[1];
+ return glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID, 0);
+ }
+
+ public static long glXFBConfigID2FBConfig(long display, int screen, int id) {
+ int[] attribs = new int[] { GLX.GLX_FBCONFIG_ID, id, 0 };
+ int[] count = { -1 };
+ PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0);
+ if (fbcfgsL == null || fbcfgsL.limit()<1) {
+ return 0;
+ }
+ return fbcfgsL.get(0);
+ }
+
+ // Visual Info
+
+ public static XVisualInfo XVisualID2XVisualInfo(long display, long visualID) {
+ XVisualInfo res = null;
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ try{
+ int[] count = new int[1];
+ XVisualInfo template = XVisualInfo.create();
+ template.setVisualid(visualID);
+ XVisualInfo[] infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualIDMask, template, count, 0);
+ if (infos == null || infos.length == 0) {
+ return null;
+ }
+ res = XVisualInfo.create(infos[0]);
+ } finally {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+ if (DEBUG) {
+ System.err.println("!!! Fetched XVisualInfo for visual ID " + toHexString(visualID));
+ System.err.println("!!! Resulting XVisualInfo: visualid = " + toHexString(res.getVisualid()));
+ }
+ return res;
+ }
+
+ public static GLCapabilities XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info, boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) {
+ int[] tmp = new int[1];
+ int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
+ if (val == 0) {
+ if(DEBUG) {
+ System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL");
+ }
+ return null;
+ }
+ val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0);
+ if (val == 0) {
+ if(DEBUG) {
+ System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA");
+ }
+ return null;
+ }
+ GLCapabilities res = new GLCapabilities(glp);
+ res.setOnscreen (onscreen);
+ res.setPBuffer (usePBuffer);
+ res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
+ res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp, 0) != 0);
+ // Note: use of hardware acceleration is determined by
+ // glXCreateContext, not by the XVisualInfo. Optimistically claim
+ // that all GLCapabilities have the capability to be hardware
+ // accelerated.
+ res.setHardwareAccelerated(true);
+ res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp, 0));
+ res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp, 0));
+ res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp, 0));
+ res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp, 0));
+ res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp, 0));
+ res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp, 0));
+ res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
+ res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
+ res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
+ res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
+ if (isMultisampleEnabled) {
+ res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
+ res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0));
+ }
+ return res;
+ }
+
+ private static String glXGetConfigErrorCode(int err) {
+ switch (err) {
+ case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION";
+ case GLX.GLX_BAD_SCREEN: return "GLX_BAD_SCREEN";
+ case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE";
+ case GLX.GLX_BAD_VISUAL: return "GLX_BAD_VISUAL";
+ default: return "Unknown error code " + err;
+ }
+ }
+
+ public static int glXGetConfig(long display, XVisualInfo info, int attrib, int[] tmp, int tmp_offset) {
+ if (display == 0) {
+ throw new GLException("No display connection");
+ }
+ int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset);
+ if (res != 0) {
+ throw new GLException("glXGetConfig("+toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res));
+ }
+ return tmp[tmp_offset];
+ }
+
+ public static String toHexString(int val) {
+ return "0x"+Integer.toHexString(val);
+ }
+
+ public static String toHexString(long val) {
+ return "0x"+Long.toHexString(val);
+ }
+
+ public String toString() {
+ return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(fbConfigID) +
+ ",\n\trequested " + getRequestedCapabilities()+
+ ",\n\tchosen " + getChosenCapabilities()+
+ "]";
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..e65fb5e90
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import com.jogamp.common.nio.PointerBuffer;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import com.jogamp.nativewindow.impl.x11.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+
+/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
+ are used on X11 platforms. Toolkits will likely need to delegate
+ to this one to change the accepted and returned types of the
+ GraphicsDevice and GraphicsConfiguration abstractions. */
+
+public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+
+ public X11GLXGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ return chooseGraphicsConfigurationStatic(capabilities, chooser, absScreen);
+ }
+
+ /**
+ protected static X11GLXGraphicsConfiguration createDefaultGraphicsConfigurationFBConfig(AbstractGraphicsScreen absScreen, boolean onscreen, boolean usePBuffer) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+ }
+ if (!(absScreen instanceof X11GraphicsScreen)) {
+ throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here");
+ }
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen)absScreen;
+
+ GLProfile glProfile = GLProfile.getDefault();
+ GLCapabilities caps=null;
+ XVisualInfo xvis=null;
+ long fbcfg = 0;
+ int fbid = -1;
+
+ // Utilizing FBConfig
+ //
+ GLCapabilities capsFB = null;
+ long display = x11Screen.getDevice().getHandle();
+
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ X11Lib.XLockDisplay(display);
+ try {
+ int screen = x11Screen.getIndex();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+
+ long visID = X11Lib.DefaultVisualID(display, x11Screen.getIndex());
+ xvis = X11GLXGraphicsConfiguration.XVisualID2XVisualInfo(display, visID);
+ caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, xvis, onscreen, usePBuffer, isMultisampleAvailable);
+
+ int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(caps, true, isMultisampleAvailable, display, screen);
+ int[] count = { -1 };
+ PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0);
+ if (fbcfgsL == null || fbcfgsL.limit()<1) {
+ throw new Exception("Could not fetch FBConfig for "+caps);
+ }
+ fbcfg = fbcfgsL.get(0);
+ capsFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfg, true, onscreen, usePBuffer, isMultisampleAvailable);
+
+ fbid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg);
+
+ xvis = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg);
+ if (xvis==null) {
+ throw new GLException("Error: Choosen FBConfig has no visual");
+ }
+ } catch (Throwable t) {
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+
+ return new X11GLXGraphicsConfiguration(x11Screen, (null!=capsFB)?capsFB:caps, caps, null, xvis, fbcfg, fbid);
+ } */
+
+ protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+ }
+ if (!(absScreen instanceof X11GraphicsScreen)) {
+ throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here");
+ }
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen)absScreen;
+
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if (capabilities == null) {
+ capabilities = new GLCapabilities(null);
+ }
+
+ boolean onscreen = capabilities.isOnscreen();
+ boolean usePBuffer = ((GLCapabilities)capabilities).isPBuffer();
+
+ GLCapabilities caps2 = (GLCapabilities) capabilities.clone();
+ if(!caps2.isOnscreen()) {
+ // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN
+ caps2.setDoubleBuffered(false);
+ }
+
+ X11GLXGraphicsConfiguration res;
+ res = chooseGraphicsConfigurationFBConfig((GLCapabilities) caps2,
+ (GLCapabilitiesChooser) chooser,
+ x11Screen);
+ if(null==res) {
+ if(usePBuffer) {
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+caps2);
+ }
+ res = chooseGraphicsConfigurationXVisual((GLCapabilities) caps2,
+ (GLCapabilitiesChooser) chooser,
+ x11Screen);
+ }
+ if(null==res) {
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for "+caps2);
+ }
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic("+x11Screen+","+caps2+"): "+res);
+ }
+ return res;
+ }
+
+ protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ X11GraphicsScreen x11Screen) {
+ long recommendedFBConfig = 0;
+ int recommendedIndex = -1;
+ GLCapabilities[] caps = null;
+ PointerBuffer fbcfgsL = null;
+ int chosen=-1;
+ int retFBID=-1;
+ XVisualInfo retXVisualInfo = null;
+ GLProfile glProfile = capabilities.getGLProfile();
+ boolean onscreen = capabilities.isOnscreen();
+ boolean usePBuffer = capabilities.isPBuffer();
+
+ // Utilizing FBConfig
+ //
+ AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ long display = absDevice.getHandle();
+
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ try {
+ X11Lib.XLockDisplay(display);
+ try{
+ int screen = x11Screen.getIndex();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+ int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, display, screen);
+ int[] count = { -1 };
+
+ // determine the recommended FBConfig ..
+ fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0);
+ if (fbcfgsL == null || fbcfgsL.limit()<1) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capabilities+"): "+fbcfgsL+", "+count[0]);
+ }
+ } else if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: "+toHexString(fbcfgsL.get(0)));
+ }
+ } else {
+ recommendedFBConfig = fbcfgsL.get(0);
+ }
+
+ // get all, glXChooseFBConfig(.. attribs==null ..) == glXGetFBConfig(..)
+ fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, null, 0, count, 0);
+ if (fbcfgsL == null || fbcfgsL.limit()<1) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]);
+ }
+ return null;
+ }
+
+ // make GLCapabilities and seek the recommendedIndex
+ caps = new GLCapabilities[fbcfgsL.limit()];
+ for (int i = 0; i < fbcfgsL.limit(); i++) {
+ if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid: ("+x11Screen+","+capabilities+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
+ }
+ } else {
+ caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i),
+ false, onscreen, usePBuffer, isMultisampleAvailable);
+ if(caps[i]!=null && recommendedFBConfig==fbcfgsL.get(i)) {
+ recommendedIndex=i;
+ if (DEBUG) {
+ System.err.println("!!! glXChooseFBConfig recommended "+i+", "+caps[i]);
+ }
+ }
+ }
+ }
+
+ if(null==chooser) {
+ chosen = recommendedIndex; // may still be -1 in case nothing was recommended (-1)
+ }
+
+ if (chosen < 0) {
+ if(null==chooser) {
+ // nothing recommended .. so use our default implementation
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
+ try {
+ chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex);
+ } catch (NativeWindowException e) {
+ if(DEBUG) {
+ e.printStackTrace();
+ }
+ chosen = -1;
+ }
+ }
+ if (chosen < 0) {
+ // keep on going ..
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first");
+ }
+ // seek first available one ..
+ for(chosen = 0; chosen < caps.length && caps[chosen]==null; chosen++) ;
+ if(chosen==caps.length) {
+ // give up ..
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out");
+ }
+ return null;
+ }
+ } else if (chosen >= caps.length) {
+ if(DEBUG) {
+ System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ", got "+chosen+")");
+ }
+ return null;
+ }
+
+ retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen));
+
+ retXVisualInfo = GLX.glXGetVisualFromFBConfigCopied(display, fbcfgsL.get(chosen));
+ if (retXVisualInfo==null) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosen) +" (Continue: "+(false==caps[chosen].isOnscreen())+"):\n\t"+caps[chosen]);
+ }
+ if(caps[chosen].isOnscreen()) {
+ // Onscreen drawables shall have a XVisual ..
+ return null;
+ }
+ }
+ }finally{
+ X11Lib.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+
+ return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, fbcfgsL.get(chosen), retFBID);
+ }
+
+ protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ X11GraphicsScreen x11Screen) {
+ if (chooser == null) {
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
+
+ // Until we have a rock-solid visual selection algorithm written
+ // in pure Java, we're going to provide the underlying window
+ // system's selection to the chooser as a hint
+
+ GLProfile glProfile = capabilities.getGLProfile();
+ boolean onscreen = capabilities.isOnscreen();
+ GLCapabilities[] caps = null;
+ int recommendedIndex = -1;
+ XVisualInfo retXVisualInfo = null;
+ int chosen=-1;
+
+ AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ long display = absDevice.getHandle();
+
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ try {
+ X11Lib.XLockDisplay(display);
+ try{
+ int screen = x11Screen.getIndex();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+ int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, display, screen);
+ XVisualInfo[] infos = null;
+
+ XVisualInfo recommendedVis = GLX.glXChooseVisualCopied(display, screen, attribs, 0);
+ if (DEBUG) {
+ System.err.print("!!! glXChooseVisual recommended ");
+ if (recommendedVis == null) {
+ System.err.println("null visual");
+ } else {
+ System.err.println("visual id " + toHexString(recommendedVis.getVisualid()));
+ }
+ }
+ int[] count = new int[1];
+ XVisualInfo template = XVisualInfo.create();
+ template.setScreen(screen);
+ infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualScreenMask, template, count, 0);
+ if (infos == null || infos.length<1) {
+ throw new GLException("Error while enumerating available XVisualInfos");
+ }
+ caps = new GLCapabilities[infos.length];
+ for (int i = 0; i < infos.length; i++) {
+ caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable);
+ // Attempt to find the visual chosen by glXChooseVisual
+ if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) {
+ recommendedIndex = i;
+ }
+ }
+ try {
+ chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex);
+ } catch (NativeWindowException e) {
+ if(DEBUG) {
+ e.printStackTrace();
+ }
+ chosen = -1;
+ }
+ if (chosen < 0) {
+ // keep on going ..
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual Failed .. unable to choose config, using first");
+ }
+ chosen = 0; // default ..
+ } else if (chosen >= caps.length) {
+ throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
+ }
+ if (infos[chosen] == null) {
+ throw new GLException("GLCapabilitiesChooser chose an invalid visual for "+caps[chosen]);
+ }
+ retXVisualInfo = XVisualInfo.create(infos[chosen]);
+ }finally{
+ X11Lib.XUnlockDisplay(display);
+ }
+ } finally {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+ return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, 0, -1);
+ }
+
+ public static String toHexString(int val) {
+ return "0x"+Integer.toHexString(val);
+ }
+
+ public static String toHexString(long val) {
+ return "0x"+Long.toHexString(val);
+ }
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java
new file mode 100644
index 000000000..bea953ee9
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.*;
+
+public class X11OffscreenGLXContext extends X11GLXContext {
+ private X11OffscreenGLXDrawable drawable;
+
+ public X11OffscreenGLXContext(X11OffscreenGLXDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ GL gl = getGL();
+ return gl.isGL2GL3()?GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV:GL.GL_UNSIGNED_SHORT_5_5_5_1;
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ GLCapabilities caps = (GLCapabilities)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ if (caps.getDoubleBuffered()) {
+ return GL.GL_BACK;
+ }
+ return GL.GL_FRONT;
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ // There doesn't seem to be a way to do this in the construction
+ // of the Pixmap or GLXPixmap
+ return true;
+ }
+
+ protected void create() {
+ createContext(false);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java
new file mode 100644
index 000000000..14d07e74f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.nativewindow.impl.x11.*;
+
+public class X11OffscreenGLXDrawable extends X11GLXDrawable {
+ private long pixmap;
+
+ protected X11OffscreenGLXDrawable(GLDrawableFactory factory, NativeWindow target) {
+ super(factory, target, true);
+ create();
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ create();
+ } else {
+ destroy();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11OffscreenGLXContext(this, shareWith);
+ }
+
+ private void create() {
+ NativeWindow nw = getNativeWindow();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ XVisualInfo vis = config.getXVisualInfo();
+ int bitsPerPixel = vis.getDepth();
+ AbstractGraphicsScreen aScreen = config.getScreen();
+ AbstractGraphicsDevice aDevice = aScreen.getDevice();
+ long dpy = aDevice.getHandle();
+ int screen = aScreen.getIndex();
+
+ getFactoryImpl().lockToolkit();
+ try {
+ X11Lib.XLockDisplay(dpy);
+ try{
+
+ pixmap = X11Lib.XCreatePixmap(dpy, X11Lib.RootWindow(dpy, screen),
+ component.getWidth(), component.getHeight(), bitsPerPixel);
+ if (pixmap == 0) {
+ throw new GLException("XCreatePixmap failed");
+ }
+ long drawable = GLX.glXCreateGLXPixmap(dpy, vis, pixmap);
+ if (drawable == 0) {
+ X11Lib.XFreePixmap(dpy, pixmap);
+ pixmap = 0;
+ throw new GLException("glXCreateGLXPixmap failed");
+ }
+ ((SurfaceChangeable)nw).setSurfaceHandle(drawable);
+ if (DEBUG) {
+ System.err.println("Created pixmap " + toHexString(pixmap) +
+ ", GLXPixmap " + toHexString(drawable) +
+ ", display " + toHexString(dpy));
+ }
+ }finally{
+ X11Lib.XUnlockDisplay(dpy);
+ }
+ } finally {
+ getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ public void destroy() {
+ if (pixmap == 0) return;
+
+ NativeWindow nw = getNativeWindow();
+ long display = nw.getDisplayHandle();
+
+ getFactoryImpl().lockToolkit();
+ try {
+ X11Lib.XLockDisplay(display);
+ try{
+ long drawable = nw.getSurfaceHandle();
+ if (DEBUG) {
+ System.err.println("Destroying pixmap " + toHexString(pixmap) +
+ ", GLXPixmap " + toHexString(drawable) +
+ ", display " + toHexString(display));
+ }
+
+ // Must destroy pixmap and GLXPixmap
+
+ if (DEBUG) {
+ long cur = GLX.glXGetCurrentContext();
+ if (cur != 0) {
+ System.err.println("WARNING: found context " + toHexString(cur) + " current during pixmap destruction");
+ }
+ }
+
+ // FIXME: workaround for crashes on NVidia hardware when
+ // destroying pixmap (no context is current at the point of the
+ // crash, at least from the point of view of
+ // glXGetCurrentContext)
+ GLX.glXMakeCurrent(display, 0, 0);
+
+ GLX.glXDestroyGLXPixmap(display, drawable);
+ X11Lib.XFreePixmap(display, pixmap);
+ drawable = 0;
+ pixmap = 0;
+ ((SurfaceChangeable)nw).setSurfaceHandle(0);
+
+ }finally{
+ X11Lib.XUnlockDisplay(display);
+ }
+ } finally {
+ getFactoryImpl().unlockToolkit();
+ display = 0;
+ }
+ }
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java
new file mode 100644
index 000000000..c89a5efd5
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import java.util.*;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.*;
+
+public class X11OnscreenGLXContext extends X11GLXContext {
+ // This indicates whether the context we have created is indirect
+ // and therefore requires the toolkit to be locked around all GL
+ // calls rather than just all GLX calls
+ protected boolean isIndirect;
+
+ public X11OnscreenGLXContext(X11OnscreenGLXDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ public boolean isOptimizable() {
+ return super.isOptimizable() && !isIndirect;
+ }
+
+ protected void create() {
+ createContext(true);
+ isIndirect = !GLX.glXIsDirect(drawable.getNativeWindow().getDisplayHandle(), context);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java
new file mode 100644
index 000000000..43468b858
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.*;
+
+public class X11OnscreenGLXDrawable extends X11GLXDrawable {
+ protected X11OnscreenGLXDrawable(GLDrawableFactory factory, NativeWindow component) {
+ super(factory, component, false);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11OnscreenGLXContext(this, shareWith);
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java
new file mode 100644
index 000000000..1b70adf6b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.*;
+
+public class X11PbufferGLXContext extends X11GLXContext {
+ private X11PbufferGLXDrawable drawable;
+
+ public X11PbufferGLXContext(X11PbufferGLXDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ public void bindPbufferToTexture() {
+ // FIXME: figure out how to implement this
+ throw new GLException("Not yet implemented");
+ }
+
+ public void releasePbufferFromTexture() {
+ // FIXME: figure out how to implement this
+ throw new GLException("Not yet implemented");
+ }
+
+
+ public int getFloatingPointMode() {
+ return drawable.getFloatingPointMode();
+ }
+
+ protected void create() {
+ createContext(true);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java
new file mode 100644
index 000000000..50b32b9ec
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.glx.*;
+import com.jogamp.nativewindow.impl.x11.*;
+
+public class X11PbufferGLXDrawable extends X11GLXDrawable {
+ protected X11PbufferGLXDrawable(GLDrawableFactory factory, NativeWindow target) {
+ /* GLCapabilities caps,
+ GLCapabilitiesChooser chooser,
+ int width, int height */
+ super(factory, target, true);
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration());
+ }
+
+ createPbuffer();
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + this);
+ }
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ createPbuffer();
+ } else {
+ destroy();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11PbufferGLXContext(this, shareWith);
+ }
+
+ public void destroy() {
+ getFactoryImpl().lockToolkit();
+ try {
+ NativeWindow nw = getNativeWindow();
+ if (nw.getSurfaceHandle() != 0) {
+ GLX.glXDestroyPbuffer(nw.getDisplayHandle(), nw.getSurfaceHandle());
+ }
+ ((SurfaceChangeable)nw).setSurfaceHandle(0);
+ } finally {
+ getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ private void createPbuffer() {
+ getFactoryImpl().lockToolkit();
+ try {
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsScreen aScreen = config.getScreen();
+ AbstractGraphicsDevice aDevice = aScreen.getDevice();
+ long display = aDevice.getHandle();
+ int screen = aScreen.getIndex();
+
+ if (display==0) {
+ throw new GLException("Null display");
+ }
+
+ NativeWindow nw = getNativeWindow();
+
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+
+ if (capabilities.getPbufferRenderToTexture()) {
+ throw new GLException("Render-to-texture pbuffers not supported yet on X11");
+ }
+
+ if (capabilities.getPbufferRenderToTextureRectangle()) {
+ throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11");
+ }
+
+ // Create the p-buffer.
+ int niattribs = 0;
+ int[] iattributes = new int[5];
+
+ iattributes[niattribs++] = GLX.GLX_PBUFFER_WIDTH;
+ iattributes[niattribs++] = nw.getWidth();
+ iattributes[niattribs++] = GLX.GLX_PBUFFER_HEIGHT;
+ iattributes[niattribs++] = nw.getHeight();
+ iattributes[niattribs++] = 0;
+
+ long pbuffer = GLX.glXCreatePbuffer(display, config.getFBConfig(), iattributes, 0);
+ if (pbuffer == 0) {
+ // FIXME: query X error code for detail error message
+ throw new GLException("pbuffer creation error: glXCreatePbuffer() failed");
+ }
+
+ // Set up instance variables
+ ((SurfaceChangeable)nw).setSurfaceHandle(pbuffer);
+
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_WIDTH, tmp, 0);
+ int width = tmp[0];
+ GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_HEIGHT, tmp, 0);
+ int height = tmp[0];
+ ((SurfaceChangeable)nw).setSize(width, height);
+ } finally {
+ getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ public int getFloatingPointMode() {
+ // Floating-point pbuffers currently require NVidia hardware on X11
+ return GLPbuffer.NV_FLOAT;
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..dc6c60664
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.impl.x11.glx.awt;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.nativewindow.awt.*;
+import javax.media.opengl.*;
+import javax.media.opengl.awt.*;
+
+import com.jogamp.opengl.impl.*;
+import com.jogamp.nativewindow.impl.jawt.*;
+import com.jogamp.nativewindow.impl.jawt.x11.*;
+import com.jogamp.nativewindow.impl.x11.*;
+import com.jogamp.opengl.impl.x11.*;
+import com.jogamp.opengl.impl.x11.glx.*;
+
+public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+
+ public X11AWTGLXGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ GraphicsDevice device = null;
+ if (absScreen != null &&
+ !(absScreen instanceof AWTGraphicsScreen)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
+ }
+
+ if(null==absScreen) {
+ absScreen = AWTGraphicsScreen.createScreenDevice(-1);
+ }
+ AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen;
+ device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if(DEBUG) {
+ System.err.println("X11AWTGLXGraphicsConfigurationFactory: got "+absScreen);
+ }
+
+ GraphicsConfiguration gc;
+ X11GraphicsConfiguration x11Config;
+
+ // Need the lock here, since it could be an AWT owned display connection
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ try {
+ long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
+ if(0==displayHandle) {
+ displayHandle = X11Util.createThreadLocalDefaultDisplay();
+ if(DEBUG) {
+ System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display");
+ }
+ } else {
+ if(DEBUG) {
+ System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle));
+ }
+ }
+ ((AWTGraphicsDevice)awtScreen.getDevice()).setHandle(displayHandle);
+ X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle);
+
+ X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex());
+ if(DEBUG) {
+ System.err.println("X11AWTGLXGraphicsConfigurationFactory: made "+x11Screen);
+ }
+
+ gc = device.getDefaultConfiguration();
+ AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capabilities, gc);
+ if(DEBUG) {
+ System.err.println("AWT Colormodel compatible: "+capabilities);
+ }
+
+ x11Config = (X11GraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(x11Device).chooseGraphicsConfiguration(capabilities,
+ chooser,
+ x11Screen);
+ if (x11Config == null) {
+ throw new GLException("Unable to choose a GraphicsConfiguration: "+capabilities+",\n\t"+chooser+"\n\t"+x11Screen);
+ }
+
+ long visualID = x11Config.getVisualID();
+ // Now figure out which GraphicsConfiguration corresponds to this
+ // visual by matching the visual ID
+ GraphicsConfiguration[] configs = device.getConfigurations();
+ for (int i = 0; i < configs.length; i++) {
+ GraphicsConfiguration config = configs[i];
+ if (config != null) {
+ if (X11SunJDKReflection.graphicsConfigurationGetVisualID(config) == visualID) {
+ return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(),
+ config, x11Config);
+ }
+ }
+ }
+ } finally {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+ // Either we weren't able to reflectively introspect on the
+ // X11GraphicsConfig or something went wrong in the steps above;
+ // Let's take the default configuration as used on Windows and MacOSX then ..
+ if(DEBUG) {
+ System.err.println("!!! Using default configuration");
+ }
+ return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), gc, x11Config);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
new file mode 100644
index 000000000..d8e1cf080
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.util;
+
+import java.awt.Component;
+import java.awt.EventQueue;
+import java.awt.Rectangle;
+import java.util.*;
+import javax.swing.*;
+
+import javax.media.opengl.*;
+
+/** Abstraction to factor out AWT dependencies from the Animator's
+ implementation in a way that still allows the FPSAnimator to pick
+ up this behavior if desired. */
+
+class AWTAnimatorImpl extends AnimatorImpl {
+ // For efficient rendering of Swing components, in particular when
+ // they overlap one another
+ private List lightweights = new ArrayList();
+ private Map repaintManagers = new IdentityHashMap();
+ private Map dirtyRegions = new IdentityHashMap();
+
+ public void display(Animator animator,
+ boolean ignoreExceptions,
+ boolean printExceptions) {
+ Iterator iter = animator.drawableIterator();
+ while (iter.hasNext()) {
+ GLAutoDrawable drawable = (GLAutoDrawable) iter.next();
+ if (drawable instanceof JComponent) {
+ // Lightweight components need a more efficient drawing
+ // scheme than simply forcing repainting of each one in
+ // turn since drawing one can force another one to be
+ // drawn in turn
+ lightweights.add(drawable);
+ } else {
+ try {
+ drawable.display();
+ } catch (RuntimeException e) {
+ if (ignoreExceptions) {
+ if (printExceptions) {
+ e.printStackTrace();
+ }
+ } else {
+ throw(e);
+ }
+ }
+ }
+ }
+ if (lightweights.size() > 0) {
+ try {
+ SwingUtilities.invokeAndWait(drawWithRepaintManagerRunnable);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ lightweights.clear();
+ }
+ }
+
+ // Uses RepaintManager APIs to implement more efficient redrawing of
+ // the Swing widgets we're animating
+ private Runnable drawWithRepaintManagerRunnable = new Runnable() {
+ public void run() {
+ for (Iterator iter = lightweights.iterator(); iter.hasNext(); ) {
+ JComponent comp = (JComponent) iter.next();
+ RepaintManager rm = RepaintManager.currentManager(comp);
+ rm.markCompletelyDirty(comp);
+ repaintManagers.put(rm, rm);
+
+ // RepaintManagers don't currently optimize the case of
+ // overlapping sibling components. If we have two
+ // JInternalFrames in a JDesktopPane, the redraw of the
+ // bottom one will cause the top one to be redrawn as
+ // well. The top one will then be redrawn separately. In
+ // order to optimize this case we need to compute the union
+ // of all of the dirty regions on a particular JComponent if
+ // optimized drawing isn't enabled for it.
+
+ // Walk up the hierarchy trying to find a non-optimizable
+ // ancestor
+ Rectangle visible = comp.getVisibleRect();
+ int x = visible.x;
+ int y = visible.y;
+ while (comp != null) {
+ x += comp.getX();
+ y += comp.getY();
+ Component c = comp.getParent();
+ if ((c == null) || (!(c instanceof JComponent))) {
+ comp = null;
+ } else {
+ comp = (JComponent) c;
+ if (!comp.isOptimizedDrawingEnabled()) {
+ rm = RepaintManager.currentManager(comp);
+ repaintManagers.put(rm, rm);
+ // Need to dirty this region
+ Rectangle dirty = (Rectangle) dirtyRegions.get(comp);
+ if (dirty == null) {
+ dirty = new Rectangle(x, y, visible.width, visible.height);
+ dirtyRegions.put(comp, dirty);
+ } else {
+ // Compute union with already dirty region
+ // Note we could compute multiple non-overlapping
+ // regions: might want to do that in the future
+ // (prob. need more complex algorithm -- dynamic
+ // programming?)
+ dirty.add(new Rectangle(x, y, visible.width, visible.height));
+ }
+ }
+ }
+ }
+ }
+
+ // Dirty any needed regions on non-optimizable components
+ for (Iterator iter = dirtyRegions.keySet().iterator(); iter.hasNext(); ) {
+ JComponent comp = (JComponent) iter.next();
+ Rectangle rect = (Rectangle) dirtyRegions.get(comp);
+ RepaintManager rm = RepaintManager.currentManager(comp);
+ rm.addDirtyRegion(comp, rect.x, rect.y, rect.width, rect.height);
+ }
+
+ // Draw all dirty regions
+ for (Iterator iter = repaintManagers.keySet().iterator(); iter.hasNext(); ) {
+ ((RepaintManager) iter.next()).paintDirtyRegions();
+ }
+ dirtyRegions.clear();
+ repaintManagers.clear();
+ }
+ };
+
+ public boolean skipWaitForStop(Thread thread) {
+ return ((Thread.currentThread() == thread) || EventQueue.isDispatchThread());
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
new file mode 100755
index 000000000..30be0bd90
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util;
+
+import java.util.*;
+
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.impl.Debug;
+
+/** <P> An Animator can be attached to one or more {@link
+ GLAutoDrawable}s to drive their display() methods in a loop. </P>
+
+ <P> The Animator class creates a background thread in which the
+ calls to <code>display()</code> are performed. After each drawable
+ has been redrawn, a brief pause is performed to avoid swamping the
+ CPU, unless {@link #setRunAsFastAsPossible} has been called. </P>
+*/
+
+public class Animator {
+ protected static final boolean DEBUG = Debug.debug("Animator");
+
+ private volatile ArrayList/*<GLAutoDrawable>*/ drawables = new ArrayList();
+ private AnimatorImpl impl;
+ private Runnable runnable;
+ private boolean runAsFastAsPossible;
+ protected ThreadGroup threadGroup;
+ protected Thread thread;
+ protected volatile boolean shouldStop;
+ protected boolean ignoreExceptions;
+ protected boolean printExceptions;
+
+ /** Creates a new, empty Animator. */
+ public Animator(ThreadGroup tg) {
+
+ if(GLProfile.isAWTJOGLAvailable()) {
+ try {
+ impl = (AnimatorImpl) Class.forName("com.jogamp.opengl.util.awt.AWTAnimatorImpl").newInstance();
+ } catch (Exception e) { }
+ }
+ if(null==impl) {
+ impl = new AnimatorImpl();
+ }
+ threadGroup = tg;
+
+ if(DEBUG) {
+ System.out.println("Animator created, ThreadGroup: "+threadGroup);
+ }
+ }
+
+ public Animator() {
+ this((ThreadGroup)null);
+ }
+
+ /** Creates a new Animator for a particular drawable. */
+ public Animator(GLAutoDrawable drawable) {
+ this((ThreadGroup)null);
+ add(drawable);
+ }
+
+ /** Creates a new Animator for a particular drawable. */
+ public Animator(ThreadGroup tg, GLAutoDrawable drawable) {
+ this(tg);
+ add(drawable);
+ }
+
+ /** Adds a drawable to the list managed by this Animator. */
+ public synchronized void add(GLAutoDrawable drawable) {
+ ArrayList newList = (ArrayList) drawables.clone();
+ newList.add(drawable);
+ drawables = newList;
+ notifyAll();
+ }
+
+ /** Removes a drawable from the list managed by this Animator. */
+ public synchronized void remove(GLAutoDrawable drawable) {
+ ArrayList newList = (ArrayList) drawables.clone();
+ newList.remove(drawable);
+ drawables = newList;
+ }
+
+ /** Returns an iterator over the drawables managed by this
+ Animator. */
+ public Iterator/*<GLAutoDrawable>*/ drawableIterator() {
+ return drawables.iterator();
+ }
+
+ /** Sets a flag causing this Animator to ignore exceptions produced
+ while redrawing the drawables. By default this flag is set to
+ false, causing any exception thrown to halt the Animator. */
+ public void setIgnoreExceptions(boolean ignoreExceptions) {
+ this.ignoreExceptions = ignoreExceptions;
+ }
+
+ /** Sets a flag indicating that when exceptions are being ignored by
+ this Animator (see {@link #setIgnoreExceptions}), to print the
+ exceptions' stack traces for diagnostic information. Defaults to
+ false. */
+ public void setPrintExceptions(boolean printExceptions) {
+ this.printExceptions = printExceptions;
+ }
+
+ /** Sets a flag in this Animator indicating that it is to run as
+ fast as possible. By default there is a brief pause in the
+ animation loop which prevents the CPU from getting swamped.
+ This method may not have an effect on subclasses. */
+ public final void setRunAsFastAsPossible(boolean runFast) {
+ runAsFastAsPossible = runFast;
+ }
+
+ /** Called every frame to cause redrawing of all of the
+ GLAutoDrawables this Animator manages. Subclasses should call
+ this to get the most optimized painting behavior for the set of
+ components this Animator manages, in particular when multiple
+ lightweight widgets are continually being redrawn. */
+ protected void display() {
+ impl.display(this, ignoreExceptions, printExceptions);
+ }
+
+ class MainLoop implements Runnable {
+ public void run() {
+ try {
+ if(DEBUG) {
+ System.out.println("Animator started: "+Thread.currentThread());
+ }
+ while (!shouldStop) {
+ // Don't consume CPU unless there is work to be done
+ if (drawables.size() == 0) {
+ synchronized (Animator.this) {
+ while (drawables.size() == 0 && !shouldStop) {
+ try {
+ Animator.this.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+ display();
+ if (!runAsFastAsPossible) {
+ // Avoid swamping the CPU
+ Thread.yield();
+ }
+ }
+ if(DEBUG) {
+ System.out.println("Animator stopped: "+Thread.currentThread());
+ }
+ } finally {
+ shouldStop = false;
+ synchronized (Animator.this) {
+ thread = null;
+ Animator.this.notify();
+ }
+ }
+ }
+ }
+
+ /** Starts this animator. */
+ public synchronized void start() {
+ if (thread != null) {
+ throw new GLException("Already started");
+ }
+ if (runnable == null) {
+ runnable = new MainLoop();
+ }
+ if(null==threadGroup) {
+ thread = new Thread(runnable);
+ } else {
+ thread = new Thread(threadGroup, runnable);
+ }
+ thread.start();
+ }
+
+ /** Indicates whether this animator is currently running. This
+ should only be used as a heuristic to applications because in
+ some circumstances the Animator may be in the process of
+ shutting down and this method will still return true. */
+ public synchronized boolean isAnimating() {
+ return (thread != null);
+ }
+
+ /** Stops this animator. In most situations this method blocks until
+ completion, except when called from the animation thread itself
+ or in some cases from an implementation-internal thread like the
+ AWT event queue thread. */
+ public synchronized void stop() {
+ shouldStop = true;
+ notifyAll();
+
+ // It's hard to tell whether the thread which calls stop() has
+ // dependencies on the Animator's internal thread. Currently we
+ // use a couple of heuristics to determine whether we should do
+ // the blocking wait().
+ if (impl.skipWaitForStop(thread)) {
+ return;
+ }
+
+ while (shouldStop && thread != null) {
+ try {
+ wait();
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorImpl.java
new file mode 100644
index 000000000..50b91b729
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorImpl.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+package com.jogamp.opengl.util;
+
+import java.util.*;
+import javax.media.opengl.*;
+
+/** Abstraction to factor out AWT dependencies from the Animator's
+ implementation in a way that still allows the FPSAnimator to pick
+ up this behavior if desired. */
+
+class AnimatorImpl {
+ public void display(Animator animator,
+ boolean ignoreExceptions,
+ boolean printExceptions) {
+ Iterator iter = animator.drawableIterator();
+ while (iter.hasNext()) {
+ GLAutoDrawable drawable = (GLAutoDrawable) iter.next();
+ try {
+ drawable.display();
+ } catch (RuntimeException e) {
+ if (ignoreExceptions) {
+ if (printExceptions) {
+ e.printStackTrace();
+ }
+ } else {
+ throw(e);
+ }
+ }
+ }
+ }
+
+ public boolean skipWaitForStop(Thread thread) {
+ return (Thread.currentThread() == thread);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/FBObject.java b/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
new file mode 100755
index 000000000..4920ed5f5
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.opengl.util;
+
+import javax.media.opengl.*;
+
+public class FBObject {
+ private int width, height, attr;
+ private int fb, fbo_tex, depth_rb, stencil_rb, vStatus;
+ private int texInternalFormat, texDataFormat, texDataType;
+
+ public static final int ATTR_DEPTH = 1 << 0;
+ public static final int ATTR_STENCIL = 1 << 1;
+
+ public FBObject(int width, int height, int attributes) {
+ this.width = width;
+ this.height = height;
+ this.attr = attributes;
+ }
+
+
+ public boolean validateStatus(GL gl) {
+ vStatus = getStatus(gl, fb);
+ switch(vStatus) {
+ case GL.GL_FRAMEBUFFER_COMPLETE:
+ return true;
+ case GL.GL_FRAMEBUFFER_UNSUPPORTED:
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
+ //case GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+ //case GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+ //case GL2.GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
+ case 0:
+ default:
+ return false;
+ }
+ }
+
+ public static int getStatus(GL gl, int fb) {
+ if(!gl.glIsFramebuffer(fb)) {
+ return -1;
+ }
+ return gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER);
+ //return gl.glCheckFramebufferStatus(fb);
+ }
+
+ public String getStatusString() {
+ return getStatusString(vStatus);
+ }
+
+ public static String getStatusString(int fbStatus) {
+ switch(fbStatus) {
+ case -1:
+ return "NOT A FBO";
+ case GL.GL_FRAMEBUFFER_COMPLETE:
+ return "OK";
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ return("GL FBO: incomplete,incomplete attachment\n");
+ case GL.GL_FRAMEBUFFER_UNSUPPORTED:
+ return("GL FBO: Unsupported framebuffer format");
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ return("GL FBO: incomplete,missing attachment");
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+ return("GL FBO: incomplete,attached images must have same dimensions");
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
+ return("GL FBO: incomplete,attached images must have same format");
+ /*
+ case GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+ return("GL FBO: incomplete,missing draw buffer");
+ case GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+ return("GL FBO: incomplete,missing read buffer");
+ case GL2.GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
+ return("GL FBO: incomplete, duplicate attachment");
+ */
+ case 0:
+ return("GL FBO: incomplete, implementation fault");
+ default:
+ return("GL FBO: incomplete, implementation ERROR");
+ }
+ }
+
+ public void init(GL gl) {
+ int textureInternalFormat, textureDataFormat, textureDataType;
+
+ if(gl.isGL2()) {
+ textureInternalFormat=GL.GL_RGBA8;
+ textureDataFormat=GL2.GL_BGRA;
+ textureDataType=GL2.GL_UNSIGNED_INT_8_8_8_8_REV;
+ } else if(gl.isGLES()) {
+ textureInternalFormat=GL.GL_RGBA;
+ textureDataFormat=GL.GL_RGBA;
+ textureDataType=GL.GL_UNSIGNED_BYTE;
+ } else {
+ textureInternalFormat=GL.GL_RGB;
+ textureDataFormat=GL.GL_RGB;
+ textureDataType=GL.GL_UNSIGNED_BYTE;
+ }
+ init(gl, textureInternalFormat, textureDataFormat, textureDataType);
+ }
+
+ public void init(GL gl, int textureInternalFormat, int textureDataFormat, int textureDataType) {
+ texInternalFormat=textureInternalFormat;
+ texDataFormat=textureDataFormat;
+ texDataType=textureDataType;
+
+ // generate fbo ..
+ int name[] = new int[1];
+
+ gl.glGenFramebuffers(1, name, 0);
+ fb = name[0];
+ System.out.println("fb: "+fb);
+
+ gl.glGenTextures(1, name, 0);
+ fbo_tex = name[0];
+ System.out.println("fbo_tex: "+fbo_tex);
+
+ if(0!=(attr&ATTR_DEPTH)) {
+ gl.glGenRenderbuffers(1, name, 0);
+ depth_rb = name[0];
+ System.out.println("depth_rb: "+depth_rb);
+ } else {
+ depth_rb = 0;
+ }
+ if(0!=(attr&ATTR_STENCIL)) {
+ gl.glGenRenderbuffers(1, name, 0);
+ stencil_rb = name[0];
+ System.out.println("stencil_rb: "+stencil_rb);
+ } else {
+ stencil_rb = 0;
+ }
+
+ // bind fbo ..
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb);
+
+ gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex);
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, texInternalFormat, width, height, 0,
+ texDataFormat, texDataType, null);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ //gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP);
+ //gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP);
+
+
+ // Set up the color buffer for use as a renderable texture:
+ gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0,
+ GL.GL_TEXTURE_2D, fbo_tex, 0);
+
+ if(depth_rb!=0) {
+ // Initialize the depth buffer:
+ gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, depth_rb);
+ gl.glRenderbufferStorage(GL.GL_RENDERBUFFER,
+ GL.GL_DEPTH_COMPONENT16, width, height);
+ // Set up the depth buffer attachment:
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_DEPTH_ATTACHMENT,
+ GL.GL_RENDERBUFFER, depth_rb);
+ }
+
+ if(stencil_rb!=0) {
+ // Initialize the stencil buffer:
+ gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, stencil_rb);
+ gl.glRenderbufferStorage(GL.GL_RENDERBUFFER,
+ GL.GL_STENCIL_INDEX8, width, height);
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_STENCIL_ATTACHMENT,
+ GL.GL_RENDERBUFFER, stencil_rb);
+ }
+
+ // Check the FBO for completeness
+ if(validateStatus(gl)) {
+ System.out.println("Framebuffer " + fb + " is complete");
+ } else {
+ System.out.println("Framebuffer " + fb + " is incomplete: status = 0x" + Integer.toHexString(vStatus) +
+ " : " + getStatusString());
+ }
+
+ unbind(gl);
+ }
+
+ public void destroy(GL gl) {
+ unbind(gl);
+
+ int name[] = new int[1];
+
+ if(0!=stencil_rb) {
+ name[0] = stencil_rb;
+ gl.glDeleteRenderbuffers(1, name, 0);
+ stencil_rb = 0;
+ }
+ if(0!=depth_rb) {
+ name[0] = depth_rb;
+ gl.glDeleteRenderbuffers(1, name, 0);
+ depth_rb=0;
+ }
+ if(0!=fbo_tex) {
+ name[0] = fbo_tex;
+ gl.glDeleteTextures(1, name, 0);
+ fbo_tex = 0;
+ }
+ if(0!=fb) {
+ name[0] = fb;
+ gl.glDeleteFramebuffers(1, name, 0);
+ fb = 0;
+ }
+ }
+
+ public void bind(GL gl) {
+ gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex);
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb);
+ }
+
+ public void unbind(GL gl) {
+ gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0);
+ }
+
+ public void use(GL gl) {
+ gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex); // to use it ..
+ }
+
+ public int getFBName() {
+ return fb;
+ }
+ public int getTextureName() {
+ return fbo_tex;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java b/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java
new file mode 100755
index 000000000..75c4cdff7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util;
+
+import java.util.*;
+import javax.media.opengl.*;
+
+/** An Animator subclass which attempts to achieve a target
+ frames-per-second rate to avoid using all CPU time. The target FPS
+ is only an estimate and is not guaranteed. */
+
+public class FPSAnimator extends Animator {
+ private Timer timer;
+ private int fps;
+ private boolean scheduleAtFixedRate;
+
+ /** Creates an FPSAnimator with a given target frames-per-second
+ value. Equivalent to <code>FPSAnimator(null, fps)</code>. */
+ public FPSAnimator(int fps) {
+ this(null, fps);
+ }
+
+ /** Creates an FPSAnimator with a given target frames-per-second
+ value and a flag indicating whether to use fixed-rate
+ scheduling. Equivalent to <code>FPSAnimator(null, fps,
+ scheduleAtFixedRate)</code>. */
+ public FPSAnimator(int fps, boolean scheduleAtFixedRate) {
+ this(null, fps, scheduleAtFixedRate);
+ }
+
+ /** Creates an FPSAnimator with a given target frames-per-second
+ value and an initial drawable to animate. Equivalent to
+ <code>FPSAnimator(null, fps, false)</code>. */
+ public FPSAnimator(GLAutoDrawable drawable, int fps) {
+ this(drawable, fps, false);
+ }
+
+ /** Creates an FPSAnimator with a given target frames-per-second
+ value, an initial drawable to animate, and a flag indicating
+ whether to use fixed-rate scheduling. */
+ public FPSAnimator(GLAutoDrawable drawable, int fps, boolean scheduleAtFixedRate) {
+ this.fps = fps;
+ if (drawable != null) {
+ add(drawable);
+ }
+ this.scheduleAtFixedRate = scheduleAtFixedRate;
+ }
+
+ /** Starts this FPSAnimator. */
+ public synchronized void start() {
+ if (timer != null) {
+ throw new GLException("Already started");
+ }
+ timer = new Timer();
+ long delay = (long) (1000.0f / (float) fps);
+ TimerTask task = new TimerTask() {
+ public void run() {
+ display();
+ }
+ };
+ if (scheduleAtFixedRate) {
+ timer.scheduleAtFixedRate(task, 0, delay);
+ } else {
+ timer.schedule(task, 0, delay);
+ }
+ }
+
+ /** Indicates whether this FPSAnimator is currently running. This
+ should only be used as a heuristic to applications because in
+ some circumstances the FPSAnimator may be in the process of
+ shutting down and this method will still return true. */
+ public synchronized boolean isAnimating() {
+ return (timer != null);
+ }
+
+ /** Stops this FPSAnimator. Due to the implementation of the
+ FPSAnimator it is not guaranteed that the FPSAnimator will be
+ completely stopped by the time this method returns. */
+ public synchronized void stop() {
+ if (timer == null) {
+ throw new GLException("Already stopped");
+ }
+ timer.cancel();
+ timer = null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/FileUtil.java b/src/jogl/classes/com/jogamp/opengl/util/FileUtil.java
new file mode 100755
index 000000000..6ad0da825
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/FileUtil.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util;
+
+import java.io.*;
+
+/** Utilities for dealing with files. */
+
+public class FileUtil {
+ private FileUtil() {}
+
+ /**
+ * Returns the lowercase suffix of the given file name (the text
+ * after the last '.' in the file name). Returns null if the file
+ * name has no suffix. Only operates on the given file name;
+ * performs no I/O operations.
+ *
+ * @param file name of the file
+ * @return lowercase suffix of the file name
+ * @throws NullPointerException if file is null
+ */
+
+ public static String getFileSuffix(File file) {
+ return getFileSuffix(file.getName());
+ }
+
+ /**
+ * Returns the lowercase suffix of the given file name (the text
+ * after the last '.' in the file name). Returns null if the file
+ * name has no suffix. Only operates on the given file name;
+ * performs no I/O operations.
+ *
+ * @param filename name of the file
+ * @return lowercase suffix of the file name
+ * @throws NullPointerException if filename is null
+ */
+ public static String getFileSuffix(String filename) {
+ int lastDot = filename.lastIndexOf('.');
+ if (lastDot < 0) {
+ return null;
+ }
+ return toLowerCase(filename.substring(lastDot + 1));
+ }
+
+ private static String toLowerCase(String arg) {
+ if (arg == null) {
+ return null;
+ }
+
+ return arg.toLowerCase();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/FixedPoint.java b/src/jogl/classes/com/jogamp/opengl/util/FixedPoint.java
new file mode 100644
index 000000000..6412db5ef
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/FixedPoint.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.opengl.util;
+
+public class FixedPoint {
+ public static final int toFixed(int value) {
+ if (value < -32768) value = -32768;
+ if (value > 32767) value = 32767;
+ return value * 65536;
+ }
+
+ public static final int toFixed(float value) {
+ if (value < -32768) value = -32768;
+ if (value > 32767) value = 32767;
+ return (int)(value * 65536.0f);
+ }
+
+ public static final float toFloat(int value) {
+ return (float)value/65536.0f;
+ }
+
+ public static final int mult(int x1, int x2) {
+ return (int) ( ((long)x1*(long)x2)/65536 );
+ }
+
+ public static final int div(int x1, int x2) {
+ return (int) ( (((long)x1)<<16)/x2 );
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
new file mode 100644
index 000000000..1141f6624
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
@@ -0,0 +1,354 @@
+
+package com.jogamp.opengl.util;
+
+import com.jogamp.common.nio.Buffers;
+import java.security.*;
+
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.util.glsl.*;
+
+import com.jogamp.opengl.impl.SystemUtil;
+
+import java.nio.*;
+
+public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayDataEditable {
+
+ /**
+ * The OpenGL ES emulation on the PC probably has a buggy VBO implementation,
+ * where we have to 'refresh' the VertexPointer or VertexAttribArray after each
+ * BindBuffer !
+ *
+ * This should not be necessary on proper native implementations.
+ */
+ public static final boolean hasVBOBug = AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return SystemUtil.getenv("JOGL_VBO_BUG");
+ }
+ }) != null;
+
+ /**
+ * @param index The GL array index
+ * @param name The optional custom name for the GL array index, maybe null.
+ * If null, the default name mapping will be used, see 'getPredefinedArrayIndexName(int)'.
+ * This name might be used as the shader attribute name.
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param normalized Wheather the data shall be normalized
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataClient createFixed(GL gl, int index, String name, int comps, int dataType, boolean normalized,
+ int initialSize)
+ throws GLException
+ {
+ gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true);
+ GLArrayDataClient adc = new GLArrayDataClient();
+ GLArrayHandler glArrayHandler = new GLFixedArrayHandler(adc);
+ adc.init(name, index, comps, dataType, normalized, 0, null, initialSize, false, glArrayHandler, 0, 0);
+ return adc;
+ }
+
+ public static GLArrayDataClient createFixed(GL gl, int index, String name, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer)
+ throws GLException
+ {
+ gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true);
+ GLArrayDataClient adc = new GLArrayDataClient();
+ GLArrayHandler glArrayHandler = new GLFixedArrayHandler(adc);
+ adc.init(name, index, comps, dataType, normalized, stride, buffer, comps*comps, false, glArrayHandler, 0, 0);
+ return adc;
+ }
+
+ public static GLArrayDataClient createGLSL(GL gl, String name, int comps, int dataType, boolean normalized,
+ int initialSize)
+ throws GLException
+ {
+ if(!gl.hasGLSL()) {
+ throw new GLException("GLArrayDataClient.GLSL not supported: "+gl);
+ }
+ gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true);
+
+ GLArrayDataClient adc = new GLArrayDataClient();
+ GLArrayHandler glArrayHandler = new GLSLArrayHandler(adc);
+ adc.init(name, -1, comps, dataType, normalized, 0, null, initialSize, true, glArrayHandler, 0, 0);
+ return adc;
+ }
+
+ public static GLArrayDataClient createGLSL(GL gl, String name, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer)
+ throws GLException
+ {
+ if(!gl.hasGLSL()) {
+ throw new GLException("GLArrayDataClient.GLSL not supported: "+gl);
+ }
+ gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true);
+
+ GLArrayDataClient adc = new GLArrayDataClient();
+ GLArrayHandler glArrayHandler = new GLSLArrayHandler(adc);
+ adc.init(name, -1, comps, dataType, normalized, stride, buffer, comps*comps, true, glArrayHandler, 0, 0);
+ return adc;
+ }
+
+ //
+ // Data read access
+ //
+
+ public final boolean isBufferWritten() { return bufferWritten; }
+
+ public final boolean sealed() { return sealed; }
+
+ public int getBufferUsage() { return -1; }
+
+ //
+ // Data and GL state modification ..
+ //
+
+ public final void setBufferWritten(boolean written) { bufferWritten=written; }
+
+ public void destroy(GL gl) {
+ reset(gl);
+ buffer=null;
+ }
+
+ public void reset(GL gl) {
+ enableBuffer(gl, false);
+ reset();
+ }
+
+ public void seal(GL gl, boolean seal)
+ {
+ seal(seal);
+ if(sealedGL==seal) return;
+ sealedGL = seal;
+ if(seal) {
+ init_vbo(gl);
+
+ enableBuffer(gl, true);
+ } else {
+ enableBuffer(gl, false);
+ }
+ }
+
+ public void enableBuffer(GL gl, boolean enable) {
+ if(enableBufferAlways && enable) {
+ bufferEnabled = false;
+ }
+ if( bufferEnabled != enable && components>0 ) {
+ if(enable) {
+ checkSeal(true);
+ if(null!=buffer) {
+ buffer.rewind();
+ }
+ }
+ glArrayHandler.enableBuffer(gl, enable);
+ bufferEnabled = enable;
+ }
+ }
+
+ public void setEnableAlways(boolean always) {
+ enableBufferAlways = always;
+ }
+
+ //
+ // Data modification ..
+ //
+
+ public void reset() {
+ if(buffer!=null) {
+ buffer.clear();
+ }
+ this.sealed=false;
+ this.bufferEnabled=false;
+ this.bufferWritten=false;
+ }
+
+ public void seal(boolean seal)
+ {
+ if(sealed==seal) return;
+ sealed = seal;
+ if(seal) {
+ bufferWritten=false;
+ if (null!=buffer) {
+ buffer.flip();
+ }
+ } else {
+ if (null!=buffer) {
+ buffer.position(buffer.limit());
+ buffer.limit(buffer.capacity());
+ }
+ }
+ }
+
+
+ public void rewind() {
+ if(buffer!=null) {
+ buffer.rewind();
+ }
+ }
+
+ public void padding(int done) {
+ if ( buffer==null || sealed ) return;
+ while(done<strideL) {
+ Buffers.putb(buffer, (byte)0);
+ done++;
+ }
+ }
+
+ /**
+ * Generic buffer relative put method.
+ *
+ * This class buffer Class must match the arguments buffer class.
+ * The arguments remaining elements must be a multiple of this arrays element stride.
+ */
+ public void put(Buffer v) {
+ if ( buffer==null || sealed ) return;
+ if(0!=(v.remaining() % strideL)) {
+ throw new GLException("Buffer length ("+v.remaining()+") is not a multiple of component-stride:\n\t"+this);
+ }
+ growBufferIfNecessary(v.remaining());
+ Buffers.put(buffer, v);
+ }
+
+ public void putb(byte v) {
+ if ( buffer==null || sealed ) return;
+ growBufferIfNecessary(1);
+ Buffers.putb(buffer, v);
+ }
+
+ public void puts(short v) {
+ if ( buffer==null || sealed ) return;
+ growBufferIfNecessary(1);
+ Buffers.puts(buffer, v);
+ }
+
+ public void puti(int v) {
+ if ( buffer==null || sealed ) return;
+ growBufferIfNecessary(1);
+ Buffers.puti(buffer, v);
+ }
+
+ public void putx(int v) {
+ puti(v);
+ }
+
+ public void putf(float v) {
+ if ( buffer==null || sealed ) return;
+ growBufferIfNecessary(1);
+ Buffers.putf(buffer, v);
+ }
+
+ public String toString() {
+ return "GLArrayDataClient["+name+
+ ", index "+index+
+ ", location "+location+
+ ", isVertexAttribute "+isVertexAttribute+
+ ", dataType "+dataType+
+ ", bufferClazz "+clazz+
+ ", elements "+getElementNumber()+
+ ", components "+components+
+ ", stride "+stride+"u "+strideB+"b "+strideL+"c"+
+ ", initialSize "+initialSize+
+ ", sealed "+sealed+
+ ", bufferEnabled "+bufferEnabled+
+ ", bufferWritten "+bufferWritten+
+ ", buffer "+buffer+
+ "]";
+ }
+
+ // non public matters
+
+ protected final boolean growBufferIfNecessary(int spare) {
+ if(buffer==null || buffer.remaining()<spare) {
+ growBuffer(initialSize);
+ return true;
+ }
+ return false;
+ }
+
+ protected final void growBuffer(int additional) {
+ if(sealed || 0==additional || 0==components) return;
+
+ // add the stride delta
+ additional += (additional/components)*(strideL-components);
+
+ if(components>0) {
+ int osize = (buffer!=null)?buffer.capacity():0;
+ if(clazz==ByteBuffer.class) {
+ ByteBuffer newBBuffer = Buffers.newDirectByteBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newBBuffer.put((ByteBuffer)buffer);
+ }
+ buffer = newBBuffer;
+ } else if(clazz==ShortBuffer.class) {
+ ShortBuffer newSBuffer = Buffers.newDirectShortBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newSBuffer.put((ShortBuffer)buffer);
+ }
+ buffer = newSBuffer;
+ } else if(clazz==IntBuffer.class) {
+ IntBuffer newIBuffer = Buffers.newDirectIntBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newIBuffer.put((IntBuffer)buffer);
+ }
+ buffer = newIBuffer;
+ } else if(clazz==FloatBuffer.class) {
+ FloatBuffer newFBuffer = Buffers.newDirectFloatBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newFBuffer.put((FloatBuffer)buffer);
+ }
+ buffer = newFBuffer;
+ } else {
+ throw new GLException("Given Buffer Class not supported: "+clazz+":\n\t"+this);
+ }
+ }
+ }
+
+ protected final void checkSeal(boolean test) throws GLException {
+ if(sealed!=test) {
+ if(test) {
+ throw new GLException("Not Sealed yet, seal first:\n\t"+this);
+ } else {
+ throw new GLException("Already Sealed, can't modify VBO:\n\t"+this);
+ }
+ }
+ }
+
+ protected void init(String name, int index, int comps, int dataType, boolean normalized, int stride, Buffer data,
+ int initialSize, boolean isVertexAttribute, GLArrayHandler handler,
+ int vboName, long bufferOffset)
+ throws GLException
+ {
+ super.init(name, index, comps, dataType, normalized, stride, data, isVertexAttribute,
+ vboName, bufferOffset);
+
+ this.initialSize = initialSize;
+ this.glArrayHandler = handler;
+ this.sealed=false;
+ this.sealedGL=false;
+ this.bufferEnabled=false;
+ this.enableBufferAlways=false;
+ this.bufferWritten=false;
+ if(null==buffer) {
+ growBuffer(initialSize);
+ }
+ }
+
+ protected void init_vbo(GL gl) {}
+
+ protected GLArrayDataClient() { }
+
+ protected boolean sealed, sealedGL;
+ protected boolean bufferEnabled;
+ protected boolean bufferWritten;
+ protected boolean enableBufferAlways;
+
+ protected int initialSize;
+
+ protected GLArrayHandler glArrayHandler;
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
new file mode 100644
index 000000000..0f8ed27be
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
@@ -0,0 +1,110 @@
+
+package com.jogamp.opengl.util;
+
+import javax.media.opengl.*;
+
+import java.nio.*;
+
+/**
+ *
+ * The total number of bytes hold by the referenced buffer is:
+ * getComponentSize()* getComponentNumber() * getElementNumber()
+ *
+ */
+public interface GLArrayDataEditable extends GLArrayData {
+
+ public boolean sealed();
+
+ /**
+ * The VBO buffer usage, if it's an VBO, otherwise -1
+ */
+ public int getBufferUsage();
+
+ /**
+ * Is the buffer written to the GPU ?
+ */
+ public boolean isBufferWritten();
+
+ /**
+ * Marks the buffer written to the GPU
+ */
+ public void setBufferWritten(boolean written);
+
+ //
+ // Data and GL state modification ..
+ //
+
+ public void destroy(GL gl);
+
+ public void reset(GL gl);
+
+ /**
+ * If seal is true, it
+ * disable write operations to the buffer.
+ * Calls flip, ie limit:=position and position:=0.
+ * Also enables the buffer for OpenGL, and passes the data.
+ *
+ * If seal is false, it
+ * enable write operations continuing
+ * at the buffer position, where you left off at seal(true),
+ * ie position:=limit and limit:=capacity.
+ * Also disables the buffer for OpenGL.
+ *
+ * @see #seal(boolean)
+ */
+ public void seal(GL gl, boolean seal);
+
+ /**
+ * Enables/disables the buffer, which implies
+ * the client state, binding the VBO
+ * and transfering the data if not done yet.
+ *
+ * The above will only be executed,
+ * if the buffer is disabled,
+ * or 'setEnableAlways' was called with 'true'.
+ *
+ * @see #setEnableAlways(boolean)
+ */
+ public void enableBuffer(GL gl, boolean enable);
+
+ /**
+ * Affects the behavior of 'enableBuffer'.
+ *
+ * The default is 'false'
+ *
+ * This is usefull when you mix up
+ * GLArrayData usage with conventional GL array calls.
+ *
+ * @see #enableBuffer(GL, boolean)
+ */
+ public void setEnableAlways(boolean always);
+
+ //
+ // Data modification ..
+ //
+
+ public void reset();
+
+ /**
+ * If seal is true, it
+ * disable write operations to the buffer.
+ * Calls flip, ie limit:=position and position:=0.
+ *
+ * If seal is false, it
+ * enable write operations continuing
+ * at the buffer position, where you left off at seal(true),
+ * ie position:=limit and limit:=capacity.
+ *
+ */
+ public void seal(boolean seal);
+
+ public void rewind();
+ public void padding(int done);
+ public void put(Buffer v);
+ public void putb(byte v);
+ public void puts(short v);
+ public void puti(int v);
+ public void putx(int v);
+ public void putf(float v);
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
new file mode 100644
index 000000000..c061e212a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
@@ -0,0 +1,209 @@
+
+package com.jogamp.opengl.util;
+
+import javax.media.opengl.*;
+import java.nio.*;
+
+import com.jogamp.opengl.util.glsl.*;
+
+public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataEditable {
+
+ //
+ // lifetime matters
+ //
+
+ /**
+ * Create a VBOBuffer object, using a predefined fixed function array index
+ * and starting with a given Buffer object incl it's stride
+ *
+ * On profiles GL2 and ES1 the fixed function pipeline behavior is as expected.
+ * On profile ES2 the fixed function emulation will transform these calls to
+ * EnableVertexAttribArray and VertexAttribPointer calls,
+ * and a predefined vertex attribute variable name will be choosen.
+ *
+ * @param index The GL array index
+ * @param name The optional custom name for the GL array index, maybe null.
+ * If null, the default name mapping will be used, see 'getPredefinedArrayIndexName(int)'.
+ * This name might be used as the shader attribute name.
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param normalized Wheather the data shall be normalized
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataServer createFixed(GL gl, int index, String name, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer, int vboBufferUsage)
+ throws GLException
+ {
+ gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true);
+
+ GLArrayDataServer ads = new GLArrayDataServer();
+ GLArrayHandler glArrayHandler = new GLFixedArrayHandler(ads);
+ ads.init(gl, name, index, comps, dataType, normalized, stride, buffer, buffer.limit(), false, glArrayHandler,
+ 0, 0, vboBufferUsage);
+ return ads;
+ }
+
+ /**
+ * Create a VBOBuffer object, using a predefined fixed function array index
+ * and starting with a new created Buffer object with initialSize size
+ *
+ * On profiles GL2 and ES1 the fixed function pipeline behavior is as expected.
+ * On profile ES2 the fixed function emulation will transform these calls to
+ * EnableVertexAttribArray and VertexAttribPointer calls,
+ * and a predefined vertex attribute variable name will be choosen.
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataServer createFixed(GL gl, int index, String name, int comps, int dataType, boolean normalized,
+ int initialSize, int vboBufferUsage)
+ throws GLException
+ {
+ gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true);
+
+ GLArrayDataServer ads = new GLArrayDataServer();
+ GLArrayHandler glArrayHandler = new GLFixedArrayHandler(ads);
+ ads.init(gl, name, index, comps, dataType, normalized, 0, null, initialSize, false, glArrayHandler,
+ 0, 0, vboBufferUsage);
+ return ads;
+ }
+
+ /**
+ * Create a VBOBuffer object, using a custom GLSL array attribute name
+ * and starting with a new created Buffer object with initialSize size
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataServer createGLSL(GL gl, String name, int comps, int dataType, boolean normalized,
+ int initialSize, int vboBufferUsage)
+ throws GLException
+ {
+ if(!gl.hasGLSL()) {
+ throw new GLException("GLArrayDataServer.GLSL not supported: "+gl);
+ }
+ gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true);
+
+ GLArrayDataServer ads = new GLArrayDataServer();
+ GLArrayHandler glArrayHandler = new GLSLArrayHandler(ads);
+ ads.init(gl, name, -1, comps, dataType, normalized, 0, null, initialSize, true, glArrayHandler,
+ 0, 0, vboBufferUsage);
+ return ads;
+ }
+
+ /**
+ * Create a VBOBuffer object, using a custom GLSL array attribute name
+ * and starting with a given Buffer object incl it's stride
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataServer createGLSL(GL gl, String name, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer, int vboBufferUsage)
+ throws GLException
+ {
+ if(!gl.hasGLSL()) {
+ throw new GLException("GLArrayDataServer.GLSL not supported: "+gl);
+ }
+ gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true);
+
+ GLArrayDataServer ads = new GLArrayDataServer();
+ GLArrayHandler glArrayHandler = new GLSLArrayHandler(ads);
+ ads.init(gl, name, -1, comps, dataType, normalized, stride, buffer, buffer.limit(), true, glArrayHandler,
+ 0, 0, vboBufferUsage);
+ return ads;
+ }
+
+ //
+ // Data matters GLArrayData
+ //
+
+ public int getBufferUsage() { return vboBufferUsage; }
+
+ //
+ // Data and GL state modification ..
+ //
+
+ public void destroy(GL gl) {
+ super.destroy(gl);
+ if(vboName!=0) {
+ int[] tmp = new int[1];
+ tmp[0] = vboName;
+ gl.glDeleteBuffers(1, tmp, 0);
+ vboName = 0;
+ }
+ }
+
+ //
+ // data matters
+ //
+
+ /**
+ * Convenient way do disable the VBO behavior and
+ * switch to client side data one
+ * Only possible if buffer is defined.
+ */
+ public void setVBOUsage(boolean vboUsage) {
+ checkSeal(false);
+ super.setVBOUsage(vboUsage);
+ }
+
+ public String toString() {
+ return "GLArrayDataServer["+name+
+ ", index "+index+
+ ", location "+location+
+ ", isVertexAttribute "+isVertexAttribute+
+ ", dataType "+dataType+
+ ", bufferClazz "+clazz+
+ ", elements "+getElementNumber()+
+ ", components "+components+
+ ", stride "+stride+"u "+strideB+"b "+strideL+"c"+
+ ", initialSize "+initialSize+
+ ", vboBufferUsage "+vboBufferUsage+
+ ", vboUsage "+vboUsage+
+ ", vboName "+vboName+
+ ", sealed "+sealed+
+ ", bufferEnabled "+bufferEnabled+
+ ", bufferWritten "+bufferWritten+
+ ", buffer "+buffer+
+ ", offset "+bufferOffset+
+ "]";
+ }
+
+ //
+ // non public matters ..
+ //
+
+ protected void init(GL gl, String name, int index, int comps, int dataType, boolean normalized,
+ int stride, Buffer data, int initialSize, boolean isVertexAttribute,
+ GLArrayHandler glArrayHandler,
+ int vboName, long bufferOffset, int vboBufferUsage)
+ throws GLException
+ {
+ super.init(name, index, comps, dataType, normalized, stride, data, initialSize, isVertexAttribute, glArrayHandler,
+ vboName, bufferOffset);
+
+ vboUsage=true;
+
+ if( ! (gl.isGL2ES2() && vboBufferUsage==GL2ES2.GL_STREAM_DRAW) ) {
+ switch(vboBufferUsage) {
+ case -1: // nop
+ case GL.GL_STATIC_DRAW:
+ case GL.GL_DYNAMIC_DRAW:
+ break;
+ default:
+ throw new GLException("invalid vboBufferUsage: "+vboBufferUsage+":\n\t"+this);
+ }
+ }
+ this.vboBufferUsage=vboBufferUsage;
+ }
+
+ protected void init_vbo(GL gl) {
+ if(vboUsage && vboName==0) {
+ int[] tmp = new int[1];
+ gl.glGenBuffers(1, tmp, 0);
+ vboName = tmp[0];
+ }
+ }
+
+ protected int vboBufferUsage;
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
new file mode 100644
index 000000000..2ab77fa1b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
@@ -0,0 +1,215 @@
+
+package com.jogamp.opengl.util;
+
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.util.glsl.fixedfunc.impl.*;
+
+import java.nio.*;
+
+public class GLArrayDataWrapper implements GLArrayData {
+
+ public static GLArrayDataWrapper createFixed(GL gl, int index, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer,
+ int vboName, long bufferOffset)
+ throws GLException
+ {
+ gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true);
+ GLArrayDataWrapper adc = new GLArrayDataWrapper();
+ adc.init(null, index, comps, dataType, normalized, stride, buffer, false,
+ vboName, bufferOffset);
+ return adc;
+ }
+
+ public static GLArrayDataWrapper createGLSL(GL gl, String name, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer,
+ int vboName, long bufferOffset)
+ throws GLException
+ {
+ if(!gl.hasGLSL()) {
+ throw new GLException("GLArrayDataWrapper.GLSL not supported: "+gl);
+ }
+ gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true);
+
+ GLArrayDataWrapper adc = new GLArrayDataWrapper();
+ adc.init(name, -1, comps, dataType, normalized, stride, buffer, true,
+ vboName, bufferOffset);
+ return adc;
+ }
+
+ //
+ // Data read access
+ //
+
+ public final boolean isVertexAttribute() { return isVertexAttribute; }
+
+ public final int getIndex() { return index; }
+
+ public final int getLocation() { return location; }
+
+ public final void setLocation(int v) { location = v; }
+
+ public final String getName() { return name; }
+
+ public final long getOffset() { return vboUsage?bufferOffset:-1; }
+
+ public final int getVBOName() { return vboUsage?vboName:-1; }
+
+ public final boolean isVBO() { return vboUsage; }
+
+ public final Buffer getBuffer() { return buffer; }
+
+ public final int getComponentNumber() { return components; }
+
+ public final int getComponentType() { return dataType; }
+
+ public final int getComponentSize() {
+ if(clazz==ByteBuffer.class) {
+ return GLBuffers.SIZEOF_BYTE;
+ }
+ if(clazz==ShortBuffer.class) {
+ return GLBuffers.SIZEOF_SHORT;
+ }
+ if(clazz==IntBuffer.class) {
+ return GLBuffers.SIZEOF_INT;
+ }
+ if(clazz==FloatBuffer.class) {
+ return GLBuffers.SIZEOF_FLOAT;
+ }
+ throw new GLException("Given Buffer Class not supported: "+clazz+":\n\t"+this);
+ }
+
+ public final int getElementNumber() {
+ if(null==buffer) return 0;
+ return ( buffer.position()==0 ) ? ( buffer.limit() / components ) : ( buffer.position() / components ) ;
+ }
+
+ public final boolean getNormalized() { return normalized; }
+
+ public final int getStride() { return stride; }
+
+ public final Class getBufferClass() { return clazz; }
+
+ public void destroy(GL gl) {
+ this.buffer = null;
+ this.components = 0;
+ this.stride=0;
+ this.strideB=0;
+ this.strideL=0;
+ this.vboName=0;
+ this.vboUsage=false;
+ this.bufferOffset=0;
+ }
+
+ public String toString() {
+ return "GLArrayDataWrapper["+name+
+ ", index "+index+
+ ", location "+location+
+ ", isVertexAttribute "+isVertexAttribute+
+ ", dataType "+dataType+
+ ", bufferClazz "+clazz+
+ ", elements "+getElementNumber()+
+ ", components "+components+
+ ", stride "+stride+"u "+strideB+"b "+strideL+"c"+
+ ", buffer "+buffer+
+ ", offset "+bufferOffset+
+ ", vboUsage "+vboUsage+
+ ", vboName "+vboName+
+ "]";
+ }
+
+ public static final Class getBufferClass(int dataType) {
+ switch(dataType) {
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_BYTE:
+ return ByteBuffer.class;
+ case GL.GL_SHORT:
+ case GL.GL_UNSIGNED_SHORT:
+ return ShortBuffer.class;
+ case GL2ES1.GL_FIXED:
+ return IntBuffer.class;
+ case GL.GL_FLOAT:
+ return FloatBuffer.class;
+ default:
+ throw new GLException("Given OpenGL data type not supported: "+dataType);
+ }
+ }
+
+ public void setName(String newName) {
+ location = -1;
+ name = newName;
+ }
+
+ public void setVBOUsage(boolean vboUsage) {
+ this.vboUsage=vboUsage;
+ }
+
+ public void setVBOName(int vboName) {
+ this.vboName=vboName;
+ setVBOUsage(vboName>0);
+ }
+
+ protected void init(String name, int index, int comps, int dataType, boolean normalized, int stride, Buffer data,
+ boolean isVertexAttribute,
+ int vboName, long bufferOffset)
+ throws GLException
+ {
+ this.isVertexAttribute = isVertexAttribute;
+ this.index = index;
+ this.location = -1;
+ // We can't have any dependence on the FixedFuncUtil class here for build bootstrapping reasons
+ this.name = (null==name)?FixedFuncPipeline.getPredefinedArrayIndexName(index):name;
+ if(null==this.name) {
+ throw new GLException("Not a valid GL array index: "+index);
+ }
+ this.dataType = dataType;
+ this.clazz = getBufferClass(dataType);
+ switch(dataType) {
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL2ES1.GL_FIXED:
+ this.normalized = normalized;
+ break;
+ default:
+ this.normalized = false;
+ }
+
+ int bpc = getComponentSize();
+ if(0<stride && stride<comps*bpc) {
+ throw new GLException("stride ("+stride+") lower than component bytes, "+comps+" * "+bpc);
+ }
+ if(0<stride && stride%bpc!=0) {
+ throw new GLException("stride ("+stride+") not a multiple of bpc "+bpc);
+ }
+ this.buffer = data;
+ this.components = comps;
+ this.stride=stride;
+ this.strideB=(0==stride)?comps*bpc:stride;
+ this.strideL=(0==stride)?comps:strideB/bpc;
+ this.vboName=vboName;
+ this.vboUsage=vboName>0;
+ this.bufferOffset=bufferOffset;
+ }
+
+ protected GLArrayDataWrapper() { }
+
+ protected int index;
+ protected int location;
+ protected String name;
+ protected int components;
+ protected int dataType;
+ protected boolean normalized;
+ protected int stride; // user given stride
+ protected int strideB; // stride in bytes
+ protected int strideL; // stride in logical components
+ protected Class clazz;
+ protected Buffer buffer;
+ protected boolean isVertexAttribute;
+
+ protected long bufferOffset;
+ protected int vboName;
+ protected boolean vboUsage;
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayHandler.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayHandler.java
new file mode 100644
index 000000000..bfabb5b01
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayHandler.java
@@ -0,0 +1,11 @@
+
+package com.jogamp.opengl.util;
+
+import javax.media.opengl.*;
+
+public interface GLArrayHandler {
+
+ public void enableBuffer(GL gl, boolean enable);
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
new file mode 100755
index 000000000..efe3a7675
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+package com.jogamp.opengl.util;
+
+import com.jogamp.common.nio.Buffers;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
+
+import java.nio.*;
+
+/**
+ * Utility routines for dealing with direct buffers.
+ * @author Kenneth Russel
+ * @author Michael Bien
+ */
+public class GLBuffers extends Buffers {
+
+ public static final int sizeOfGLType(int glType) {
+ switch (glType) {
+ case GL.GL_UNSIGNED_BYTE:
+ return SIZEOF_BYTE;
+ case GL.GL_BYTE:
+ return SIZEOF_BYTE;
+ case GL.GL_UNSIGNED_SHORT:
+ return SIZEOF_SHORT;
+ case GL.GL_SHORT:
+ return SIZEOF_SHORT;
+ case GL.GL_FLOAT:
+ return SIZEOF_FLOAT;
+ case GL.GL_FIXED:
+ return SIZEOF_INT;
+ case GL2ES2.GL_INT:
+ return SIZEOF_INT;
+ case GL2ES2.GL_UNSIGNED_INT:
+ return SIZEOF_INT;
+ case GL2.GL_DOUBLE:
+ return SIZEOF_DOUBLE;
+ }
+ return -1;
+ }
+
+ public static final Buffer newDirectGLBuffer(int glType, int numElements) {
+ switch (glType) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ return newDirectByteBuffer(numElements);
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ return newDirectShortBuffer(numElements);
+ case GL.GL_FLOAT:
+ return newDirectFloatBuffer(numElements);
+ case GL.GL_FIXED:
+ case GL2ES2.GL_INT:
+ case GL2ES2.GL_UNSIGNED_INT:
+ return newDirectIntBuffer(numElements);
+ case GL2.GL_DOUBLE:
+ return newDirectDoubleBuffer(numElements);
+ }
+ return null;
+ }
+
+ public static final Buffer sliceGLBuffer(ByteBuffer parent, int bytePos, int byteLen, int glType) {
+ if (parent == null || byteLen == 0) {
+ return null;
+ }
+ parent.position(bytePos);
+ parent.limit(bytePos + byteLen);
+
+ switch (glType) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ return parent.slice();
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ return parent.asShortBuffer();
+ case GL.GL_FLOAT:
+ return parent.asFloatBuffer();
+ case GL.GL_FIXED:
+ case GL2ES2.GL_INT:
+ case GL2ES2.GL_UNSIGNED_INT:
+ return parent.asIntBuffer();
+ case GL2.GL_DOUBLE:
+ return parent.asDoubleBuffer();
+ }
+ return null;
+ }
+
+ //----------------------------------------------------------------------
+ // Conversion routines
+ //
+ public final static float[] getFloatArray(double[] source) {
+ int i = source.length;
+ float[] dest = new float[i--];
+ while (i >= 0) {
+ dest[i] = (float) source[i];
+ i--;
+ }
+ return dest;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLFixedArrayHandler.java b/src/jogl/classes/com/jogamp/opengl/util/GLFixedArrayHandler.java
new file mode 100644
index 000000000..f0f5ea896
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLFixedArrayHandler.java
@@ -0,0 +1,65 @@
+
+package com.jogamp.opengl.util;
+
+import javax.media.opengl.*;
+import javax.media.opengl.fixedfunc.*;
+import com.jogamp.opengl.util.*;
+import java.nio.*;
+
+public class GLFixedArrayHandler implements GLArrayHandler {
+ private GLArrayDataEditable ad;
+
+ public GLFixedArrayHandler(GLArrayDataEditable ad) {
+ this.ad = ad;
+ }
+
+ protected final void passArrayPointer(GLPointerFunc gl) {
+ switch(ad.getIndex()) {
+ case GLPointerFunc.GL_VERTEX_ARRAY:
+ gl.glVertexPointer(ad);
+ break;
+ case GLPointerFunc.GL_NORMAL_ARRAY:
+ gl.glNormalPointer(ad);
+ break;
+ case GLPointerFunc.GL_COLOR_ARRAY:
+ gl.glColorPointer(ad);
+ break;
+ case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+ gl.glTexCoordPointer(ad);
+ break;
+ default:
+ throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad);
+ }
+ }
+
+ public void enableBuffer(GL gl, boolean enable) {
+ GLPointerFunc glp = gl.getGL2ES1();
+ if(enable) {
+ glp.glEnableClientState(ad.getIndex());
+
+ Buffer buffer = ad.getBuffer();
+
+ if(ad.isVBO()) {
+ // always bind and refresh the VBO mgr,
+ // in case more than one gl*Pointer objects are in use
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, ad.getVBOName());
+ if(!ad.isBufferWritten()) {
+ if(null!=buffer) {
+ gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit() * ad.getComponentSize(), buffer, ad.getBufferUsage());
+ }
+ ad.setBufferWritten(true);
+ }
+ passArrayPointer(glp);
+ } else if(null!=buffer) {
+ passArrayPointer(glp);
+ ad.setBufferWritten(true);
+ }
+ } else {
+ if(ad.isVBO()) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ }
+ glp.glDisableClientState(ad.getIndex());
+ }
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Gamma.java b/src/jogl/classes/com/jogamp/opengl/util/Gamma.java
new file mode 100755
index 000000000..672325cf3
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/Gamma.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+/** Provides control over the primary display's gamma, brightness and
+ contrast controls via the hardware gamma ramp tables. Not
+ supported on all platforms or graphics hardware. <P>
+
+ Thanks to the LWJGL project for illustrating how to access gamma
+ control on the various platforms.
+*/
+
+public class Gamma {
+ private Gamma() {}
+
+ /**
+ * Sets the gamma, brightness, and contrast of the current main
+ * display. This functionality is not available on all platforms and
+ * graphics hardware. Returns true if the settings were successfully
+ * changed, false if not. This method may return false for some
+ * values of the incoming arguments even on hardware which does
+ * support the underlying functionality. <P>
+ *
+ * If this method returns true, the display settings will
+ * automatically be reset to their original values upon JVM exit
+ * (assuming the JVM does not crash); if the user wishes to change
+ * the display settings back to normal ahead of time, use {@link
+ * #resetDisplayGamma resetDisplayGamma}(). It is recommended to
+ * call {@link #resetDisplayGamma resetDisplayGamma} before calling
+ * e.g. <code>System.exit()</code> from the application rather than
+ * rely on the shutdown hook functionality due to inevitable race
+ * conditions and unspecified behavior during JVM teardown. <P>
+ *
+ * This method may be called multiple times during the application's
+ * execution, but calling {@link #resetDisplayGamma
+ * resetDisplayGamma} will only reset the settings to the values
+ * before the first call to this method. <P>
+ *
+ * @param gamma The gamma value, typically > 1.0 (default values
+ * vary, but typically roughly 1.0)
+ * @param brightness The brightness value between -1.0 and 1.0,
+ * inclusive (default values vary, but typically 0)
+ * @param contrast The contrast, greater than 0.0 (default values
+ * vary, but typically 1)
+ * @return true if gamma settings were successfully changed, false
+ * if not
+ * @throws IllegalArgumentException if any of the parameters were
+ * out-of-bounds
+ */
+ public static boolean setDisplayGamma(GL gl, float gamma, float brightness, float contrast) throws IllegalArgumentException {
+ return GLDrawableFactoryImpl.getFactoryImpl(gl.getContext().getGLDrawable().getGLProfile()).setDisplayGamma(gamma, brightness, contrast);
+ }
+
+ /**
+ * Resets the gamma, brightness and contrast values for the primary
+ * display to their original values before {@link #setDisplayGamma
+ * setDisplayGamma} was called the first time. {@link
+ * #setDisplayGamma setDisplayGamma} must be called before calling
+ * this method or an unspecified exception will be thrown. While it
+ * is not explicitly required that this method be called before
+ * exiting, calling it is recommended because of the inevitable
+ * unspecified behavior during JVM teardown.
+ */
+ public static void resetDisplayGamma(GL gl) {
+ GLDrawableFactoryImpl.getFactoryImpl(gl.getContext().getGLDrawable().getGLProfile()).resetDisplayGamma();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
new file mode 100644
index 000000000..04b994198
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
@@ -0,0 +1,974 @@
+
+package com.jogamp.opengl.util;
+
+import com.jogamp.common.util.*;
+import javax.media.opengl.*;
+import javax.media.opengl.fixedfunc.*;
+import java.nio.*;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+public class ImmModeSink {
+
+ public static final boolean DEBUG_BEGIN_END = false;
+ public static final boolean DEBUG_DRAW = false;
+
+ // public static final int GL_QUADS = 0x0007; // Needs data manipulation
+ public static final int GL_QUAD_STRIP = 0x0008;
+ public static final int GL_POLYGON = 0x0009;
+
+ /**
+ * Uses a GL2ES1, or ES2 fixed function emulation immediate mode sink
+ */
+ public static ImmModeSink createFixed(GL gl, int glBufferUsage, int initialSize,
+ int vComps, int vDataType,
+ int cComps, int cDataType,
+ int nComps, int nDataType,
+ int tComps, int tDataType) {
+ return new ImmModeSink(gl, glBufferUsage, initialSize,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, false);
+ }
+
+ /**
+ * Uses a GL2ES2 GLSL shader immediate mode sink.
+ * To issue the draw() command,
+ * a ShaderState must be current, using ShaderState.glUseProgram().
+ *
+ * @see #draw(GL, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrent()
+ */
+ public static ImmModeSink createGLSL(GL gl, int glBufferUsage, int initialSize,
+ int vComps, int vDataType,
+ int cComps, int cDataType,
+ int nComps, int nDataType,
+ int tComps, int tDataType) {
+ return new ImmModeSink(gl, glBufferUsage, initialSize,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, true);
+ }
+
+ public static boolean usesVBO() { return vboUsage; }
+
+ public static void setVBOUsage(boolean v) { vboUsage = v; }
+
+ public void destroy(GL gl) {
+ destroyList(gl);
+
+ vboSet.destroy(gl);
+ }
+
+ public void reset() {
+ reset(null);
+ }
+
+ public void reset(GL gl) {
+ destroyList(gl);
+ vboSet.reset(gl);
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer("ImmModeSink[");
+ sb.append(",\n\tVBO list: "+vboSetList.size()+" [");
+ for(Iterator i=vboSetList.iterator(); i.hasNext() ; ) {
+ sb.append("\n\t");
+ sb.append( (VBOSet)i.next() );
+ }
+ if(vboSetList.size()>0) {
+ sb.append("\n\t],\nVBO current: NOP]");
+ } else {
+ sb.append("\n\t],\nVBO current: \n");
+ sb.append(vboSet);
+ sb.append("\n]");
+ }
+ return sb.toString();
+ }
+
+ public void draw(GL gl, boolean disableBufferAfterDraw) {
+ if(DEBUG_DRAW) {
+ Exception e = new Exception("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
+ e.printStackTrace();
+ }
+ int n=0;
+ for(Iterator i=vboSetList.iterator(); i.hasNext() ; n++) {
+ ((VBOSet)i.next()).draw(gl, null, disableBufferAfterDraw, n);
+ }
+ }
+
+ public void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw) {
+ if(DEBUG_DRAW) {
+ Exception e = new Exception("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
+ e.printStackTrace();
+ }
+ int n=0;
+ for(Iterator i=vboSetList.iterator(); i.hasNext() ; n++) {
+ ((VBOSet)i.next()).draw(gl, indices, disableBufferAfterDraw, n);
+ }
+ }
+
+ public void glBegin(int mode) {
+ if(DEBUG_BEGIN_END) {
+ Exception e = new Exception("ImmModeSink.glBegin("+vboSet.mode+"):\n\t"+this);
+ e.printStackTrace();
+ }
+ vboSet.modeOrig = mode;
+ switch(mode) {
+ // Needs data manipulation ..
+ //case GL_QUADS:
+ // mode=GL.GL_LINES;
+ // break;
+ case GL_QUAD_STRIP:
+ mode=GL.GL_TRIANGLE_STRIP;
+ break;
+ case GL_POLYGON:
+ mode=GL.GL_LINES;
+ break;
+ }
+ vboSet.mode = mode;
+ vboSet.checkSeal(false);
+ }
+
+ public final void glEnd(GL gl) {
+ glEnd(gl, null, true);
+ }
+
+ public void glEnd(GL gl, boolean immediateDraw) {
+ glEnd(gl, null, immediateDraw);
+ }
+
+ public final void glEnd(GL gl, Buffer indices) {
+ glEnd(gl, indices, true);
+ }
+
+ private void glEnd(GL gl, Buffer indices, boolean immediateDraw) {
+ if(DEBUG_BEGIN_END) {
+ Exception e = new Exception("ImmModeSink START glEnd(immediate: "+immediateDraw+"):\n\t"+this);
+ e.printStackTrace();
+ }
+ if(immediateDraw) {
+ vboSet.seal(gl, true);
+ vboSet.draw(gl, indices, true, -1);
+ reset(gl);
+ } else {
+ vboSet.seal(gl, true);
+ vboSet.enableBuffer(gl, false);
+ vboSetList.add(vboSet);
+ vboSet = vboSet.regenerate();
+ }
+ }
+
+ public void glVertexv(Buffer v) {
+ vboSet.glVertexv(v);
+ }
+ public void glNormalv(Buffer v) {
+ vboSet.glNormalv(v);
+ }
+ public void glColorv(Buffer v) {
+ vboSet.glColorv(v);
+ }
+ public void glTexCoordv(Buffer v) {
+ vboSet.glTexCoordv(v);
+ }
+
+ public final void glVertex2f(float x, float y) {
+ vboSet.glVertex2f(x,y);
+ }
+
+ public final void glVertex3f(float x, float y, float z) {
+ vboSet.glVertex3f(x,y,z);
+ }
+
+ public final void glNormal3f(float x, float y, float z) {
+ vboSet.glNormal3f(x,y,z);
+ }
+
+ public final void glColor3f(float x, float y, float z) {
+ vboSet.glColor3f(x,y,z);
+ }
+
+ public final void glColor4f(float x, float y, float z, float a) {
+ vboSet.glColor4f(x,y,z, a);
+ }
+
+ public final void glTexCoord2f(float x, float y) {
+ vboSet.glTexCoord2f(x,y);
+ }
+
+ public final void glTexCoord3f(float x, float y, float z) {
+ vboSet.glTexCoord3f(x,y,z);
+ }
+
+ public final void glVertex2s(short x, short y) {
+ vboSet.glVertex2s(x,y);
+ }
+
+ public final void glVertex3s(short x, short y, short z) {
+ vboSet.glVertex3s(x,y,z);
+ }
+
+ public final void glNormal3s(short x, short y, short z) {
+ vboSet.glNormal3s(x,y,z);
+ }
+
+ public final void glColor3s(short x, short y, short z) {
+ vboSet.glColor3s(x,y,z);
+ }
+
+ public final void glColor4s(short x, short y, short z, short a) {
+ vboSet.glColor4s(x,y,z,a);
+ }
+
+ public final void glTexCoord2s(short x, short y) {
+ vboSet.glTexCoord2s(x,y);
+ }
+
+ public final void glTexCoord3s(short x, short y, short z) {
+ vboSet.glTexCoord3s(x,y,z);
+ }
+
+ public final void glVertex2b(byte x, byte y) {
+ vboSet.glVertex2b(x,y);
+ }
+
+ public final void glVertex3b(byte x, byte y, byte z) {
+ vboSet.glVertex3b(x,y,z);
+ }
+
+ public final void glNormal3b(byte x, byte y, byte z) {
+ vboSet.glNormal3b(x,y,z);
+ }
+
+ public final void glColor3b(byte x, byte y, byte z) {
+ vboSet.glColor3b(x,y,z);
+ }
+
+ public final void glColor4b(byte x, byte y, byte z, byte a) {
+ vboSet.glColor4b(x,y,z,a);
+ }
+
+ public final void glTexCoord2b(byte x, byte y) {
+ vboSet.glTexCoord2b(x,y);
+ }
+
+ public final void glTexCoord3b(byte x, byte y, byte z) {
+ vboSet.glTexCoord3b(x,y,z);
+ }
+
+ protected ImmModeSink(GL gl, int glBufferUsage, int initialSize,
+ int vComps, int vDataType,
+ int cComps, int cDataType,
+ int nComps, int nDataType,
+ int tComps, int tDataType, boolean useGLSL) {
+ if(useGLSL && !gl.hasGLSL()) {
+ throw new GLException("ImmModeSink GLSL usage not supported: "+gl);
+ }
+ vboSet = new VBOSet(gl, glBufferUsage, initialSize,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL);
+ this.vboSetList = new ArrayList();
+ }
+
+ private void destroyList(GL gl) {
+ for(Iterator i=vboSetList.iterator(); i.hasNext() ; ) {
+ ((VBOSet)i.next()).destroy(gl);
+ }
+ vboSetList.clear();
+ }
+
+ private VBOSet vboSet;
+ private ArrayList vboSetList;
+ private static boolean vboUsage = true;
+
+ protected static class VBOSet {
+ protected VBOSet (GL gl, int glBufferUsage, int initialSize,
+ int vComps, int vDataType,
+ int cComps, int cDataType,
+ int nComps, int nDataType,
+ int tComps, int tDataType, boolean useGLSL) {
+ this.gl=gl;
+ this.glBufferUsage=glBufferUsage;
+ this.initialSize=initialSize;
+ this.vDataType=vDataType;
+ this.vComps=vComps;
+ this.cDataType=cDataType;
+ this.cComps=cComps;
+ this.nDataType=nDataType;
+ this.nComps=nComps;
+ this.tDataType=tDataType;
+ this.tComps=tComps;
+ this.useGLSL=useGLSL;
+
+ allocateBuffer(initialSize);
+ rewind();
+
+ this.sealed=false;
+ this.sealedGL=false;
+ this.mode = -1;
+ this.modeOrig = -1;
+ this.bufferEnabled=false;
+ this.bufferWritten=false;
+ }
+
+ protected final VBOSet regenerate() {
+ return new VBOSet(gl, glBufferUsage, initialSize,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL);
+ }
+
+ protected void checkSeal(boolean test) throws GLException {
+ if(mode<0) {
+ throw new GLException("No mode set yet, call glBegin(mode) first:\n\t"+this);
+ }
+ if(sealed!=test) {
+ if(test) {
+ throw new GLException("Not Sealed yet, call glEnd() first:\n\t"+this);
+ } else {
+ throw new GLException("Already Sealed, can't modify VBO after glEnd():\n\t"+this);
+ }
+ }
+ }
+
+ protected void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw, int i)
+ {
+ if(DEBUG_DRAW) {
+ Exception e = new Exception("ImmModeSink.draw["+i+"](disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
+ e.printStackTrace();
+ }
+ enableBuffer(gl, true);
+
+ if (buffer!=null) {
+ GL2ES1 glf = gl.getGL2ES1();
+
+ if(null==indices) {
+ glf.glDrawArrays(mode, 0, count);
+ } else {
+ Class clazz = indices.getClass();
+ int type=-1;
+ if(ReflectionUtil.instanceOf(clazz, ByteBuffer.class.getName())) {
+ type = GL.GL_UNSIGNED_BYTE;
+ } else if(ReflectionUtil.instanceOf(clazz, ShortBuffer.class.getName())) {
+ type = GL.GL_UNSIGNED_SHORT;
+ }
+ if(0>type) {
+ throw new GLException("Given Buffer Class not supported: "+clazz+", should be ubyte or ushort:\n\t"+this);
+ }
+ glf.glDrawElements(mode, indices.remaining(), type, indices);
+ // GL2: gl.glDrawRangeElements(mode, 0, indices.remaining()-1, indices.remaining(), type, indices);
+ }
+ }
+
+ if(disableBufferAfterDraw) {
+ enableBuffer(gl, false);
+ }
+ }
+
+ public void glVertexv(Buffer v) {
+ checkSeal(false);
+ GLBuffers.put(vertexArray, v);
+ }
+ public void glNormalv(Buffer v) {
+ checkSeal(false);
+ GLBuffers.put(normalArray, v);
+ }
+ public void glColorv(Buffer v) {
+ checkSeal(false);
+ GLBuffers.put(colorArray, v);
+ }
+ public void glTexCoordv(Buffer v) {
+ checkSeal(false);
+ GLBuffers.put(textCoordArray, v);
+ }
+
+ public void glVertex2b(byte x, byte y) {
+ checkSeal(false);
+ growBufferIfNecessary(VERTEX, 2);
+ if(vComps>0)
+ GLBuffers.putb(vertexArray, x);
+ if(vComps>1)
+ GLBuffers.putb(vertexArray, y);
+ padding(VERTEX, vComps-2);
+ }
+ public void glVertex3b(byte x, byte y, byte z) {
+ checkSeal(false);
+ growBufferIfNecessary(VERTEX, 3);
+ if(vComps>0)
+ GLBuffers.putb(vertexArray, x);
+ if(vComps>1)
+ GLBuffers.putb(vertexArray, y);
+ if(vComps>2)
+ GLBuffers.putb(vertexArray, z);
+ padding(VERTEX, vComps-3);
+ }
+ public void glVertex2s(short x, short y) {
+ checkSeal(false);
+ growBufferIfNecessary(VERTEX, 2);
+ if(vComps>0)
+ GLBuffers.puts(vertexArray, x);
+ if(vComps>1)
+ GLBuffers.puts(vertexArray, y);
+ padding(VERTEX, vComps-2);
+ }
+ public void glVertex3s(short x, short y, short z) {
+ checkSeal(false);
+ growBufferIfNecessary(VERTEX, 3);
+ if(vComps>0)
+ GLBuffers.puts(vertexArray, x);
+ if(vComps>1)
+ GLBuffers.puts(vertexArray, y);
+ if(vComps>2)
+ GLBuffers.puts(vertexArray, z);
+ padding(VERTEX, vComps-3);
+ }
+ public void glVertex2f(float x, float y) {
+ checkSeal(false);
+ growBufferIfNecessary(VERTEX, 2);
+ if(vComps>0)
+ GLBuffers.putf(vertexArray, x);
+ if(vComps>1)
+ GLBuffers.putf(vertexArray, y);
+ padding(VERTEX, vComps-2);
+ }
+ public void glVertex3f(float x, float y, float z) {
+ checkSeal(false);
+ growBufferIfNecessary(VERTEX, 3);
+ if(vComps>0)
+ GLBuffers.putf(vertexArray, x);
+ if(vComps>1)
+ GLBuffers.putf(vertexArray, y);
+ if(vComps>2)
+ GLBuffers.putf(vertexArray, z);
+ padding(VERTEX, vComps-3);
+ }
+
+ public void glNormal3b(byte x, byte y, byte z) {
+ checkSeal(false);
+ growBufferIfNecessary(NORMAL, 3);
+ if(nComps>0)
+ GLBuffers.putb(normalArray, x);
+ if(nComps>1)
+ GLBuffers.putb(normalArray, y);
+ if(nComps>2)
+ GLBuffers.putb(normalArray, z);
+ padding(NORMAL, nComps-3);
+ }
+ public void glNormal3s(short x, short y, short z) {
+ checkSeal(false);
+ growBufferIfNecessary(NORMAL, 3);
+ if(nComps>0)
+ GLBuffers.puts(normalArray, x);
+ if(nComps>1)
+ GLBuffers.puts(normalArray, y);
+ if(nComps>2)
+ GLBuffers.puts(normalArray, z);
+ padding(NORMAL, nComps-3);
+ }
+ public void glNormal3f(float x, float y, float z) {
+ checkSeal(false);
+ growBufferIfNecessary(NORMAL, 3);
+ if(nComps>0)
+ GLBuffers.putf(normalArray, x);
+ if(nComps>1)
+ GLBuffers.putf(normalArray, y);
+ if(nComps>2)
+ GLBuffers.putf(normalArray, z);
+ padding(NORMAL, nComps-3);
+ }
+
+ public void glColor3b(byte r, byte g, byte b) {
+ checkSeal(false);
+ growBufferIfNecessary(COLOR, 3);
+ if(cComps>0)
+ GLBuffers.putb(colorArray, r);
+ if(cComps>1)
+ GLBuffers.putb(colorArray, g);
+ if(cComps>2)
+ GLBuffers.putb(colorArray, b);
+ padding(COLOR, cComps-3);
+ }
+ public void glColor4b(byte r, byte g, byte b, byte a) {
+ checkSeal(false);
+ growBufferIfNecessary(COLOR, 4);
+ if(cComps>0)
+ GLBuffers.putb(colorArray, r);
+ if(cComps>1)
+ GLBuffers.putb(colorArray, g);
+ if(cComps>2)
+ GLBuffers.putb(colorArray, b);
+ if(cComps>3)
+ GLBuffers.putb(colorArray, a);
+ padding(COLOR, cComps-4);
+ }
+ public void glColor3s(short r, short g, short b) {
+ checkSeal(false);
+ growBufferIfNecessary(COLOR, 3);
+ if(cComps>0)
+ GLBuffers.puts(colorArray, r);
+ if(cComps>1)
+ GLBuffers.puts(colorArray, g);
+ if(cComps>2)
+ GLBuffers.puts(colorArray, b);
+ padding(COLOR, cComps-3);
+ }
+ public void glColor4s(short r, short g, short b, short a) {
+ checkSeal(false);
+ growBufferIfNecessary(COLOR, 4);
+ if(cComps>0)
+ GLBuffers.puts(colorArray, r);
+ if(cComps>1)
+ GLBuffers.puts(colorArray, g);
+ if(cComps>2)
+ GLBuffers.puts(colorArray, b);
+ if(cComps>3)
+ GLBuffers.puts(colorArray, a);
+ padding(COLOR, cComps-4);
+ }
+ public void glColor3f(float r, float g, float b) {
+ checkSeal(false);
+ growBufferIfNecessary(COLOR, 3);
+ if(cComps>0)
+ GLBuffers.putf(colorArray, r);
+ if(cComps>1)
+ GLBuffers.putf(colorArray, g);
+ if(cComps>2)
+ GLBuffers.putf(colorArray, b);
+ padding(COLOR, cComps-3);
+ }
+ public void glColor4f(float r, float g, float b, float a) {
+ checkSeal(false);
+ growBufferIfNecessary(COLOR, 4);
+ if(cComps>0)
+ GLBuffers.putf(colorArray, r);
+ if(cComps>1)
+ GLBuffers.putf(colorArray, g);
+ if(cComps>2)
+ GLBuffers.putf(colorArray, b);
+ if(cComps>3)
+ GLBuffers.putf(colorArray, a);
+ padding(COLOR, cComps-4);
+ }
+
+ public void glTexCoord2b(byte x, byte y) {
+ checkSeal(false);
+ growBufferIfNecessary(TEXTCOORD, 2);
+ if(tComps>0)
+ GLBuffers.putb(textCoordArray, x);
+ if(tComps>1)
+ GLBuffers.putb(textCoordArray, y);
+ padding(TEXTCOORD, tComps-2);
+ }
+ public void glTexCoord3b(byte x, byte y, byte z) {
+ checkSeal(false);
+ growBufferIfNecessary(TEXTCOORD, 3);
+ if(tComps>0)
+ GLBuffers.putb(textCoordArray, x);
+ if(tComps>1)
+ GLBuffers.putb(textCoordArray, y);
+ if(tComps>2)
+ GLBuffers.putb(textCoordArray, z);
+ padding(TEXTCOORD, tComps-3);
+ }
+ public void glTexCoord2s(short x, short y) {
+ checkSeal(false);
+ growBufferIfNecessary(TEXTCOORD, 2);
+ if(tComps>0)
+ GLBuffers.puts(textCoordArray, x);
+ if(tComps>1)
+ GLBuffers.puts(textCoordArray, y);
+ padding(TEXTCOORD, tComps-2);
+ }
+ public void glTexCoord3s(short x, short y, short z) {
+ checkSeal(false);
+ growBufferIfNecessary(TEXTCOORD, 3);
+ if(tComps>0)
+ GLBuffers.puts(textCoordArray, x);
+ if(tComps>1)
+ GLBuffers.puts(textCoordArray, y);
+ if(tComps>2)
+ GLBuffers.puts(textCoordArray, z);
+ padding(TEXTCOORD, tComps-3);
+ }
+ public void glTexCoord2f(float x, float y) {
+ checkSeal(false);
+ growBufferIfNecessary(TEXTCOORD, 2);
+ if(tComps>0)
+ GLBuffers.putf(textCoordArray, x);
+ if(tComps>1)
+ GLBuffers.putf(textCoordArray, y);
+ padding(TEXTCOORD, tComps-2);
+ }
+ public void glTexCoord3f(float x, float y, float z) {
+ checkSeal(false);
+ growBufferIfNecessary(TEXTCOORD, 3);
+ if(tComps>0)
+ GLBuffers.putf(textCoordArray, x);
+ if(tComps>1)
+ GLBuffers.putf(textCoordArray, y);
+ if(tComps>2)
+ GLBuffers.putf(textCoordArray, z);
+ padding(TEXTCOORD, tComps-3);
+ }
+
+ public void rewind() {
+ if(null!=vertexArray) {
+ vertexArray.rewind();
+ }
+ if(null!=colorArray) {
+ colorArray.rewind();
+ }
+ if(null!=normalArray) {
+ normalArray.rewind();
+ }
+ if(null!=textCoordArray) {
+ textCoordArray.rewind();
+ }
+ }
+
+ public void destroy(GL gl) {
+ reset(gl);
+
+ vertexArray=null; colorArray=null; normalArray=null; textCoordArray=null;
+ vArrayData=null; cArrayData=null; nArrayData=null; tArrayData=null;
+ buffer=null;
+ bSize=0; count=0;
+ }
+
+ public void reset(GL gl) {
+ enableBuffer(gl, false);
+ reset();
+ }
+
+ public void reset() {
+ if(buffer!=null) {
+ buffer.clear();
+ }
+ rewind();
+
+ this.mode = -1;
+ this.modeOrig = -1;
+ this.sealed=false;
+ this.bufferEnabled=false;
+ this.bufferWritten=false;
+ }
+
+ public void seal(GL glObj, boolean seal)
+ {
+ seal(seal);
+ if(sealedGL==seal) return;
+ sealedGL = seal;
+ GL gl = glObj.getGL();
+ if(seal) {
+ if(vboUsage && vboName==0) {
+ int[] tmp = new int[1];
+ gl.glGenBuffers(1, tmp, 0);
+ vboName = tmp[0];
+ }
+ if(null!=vArrayData)
+ vArrayData.setVBOName(vboName);
+ if(null!=cArrayData)
+ cArrayData.setVBOName(vboName);
+ if(null!=nArrayData)
+ nArrayData.setVBOName(vboName);
+ if(null!=tArrayData)
+ tArrayData.setVBOName(vboName);
+ enableBuffer(gl, true);
+ } else {
+ enableBuffer(gl, false);
+ }
+ }
+
+ public void seal(boolean seal)
+ {
+ if(sealed==seal) return;
+ sealed = seal;
+ if(seal) {
+ bufferWritten=false;
+ }
+ }
+
+ public void enableBuffer(GL gl, boolean enable) {
+ /* if(enableBufferAlways && enable) {
+ bufferEnabled = false;
+ } */
+ if( bufferEnabled != enable && count>0 ) {
+ if(enable) {
+ checkSeal(true);
+ }
+ if(useGLSL) {
+ enableBufferGLSL(gl, enable);
+ } else {
+ enableBufferFixed(gl, enable);
+ }
+ bufferEnabled = enable;
+ }
+ }
+
+ public void enableBufferFixed(GL gl, boolean enable) {
+ GL2ES1 glf = gl.getGL2ES1();
+
+ if(enable) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+
+ if(!bufferWritten) {
+ gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, GL.GL_STATIC_DRAW);
+ bufferWritten=true;
+ }
+
+ if(vComps>0) {
+ glf.glEnableClientState(glf.GL_VERTEX_ARRAY);
+ glf.glVertexPointer(vArrayData);
+ }
+ if(cComps>0) {
+ glf.glEnableClientState(glf.GL_COLOR_ARRAY);
+ glf.glColorPointer(cArrayData);
+ }
+ if(nComps>0) {
+ glf.glEnableClientState(glf.GL_NORMAL_ARRAY);
+ glf.glNormalPointer(nArrayData);
+ }
+ if(tComps>0) {
+ glf.glEnableClientState(glf.GL_TEXTURE_COORD_ARRAY);
+ glf.glTexCoordPointer(tArrayData);
+ }
+
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ } else {
+ if(vComps>0) {
+ glf.glDisableClientState(glf.GL_VERTEX_ARRAY);
+ }
+ if(cComps>0) {
+ glf.glDisableClientState(glf.GL_COLOR_ARRAY);
+ }
+ if(nComps>0) {
+ glf.glDisableClientState(glf.GL_NORMAL_ARRAY);
+ }
+ if(tComps>0) {
+ glf.glDisableClientState(glf.GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+ }
+
+ public void enableBufferGLSL(GL gl, boolean enable) {
+ GL2ES2 glsl = gl.getGL2ES2();
+ com.jogamp.opengl.util.glsl.ShaderState st = com.jogamp.opengl.util.glsl.ShaderState.getCurrent();
+ if(null==st) {
+ throw new GLException("No ShaderState current");
+ }
+
+ if(enable) {
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+
+ if(!bufferWritten) {
+ glsl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit(), buffer, GL.GL_STATIC_DRAW);
+ bufferWritten=true;
+ }
+
+ if(vComps>0) {
+ st.glEnableVertexAttribArray(glsl, vArrayData.getName());
+ st.glVertexAttribPointer(glsl, vArrayData);
+ }
+ if(cComps>0) {
+ st.glEnableVertexAttribArray(glsl, cArrayData.getName());
+ st.glVertexAttribPointer(glsl, cArrayData);
+ }
+ if(nComps>0) {
+ st.glEnableVertexAttribArray(glsl, nArrayData.getName());
+ st.glVertexAttribPointer(glsl, nArrayData);
+ }
+ if(tComps>0) {
+ st.glEnableVertexAttribArray(glsl, tArrayData.getName());
+ st.glVertexAttribPointer(glsl, tArrayData);
+ }
+
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ } else {
+ if(vComps>0) {
+ st.glDisableVertexAttribArray(glsl, vArrayData.getName());
+ }
+ if(cComps>0) {
+ st.glDisableVertexAttribArray(glsl, cArrayData.getName());
+ }
+ if(nComps>0) {
+ st.glDisableVertexAttribArray(glsl, nArrayData.getName());
+ }
+ if(tComps>0) {
+ st.glDisableVertexAttribArray(glsl, tArrayData.getName());
+ }
+ }
+ }
+
+ public String toString() {
+ return "VBOSet[mode "+mode+
+ ", modeOrig "+modeOrig+
+ ", sealed "+sealed+
+ ", bufferEnabled "+bufferEnabled+
+ ", bufferWritten "+bufferWritten+
+ ",\n\t"+vArrayData+
+ ",\n\t"+cArrayData+
+ ",\n\t"+nArrayData+
+ ",\n\t"+tArrayData+
+ "]";
+ }
+
+ // non public matters
+
+ protected void allocateBuffer(int elements) {
+ int vWidth = vComps * GLBuffers.sizeOfGLType(vDataType);
+ int cWidth = cComps * GLBuffers.sizeOfGLType(cDataType);
+ int nWidth = nComps * GLBuffers.sizeOfGLType(nDataType);
+ int tWidth = tComps * GLBuffers.sizeOfGLType(tDataType);
+
+ count = elements;
+ bSize = count * ( vWidth + cWidth + nWidth + tWidth ) ;
+
+ buffer = GLBuffers.newDirectByteBuffer(bSize);
+
+ int pos = 0;
+ int size= count * vWidth ;
+ if(size>0) {
+ vertexArray = GLBuffers.sliceGLBuffer(buffer, pos, size, vDataType);
+ } else {
+ vertexArray = null;
+ }
+ vOffset = pos;
+ pos+=size;
+
+ size= count * cWidth ;
+ if(size>0) {
+ colorArray = GLBuffers.sliceGLBuffer(buffer, pos, size, cDataType);
+ } else {
+ colorArray = null;
+ }
+ cOffset = pos;
+ pos+=size;
+
+ size= count * nWidth ;
+ if(size>0) {
+ normalArray = GLBuffers.sliceGLBuffer(buffer, pos, size, nDataType);
+ } else {
+ normalArray = null;
+ }
+ nOffset = pos;
+ pos+=size;
+
+ size= count * tWidth ;
+ if(size>0) {
+ textCoordArray = GLBuffers.sliceGLBuffer(buffer, pos, size, tDataType);
+ } else {
+ textCoordArray = null;
+ }
+ tOffset = pos;
+ pos+=size;
+
+ buffer.position(pos);
+ buffer.flip();
+
+ if(vComps>0) {
+ vArrayData = GLArrayDataWrapper.createFixed(gl, GLPointerFunc.GL_VERTEX_ARRAY, vComps, vDataType, false,
+ 0, vertexArray, 0, vOffset);
+ } else {
+ vArrayData = null;
+ }
+ if(cComps>0) {
+ cArrayData = GLArrayDataWrapper.createFixed(gl, GLPointerFunc.GL_COLOR_ARRAY, cComps, cDataType, false,
+ 0, colorArray, 0, cOffset);
+ } else {
+ cArrayData = null;
+ }
+ if(nComps>0) {
+ nArrayData = GLArrayDataWrapper.createFixed(gl, GLPointerFunc.GL_NORMAL_ARRAY, nComps, nDataType, false,
+ 0, normalArray, 0, nOffset);
+ } else {
+ nArrayData = null;
+ }
+ if(tComps>0) {
+ tArrayData = GLArrayDataWrapper.createFixed(gl, GLPointerFunc.GL_TEXTURE_COORD_ARRAY, tComps, tDataType, false,
+ 0, textCoordArray, 0, tOffset);
+ } else {
+ tArrayData = null;
+ }
+
+ }
+
+ protected final boolean growBufferIfNecessary(int type, int spare) {
+ if(buffer==null || count < spare) {
+ growBuffer(type, initialSize);
+ return true;
+ }
+ return false;
+ }
+
+ protected final void growBuffer(int type, int additional) {
+ if(sealed || 0==additional) return;
+
+ // save olde values ..
+ Buffer _vertexArray=vertexArray, _colorArray=colorArray, _normalArray=normalArray, _textCoordArray=textCoordArray;
+ ByteBuffer _buffer = buffer;
+
+ allocateBuffer(count+additional);
+
+ if(null!=_vertexArray) {
+ _vertexArray.flip();
+ GLBuffers.put(vertexArray, _vertexArray);
+ }
+ if(null!=_colorArray) {
+ _colorArray.flip();
+ GLBuffers.put(colorArray, _colorArray);
+ }
+ if(null!=_normalArray) {
+ _normalArray.flip();
+ GLBuffers.put(normalArray, _normalArray);
+ }
+ if(null!=_textCoordArray) {
+ _textCoordArray.flip();
+ GLBuffers.put(textCoordArray, _textCoordArray);
+ }
+ }
+
+ protected void padding(int type, int fill) {
+ if ( sealed ) return;
+
+ Buffer dest = null;
+
+ switch (type) {
+ case VERTEX:
+ dest = vertexArray;
+ break;
+ case COLOR:
+ dest = colorArray;
+ break;
+ case NORMAL:
+ dest = normalArray;
+ break;
+ case TEXTCOORD:
+ dest = textCoordArray;
+ break;
+ }
+
+ if ( null==dest ) return;
+
+ while((fill--)>0) {
+ GLBuffers.putb(dest, (byte)0);
+ }
+ }
+
+ protected int mode, modeOrig;
+ protected int glBufferUsage, initialSize;
+
+ protected ByteBuffer buffer;
+ protected int bSize, count, vboName;
+
+ public static final int VERTEX = 0;
+ public static final int COLOR = 1;
+ public static final int NORMAL = 2;
+ public static final int TEXTCOORD = 3;
+
+ protected int vOffset, cOffset, nOffset, tOffset;
+ protected int vComps, cComps, nComps, tComps;
+ protected int vDataType, cDataType, nDataType, tDataType;
+ protected Buffer vertexArray, colorArray, normalArray, textCoordArray;
+ protected GLArrayDataWrapper vArrayData, cArrayData, nArrayData, tArrayData;
+
+ protected boolean sealed, sealedGL, useGLSL;
+ protected boolean bufferEnabled, bufferWritten;
+ protected GL gl;
+ }
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Locator.java b/src/jogl/classes/com/jogamp/opengl/util/Locator.java
new file mode 100644
index 000000000..c524c0888
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/Locator.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.opengl.util;
+
+import java.util.*;
+import java.nio.*;
+import java.io.*;
+import java.net.*;
+
+/** Utilities for dealing with resources. */
+
+public class Locator {
+ private Locator() {}
+
+ /**
+ * Locates the resource using 'getResource(String path, ClassLoader cl)',
+ * with this context ClassLoader and the path as is,
+ * as well with the context's package name path plus the path.
+ *
+ * @see #getResource(String, ClassLoader)
+ */
+ public static URL getResource(Class context, String path) {
+ ClassLoader contextCL = (null!=context)?context.getClassLoader():null;
+ URL url = getResource(path, contextCL);
+ if (url == null && null!=context) {
+ // Try again by scoping the path within the class's package
+ String className = context.getName().replace('.', '/');
+ int lastSlash = className.lastIndexOf('/');
+ if (lastSlash >= 0) {
+ String tmpPath = className.substring(0, lastSlash + 1) + path;
+ url = getResource(tmpPath, contextCL);
+ }
+ }
+ return url;
+ }
+
+ /**
+ * Locates the resource using the ClassLoader's facility,
+ * the absolute URL and absolute file.
+ *
+ * @see ClassLoader#getResource(String)
+ * @see ClassLoader#getSystemResource(String)
+ * @see URL#URL(String)
+ * @see File#File(String)
+ */
+ public static URL getResource(String path, ClassLoader cl) {
+ URL url = null;
+ if (cl != null) {
+ url = cl.getResource(path);
+ } else {
+ url = ClassLoader.getSystemResource(path);
+ }
+ if(!urlExists(url)) {
+ url = null;
+ try {
+ url = new URL(path);
+ } catch (MalformedURLException e) { }
+ }
+ if(!urlExists(url)) {
+ url = null;
+ try {
+ File file = new File(path);
+ if(file.exists()) {
+ url = file.toURL();
+ }
+ } catch (MalformedURLException e) {}
+ }
+ return url;
+ }
+
+ /**
+ * Generates a path for the 'relativeFile' relative to the 'absoluteFileLocation'
+ */
+ public static String getRelativeOf(String absoluteFileLocation, String relativeFile) {
+ File file = new File(absoluteFileLocation);
+ file = file.getParentFile();
+ while (file != null && relativeFile.startsWith("../")) {
+ file = file.getParentFile();
+ relativeFile = relativeFile.substring(3);
+ }
+ if (file != null) {
+ String res = new File(file, relativeFile).getPath();
+ // Handle things on Windows
+ return res.replace('\\', '/');
+ } else {
+ return relativeFile;
+ }
+ }
+
+ /**
+ * Returns true, if the url exists,
+ * trying to open a connection.
+ */
+ public static boolean urlExists(URL url) {
+ boolean v = false;
+ if(null!=url) {
+ try {
+ URLConnection uc = url.openConnection();
+ v = true;
+ } catch (IOException ioe) { }
+ }
+ return v;
+ }
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
new file mode 100755
index 000000000..47de8ce0a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java
@@ -0,0 +1,686 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.opengl.util;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.impl.ProjectFloat;
+
+import java.nio.*;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.media.opengl.*;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+public class PMVMatrix implements GLMatrixFunc {
+
+ public PMVMatrix() {
+ projectFloat = new ProjectFloat();
+
+ matrixIdent = Buffers.newDirectFloatBuffer(1*16);
+ projectFloat.gluMakeIdentityf(matrixIdent);
+ matrixIdent.rewind();
+
+ // T Texture
+ // P Projection
+ // Mv ModelView
+ // Mvi Modelview-Inverse
+ // Mvit Modelview-Inverse-Transpose
+ // Pmv P * Mv
+ matrixTPMvMvitPmv = Buffers.newDirectFloatBuffer(6*16); // grouping T + P + Mv + Mvi + Mvit + Pmv
+ matrixPMvMvitPmv = slice(matrixTPMvMvitPmv, 1*16, 5*16); // grouping P + Mv + Mvi + Mvit + Pmv
+ matrixT = slice(matrixTPMvMvitPmv, 0*16, 1*16); // T
+ matrixPMvMvit = slice(matrixTPMvMvitPmv, 1*16, 4*16); // grouping P + Mv + Mvi + Mvit
+ matrixPMvMvi = slice(matrixTPMvMvitPmv, 1*16, 3*16); // grouping P + Mv + Mvi
+ matrixPMv = slice(matrixTPMvMvitPmv, 1*16, 2*16); // grouping P + Mv
+ matrixP = slice(matrixTPMvMvitPmv, 1*16, 1*16); // P
+ matrixMv = slice(matrixTPMvMvitPmv, 2*16, 1*16); // Mv
+ matrixMvi = slice(matrixTPMvMvitPmv, 3*16, 1*16); // Mvi
+ matrixMvit = slice(matrixTPMvMvitPmv, 4*16, 1*16); // Mvit
+ matrixPmv = slice(matrixTPMvMvitPmv, 5*16, 1*16); // Pmv
+ matrixTPMvMvitPmv.rewind();
+
+ matrixMvit3 = Buffers.newDirectFloatBuffer(3*3);
+
+ localBuf = Buffers.newDirectFloatBuffer(6*16);
+
+ matrixMult=slice(localBuf, 0*16, 16);
+
+ matrixTrans=slice(localBuf, 1*16, 16);
+ projectFloat.gluMakeIdentityf(matrixTrans);
+
+ matrixRot=slice(localBuf, 2*16, 16);
+ projectFloat.gluMakeIdentityf(matrixRot);
+
+ matrixScale=slice(localBuf, 3*16, 16);
+ projectFloat.gluMakeIdentityf(matrixScale);
+
+ matrixOrtho=slice(localBuf, 4*16, 16);
+ projectFloat.gluMakeIdentityf(matrixOrtho);
+
+ matrixFrustum=slice(localBuf, 5*16, 16);
+ projectFloat.gluMakeZero(matrixFrustum);
+
+ vec3f=new float[3];
+
+ matrixPStack = new ArrayList();
+ matrixMvStack= new ArrayList();
+
+ // default values and mode
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glMatrixMode(GL.GL_TEXTURE);
+ glLoadIdentity();
+ setDirty();
+ }
+
+ public void destroy() {
+ if(null!=projectFloat) {
+ projectFloat.destroy(); projectFloat=null;
+ }
+
+ if(null!=matrixIdent) {
+ matrixIdent.clear(); matrixIdent=null;
+ }
+ if(null!=matrixTPMvMvitPmv) {
+ matrixTPMvMvitPmv.clear(); matrixTPMvMvitPmv=null;
+ }
+ if(null!=matrixMvit3) {
+ matrixMvit3.clear(); matrixMvit3=null;
+ }
+ if(null!=localBuf) {
+ localBuf.clear(); localBuf=null;
+ }
+
+ if(null!=matrixPStack) {
+ matrixPStack.clear(); matrixPStack=null;
+ }
+ vec3f=null;
+ if(null!=matrixMvStack) {
+ matrixMvStack.clear(); matrixMvStack=null;
+ }
+ if(null!=matrixPStack) {
+ matrixPStack.clear(); matrixPStack=null;
+ }
+ if(null!=matrixTStack) {
+ matrixTStack.clear(); matrixTStack=null;
+ }
+
+ matrixTPMvMvitPmv=null; matrixPMvMvit=null; matrixPMvMvitPmv=null; matrixPMvMvi=null; matrixPMv=null;
+ matrixP=null; matrixT=null; matrixMv=null; matrixMvi=null; matrixMvit=null; matrixPmv=null;
+ matrixMult=null; matrixTrans=null; matrixRot=null; matrixScale=null; matrixOrtho=null; matrixFrustum=null;
+ }
+
+ private static FloatBuffer slice(FloatBuffer buf, int pos, int len) {
+ buf.position(pos);
+ buf.limit(pos + len);
+ return buf.slice();
+ }
+
+ public static final boolean isMatrixModeName(final int matrixModeName) {
+ switch(matrixModeName) {
+ case GL_MODELVIEW_MATRIX:
+ case GL_PROJECTION_MATRIX:
+ case GL_TEXTURE_MATRIX:
+ return true;
+ }
+ return false;
+ }
+
+ public static final int matrixModeName2MatrixGetName(final int matrixModeName) {
+ switch(matrixModeName) {
+ case GL_MODELVIEW:
+ return GL_MODELVIEW_MATRIX;
+ case GL_PROJECTION:
+ return GL_PROJECTION_MATRIX;
+ case GL.GL_TEXTURE:
+ return GL_TEXTURE_MATRIX;
+ default:
+ throw new GLException("unsupported matrixName: "+matrixModeName);
+ }
+ }
+
+ public static final boolean isMatrixGetName(final int matrixGetName) {
+ switch(matrixGetName) {
+ case GL_MATRIX_MODE:
+ case GL_MODELVIEW_MATRIX:
+ case GL_PROJECTION_MATRIX:
+ case GL_TEXTURE_MATRIX:
+ return true;
+ }
+ return false;
+ }
+
+ public static final int matrixGetName2MatrixModeName(final int matrixGetName) {
+ switch(matrixGetName) {
+ case GL_MODELVIEW_MATRIX:
+ return GL_MODELVIEW;
+ case GL_PROJECTION_MATRIX:
+ return GL_PROJECTION;
+ case GL_TEXTURE_MATRIX:
+ return GL.GL_TEXTURE;
+ default:
+ throw new GLException("unsupported matrixGetName: "+matrixGetName);
+ }
+ }
+
+ public void setDirty() {
+ modified = DIRTY_MODELVIEW | DIRTY_PROJECTION | DIRTY_TEXTURE ;
+ matrixMode = GL_MODELVIEW;
+ }
+
+ public int getDirtyBits() {
+ return modified;
+ }
+
+ public boolean isDirty(final int matrixName) {
+ boolean res;
+ switch(matrixName) {
+ case GL_MODELVIEW:
+ res = (modified&DIRTY_MODELVIEW)!=0 ;
+ break;
+ case GL_PROJECTION:
+ res = (modified&DIRTY_PROJECTION)!=0 ;
+ break;
+ case GL.GL_TEXTURE:
+ res = (modified&DIRTY_TEXTURE)!=0 ;
+ break;
+ default:
+ throw new GLException("unsupported matrixName: "+matrixName);
+ }
+ return res;
+ }
+
+ public boolean isDirty() {
+ return modified!=0;
+ }
+
+ public boolean update() {
+ // if(0==modified) return false;
+
+ // int res = modified;
+ int res = DIRTY_MODELVIEW | DIRTY_PROJECTION ;
+ if( (res&DIRTY_MODELVIEW)!=0 ) {
+ setMviMvit();
+ }
+ if( (res&DIRTY_MODELVIEW)!=0 || (res&DIRTY_PROJECTION)!=0 ) {
+ glMultMatrixf(matrixP, matrixMv, matrixPmv);
+ }
+ modified=0;
+ return res!=0;
+ }
+
+ public final int glGetMatrixMode() {
+ return matrixMode;
+ }
+
+ public final FloatBuffer glGetTMatrixf() {
+ return matrixT;
+ }
+
+ public final FloatBuffer glGetPMatrixf() {
+ return matrixP;
+ }
+
+ public final FloatBuffer glGetMvMatrixf() {
+ return matrixMv;
+ }
+
+ public final FloatBuffer glGetPMvMvitPmvMatrixf() {
+ return matrixPMvMvitPmv;
+ }
+
+ public final FloatBuffer glGetPMvMvitMatrixf() {
+ return matrixPMvMvit;
+ }
+
+ public final FloatBuffer glGetPMvMviMatrixf() {
+ return matrixPMvMvi;
+ }
+
+ public final FloatBuffer glGetPMvMatrixf() {
+ return matrixPMv;
+ }
+
+ public final FloatBuffer glGetMviMatrixf() {
+ return matrixMvi;
+ }
+
+ public final FloatBuffer glGetPmvMatrixf() {
+ return matrixPmv;
+ }
+
+ public final FloatBuffer glGetNormalMatrixf() {
+ return matrixMvit3;
+ }
+
+ /*
+ * @return the current matrix
+ */
+ public final FloatBuffer glGetMatrixf() {
+ return glGetMatrixf(matrixMode);
+ }
+
+ /**
+ * @param matrixName GL_MODELVIEW, GL_PROJECTION or GL.GL_TEXTURE
+ * @return the given matrix
+ */
+ public final FloatBuffer glGetMatrixf(final int matrixName) {
+ if(matrixName==GL_MODELVIEW) {
+ return matrixMv;
+ } else if(matrixName==GL_PROJECTION) {
+ return matrixP;
+ } else if(matrixName==GL.GL_TEXTURE) {
+ return matrixT;
+ } else {
+ throw new GLException("unsupported matrixName: "+matrixName);
+ }
+ }
+
+ public final void gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) {
+ float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear;
+ float bottom=-1.0f*top;
+ float left=aspect*bottom;
+ float right=aspect*top;
+ glFrustumf(left, right, bottom, top, zNear, zFar);
+ }
+
+ public static final void glMultMatrixf(final FloatBuffer a, final FloatBuffer b, FloatBuffer p) {
+ for (int i = 0; i < 4; i++) {
+ final float ai0=a.get(i+0*4), ai1=a.get(i+1*4), ai2=a.get(i+2*4), ai3=a.get(i+3*4);
+ p.put(i+0*4 , ai0 * b.get(0+0*4) + ai1 * b.get(1+0*4) + ai2 * b.get(2+0*4) + ai3 * b.get(3+0*4) );
+ p.put(i+1*4 , ai0 * b.get(0+1*4) + ai1 * b.get(1+1*4) + ai2 * b.get(2+1*4) + ai3 * b.get(3+1*4) );
+ p.put(i+2*4 , ai0 * b.get(0+2*4) + ai1 * b.get(1+2*4) + ai2 * b.get(2+2*4) + ai3 * b.get(3+2*4) );
+ p.put(i+3*4 , ai0 * b.get(0+3*4) + ai1 * b.get(1+3*4) + ai2 * b.get(2+3*4) + ai3 * b.get(3+3*4) );
+ }
+ }
+ public static final void glMultMatrixf(final FloatBuffer a, final float[] b, int b_off, FloatBuffer p) {
+ for (int i = 0; i < 4; i++) {
+ final float ai0=a.get(i+0*4), ai1=a.get(i+1*4), ai2=a.get(i+2*4), ai3=a.get(i+3*4);
+ p.put(i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] );
+ p.put(i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] );
+ p.put(i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] );
+ p.put(i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] );
+ }
+ }
+
+ //
+ // MatrixIf
+ //
+
+ public void glMatrixMode(final int matrixName) {
+ switch(matrixName) {
+ case GL_MODELVIEW:
+ case GL_PROJECTION:
+ case GL.GL_TEXTURE:
+ break;
+ default:
+ throw new GLException("unsupported matrixName: "+matrixName);
+ }
+ matrixMode = matrixName;
+ }
+
+ public void glGetFloatv(int matrixGetName, FloatBuffer params) {
+ int pos = params.position();
+ if(matrixGetName==GL_MATRIX_MODE) {
+ params.put((float)matrixMode);
+ } else {
+ FloatBuffer matrix = glGetMatrixf(matrixGetName2MatrixModeName(matrixGetName));
+ params.put(matrix);
+ matrix.rewind();
+ }
+ params.position(pos);
+ }
+ public void glGetFloatv(int matrixGetName, float[] params, int params_offset) {
+ if(matrixGetName==GL_MATRIX_MODE) {
+ params[params_offset]=(float)matrixMode;
+ } else {
+ FloatBuffer matrix = glGetMatrixf(matrixGetName2MatrixModeName(matrixGetName));
+ matrix.get(params, params_offset, 16);
+ matrix.rewind();
+ }
+ }
+ public void glGetIntegerv(int pname, IntBuffer params) {
+ int pos = params.position();
+ if(pname==GL_MATRIX_MODE) {
+ params.put(matrixMode);
+ } else {
+ throw new GLException("unsupported pname: "+pname);
+ }
+ params.position(pos);
+ }
+ public void glGetIntegerv(int pname, int[] params, int params_offset) {
+ if(pname==GL_MATRIX_MODE) {
+ params[params_offset]=matrixMode;
+ } else {
+ throw new GLException("unsupported pname: "+pname);
+ }
+ }
+
+ public final void glLoadMatrixf(final float[] values, final int offset) {
+ int len = values.length-offset;
+ if(matrixMode==GL_MODELVIEW) {
+ matrixMv.clear();
+ matrixMv.put(values, offset, len);
+ matrixMv.rewind();
+ modified |= DIRTY_MODELVIEW ;
+ } else if(matrixMode==GL_PROJECTION) {
+ matrixP.clear();
+ matrixP.put(values, offset, len);
+ matrixP.rewind();
+ modified |= DIRTY_PROJECTION ;
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ matrixT.clear();
+ matrixT.put(values, offset, len);
+ matrixT.rewind();
+ modified |= DIRTY_TEXTURE ;
+ }
+ }
+
+ public final void glLoadMatrixf(java.nio.FloatBuffer m) {
+ int spos = m.position();
+ if(matrixMode==GL_MODELVIEW) {
+ matrixMv.clear();
+ matrixMv.put(m);
+ matrixMv.rewind();
+ modified |= DIRTY_MODELVIEW ;
+ } else if(matrixMode==GL_PROJECTION) {
+ matrixP.clear();
+ matrixP.put(m);
+ matrixP.rewind();
+ modified |= DIRTY_PROJECTION ;
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ matrixT.clear();
+ matrixT.put(m);
+ matrixT.rewind();
+ modified |= DIRTY_TEXTURE ;
+ }
+ m.position(spos);
+ }
+
+ public final void glPopMatrix() {
+ float[] stackEntry=null;
+ if(matrixMode==GL_MODELVIEW) {
+ stackEntry = (float[])matrixMvStack.remove(0);
+ } else if(matrixMode==GL_PROJECTION) {
+ stackEntry = (float[])matrixPStack.remove(0);
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ stackEntry = (float[])matrixTStack.remove(0);
+ }
+ glLoadMatrixf(stackEntry, 0);
+ }
+
+ public final void glPushMatrix() {
+ float[] stackEntry = new float[1*16];
+ if(matrixMode==GL_MODELVIEW) {
+ matrixMv.get(stackEntry);
+ matrixMv.rewind();
+ matrixMvStack.add(0, stackEntry);
+ } else if(matrixMode==GL_PROJECTION) {
+ matrixP.get(stackEntry);
+ matrixP.rewind();
+ matrixPStack.add(0, stackEntry);
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ matrixT.get(stackEntry);
+ matrixT.rewind();
+ matrixTStack.add(0, stackEntry);
+ }
+ }
+
+ public final void glLoadIdentity() {
+ if(matrixMode==GL_MODELVIEW) {
+ matrixMv.clear();
+ matrixMv.put(matrixIdent);
+ matrixMv.rewind();
+ matrixIdent.rewind();
+ modified |= DIRTY_MODELVIEW ;
+ } else if(matrixMode==GL_PROJECTION) {
+ matrixP.clear();
+ matrixP.put(matrixIdent);
+ matrixP.rewind();
+ matrixIdent.rewind();
+ modified |= DIRTY_PROJECTION ;
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ matrixT.clear();
+ matrixT.put(matrixIdent);
+ matrixT.rewind();
+ matrixIdent.rewind();
+ modified |= DIRTY_TEXTURE ;
+ }
+ }
+
+ public final void glMultMatrixf(final FloatBuffer m) {
+ if(matrixMode==GL_MODELVIEW) {
+ glMultMatrixf(matrixMv, m, matrixMult);
+ matrixMv.clear();
+ matrixMv.put(matrixMult);
+ matrixMv.rewind();
+ modified |= DIRTY_MODELVIEW ;
+ } else if(matrixMode==GL_PROJECTION) {
+ glMultMatrixf(matrixP, m, matrixMult);
+ matrixP.clear();
+ matrixP.put(matrixMult);
+ matrixP.rewind();
+ modified |= DIRTY_PROJECTION ;
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ glMultMatrixf(matrixT, m, matrixMult);
+ matrixT.clear();
+ matrixT.put(matrixMult);
+ matrixT.rewind();
+ modified |= DIRTY_TEXTURE ;
+ }
+ matrixMult.rewind();
+ }
+
+ public void glMultMatrixf(float[] m, int m_offset) {
+ if(matrixMode==GL_MODELVIEW) {
+ glMultMatrixf(matrixMv, m, m_offset, matrixMult);
+ matrixMv.clear();
+ matrixMv.put(matrixMult);
+ matrixMv.rewind();
+ modified |= DIRTY_MODELVIEW ;
+ } else if(matrixMode==GL_PROJECTION) {
+ glMultMatrixf(matrixP, m, m_offset, matrixMult);
+ matrixP.clear();
+ matrixP.put(matrixMult);
+ matrixP.rewind();
+ modified |= DIRTY_PROJECTION ;
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ glMultMatrixf(matrixT, m, m_offset, matrixMult);
+ matrixT.clear();
+ matrixT.put(matrixMult);
+ matrixT.rewind();
+ modified |= DIRTY_TEXTURE ;
+ }
+ matrixMult.rewind();
+ }
+
+ public final void glTranslatef(final float x, final float y, final float z) {
+ // Translation matrix:
+ // 1 0 0 x
+ // 0 1 0 y
+ // 0 0 1 z
+ // 0 0 0 1
+ matrixTrans.put(0+4*3, x);
+ matrixTrans.put(1+4*3, y);
+ matrixTrans.put(2+4*3, z);
+ glMultMatrixf(matrixTrans);
+ }
+
+ public final void glRotatef(final float angdeg, float x, float y, float z) {
+ float angrad = angdeg * (float) Math.PI / 180;
+ float c = (float)Math.cos(angrad);
+ float ic= 1.0f - c;
+ float s = (float)Math.sin(angrad);
+
+ vec3f[0]=x; vec3f[1]=y; vec3f[2]=z;
+ projectFloat.normalize(vec3f);
+ x = vec3f[0]; y = vec3f[1]; z = vec3f[2];
+
+ // Rotation matrix:
+ // xx(1−c)+c xy(1−c)+zs xz(1−c)-ys 0
+ // xy(1−c)-zs yy(1−c)+c yz(1−c)+xs 0
+ // xz(1−c)+ys yz(1−c)-xs zz(1−c)+c 0
+ // 0 0 0 1
+ float xy = x*y;
+ float xz = x*z;
+ float xs = x*s;
+ float ys = y*s;
+ float yz = y*z;
+ float zs = z*s;
+ matrixRot.put(0*4+0, x*x*ic+c);
+ matrixRot.put(0*4+1, xy*ic+zs);
+ matrixRot.put(0*4+2, xz*ic-ys);
+
+ matrixRot.put(1*4+0, xy*ic-zs);
+ matrixRot.put(1*4+1, y*y*ic+c);
+ matrixRot.put(1*4+2, yz*ic+xs);
+
+ matrixRot.put(2*4+0, xz*ic+ys);
+ matrixRot.put(2*4+1, yz*ic-xs);
+ matrixRot.put(2*4+2, z*z*ic+c);
+
+ glMultMatrixf(matrixRot);
+ }
+
+ public final void glScalef(final float x, final float y, final float z) {
+ // Scale matrix:
+ // x 0 0 0
+ // 0 y 0 0
+ // 0 0 z 0
+ // 0 0 0 1
+ matrixScale.put(0+4*0, x);
+ matrixScale.put(1+4*1, y);
+ matrixScale.put(2+4*2, z);
+
+ glMultMatrixf(matrixScale);
+ }
+
+ public final void glOrthof(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) {
+ // Ortho matrix:
+ // 2/dx 0 0 tx
+ // 0 2/dy 0 ty
+ // 0 0 2/dz tz
+ // 0 0 0 1
+ float dx=right-left;
+ float dy=top-bottom;
+ float dz=zFar-zNear;
+ float tx=-1.0f*(right+left)/dx;
+ float ty=-1.0f*(top+bottom)/dy;
+ float tz=-1.0f*(zFar+zNear)/dz;
+
+ matrixOrtho.put(0+4*0, 2.0f/dx);
+ matrixOrtho.put(1+4*1, 2.0f/dy);
+ matrixOrtho.put(2+4*2, -2.0f/dz);
+ matrixOrtho.put(0+4*3, tx);
+ matrixOrtho.put(1+4*3, ty);
+ matrixOrtho.put(2+4*3, tz);
+
+ glMultMatrixf(matrixOrtho);
+ }
+
+ public final void glFrustumf(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) {
+ if(zNear<=0.0f||zFar<0.0f) {
+ throw new GLException("GL_INVALID_VALUE: zNear and zFar must be positive, and zNear>0");
+ }
+ if(left==right || top==bottom) {
+ throw new GLException("GL_INVALID_VALUE: top,bottom and left,right must not be equal");
+ }
+ // Frustum matrix:
+ // 2*zNear/dx 0 A 0
+ // 0 2*zNear/dy B 0
+ // 0 0 C D
+ // 0 0 −1 0
+ float zNear2 = 2.0f*zNear;
+ float dx=right-left;
+ float dy=top-bottom;
+ float dz=zFar-zNear;
+ float A=(right+left)/dx;
+ float B=(top+bottom)/dy;
+ float C=-1.0f*(zFar+zNear)/dz;
+ float D=-2.0f*(zFar*zNear)/dz;
+
+ matrixFrustum.put(0+4*0, zNear2/dx);
+ matrixFrustum.put(1+4*1, zNear2/dy);
+ matrixFrustum.put(2+4*2, C);
+
+ matrixFrustum.put(0+4*2, A);
+ matrixFrustum.put(1+4*2, B);
+
+ matrixFrustum.put(2+4*3, D);
+ matrixFrustum.put(3+4*2, -1.0f);
+
+ glMultMatrixf(matrixFrustum);
+ }
+
+ //
+ // private
+ //
+
+ private final void setMviMvit() {
+ if(!projectFloat.gluInvertMatrixf(matrixMv, matrixMvi)) {
+ throw new GLException("Invalid source Mv matrix, can't compute inverse");
+ }
+
+ // transpose matrix
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ matrixMvit.put(j+i*4, matrixMvi.get(i+j*4));
+ }
+ }
+
+ // fetch 3x3
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ matrixMvit3.put(i+j*3, matrixMvit.get(i+j*4));
+ }
+ }
+ }
+
+ protected FloatBuffer matrixIdent;
+ protected FloatBuffer matrixTPMvMvitPmv, matrixPMvMvit, matrixPMvMvitPmv, matrixPMvMvi, matrixPMv, matrixP, matrixT, matrixMv, matrixMvi, matrixMvit, matrixPmv;
+ protected FloatBuffer matrixMvit3;
+ protected FloatBuffer localBuf, matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum;
+ protected float[] vec3f;
+ protected List/*FloatBuffer*/ matrixTStack, matrixPStack, matrixMvStack;
+ protected int matrixMode = GL_MODELVIEW;
+ protected int modified = 0;
+ protected ProjectFloat projectFloat;
+
+ public static final int DIRTY_MODELVIEW = 1 << 0;
+ public static final int DIRTY_PROJECTION = 1 << 1;
+ public static final int DIRTY_TEXTURE = 1 << 2;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/StreamUtil.java b/src/jogl/classes/com/jogamp/opengl/util/StreamUtil.java
new file mode 100755
index 000000000..4cf8cb1f0
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/StreamUtil.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util;
+
+import java.io.*;
+import java.nio.*;
+
+/** Utilities for dealing with streams. */
+
+public class StreamUtil {
+ private StreamUtil() {}
+
+ public static byte[] readAll2Array(InputStream stream) throws IOException {
+ BytesRead bytesRead = readAllImpl(stream);
+ byte[] data = bytesRead.data;
+ if (bytesRead.payloadLen != data.length) {
+ data = new byte[bytesRead.payloadLen];
+ System.arraycopy(bytesRead.data, 0, data, 0, bytesRead.payloadLen);
+ }
+ return data;
+ }
+
+ public static ByteBuffer readAll2Buffer(InputStream stream) throws IOException {
+ BytesRead bytesRead = readAllImpl(stream);
+ return GLBuffers.newDirectByteBuffer(bytesRead.data, 0, bytesRead.payloadLen);
+ }
+
+ private static BytesRead readAllImpl(InputStream stream) throws IOException {
+ // FIXME: Shall we do this here ?
+ if( !(stream instanceof BufferedInputStream) ) {
+ stream = new BufferedInputStream(stream);
+ }
+ int avail = stream.available();
+ byte[] data = new byte[avail];
+ int numRead = 0;
+ int pos = 0;
+ do {
+ if (pos + avail > data.length) {
+ byte[] newData = new byte[pos + avail];
+ System.arraycopy(data, 0, newData, 0, pos);
+ data = newData;
+ }
+ numRead = stream.read(data, pos, avail);
+ if (numRead >= 0) {
+ pos += numRead;
+ }
+ avail = stream.available();
+ } while (avail > 0 && numRead >= 0);
+
+ return new BytesRead(pos, data);
+ }
+
+ private static class BytesRead {
+ BytesRead(int payloadLen, byte[] data) {
+ this.payloadLen=payloadLen;
+ this.data=data;
+ }
+ int payloadLen;
+ byte[] data;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/TGAWriter.java b/src/jogl/classes/com/jogamp/opengl/util/TGAWriter.java
new file mode 100755
index 000000000..b949f0e39
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/TGAWriter.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.util;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+
+/**
+ * Utility class which helps take fast screenshots of OpenGL rendering
+ * results into Targa-format files. Used by the {@link com.jogamp.opengl.util.awt.Screenshot}
+ * class; can also be used in conjunction with the {@link com.jogamp.opengl.util.gl2.TileRenderer} class.
+ */
+public class TGAWriter {
+
+ private static final int TARGA_HEADER_SIZE = 18;
+
+ private FileChannel ch;
+ private ByteBuffer buf;
+
+ /** Constructor for the TGAWriter. */
+ public TGAWriter() {
+ }
+
+ /**
+ * Opens the specified Targa file for writing, overwriting any
+ * existing file, and sets up the header of the file expecting the
+ * data to be filled in before closing it.
+ *
+ * @param file the file to write containing the screenshot
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ * @param alpha whether the alpha channel should be saved. If true,
+ * requires GL_EXT_abgr extension to be present.
+ *
+ * @throws IOException if an I/O error occurred while writing the
+ * file
+ */
+ public void open(File file,
+ int width,
+ int height,
+ boolean alpha) throws IOException {
+ RandomAccessFile out = new RandomAccessFile(file, "rw");
+ ch = out.getChannel();
+ int pixelSize = (alpha ? 32 : 24);
+ int numChannels = (alpha ? 4 : 3);
+
+ int fileLength = TARGA_HEADER_SIZE + width * height * numChannels;
+ out.setLength(fileLength);
+ MappedByteBuffer image = ch.map(FileChannel.MapMode.READ_WRITE, 0, fileLength);
+
+ // write the TARGA header
+ image.put(0, (byte) 0).put(1, (byte) 0);
+ image.put(2, (byte) 2); // uncompressed type
+ image.put(12, (byte) (width & 0xFF)); // width
+ image.put(13, (byte) (width >> 8)); // width
+ image.put(14, (byte) (height & 0xFF)); // height
+ image.put(15, (byte) (height >> 8)); // height
+ image.put(16, (byte) pixelSize); // pixel size
+
+ // go to image data position
+ image.position(TARGA_HEADER_SIZE);
+ // jogl needs a sliced buffer
+ buf = image.slice();
+ }
+
+ /**
+ * Returns the ByteBuffer corresponding to the data for the image.
+ * This must be filled in with data in either BGR or BGRA format
+ * depending on whether an alpha channel was specified during
+ * open().
+ */
+ public ByteBuffer getImageData() {
+ return buf;
+ }
+
+ public void close() throws IOException {
+ // close the file channel
+ ch.close();
+ buf = null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/ImageUtil.java b/src/jogl/classes/com/jogamp/opengl/util/awt/ImageUtil.java
new file mode 100755
index 000000000..a3139b16a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/ImageUtil.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.awt;
+
+import java.awt.*;
+import java.awt.image.*;
+
+/** Utilities for dealing with images. */
+
+public class ImageUtil {
+ private ImageUtil() {}
+
+ /** Flips the supplied BufferedImage vertically. This is often a
+ necessary conversion step to display a Java2D image correctly
+ with OpenGL and vice versa. */
+ public static void flipImageVertically(BufferedImage image) {
+ WritableRaster raster = image.getRaster();
+ Object scanline1 = null;
+ Object scanline2 = null;
+
+ for (int i = 0; i < image.getHeight() / 2; i++) {
+ scanline1 = raster.getDataElements(0, i, image.getWidth(), 1, scanline1);
+ scanline2 = raster.getDataElements(0, image.getHeight() - i - 1, image.getWidth(), 1, scanline2);
+ raster.setDataElements(0, i, image.getWidth(), 1, scanline2);
+ raster.setDataElements(0, image.getHeight() - i - 1, image.getWidth(), 1, scanline1);
+ }
+ }
+
+ /**
+ * Creates a <code>BufferedImage</code> with a pixel format compatible with the graphics
+ * environment. The returned image can thus benefit from hardware accelerated operations
+ * in Java2D API.
+ *
+ * @param width The width of the image to be created
+ * @param height The height of the image to be created
+ *
+ * @return A instance of <code>BufferedImage</code> with a type compatible with the graphics card.
+ */
+ public static BufferedImage createCompatibleImage(int width, int height) {
+ GraphicsConfiguration configuration =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration();
+ return configuration.createCompatibleImage(width, height);
+ }
+
+ /**
+ * Creates a thumbnail from an image. A thumbnail is a scaled down version of the original picture.
+ * This method will retain the width to height ratio of the original picture and return a new
+ * instance of <code>BufferedImage</code>. The original picture is not modified.
+ *
+ * @param image The original image to sample down
+ * @param thumbWidth The width of the thumbnail to be created
+ *
+ * @throws IllegalArgumentException If thumbWidth is greater than image.getWidth()
+ *
+ * @return A thumbnail with the requested width or the original picture if thumbWidth = image.getWidth()
+ */
+ public static BufferedImage createThumbnail(BufferedImage image, int thumbWidth) {
+ // Thanks to Romain Guy for this utility
+ if (thumbWidth > image.getWidth()) {
+ throw new IllegalArgumentException("Thumbnail width must be greater than image width");
+ }
+
+ if (thumbWidth == image.getWidth()) {
+ return image;
+ }
+
+ float ratio = (float) image.getWidth() / (float) image.getHeight();
+ int width = image.getWidth();
+ BufferedImage thumb = image;
+
+ do {
+ width /= 2;
+ if (width < thumbWidth) {
+ width = thumbWidth;
+ }
+
+ BufferedImage temp = createCompatibleImage(width, (int) (width / ratio));
+ Graphics2D g2 = temp.createGraphics();
+ g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+ g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
+ g2.dispose();
+ thumb = temp;
+ } while (width != thumbWidth);
+
+ return thumb;
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/Overlay.java b/src/jogl/classes/com/jogamp/opengl/util/awt/Overlay.java
new file mode 100755
index 000000000..1275c9391
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/Overlay.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.awt;
+
+import java.awt.Graphics2D;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.texture.*;
+
+/** Provides a Java 2D overlay on top of an arbitrary GLDrawable,
+ making it easier to do things like draw text and images on top of
+ an OpenGL scene while still maintaining reasonably good
+ efficiency. */
+
+public class Overlay {
+ private GLDrawable drawable;
+ private TextureRenderer renderer;
+ private boolean contentsLost;
+
+ /** Creates a new Java 2D overlay on top of the specified
+ GLDrawable. */
+ public Overlay(GLDrawable drawable) {
+ this.drawable = drawable;
+ }
+
+ /** Creates a {@link java.awt.Graphics2D Graphics2D} instance for
+ rendering into the overlay. The returned object should be
+ disposed of using the normal {@link java.awt.Graphics#dispose()
+ Graphics.dispose()} method once it is no longer being used.
+
+ @return a new {@link java.awt.Graphics2D Graphics2D} object for
+ rendering into the backing store of this renderer
+ */
+ public Graphics2D createGraphics() {
+ // Validate the size of the renderer against the current size of
+ // the drawable
+ validateRenderer();
+ return renderer.createGraphics();
+ }
+
+ /** Indicates whether the Java 2D contents of the overlay were lost
+ since the last time {@link #createGraphics} was called. This
+ method should be called immediately after calling {@link
+ #createGraphics} to see whether the entire contents of the
+ overlay need to be redrawn or just the region the application is
+ interested in updating.
+
+ @return whether the contents of the overlay were lost since the
+ last render
+ */
+ public boolean contentsLost() {
+ return contentsLost;
+ }
+
+ /** Marks the given region of the overlay as dirty. This region, and
+ any previously set dirty regions, will be automatically
+ synchronized with the underlying Texture during the next {@link
+ #draw draw} or {@link #drawAll drawAll} operation, at which
+ point the dirty region will be cleared. It is not necessary for
+ an OpenGL context to be current when this method is called.
+
+ @param x the x coordinate (in Java 2D coordinates -- relative to
+ upper left) of the region to update
+ @param y the y coordinate (in Java 2D coordinates -- relative to
+ upper left) of the region to update
+ @param width the width of the region to update
+ @param height the height of the region to update
+
+ @throws GLException If an OpenGL context is not current when this method is called */
+ public void markDirty(int x, int y, int width, int height) {
+ renderer.markDirty(x, y, width, height);
+ }
+
+ /** Draws the entire contents of the overlay on top of the OpenGL
+ drawable. This is a convenience method which encapsulates all
+ portions of the rendering process; if this method is used,
+ {@link #beginRendering}, {@link #endRendering}, etc. should not
+ be used. This method should be called while the OpenGL context
+ for the drawable is current, and after your OpenGL scene has
+ been rendered.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void drawAll() throws GLException {
+ beginRendering();
+ draw(0, 0, drawable.getWidth(), drawable.getHeight());
+ endRendering();
+ }
+
+ /** Begins the OpenGL rendering process for the overlay. This is
+ separated out so advanced applications can render independent
+ pieces of the overlay to different portions of the drawable.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void beginRendering() throws GLException {
+ renderer.beginOrthoRendering(drawable.getWidth(), drawable.getHeight());
+ }
+
+ /** Ends the OpenGL rendering process for the overlay. This is
+ separated out so advanced applications can render independent
+ pieces of the overlay to different portions of the drawable.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void endRendering() throws GLException {
+ renderer.endOrthoRendering();
+ }
+
+ /** Draws the specified sub-rectangle of the overlay on top of the
+ OpenGL drawable. {@link #beginRendering} and {@link
+ #endRendering} must be used in conjunction with this method to
+ achieve proper rendering results. This method should be called
+ while the OpenGL context for the drawable is current, and after
+ your OpenGL scene has been rendered.
+
+ @param x the lower-left x coordinate (relative to the lower left
+ of the overlay) of the rectangle to draw
+ @param y the lower-left y coordinate (relative to the lower left
+ of the overlay) of the rectangle to draw
+ @param width the width of the rectangle to draw
+ @param height the height of the rectangle to draw
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void draw(int x, int y, int width, int height) throws GLException {
+ draw(x, y, x, y, width, height);
+ }
+
+ /** Draws the specified sub-rectangle of the overlay at the
+ specified x and y coordinate on top of the OpenGL drawable.
+ {@link #beginRendering} and {@link #endRendering} must be used
+ in conjunction with this method to achieve proper rendering
+ results. This method should be called while the OpenGL context
+ for the drawable is current, and after your OpenGL scene has
+ been rendered.
+
+ @param screenx the on-screen x coordinate at which to draw the rectangle
+ @param screeny the on-screen y coordinate (relative to lower left) at
+ which to draw the rectangle
+ @param overlayx the x coordinate of the pixel in the overlay of
+ the lower left portion of the rectangle to draw
+ @param overlayy the y coordinate of the pixel in the overlay
+ (relative to lower left) of the lower left portion of the
+ rectangle to draw
+ @param width the width of the rectangle to draw
+ @param height the height of the rectangle to draw
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void draw(int screenx, int screeny,
+ int overlayx, int overlayy,
+ int width, int height) throws GLException {
+ renderer.drawOrthoRect(screenx, screeny,
+ overlayx, overlayy,
+ width, height);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private void validateRenderer() {
+ if (renderer == null) {
+ renderer = new TextureRenderer(drawable.getWidth(),
+ drawable.getHeight(),
+ true);
+ contentsLost = true;
+ } else if (renderer.getWidth() != drawable.getWidth() ||
+ renderer.getHeight() != drawable.getHeight()) {
+ renderer.setSize(drawable.getWidth(), drawable.getHeight());
+ contentsLost = true;
+ } else {
+ contentsLost = false;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java b/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java
new file mode 100755
index 000000000..7019d720f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.util.awt;
+
+import java.awt.image.*;
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import javax.imageio.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import javax.media.opengl.glu.gl2.*;
+
+import com.jogamp.opengl.util.*;
+
+/** Utilities for taking screenshots of OpenGL applications. */
+
+public class Screenshot {
+ private Screenshot() {}
+
+ /**
+ * Takes a fast screenshot of the current OpenGL drawable to a Targa
+ * file. Requires the OpenGL context for the desired drawable to be
+ * current. Takes the screenshot from the last assigned read buffer,
+ * or the OpenGL default read buffer if none has been specified by
+ * the user (GL_FRONT for single-buffered configurations and GL_BACK
+ * for double-buffered configurations). This is the fastest
+ * mechanism for taking a screenshot of an application. Contributed
+ * by Carsten Weisse of Bytonic Software (http://bytonic.de/). <p>
+ *
+ * No alpha channel is written with this variant.
+ *
+ * @param file the file to write containing the screenshot
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ * @throws IOException if an I/O error occurred while writing the
+ * file
+ */
+ public static void writeToTargaFile(File file,
+ int width,
+ int height) throws GLException, IOException {
+ writeToTargaFile(file, width, height, false);
+ }
+
+ /**
+ * Takes a fast screenshot of the current OpenGL drawable to a Targa
+ * file. Requires the OpenGL context for the desired drawable to be
+ * current. Takes the screenshot from the last assigned read buffer,
+ * or the OpenGL default read buffer if none has been specified by
+ * the user (GL_FRONT for single-buffered configurations and GL_BACK
+ * for double-buffered configurations). This is the fastest
+ * mechanism for taking a screenshot of an application. Contributed
+ * by Carsten Weisse of Bytonic Software (http://bytonic.de/).
+ *
+ * @param file the file to write containing the screenshot
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ * @param alpha whether the alpha channel should be saved. If true,
+ * requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ * @throws IOException if an I/O error occurred while writing the
+ * file
+ */
+ public static void writeToTargaFile(File file,
+ int width,
+ int height,
+ boolean alpha) throws GLException, IOException {
+ writeToTargaFile(file, 0, 0, width, height, alpha);
+ }
+
+ /**
+ * Takes a fast screenshot of the current OpenGL drawable to a Targa
+ * file. Requires the OpenGL context for the desired drawable to be
+ * current. Takes the screenshot from the last assigned read buffer,
+ * or the OpenGL default read buffer if none has been specified by
+ * the user (GL_FRONT for single-buffered configurations and GL_BACK
+ * for double-buffered configurations). This is the fastest
+ * mechanism for taking a screenshot of an application. Contributed
+ * by Carsten Weisse of Bytonic Software (http://bytonic.de/).
+ *
+ * @param file the file to write containing the screenshot
+ * @param x the starting x coordinate of the screenshot, measured from the lower-left
+ * @param y the starting y coordinate of the screenshot, measured from the lower-left
+ * @param width the width of the desired screenshot area
+ * @param height the height of the desired screenshot area
+ * @param alpha whether the alpha channel should be saved. If true,
+ * requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ * @throws IOException if an I/O error occurred while writing the
+ * file
+ */
+ public static void writeToTargaFile(File file,
+ int x,
+ int y,
+ int width,
+ int height,
+ boolean alpha) throws GLException, IOException {
+ if (alpha) {
+ checkExtABGR();
+ }
+
+ TGAWriter writer = new TGAWriter();
+ writer.open(file, width, height, alpha);
+ ByteBuffer bgr = writer.getImageData();
+
+ GL2 gl = GLUgl2.getCurrentGL2();
+
+ // Set up pixel storage modes
+ PixelStorageModes psm = new PixelStorageModes();
+ psm.save(gl);
+
+ int readbackType = (alpha ? GL2.GL_ABGR_EXT : GL2.GL_BGR);
+
+ // read the BGR values into the image buffer
+ gl.glReadPixels(x, y, width, height, readbackType,
+ GL2.GL_UNSIGNED_BYTE, bgr);
+
+ // Restore pixel storage modes
+ psm.restore(gl);
+
+ // close the file
+ writer.close();
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to a
+ * BufferedImage. Requires the OpenGL context for the desired
+ * drawable to be current. Takes the screenshot from the last
+ * assigned read buffer, or the OpenGL default read buffer if none
+ * has been specified by the user (GL_FRONT for single-buffered
+ * configurations and GL_BACK for double-buffered configurations).
+ * Note that the scanlines of the resulting image are flipped
+ * vertically in order to correctly match the OpenGL contents, which
+ * takes time and is therefore not as fast as the Targa screenshot
+ * function. <P>
+ *
+ * No alpha channel is read back with this variant.
+ *
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ */
+ public static BufferedImage readToBufferedImage(int width,
+ int height) throws GLException {
+ return readToBufferedImage(width, height, false);
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to a
+ * BufferedImage. Requires the OpenGL context for the desired
+ * drawable to be current. Takes the screenshot from the last
+ * assigned read buffer, or the OpenGL default read buffer if none
+ * has been specified by the user (GL_FRONT for single-buffered
+ * configurations and GL_BACK for double-buffered configurations).
+ * Note that the scanlines of the resulting image are flipped
+ * vertically in order to correctly match the OpenGL contents, which
+ * takes time and is therefore not as fast as the Targa screenshot
+ * function.
+ *
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ * @param alpha whether the alpha channel should be read back. If
+ * true, requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ */
+ public static BufferedImage readToBufferedImage(int width,
+ int height,
+ boolean alpha) throws GLException {
+ return readToBufferedImage(0, 0, width, height, alpha);
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to a
+ * BufferedImage. Requires the OpenGL context for the desired
+ * drawable to be current. Takes the screenshot from the last
+ * assigned read buffer, or the OpenGL default read buffer if none
+ * has been specified by the user (GL_FRONT for single-buffered
+ * configurations and GL_BACK for double-buffered configurations).
+ * Note that the scanlines of the resulting image are flipped
+ * vertically in order to correctly match the OpenGL contents, which
+ * takes time and is therefore not as fast as the Targa screenshot
+ * function.
+ *
+ * @param x the starting x coordinate of the screenshot, measured from the lower-left
+ * @param y the starting y coordinate of the screenshot, measured from the lower-left
+ * @param width the width of the desired screenshot area
+ * @param height the height of the desired screenshot area
+ * @param alpha whether the alpha channel should be read back. If
+ * true, requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ */
+ public static BufferedImage readToBufferedImage(int x,
+ int y,
+ int width,
+ int height,
+ boolean alpha) throws GLException {
+ int bufImgType = (alpha ? BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_3BYTE_BGR);
+ int readbackType = (alpha ? GL2.GL_ABGR_EXT : GL2.GL_BGR);
+
+ if (alpha) {
+ checkExtABGR();
+ }
+
+ // Allocate necessary storage
+ BufferedImage image = new BufferedImage(width, height, bufImgType);
+
+ GL2 gl = GLUgl2.getCurrentGL2();
+
+ // Set up pixel storage modes
+ PixelStorageModes psm = new PixelStorageModes();
+ psm.save(gl);
+
+ // read the BGR values into the image
+ gl.glReadPixels(x, y, width, height, readbackType,
+ GL2.GL_UNSIGNED_BYTE,
+ ByteBuffer.wrap(((DataBufferByte) image.getRaster().getDataBuffer()).getData()));
+
+ // Restore pixel storage modes
+ psm.restore(gl);
+
+ // Must flip BufferedImage vertically for correct results
+ ImageUtil.flipImageVertically(image);
+ return image;
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to the
+ * specified file on disk using the ImageIO package. Requires the
+ * OpenGL context for the desired drawable to be current. Takes the
+ * screenshot from the last assigned read buffer, or the OpenGL
+ * default read buffer if none has been specified by the user
+ * (GL_FRONT for single-buffered configurations and GL_BACK for
+ * double-buffered configurations). This is not the fastest
+ * mechanism for taking a screenshot but may be more convenient than
+ * others for getting images for consumption by other packages. The
+ * file format is inferred from the suffix of the given file. <P>
+ *
+ * No alpha channel is saved with this variant.
+ *
+ * @param file the file to write containing the screenshot
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ *
+ * @throws IOException if an I/O error occurred or if the file could
+ * not be written to disk due to the requested file format being
+ * unsupported by ImageIO
+ */
+ public static void writeToFile(File file,
+ int width,
+ int height) throws IOException, GLException {
+ writeToFile(file, width, height, false);
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to the
+ * specified file on disk using the ImageIO package. Requires the
+ * OpenGL context for the desired drawable to be current. Takes the
+ * screenshot from the last assigned read buffer, or the OpenGL
+ * default read buffer if none has been specified by the user
+ * (GL_FRONT for single-buffered configurations and GL_BACK for
+ * double-buffered configurations). This is not the fastest
+ * mechanism for taking a screenshot but may be more convenient than
+ * others for getting images for consumption by other packages. The
+ * file format is inferred from the suffix of the given file. <P>
+ *
+ * Note that some file formats, in particular JPEG, can not handle
+ * an alpha channel properly. If the "alpha" argument is specified
+ * as true for such a file format it will be silently ignored.
+ *
+ * @param file the file to write containing the screenshot
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ * @param alpha whether an alpha channel should be saved. If true,
+ * requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ *
+ * @throws IOException if an I/O error occurred or if the file could
+ * not be written to disk due to the requested file format being
+ * unsupported by ImageIO
+ */
+ public static void writeToFile(File file,
+ int width,
+ int height,
+ boolean alpha) throws IOException, GLException {
+ writeToFile(file, 0, 0, width, height, alpha);
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to the
+ * specified file on disk using the ImageIO package. Requires the
+ * OpenGL context for the desired drawable to be current. Takes the
+ * screenshot from the last assigned read buffer, or the OpenGL
+ * default read buffer if none has been specified by the user
+ * (GL_FRONT for single-buffered configurations and GL_BACK for
+ * double-buffered configurations). This is not the fastest
+ * mechanism for taking a screenshot but may be more convenient than
+ * others for getting images for consumption by other packages. The
+ * file format is inferred from the suffix of the given file. <P>
+ *
+ * Note that some file formats, in particular JPEG, can not handle
+ * an alpha channel properly. If the "alpha" argument is specified
+ * as true for such a file format it will be silently ignored.
+ *
+ * @param file the file to write containing the screenshot
+ * @param x the starting x coordinate of the screenshot, measured from the lower-left
+ * @param y the starting y coordinate of the screenshot, measured from the lower-left
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ * @param alpha whether an alpha channel should be saved. If true,
+ * requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ *
+ * @throws IOException if an I/O error occurred or if the file could
+ * not be written to disk due to the requested file format being
+ * unsupported by ImageIO
+ */
+ public static void writeToFile(File file,
+ int x,
+ int y,
+ int width,
+ int height,
+ boolean alpha) throws IOException, GLException {
+ String fileSuffix = FileUtil.getFileSuffix(file);
+ if (alpha && (fileSuffix.equals("jpg") || fileSuffix.equals("jpeg"))) {
+ // JPEGs can't deal properly with alpha channels
+ alpha = false;
+ }
+
+ BufferedImage image = readToBufferedImage(x, y, width, height, alpha);
+ if (!ImageIO.write(image, fileSuffix, file)) {
+ throw new IOException("Unsupported file format " + fileSuffix);
+ }
+ }
+
+ private static int glGetInteger(GL2 gl, int pname, int[] tmp) {
+ gl.glGetIntegerv(pname, tmp, 0);
+ return tmp[0];
+ }
+
+ private static void checkExtABGR() {
+ GL2 gl = GLUgl2.getCurrentGL2();
+ if (!gl.isExtensionAvailable("GL_EXT_abgr")) {
+ throw new IllegalArgumentException("Saving alpha channel requires GL_EXT_abgr");
+ }
+ }
+
+ static class PixelStorageModes {
+ int packAlignment;
+ int packRowLength;
+ int packSkipRows;
+ int packSkipPixels;
+ int packSwapBytes;
+ int[] tmp = new int[1];
+
+ void save(GL2 gl) {
+ packAlignment = glGetInteger(gl, GL2.GL_PACK_ALIGNMENT, tmp);
+ packRowLength = glGetInteger(gl, GL2.GL_PACK_ROW_LENGTH, tmp);
+ packSkipRows = glGetInteger(gl, GL2.GL_PACK_SKIP_ROWS, tmp);
+ packSkipPixels = glGetInteger(gl, GL2.GL_PACK_SKIP_PIXELS, tmp);
+ packSwapBytes = glGetInteger(gl, GL2.GL_PACK_SWAP_BYTES, tmp);
+
+ gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, 1);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, 0);
+ }
+
+ void restore(GL2 gl) {
+ gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, packAlignment);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, packRowLength);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, packSkipRows);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, packSkipPixels);
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, packSwapBytes);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
new file mode 100755
index 000000000..bac9f88ea
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
@@ -0,0 +1,1952 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+package com.jogamp.opengl.util.awt;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.impl.Debug;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.packrect.*;
+import com.jogamp.opengl.util.texture.*;
+import com.jogamp.opengl.util.texture.awt.*;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+
+// For debugging purposes
+import java.awt.EventQueue;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.event.*;
+import java.awt.font.*;
+import java.awt.geom.*;
+
+import java.nio.*;
+
+import java.text.*;
+
+import java.util.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import javax.media.opengl.glu.gl2.*;
+import javax.media.opengl.awt.*;
+
+
+/** Renders bitmapped Java 2D text into an OpenGL window with high
+ performance, full Unicode support, and a simple API. Performs
+ appropriate caching of text rendering results in an OpenGL texture
+ internally to avoid repeated font rasterization. The caching is
+ completely automatic, does not require any user intervention, and
+ has no visible controls in the public API. <P>
+
+ Using the {@link TextRenderer TextRenderer} is simple. Add a
+ "<code>TextRenderer renderer;</code>" field to your {@link
+ javax.media.opengl.GLEventListener GLEventListener}. In your {@link
+ javax.media.opengl.GLEventListener#init init} method, add:
+
+ <PRE>
+ renderer = new TextRenderer(new Font("SansSerif", Font.BOLD, 36));
+ </PRE>
+
+ <P> In the {@link javax.media.opengl.GLEventListener#display display} method of your
+ {@link javax.media.opengl.GLEventListener GLEventListener}, add:
+ <PRE>
+ renderer.beginRendering(drawable.getWidth(), drawable.getHeight());
+ // optionally set the color
+ renderer.setColor(1.0f, 0.2f, 0.2f, 0.8f);
+ renderer.draw("Text to draw", xPosition, yPosition);
+ // ... more draw commands, color changes, etc.
+ renderer.endRendering();
+ </PRE>
+
+ Unless you are sharing textures and display lists between OpenGL
+ contexts, you do not need to call the {@link #dispose dispose}
+ method of the TextRenderer; the OpenGL resources it uses
+ internally will be cleaned up automatically when the OpenGL
+ context is destroyed. <P>
+
+ <b>Note</b> that the TextRenderer may cause the vertex and texture
+ coordinate array buffer bindings to change, or to be unbound. This
+ is important to note if you are using Vertex Buffer Objects (VBOs)
+ in your application. <P>
+
+ Internally, the renderer uses a rectangle packing algorithm to
+ pack both glyphs and full Strings' rendering results (which are
+ variable size) onto a larger OpenGL texture. The internal backing
+ store is maintained using a {@link
+ com.jogamp.opengl.util.awt.TextureRenderer TextureRenderer}. A least
+ recently used (LRU) algorithm is used to discard previously
+ rendered strings; the specific algorithm is undefined, but is
+ currently implemented by flushing unused Strings' rendering
+ results every few hundred rendering cycles, where a rendering
+ cycle is defined as a pair of calls to {@link #beginRendering
+ beginRendering} / {@link #endRendering endRendering}.
+
+ @author John Burkey
+ @author Kenneth Russell
+*/
+public class TextRenderer {
+ private static final boolean DEBUG = Debug.debug("TextRenderer");
+
+ // These are occasionally useful for more in-depth debugging
+ private static final boolean DISABLE_GLYPH_CACHE = false;
+ private static final boolean DRAW_BBOXES = false;
+
+ static final int kSize = 256;
+
+ // Every certain number of render cycles, flush the strings which
+ // haven't been used recently
+ private static final int CYCLES_PER_FLUSH = 100;
+
+ // The amount of vertical dead space on the backing store before we
+ // force a compaction
+ private static final float MAX_VERTICAL_FRAGMENTATION = 0.7f;
+ static final int kQuadsPerBuffer = 100;
+ static final int kCoordsPerVertVerts = 3;
+ static final int kCoordsPerVertTex = 2;
+ static final int kVertsPerQuad = 4;
+ static final int kTotalBufferSizeVerts = kQuadsPerBuffer * kVertsPerQuad;
+ static final int kTotalBufferSizeCoordsVerts = kQuadsPerBuffer * kVertsPerQuad * kCoordsPerVertVerts;
+ static final int kTotalBufferSizeCoordsTex = kQuadsPerBuffer * kVertsPerQuad * kCoordsPerVertTex;
+ static final int kTotalBufferSizeBytesVerts = kTotalBufferSizeCoordsVerts * 4;
+ static final int kTotalBufferSizeBytesTex = kTotalBufferSizeCoordsTex * 4;
+ static final int kSizeInBytes_OneVertices_VertexData = kCoordsPerVertVerts * 4;
+ static final int kSizeInBytes_OneVertices_TexData = kCoordsPerVertTex * 4;
+ private Font font;
+ private boolean antialiased;
+ private boolean useFractionalMetrics;
+
+ // Whether we're attempting to use automatic mipmap generation support
+ private boolean mipmap;
+ private RectanglePacker packer;
+ private boolean haveMaxSize;
+ private RenderDelegate renderDelegate;
+ private TextureRenderer cachedBackingStore;
+ private Graphics2D cachedGraphics;
+ private FontRenderContext cachedFontRenderContext;
+ private Map /*<String,Rect>*/ stringLocations = new HashMap /*<String,Rect>*/();
+ private GlyphProducer mGlyphProducer;
+
+ private int numRenderCycles;
+
+ // Need to keep track of whether we're in a beginRendering() /
+ // endRendering() cycle so we can re-enter the exact same state if
+ // we have to reallocate the backing store
+ private boolean inBeginEndPair;
+ private boolean isOrthoMode;
+ private int beginRenderingWidth;
+ private int beginRenderingHeight;
+ private boolean beginRenderingDepthTestDisabled;
+
+ // For resetting the color after disposal of the old backing store
+ private boolean haveCachedColor;
+ private float cachedR;
+ private float cachedG;
+ private float cachedB;
+ private float cachedA;
+ private Color cachedColor;
+ private boolean needToResetColor;
+
+ // For debugging only
+ private Frame dbgFrame;
+
+ // Debugging purposes only
+ private boolean debugged;
+ Pipelined_QuadRenderer mPipelinedQuadRenderer;
+
+ //emzic: added boolean flag
+ private boolean useVertexArrays = true;
+
+ //emzic: added boolean flag
+ private boolean isExtensionAvailable_GL_VERSION_1_5;
+ private boolean checkFor_isExtensionAvailable_GL_VERSION_1_5;
+
+ // Whether GL_LINEAR filtering is enabled for the backing store
+ private boolean smoothing = true;
+
+ /** Creates a new TextRenderer with the given font, using no
+ antialiasing or fractional metrics, and the default
+ RenderDelegate. Equivalent to <code>TextRenderer(font, false,
+ false)</code>.
+
+ @param font the font to render with
+ */
+ public TextRenderer(Font font) {
+ this(font, false, false, null, false);
+ }
+
+ /** Creates a new TextRenderer with the given font, using no
+ antialiasing or fractional metrics, and the default
+ RenderDelegate. If <CODE>mipmap</CODE> is true, attempts to use
+ OpenGL's automatic mipmap generation for better smoothing when
+ rendering the TextureRenderer's contents at a distance.
+ Equivalent to <code>TextRenderer(font, false, false)</code>.
+
+ @param font the font to render with
+ @param mipmap whether to attempt use of automatic mipmap generation
+ */
+ public TextRenderer(Font font, boolean mipmap) {
+ this(font, false, false, null, mipmap);
+ }
+
+ /** Creates a new TextRenderer with the given Font, specified font
+ properties, and default RenderDelegate. The
+ <code>antialiased</code> and <code>useFractionalMetrics</code>
+ flags provide control over the same properties at the Java 2D
+ level. No mipmap support is requested. Equivalent to
+ <code>TextRenderer(font, antialiased, useFractionalMetrics,
+ null)</code>.
+
+ @param font the font to render with
+ @param antialiased whether to use antialiased fonts
+ @param useFractionalMetrics whether to use fractional font
+ metrics at the Java 2D level
+ */
+ public TextRenderer(Font font, boolean antialiased,
+ boolean useFractionalMetrics) {
+ this(font, antialiased, useFractionalMetrics, null, false);
+ }
+
+ /** Creates a new TextRenderer with the given Font, specified font
+ properties, and given RenderDelegate. The
+ <code>antialiased</code> and <code>useFractionalMetrics</code>
+ flags provide control over the same properties at the Java 2D
+ level. The <code>renderDelegate</code> provides more control
+ over the text rendered. No mipmap support is requested.
+
+ @param font the font to render with
+ @param antialiased whether to use antialiased fonts
+ @param useFractionalMetrics whether to use fractional font
+ metrics at the Java 2D level
+ @param renderDelegate the render delegate to use to draw the
+ text's bitmap, or null to use the default one
+ */
+ public TextRenderer(Font font, boolean antialiased,
+ boolean useFractionalMetrics, RenderDelegate renderDelegate) {
+ this(font, antialiased, useFractionalMetrics, renderDelegate, false);
+ }
+
+ /** Creates a new TextRenderer with the given Font, specified font
+ properties, and given RenderDelegate. The
+ <code>antialiased</code> and <code>useFractionalMetrics</code>
+ flags provide control over the same properties at the Java 2D
+ level. The <code>renderDelegate</code> provides more control
+ over the text rendered. If <CODE>mipmap</CODE> is true, attempts
+ to use OpenGL's automatic mipmap generation for better smoothing
+ when rendering the TextureRenderer's contents at a distance.
+
+ @param font the font to render with
+ @param antialiased whether to use antialiased fonts
+ @param useFractionalMetrics whether to use fractional font
+ metrics at the Java 2D level
+ @param renderDelegate the render delegate to use to draw the
+ text's bitmap, or null to use the default one
+ @param mipmap whether to attempt use of automatic mipmap generation
+ */
+ public TextRenderer(Font font, boolean antialiased,
+ boolean useFractionalMetrics, RenderDelegate renderDelegate,
+ boolean mipmap) {
+ this.font = font;
+ this.antialiased = antialiased;
+ this.useFractionalMetrics = useFractionalMetrics;
+ this.mipmap = mipmap;
+
+ // FIXME: consider adjusting the size based on font size
+ // (it will already automatically resize if necessary)
+ packer = new RectanglePacker(new Manager(), kSize, kSize);
+
+ if (renderDelegate == null) {
+ renderDelegate = new DefaultRenderDelegate();
+ }
+
+ this.renderDelegate = renderDelegate;
+
+ mGlyphProducer = new GlyphProducer(font.getNumGlyphs());
+ }
+
+ /** Returns the bounding rectangle of the given String, assuming it
+ was rendered at the origin. See {@link #getBounds(CharSequence)
+ getBounds(CharSequence)}. */
+ public Rectangle2D getBounds(String str) {
+ return getBounds((CharSequence) str);
+ }
+
+ /** Returns the bounding rectangle of the given CharSequence,
+ assuming it was rendered at the origin. The coordinate system of
+ the returned rectangle is Java 2D's, with increasing Y
+ coordinates in the downward direction. The relative coordinate
+ (0, 0) in the returned rectangle corresponds to the baseline of
+ the leftmost character of the rendered string, in similar
+ fashion to the results returned by, for example, {@link
+ java.awt.font.GlyphVector#getVisualBounds}. Most applications
+ will use only the width and height of the returned Rectangle for
+ the purposes of centering or justifying the String. It is not
+ specified which Java 2D bounds ({@link
+ java.awt.font.GlyphVector#getVisualBounds getVisualBounds},
+ {@link java.awt.font.GlyphVector#getPixelBounds getPixelBounds},
+ etc.) the returned bounds correspond to, although every effort
+ is made to ensure an accurate bound. */
+ public Rectangle2D getBounds(CharSequence str) {
+ // FIXME: this should be more optimized and use the glyph cache
+ Rect r = null;
+
+ if ((r = (Rect) stringLocations.get(str)) != null) {
+ TextData data = (TextData) r.getUserData();
+
+ // Reconstitute the Java 2D results based on the cached values
+ return new Rectangle2D.Double(-data.origin().x, -data.origin().y,
+ r.w(), r.h());
+ }
+
+ // Must return a Rectangle compatible with the layout algorithm --
+ // must be idempotent
+ return normalize(renderDelegate.getBounds(str, font,
+ getFontRenderContext()));
+ }
+
+ /** Returns the Font this renderer is using. */
+ public Font getFont() {
+ return font;
+ }
+
+ /** Returns a FontRenderContext which can be used for external
+ text-related size computations. This object should be considered
+ transient and may become invalidated between {@link
+ #beginRendering beginRendering} / {@link #endRendering
+ endRendering} pairs. */
+ public FontRenderContext getFontRenderContext() {
+ if (cachedFontRenderContext == null) {
+ cachedFontRenderContext = getGraphics2D().getFontRenderContext();
+ }
+
+ return cachedFontRenderContext;
+ }
+
+ /** Begins rendering with this {@link TextRenderer TextRenderer}
+ into the current OpenGL drawable, pushing the projection and
+ modelview matrices and some state bits and setting up a
+ two-dimensional orthographic projection with (0, 0) as the
+ lower-left coordinate and (width, height) as the upper-right
+ coordinate. Binds and enables the internal OpenGL texture
+ object, sets the texture environment mode to GL_MODULATE, and
+ changes the current color to the last color set with this
+ TextRenderer via {@link #setColor setColor}. This method
+ disables the depth test and is equivalent to
+ beginRendering(width, height, true).
+
+ @param width the width of the current on-screen OpenGL drawable
+ @param height the height of the current on-screen OpenGL drawable
+ @throws javax.media.opengl.GLException If an OpenGL context is not current when this method is called
+ */
+ public void beginRendering(int width, int height) throws GLException {
+ beginRendering(width, height, true);
+ }
+
+ /** Begins rendering with this {@link TextRenderer TextRenderer}
+ into the current OpenGL drawable, pushing the projection and
+ modelview matrices and some state bits and setting up a
+ two-dimensional orthographic projection with (0, 0) as the
+ lower-left coordinate and (width, height) as the upper-right
+ coordinate. Binds and enables the internal OpenGL texture
+ object, sets the texture environment mode to GL_MODULATE, and
+ changes the current color to the last color set with this
+ TextRenderer via {@link #setColor setColor}. Disables the depth
+ test if the disableDepthTest argument is true.
+
+ @param width the width of the current on-screen OpenGL drawable
+ @param height the height of the current on-screen OpenGL drawable
+ @param disableDepthTest whether to disable the depth test
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void beginRendering(int width, int height, boolean disableDepthTest)
+ throws GLException {
+ beginRendering(true, width, height, disableDepthTest);
+ }
+
+ /** Begins rendering of 2D text in 3D with this {@link TextRenderer
+ TextRenderer} into the current OpenGL drawable. Assumes the end
+ user is responsible for setting up the modelview and projection
+ matrices, and will render text using the {@link #draw3D draw3D}
+ method. This method pushes some OpenGL state bits, binds and
+ enables the internal OpenGL texture object, sets the texture
+ environment mode to GL_MODULATE, and changes the current color
+ to the last color set with this TextRenderer via {@link
+ #setColor setColor}.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void begin3DRendering() throws GLException {
+ beginRendering(false, 0, 0, false);
+ }
+
+ /** Changes the current color of this TextRenderer to the supplied
+ one. The default color is opaque white.
+
+ @param color the new color to use for rendering text
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void setColor(Color color) throws GLException {
+ boolean noNeedForFlush = (haveCachedColor && (cachedColor != null) &&
+ color.equals(cachedColor));
+
+ if (!noNeedForFlush) {
+ flushGlyphPipeline();
+ }
+
+ getBackingStore().setColor(color);
+ haveCachedColor = true;
+ cachedColor = color;
+ }
+
+ /** Changes the current color of this TextRenderer to the supplied
+ one, where each component ranges from 0.0f - 1.0f. The alpha
+ component, if used, does not need to be premultiplied into the
+ color channels as described in the documentation for {@link
+ com.jogamp.opengl.util.texture.Texture Texture}, although
+ premultiplied colors are used internally. The default color is
+ opaque white.
+
+ @param r the red component of the new color
+ @param g the green component of the new color
+ @param b the blue component of the new color
+ @param a the alpha component of the new color, 0.0f = completely
+ transparent, 1.0f = completely opaque
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void setColor(float r, float g, float b, float a)
+ throws GLException {
+ boolean noNeedForFlush = (haveCachedColor && (cachedColor == null) &&
+ (r == cachedR) && (g == cachedG) && (b == cachedB) &&
+ (a == cachedA));
+
+ if (!noNeedForFlush) {
+ flushGlyphPipeline();
+ }
+
+ getBackingStore().setColor(r, g, b, a);
+ haveCachedColor = true;
+ cachedR = r;
+ cachedG = g;
+ cachedB = b;
+ cachedA = a;
+ cachedColor = null;
+ }
+
+ /** Draws the supplied CharSequence at the desired location using
+ the renderer's current color. The baseline of the leftmost
+ character is at position (x, y) specified in OpenGL coordinates,
+ where the origin is at the lower-left of the drawable and the Y
+ coordinate increases in the upward direction.
+
+ @param str the string to draw
+ @param x the x coordinate at which to draw
+ @param y the y coordinate at which to draw
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void draw(CharSequence str, int x, int y) throws GLException {
+ draw3D(str, x, y, 0, 1);
+ }
+
+ /** Draws the supplied String at the desired location using the
+ renderer's current color. See {@link #draw(CharSequence, int,
+ int) draw(CharSequence, int, int)}. */
+ public void draw(String str, int x, int y) throws GLException {
+ draw3D(str, x, y, 0, 1);
+ }
+
+ /** Draws the supplied CharSequence at the desired 3D location using
+ the renderer's current color. The baseline of the leftmost
+ character is placed at position (x, y, z) in the current
+ coordinate system.
+
+ @param str the string to draw
+ @param x the x coordinate at which to draw
+ @param y the y coordinate at which to draw
+ @param z the z coordinate at which to draw
+ @param scaleFactor a uniform scale factor applied to the width and height of the drawn rectangle
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void draw3D(CharSequence str, float x, float y, float z,
+ float scaleFactor) {
+ internal_draw3D(str, x, y, z, scaleFactor);
+ }
+
+ /** Draws the supplied String at the desired 3D location using the
+ renderer's current color. See {@link #draw3D(CharSequence,
+ float, float, float, float) draw3D(CharSequence, float, float,
+ float, float)}. */
+ public void draw3D(String str, float x, float y, float z, float scaleFactor) {
+ internal_draw3D(str, x, y, z, scaleFactor);
+ }
+
+ /** Returns the pixel width of the given character. */
+ public float getCharWidth(char inChar) {
+ return mGlyphProducer.getGlyphPixelWidth(inChar);
+ }
+
+ /** Causes the TextRenderer to flush any internal caches it may be
+ maintaining and draw its rendering results to the screen. This
+ should be called after each call to draw() if you are setting
+ OpenGL state such as the modelview matrix between calls to
+ draw(). */
+ public void flush() {
+ flushGlyphPipeline();
+ }
+
+ /** Ends a render cycle with this {@link TextRenderer TextRenderer}.
+ Restores the projection and modelview matrices as well as
+ several OpenGL state bits. Should be paired with {@link
+ #beginRendering beginRendering}.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void endRendering() throws GLException {
+ endRendering(true);
+ }
+
+ /** Ends a 3D render cycle with this {@link TextRenderer TextRenderer}.
+ Restores several OpenGL state bits. Should be paired with {@link
+ #begin3DRendering begin3DRendering}.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void end3DRendering() throws GLException {
+ endRendering(false);
+ }
+
+ /** Disposes of all resources this TextRenderer is using. It is not
+ valid to use the TextRenderer after this method is called.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void dispose() throws GLException {
+ packer.dispose();
+ packer = null;
+ cachedBackingStore = null;
+ cachedGraphics = null;
+ cachedFontRenderContext = null;
+
+ if (dbgFrame != null) {
+ dbgFrame.dispose();
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static Rectangle2D preNormalize(Rectangle2D src) {
+ // Need to round to integer coordinates
+ // Also give ourselves a little slop around the reported
+ // bounds of glyphs because it looks like neither the visual
+ // nor the pixel bounds works perfectly well
+ int minX = (int) Math.floor(src.getMinX()) - 1;
+ int minY = (int) Math.floor(src.getMinY()) - 1;
+ int maxX = (int) Math.ceil(src.getMaxX()) + 1;
+ int maxY = (int) Math.ceil(src.getMaxY()) + 1;
+ return new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
+ }
+
+
+ private Rectangle2D normalize(Rectangle2D src) {
+ // Give ourselves a boundary around each entity on the backing
+ // store in order to prevent bleeding of nearby Strings due to
+ // the fact that we use linear filtering
+
+ // NOTE that this boundary is quite heuristic and is related
+ // to how far away in 3D we may view the text --
+ // heuristically, 1.5% of the font's height
+ int boundary = (int) Math.max(1, 0.015 * font.getSize());
+
+ return new Rectangle2D.Double((int) Math.floor(src.getMinX() - boundary),
+ (int) Math.floor(src.getMinY() - boundary),
+ (int) Math.ceil(src.getWidth() + 2 * boundary),
+ (int) Math.ceil(src.getHeight()) + 2 * boundary);
+ }
+
+ private TextureRenderer getBackingStore() {
+ TextureRenderer renderer = (TextureRenderer) packer.getBackingStore();
+
+ if (renderer != cachedBackingStore) {
+ // Backing store changed since last time; discard any cached Graphics2D
+ if (cachedGraphics != null) {
+ cachedGraphics.dispose();
+ cachedGraphics = null;
+ cachedFontRenderContext = null;
+ }
+
+ cachedBackingStore = renderer;
+ }
+
+ return cachedBackingStore;
+ }
+
+ private Graphics2D getGraphics2D() {
+ TextureRenderer renderer = getBackingStore();
+
+ if (cachedGraphics == null) {
+ cachedGraphics = renderer.createGraphics();
+
+ // Set up composite, font and rendering hints
+ cachedGraphics.setComposite(AlphaComposite.Src);
+ cachedGraphics.setColor(Color.WHITE);
+ cachedGraphics.setFont(font);
+ cachedGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ (antialiased ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON
+ : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF));
+ cachedGraphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
+ (useFractionalMetrics
+ ? RenderingHints.VALUE_FRACTIONALMETRICS_ON
+ : RenderingHints.VALUE_FRACTIONALMETRICS_OFF));
+ }
+
+ return cachedGraphics;
+ }
+
+ private void beginRendering(boolean ortho, int width, int height,
+ boolean disableDepthTestForOrtho) {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+
+ if (DEBUG && !debugged) {
+ debug(gl);
+ }
+
+ inBeginEndPair = true;
+ isOrthoMode = ortho;
+ beginRenderingWidth = width;
+ beginRenderingHeight = height;
+ beginRenderingDepthTestDisabled = disableDepthTestForOrtho;
+
+ if (ortho) {
+ getBackingStore().beginOrthoRendering(width, height,
+ disableDepthTestForOrtho);
+ } else {
+ getBackingStore().begin3DRendering();
+ }
+
+ // Push client attrib bits used by the pipelined quad renderer
+ gl.glPushClientAttrib((int) GL2.GL_ALL_CLIENT_ATTRIB_BITS);
+
+ if (!haveMaxSize) {
+ // Query OpenGL for the maximum texture size and set it in the
+ // RectanglePacker to keep it from expanding too large
+ int[] sz = new int[1];
+ gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_SIZE, sz, 0);
+ packer.setMaxSize(sz[0], sz[0]);
+ haveMaxSize = true;
+ }
+
+ if (needToResetColor && haveCachedColor) {
+ if (cachedColor == null) {
+ getBackingStore().setColor(cachedR, cachedG, cachedB, cachedA);
+ } else {
+ getBackingStore().setColor(cachedColor);
+ }
+
+ needToResetColor = false;
+ }
+
+ // Disable future attempts to use mipmapping if TextureRenderer
+ // doesn't support it
+ if (mipmap && !getBackingStore().isUsingAutoMipmapGeneration()) {
+ if (DEBUG) {
+ System.err.println("Disabled mipmapping in TextRenderer");
+ }
+
+ mipmap = false;
+ }
+ }
+
+ /**
+ * emzic: here the call to glBindBuffer crashes on certain graphicscard/driver combinations
+ * this is why the ugly try-catch block has been added, which falls back to the old textrenderer
+ *
+ * @param ortho
+ * @throws GLException
+ */
+ private void endRendering(boolean ortho) throws GLException {
+ flushGlyphPipeline();
+
+ inBeginEndPair = false;
+
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+
+ // Pop client attrib bits used by the pipelined quad renderer
+ gl.glPopClientAttrib();
+
+ // The OpenGL spec is unclear about whether this changes the
+ // buffer bindings, so preemptively zero out the GL_ARRAY_BUFFER
+ // binding
+ if (is15Available(gl)) {
+ try {
+ gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
+ } catch (Exception e) {
+ isExtensionAvailable_GL_VERSION_1_5 = false;
+ }
+ }
+
+ if (ortho) {
+ getBackingStore().endOrthoRendering();
+ } else {
+ getBackingStore().end3DRendering();
+ }
+
+ if (++numRenderCycles >= CYCLES_PER_FLUSH) {
+ numRenderCycles = 0;
+
+ if (DEBUG) {
+ System.err.println("Clearing unused entries in endRendering()");
+ }
+
+ clearUnusedEntries();
+ }
+ }
+
+ private void clearUnusedEntries() {
+ final java.util.List deadRects = new ArrayList /*<Rect>*/();
+
+ // Iterate through the contents of the backing store, removing
+ // text strings that haven't been used recently
+ packer.visit(new RectVisitor() {
+ public void visit(Rect rect) {
+ TextData data = (TextData) rect.getUserData();
+
+ if (data.used()) {
+ data.clearUsed();
+ } else {
+ deadRects.add(rect);
+ }
+ }
+ });
+
+ for (Iterator iter = deadRects.iterator(); iter.hasNext();) {
+ Rect r = (Rect) iter.next();
+ packer.remove(r);
+ stringLocations.remove(((TextData) r.getUserData()).string());
+
+ int unicodeToClearFromCache = ((TextData) r.getUserData()).unicodeID;
+
+ if (unicodeToClearFromCache > 0) {
+ mGlyphProducer.clearCacheEntry(unicodeToClearFromCache);
+ }
+
+ // if (DEBUG) {
+ // Graphics2D g = getGraphics2D();
+ // g.setComposite(AlphaComposite.Clear);
+ // g.fillRect(r.x(), r.y(), r.w(), r.h());
+ // g.setComposite(AlphaComposite.Src);
+ // }
+ }
+
+ // If we removed dead rectangles this cycle, try to do a compaction
+ float frag = packer.verticalFragmentationRatio();
+
+ if (!deadRects.isEmpty() && (frag > MAX_VERTICAL_FRAGMENTATION)) {
+ if (DEBUG) {
+ System.err.println(
+ "Compacting TextRenderer backing store due to vertical fragmentation " +
+ frag);
+ }
+
+ packer.compact();
+ }
+
+ if (DEBUG) {
+ getBackingStore().markDirty(0, 0, getBackingStore().getWidth(),
+ getBackingStore().getHeight());
+ }
+ }
+
+ private void internal_draw3D(CharSequence str, float x, float y, float z,
+ float scaleFactor) {
+ List/*<Glyph>*/ glyphs = mGlyphProducer.getGlyphs(str);
+ for (Iterator iter = glyphs.iterator(); iter.hasNext(); ) {
+ Glyph glyph = (Glyph) iter.next();
+ float advance = glyph.draw3D(x, y, z, scaleFactor);
+ x += advance * scaleFactor;
+ }
+ }
+
+ private void flushGlyphPipeline() {
+ if (mPipelinedQuadRenderer != null) {
+ mPipelinedQuadRenderer.draw();
+ }
+ }
+
+ private void draw3D_ROBUST(CharSequence str, float x, float y, float z,
+ float scaleFactor) {
+ String curStr;
+ if (str instanceof String) {
+ curStr = (String) str;
+ } else {
+ curStr = str.toString();
+ }
+
+ // Look up the string on the backing store
+ Rect rect = (Rect) stringLocations.get(curStr);
+
+ if (rect == null) {
+ // Rasterize this string and place it on the backing store
+ Graphics2D g = getGraphics2D();
+ Rectangle2D origBBox = preNormalize(renderDelegate.getBounds(curStr, font, getFontRenderContext()));
+ Rectangle2D bbox = normalize(origBBox);
+ Point origin = new Point((int) -bbox.getMinX(),
+ (int) -bbox.getMinY());
+ rect = new Rect(0, 0, (int) bbox.getWidth(),
+ (int) bbox.getHeight(),
+ new TextData(curStr, origin, origBBox, -1));
+
+ packer.add(rect);
+ stringLocations.put(curStr, rect);
+
+ // Re-fetch the Graphics2D in case the addition of the rectangle
+ // caused the old backing store to be thrown away
+ g = getGraphics2D();
+
+ // OK, should now have an (x, y) for this rectangle; rasterize
+ // the String
+ int strx = rect.x() + origin.x;
+ int stry = rect.y() + origin.y;
+
+ // Clear out the area we're going to draw into
+ g.setComposite(AlphaComposite.Clear);
+ g.fillRect(rect.x(), rect.y(), rect.w(), rect.h());
+ g.setComposite(AlphaComposite.Src);
+
+ // Draw the string
+ renderDelegate.draw(g, curStr, strx, stry);
+
+ if (DRAW_BBOXES) {
+ TextData data = (TextData) rect.getUserData();
+ // Draw a bounding box on the backing store
+ g.drawRect(strx - data.origOriginX(),
+ stry - data.origOriginY(),
+ (int) data.origRect().getWidth(),
+ (int) data.origRect().getHeight());
+ g.drawRect(strx - data.origin().x,
+ stry - data.origin().y,
+ rect.w(),
+ rect.h());
+ }
+
+ // Mark this region of the TextureRenderer as dirty
+ getBackingStore().markDirty(rect.x(), rect.y(), rect.w(),
+ rect.h());
+ }
+
+ // OK, now draw the portion of the backing store to the screen
+ TextureRenderer renderer = getBackingStore();
+
+ // NOTE that the rectangles managed by the packer have their
+ // origin at the upper-left but the TextureRenderer's origin is
+ // at its lower left!!!
+ TextData data = (TextData) rect.getUserData();
+ data.markUsed();
+
+ Rectangle2D origRect = data.origRect();
+
+ // Align the leftmost point of the baseline to the (x, y, z) coordinate requested
+ renderer.draw3DRect(x - (scaleFactor * data.origOriginX()),
+ y - (scaleFactor * ((float) origRect.getHeight() - data.origOriginY())), z,
+ rect.x() + (data.origin().x - data.origOriginX()),
+ renderer.getHeight() - rect.y() - (int) origRect.getHeight() -
+ (data.origin().y - data.origOriginY()),
+ (int) origRect.getWidth(), (int) origRect.getHeight(), scaleFactor);
+ }
+
+ //----------------------------------------------------------------------
+ // Debugging functionality
+ //
+ private void debug(GL gl) {
+ dbgFrame = new Frame("TextRenderer Debug Output");
+
+ GLCanvas dbgCanvas = new GLCanvas(new GLCapabilities(gl.getGLProfile()), null,
+ GLContext.getCurrent(), null);
+ dbgCanvas.addGLEventListener(new DebugListener(gl, dbgFrame));
+ dbgFrame.add(dbgCanvas);
+
+ final FPSAnimator anim = new FPSAnimator(dbgCanvas, 10);
+ dbgFrame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ // Run this on another thread than the AWT event queue to
+ // make sure the call to Animator.stop() completes before
+ // exiting
+ new Thread(new Runnable() {
+ public void run() {
+ anim.stop();
+ }
+ }).start();
+ }
+ });
+ dbgFrame.setSize(kSize, kSize);
+ dbgFrame.setVisible(true);
+ anim.start();
+ debugged = true;
+ }
+
+ /** Class supporting more full control over the process of rendering
+ the bitmapped text. Allows customization of whether the backing
+ store text bitmap is full-color or intensity only, the size of
+ each individual rendered text rectangle, and the contents of
+ each individual rendered text string. The default implementation
+ of this interface uses an intensity-only texture, a
+ closely-cropped rectangle around the text, and renders text
+ using the color white, which is modulated by the set color
+ during the rendering process. */
+ public static interface RenderDelegate {
+ /** Indicates whether the backing store of this TextRenderer
+ should be intensity-only (the default) or full-color. */
+ public boolean intensityOnly();
+
+ /** Computes the bounds of the given String relative to the
+ origin. */
+ public Rectangle2D getBounds(String str, Font font,
+ FontRenderContext frc);
+
+ /** Computes the bounds of the given character sequence relative
+ to the origin. */
+ public Rectangle2D getBounds(CharSequence str, Font font,
+ FontRenderContext frc);
+
+ /** Computes the bounds of the given GlyphVector, already
+ assumed to have been created for a particular Font,
+ relative to the origin. */
+ public Rectangle2D getBounds(GlyphVector gv, FontRenderContext frc);
+
+ /** Render the passed character sequence at the designated
+ location using the supplied Graphics2D instance. The
+ surrounding region will already have been cleared to the RGB
+ color (0, 0, 0) with zero alpha. The initial drawing context
+ of the passed Graphics2D will be set to use
+ AlphaComposite.Src, the color white, the Font specified in the
+ TextRenderer's constructor, and the rendering hints specified
+ in the TextRenderer constructor. Changes made by the end user
+ may be visible in successive calls to this method, but are not
+ guaranteed to be preserved. Implementors of this method
+ should reset the Graphics2D's state to that desired each time
+ this method is called, in particular those states which are
+ not the defaults. */
+ public void draw(Graphics2D graphics, String str, int x, int y);
+
+ /** Render the passed GlyphVector at the designated location using
+ the supplied Graphics2D instance. The surrounding region will
+ already have been cleared to the RGB color (0, 0, 0) with zero
+ alpha. The initial drawing context of the passed Graphics2D
+ will be set to use AlphaComposite.Src, the color white, the
+ Font specified in the TextRenderer's constructor, and the
+ rendering hints specified in the TextRenderer constructor.
+ Changes made by the end user may be visible in successive
+ calls to this method, but are not guaranteed to be preserved.
+ Implementors of this method should reset the Graphics2D's
+ state to that desired each time this method is called, in
+ particular those states which are not the defaults. */
+ public void drawGlyphVector(Graphics2D graphics, GlyphVector str,
+ int x, int y);
+ }
+
+ private static class CharSequenceIterator implements CharacterIterator {
+ CharSequence mSequence;
+ int mLength;
+ int mCurrentIndex;
+
+ CharSequenceIterator() {
+ }
+
+ CharSequenceIterator(CharSequence sequence) {
+ initFromCharSequence(sequence);
+ }
+
+ public void initFromCharSequence(CharSequence sequence) {
+ mSequence = sequence;
+ mLength = mSequence.length();
+ mCurrentIndex = 0;
+ }
+
+ public char last() {
+ mCurrentIndex = Math.max(0, mLength - 1);
+
+ return current();
+ }
+
+ public char current() {
+ if ((mLength == 0) || (mCurrentIndex >= mLength)) {
+ return CharacterIterator.DONE;
+ }
+
+ return mSequence.charAt(mCurrentIndex);
+ }
+
+ public char next() {
+ mCurrentIndex++;
+
+ return current();
+ }
+
+ public char previous() {
+ mCurrentIndex = Math.max(mCurrentIndex - 1, 0);
+
+ return current();
+ }
+
+ public char setIndex(int position) {
+ mCurrentIndex = position;
+
+ return current();
+ }
+
+ public int getBeginIndex() {
+ return 0;
+ }
+
+ public int getEndIndex() {
+ return mLength;
+ }
+
+ public int getIndex() {
+ return mCurrentIndex;
+ }
+
+ public Object clone() {
+ CharSequenceIterator iter = new CharSequenceIterator(mSequence);
+ iter.mCurrentIndex = mCurrentIndex;
+
+ return iter;
+ }
+
+ public char first() {
+ if (mLength == 0) {
+ return CharacterIterator.DONE;
+ }
+
+ mCurrentIndex = 0;
+
+ return current();
+ }
+ }
+
+ // Data associated with each rectangle of text
+ static class TextData {
+ // Back-pointer to String this TextData describes, if it
+ // represents a String rather than a single glyph
+ private String str;
+
+ // If this TextData represents a single glyph, this is its
+ // unicode ID
+ int unicodeID;
+
+ // The following must be defined and used VERY precisely. This is
+ // the offset from the upper-left corner of this rectangle (Java
+ // 2D coordinate system) at which the string must be rasterized in
+ // order to fit within the rectangle -- the leftmost point of the
+ // baseline.
+ private Point origin;
+
+ // This represents the pre-normalized rectangle, which fits
+ // within the rectangle on the backing store. We keep a
+ // one-pixel border around entries on the backing store to
+ // prevent bleeding of adjacent letters when using GL_LINEAR
+ // filtering for rendering. The origin of this rectangle is
+ // equivalent to the origin above.
+ private Rectangle2D origRect;
+
+ private boolean used; // Whether this text was used recently
+
+ TextData(String str, Point origin, Rectangle2D origRect, int unicodeID) {
+ this.str = str;
+ this.origin = origin;
+ this.origRect = origRect;
+ this.unicodeID = unicodeID;
+ }
+
+ String string() {
+ return str;
+ }
+
+ Point origin() {
+ return origin;
+ }
+
+ // The following three methods are used to locate the glyph
+ // within the expanded rectangle coming from normalize()
+ int origOriginX() {
+ return (int) -origRect.getMinX();
+ }
+
+ int origOriginY() {
+ return (int) -origRect.getMinY();
+ }
+
+ Rectangle2D origRect() {
+ return origRect;
+ }
+
+ boolean used() {
+ return used;
+ }
+
+ void markUsed() {
+ used = true;
+ }
+
+ void clearUsed() {
+ used = false;
+ }
+ }
+
+ class Manager implements BackingStoreManager {
+ private Graphics2D g;
+
+ public Object allocateBackingStore(int w, int h) {
+ // FIXME: should consider checking Font's attributes to see
+ // whether we're likely to need to support a full RGBA backing
+ // store (i.e., non-default Paint, foreground color, etc.), but
+ // for now, let's just be more efficient
+ TextureRenderer renderer;
+
+ if (renderDelegate.intensityOnly()) {
+ renderer = TextureRenderer.createAlphaOnlyRenderer(w, h, mipmap);
+ } else {
+ renderer = new TextureRenderer(w, h, true, mipmap);
+ }
+ renderer.setSmoothing(smoothing);
+
+ if (DEBUG) {
+ System.err.println(" TextRenderer allocating backing store " +
+ w + " x " + h);
+ }
+
+ return renderer;
+ }
+
+ public void deleteBackingStore(Object backingStore) {
+ ((TextureRenderer) backingStore).dispose();
+ }
+
+ public boolean preExpand(Rect cause, int attemptNumber) {
+ // Only try this one time; clear out potentially obsolete entries
+ // NOTE: this heuristic and the fact that it clears the used bit
+ // of all entries seems to cause cycling of entries in some
+ // situations, where the backing store becomes small compared to
+ // the amount of text on the screen (see the TextFlow demo) and
+ // the entries continually cycle in and out of the backing
+ // store, decreasing performance. If we added a little age
+ // information to the entries, and only cleared out entries
+ // above a certain age, this behavior would be eliminated.
+ // However, it seems the system usually stabilizes itself, so
+ // for now we'll just keep things simple. Note that if we don't
+ // clear the used bit here, the backing store tends to increase
+ // very quickly to its maximum size, at least with the TextFlow
+ // demo when the text is being continually re-laid out.
+ if (attemptNumber == 0) {
+ if (DEBUG) {
+ System.err.println(
+ "Clearing unused entries in preExpand(): attempt number " +
+ attemptNumber);
+ }
+
+ if (inBeginEndPair) {
+ // Draw any outstanding glyphs
+ flush();
+ }
+
+ clearUnusedEntries();
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean additionFailed(Rect cause, int attemptNumber) {
+ // Heavy hammer -- might consider doing something different
+ packer.clear();
+ stringLocations.clear();
+ mGlyphProducer.clearAllCacheEntries();
+
+ if (DEBUG) {
+ System.err.println(
+ " *** Cleared all text because addition failed ***");
+ }
+
+ if (attemptNumber == 0) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean canCompact() {
+ return true;
+ }
+
+ public void beginMovement(Object oldBackingStore, Object newBackingStore) {
+ // Exit the begin / end pair if necessary
+ if (inBeginEndPair) {
+ // Draw any outstanding glyphs
+ flush();
+
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+
+ // Pop client attrib bits used by the pipelined quad renderer
+ gl.glPopClientAttrib();
+
+ // The OpenGL spec is unclear about whether this changes the
+ // buffer bindings, so preemptively zero out the GL_ARRAY_BUFFER
+ // binding
+ if (is15Available(gl)) {
+ try {
+ gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
+ } catch (Exception e) {
+ isExtensionAvailable_GL_VERSION_1_5 = false;
+ }
+ }
+
+ if (isOrthoMode) {
+ ((TextureRenderer) oldBackingStore).endOrthoRendering();
+ } else {
+ ((TextureRenderer) oldBackingStore).end3DRendering();
+ }
+ }
+
+ TextureRenderer newRenderer = (TextureRenderer) newBackingStore;
+ g = newRenderer.createGraphics();
+ }
+
+ public void move(Object oldBackingStore, Rect oldLocation,
+ Object newBackingStore, Rect newLocation) {
+ TextureRenderer oldRenderer = (TextureRenderer) oldBackingStore;
+ TextureRenderer newRenderer = (TextureRenderer) newBackingStore;
+
+ if (oldRenderer == newRenderer) {
+ // Movement on the same backing store -- easy case
+ g.copyArea(oldLocation.x(), oldLocation.y(), oldLocation.w(),
+ oldLocation.h(), newLocation.x() - oldLocation.x(),
+ newLocation.y() - oldLocation.y());
+ } else {
+ // Need to draw from the old renderer's image into the new one
+ Image img = oldRenderer.getImage();
+ g.drawImage(img, newLocation.x(), newLocation.y(),
+ newLocation.x() + newLocation.w(),
+ newLocation.y() + newLocation.h(), oldLocation.x(),
+ oldLocation.y(), oldLocation.x() + oldLocation.w(),
+ oldLocation.y() + oldLocation.h(), null);
+ }
+ }
+
+ public void endMovement(Object oldBackingStore, Object newBackingStore) {
+ g.dispose();
+
+ // Sync the whole surface
+ TextureRenderer newRenderer = (TextureRenderer) newBackingStore;
+ newRenderer.markDirty(0, 0, newRenderer.getWidth(),
+ newRenderer.getHeight());
+
+ // Re-enter the begin / end pair if necessary
+ if (inBeginEndPair) {
+ if (isOrthoMode) {
+ ((TextureRenderer) newBackingStore).beginOrthoRendering(beginRenderingWidth,
+ beginRenderingHeight, beginRenderingDepthTestDisabled);
+ } else {
+ ((TextureRenderer) newBackingStore).begin3DRendering();
+ }
+
+ // Push client attrib bits used by the pipelined quad renderer
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+ gl.glPushClientAttrib((int) GL2.GL_ALL_CLIENT_ATTRIB_BITS);
+
+ if (haveCachedColor) {
+ if (cachedColor == null) {
+ ((TextureRenderer) newBackingStore).setColor(cachedR,
+ cachedG, cachedB, cachedA);
+ } else {
+ ((TextureRenderer) newBackingStore).setColor(cachedColor);
+ }
+ }
+ } else {
+ needToResetColor = true;
+ }
+ }
+ }
+
+ public static class DefaultRenderDelegate implements RenderDelegate {
+ public boolean intensityOnly() {
+ return true;
+ }
+
+ public Rectangle2D getBounds(CharSequence str, Font font,
+ FontRenderContext frc) {
+ return getBounds(font.createGlyphVector(frc,
+ new CharSequenceIterator(str)),
+ frc);
+ }
+
+ public Rectangle2D getBounds(String str, Font font,
+ FontRenderContext frc) {
+ return getBounds(font.createGlyphVector(frc, str), frc);
+ }
+
+ public Rectangle2D getBounds(GlyphVector gv, FontRenderContext frc) {
+ return gv.getVisualBounds();
+ }
+
+ public void drawGlyphVector(Graphics2D graphics, GlyphVector str,
+ int x, int y) {
+ graphics.drawGlyphVector(str, x, y);
+ }
+
+ public void draw(Graphics2D graphics, String str, int x, int y) {
+ graphics.drawString(str, x, y);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Glyph-by-glyph rendering support
+ //
+
+ // A temporary to prevent excessive garbage creation
+ private char[] singleUnicode = new char[1];
+
+ /** A Glyph represents either a single unicode glyph or a
+ substring of characters to be drawn. The reason for the dual
+ behavior is so that we can take in a sequence of unicode
+ characters and partition them into runs of individual glyphs,
+ but if we encounter complex text and/or unicode sequences we
+ don't understand, we can render them using the
+ string-by-string method. <P>
+
+ Glyphs need to be able to re-upload themselves to the backing
+ store on demand as we go along in the render sequence.
+ */
+
+ class Glyph {
+ // If this Glyph represents an individual unicode glyph, this
+ // is its unicode ID. If it represents a String, this is -1.
+ private int unicodeID;
+ // If the above field isn't -1, then these fields are used.
+ // The glyph code in the font
+ private int glyphCode;
+ // The GlyphProducer which created us
+ private GlyphProducer producer;
+ // The advance of this glyph
+ private float advance;
+ // The GlyphVector for this single character; this is passed
+ // in during construction but cleared during the upload
+ // process
+ private GlyphVector singleUnicodeGlyphVector;
+ // The rectangle of this glyph on the backing store, or null
+ // if it has been cleared due to space pressure
+ private Rect glyphRectForTextureMapping;
+ // If this Glyph represents a String, this is the sequence of
+ // characters
+ private String str;
+ // Whether we need a valid advance when rendering this string
+ // (i.e., whether it has other single glyphs coming after it)
+ private boolean needAdvance;
+
+ // Creates a Glyph representing an individual Unicode character
+ public Glyph(int unicodeID,
+ int glyphCode,
+ float advance,
+ GlyphVector singleUnicodeGlyphVector,
+ GlyphProducer producer) {
+ this.unicodeID = unicodeID;
+ this.glyphCode = glyphCode;
+ this.advance = advance;
+ this.singleUnicodeGlyphVector = singleUnicodeGlyphVector;
+ this.producer = producer;
+ }
+
+ // Creates a Glyph representing a sequence of characters, with
+ // an indication of whether additional single glyphs are being
+ // rendered after it
+ public Glyph(String str, boolean needAdvance) {
+ this.str = str;
+ this.needAdvance = needAdvance;
+ }
+
+ /** Returns this glyph's unicode ID */
+ public int getUnicodeID() {
+ return unicodeID;
+ }
+
+ /** Returns this glyph's (font-specific) glyph code */
+ public int getGlyphCode() {
+ return glyphCode;
+ }
+
+ /** Returns the advance for this glyph */
+ public float getAdvance() {
+ return advance;
+ }
+
+ /** Draws this glyph and returns the (x) advance for this glyph */
+ public float draw3D(float inX, float inY, float z, float scaleFactor) {
+ if (str != null) {
+ draw3D_ROBUST(str, inX, inY, z, scaleFactor);
+ if (!needAdvance) {
+ return 0;
+ }
+ // Compute and return the advance for this string
+ GlyphVector gv = font.createGlyphVector(getFontRenderContext(), str);
+ float totalAdvance = 0;
+ for (int i = 0; i < gv.getNumGlyphs(); i++) {
+ totalAdvance += gv.getGlyphMetrics(i).getAdvance();
+ }
+ return totalAdvance;
+ }
+
+ // This is the code path taken for individual glyphs
+ if (glyphRectForTextureMapping == null) {
+ upload();
+ }
+
+ try {
+ if (mPipelinedQuadRenderer == null) {
+ mPipelinedQuadRenderer = new Pipelined_QuadRenderer();
+ }
+
+ TextureRenderer renderer = getBackingStore();
+ // Handles case where NPOT texture is used for backing store
+ TextureCoords wholeImageTexCoords = renderer.getTexture().getImageTexCoords();
+ float xScale = wholeImageTexCoords.right();
+ float yScale = wholeImageTexCoords.bottom();
+
+ Rect rect = glyphRectForTextureMapping;
+ TextData data = (TextData) rect.getUserData();
+ data.markUsed();
+
+ Rectangle2D origRect = data.origRect();
+
+ float x = inX - (scaleFactor * data.origOriginX());
+ float y = inY - (scaleFactor * ((float) origRect.getHeight() - data.origOriginY()));
+
+ int texturex = rect.x() + (data.origin().x - data.origOriginX());
+ int texturey = renderer.getHeight() - rect.y() - (int) origRect.getHeight() -
+ (data.origin().y - data.origOriginY());
+ int width = (int) origRect.getWidth();
+ int height = (int) origRect.getHeight();
+
+ float tx1 = xScale * (float) texturex / (float) renderer.getWidth();
+ float ty1 = yScale * (1.0f -
+ ((float) texturey / (float) renderer.getHeight()));
+ float tx2 = xScale * (float) (texturex + width) / (float) renderer.getWidth();
+ float ty2 = yScale * (1.0f -
+ ((float) (texturey + height) / (float) renderer.getHeight()));
+
+ mPipelinedQuadRenderer.glTexCoord2f(tx1, ty1);
+ mPipelinedQuadRenderer.glVertex3f(x, y, z);
+ mPipelinedQuadRenderer.glTexCoord2f(tx2, ty1);
+ mPipelinedQuadRenderer.glVertex3f(x + (width * scaleFactor), y,
+ z);
+ mPipelinedQuadRenderer.glTexCoord2f(tx2, ty2);
+ mPipelinedQuadRenderer.glVertex3f(x + (width * scaleFactor),
+ y + (height * scaleFactor), z);
+ mPipelinedQuadRenderer.glTexCoord2f(tx1, ty2);
+ mPipelinedQuadRenderer.glVertex3f(x,
+ y + (height * scaleFactor), z);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return advance;
+ }
+
+ /** Notifies this glyph that it's been cleared out of the cache */
+ public void clear() {
+ glyphRectForTextureMapping = null;
+ }
+
+ private void upload() {
+ GlyphVector gv = getGlyphVector();
+ Rectangle2D origBBox = preNormalize(renderDelegate.getBounds(gv, getFontRenderContext()));
+ Rectangle2D bbox = normalize(origBBox);
+ Point origin = new Point((int) -bbox.getMinX(),
+ (int) -bbox.getMinY());
+ Rect rect = new Rect(0, 0, (int) bbox.getWidth(),
+ (int) bbox.getHeight(),
+ new TextData(null, origin, origBBox, unicodeID));
+ packer.add(rect);
+ glyphRectForTextureMapping = rect;
+ Graphics2D g = getGraphics2D();
+ // OK, should now have an (x, y) for this rectangle; rasterize
+ // the glyph
+ int strx = rect.x() + origin.x;
+ int stry = rect.y() + origin.y;
+
+ // Clear out the area we're going to draw into
+ g.setComposite(AlphaComposite.Clear);
+ g.fillRect(rect.x(), rect.y(), rect.w(), rect.h());
+ g.setComposite(AlphaComposite.Src);
+
+ // Draw the string
+ renderDelegate.drawGlyphVector(g, gv, strx, stry);
+
+ if (DRAW_BBOXES) {
+ TextData data = (TextData) rect.getUserData();
+ // Draw a bounding box on the backing store
+ g.drawRect(strx - data.origOriginX(),
+ stry - data.origOriginY(),
+ (int) data.origRect().getWidth(),
+ (int) data.origRect().getHeight());
+ g.drawRect(strx - data.origin().x,
+ stry - data.origin().y,
+ rect.w(),
+ rect.h());
+ }
+
+ // Mark this region of the TextureRenderer as dirty
+ getBackingStore().markDirty(rect.x(), rect.y(), rect.w(),
+ rect.h());
+ // Re-register ourselves with our producer
+ producer.register(this);
+ }
+
+ private GlyphVector getGlyphVector() {
+ GlyphVector gv = singleUnicodeGlyphVector;
+ if (gv != null) {
+ singleUnicodeGlyphVector = null; // Don't need this anymore
+ return gv;
+ }
+ singleUnicode[0] = (char) unicodeID;
+ return font.createGlyphVector(getFontRenderContext(), singleUnicode);
+ }
+ }
+
+ class GlyphProducer {
+ final int undefined = -2;
+ FontRenderContext fontRenderContext;
+ List/*<Glyph>*/ glyphsOutput = new ArrayList/*<Glyph>*/();
+ // The mapping from unicode character to font-specific glyph ID
+ int[] unicodes2Glyphs;
+ // The mapping from glyph ID to Glyph
+ Glyph[] glyphCache;
+ // We re-use this for each incoming string
+ CharSequenceIterator iter = new CharSequenceIterator();
+
+ GlyphProducer(int fontLengthInGlyphs) {
+ unicodes2Glyphs = new int[512];
+ glyphCache = new Glyph[fontLengthInGlyphs];
+ clearAllCacheEntries();
+ }
+
+ public List/*<Glyph>*/ getGlyphs(CharSequence inString) {
+ glyphsOutput.clear();
+ iter.initFromCharSequence(inString);
+ GlyphVector fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(),
+ iter);
+ boolean complex = (fullRunGlyphVector.getLayoutFlags() != 0);
+ if (complex || DISABLE_GLYPH_CACHE) {
+ // Punt to the robust version of the renderer
+ glyphsOutput.add(new Glyph(inString.toString(), false));
+ return glyphsOutput;
+ }
+
+ int lengthInGlyphs = fullRunGlyphVector.getNumGlyphs();
+ int i = 0;
+ while (i < lengthInGlyphs) {
+ Glyph glyph = getGlyph(inString, fullRunGlyphVector, i);
+ if (glyph != null) {
+ glyphsOutput.add(glyph);
+ i++;
+ } else {
+ // Assemble a run of characters that don't fit in
+ // the cache
+ StringBuffer buf = new StringBuffer();
+ while (i < lengthInGlyphs &&
+ getGlyph(inString, fullRunGlyphVector, i) == null) {
+ buf.append(inString.charAt(i++));
+ }
+ glyphsOutput.add(new Glyph(buf.toString(),
+ // Any more glyphs after this run?
+ i < lengthInGlyphs));
+ }
+ }
+ return glyphsOutput;
+ }
+
+ public void clearCacheEntry(int unicodeID) {
+ int glyphID = unicodes2Glyphs[unicodeID];
+ if (glyphID != undefined) {
+ Glyph glyph = glyphCache[glyphID];
+ if (glyph != null) {
+ glyph.clear();
+ }
+ glyphCache[glyphID] = null;
+ }
+ unicodes2Glyphs[unicodeID] = undefined;
+ }
+
+ public void clearAllCacheEntries() {
+ for (int i = 0; i < unicodes2Glyphs.length; i++) {
+ clearCacheEntry(i);
+ }
+ }
+
+ public void register(Glyph glyph) {
+ unicodes2Glyphs[glyph.getUnicodeID()] = glyph.getGlyphCode();
+ glyphCache[glyph.getGlyphCode()] = glyph;
+ }
+
+ public float getGlyphPixelWidth(char unicodeID) {
+ Glyph glyph = getGlyph(unicodeID);
+ if (glyph != null) {
+ return glyph.getAdvance();
+ }
+
+ // Have to do this the hard / uncached way
+ singleUnicode[0] = unicodeID;
+ GlyphVector gv = font.createGlyphVector(fontRenderContext,
+ singleUnicode);
+ return gv.getGlyphMetrics(0).getAdvance();
+ }
+
+ // Returns a glyph object for this single glyph. Returns null
+ // if the unicode or glyph ID would be out of bounds of the
+ // glyph cache.
+ private Glyph getGlyph(CharSequence inString,
+ GlyphVector fullRunGlyphVector,
+ int index) {
+ char unicodeID = inString.charAt(index);
+
+ if (unicodeID >= unicodes2Glyphs.length) {
+ return null;
+ }
+
+ int glyphID = unicodes2Glyphs[unicodeID];
+ if (glyphID != undefined) {
+ return glyphCache[glyphID];
+ }
+
+ // Must fabricate the glyph
+ singleUnicode[0] = unicodeID;
+ GlyphVector gv = font.createGlyphVector(getFontRenderContext(), singleUnicode);
+ return getGlyph(unicodeID, gv, fullRunGlyphVector.getGlyphMetrics(index));
+ }
+
+ // It's unclear whether this variant might produce less
+ // optimal results than if we can see the entire GlyphVector
+ // for the incoming string
+ private Glyph getGlyph(int unicodeID) {
+ if (unicodeID >= unicodes2Glyphs.length) {
+ return null;
+ }
+
+ int glyphID = unicodes2Glyphs[unicodeID];
+ if (glyphID != undefined) {
+ return glyphCache[glyphID];
+ }
+ singleUnicode[0] = (char) unicodeID;
+ GlyphVector gv = font.createGlyphVector(getFontRenderContext(), singleUnicode);
+ return getGlyph(unicodeID, gv, gv.getGlyphMetrics(0));
+ }
+
+ private Glyph getGlyph(int unicodeID,
+ GlyphVector singleUnicodeGlyphVector,
+ GlyphMetrics metrics) {
+ int glyphCode = singleUnicodeGlyphVector.getGlyphCode(0);
+ // Have seen huge glyph codes (65536) coming out of some fonts in some Unicode situations
+ if (glyphCode >= glyphCache.length) {
+ return null;
+ }
+ Glyph glyph = new Glyph(unicodeID,
+ glyphCode,
+ metrics.getAdvance(),
+ singleUnicodeGlyphVector,
+ this);
+ register(glyph);
+ return glyph;
+ }
+ }
+
+ class Pipelined_QuadRenderer {
+ int mOutstandingGlyphsVerticesPipeline = 0;
+ FloatBuffer mTexCoords;
+ FloatBuffer mVertCoords;
+ boolean usingVBOs;
+ int mVBO_For_ResuableTileVertices;
+ int mVBO_For_ResuableTileTexCoords;
+
+ Pipelined_QuadRenderer() {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+ mVertCoords = Buffers.newDirectFloatBuffer(kTotalBufferSizeCoordsVerts);
+ mTexCoords = Buffers.newDirectFloatBuffer(kTotalBufferSizeCoordsTex);
+
+ usingVBOs = is15Available(gl);
+
+ if (usingVBOs) {
+ try {
+ int[] vbos = new int[2];
+ gl.glGenBuffers(2, IntBuffer.wrap(vbos));
+
+ mVBO_For_ResuableTileVertices = vbos[0];
+ mVBO_For_ResuableTileTexCoords = vbos[1];
+
+ gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,
+ mVBO_For_ResuableTileVertices);
+ gl.glBufferData(GL2.GL_ARRAY_BUFFER, kTotalBufferSizeBytesVerts,
+ null, GL2.GL_STREAM_DRAW); // stream draw because this is a single quad use pipeline
+
+ gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,
+ mVBO_For_ResuableTileTexCoords);
+ gl.glBufferData(GL2.GL_ARRAY_BUFFER, kTotalBufferSizeBytesTex,
+ null, GL2.GL_STREAM_DRAW); // stream draw because this is a single quad use pipeline
+ } catch (Exception e) {
+ isExtensionAvailable_GL_VERSION_1_5 = false;
+ usingVBOs = false;
+ }
+ }
+ }
+
+ public void glTexCoord2f(float v, float v1) {
+ mTexCoords.put(v);
+ mTexCoords.put(v1);
+ }
+
+ public void glVertex3f(float inX, float inY, float inZ) {
+ mVertCoords.put(inX);
+ mVertCoords.put(inY);
+ mVertCoords.put(inZ);
+
+ mOutstandingGlyphsVerticesPipeline++;
+
+ if (mOutstandingGlyphsVerticesPipeline >= kTotalBufferSizeVerts) {
+ this.draw();
+ }
+ }
+
+ private void draw() {
+ if (useVertexArrays) {
+ drawVertexArrays();
+ } else {
+ drawIMMEDIATE();
+ }
+ }
+
+ private void drawVertexArrays() {
+ if (mOutstandingGlyphsVerticesPipeline > 0) {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+
+ TextureRenderer renderer = getBackingStore();
+ Texture texture = renderer.getTexture(); // triggers texture uploads. Maybe this should be more obvious?
+
+ mVertCoords.rewind();
+ mTexCoords.rewind();
+
+ gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
+
+ if (usingVBOs) {
+ gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,
+ mVBO_For_ResuableTileVertices);
+ gl.glBufferSubData(GL2.GL_ARRAY_BUFFER, 0,
+ mOutstandingGlyphsVerticesPipeline * kSizeInBytes_OneVertices_VertexData,
+ mVertCoords); // upload only the new stuff
+ gl.glVertexPointer(3, GL2.GL_FLOAT, 0, 0);
+ } else {
+ gl.glVertexPointer(3, GL2.GL_FLOAT, 0, mVertCoords);
+ }
+
+ gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
+
+ if (usingVBOs) {
+ gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,
+ mVBO_For_ResuableTileTexCoords);
+ gl.glBufferSubData(GL2.GL_ARRAY_BUFFER, 0,
+ mOutstandingGlyphsVerticesPipeline * kSizeInBytes_OneVertices_TexData,
+ mTexCoords); // upload only the new stuff
+ gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, 0);
+ } else {
+ gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, mTexCoords);
+ }
+
+ gl.glDrawArrays(GL2.GL_QUADS, 0,
+ mOutstandingGlyphsVerticesPipeline);
+
+ mVertCoords.rewind();
+ mTexCoords.rewind();
+ mOutstandingGlyphsVerticesPipeline = 0;
+ }
+ }
+
+ private void drawIMMEDIATE() {
+ if (mOutstandingGlyphsVerticesPipeline > 0) {
+ TextureRenderer renderer = getBackingStore();
+ Texture texture = renderer.getTexture(); // triggers texture uploads. Maybe this should be more obvious?
+
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+ gl.glBegin(GL2.GL_QUADS);
+
+ try {
+ int numberOfQuads = mOutstandingGlyphsVerticesPipeline / 4;
+ mVertCoords.rewind();
+ mTexCoords.rewind();
+
+ for (int i = 0; i < numberOfQuads; i++) {
+ gl.glTexCoord2f(mTexCoords.get(), mTexCoords.get());
+ gl.glVertex3f(mVertCoords.get(), mVertCoords.get(),
+ mVertCoords.get());
+
+ gl.glTexCoord2f(mTexCoords.get(), mTexCoords.get());
+ gl.glVertex3f(mVertCoords.get(), mVertCoords.get(),
+ mVertCoords.get());
+
+ gl.glTexCoord2f(mTexCoords.get(), mTexCoords.get());
+ gl.glVertex3f(mVertCoords.get(), mVertCoords.get(),
+ mVertCoords.get());
+
+ gl.glTexCoord2f(mTexCoords.get(), mTexCoords.get());
+ gl.glVertex3f(mVertCoords.get(), mVertCoords.get(),
+ mVertCoords.get());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ gl.glEnd();
+ mVertCoords.rewind();
+ mTexCoords.rewind();
+ mOutstandingGlyphsVerticesPipeline = 0;
+ }
+ }
+ }
+ }
+
+ class DebugListener implements GLEventListener {
+ private GLU glu;
+ private Frame frame;
+
+ DebugListener(GL gl, Frame frame) {
+ this.glu = GLU.createGLU(gl);
+ this.frame = frame;
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+ gl.glClear(GL2.GL_DEPTH_BUFFER_BIT | GL2.GL_COLOR_BUFFER_BIT);
+
+ if (packer == null) {
+ return;
+ }
+
+ TextureRenderer rend = getBackingStore();
+ final int w = rend.getWidth();
+ final int h = rend.getHeight();
+ rend.beginOrthoRendering(w, h);
+ rend.drawOrthoRect(0, 0);
+ rend.endOrthoRendering();
+
+ if ((frame.getWidth() != w) || (frame.getHeight() != h)) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ frame.setSize(w, h);
+ }
+ });
+ }
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ glu.destroy();
+ glu=null;
+ frame=null;
+ }
+
+ // Unused methods
+ public void init(GLAutoDrawable drawable) {
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width,
+ int height) {
+ }
+
+ public void displayChanged(GLAutoDrawable drawable,
+ boolean modeChanged, boolean deviceChanged) {
+ }
+ }
+
+ /**
+ * Sets whether vertex arrays are being used internally for
+ * rendering, or whether text is rendered using the OpenGL
+ * immediate mode commands. This is provided as a concession for
+ * certain graphics cards which have poor vertex array
+ * performance. Defaults to true.
+ */
+ public void setUseVertexArrays(boolean useVertexArrays) {
+ this.useVertexArrays = useVertexArrays;
+ }
+
+ /**
+ * Indicates whether vertex arrays are being used internally for
+ * rendering, or whether text is rendered using the OpenGL
+ * immediate mode commands. Defaults to true.
+ */
+ public boolean getUseVertexArrays() {
+ return useVertexArrays;
+ }
+
+ /**
+ * Sets whether smoothing (i.e., GL_LINEAR filtering) is enabled
+ * in the backing TextureRenderer of this TextRenderer. A few
+ * graphics cards do not behave well when this is enabled,
+ * resulting in fuzzy text. Defaults to true.
+ */
+ public void setSmoothing(boolean smoothing) {
+ this.smoothing = smoothing;
+ getBackingStore().setSmoothing(smoothing);
+ }
+
+ /**
+ * Indicates whether smoothing is enabled in the backing
+ * TextureRenderer of this TextRenderer. A few graphics cards do
+ * not behave well when this is enabled, resulting in fuzzy text.
+ * Defaults to true.
+ */
+ public boolean getSmoothing() {
+ return smoothing;
+ }
+
+ private boolean is15Available(GL gl) {
+ if (!checkFor_isExtensionAvailable_GL_VERSION_1_5) {
+ isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable("GL_VERSION_1_5");
+ checkFor_isExtensionAvailable_GL_VERSION_1_5 = true;
+ }
+ return isExtensionAvailable_GL_VERSION_1_5;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java
new file mode 100755
index 000000000..bc5aa517e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java
@@ -0,0 +1,699 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.awt;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.image.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import javax.media.opengl.glu.gl2.*;
+import com.jogamp.opengl.util.texture.*;
+import com.jogamp.opengl.util.texture.spi.*;
+import com.jogamp.opengl.util.texture.awt.*;
+
+/** Provides the ability to render into an OpenGL {@link
+ com.jogamp.opengl.util.texture.Texture Texture} using the Java 2D
+ APIs. This renderer class uses an internal Java 2D image (of
+ unspecified type) for its backing store and flushes portions of
+ that image to an OpenGL texture on demand. The resulting OpenGL
+ texture can then be mapped on to a polygon for display. */
+
+public class TextureRenderer {
+ // For now, we supply only a BufferedImage back-end for this
+ // renderer. In theory we could use the Java 2D/JOGL bridge to fully
+ // accelerate the rendering paths, but there are restrictions on
+ // what work can be done where; for example, Graphics2D-related work
+ // must not be done on the Queue Flusher Thread, but JOGL's
+ // OpenGL-related work must be. This implies that the user's code
+ // would need to be split up into multiple callbacks run from the
+ // appropriate threads, which would be somewhat unfortunate.
+
+ // Whether we have an alpha channel in the (RGB/A) backing store
+ private boolean alpha;
+
+ // Whether we're using only a GL_INTENSITY backing store
+ private boolean intensity;
+
+ // Whether we're attempting to use automatic mipmap generation support
+ private boolean mipmap;
+
+ // Whether smoothing is enabled for the OpenGL texture (switching
+ // between GL_LINEAR and GL_NEAREST filtering)
+ private boolean smoothing = true;
+ private boolean smoothingChanged;
+
+ // The backing store itself
+ private BufferedImage image;
+
+ private Texture texture;
+ private AWTTextureData textureData;
+ private boolean mustReallocateTexture;
+ private Rectangle dirtyRegion;
+
+ private GLUgl2 glu = new GLUgl2();
+
+ // Current color
+ private float r = 1.0f;
+ private float g = 1.0f;
+ private float b = 1.0f;
+ private float a = 1.0f;
+
+ /** Creates a new renderer with backing store of the specified width
+ and height. If <CODE>alpha</CODE> is true, allocates an alpha
+ channel in the backing store image. No mipmap support is
+ requested.
+
+ @param width the width of the texture to render into
+ @param height the height of the texture to render into
+ @param alpha whether to allocate an alpha channel for the texture
+ */
+ public TextureRenderer(int width, int height, boolean alpha) {
+ this(width, height, alpha, false);
+ }
+
+ /** Creates a new renderer with backing store of the specified width
+ and height. If <CODE>alpha</CODE> is true, allocates an alpha channel in the
+ backing store image. If <CODE>mipmap</CODE> is true, attempts to use OpenGL's
+ automatic mipmap generation for better smoothing when rendering
+ the TextureRenderer's contents at a distance.
+
+ @param width the width of the texture to render into
+ @param height the height of the texture to render into
+ @param alpha whether to allocate an alpha channel for the texture
+ @param mipmap whether to attempt use of automatic mipmap generation
+ */
+ public TextureRenderer(int width, int height, boolean alpha, boolean mipmap) {
+ this(width, height, alpha, false, mipmap);
+ }
+
+ // Internal constructor to avoid confusion since alpha only makes
+ // sense when intensity is not set
+ private TextureRenderer(int width, int height, boolean alpha, boolean intensity, boolean mipmap) {
+ this.alpha = alpha;
+ this.intensity = intensity;
+ this.mipmap = mipmap;
+ init(width, height);
+ }
+
+ /** Creates a new renderer with a special kind of backing store
+ which acts only as an alpha channel. No mipmap support is
+ requested. Internally, this associates a GL_INTENSITY OpenGL
+ texture with the backing store. */
+ public static TextureRenderer createAlphaOnlyRenderer(int width, int height) {
+ return createAlphaOnlyRenderer(width, height, false);
+ }
+
+ /** Creates a new renderer with a special kind of backing store
+ which acts only as an alpha channel. If <CODE>mipmap</CODE> is
+ true, attempts to use OpenGL's automatic mipmap generation for
+ better smoothing when rendering the TextureRenderer's contents
+ at a distance. Internally, this associates a GL_INTENSITY OpenGL
+ texture with the backing store. */
+ public static TextureRenderer createAlphaOnlyRenderer(int width, int height, boolean mipmap) {
+ return new TextureRenderer(width, height, false, true, mipmap);
+ }
+
+ /** Returns the width of the backing store of this renderer.
+
+ @return the width of the backing store of this renderer
+ */
+ public int getWidth() {
+ return image.getWidth();
+ }
+
+ /** Returns the height of the backing store of this renderer.
+
+ @return the height of the backing store of this renderer
+ */
+ public int getHeight() {
+ return image.getHeight();
+ }
+
+ /** Returns the size of the backing store of this renderer in a
+ newly-allocated {@link java.awt.Dimension Dimension} object.
+
+ @return the size of the backing store of this renderer
+ */
+ public Dimension getSize() {
+ return getSize(null);
+ }
+
+ /** Returns the size of the backing store of this renderer. Uses the
+ {@link java.awt.Dimension Dimension} object if one is supplied,
+ or allocates a new one if null is passed.
+
+ @param d a {@link java.awt.Dimension Dimension} object in which
+ to store the results, or null to allocate a new one
+
+ @return the size of the backing store of this renderer
+ */
+ public Dimension getSize(Dimension d) {
+ if (d == null)
+ d = new Dimension();
+ d.setSize(image.getWidth(), image.getHeight());
+ return d;
+ }
+
+ /** Sets the size of the backing store of this renderer. This may
+ cause the OpenGL texture object associated with this renderer to
+ be invalidated; it is not recommended to cache this texture
+ object outside this class but to instead call {@link #getTexture
+ getTexture} when it is needed.
+
+ @param width the new width of the backing store of this renderer
+ @param height the new height of the backing store of this renderer
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void setSize(int width, int height) throws GLException {
+ init(width, height);
+ }
+
+ /** Sets the size of the backing store of this renderer. This may
+ cause the OpenGL texture object associated with this renderer to
+ be invalidated.
+
+ @param d the new size of the backing store of this renderer
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void setSize(Dimension d) throws GLException {
+ setSize(d.width, d.height);
+ }
+
+ /** Sets whether smoothing is enabled for the OpenGL texture; if so,
+ uses GL_LINEAR interpolation for the minification and
+ magnification filters. Defaults to true. Changes to this setting
+ will not take effect until the next call to {@link
+ #beginOrthoRendering beginOrthoRendering}.
+
+ @param smoothing whether smoothing is enabled for the OpenGL texture
+ */
+ public void setSmoothing(boolean smoothing) {
+ this.smoothing = smoothing;
+ smoothingChanged = true;
+ }
+
+ /** Returns whether smoothing is enabled for the OpenGL texture; see
+ {@link #setSmoothing setSmoothing}. Defaults to true.
+
+ @return whether smoothing is enabled for the OpenGL texture
+ */
+ public boolean getSmoothing() {
+ return smoothing;
+ }
+
+ /** Creates a {@link java.awt.Graphics2D Graphics2D} instance for
+ rendering to the backing store of this renderer. The returned
+ object should be disposed of using the normal {@link
+ java.awt.Graphics#dispose() Graphics.dispose()} method once it
+ is no longer being used.
+
+ @return a new {@link java.awt.Graphics2D Graphics2D} object for
+ rendering into the backing store of this renderer
+ */
+ public Graphics2D createGraphics() {
+ return image.createGraphics();
+ }
+
+ /** Returns the underlying Java 2D {@link java.awt.Image Image}
+ being rendered into. */
+ public Image getImage() {
+ return image;
+ }
+
+ /** Marks the given region of the TextureRenderer as dirty. This
+ region, and any previously set dirty regions, will be
+ automatically synchronized with the underlying Texture during
+ the next {@link #getTexture getTexture} operation, at which
+ point the dirty region will be cleared. It is not necessary for
+ an OpenGL context to be current when this method is called.
+
+ @param x the x coordinate (in Java 2D coordinates -- relative to
+ upper left) of the region to update
+ @param y the y coordinate (in Java 2D coordinates -- relative to
+ upper left) of the region to update
+ @param width the width of the region to update
+ @param height the height of the region to update
+ */
+ public void markDirty(int x, int y, int width, int height) {
+ Rectangle curRegion = new Rectangle(x, y, width, height);
+ if (dirtyRegion == null) {
+ dirtyRegion = curRegion;
+ } else {
+ dirtyRegion.add(curRegion);
+ }
+ }
+
+ /** Returns the underlying OpenGL Texture object associated with
+ this renderer, synchronizing any dirty regions of the
+ TextureRenderer with the underlying OpenGL texture.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public Texture getTexture() throws GLException {
+ if (dirtyRegion != null) {
+ sync(dirtyRegion.x, dirtyRegion.y, dirtyRegion.width, dirtyRegion.height);
+ dirtyRegion = null;
+ }
+
+ ensureTexture();
+ return texture;
+ }
+
+ /** Disposes all resources associated with this renderer. It is not
+ valid to use this renderer after calling this method.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void dispose() throws GLException {
+ if (texture != null) {
+ texture.dispose();
+ texture = null;
+ }
+ if (image != null) {
+ image.flush();
+ image = null;
+ }
+ }
+
+ /** Convenience method which assists in rendering portions of the
+ OpenGL texture to the screen, if the application intends to draw
+ them as a flat overlay on to the screen. Pushes OpenGL state
+ bits (GL_ENABLE_BIT, GL_DEPTH_BUFFER_BIT and GL_TRANSFORM_BIT);
+ disables the depth test, back-face culling, and lighting;
+ enables the texture in this renderer; and sets up the viewing
+ matrices for orthographic rendering where the coordinates go
+ from (0, 0) at the lower left to (width, height) at the upper
+ right. Equivalent to beginOrthoRendering(width, height, true).
+ {@link #endOrthoRendering} must be used in conjunction with this
+ method to restore all OpenGL states.
+
+ @param width the width of the current on-screen OpenGL drawable
+ @param height the height of the current on-screen OpenGL drawable
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void beginOrthoRendering(int width, int height) throws GLException {
+ beginOrthoRendering(width, height, true);
+ }
+
+ /** Convenience method which assists in rendering portions of the
+ OpenGL texture to the screen, if the application intends to draw
+ them as a flat overlay on to the screen. Pushes OpenGL state
+ bits (GL_ENABLE_BIT, GL_DEPTH_BUFFER_BIT and GL_TRANSFORM_BIT);
+ disables the depth test (if the "disableDepthTest" argument is
+ true), back-face culling, and lighting; enables the texture in
+ this renderer; and sets up the viewing matrices for orthographic
+ rendering where the coordinates go from (0, 0) at the lower left
+ to (width, height) at the upper right. {@link
+ #endOrthoRendering} must be used in conjunction with this method
+ to restore all OpenGL states.
+
+ @param width the width of the current on-screen OpenGL drawable
+ @param height the height of the current on-screen OpenGL drawable
+ @param disableDepthTest whether the depth test should be disabled
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void beginOrthoRendering(int width, int height, boolean disableDepthTest) throws GLException {
+ beginRendering(true, width, height, disableDepthTest);
+ }
+
+ /** Convenience method which assists in rendering portions of the
+ OpenGL texture to the screen as 2D quads in 3D space. Pushes
+ OpenGL state (GL_ENABLE_BIT); disables lighting; and enables the
+ texture in this renderer. Unlike {@link #beginOrthoRendering
+ beginOrthoRendering}, does not modify the depth test, back-face
+ culling, lighting, or the modelview or projection matrices. The
+ user is responsible for setting up the view matrices for correct
+ results of {@link #draw3DRect draw3DRect}. {@link
+ #end3DRendering} must be used in conjunction with this method to
+ restore all OpenGL states.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void begin3DRendering() throws GLException {
+ beginRendering(false, 0, 0, false);
+ }
+
+ /** Changes the color of the polygons, and therefore the drawn
+ images, this TextureRenderer produces. Use of this method is
+ optional. The TextureRenderer uses the GL_MODULATE texture
+ environment mode, which causes the portions of the rendered
+ texture to be multiplied by the color of the rendered
+ polygons. The polygon color can be varied to achieve effects
+ like tinting of the overall output or fading in and out by
+ changing the alpha of the color. <P>
+
+ Each component ranges from 0.0f - 1.0f. The alpha component, if
+ used, does not need to be premultiplied into the color channels
+ as described in the documentation for {@link
+ com.jogamp.opengl.util.texture.Texture Texture}, although
+ premultiplied colors are used internally. The default color is
+ opaque white.
+
+ @param r the red component of the new color
+ @param g the green component of the new color
+ @param b the blue component of the new color
+ @param a the alpha component of the new color, 0.0f = completely
+ transparent, 1.0f = completely opaque
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void setColor(float r, float g, float b, float a) throws GLException {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+ this.r = r * a;
+ this.g = g * a;
+ this.b = b * a;
+ this.a = a;
+
+ gl.glColor4f(this.r, this.g, this.b, this.a);
+ }
+
+ private float[] compArray;
+ /** Changes the current color of this TextureRenderer to the
+ supplied one. The default color is opaque white. See {@link
+ #setColor(float,float,float,float) setColor} for more details.
+
+ @param color the new color to use for rendering
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void setColor(Color color) throws GLException {
+ // Get color's RGBA components as floats in the range [0,1].
+ if (compArray == null) {
+ compArray = new float[4];
+ }
+ color.getRGBComponents(compArray);
+ setColor(compArray[0], compArray[1], compArray[2], compArray[3]);
+ }
+
+ /** Draws an orthographically projected rectangle containing all of
+ the underlying texture to the specified location on the
+ screen. All (x, y) coordinates are specified relative to the
+ lower left corner of either the texture image or the current
+ OpenGL drawable. This method is equivalent to
+ <code>drawOrthoRect(screenx, screeny, 0, 0, getWidth(),
+ getHeight());</code>.
+
+ @param screenx the on-screen x coordinate at which to draw the rectangle
+ @param screeny the on-screen y coordinate (relative to lower left) at
+ which to draw the rectangle
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void drawOrthoRect(int screenx, int screeny) throws GLException {
+ drawOrthoRect(screenx, screeny, 0, 0, getWidth(), getHeight());
+ }
+
+ /** Draws an orthographically projected rectangle of the underlying
+ texture to the specified location on the screen. All (x, y)
+ coordinates are specified relative to the lower left corner of
+ either the texture image or the current OpenGL drawable.
+
+ @param screenx the on-screen x coordinate at which to draw the rectangle
+ @param screeny the on-screen y coordinate (relative to lower left) at
+ which to draw the rectangle
+ @param texturex the x coordinate of the pixel in the texture of
+ the lower left portion of the rectangle to draw
+ @param texturey the y coordinate of the pixel in the texture
+ (relative to lower left) of the lower left portion of the
+ rectangle to draw
+ @param width the width of the rectangle to draw
+ @param height the height of the rectangle to draw
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void drawOrthoRect(int screenx, int screeny,
+ int texturex, int texturey,
+ int width, int height) throws GLException {
+ draw3DRect(screenx, screeny, 0, texturex, texturey, width, height, 1);
+ }
+
+ /** Draws a rectangle of the underlying texture to the specified 3D
+ location. In the current coordinate system, the lower left
+ corner of the rectangle is placed at (x, y, z), and the upper
+ right corner is placed at (x + width * scaleFactor, y + height *
+ scaleFactor, z). The lower left corner of the sub-rectangle of
+ the texture is (texturex, texturey) and the upper right corner
+ is (texturex + width, texturey + height). For back-face culling
+ purposes, the rectangle is drawn with counterclockwise
+ orientation of the vertices when viewed from the front.
+
+ @param x the x coordinate at which to draw the rectangle
+ @param y the y coordinate at which to draw the rectangle
+ @param z the z coordinate at which to draw the rectangle
+ @param texturex the x coordinate of the pixel in the texture of
+ the lower left portion of the rectangle to draw
+ @param texturey the y coordinate of the pixel in the texture
+ (relative to lower left) of the lower left portion of the
+ rectangle to draw
+ @param width the width in texels of the rectangle to draw
+ @param height the height in texels of the rectangle to draw
+ @param scaleFactor the scale factor to apply (multiplicatively)
+ to the size of the drawn rectangle
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void draw3DRect(float x, float y, float z,
+ int texturex, int texturey,
+ int width, int height,
+ float scaleFactor) throws GLException {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+ Texture texture = getTexture();
+ TextureCoords coords = texture.getSubImageTexCoords(texturex, texturey,
+ texturex + width,
+ texturey + height);
+ gl.glBegin(GL2.GL_QUADS);
+ gl.glTexCoord2f(coords.left(), coords.bottom());
+ gl.glVertex3f(x, y, z);
+ gl.glTexCoord2f(coords.right(), coords.bottom());
+ gl.glVertex3f(x + width * scaleFactor, y, z);
+ gl.glTexCoord2f(coords.right(), coords.top());
+ gl.glVertex3f(x + width * scaleFactor, y + height * scaleFactor, z);
+ gl.glTexCoord2f(coords.left(), coords.top());
+ gl.glVertex3f(x, y + height * scaleFactor, z);
+ gl.glEnd();
+ }
+
+ /** Convenience method which assists in rendering portions of the
+ OpenGL texture to the screen, if the application intends to draw
+ them as a flat overlay on to the screen. Must be used if {@link
+ #beginOrthoRendering} is used to set up the rendering stage for
+ this overlay.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void endOrthoRendering() throws GLException {
+ endRendering(true);
+ }
+
+ /** Convenience method which assists in rendering portions of the
+ OpenGL texture to the screen as 2D quads in 3D space. Must be
+ used if {@link #begin3DRendering} is used to set up the
+ rendering stage for this overlay.
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ public void end3DRendering() throws GLException {
+ endRendering(false);
+ }
+
+ /** Indicates whether automatic mipmap generation is in use for this
+ TextureRenderer. The result of this method may change from true
+ to false if it is discovered during allocation of the
+ TextureRenderer's backing store that automatic mipmap generation
+ is not supported at the OpenGL level. */
+ public boolean isUsingAutoMipmapGeneration() {
+ return mipmap;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private void beginRendering(boolean ortho, int width, int height, boolean disableDepthTestForOrtho) {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+ int attribBits =
+ GL2.GL_ENABLE_BIT | GL2.GL_TEXTURE_BIT | GL2.GL_COLOR_BUFFER_BIT |
+ (ortho ? (GL2.GL_DEPTH_BUFFER_BIT | GL2.GL_TRANSFORM_BIT) : 0);
+ gl.glPushAttrib(attribBits);
+ gl.glDisable(GL2.GL_LIGHTING);
+ if (ortho) {
+ if (disableDepthTestForOrtho) {
+ gl.glDisable(GL2.GL_DEPTH_TEST);
+ }
+ gl.glDisable(GL2.GL_CULL_FACE);
+ gl.glMatrixMode(GL2.GL_PROJECTION);
+ gl.glPushMatrix();
+ gl.glLoadIdentity();
+ glu.gluOrtho2D(0, width, 0, height);
+ gl.glMatrixMode(GL2.GL_MODELVIEW);
+ gl.glPushMatrix();
+ gl.glLoadIdentity();
+ gl.glMatrixMode(GL2.GL_TEXTURE);
+ gl.glPushMatrix();
+ gl.glLoadIdentity();
+ }
+ gl.glEnable(GL2.GL_BLEND);
+ gl.glBlendFunc(GL2.GL_ONE, GL2.GL_ONE_MINUS_SRC_ALPHA);
+ Texture texture = getTexture();
+ texture.enable();
+ texture.bind();
+ gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE);
+ // Change polygon color to last saved
+ gl.glColor4f(r, g, b, a);
+ if (smoothingChanged) {
+ smoothingChanged = false;
+ if (smoothing) {
+ texture.setTexParameteri(GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
+ if (mipmap) {
+ texture.setTexParameteri(GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR_MIPMAP_LINEAR);
+ } else {
+ texture.setTexParameteri(GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
+ }
+ } else {
+ texture.setTexParameteri(GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
+ texture.setTexParameteri(GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
+ }
+ }
+ }
+
+ private void endRendering(boolean ortho) {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+ Texture texture = getTexture();
+ texture.disable();
+ if (ortho) {
+ gl.glMatrixMode(GL2.GL_PROJECTION);
+ gl.glPopMatrix();
+ gl.glMatrixMode(GL2.GL_MODELVIEW);
+ gl.glPopMatrix();
+ gl.glMatrixMode(GL2.GL_TEXTURE);
+ gl.glPopMatrix();
+ }
+ gl.glPopAttrib();
+ }
+
+ private void init(int width, int height) {
+ GL2 gl = GLContext.getCurrentGL().getGL2();
+ // Discard previous BufferedImage if any
+ if (image != null) {
+ image.flush();
+ image = null;
+ }
+
+ // Infer the internal format if not an intensity texture
+ int internalFormat = (intensity ? GL2.GL_INTENSITY : 0);
+ int imageType =
+ (intensity ? BufferedImage.TYPE_BYTE_GRAY :
+ (alpha ? BufferedImage.TYPE_INT_ARGB_PRE : BufferedImage.TYPE_INT_RGB));
+ image = new BufferedImage(width, height, imageType);
+ // Always realllocate the TextureData associated with this
+ // BufferedImage; it's just a reference to the contents but we
+ // need it in order to update sub-regions of the underlying
+ // texture
+ textureData = new AWTTextureData(gl.getGLProfile(), internalFormat, 0, mipmap, image);
+ // For now, always reallocate the underlying OpenGL texture when
+ // the backing store size changes
+ mustReallocateTexture = true;
+ }
+
+ /** Synchronizes the specified region of the backing store down to
+ the underlying OpenGL texture. If {@link #markDirty markDirty}
+ is used instead to indicate the regions that are out of sync,
+ this method does not need to be called.
+
+ @param x the x coordinate (in Java 2D coordinates -- relative to
+ upper left) of the region to update
+ @param y the y coordinate (in Java 2D coordinates -- relative to
+ upper left) of the region to update
+ @param width the width of the region to update
+ @param height the height of the region to update
+
+ @throws GLException If an OpenGL context is not current when this method is called
+ */
+ private void sync(int x, int y, int width, int height) throws GLException {
+ // Force allocation if necessary
+ boolean canSkipUpdate = ensureTexture();
+
+ if (!canSkipUpdate) {
+ // Update specified region.
+ // NOTE that because BufferedImage-based TextureDatas now don't
+ // do anything to their contents, the coordinate systems for
+ // OpenGL and Java 2D actually line up correctly for
+ // updateSubImage calls, so we don't need to do any argument
+ // conversion here (i.e., flipping the Y coordinate).
+ texture.updateSubImage(textureData, 0, x, y, x, y, width, height);
+ }
+ }
+
+ // Returns true if the texture was newly allocated, false if not
+ private boolean ensureTexture() {
+ if (mustReallocateTexture) {
+ if (texture != null) {
+ texture.dispose();
+ texture = null;
+ }
+ mustReallocateTexture = false;
+ }
+
+ if (texture == null) {
+ texture = TextureIO.newTexture(textureData);
+ if (mipmap && !texture.isUsingAutoMipmapGeneration()) {
+ // Only try this once
+ texture.dispose();
+ mipmap = false;
+ textureData.setMipmap(false);
+ texture = TextureIO.newTexture(textureData);
+ }
+
+ if (!smoothing) {
+ // The TextureIO classes default to GL_LINEAR filtering
+ texture.setTexParameteri(GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
+ texture.setTexParameteri(GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
+ }
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/BitmapCharRec.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/BitmapCharRec.java
new file mode 100644
index 000000000..34685e1b2
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/BitmapCharRec.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1998. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+class BitmapCharRec {
+ public int width;
+ public int height;
+ public float xorig;
+ public float yorig;
+ public float advance;
+ public byte[] bitmap;
+
+ public BitmapCharRec(int width,
+ int height,
+ float xorig,
+ float yorig,
+ float advance,
+ byte[] bitmap) {
+ this.width = width;
+ this.height = height;
+ this.xorig = xorig;
+ this.yorig = yorig;
+ this.advance = advance;
+ this.bitmap = bitmap;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/BitmapFontRec.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/BitmapFontRec.java
new file mode 100644
index 000000000..18f7d3b28
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/BitmapFontRec.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1998. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+class BitmapFontRec {
+ public String name;
+ public int num_chars;
+ public int first;
+ public BitmapCharRec[] ch;
+
+ public BitmapFontRec(String name,
+ int num_chars,
+ int first,
+ BitmapCharRec[] ch) {
+ this.name = name;
+ this.num_chars = num_chars;
+ this.first = first;
+ this.ch = ch;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/CoordRec.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/CoordRec.java
new file mode 100644
index 000000000..9ad95ec03
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/CoordRec.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1998. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+class CoordRec {
+ public float x;
+ public float y;
+
+ public CoordRec(float x, float y) {
+ this.x = x;
+ this.y = y;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUT.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUT.java
new file mode 100644
index 000000000..8befc13ba
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUT.java
@@ -0,0 +1,1342 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import javax.media.opengl.glu.gl2.*;
+
+/** Subset of the routines provided by the GLUT interface. Note the
+ signatures of many of the methods are necessarily different than
+ the corresponding C version. A GLUT object must only be used from
+ one particular thread at a time. <P>
+
+ Copyright (c) Mark J. Kilgard, 1994, 1997. <P>
+
+ (c) Copyright 1993, Silicon Graphics, Inc. <P>
+
+ ALL RIGHTS RESERVED <P>
+
+ Permission to use, copy, modify, and distribute this software
+ for any purpose and without fee is hereby granted, provided
+ that the above copyright notice appear in all copies and that
+ both the copyright notice and this permission notice appear in
+ supporting documentation, and that the name of Silicon
+ Graphics, Inc. not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. <P>
+
+ THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
+ "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
+ OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
+ EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
+ ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
+ CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
+ INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
+ SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
+ NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
+ OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
+ PERFORMANCE OF THIS SOFTWARE. <P>
+
+ US Government Users Restricted Rights <P>
+
+ Use, duplication, or disclosure by the Government is subject to
+ restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ (c)(1)(ii) of the Rights in Technical Data and Computer
+ Software clause at DFARS 252.227-7013 and/or in similar or
+ successor clauses in the FAR or the DOD or NASA FAR
+ Supplement. Unpublished-- rights reserved under the copyright
+ laws of the United States. Contractor/manufacturer is Silicon
+ Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
+ 94039-7311. <P>
+
+ OpenGL(TM) is a trademark of Silicon Graphics, Inc. <P>
+*/
+
+public class GLUT {
+ public static final int STROKE_ROMAN = 0;
+ public static final int STROKE_MONO_ROMAN = 1;
+ public static final int BITMAP_9_BY_15 = 2;
+ public static final int BITMAP_8_BY_13 = 3;
+ public static final int BITMAP_TIMES_ROMAN_10 = 4;
+ public static final int BITMAP_TIMES_ROMAN_24 = 5;
+ public static final int BITMAP_HELVETICA_10 = 6;
+ public static final int BITMAP_HELVETICA_12 = 7;
+ public static final int BITMAP_HELVETICA_18 = 8;
+
+ private GLUgl2 glu = new GLUgl2();
+
+ //----------------------------------------------------------------------
+ // Shapes
+ //
+
+ public void glutWireSphere(double radius, int slices, int stacks) {
+ quadObjInit(glu);
+ glu.gluQuadricDrawStyle(quadObj, GLU.GLU_LINE);
+ glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
+ /* If we ever changed/used the texture or orientation state
+ of quadObj, we'd need to change it to the defaults here
+ with gluQuadricTexture and/or gluQuadricOrientation. */
+ glu.gluSphere(quadObj, radius, slices, stacks);
+ }
+
+ public void glutSolidSphere(double radius, int slices, int stacks) {
+ quadObjInit(glu);
+ glu.gluQuadricDrawStyle(quadObj, GLU.GLU_FILL);
+ glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
+ /* If we ever changed/used the texture or orientation state
+ of quadObj, we'd need to change it to the defaults here
+ with gluQuadricTexture and/or gluQuadricOrientation. */
+ glu.gluSphere(quadObj, radius, slices, stacks);
+ }
+
+ public void glutWireCone(double base, double height,
+ int slices, int stacks) {
+ quadObjInit(glu);
+ glu.gluQuadricDrawStyle(quadObj, GLU.GLU_LINE);
+ glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
+ /* If we ever changed/used the texture or orientation state
+ of quadObj, we'd need to change it to the defaults here
+ with gluQuadricTexture and/or gluQuadricOrientation. */
+ glu.gluCylinder(quadObj, base, 0.0, height, slices, stacks);
+ }
+
+ public void glutSolidCone(double base, double height,
+ int slices, int stacks) {
+ quadObjInit(glu);
+ glu.gluQuadricDrawStyle(quadObj, GLU.GLU_FILL);
+ glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
+ /* If we ever changed/used the texture or orientation state
+ of quadObj, we'd need to change it to the defaults here
+ with gluQuadricTexture and/or gluQuadricOrientation. */
+ glu.gluCylinder(quadObj, base, 0.0, height, slices, stacks);
+ }
+
+ public void glutWireCylinder(double radius, double height, int slices, int stacks) {
+ quadObjInit(glu);
+ glu.gluQuadricDrawStyle(quadObj, GLU.GLU_LINE);
+ glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
+ /* If we ever changed/used the texture or orientation state
+ of quadObj, we'd need to change it to the defaults here
+ with gluQuadricTexture and/or gluQuadricOrientation. */
+ glu.gluCylinder(quadObj, radius, radius, height, slices, stacks);
+ }
+
+ public void glutSolidCylinder(double radius, double height, int slices, int stacks) {
+ GL2 gl = GLUgl2.getCurrentGL2();
+
+ // Prepare table of points for drawing end caps
+ double [] x = new double[slices];
+ double [] y = new double[slices];
+ double angleDelta = Math.PI * 2 / slices;
+ double angle = 0;
+ for (int i = 0 ; i < slices ; i ++) {
+ angle = i * angleDelta;
+ x[i] = Math.cos(angle) * radius;
+ y[i] = Math.sin(angle) * radius;
+ }
+
+ // Draw bottom cap
+ gl.glBegin(GL2.GL_TRIANGLE_FAN);
+ gl.glNormal3d(0,0,-1);
+ gl.glVertex3d(0,0,0);
+ for (int i = 0 ; i < slices ; i ++) {
+ gl.glVertex3d(x[i], y[i], 0);
+ }
+ gl.glVertex3d(x[0], y[0], 0);
+ gl.glEnd();
+
+ // Draw top cap
+ gl.glBegin(GL2.GL_TRIANGLE_FAN);
+ gl.glNormal3d(0,0,1);
+ gl.glVertex3d(0,0,height);
+ for (int i = 0 ; i < slices ; i ++) {
+ gl.glVertex3d(x[i], y[i], height);
+ }
+ gl.glVertex3d(x[0], y[0], height);
+ gl.glEnd();
+
+ // Draw walls
+ quadObjInit(glu);
+ glu.gluQuadricDrawStyle(quadObj, GLU.GLU_FILL);
+ glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
+ /* If we ever changed/used the texture or orientation state
+ of quadObj, we'd need to change it to the defaults here
+ with gluQuadricTexture and/or gluQuadricOrientation. */
+ glu.gluCylinder(quadObj, radius, radius, height, slices, stacks);
+ }
+
+ public void glutWireCube(float size) {
+ drawBox(GLUgl2.getCurrentGL2(), size, GL2.GL_LINE_LOOP);
+ }
+
+ public void glutSolidCube(float size) {
+ drawBox(GLUgl2.getCurrentGL2(), size, GL2.GL_QUADS);
+ }
+
+ public void glutWireTorus(double innerRadius, double outerRadius,
+ int nsides, int rings) {
+ GL2 gl = GLUgl2.getCurrentGL2();
+ gl.glPushAttrib(GL2.GL_POLYGON_BIT);
+ gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
+ doughnut(gl, innerRadius, outerRadius, nsides, rings);
+ gl.glPopAttrib();
+ }
+
+ public void glutSolidTorus(double innerRadius, double outerRadius,
+ int nsides, int rings) {
+ doughnut(GLUgl2.getCurrentGL2(), innerRadius, outerRadius, nsides, rings);
+ }
+
+ public void glutWireDodecahedron() {
+ dodecahedron(GLUgl2.getCurrentGL2(), GL2.GL_LINE_LOOP);
+ }
+
+ public void glutSolidDodecahedron() {
+ dodecahedron(GLUgl2.getCurrentGL2(), GL2.GL_TRIANGLE_FAN);
+ }
+
+ public void glutWireOctahedron() {
+ octahedron(GLUgl2.getCurrentGL2(), GL2.GL_LINE_LOOP);
+ }
+
+ public void glutSolidOctahedron() {
+ octahedron(GLUgl2.getCurrentGL2(), GL2.GL_TRIANGLES);
+ }
+
+ public void glutWireIcosahedron() {
+ icosahedron(GLUgl2.getCurrentGL2(), GL2.GL_LINE_LOOP);
+ }
+
+ public void glutSolidIcosahedron() {
+ icosahedron(GLUgl2.getCurrentGL2(), GL2.GL_TRIANGLES);
+ }
+
+ public void glutWireTetrahedron() {
+ tetrahedron(GLUgl2.getCurrentGL2(), GL2.GL_LINE_LOOP);
+ }
+
+ public void glutSolidTetrahedron() {
+ tetrahedron(GLUgl2.getCurrentGL2(), GL2.GL_TRIANGLES);
+ }
+
+/**
+ * Renders the teapot as a solid shape of the specified size. The teapot is
+ * created in a way that replicates the C GLUT implementation.
+ *
+ * @param scale
+ * the factor by which to scale the teapot
+ */
+ public void glutSolidTeapot(double scale) {
+ glutSolidTeapot(scale, true);
+ }
+
+ /**
+ * Renders the teapot as a solid shape of the specified size. The teapot can
+ * either be created in a way that is backward-compatible with the standard
+ * C glut library (i.e. broken), or in a more pleasing way (i.e. with
+ * surfaces whose front-faces point outwards and standing on the z=0 plane,
+ * instead of the y=-1 plane). Both surface normals and texture coordinates
+ * for the teapot are generated. The teapot is generated with OpenGL
+ * evaluators.
+ *
+ * @param scale
+ * the factor by which to scale the teapot
+ * @param cStyle
+ * whether to create the teapot in exactly the same way as in the C
+ * implementation of GLUT
+ */
+ public void glutSolidTeapot(double scale, boolean cStyle) {
+ teapot(GLUgl2.getCurrentGL2(), 14, scale, GL2.GL_FILL, cStyle);
+ }
+
+ /**
+ * Renders the teapot as a wireframe shape of the specified size. The teapot
+ * is created in a way that replicates the C GLUT implementation.
+ *
+ * @param scale
+ * the factor by which to scale the teapot
+ */
+ public void glutWireTeapot(double scale) {
+ glutWireTeapot(scale, true);
+ }
+
+ /**
+ * Renders the teapot as a wireframe shape of the specified size. The teapot
+ * can either be created in a way that is backward-compatible with the
+ * standard C glut library (i.e. broken), or in a more pleasing way (i.e.
+ * with surfaces whose front-faces point outwards and standing on the z=0
+ * plane, instead of the y=-1 plane). Both surface normals and texture
+ * coordinates for the teapot are generated. The teapot is generated with
+ * OpenGL evaluators.
+ *
+ * @param scale
+ * the factor by which to scale the teapot
+ * @param cStyle
+ * whether to create the teapot in exactly the same way as in the C
+ * implementation of GLUT
+ */
+ public void glutWireTeapot(double scale, boolean cStyle) {
+ teapot(GLUgl2.getCurrentGL2(), 10, scale, GL2.GL_LINE, cStyle);
+ }
+
+ //----------------------------------------------------------------------
+ // Fonts
+ //
+
+ public void glutBitmapCharacter(int font, char character) {
+ GL2 gl = GLUgl2.getCurrentGL2();
+ int[] swapbytes = new int[1];
+ int[] lsbfirst = new int[1];
+ int[] rowlength = new int[1];
+ int[] skiprows = new int[1];
+ int[] skippixels = new int[1];
+ int[] alignment = new int[1];
+ beginBitmap(gl,
+ swapbytes,
+ lsbfirst,
+ rowlength,
+ skiprows,
+ skippixels,
+ alignment);
+ bitmapCharacterImpl(gl, font, character);
+ endBitmap(gl,
+ swapbytes,
+ lsbfirst,
+ rowlength,
+ skiprows,
+ skippixels,
+ alignment);
+ }
+
+ public void glutBitmapString (int font, String string) {
+ GL2 gl = GLUgl2.getCurrentGL2();
+ int[] swapbytes = new int[1];
+ int[] lsbfirst = new int[1];
+ int[] rowlength = new int[1];
+ int[] skiprows = new int[1];
+ int[] skippixels = new int[1];
+ int[] alignment = new int[1];
+ beginBitmap(gl,
+ swapbytes,
+ lsbfirst,
+ rowlength,
+ skiprows,
+ skippixels,
+ alignment);
+ int len = string.length();
+ for (int i = 0; i < len; i++) {
+ bitmapCharacterImpl(gl, font, string.charAt(i));
+ }
+ endBitmap(gl,
+ swapbytes,
+ lsbfirst,
+ rowlength,
+ skiprows,
+ skippixels,
+ alignment);
+ }
+
+ public int glutBitmapWidth (int font, char character) {
+ BitmapFontRec fontinfo = getBitmapFont(font);
+ int c = character & 0xFFFF;
+ if (c < fontinfo.first || c >= fontinfo.first + fontinfo.num_chars)
+ return 0;
+ BitmapCharRec ch = fontinfo.ch[c - fontinfo.first];
+ if (ch != null)
+ return (int) ch.advance;
+ else
+ return 0;
+ }
+
+ public void glutStrokeCharacter(int font, char character) {
+ GL2 gl = GLUgl2.getCurrentGL2();
+ StrokeFontRec fontinfo = getStrokeFont(font);
+ int c = character & 0xFFFF;
+ if (c < 0 || c >= fontinfo.num_chars)
+ return;
+ StrokeCharRec ch = fontinfo.ch[c];
+ if (ch != null) {
+ for (int i = 0; i < ch.num_strokes; i++) {
+ StrokeRec stroke = ch.stroke[i];
+ gl.glBegin(GL2.GL_LINE_STRIP);
+ for (int j = 0; j < stroke.num_coords; j++) {
+ CoordRec coord = stroke.coord[j];
+ gl.glVertex2f(coord.x, coord.y);
+ }
+ gl.glEnd();
+ }
+ gl.glTranslatef(ch.right, 0.0f, 0.0f);
+ }
+ }
+
+ public void glutStrokeString(int font, String string) {
+ GL2 gl = GLUgl2.getCurrentGL2();
+ StrokeFontRec fontinfo = getStrokeFont(font);
+ int len = string.length();
+ for (int pos = 0; pos < len; pos++) {
+ int c = string.charAt(pos) & 0xFFFF;
+ if (c < 0 || c >= fontinfo.num_chars)
+ continue;
+ StrokeCharRec ch = fontinfo.ch[c];
+ if (ch != null) {
+ for (int i = 0; i < ch.num_strokes; i++) {
+ StrokeRec stroke = ch.stroke[i];
+ gl.glBegin(GL2.GL_LINE_STRIP);
+ for (int j = 0; j < stroke.num_coords; j++) {
+ CoordRec coord = stroke.coord[j];
+ gl.glVertex2f(coord.x, coord.y);
+ }
+ gl.glEnd();
+ }
+ gl.glTranslatef(ch.right, 0.0f, 0.0f);
+ }
+ }
+ }
+
+ public int glutStrokeWidth (int font, char character) {
+ return (int) glutStrokeWidthf(font, character);
+ }
+
+ public float glutStrokeWidthf (int font, char character) {
+ StrokeFontRec fontinfo = getStrokeFont(font);
+ int c = character & 0xFFFF;
+ if (c < 0 || c >= fontinfo.num_chars)
+ return 0;
+ StrokeCharRec ch = fontinfo.ch[c];
+ if (ch != null)
+ return ch.right;
+ else
+ return 0;
+ }
+
+ public int glutBitmapLength (int font, String string) {
+ BitmapFontRec fontinfo = getBitmapFont(font);
+ int length = 0;
+ int len = string.length();
+ for (int pos = 0; pos < len; pos++) {
+ int c = string.charAt(pos) & 0xFFFF;
+ if (c >= fontinfo.first && c < fontinfo.first + fontinfo.num_chars) {
+ BitmapCharRec ch = fontinfo.ch[c - fontinfo.first];
+ if (ch != null)
+ length += ch.advance;
+ }
+ }
+ return length;
+ }
+
+ public int glutStrokeLength (int font, String string) {
+ return (int) glutStrokeLengthf(font, string);
+ }
+
+ public float glutStrokeLengthf (int font, String string) {
+ StrokeFontRec fontinfo = getStrokeFont(font);
+ float length = 0;
+ int len = string.length();
+ for (int i = 0; i < len; i++) {
+ char c = string.charAt(i);
+ if (c >= 0 && c < fontinfo.num_chars) {
+ StrokeCharRec ch = fontinfo.ch[c];
+ if (ch != null)
+ length += ch.right;
+ }
+ }
+ return length;
+ }
+
+ /**
+ This function draws a wireframe dodecahedron whose
+ facets are rhombic and
+ whose vertices are at unit radius.
+ No facet lies normal to any coordinate axes.
+ The polyhedron is centered at the origin.
+ */
+ public void glutWireRhombicDodecahedron() {
+ GL2 gl = GLUgl2.getCurrentGL2();
+ for( int i = 0; i < 12; i++ ) {
+ gl.glBegin( GL2.GL_LINE_LOOP );
+ gl.glNormal3dv( rdod_n[ i ],0 );
+ gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 0 ] ],0 );
+ gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 1 ] ],0 );
+ gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 2 ] ],0 );
+ gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 3 ] ],0 );
+ gl.glEnd( );
+ }
+ }
+
+ /**
+ This function draws a solid-shaded dodecahedron
+ whose facets are rhombic and
+ whose vertices are at unit radius.
+ No facet lies normal to any coordinate axes.
+ The polyhedron is centered at the origin.
+ */
+ public void glutSolidRhombicDodecahedron() {
+ GL2 gl = GLUgl2.getCurrentGL2();
+ gl.glBegin( GL2.GL_QUADS );
+ for( int i = 0; i < 12; i++ ) {
+ gl.glNormal3dv( rdod_n[ i ],0 );
+ gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 0 ] ],0 );
+ gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 1 ] ],0 );
+ gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 2 ] ],0 );
+ gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 3 ] ],0 );
+ }
+ gl.glEnd( );
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ //----------------------------------------------------------------------
+ // Shape implementation
+ //
+
+ private GLUquadric quadObj;
+ private void quadObjInit(GLUgl2 glu) {
+ if (quadObj == null) {
+ quadObj = glu.gluNewQuadric();
+ }
+ if (quadObj == null) {
+ throw new GLException("Out of memory");
+ }
+ }
+
+ private static void doughnut(GL2 gl, double r, double R, int nsides, int rings) {
+ int i, j;
+ float theta, phi, theta1;
+ float cosTheta, sinTheta;
+ float cosTheta1, sinTheta1;
+ float ringDelta, sideDelta;
+
+ ringDelta = (float) (2.0 * Math.PI / rings);
+ sideDelta = (float) (2.0 * Math.PI / nsides);
+
+ theta = 0.0f;
+ cosTheta = 1.0f;
+ sinTheta = 0.0f;
+ for (i = rings - 1; i >= 0; i--) {
+ theta1 = theta + ringDelta;
+ cosTheta1 = (float) Math.cos(theta1);
+ sinTheta1 = (float) Math.sin(theta1);
+ gl.glBegin(GL2.GL_QUAD_STRIP);
+ phi = 0.0f;
+ for (j = nsides; j >= 0; j--) {
+ float cosPhi, sinPhi, dist;
+
+ phi += sideDelta;
+ cosPhi = (float) Math.cos(phi);
+ sinPhi = (float) Math.sin(phi);
+ dist = (float) (R + r * cosPhi);
+
+ gl.glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
+ gl.glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, (float) r * sinPhi);
+ gl.glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
+ gl.glVertex3f(cosTheta * dist, -sinTheta * dist, (float) r * sinPhi);
+ }
+ gl.glEnd();
+ theta = theta1;
+ cosTheta = cosTheta1;
+ sinTheta = sinTheta1;
+ }
+ }
+
+ private static float[][] boxVertices;
+ private static final float[][] boxNormals = {
+ {-1.0f, 0.0f, 0.0f},
+ {0.0f, 1.0f, 0.0f},
+ {1.0f, 0.0f, 0.0f},
+ {0.0f, -1.0f, 0.0f},
+ {0.0f, 0.0f, 1.0f},
+ {0.0f, 0.0f, -1.0f}
+ };
+ private static final int[][] boxFaces = {
+ {0, 1, 2, 3},
+ {3, 2, 6, 7},
+ {7, 6, 5, 4},
+ {4, 5, 1, 0},
+ {5, 6, 2, 1},
+ {7, 4, 0, 3}
+ };
+ private void drawBox(GL2 gl, float size, int type) {
+ if (boxVertices == null) {
+ float[][] v = new float[8][];
+ for (int i = 0; i < 8; i++) {
+ v[i] = new float[3];
+ }
+ v[0][0] = v[1][0] = v[2][0] = v[3][0] = -0.5f;
+ v[4][0] = v[5][0] = v[6][0] = v[7][0] = 0.5f;
+ v[0][1] = v[1][1] = v[4][1] = v[5][1] = -0.5f;
+ v[2][1] = v[3][1] = v[6][1] = v[7][1] = 0.5f;
+ v[0][2] = v[3][2] = v[4][2] = v[7][2] = -0.5f;
+ v[1][2] = v[2][2] = v[5][2] = v[6][2] = 0.5f;
+ boxVertices = v;
+ }
+ float[][] v = boxVertices;
+ float[][] n = boxNormals;
+ int[][] faces = boxFaces;
+ for (int i = 5; i >= 0; i--) {
+ gl.glBegin(type);
+ gl.glNormal3fv(n[i], 0);
+ float[] vt = v[faces[i][0]];
+ gl.glVertex3f(vt[0] * size, vt[1] * size, vt[2] * size);
+ vt = v[faces[i][1]];
+ gl.glVertex3f(vt[0] * size, vt[1] * size, vt[2] * size);
+ vt = v[faces[i][2]];
+ gl.glVertex3f(vt[0] * size, vt[1] * size, vt[2] * size);
+ vt = v[faces[i][3]];
+ gl.glVertex3f(vt[0] * size, vt[1] * size, vt[2] * size);
+ gl.glEnd();
+ }
+ }
+
+ private float[][] dodec;
+
+ private void initDodecahedron() {
+ dodec = new float[20][];
+ for (int i = 0; i < dodec.length; i++) {
+ dodec[i] = new float[3];
+ }
+
+ float alpha, beta;
+
+ alpha = (float) Math.sqrt(2.0f / (3.0f + Math.sqrt(5.0)));
+ beta = 1.0f + (float) Math.sqrt(6.0 / (3.0 + Math.sqrt(5.0)) -
+ 2.0 + 2.0 * Math.sqrt(2.0 / (3.0 + Math.sqrt(5.0))));
+ dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
+ dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
+ dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
+ dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
+ dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
+ dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
+ dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
+ dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
+ dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
+ dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
+ dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
+ dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
+ dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
+ dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
+ dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
+ dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
+ dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
+ dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
+ dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
+ dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
+ }
+
+ private static void diff3(float[] a, float[] b, float[] c) {
+ c[0] = a[0] - b[0];
+ c[1] = a[1] - b[1];
+ c[2] = a[2] - b[2];
+ }
+
+ private static void crossprod(float[] v1, float[] v2, float[] prod) {
+ float[] p = new float[3]; /* in case prod == v1 or v2 */
+
+ p[0] = v1[1] * v2[2] - v2[1] * v1[2];
+ p[1] = v1[2] * v2[0] - v2[2] * v1[0];
+ p[2] = v1[0] * v2[1] - v2[0] * v1[1];
+ prod[0] = p[0];
+ prod[1] = p[1];
+ prod[2] = p[2];
+ }
+
+ private static void normalize(float[] v) {
+ float d;
+
+ d = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+ if (d == 0.0) {
+ v[0] = d = 1.0f;
+ }
+ d = 1 / d;
+ v[0] *= d;
+ v[1] *= d;
+ v[2] *= d;
+ }
+
+ private void pentagon(GL2 gl, int a, int b, int c, int d, int e, int shadeType) {
+ float[] n0 = new float[3];
+ float[] d1 = new float[3];
+ float[] d2 = new float[3];
+
+ diff3(dodec[a], dodec[b], d1);
+ diff3(dodec[b], dodec[c], d2);
+ crossprod(d1, d2, n0);
+ normalize(n0);
+
+ gl.glBegin(shadeType);
+ gl.glNormal3fv(n0, 0);
+ gl.glVertex3fv(dodec[a], 0);
+ gl.glVertex3fv(dodec[b], 0);
+ gl.glVertex3fv(dodec[c], 0);
+ gl.glVertex3fv(dodec[d], 0);
+ gl.glVertex3fv(dodec[e], 0);
+ gl.glEnd();
+ }
+
+ private void dodecahedron(GL2 gl, int type) {
+ if (dodec == null) {
+ initDodecahedron();
+ }
+ pentagon(gl, 0, 1, 9, 16, 5, type);
+ pentagon(gl, 1, 0, 3, 18, 7, type);
+ pentagon(gl, 1, 7, 11, 10, 9, type);
+ pentagon(gl, 11, 7, 18, 19, 6, type);
+ pentagon(gl, 8, 17, 16, 9, 10, type);
+ pentagon(gl, 2, 14, 15, 6, 19, type);
+ pentagon(gl, 2, 13, 12, 4, 14, type);
+ pentagon(gl, 2, 19, 18, 3, 13, type);
+ pentagon(gl, 3, 0, 5, 12, 13, type);
+ pentagon(gl, 6, 15, 8, 10, 11, type);
+ pentagon(gl, 4, 17, 8, 15, 14, type);
+ pentagon(gl, 4, 12, 5, 16, 17, type);
+ }
+
+ private static void recorditem(GL2 gl, float[] n1, float[] n2, float[] n3, int shadeType) {
+ float[] q0 = new float[3];
+ float[] q1 = new float[3];
+
+ diff3(n1, n2, q0);
+ diff3(n2, n3, q1);
+ crossprod(q0, q1, q1);
+ normalize(q1);
+
+ gl.glBegin(shadeType);
+ gl.glNormal3fv(q1, 0);
+ gl.glVertex3fv(n1, 0);
+ gl.glVertex3fv(n2, 0);
+ gl.glVertex3fv(n3, 0);
+ gl.glEnd();
+ }
+
+ private static void subdivide(GL2 gl, float[] v0, float[] v1, float[] v2, int shadeType) {
+ int depth;
+ float[] w0 = new float[3];
+ float[] w1 = new float[3];
+ float[] w2 = new float[3];
+ float l;
+ int i, j, k, n;
+
+ depth = 1;
+ for (i = 0; i < depth; i++) {
+ for (j = 0; i + j < depth; j++) {
+ k = depth - i - j;
+ for (n = 0; n < 3; n++) {
+ w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
+ w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
+ / depth;
+ w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
+ / depth;
+ }
+ l = (float) Math.sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
+ w0[0] /= l;
+ w0[1] /= l;
+ w0[2] /= l;
+ l = (float) Math.sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
+ w1[0] /= l;
+ w1[1] /= l;
+ w1[2] /= l;
+ l = (float) Math.sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
+ w2[0] /= l;
+ w2[1] /= l;
+ w2[2] /= l;
+ recorditem(gl, w1, w0, w2, shadeType);
+ }
+ }
+ }
+
+ private static void drawtriangle(GL2 gl, int i, float[][] data, int[][] ndx, int shadeType) {
+ float[] x0 = data[ndx[i][0]];
+ float[] x1 = data[ndx[i][1]];
+ float[] x2 = data[ndx[i][2]];
+ subdivide(gl, x0, x1, x2, shadeType);
+ }
+
+ /* octahedron data: The octahedron produced is centered at the
+ origin and has radius 1.0 */
+ private static final float[][] odata =
+ {
+ {1.0f, 0.0f, 0.0f},
+ {-1.0f, 0.0f, 0.0f},
+ {0.0f, 1.0f, 0.0f},
+ {0.0f, -1.0f, 0.0f},
+ {0.0f, 0.0f, 1.0f},
+ {0.0f, 0.0f, -1.0f}
+ };
+
+ private static final int[][] ondex =
+ {
+ {0, 4, 2},
+ {1, 2, 4},
+ {0, 3, 4},
+ {1, 4, 3},
+ {0, 2, 5},
+ {1, 5, 2},
+ {0, 5, 3},
+ {1, 3, 5}
+ };
+
+ private static void octahedron(GL2 gl, int shadeType) {
+ int i;
+
+ for (i = 7; i >= 0; i--) {
+ drawtriangle(gl, i, odata, ondex, shadeType);
+ }
+ }
+
+ /* icosahedron data: These numbers are rigged to make an
+ icosahedron of radius 1.0 */
+
+ private static final float X = .525731112119133606f;
+ private static final float Z = .850650808352039932f;
+
+ private static final float[][] idata =
+ {
+ {-X, 0, Z},
+ {X, 0, Z},
+ {-X, 0, -Z},
+ {X, 0, -Z},
+ {0, Z, X},
+ {0, Z, -X},
+ {0, -Z, X},
+ {0, -Z, -X},
+ {Z, X, 0},
+ {-Z, X, 0},
+ {Z, -X, 0},
+ {-Z, -X, 0}
+ };
+
+ private static final int[][] index =
+ {
+ {0, 4, 1},
+ {0, 9, 4},
+ {9, 5, 4},
+ {4, 5, 8},
+ {4, 8, 1},
+ {8, 10, 1},
+ {8, 3, 10},
+ {5, 3, 8},
+ {5, 2, 3},
+ {2, 7, 3},
+ {7, 10, 3},
+ {7, 6, 10},
+ {7, 11, 6},
+ {11, 0, 6},
+ {0, 1, 6},
+ {6, 1, 10},
+ {9, 0, 11},
+ {9, 11, 2},
+ {9, 2, 5},
+ {7, 2, 11},
+ };
+
+ private static void icosahedron(GL2 gl, int shadeType) {
+ int i;
+
+ for (i = 19; i >= 0; i--) {
+ drawtriangle(gl, i, idata, index, shadeType);
+ }
+ }
+
+ /* rhombic dodecahedron data: */
+
+ private static final double rdod_r[][] =
+ {
+ { 0.0, 0.0, 1.0 },
+ { 0.707106781187, 0.000000000000, 0.5 },
+ { 0.000000000000, 0.707106781187, 0.5 },
+ { -0.707106781187, 0.000000000000, 0.5 },
+ { 0.000000000000, -0.707106781187, 0.5 },
+ { 0.707106781187, 0.707106781187, 0.0 },
+ { -0.707106781187, 0.707106781187, 0.0 },
+ { -0.707106781187, -0.707106781187, 0.0 },
+ { 0.707106781187, -0.707106781187, 0.0 },
+ { 0.707106781187, 0.000000000000, -0.5 },
+ { 0.000000000000, 0.707106781187, -0.5 },
+ { -0.707106781187, 0.000000000000, -0.5 },
+ { 0.000000000000, -0.707106781187, -0.5 },
+ { 0.0, 0.0, -1.0 }
+ };
+
+ private static final int rdod_v[][] =
+ {
+ { 0, 1, 5, 2 },
+ { 0, 2, 6, 3 },
+ { 0, 3, 7, 4 },
+ { 0, 4, 8, 1 },
+ { 5, 10, 6, 2 },
+ { 6, 11, 7, 3 },
+ { 7, 12, 8, 4 },
+ { 8, 9, 5, 1 },
+ { 5, 9, 13, 10 },
+ { 6, 10, 13, 11 },
+ { 7, 11, 13, 12 },
+ { 8, 12, 13, 9 }
+ };
+
+ private static final double rdod_n[][] =
+ {
+ { 0.353553390594, 0.353553390594, 0.5 },
+ { -0.353553390594, 0.353553390594, 0.5 },
+ { -0.353553390594, -0.353553390594, 0.5 },
+ { 0.353553390594, -0.353553390594, 0.5 },
+ { 0.000000000000, 1.000000000000, 0.0 },
+ { -1.000000000000, 0.000000000000, 0.0 },
+ { 0.000000000000, -1.000000000000, 0.0 },
+ { 1.000000000000, 0.000000000000, 0.0 },
+ { 0.353553390594, 0.353553390594, -0.5 },
+ { -0.353553390594, 0.353553390594, -0.5 },
+ { -0.353553390594, -0.353553390594, -0.5 },
+ { 0.353553390594, -0.353553390594, -0.5 }
+ };
+
+ /* tetrahedron data: */
+
+ private static final float T = 1.73205080756887729f;
+
+ private static final float[][] tdata =
+ {
+ {T, T, T},
+ {T, -T, -T},
+ {-T, T, -T},
+ {-T, -T, T}
+ };
+
+ private static final int[][] tndex =
+ {
+ {0, 1, 3},
+ {2, 1, 0},
+ {3, 2, 0},
+ {1, 2, 3}
+ };
+
+ private static final void tetrahedron(GL2 gl, int shadeType) {
+ for (int i = 3; i >= 0; i--)
+ drawtriangle(gl, i, tdata, tndex, shadeType);
+ }
+
+ // Teapot implementation (a modified port of glut_teapot.c)
+ //
+ // Rim, body, lid, and bottom data must be reflected in x and
+ // y; handle and spout data across the y axis only.
+ private static final int[][] teapotPatchData = {
+ /* rim */
+ {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
+ /* body */
+ {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27},
+ {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40},
+ /* lid */
+ {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3,},
+ {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117},
+ /* bottom */
+ {118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37},
+ /* handle */
+ {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56},
+ {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67},
+ /* spout */
+ {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83},
+ {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95}
+ };
+ private static final float[][] teapotCPData = {
+ {0.2f, 0f, 2.7f},
+ {0.2f, -0.112f, 2.7f},
+ {0.112f, -0.2f, 2.7f},
+ {0f, -0.2f, 2.7f},
+ {1.3375f, 0f, 2.53125f},
+ {1.3375f, -0.749f, 2.53125f},
+ {0.749f, -1.3375f, 2.53125f},
+ {0f, -1.3375f, 2.53125f},
+ {1.4375f, 0f, 2.53125f},
+ {1.4375f, -0.805f, 2.53125f},
+ {0.805f, -1.4375f, 2.53125f},
+ {0f, -1.4375f, 2.53125f},
+ {1.5f, 0f, 2.4f},
+ {1.5f, -0.84f, 2.4f},
+ {0.84f, -1.5f, 2.4f},
+ {0f, -1.5f, 2.4f},
+ {1.75f, 0f, 1.875f},
+ {1.75f, -0.98f, 1.875f},
+ {0.98f, -1.75f, 1.875f},
+ {0f, -1.75f, 1.875f},
+ {2f, 0f, 1.35f},
+ {2f, -1.12f, 1.35f},
+ {1.12f, -2f, 1.35f},
+ {0f, -2f, 1.35f},
+ {2f, 0f, 0.9f},
+ {2f, -1.12f, 0.9f},
+ {1.12f, -2f, 0.9f},
+ {0f, -2f, 0.9f},
+ {-2f, 0f, 0.9f},
+ {2f, 0f, 0.45f},
+ {2f, -1.12f, 0.45f},
+ {1.12f, -2f, 0.45f},
+ {0f, -2f, 0.45f},
+ {1.5f, 0f, 0.225f},
+ {1.5f, -0.84f, 0.225f},
+ {0.84f, -1.5f, 0.225f},
+ {0f, -1.5f, 0.225f},
+ {1.5f, 0f, 0.15f},
+ {1.5f, -0.84f, 0.15f},
+ {0.84f, -1.5f, 0.15f},
+ {0f, -1.5f, 0.15f},
+ {-1.6f, 0f, 2.025f},
+ {-1.6f, -0.3f, 2.025f},
+ {-1.5f, -0.3f, 2.25f},
+ {-1.5f, 0f, 2.25f},
+ {-2.3f, 0f, 2.025f},
+ {-2.3f, -0.3f, 2.025f},
+ {-2.5f, -0.3f, 2.25f},
+ {-2.5f, 0f, 2.25f},
+ {-2.7f, 0f, 2.025f},
+ {-2.7f, -0.3f, 2.025f},
+ {-3f, -0.3f, 2.25f},
+ {-3f, 0f, 2.25f},
+ {-2.7f, 0f, 1.8f},
+ {-2.7f, -0.3f, 1.8f},
+ {-3f, -0.3f, 1.8f},
+ {-3f, 0f, 1.8f},
+ {-2.7f, 0f, 1.575f},
+ {-2.7f, -0.3f, 1.575f},
+ {-3f, -0.3f, 1.35f},
+ {-3f, 0f, 1.35f},
+ {-2.5f, 0f, 1.125f},
+ {-2.5f, -0.3f, 1.125f},
+ {-2.65f, -0.3f, 0.9375f},
+ {-2.65f, 0f, 0.9375f},
+ {-2f, -0.3f, 0.9f},
+ {-1.9f, -0.3f, 0.6f},
+ {-1.9f, 0f, 0.6f},
+ {1.7f, 0f, 1.425f},
+ {1.7f, -0.66f, 1.425f},
+ {1.7f, -0.66f, 0.6f},
+ {1.7f, 0f, 0.6f},
+ {2.6f, 0f, 1.425f},
+ {2.6f, -0.66f, 1.425f},
+ {3.1f, -0.66f, 0.825f},
+ {3.1f, 0f, 0.825f},
+ {2.3f, 0f, 2.1f},
+ {2.3f, -0.25f, 2.1f},
+ {2.4f, -0.25f, 2.025f},
+ {2.4f, 0f, 2.025f},
+ {2.7f, 0f, 2.4f},
+ {2.7f, -0.25f, 2.4f},
+ {3.3f, -0.25f, 2.4f},
+ {3.3f, 0f, 2.4f},
+ {2.8f, 0f, 2.475f},
+ {2.8f, -0.25f, 2.475f},
+ {3.525f, -0.25f, 2.49375f},
+ {3.525f, 0f, 2.49375f},
+ {2.9f, 0f, 2.475f},
+ {2.9f, -0.15f, 2.475f},
+ {3.45f, -0.15f, 2.5125f},
+ {3.45f, 0f, 2.5125f},
+ {2.8f, 0f, 2.4f},
+ {2.8f, -0.15f, 2.4f},
+ {3.2f, -0.15f, 2.4f},
+ {3.2f, 0f, 2.4f},
+ {0f, 0f, 3.15f},
+ {0.8f, 0f, 3.15f},
+ {0.8f, -0.45f, 3.15f},
+ {0.45f, -0.8f, 3.15f},
+ {0f, -0.8f, 3.15f},
+ {0f, 0f, 2.85f},
+ {1.4f, 0f, 2.4f},
+ {1.4f, -0.784f, 2.4f},
+ {0.784f, -1.4f, 2.4f},
+ {0f, -1.4f, 2.4f},
+ {0.4f, 0f, 2.55f},
+ {0.4f, -0.224f, 2.55f},
+ {0.224f, -0.4f, 2.55f},
+ {0f, -0.4f, 2.55f},
+ {1.3f, 0f, 2.55f},
+ {1.3f, -0.728f, 2.55f},
+ {0.728f, -1.3f, 2.55f},
+ {0f, -1.3f, 2.55f},
+ {1.3f, 0f, 2.4f},
+ {1.3f, -0.728f, 2.4f},
+ {0.728f, -1.3f, 2.4f},
+ {0f, -1.3f, 2.4f},
+ {0f, 0f, 0f},
+ {1.425f, -0.798f, 0f},
+ {1.5f, 0f, 0.075f},
+ {1.425f, 0f, 0f},
+ {0.798f, -1.425f, 0f},
+ {0f, -1.5f, 0.075f},
+ {0f, -1.425f, 0f},
+ {1.5f, -0.84f, 0.075f},
+ {0.84f, -1.5f, 0.075f}
+ };
+ // Since GL2.glMap2f expects a packed array of floats, we must convert
+ // from a 3-dimensional array to a 1-dimensional array
+ private static final float[] teapotTex = {
+ 0, 0, 1, 0, 0, 1, 1, 1
+ };
+
+ private static void teapot(GL2 gl,
+ int grid,
+ double scale,
+ int type,
+ boolean backCompatible)
+ {
+ // As mentioned above, GL2.glMap2f expects a packed array of floats
+ float[] p = new float[4*4*3];
+ float[] q = new float[4*4*3];
+ float[] r = new float[4*4*3];
+ float[] s = new float[4*4*3];
+ int i, j, k, l;
+
+ gl.glPushAttrib(GL2.GL_ENABLE_BIT | GL2.GL_EVAL_BIT | GL2.GL_POLYGON_BIT);
+ gl.glEnable(GL2.GL_AUTO_NORMAL);
+ gl.glEnable(GL2.GL_NORMALIZE);
+ gl.glEnable(GL2.GL_MAP2_VERTEX_3);
+ gl.glEnable(GL2.GL_MAP2_TEXTURE_COORD_2);
+ gl.glPushMatrix();
+ if (!backCompatible) {
+ // The time has come to have the teapot no longer be inside out
+ gl.glFrontFace(GL2.GL_CW);
+ gl.glScaled(0.5*scale, 0.5*scale, 0.5*scale);
+ } else {
+ // We want the teapot in it's backward compatible position and
+ // orientation
+ gl.glRotatef(270.0f, 1, 0, 0);
+ gl.glScalef((float)(0.5 * scale),
+ (float)(0.5 * scale),
+ (float)(0.5 * scale));
+ gl.glTranslatef(0.0f, 0.0f, -1.5f);
+ }
+ for (i = 0; i < 10; i++) {
+ for (j = 0; j < 4; j++) {
+ for (k = 0; k < 4; k++) {
+ for (l = 0; l < 3; l++) {
+ p[(j*4+k)*3+l] = teapotCPData[teapotPatchData[i][j * 4 + k]][l];
+ q[(j*4+k)*3+l] =
+ teapotCPData[teapotPatchData[i][j * 4 + (3 - k)]][l];
+ if (l == 1)
+ q[(j*4+k)*3+l] *= -1.0;
+ if (i < 6) {
+ r[(j*4+k)*3+l] =
+ teapotCPData[teapotPatchData[i][j * 4 + (3 - k)]][l];
+ if (l == 0)
+ r[(j*4+k)*3+l] *= -1.0;
+ s[(j*4+k)*3+l] = teapotCPData[teapotPatchData[i][j * 4 + k]][l];
+ if (l == 0)
+ s[(j*4+k)*3+l] *= -1.0;
+ if (l == 1)
+ s[(j*4+k)*3+l] *= -1.0;
+ }
+ }
+ }
+ }
+ gl.glMap2f(GL2.GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, teapotTex, 0);
+ gl.glMap2f(GL2.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, p, 0);
+ gl.glMapGrid2f(grid, 0.0f, 1.0f, grid, 0.0f, 1.0f);
+ evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+ gl.glMap2f(GL2.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, q, 0);
+ evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+ if (i < 6) {
+ gl.glMap2f(GL2.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, r, 0);
+ evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+ gl.glMap2f(GL2.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, s, 0);
+ evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+ }
+ }
+ gl.glPopMatrix();
+ gl.glPopAttrib();
+ }
+
+ private static void evaluateTeapotMesh(GL2 gl,
+ int grid,
+ int type,
+ int partNum,
+ boolean repairSingularities)
+ {
+ if (repairSingularities && (partNum == 5 || partNum == 3)) {
+ // Instead of using evaluators that give bad results at singularities,
+ // evaluate by hand
+ gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, type);
+ for (int nv = 0; nv < grid; nv++) {
+ if (nv == 0) {
+ // Draw a small triangle-fan to fill the hole
+ gl.glDisable(GL2.GL_AUTO_NORMAL);
+ gl.glNormal3f(0, 0, partNum == 3 ? 1 : -1);
+ gl.glBegin(GL2.GL_TRIANGLE_FAN);
+ {
+ gl.glEvalCoord2f(0, 0);
+ // Note that we draw in clock-wise order to match the evaluator
+ // method
+ for (int nu = 0; nu <= grid; nu++)
+ {
+ gl.glEvalCoord2f(nu / (float)grid, (1f / grid) / (float)grid);
+ }
+ }
+ gl.glEnd();
+ gl.glEnable(GL2.GL_AUTO_NORMAL);
+ }
+ // Draw the rest of the piece as an evaluated quad-strip
+ gl.glBegin(GL2.GL_QUAD_STRIP);
+ {
+ // Note that we draw in clock-wise order to match the evaluator method
+ for (int nu = grid; nu >= 0; nu--) {
+ gl.glEvalCoord2f(nu / (float)grid, (nv + 1) / (float)grid);
+ gl.glEvalCoord2f(nu / (float)grid, Math.max(nv, 1f / grid)
+ / (float)grid);
+ }
+ }
+ gl.glEnd();
+ }
+ } else {
+ gl.glEvalMesh2(type, 0, grid, 0, grid);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Font implementation
+ //
+
+ private static void bitmapCharacterImpl(GL2 gl, int font, char cin) {
+ BitmapFontRec fontinfo = getBitmapFont(font);
+ int c = cin & 0xFFFF;
+ if (c < fontinfo.first ||
+ c >= fontinfo.first + fontinfo.num_chars)
+ return;
+ BitmapCharRec ch = fontinfo.ch[c - fontinfo.first];
+ if (ch != null) {
+ gl.glBitmap(ch.width, ch.height, ch.xorig, ch.yorig,
+ ch.advance, 0, ch.bitmap, 0);
+ }
+ }
+
+ private static final BitmapFontRec[] bitmapFonts = new BitmapFontRec[9];
+ private static final StrokeFontRec[] strokeFonts = new StrokeFontRec[9];
+
+ private static BitmapFontRec getBitmapFont(int font) {
+ BitmapFontRec rec = bitmapFonts[font];
+ if (rec == null) {
+ switch (font) {
+ case BITMAP_9_BY_15:
+ rec = GLUTBitmap9x15.glutBitmap9By15;
+ break;
+ case BITMAP_8_BY_13:
+ rec = GLUTBitmap8x13.glutBitmap8By13;
+ break;
+ case BITMAP_TIMES_ROMAN_10:
+ rec = GLUTBitmapTimesRoman10.glutBitmapTimesRoman10;
+ break;
+ case BITMAP_TIMES_ROMAN_24:
+ rec = GLUTBitmapTimesRoman24.glutBitmapTimesRoman24;
+ break;
+ case BITMAP_HELVETICA_10:
+ rec = GLUTBitmapHelvetica10.glutBitmapHelvetica10;
+ break;
+ case BITMAP_HELVETICA_12:
+ rec = GLUTBitmapHelvetica12.glutBitmapHelvetica12;
+ break;
+ case BITMAP_HELVETICA_18:
+ rec = GLUTBitmapHelvetica18.glutBitmapHelvetica18;
+ break;
+ default:
+ throw new GLException("Unknown bitmap font number " + font);
+ }
+ bitmapFonts[font] = rec;
+ }
+ return rec;
+ }
+
+ private static StrokeFontRec getStrokeFont(int font) {
+ StrokeFontRec rec = strokeFonts[font];
+ if (rec == null) {
+ switch (font) {
+ case STROKE_ROMAN:
+ rec = GLUTStrokeRoman.glutStrokeRoman;
+ break;
+ case STROKE_MONO_ROMAN:
+ rec = GLUTStrokeMonoRoman.glutStrokeMonoRoman;
+ break;
+ default:
+ throw new GLException("Unknown stroke font number " + font);
+ }
+ }
+ return rec;
+ }
+
+ private static void beginBitmap(GL2 gl,
+ int[] swapbytes,
+ int[] lsbfirst,
+ int[] rowlength,
+ int[] skiprows,
+ int[] skippixels,
+ int[] alignment) {
+ gl.glGetIntegerv(GL2.GL_UNPACK_SWAP_BYTES, swapbytes, 0);
+ gl.glGetIntegerv(GL2.GL_UNPACK_LSB_FIRST, lsbfirst, 0);
+ gl.glGetIntegerv(GL2.GL_UNPACK_ROW_LENGTH, rowlength, 0);
+ gl.glGetIntegerv(GL2.GL_UNPACK_SKIP_ROWS, skiprows, 0);
+ gl.glGetIntegerv(GL2.GL_UNPACK_SKIP_PIXELS, skippixels, 0);
+ gl.glGetIntegerv(GL2.GL_UNPACK_ALIGNMENT, alignment, 0);
+ /* Little endian machines (DEC Alpha for example) could
+ benefit from setting GL_UNPACK_LSB_FIRST to GL_TRUE
+ instead of GL_FALSE, but this would require changing the
+ generated bitmaps too. */
+ gl.glPixelStorei(GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE);
+ gl.glPixelStorei(GL2.GL_UNPACK_LSB_FIRST, GL2.GL_FALSE);
+ gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, 0);
+ gl.glPixelStorei(GL2.GL_UNPACK_SKIP_ROWS, 0);
+ gl.glPixelStorei(GL2.GL_UNPACK_SKIP_PIXELS, 0);
+ gl.glPixelStorei(GL2.GL_UNPACK_ALIGNMENT, 1);
+ }
+
+ private static void endBitmap(GL2 gl,
+ int[] swapbytes,
+ int[] lsbfirst,
+ int[] rowlength,
+ int[] skiprows,
+ int[] skippixels,
+ int[] alignment) {
+ /* Restore saved modes. */
+ gl.glPixelStorei(GL2.GL_UNPACK_SWAP_BYTES, swapbytes[0]);
+ gl.glPixelStorei(GL2.GL_UNPACK_LSB_FIRST, lsbfirst[0]);
+ gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, rowlength[0]);
+ gl.glPixelStorei(GL2.GL_UNPACK_SKIP_ROWS, skiprows[0]);
+ gl.glPixelStorei(GL2.GL_UNPACK_SKIP_PIXELS, skippixels[0]);
+ gl.glPixelStorei(GL2.GL_UNPACK_ALIGNMENT, alignment[0]);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmap8x13.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmap8x13.java
new file mode 100644
index 000000000..07ded652a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmap8x13.java
@@ -0,0 +1,2078 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+class GLUTBitmap8x13 {
+
+/* GENERATED FILE -- DO NOT MODIFY */
+
+
+static final BitmapCharRec ch0 = new BitmapCharRec(0,0,0,0,8,null);
+
+static final BitmapCharRec ch32 = new BitmapCharRec(0,0,0,0,8,null);
+
+static final BitmapCharRec ch127 = new BitmapCharRec(0,0,0,0,8,null);
+
+static final BitmapCharRec ch160 = new BitmapCharRec(0,0,0,0,8,null);
+
+/* char: 0xff */
+
+static final byte[] ch255data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x4,(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x0,(byte) 0x48,(byte) 0x48,
+};
+
+static final BitmapCharRec ch255 = new BitmapCharRec(6,12,-1,2,8,ch255data);
+
+/* char: 0xfe */
+
+static final byte[] ch254data = {
+(byte) 0x80,(byte) 0x80,(byte) 0xb8,(byte) 0xc4,(byte) 0x84,(byte) 0x84,(byte) 0xc4,(byte) 0xb8,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch254 = new BitmapCharRec(6,10,-1,2,8,ch254data);
+
+/* char: 0xfd */
+
+static final byte[] ch253data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x4,(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch253 = new BitmapCharRec(6,12,-1,2,8,ch253data);
+
+/* char: 0xfc */
+
+static final byte[] ch252data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x0,(byte) 0x48,(byte) 0x48,
+};
+
+static final BitmapCharRec ch252 = new BitmapCharRec(6,10,-1,0,8,ch252data);
+
+/* char: 0xfb */
+
+static final byte[] ch251data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x0,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch251 = new BitmapCharRec(6,10,-1,0,8,ch251data);
+
+/* char: 0xfa */
+
+static final byte[] ch250data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch250 = new BitmapCharRec(6,10,-1,0,8,ch250data);
+
+/* char: 0xf9 */
+
+static final byte[] ch249data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch249 = new BitmapCharRec(6,10,-1,0,8,ch249data);
+
+/* char: 0xf8 */
+
+static final byte[] ch248data = {
+(byte) 0x80,(byte) 0x78,(byte) 0xc4,(byte) 0xa4,(byte) 0x94,(byte) 0x8c,(byte) 0x78,(byte) 0x4,
+};
+
+static final BitmapCharRec ch248 = new BitmapCharRec(6,8,-1,1,8,ch248data);
+
+/* char: 0xf7 */
+
+static final byte[] ch247data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x0,(byte) 0xf8,(byte) 0x0,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch247 = new BitmapCharRec(5,7,-1,-1,8,ch247data);
+
+/* char: 0xf6 */
+
+static final byte[] ch246data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x48,(byte) 0x48,
+};
+
+static final BitmapCharRec ch246 = new BitmapCharRec(6,10,-1,0,8,ch246data);
+
+/* char: 0xf5 */
+
+static final byte[] ch245data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch245 = new BitmapCharRec(6,10,-1,0,8,ch245data);
+
+/* char: 0xf4 */
+
+static final byte[] ch244data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch244 = new BitmapCharRec(6,10,-1,0,8,ch244data);
+
+/* char: 0xf3 */
+
+static final byte[] ch243data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch243 = new BitmapCharRec(6,10,-1,0,8,ch243data);
+
+/* char: 0xf2 */
+
+static final byte[] ch242data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch242 = new BitmapCharRec(6,10,-1,0,8,ch242data);
+
+/* char: 0xf1 */
+
+static final byte[] ch241data = {
+(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xc4,(byte) 0xb8,(byte) 0x0,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch241 = new BitmapCharRec(6,10,-1,0,8,ch241data);
+
+/* char: 0xf0 */
+
+static final byte[] ch240data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x8,(byte) 0x50,(byte) 0x30,(byte) 0x48,
+};
+
+static final BitmapCharRec ch240 = new BitmapCharRec(6,10,-1,0,8,ch240data);
+
+/* char: 0xef */
+
+static final byte[] ch239data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x60,(byte) 0x0,(byte) 0x0,(byte) 0x50,(byte) 0x50,
+};
+
+static final BitmapCharRec ch239 = new BitmapCharRec(5,10,-1,0,8,ch239data);
+
+/* char: 0xee */
+
+static final byte[] ch238data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x60,(byte) 0x0,(byte) 0x0,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch238 = new BitmapCharRec(5,10,-1,0,8,ch238data);
+
+/* char: 0xed */
+
+static final byte[] ch237data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x60,(byte) 0x0,(byte) 0x0,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch237 = new BitmapCharRec(5,10,-1,0,8,ch237data);
+
+/* char: 0xec */
+
+static final byte[] ch236data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x60,(byte) 0x0,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch236 = new BitmapCharRec(5,10,-1,0,8,ch236data);
+
+/* char: 0xeb */
+
+static final byte[] ch235data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0xfc,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x48,(byte) 0x48,
+};
+
+static final BitmapCharRec ch235 = new BitmapCharRec(6,10,-1,0,8,ch235data);
+
+/* char: 0xea */
+
+static final byte[] ch234data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0xfc,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch234 = new BitmapCharRec(6,10,-1,0,8,ch234data);
+
+/* char: 0xe9 */
+
+static final byte[] ch233data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0xfc,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch233 = new BitmapCharRec(6,10,-1,0,8,ch233data);
+
+/* char: 0xe8 */
+
+static final byte[] ch232data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0xfc,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch232 = new BitmapCharRec(6,10,-1,0,8,ch232data);
+
+/* char: 0xe7 */
+
+static final byte[] ch231data = {
+(byte) 0x20,(byte) 0x10,(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0x80,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch231 = new BitmapCharRec(6,8,-1,2,8,ch231data);
+
+/* char: 0xe6 */
+
+static final byte[] ch230data = {
+(byte) 0x6c,(byte) 0x92,(byte) 0x90,(byte) 0x7c,(byte) 0x12,(byte) 0x6c,
+};
+
+static final BitmapCharRec ch230 = new BitmapCharRec(7,6,0,0,8,ch230data);
+
+/* char: 0xe5 */
+
+static final byte[] ch229data = {
+(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x7c,(byte) 0x4,(byte) 0x78,(byte) 0x0,(byte) 0x30,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch229 = new BitmapCharRec(6,10,-1,0,8,ch229data);
+
+/* char: 0xe4 */
+
+static final byte[] ch228data = {
+(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x7c,(byte) 0x4,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x48,(byte) 0x48,
+};
+
+static final BitmapCharRec ch228 = new BitmapCharRec(6,10,-1,0,8,ch228data);
+
+/* char: 0xe3 */
+
+static final byte[] ch227data = {
+(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x7c,(byte) 0x4,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch227 = new BitmapCharRec(6,10,-1,0,8,ch227data);
+
+/* char: 0xe2 */
+
+static final byte[] ch226data = {
+(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x7c,(byte) 0x4,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch226 = new BitmapCharRec(6,10,-1,0,8,ch226data);
+
+/* char: 0xe1 */
+
+static final byte[] ch225data = {
+(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x7c,(byte) 0x4,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch225 = new BitmapCharRec(6,10,-1,0,8,ch225data);
+
+/* char: 0xe0 */
+
+static final byte[] ch224data = {
+(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x7c,(byte) 0x4,(byte) 0x78,(byte) 0x0,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch224 = new BitmapCharRec(6,10,-1,0,8,ch224data);
+
+/* char: 0xdf */
+
+static final byte[] ch223data = {
+(byte) 0x80,(byte) 0xb8,(byte) 0xc4,(byte) 0x84,(byte) 0x84,(byte) 0xf8,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch223 = new BitmapCharRec(6,9,-1,1,8,ch223data);
+
+/* char: 0xde */
+
+static final byte[] ch222data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xf8,(byte) 0x80,
+};
+
+static final BitmapCharRec ch222 = new BitmapCharRec(6,9,-1,0,8,ch222data);
+
+/* char: 0xdd */
+
+static final byte[] ch221data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x50,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch221 = new BitmapCharRec(5,10,-1,0,8,ch221data);
+
+/* char: 0xdc */
+
+static final byte[] ch220data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x48,(byte) 0x48,
+};
+
+static final BitmapCharRec ch220 = new BitmapCharRec(6,10,-1,0,8,ch220data);
+
+/* char: 0xdb */
+
+static final byte[] ch219data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch219 = new BitmapCharRec(6,10,-1,0,8,ch219data);
+
+/* char: 0xda */
+
+static final byte[] ch218data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch218 = new BitmapCharRec(6,10,-1,0,8,ch218data);
+
+/* char: 0xd9 */
+
+static final byte[] ch217data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch217 = new BitmapCharRec(6,10,-1,0,8,ch217data);
+
+/* char: 0xd8 */
+
+static final byte[] ch216data = {
+(byte) 0x80,(byte) 0x78,(byte) 0xc4,(byte) 0xa4,(byte) 0xa4,(byte) 0xa4,(byte) 0x94,(byte) 0x94,(byte) 0x8c,(byte) 0x78,(byte) 0x4,
+};
+
+static final BitmapCharRec ch216 = new BitmapCharRec(6,11,-1,1,8,ch216data);
+
+/* char: 0xd7 */
+
+static final byte[] ch215data = {
+(byte) 0x84,(byte) 0x48,(byte) 0x30,(byte) 0x30,(byte) 0x48,(byte) 0x84,
+};
+
+static final BitmapCharRec ch215 = new BitmapCharRec(6,6,-1,-1,8,ch215data);
+
+/* char: 0xd6 */
+
+static final byte[] ch214data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch214 = new BitmapCharRec(7,10,0,0,8,ch214data);
+
+/* char: 0xd5 */
+
+static final byte[] ch213data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x28,(byte) 0x14,
+};
+
+static final BitmapCharRec ch213 = new BitmapCharRec(7,10,0,0,8,ch213data);
+
+/* char: 0xd4 */
+
+static final byte[] ch212data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x24,(byte) 0x18,
+};
+
+static final BitmapCharRec ch212 = new BitmapCharRec(7,10,0,0,8,ch212data);
+
+/* char: 0xd3 */
+
+static final byte[] ch211data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch211 = new BitmapCharRec(7,10,0,0,8,ch211data);
+
+/* char: 0xd2 */
+
+static final byte[] ch210data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x8,(byte) 0x10,
+};
+
+static final BitmapCharRec ch210 = new BitmapCharRec(7,10,0,0,8,ch210data);
+
+/* char: 0xd1 */
+
+static final byte[] ch209data = {
+(byte) 0x82,(byte) 0x86,(byte) 0x8a,(byte) 0x92,(byte) 0xa2,(byte) 0xc2,(byte) 0x82,(byte) 0x0,(byte) 0x28,(byte) 0x14,
+};
+
+static final BitmapCharRec ch209 = new BitmapCharRec(7,10,0,0,8,ch209data);
+
+/* char: 0xd0 */
+
+static final byte[] ch208data = {
+(byte) 0xfc,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0xe2,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch208 = new BitmapCharRec(7,9,0,0,8,ch208data);
+
+/* char: 0xcf */
+
+static final byte[] ch207data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x0,(byte) 0x50,(byte) 0x50,
+};
+
+static final BitmapCharRec ch207 = new BitmapCharRec(5,10,-1,0,8,ch207data);
+
+/* char: 0xce */
+
+static final byte[] ch206data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x0,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch206 = new BitmapCharRec(5,10,-1,0,8,ch206data);
+
+/* char: 0xcd */
+
+static final byte[] ch205data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch205 = new BitmapCharRec(5,10,-1,0,8,ch205data);
+
+/* char: 0xcc */
+
+static final byte[] ch204data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch204 = new BitmapCharRec(5,10,-1,0,8,ch204data);
+
+/* char: 0xcb */
+
+static final byte[] ch203data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x0,(byte) 0x48,(byte) 0x48,
+};
+
+static final BitmapCharRec ch203 = new BitmapCharRec(6,10,-1,0,8,ch203data);
+
+/* char: 0xca */
+
+static final byte[] ch202data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x0,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch202 = new BitmapCharRec(6,10,-1,0,8,ch202data);
+
+/* char: 0xc9 */
+
+static final byte[] ch201data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch201 = new BitmapCharRec(6,10,-1,0,8,ch201data);
+
+/* char: 0xc8 */
+
+static final byte[] ch200data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch200 = new BitmapCharRec(6,10,-1,0,8,ch200data);
+
+/* char: 0xc7 */
+
+static final byte[] ch199data = {
+(byte) 0x20,(byte) 0x10,(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch199 = new BitmapCharRec(6,11,-1,2,8,ch199data);
+
+/* char: 0xc6 */
+
+static final byte[] ch198data = {
+(byte) 0x9e,(byte) 0x90,(byte) 0x90,(byte) 0xf0,(byte) 0x9c,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x6e,
+};
+
+static final BitmapCharRec ch198 = new BitmapCharRec(7,9,0,0,8,ch198data);
+
+/* char: 0xc5 */
+
+static final byte[] ch197data = {
+(byte) 0x84,(byte) 0x84,(byte) 0xfc,(byte) 0x84,(byte) 0x84,(byte) 0x48,(byte) 0x30,(byte) 0x30,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch197 = new BitmapCharRec(6,10,-1,0,8,ch197data);
+
+/* char: 0xc4 */
+
+static final byte[] ch196data = {
+(byte) 0x84,(byte) 0x84,(byte) 0xfc,(byte) 0x84,(byte) 0x84,(byte) 0x48,(byte) 0x30,(byte) 0x0,(byte) 0x48,(byte) 0x48,
+};
+
+static final BitmapCharRec ch196 = new BitmapCharRec(6,10,-1,0,8,ch196data);
+
+/* char: 0xc3 */
+
+static final byte[] ch195data = {
+(byte) 0x84,(byte) 0x84,(byte) 0xfc,(byte) 0x84,(byte) 0x84,(byte) 0x48,(byte) 0x30,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch195 = new BitmapCharRec(6,10,-1,0,8,ch195data);
+
+/* char: 0xc2 */
+
+static final byte[] ch194data = {
+(byte) 0x84,(byte) 0x84,(byte) 0xfc,(byte) 0x84,(byte) 0x84,(byte) 0x48,(byte) 0x30,(byte) 0x0,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch194 = new BitmapCharRec(6,10,-1,0,8,ch194data);
+
+/* char: 0xc1 */
+
+static final byte[] ch193data = {
+(byte) 0x84,(byte) 0x84,(byte) 0xfc,(byte) 0x84,(byte) 0x84,(byte) 0x48,(byte) 0x30,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch193 = new BitmapCharRec(6,10,-1,0,8,ch193data);
+
+/* char: 0xc0 */
+
+static final byte[] ch192data = {
+(byte) 0x84,(byte) 0x84,(byte) 0xfc,(byte) 0x84,(byte) 0x84,(byte) 0x48,(byte) 0x30,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch192 = new BitmapCharRec(6,10,-1,0,8,ch192data);
+
+/* char: 0xbf */
+
+static final byte[] ch191data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x0,(byte) 0x20,
+};
+
+static final BitmapCharRec ch191 = new BitmapCharRec(6,9,-1,0,8,ch191data);
+
+/* char: 0xbe */
+
+static final byte[] ch190data = {
+(byte) 0x6,(byte) 0x1a,(byte) 0x12,(byte) 0xa,(byte) 0x66,(byte) 0x92,(byte) 0x10,(byte) 0x20,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch190 = new BitmapCharRec(7,10,0,0,8,ch190data);
+
+/* char: 0xbd */
+
+static final byte[] ch189data = {
+(byte) 0x1e,(byte) 0x10,(byte) 0xc,(byte) 0x2,(byte) 0xf2,(byte) 0x4c,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch189 = new BitmapCharRec(7,10,0,0,8,ch189data);
+
+/* char: 0xbc */
+
+static final byte[] ch188data = {
+(byte) 0x6,(byte) 0x1a,(byte) 0x12,(byte) 0xa,(byte) 0xe6,(byte) 0x42,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch188 = new BitmapCharRec(7,10,0,0,8,ch188data);
+
+/* char: 0xbb */
+
+static final byte[] ch187data = {
+(byte) 0x90,(byte) 0x48,(byte) 0x24,(byte) 0x12,(byte) 0x24,(byte) 0x48,(byte) 0x90,
+};
+
+static final BitmapCharRec ch187 = new BitmapCharRec(7,7,0,-1,8,ch187data);
+
+/* char: 0xba */
+
+static final byte[] ch186data = {
+(byte) 0xf0,(byte) 0x0,(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch186 = new BitmapCharRec(4,6,-1,-3,8,ch186data);
+
+/* char: 0xb9 */
+
+static final byte[] ch185data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch185 = new BitmapCharRec(3,6,-1,-4,8,ch185data);
+
+/* char: 0xb8 */
+
+static final byte[] ch184data = {
+(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch184 = new BitmapCharRec(2,2,-3,2,8,ch184data);
+
+/* char: 0xb7 */
+
+static final byte[] ch183data = {
+(byte) 0xc0,
+};
+
+static final BitmapCharRec ch183 = new BitmapCharRec(2,1,-3,-4,8,ch183data);
+
+/* char: 0xb6 */
+
+static final byte[] ch182data = {
+(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x68,(byte) 0xe8,(byte) 0xe8,(byte) 0xe8,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch182 = new BitmapCharRec(6,9,-1,0,8,ch182data);
+
+/* char: 0xb5 */
+
+static final byte[] ch181data = {
+(byte) 0x80,(byte) 0xb4,(byte) 0xcc,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,
+};
+
+static final BitmapCharRec ch181 = new BitmapCharRec(6,7,-1,1,8,ch181data);
+
+/* char: 0xb4 */
+
+static final byte[] ch180data = {
+(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch180 = new BitmapCharRec(2,2,-3,-8,8,ch180data);
+
+/* char: 0xb3 */
+
+static final byte[] ch179data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x10,(byte) 0x20,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch179 = new BitmapCharRec(4,6,-1,-4,8,ch179data);
+
+/* char: 0xb2 */
+
+static final byte[] ch178data = {
+(byte) 0xf0,(byte) 0x80,(byte) 0x60,(byte) 0x10,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch178 = new BitmapCharRec(4,6,-1,-4,8,ch178data);
+
+/* char: 0xb1 */
+
+static final byte[] ch177data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch177 = new BitmapCharRec(5,7,-1,-1,8,ch177data);
+
+/* char: 0xb0 */
+
+static final byte[] ch176data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch176 = new BitmapCharRec(4,4,-2,-5,8,ch176data);
+
+/* char: 0xaf */
+
+static final byte[] ch175data = {
+(byte) 0xfc,
+};
+
+static final BitmapCharRec ch175 = new BitmapCharRec(6,1,-1,-8,8,ch175data);
+
+/* char: 0xae */
+
+static final byte[] ch174data = {
+(byte) 0x38,(byte) 0x44,(byte) 0xaa,(byte) 0xb2,(byte) 0xaa,(byte) 0xaa,(byte) 0x92,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch174 = new BitmapCharRec(7,9,0,-1,8,ch174data);
+
+/* char: 0xad */
+
+static final byte[] ch173data = {
+(byte) 0xfc,
+};
+
+static final BitmapCharRec ch173 = new BitmapCharRec(6,1,-1,-4,8,ch173data);
+
+/* char: 0xac */
+
+static final byte[] ch172data = {
+(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch172 = new BitmapCharRec(6,4,-1,-1,8,ch172data);
+
+/* char: 0xab */
+
+static final byte[] ch171data = {
+(byte) 0x12,(byte) 0x24,(byte) 0x48,(byte) 0x90,(byte) 0x48,(byte) 0x24,(byte) 0x12,
+};
+
+static final BitmapCharRec ch171 = new BitmapCharRec(7,7,0,-1,8,ch171data);
+
+/* char: 0xaa */
+
+static final byte[] ch170data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0x78,(byte) 0x88,(byte) 0x78,(byte) 0x8,(byte) 0x70,
+};
+
+static final BitmapCharRec ch170 = new BitmapCharRec(5,7,-1,-2,8,ch170data);
+
+/* char: 0xa9 */
+
+static final byte[] ch169data = {
+(byte) 0x38,(byte) 0x44,(byte) 0x92,(byte) 0xaa,(byte) 0xa2,(byte) 0xaa,(byte) 0x92,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch169 = new BitmapCharRec(7,9,0,-1,8,ch169data);
+
+/* char: 0xa8 */
+
+static final byte[] ch168data = {
+(byte) 0xd8,
+};
+
+static final BitmapCharRec ch168 = new BitmapCharRec(5,1,-1,-8,8,ch168data);
+
+/* char: 0xa7 */
+
+static final byte[] ch167data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x10,(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,(byte) 0x80,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch167 = new BitmapCharRec(4,10,-2,0,8,ch167data);
+
+/* char: 0xa6 */
+
+static final byte[] ch166data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch166 = new BitmapCharRec(1,9,-3,0,8,ch166data);
+
+/* char: 0xa5 */
+
+static final byte[] ch165data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x7c,(byte) 0x10,(byte) 0x7c,(byte) 0x28,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch165 = new BitmapCharRec(7,9,0,0,8,ch165data);
+
+/* char: 0xa4 */
+
+static final byte[] ch164data = {
+(byte) 0x84,(byte) 0x78,(byte) 0x48,(byte) 0x48,(byte) 0x78,(byte) 0x84,
+};
+
+static final BitmapCharRec ch164 = new BitmapCharRec(6,6,-1,-1,8,ch164data);
+
+/* char: 0xa3 */
+
+static final byte[] ch163data = {
+(byte) 0xdc,(byte) 0x62,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x70,(byte) 0x20,(byte) 0x22,(byte) 0x1c,
+};
+
+static final BitmapCharRec ch163 = new BitmapCharRec(7,9,0,0,8,ch163data);
+
+/* char: 0xa2 */
+
+static final byte[] ch162data = {
+(byte) 0x20,(byte) 0x70,(byte) 0xa8,(byte) 0xa0,(byte) 0xa0,(byte) 0xa8,(byte) 0x70,(byte) 0x20,
+};
+
+static final BitmapCharRec ch162 = new BitmapCharRec(5,8,-1,-1,8,ch162data);
+
+/* char: 0xa1 */
+
+static final byte[] ch161data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch161 = new BitmapCharRec(1,9,-3,0,8,ch161data);
+
+/* char: 0x7e '~' */
+
+static final byte[] ch126data = {
+(byte) 0x90,(byte) 0xa8,(byte) 0x48,
+};
+
+static final BitmapCharRec ch126 = new BitmapCharRec(5,3,-1,-6,8,ch126data);
+
+/* char: 0x7d '}' */
+
+static final byte[] ch125data = {
+(byte) 0xe0,(byte) 0x10,(byte) 0x10,(byte) 0x20,(byte) 0x18,(byte) 0x20,(byte) 0x10,(byte) 0x10,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch125 = new BitmapCharRec(5,9,-1,0,8,ch125data);
+
+/* char: 0x7c '|' */
+
+static final byte[] ch124data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch124 = new BitmapCharRec(1,9,-3,0,8,ch124data);
+
+/* char: 0x7b '{' */
+
+static final byte[] ch123data = {
+(byte) 0x38,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0xc0,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x38,
+};
+
+static final BitmapCharRec ch123 = new BitmapCharRec(5,9,-2,0,8,ch123data);
+
+/* char: 0x7a 'z' */
+
+static final byte[] ch122data = {
+(byte) 0xfc,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch122 = new BitmapCharRec(6,6,-1,0,8,ch122data);
+
+/* char: 0x79 'y' */
+
+static final byte[] ch121data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x4,(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x84,(byte) 0x84,
+};
+
+static final BitmapCharRec ch121 = new BitmapCharRec(6,8,-1,2,8,ch121data);
+
+/* char: 0x78 'x' */
+
+static final byte[] ch120data = {
+(byte) 0x84,(byte) 0x48,(byte) 0x30,(byte) 0x30,(byte) 0x48,(byte) 0x84,
+};
+
+static final BitmapCharRec ch120 = new BitmapCharRec(6,6,-1,0,8,ch120data);
+
+/* char: 0x77 'w' */
+
+static final byte[] ch119data = {
+(byte) 0x44,(byte) 0xaa,(byte) 0x92,(byte) 0x92,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch119 = new BitmapCharRec(7,6,0,0,8,ch119data);
+
+/* char: 0x76 'v' */
+
+static final byte[] ch118data = {
+(byte) 0x20,(byte) 0x50,(byte) 0x50,(byte) 0x88,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch118 = new BitmapCharRec(5,6,-1,0,8,ch118data);
+
+/* char: 0x75 'u' */
+
+static final byte[] ch117data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch117 = new BitmapCharRec(6,6,-1,0,8,ch117data);
+
+/* char: 0x74 't' */
+
+static final byte[] ch116data = {
+(byte) 0x38,(byte) 0x44,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xf8,(byte) 0x40,(byte) 0x40,
+};
+
+static final BitmapCharRec ch116 = new BitmapCharRec(6,8,-1,0,8,ch116data);
+
+/* char: 0x73 's' */
+
+static final byte[] ch115data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x18,(byte) 0x60,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch115 = new BitmapCharRec(6,6,-1,0,8,ch115data);
+
+/* char: 0x72 'r' */
+
+static final byte[] ch114data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x44,(byte) 0xb8,
+};
+
+static final BitmapCharRec ch114 = new BitmapCharRec(6,6,-1,0,8,ch114data);
+
+/* char: 0x71 'q' */
+
+static final byte[] ch113data = {
+(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x8c,(byte) 0x74,
+};
+
+static final BitmapCharRec ch113 = new BitmapCharRec(6,8,-1,2,8,ch113data);
+
+/* char: 0x70 'p' */
+
+static final byte[] ch112data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xb8,(byte) 0xc4,(byte) 0x84,(byte) 0xc4,(byte) 0xb8,
+};
+
+static final BitmapCharRec ch112 = new BitmapCharRec(6,8,-1,2,8,ch112data);
+
+/* char: 0x6f 'o' */
+
+static final byte[] ch111data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch111 = new BitmapCharRec(6,6,-1,0,8,ch111data);
+
+/* char: 0x6e 'n' */
+
+static final byte[] ch110data = {
+(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xc4,(byte) 0xb8,
+};
+
+static final BitmapCharRec ch110 = new BitmapCharRec(6,6,-1,0,8,ch110data);
+
+/* char: 0x6d 'm' */
+
+static final byte[] ch109data = {
+(byte) 0x82,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0xec,
+};
+
+static final BitmapCharRec ch109 = new BitmapCharRec(7,6,0,0,8,ch109data);
+
+/* char: 0x6c 'l' */
+
+static final byte[] ch108data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x60,
+};
+
+static final BitmapCharRec ch108 = new BitmapCharRec(5,9,-1,0,8,ch108data);
+
+/* char: 0x6b 'k' */
+
+static final byte[] ch107data = {
+(byte) 0x84,(byte) 0x88,(byte) 0x90,(byte) 0xe0,(byte) 0x90,(byte) 0x88,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch107 = new BitmapCharRec(6,9,-1,0,8,ch107data);
+
+/* char: 0x6a 'j' */
+
+static final byte[] ch106data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x18,(byte) 0x0,(byte) 0x8,
+};
+
+static final BitmapCharRec ch106 = new BitmapCharRec(5,10,-1,2,8,ch106data);
+
+/* char: 0x69 'i' */
+
+static final byte[] ch105data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x60,(byte) 0x0,(byte) 0x20,
+};
+
+static final BitmapCharRec ch105 = new BitmapCharRec(5,8,-1,0,8,ch105data);
+
+/* char: 0x68 'h' */
+
+static final byte[] ch104data = {
+(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xc4,(byte) 0xb8,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch104 = new BitmapCharRec(6,9,-1,0,8,ch104data);
+
+/* char: 0x67 'g' */
+
+static final byte[] ch103data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x78,(byte) 0x80,(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x74,
+};
+
+static final BitmapCharRec ch103 = new BitmapCharRec(6,8,-1,2,8,ch103data);
+
+/* char: 0x66 'f' */
+
+static final byte[] ch102data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xf8,(byte) 0x40,(byte) 0x40,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch102 = new BitmapCharRec(6,9,-1,0,8,ch102data);
+
+/* char: 0x65 'e' */
+
+static final byte[] ch101data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0xfc,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch101 = new BitmapCharRec(6,6,-1,0,8,ch101data);
+
+/* char: 0x64 'd' */
+
+static final byte[] ch100data = {
+(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x84,(byte) 0x8c,(byte) 0x74,(byte) 0x4,(byte) 0x4,(byte) 0x4,
+};
+
+static final BitmapCharRec ch100 = new BitmapCharRec(6,9,-1,0,8,ch100data);
+
+/* char: 0x63 'c' */
+
+static final byte[] ch99data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0x80,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch99 = new BitmapCharRec(6,6,-1,0,8,ch99data);
+
+/* char: 0x62 'b' */
+
+static final byte[] ch98data = {
+(byte) 0xb8,(byte) 0xc4,(byte) 0x84,(byte) 0x84,(byte) 0xc4,(byte) 0xb8,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch98 = new BitmapCharRec(6,9,-1,0,8,ch98data);
+
+/* char: 0x61 'a' */
+
+static final byte[] ch97data = {
+(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x7c,(byte) 0x4,(byte) 0x78,
+};
+
+static final BitmapCharRec ch97 = new BitmapCharRec(6,6,-1,0,8,ch97data);
+
+/* char: 0x60 '`' */
+
+static final byte[] ch96data = {
+(byte) 0x10,(byte) 0x60,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch96 = new BitmapCharRec(4,3,-2,-6,8,ch96data);
+
+/* char: 0x5f '_' */
+
+static final byte[] ch95data = {
+(byte) 0xfe,
+};
+
+static final BitmapCharRec ch95 = new BitmapCharRec(7,1,0,1,8,ch95data);
+
+/* char: 0x5e '^' */
+
+static final byte[] ch94data = {
+(byte) 0x88,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch94 = new BitmapCharRec(5,3,-1,-6,8,ch94data);
+
+/* char: 0x5d ']' */
+
+static final byte[] ch93data = {
+(byte) 0xf0,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch93 = new BitmapCharRec(4,9,-1,0,8,ch93data);
+
+/* char: 0x5c '\' */
+
+static final byte[] ch92data = {
+(byte) 0x2,(byte) 0x2,(byte) 0x4,(byte) 0x8,(byte) 0x10,(byte) 0x20,(byte) 0x40,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch92 = new BitmapCharRec(7,9,0,0,8,ch92data);
+
+/* char: 0x5b '[' */
+
+static final byte[] ch91data = {
+(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch91 = new BitmapCharRec(4,9,-2,0,8,ch91data);
+
+/* char: 0x5a 'Z' */
+
+static final byte[] ch90data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch90 = new BitmapCharRec(6,9,-1,0,8,ch90data);
+
+/* char: 0x59 'Y' */
+
+static final byte[] ch89data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch89 = new BitmapCharRec(7,9,0,0,8,ch89data);
+
+/* char: 0x58 'X' */
+
+static final byte[] ch88data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch88 = new BitmapCharRec(7,9,0,0,8,ch88data);
+
+/* char: 0x57 'W' */
+
+static final byte[] ch87data = {
+(byte) 0x44,(byte) 0xaa,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch87 = new BitmapCharRec(7,9,0,0,8,ch87data);
+
+/* char: 0x56 'V' */
+
+static final byte[] ch86data = {
+(byte) 0x10,(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch86 = new BitmapCharRec(7,9,0,0,8,ch86data);
+
+/* char: 0x55 'U' */
+
+static final byte[] ch85data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,
+};
+
+static final BitmapCharRec ch85 = new BitmapCharRec(6,9,-1,0,8,ch85data);
+
+/* char: 0x54 'T' */
+
+static final byte[] ch84data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch84 = new BitmapCharRec(7,9,0,0,8,ch84data);
+
+/* char: 0x53 'S' */
+
+static final byte[] ch83data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x4,(byte) 0x4,(byte) 0x78,(byte) 0x80,(byte) 0x80,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch83 = new BitmapCharRec(6,9,-1,0,8,ch83data);
+
+/* char: 0x52 'R' */
+
+static final byte[] ch82data = {
+(byte) 0x84,(byte) 0x88,(byte) 0x90,(byte) 0xa0,(byte) 0xf8,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch82 = new BitmapCharRec(6,9,-1,0,8,ch82data);
+
+/* char: 0x51 'Q' */
+
+static final byte[] ch81data = {
+(byte) 0x4,(byte) 0x78,(byte) 0x94,(byte) 0xa4,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch81 = new BitmapCharRec(6,10,-1,1,8,ch81data);
+
+/* char: 0x50 'P' */
+
+static final byte[] ch80data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch80 = new BitmapCharRec(6,9,-1,0,8,ch80data);
+
+/* char: 0x4f 'O' */
+
+static final byte[] ch79data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch79 = new BitmapCharRec(6,9,-1,0,8,ch79data);
+
+/* char: 0x4e 'N' */
+
+static final byte[] ch78data = {
+(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x8c,(byte) 0x94,(byte) 0xa4,(byte) 0xc4,(byte) 0x84,(byte) 0x84,
+};
+
+static final BitmapCharRec ch78 = new BitmapCharRec(6,9,-1,0,8,ch78data);
+
+/* char: 0x4d 'M' */
+
+static final byte[] ch77data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x92,(byte) 0x92,(byte) 0xaa,(byte) 0xc6,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch77 = new BitmapCharRec(7,9,0,0,8,ch77data);
+
+/* char: 0x4c 'L' */
+
+static final byte[] ch76data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch76 = new BitmapCharRec(6,9,-1,0,8,ch76data);
+
+/* char: 0x4b 'K' */
+
+static final byte[] ch75data = {
+(byte) 0x84,(byte) 0x88,(byte) 0x90,(byte) 0xa0,(byte) 0xc0,(byte) 0xa0,(byte) 0x90,(byte) 0x88,(byte) 0x84,
+};
+
+static final BitmapCharRec ch75 = new BitmapCharRec(6,9,-1,0,8,ch75data);
+
+/* char: 0x4a 'J' */
+
+static final byte[] ch74data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch74 = new BitmapCharRec(6,9,-1,0,8,ch74data);
+
+/* char: 0x49 'I' */
+
+static final byte[] ch73data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch73 = new BitmapCharRec(5,9,-1,0,8,ch73data);
+
+/* char: 0x48 'H' */
+
+static final byte[] ch72data = {
+(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xfc,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,
+};
+
+static final BitmapCharRec ch72 = new BitmapCharRec(6,9,-1,0,8,ch72data);
+
+/* char: 0x47 'G' */
+
+static final byte[] ch71data = {
+(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x9c,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch71 = new BitmapCharRec(6,9,-1,0,8,ch71data);
+
+/* char: 0x46 'F' */
+
+static final byte[] ch70data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch70 = new BitmapCharRec(6,9,-1,0,8,ch70data);
+
+/* char: 0x45 'E' */
+
+static final byte[] ch69data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch69 = new BitmapCharRec(6,9,-1,0,8,ch69data);
+
+/* char: 0x44 'D' */
+
+static final byte[] ch68data = {
+(byte) 0xfc,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch68 = new BitmapCharRec(7,9,0,0,8,ch68data);
+
+/* char: 0x43 'C' */
+
+static final byte[] ch67data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch67 = new BitmapCharRec(6,9,-1,0,8,ch67data);
+
+/* char: 0x42 'B' */
+
+static final byte[] ch66data = {
+(byte) 0xfc,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x7c,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch66 = new BitmapCharRec(7,9,0,0,8,ch66data);
+
+/* char: 0x41 'A' */
+
+static final byte[] ch65data = {
+(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xfc,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch65 = new BitmapCharRec(6,9,-1,0,8,ch65data);
+
+/* char: 0x40 '@' */
+
+static final byte[] ch64data = {
+(byte) 0x78,(byte) 0x80,(byte) 0x94,(byte) 0xac,(byte) 0xa4,(byte) 0x9c,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch64 = new BitmapCharRec(6,9,-1,0,8,ch64data);
+
+/* char: 0x3f '?' */
+
+static final byte[] ch63data = {
+(byte) 0x10,(byte) 0x0,(byte) 0x10,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch63 = new BitmapCharRec(6,9,-1,0,8,ch63data);
+
+/* char: 0x3e '>' */
+
+static final byte[] ch62data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x10,(byte) 0x20,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch62 = new BitmapCharRec(5,9,-1,0,8,ch62data);
+
+/* char: 0x3d '=' */
+
+static final byte[] ch61data = {
+(byte) 0xfc,(byte) 0x0,(byte) 0x0,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch61 = new BitmapCharRec(6,4,-1,-2,8,ch61data);
+
+/* char: 0x3c '<' */
+
+static final byte[] ch60data = {
+(byte) 0x8,(byte) 0x10,(byte) 0x20,(byte) 0x40,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch60 = new BitmapCharRec(5,9,-2,0,8,ch60data);
+
+/* char: 0x3b ';' */
+
+static final byte[] ch59data = {
+(byte) 0x80,(byte) 0x60,(byte) 0x70,(byte) 0x0,(byte) 0x0,(byte) 0x20,(byte) 0x70,(byte) 0x20,
+};
+
+static final BitmapCharRec ch59 = new BitmapCharRec(4,8,-1,1,8,ch59data);
+
+/* char: 0x3a ':' */
+
+static final byte[] ch58data = {
+(byte) 0x40,(byte) 0xe0,(byte) 0x40,(byte) 0x0,(byte) 0x0,(byte) 0x40,(byte) 0xe0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch58 = new BitmapCharRec(3,8,-2,1,8,ch58data);
+
+/* char: 0x39 '9' */
+
+static final byte[] ch57data = {
+(byte) 0x70,(byte) 0x8,(byte) 0x4,(byte) 0x4,(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch57 = new BitmapCharRec(6,9,-1,0,8,ch57data);
+
+/* char: 0x38 '8' */
+
+static final byte[] ch56data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch56 = new BitmapCharRec(6,9,-1,0,8,ch56data);
+
+/* char: 0x37 '7' */
+
+static final byte[] ch55data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x10,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch55 = new BitmapCharRec(6,9,-1,0,8,ch55data);
+
+/* char: 0x36 '6' */
+
+static final byte[] ch54data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0xc4,(byte) 0xb8,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x38,
+};
+
+static final BitmapCharRec ch54 = new BitmapCharRec(6,9,-1,0,8,ch54data);
+
+/* char: 0x35 '5' */
+
+static final byte[] ch53data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x4,(byte) 0x4,(byte) 0xc4,(byte) 0xb8,(byte) 0x80,(byte) 0x80,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch53 = new BitmapCharRec(6,9,-1,0,8,ch53data);
+
+/* char: 0x34 '4' */
+
+static final byte[] ch52data = {
+(byte) 0x8,(byte) 0x8,(byte) 0xfc,(byte) 0x88,(byte) 0x88,(byte) 0x48,(byte) 0x28,(byte) 0x18,(byte) 0x8,
+};
+
+static final BitmapCharRec ch52 = new BitmapCharRec(6,9,-1,0,8,ch52data);
+
+/* char: 0x33 '3' */
+
+static final byte[] ch51data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x4,(byte) 0x4,(byte) 0x38,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch51 = new BitmapCharRec(6,9,-1,0,8,ch51data);
+
+/* char: 0x32 '2' */
+
+static final byte[] ch50data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x40,(byte) 0x30,(byte) 0x8,(byte) 0x4,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch50 = new BitmapCharRec(6,9,-1,0,8,ch50data);
+
+/* char: 0x31 '1' */
+
+static final byte[] ch49data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xa0,(byte) 0x60,(byte) 0x20,
+};
+
+static final BitmapCharRec ch49 = new BitmapCharRec(5,9,-1,0,8,ch49data);
+
+/* char: 0x30 '0' */
+
+static final byte[] ch48data = {
+(byte) 0x30,(byte) 0x48,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch48 = new BitmapCharRec(6,9,-1,0,8,ch48data);
+
+/* char: 0x2f '/' */
+
+static final byte[] ch47data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0x2,(byte) 0x2,
+};
+
+static final BitmapCharRec ch47 = new BitmapCharRec(7,9,0,0,8,ch47data);
+
+/* char: 0x2e '.' */
+
+static final byte[] ch46data = {
+(byte) 0x40,(byte) 0xe0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch46 = new BitmapCharRec(3,3,-2,1,8,ch46data);
+
+/* char: 0x2d '-' */
+
+static final byte[] ch45data = {
+(byte) 0xfc,
+};
+
+static final BitmapCharRec ch45 = new BitmapCharRec(6,1,-1,-4,8,ch45data);
+
+/* char: 0x2c ',' */
+
+static final byte[] ch44data = {
+(byte) 0x80,(byte) 0x60,(byte) 0x70,
+};
+
+static final BitmapCharRec ch44 = new BitmapCharRec(4,3,-1,1,8,ch44data);
+
+/* char: 0x2b '+' */
+
+static final byte[] ch43data = {
+(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch43 = new BitmapCharRec(5,5,-1,-2,8,ch43data);
+
+/* char: 0x2a '*' */
+
+static final byte[] ch42data = {
+(byte) 0x48,(byte) 0x30,(byte) 0xfc,(byte) 0x30,(byte) 0x48,
+};
+
+static final BitmapCharRec ch42 = new BitmapCharRec(6,5,-1,-2,8,ch42data);
+
+/* char: 0x29 ')' */
+
+static final byte[] ch41data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch41 = new BitmapCharRec(3,9,-2,0,8,ch41data);
+
+/* char: 0x28 '(' */
+
+static final byte[] ch40data = {
+(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch40 = new BitmapCharRec(3,9,-3,0,8,ch40data);
+
+/* char: 0x27 ''' */
+
+static final byte[] ch39data = {
+(byte) 0x80,(byte) 0x60,(byte) 0x70,
+};
+
+static final BitmapCharRec ch39 = new BitmapCharRec(4,3,-1,-6,8,ch39data);
+
+/* char: 0x26 '&' */
+
+static final byte[] ch38data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x94,(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch38 = new BitmapCharRec(6,7,-1,0,8,ch38data);
+
+/* char: 0x25 '%' */
+
+static final byte[] ch37data = {
+(byte) 0x88,(byte) 0x54,(byte) 0x48,(byte) 0x20,(byte) 0x10,(byte) 0x10,(byte) 0x48,(byte) 0xa4,(byte) 0x44,
+};
+
+static final BitmapCharRec ch37 = new BitmapCharRec(6,9,-1,0,8,ch37data);
+
+/* char: 0x24 '$' */
+
+static final byte[] ch36data = {
+(byte) 0x20,(byte) 0xf0,(byte) 0x28,(byte) 0x70,(byte) 0xa0,(byte) 0x78,(byte) 0x20,
+};
+
+static final BitmapCharRec ch36 = new BitmapCharRec(5,7,-1,-1,8,ch36data);
+
+/* char: 0x23 '#' */
+
+static final byte[] ch35data = {
+(byte) 0x48,(byte) 0x48,(byte) 0xfc,(byte) 0x48,(byte) 0xfc,(byte) 0x48,(byte) 0x48,
+};
+
+static final BitmapCharRec ch35 = new BitmapCharRec(6,7,-1,-1,8,ch35data);
+
+/* char: 0x22 '"' */
+
+static final byte[] ch34data = {
+(byte) 0x90,(byte) 0x90,(byte) 0x90,
+};
+
+static final BitmapCharRec ch34 = new BitmapCharRec(4,3,-2,-6,8,ch34data);
+
+/* char: 0x21 '!' */
+
+static final byte[] ch33data = {
+(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch33 = new BitmapCharRec(1,9,-3,0,8,ch33data);
+
+/* char: 0x1f */
+
+static final byte[] ch31data = {
+(byte) 0x80,
+};
+
+static final BitmapCharRec ch31 = new BitmapCharRec(1,1,-3,-3,8,ch31data);
+
+/* char: 0x1e */
+
+static final byte[] ch30data = {
+(byte) 0xdc,(byte) 0x62,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x70,(byte) 0x20,(byte) 0x22,(byte) 0x1c,
+};
+
+static final BitmapCharRec ch30 = new BitmapCharRec(7,9,0,0,8,ch30data);
+
+/* char: 0x1d */
+
+static final byte[] ch29data = {
+(byte) 0x80,(byte) 0x40,(byte) 0xfe,(byte) 0x10,(byte) 0xfe,(byte) 0x4,(byte) 0x2,
+};
+
+static final BitmapCharRec ch29 = new BitmapCharRec(7,7,0,0,8,ch29data);
+
+/* char: 0x1c */
+
+static final byte[] ch28data = {
+(byte) 0x88,(byte) 0x48,(byte) 0x48,(byte) 0x48,(byte) 0x48,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch28 = new BitmapCharRec(6,6,-1,0,8,ch28data);
+
+/* char: 0x1b */
+
+static final byte[] ch27data = {
+(byte) 0xfe,(byte) 0x80,(byte) 0x20,(byte) 0x8,(byte) 0x2,(byte) 0x8,(byte) 0x20,(byte) 0x80,
+};
+
+static final BitmapCharRec ch27 = new BitmapCharRec(7,8,0,0,8,ch27data);
+
+/* char: 0x1a */
+
+static final byte[] ch26data = {
+(byte) 0xfe,(byte) 0x2,(byte) 0x8,(byte) 0x20,(byte) 0x80,(byte) 0x20,(byte) 0x8,(byte) 0x2,
+};
+
+static final BitmapCharRec ch26 = new BitmapCharRec(7,8,0,0,8,ch26data);
+
+/* char: 0x19 */
+
+static final byte[] ch25data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch25 = new BitmapCharRec(1,13,-3,2,8,ch25data);
+
+/* char: 0x18 */
+
+static final byte[] ch24data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xff,
+};
+
+static final BitmapCharRec ch24 = new BitmapCharRec(8,6,0,2,8,ch24data);
+
+/* char: 0x17 */
+
+static final byte[] ch23data = {
+(byte) 0xff,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch23 = new BitmapCharRec(8,8,0,-3,8,ch23data);
+
+/* char: 0x16 */
+
+static final byte[] ch22data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xf0,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch22 = new BitmapCharRec(4,13,0,2,8,ch22data);
+
+/* char: 0x15 */
+
+static final byte[] ch21data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch21 = new BitmapCharRec(5,13,-3,2,8,ch21data);
+
+/* char: 0x14 */
+
+static final byte[] ch20data = {
+(byte) 0xff,
+};
+
+static final BitmapCharRec ch20 = new BitmapCharRec(8,1,0,1,8,ch20data);
+
+/* char: 0x13 */
+
+static final byte[] ch19data = {
+(byte) 0xff,
+};
+
+static final BitmapCharRec ch19 = new BitmapCharRec(8,1,0,-1,8,ch19data);
+
+/* char: 0x12 */
+
+static final byte[] ch18data = {
+(byte) 0xff,
+};
+
+static final BitmapCharRec ch18 = new BitmapCharRec(8,1,0,-3,8,ch18data);
+
+/* char: 0x11 */
+
+static final byte[] ch17data = {
+(byte) 0xff,
+};
+
+static final BitmapCharRec ch17 = new BitmapCharRec(8,1,0,-5,8,ch17data);
+
+/* char: 0x10 */
+
+static final byte[] ch16data = {
+(byte) 0xff,
+};
+
+static final BitmapCharRec ch16 = new BitmapCharRec(8,1,0,-7,8,ch16data);
+
+/* char: 0xf */
+
+static final byte[] ch15data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xff,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch15 = new BitmapCharRec(8,13,0,2,8,ch15data);
+
+/* char: 0xe */
+
+static final byte[] ch14data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch14 = new BitmapCharRec(5,8,-3,-3,8,ch14data);
+
+/* char: 0xd */
+
+static final byte[] ch13data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch13 = new BitmapCharRec(5,6,-3,2,8,ch13data);
+
+/* char: 0xc */
+
+static final byte[] ch12data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch12 = new BitmapCharRec(4,6,0,2,8,ch12data);
+
+/* char: 0xb */
+
+static final byte[] ch11data = {
+(byte) 0xf0,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch11 = new BitmapCharRec(4,8,0,-3,8,ch11data);
+
+/* char: 0xa */
+
+static final byte[] ch10data = {
+(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x3e,(byte) 0x20,(byte) 0x50,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch10 = new BitmapCharRec(7,9,0,2,8,ch10data);
+
+/* char: 0x9 */
+
+static final byte[] ch9data = {
+(byte) 0x3e,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x88,(byte) 0x98,(byte) 0xa8,(byte) 0xc8,(byte) 0x88,
+};
+
+static final BitmapCharRec ch9 = new BitmapCharRec(7,9,0,2,8,ch9data);
+
+/* char: 0x8 */
+
+static final byte[] ch8data = {
+(byte) 0xfe,(byte) 0x10,(byte) 0x10,(byte) 0xfe,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch8 = new BitmapCharRec(7,6,0,0,8,ch8data);
+
+/* char: 0x7 */
+
+static final byte[] ch7data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch7 = new BitmapCharRec(5,4,-1,-5,8,ch7data);
+
+/* char: 0x6 */
+
+static final byte[] ch6data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x3c,(byte) 0x20,(byte) 0x3e,(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch6 = new BitmapCharRec(7,9,0,2,8,ch6data);
+
+/* char: 0x5 */
+
+static final byte[] ch5data = {
+(byte) 0x22,(byte) 0x22,(byte) 0x3c,(byte) 0x22,(byte) 0x3c,(byte) 0x78,(byte) 0x80,(byte) 0x80,(byte) 0x78,
+};
+
+static final BitmapCharRec ch5 = new BitmapCharRec(7,9,0,2,8,ch5data);
+
+/* char: 0x4 */
+
+static final byte[] ch4data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x1c,(byte) 0x10,(byte) 0x9e,(byte) 0x80,(byte) 0xe0,(byte) 0x80,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch4 = new BitmapCharRec(7,9,0,2,8,ch4data);
+
+/* char: 0x3 */
+
+static final byte[] ch3data = {
+(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x3e,(byte) 0x88,(byte) 0x88,(byte) 0xf8,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch3 = new BitmapCharRec(7,9,0,2,8,ch3data);
+
+/* char: 0x2 */
+
+static final byte[] ch2data = {
+(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,
+};
+
+static final BitmapCharRec ch2 = new BitmapCharRec(8,12,0,2,8,ch2data);
+
+/* char: 0x1 */
+
+static final byte[] ch1data = {
+(byte) 0x10,(byte) 0x38,(byte) 0x7c,(byte) 0xfe,(byte) 0x7c,(byte) 0x38,(byte) 0x10,
+};
+
+static final BitmapCharRec ch1 = new BitmapCharRec(7,7,0,-1,8,ch1data);
+
+static final BitmapCharRec[] chars = {
+ch0,
+ch1,
+ch2,
+ch3,
+ch4,
+ch5,
+ch6,
+ch7,
+ch8,
+ch9,
+ch10,
+ch11,
+ch12,
+ch13,
+ch14,
+ch15,
+ch16,
+ch17,
+ch18,
+ch19,
+ch20,
+ch21,
+ch22,
+ch23,
+ch24,
+ch25,
+ch26,
+ch27,
+ch28,
+ch29,
+ch30,
+ch31,
+ch32,
+ch33,
+ch34,
+ch35,
+ch36,
+ch37,
+ch38,
+ch39,
+ch40,
+ch41,
+ch42,
+ch43,
+ch44,
+ch45,
+ch46,
+ch47,
+ch48,
+ch49,
+ch50,
+ch51,
+ch52,
+ch53,
+ch54,
+ch55,
+ch56,
+ch57,
+ch58,
+ch59,
+ch60,
+ch61,
+ch62,
+ch63,
+ch64,
+ch65,
+ch66,
+ch67,
+ch68,
+ch69,
+ch70,
+ch71,
+ch72,
+ch73,
+ch74,
+ch75,
+ch76,
+ch77,
+ch78,
+ch79,
+ch80,
+ch81,
+ch82,
+ch83,
+ch84,
+ch85,
+ch86,
+ch87,
+ch88,
+ch89,
+ch90,
+ch91,
+ch92,
+ch93,
+ch94,
+ch95,
+ch96,
+ch97,
+ch98,
+ch99,
+ch100,
+ch101,
+ch102,
+ch103,
+ch104,
+ch105,
+ch106,
+ch107,
+ch108,
+ch109,
+ch110,
+ch111,
+ch112,
+ch113,
+ch114,
+ch115,
+ch116,
+ch117,
+ch118,
+ch119,
+ch120,
+ch121,
+ch122,
+ch123,
+ch124,
+ch125,
+ch126,
+ch127,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+ch160,
+ch161,
+ch162,
+ch163,
+ch164,
+ch165,
+ch166,
+ch167,
+ch168,
+ch169,
+ch170,
+ch171,
+ch172,
+ch173,
+ch174,
+ch175,
+ch176,
+ch177,
+ch178,
+ch179,
+ch180,
+ch181,
+ch182,
+ch183,
+ch184,
+ch185,
+ch186,
+ch187,
+ch188,
+ch189,
+ch190,
+ch191,
+ch192,
+ch193,
+ch194,
+ch195,
+ch196,
+ch197,
+ch198,
+ch199,
+ch200,
+ch201,
+ch202,
+ch203,
+ch204,
+ch205,
+ch206,
+ch207,
+ch208,
+ch209,
+ch210,
+ch211,
+ch212,
+ch213,
+ch214,
+ch215,
+ch216,
+ch217,
+ch218,
+ch219,
+ch220,
+ch221,
+ch222,
+ch223,
+ch224,
+ch225,
+ch226,
+ch227,
+ch228,
+ch229,
+ch230,
+ch231,
+ch232,
+ch233,
+ch234,
+ch235,
+ch236,
+ch237,
+ch238,
+ch239,
+ch240,
+ch241,
+ch242,
+ch243,
+ch244,
+ch245,
+ch246,
+ch247,
+ch248,
+ch249,
+ch250,
+ch251,
+ch252,
+ch253,
+ch254,
+ch255,
+};
+
+ public static final BitmapFontRec glutBitmap8By13 = new BitmapFontRec("-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1",
+ 256,
+ 0,
+ chars);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmap9x15.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmap9x15.java
new file mode 100644
index 000000000..5d357f3f7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmap9x15.java
@@ -0,0 +1,2079 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+class GLUTBitmap9x15 {
+
+/* GENERATED FILE -- DO NOT MODIFY */
+
+static final BitmapCharRec ch0 = new BitmapCharRec(0,0,0,0,9,null);
+
+static final BitmapCharRec ch32 = new BitmapCharRec(0,0,0,0,9,null);
+
+static final BitmapCharRec ch127 = new BitmapCharRec(0,0,0,0,9,null);
+
+static final BitmapCharRec ch160 = new BitmapCharRec(0,0,0,0,9,null);
+
+/* char: 0xff */
+
+static final byte[] ch255data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x4,(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x0,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch255 = new BitmapCharRec(6,14,-1,3,9,ch255data);
+
+/* char: 0xfe */
+
+static final byte[] ch254data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xbc,(byte) 0xc2,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xc2,(byte) 0xbc,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch254 = new BitmapCharRec(7,12,-1,3,9,ch254data);
+
+/* char: 0xfd */
+
+static final byte[] ch253data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x4,(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x0,(byte) 0x30,(byte) 0x8,
+};
+
+static final BitmapCharRec ch253 = new BitmapCharRec(6,14,-1,3,9,ch253data);
+
+/* char: 0xfc */
+
+static final byte[] ch252data = {
+(byte) 0x7a,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x0,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch252 = new BitmapCharRec(7,11,-1,0,9,ch252data);
+
+/* char: 0xfb */
+
+static final byte[] ch251data = {
+(byte) 0x7a,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x0,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch251 = new BitmapCharRec(7,11,-1,0,9,ch251data);
+
+/* char: 0xfa */
+
+static final byte[] ch250data = {
+(byte) 0x7a,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x0,(byte) 0x30,(byte) 0x8,
+};
+
+static final BitmapCharRec ch250 = new BitmapCharRec(7,11,-1,0,9,ch250data);
+
+/* char: 0xf9 */
+
+static final byte[] ch249data = {
+(byte) 0x7a,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x0,(byte) 0x18,(byte) 0x20,
+};
+
+static final BitmapCharRec ch249 = new BitmapCharRec(7,11,-1,0,9,ch249data);
+
+/* char: 0xf8 */
+
+static final byte[] ch248data = {
+(byte) 0x80,(byte) 0x7c,(byte) 0xa2,(byte) 0xa2,(byte) 0x92,(byte) 0x8a,(byte) 0x8a,(byte) 0x7c,(byte) 0x2,
+};
+
+static final BitmapCharRec ch248 = new BitmapCharRec(7,9,-1,1,9,ch248data);
+
+/* char: 0xf7 */
+
+static final byte[] ch247data = {
+(byte) 0x10,(byte) 0x38,(byte) 0x10,(byte) 0x0,(byte) 0xfe,(byte) 0x0,(byte) 0x10,(byte) 0x38,(byte) 0x10,
+};
+
+static final BitmapCharRec ch247 = new BitmapCharRec(7,9,-1,0,9,ch247data);
+
+/* char: 0xf6 */
+
+static final byte[] ch246data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch246 = new BitmapCharRec(7,11,-1,0,9,ch246data);
+
+/* char: 0xf5 */
+
+static final byte[] ch245data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch245 = new BitmapCharRec(7,11,-1,0,9,ch245data);
+
+/* char: 0xf4 */
+
+static final byte[] ch244data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch244 = new BitmapCharRec(7,11,-1,0,9,ch244data);
+
+/* char: 0xf3 */
+
+static final byte[] ch243data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x30,(byte) 0x8,
+};
+
+static final BitmapCharRec ch243 = new BitmapCharRec(7,11,-1,0,9,ch243data);
+
+/* char: 0xf2 */
+
+static final byte[] ch242data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x18,(byte) 0x20,
+};
+
+static final BitmapCharRec ch242 = new BitmapCharRec(7,11,-1,0,9,ch242data);
+
+/* char: 0xf1 */
+
+static final byte[] ch241data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xc2,(byte) 0xbc,(byte) 0x0,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch241 = new BitmapCharRec(7,11,-1,0,9,ch241data);
+
+/* char: 0xf0 */
+
+static final byte[] ch240data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x8,(byte) 0x50,(byte) 0x30,(byte) 0x48,
+};
+
+static final BitmapCharRec ch240 = new BitmapCharRec(7,11,-1,0,9,ch240data);
+
+/* char: 0xef */
+
+static final byte[] ch239data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x50,(byte) 0x50,
+};
+
+static final BitmapCharRec ch239 = new BitmapCharRec(5,11,-2,0,9,ch239data);
+
+/* char: 0xee */
+
+static final byte[] ch238data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch238 = new BitmapCharRec(5,11,-2,0,9,ch238data);
+
+/* char: 0xed */
+
+static final byte[] ch237data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x60,(byte) 0x10,
+};
+
+static final BitmapCharRec ch237 = new BitmapCharRec(5,11,-2,0,9,ch237data);
+
+/* char: 0xec */
+
+static final byte[] ch236data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x30,(byte) 0x40,
+};
+
+static final BitmapCharRec ch236 = new BitmapCharRec(5,11,-2,0,9,ch236data);
+
+/* char: 0xeb */
+
+static final byte[] ch235data = {
+(byte) 0x7c,(byte) 0x80,(byte) 0x80,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch235 = new BitmapCharRec(7,11,-1,0,9,ch235data);
+
+/* char: 0xea */
+
+static final byte[] ch234data = {
+(byte) 0x7c,(byte) 0x80,(byte) 0x80,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch234 = new BitmapCharRec(7,11,-1,0,9,ch234data);
+
+/* char: 0xe9 */
+
+static final byte[] ch233data = {
+(byte) 0x7c,(byte) 0x80,(byte) 0x80,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x30,(byte) 0x8,
+};
+
+static final BitmapCharRec ch233 = new BitmapCharRec(7,11,-1,0,9,ch233data);
+
+/* char: 0xe8 */
+
+static final byte[] ch232data = {
+(byte) 0x7c,(byte) 0x80,(byte) 0x80,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x18,(byte) 0x20,
+};
+
+static final BitmapCharRec ch232 = new BitmapCharRec(7,11,-1,0,9,ch232data);
+
+/* char: 0xe7 */
+
+static final byte[] ch231data = {
+(byte) 0x30,(byte) 0x48,(byte) 0x18,(byte) 0x7c,(byte) 0x82,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch231 = new BitmapCharRec(7,10,-1,3,9,ch231data);
+
+/* char: 0xe6 */
+
+static final byte[] ch230data = {
+(byte) 0x6e,(byte) 0x92,(byte) 0x90,(byte) 0x7c,(byte) 0x12,(byte) 0x92,(byte) 0x6c,
+};
+
+static final BitmapCharRec ch230 = new BitmapCharRec(7,7,-1,0,9,ch230data);
+
+/* char: 0xe5 */
+
+static final byte[] ch229data = {
+(byte) 0x7a,(byte) 0x86,(byte) 0x82,(byte) 0x7e,(byte) 0x2,(byte) 0x2,(byte) 0x7c,(byte) 0x0,(byte) 0x18,(byte) 0x24,(byte) 0x18,
+};
+
+static final BitmapCharRec ch229 = new BitmapCharRec(7,11,-1,0,9,ch229data);
+
+/* char: 0xe4 */
+
+static final byte[] ch228data = {
+(byte) 0x7a,(byte) 0x86,(byte) 0x82,(byte) 0x7e,(byte) 0x2,(byte) 0x2,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch228 = new BitmapCharRec(7,11,-1,0,9,ch228data);
+
+/* char: 0xe3 */
+
+static final byte[] ch227data = {
+(byte) 0x7a,(byte) 0x86,(byte) 0x82,(byte) 0x7e,(byte) 0x2,(byte) 0x2,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch227 = new BitmapCharRec(7,11,-1,0,9,ch227data);
+
+/* char: 0xe2 */
+
+static final byte[] ch226data = {
+(byte) 0x7a,(byte) 0x86,(byte) 0x82,(byte) 0x7e,(byte) 0x2,(byte) 0x2,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch226 = new BitmapCharRec(7,11,-1,0,9,ch226data);
+
+/* char: 0xe1 */
+
+static final byte[] ch225data = {
+(byte) 0x7a,(byte) 0x86,(byte) 0x82,(byte) 0x7e,(byte) 0x2,(byte) 0x2,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x30,(byte) 0x8,
+};
+
+static final BitmapCharRec ch225 = new BitmapCharRec(7,11,-1,0,9,ch225data);
+
+/* char: 0xe0 */
+
+static final byte[] ch224data = {
+(byte) 0x7a,(byte) 0x86,(byte) 0x82,(byte) 0x7e,(byte) 0x2,(byte) 0x2,(byte) 0x7c,(byte) 0x0,(byte) 0x0,(byte) 0x18,(byte) 0x20,
+};
+
+static final BitmapCharRec ch224 = new BitmapCharRec(7,11,-1,0,9,ch224data);
+
+/* char: 0xdf */
+
+static final byte[] ch223data = {
+(byte) 0x80,(byte) 0xbc,(byte) 0xc2,(byte) 0x82,(byte) 0x82,(byte) 0xfc,(byte) 0x82,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch223 = new BitmapCharRec(7,9,-1,1,9,ch223data);
+
+/* char: 0xde */
+
+static final byte[] ch222data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfc,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch222 = new BitmapCharRec(7,10,-1,0,9,ch222data);
+
+/* char: 0xdd */
+
+static final byte[] ch221data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0x82,(byte) 0x82,(byte) 0x0,(byte) 0x30,(byte) 0x8,
+};
+
+static final BitmapCharRec ch221 = new BitmapCharRec(7,11,-1,0,9,ch221data);
+
+/* char: 0xdc */
+
+static final byte[] ch220data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x0,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch220 = new BitmapCharRec(7,11,-1,0,9,ch220data);
+
+/* char: 0xdb */
+
+static final byte[] ch219data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x0,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch219 = new BitmapCharRec(7,11,-1,0,9,ch219data);
+
+/* char: 0xda */
+
+static final byte[] ch218data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x0,(byte) 0x30,(byte) 0x8,
+};
+
+static final BitmapCharRec ch218 = new BitmapCharRec(7,11,-1,0,9,ch218data);
+
+/* char: 0xd9 */
+
+static final byte[] ch217data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x0,(byte) 0x18,(byte) 0x20,
+};
+
+static final BitmapCharRec ch217 = new BitmapCharRec(7,11,-1,0,9,ch217data);
+
+/* char: 0xd8 */
+
+static final byte[] ch216data = {
+(byte) 0x80,(byte) 0x7c,(byte) 0xc2,(byte) 0xa2,(byte) 0xa2,(byte) 0x92,(byte) 0x92,(byte) 0x8a,(byte) 0x8a,(byte) 0x86,(byte) 0x7c,(byte) 0x2,
+};
+
+static final BitmapCharRec ch216 = new BitmapCharRec(7,12,-1,1,9,ch216data);
+
+/* char: 0xd7 */
+
+static final byte[] ch215data = {
+(byte) 0x82,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0x82,
+};
+
+static final BitmapCharRec ch215 = new BitmapCharRec(7,7,-1,-1,9,ch215data);
+
+/* char: 0xd6 */
+
+static final byte[] ch214data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch214 = new BitmapCharRec(7,11,-1,0,9,ch214data);
+
+/* char: 0xd5 */
+
+static final byte[] ch213data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch213 = new BitmapCharRec(7,11,-1,0,9,ch213data);
+
+/* char: 0xd4 */
+
+static final byte[] ch212data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch212 = new BitmapCharRec(7,11,-1,0,9,ch212data);
+
+/* char: 0xd3 */
+
+static final byte[] ch211data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x30,(byte) 0x8,
+};
+
+static final BitmapCharRec ch211 = new BitmapCharRec(7,11,-1,0,9,ch211data);
+
+/* char: 0xd2 */
+
+static final byte[] ch210data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x0,(byte) 0x18,(byte) 0x20,
+};
+
+static final BitmapCharRec ch210 = new BitmapCharRec(7,11,-1,0,9,ch210data);
+
+/* char: 0xd1 */
+
+static final byte[] ch209data = {
+(byte) 0x82,(byte) 0x86,(byte) 0x8a,(byte) 0x92,(byte) 0x92,(byte) 0xa2,(byte) 0xc2,(byte) 0x82,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch209 = new BitmapCharRec(7,11,-1,0,9,ch209data);
+
+/* char: 0xd0 */
+
+static final byte[] ch208data = {
+(byte) 0xfc,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0xf2,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch208 = new BitmapCharRec(7,10,-1,0,9,ch208data);
+
+/* char: 0xcf */
+
+static final byte[] ch207data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x0,(byte) 0x50,(byte) 0x50,
+};
+
+static final BitmapCharRec ch207 = new BitmapCharRec(5,11,-2,0,9,ch207data);
+
+/* char: 0xce */
+
+static final byte[] ch206data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x0,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch206 = new BitmapCharRec(5,11,-2,0,9,ch206data);
+
+/* char: 0xcd */
+
+static final byte[] ch205data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x0,(byte) 0x60,(byte) 0x10,
+};
+
+static final BitmapCharRec ch205 = new BitmapCharRec(5,11,-2,0,9,ch205data);
+
+/* char: 0xcc */
+
+static final byte[] ch204data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x0,(byte) 0x30,(byte) 0x40,
+};
+
+static final BitmapCharRec ch204 = new BitmapCharRec(5,11,-2,0,9,ch204data);
+
+/* char: 0xcb */
+
+static final byte[] ch203data = {
+(byte) 0xfe,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x78,(byte) 0x40,(byte) 0x40,(byte) 0xfe,(byte) 0x0,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch203 = new BitmapCharRec(7,11,-1,0,9,ch203data);
+
+/* char: 0xca */
+
+static final byte[] ch202data = {
+(byte) 0xfe,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x78,(byte) 0x40,(byte) 0x40,(byte) 0xfe,(byte) 0x0,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch202 = new BitmapCharRec(7,11,-1,0,9,ch202data);
+
+/* char: 0xc9 */
+
+static final byte[] ch201data = {
+(byte) 0xfe,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x78,(byte) 0x40,(byte) 0x40,(byte) 0xfe,(byte) 0x0,(byte) 0x30,(byte) 0x8,
+};
+
+static final BitmapCharRec ch201 = new BitmapCharRec(7,11,-1,0,9,ch201data);
+
+/* char: 0xc8 */
+
+static final byte[] ch200data = {
+(byte) 0xfe,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x78,(byte) 0x40,(byte) 0x40,(byte) 0xfe,(byte) 0x0,(byte) 0x18,(byte) 0x20,
+};
+
+static final BitmapCharRec ch200 = new BitmapCharRec(7,11,-1,0,9,ch200data);
+
+/* char: 0xc7 */
+
+static final byte[] ch199data = {
+(byte) 0x30,(byte) 0x48,(byte) 0x18,(byte) 0x7c,(byte) 0x82,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch199 = new BitmapCharRec(7,13,-1,3,9,ch199data);
+
+/* char: 0xc6 */
+
+static final byte[] ch198data = {
+(byte) 0x9e,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0xfc,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x6e,
+};
+
+static final BitmapCharRec ch198 = new BitmapCharRec(7,10,-1,0,9,ch198data);
+
+/* char: 0xc5 */
+
+static final byte[] ch197data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x38,(byte) 0x10,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch197 = new BitmapCharRec(7,11,-1,0,9,ch197data);
+
+/* char: 0xc4 */
+
+static final byte[] ch196data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x38,(byte) 0x0,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch196 = new BitmapCharRec(7,11,-1,0,9,ch196data);
+
+/* char: 0xc3 */
+
+static final byte[] ch195data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x38,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch195 = new BitmapCharRec(7,11,-1,0,9,ch195data);
+
+/* char: 0xc2 */
+
+static final byte[] ch194data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x38,(byte) 0x0,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch194 = new BitmapCharRec(7,11,-1,0,9,ch194data);
+
+/* char: 0xc1 */
+
+static final byte[] ch193data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x38,(byte) 0x0,(byte) 0x30,(byte) 0x8,
+};
+
+static final BitmapCharRec ch193 = new BitmapCharRec(7,11,-1,0,9,ch193data);
+
+/* char: 0xc0 */
+
+static final byte[] ch192data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x38,(byte) 0x0,(byte) 0x18,(byte) 0x20,
+};
+
+static final BitmapCharRec ch192 = new BitmapCharRec(7,11,-1,0,9,ch192data);
+
+/* char: 0xbf */
+
+static final byte[] ch191data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x10,
+};
+
+static final BitmapCharRec ch191 = new BitmapCharRec(7,10,-1,0,9,ch191data);
+
+/* char: 0xbe */
+
+static final byte[] ch190data = {
+(byte) 0x6,(byte) 0x1a,(byte) 0x12,(byte) 0xa,(byte) 0x66,(byte) 0x92,(byte) 0x10,(byte) 0x20,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch190 = new BitmapCharRec(7,10,-1,0,9,ch190data);
+
+/* char: 0xbd */
+
+static final byte[] ch189data = {
+(byte) 0x1e,(byte) 0x10,(byte) 0xc,(byte) 0x2,(byte) 0xf2,(byte) 0x4c,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch189 = new BitmapCharRec(7,10,-1,0,9,ch189data);
+
+/* char: 0xbc */
+
+static final byte[] ch188data = {
+(byte) 0x6,(byte) 0x1a,(byte) 0x12,(byte) 0xa,(byte) 0xe6,(byte) 0x42,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch188 = new BitmapCharRec(7,10,-1,0,9,ch188data);
+
+/* char: 0xbb */
+
+static final byte[] ch187data = {
+(byte) 0x90,(byte) 0x48,(byte) 0x24,(byte) 0x12,(byte) 0x12,(byte) 0x24,(byte) 0x48,(byte) 0x90,
+};
+
+static final BitmapCharRec ch187 = new BitmapCharRec(7,8,-1,-1,9,ch187data);
+
+/* char: 0xba */
+
+static final byte[] ch186data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch186 = new BitmapCharRec(5,6,-1,-5,9,ch186data);
+
+/* char: 0xb9 */
+
+static final byte[] ch185data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch185 = new BitmapCharRec(3,6,-1,-4,9,ch185data);
+
+/* char: 0xb8 */
+
+static final byte[] ch184data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x30,
+};
+
+static final BitmapCharRec ch184 = new BitmapCharRec(4,3,-2,3,9,ch184data);
+
+/* char: 0xb7 */
+
+static final byte[] ch183data = {
+(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch183 = new BitmapCharRec(2,2,-4,-4,9,ch183data);
+
+/* char: 0xb6 */
+
+static final byte[] ch182data = {
+(byte) 0xa,(byte) 0xa,(byte) 0xa,(byte) 0xa,(byte) 0xa,(byte) 0x7a,(byte) 0x8a,(byte) 0x8a,(byte) 0x8a,(byte) 0x7e,
+};
+
+static final BitmapCharRec ch182 = new BitmapCharRec(7,10,-1,0,9,ch182data);
+
+/* char: 0xb5 */
+
+static final byte[] ch181data = {
+(byte) 0x80,(byte) 0x80,(byte) 0xba,(byte) 0xc6,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch181 = new BitmapCharRec(7,9,-1,2,9,ch181data);
+
+/* char: 0xb4 */
+
+static final byte[] ch180data = {
+(byte) 0xc0,(byte) 0x20,
+};
+
+static final BitmapCharRec ch180 = new BitmapCharRec(3,2,-3,-9,9,ch180data);
+
+/* char: 0xb3 */
+
+static final byte[] ch179data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x10,(byte) 0x20,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch179 = new BitmapCharRec(4,6,-1,-4,9,ch179data);
+
+/* char: 0xb2 */
+
+static final byte[] ch178data = {
+(byte) 0xf0,(byte) 0x80,(byte) 0x60,(byte) 0x10,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch178 = new BitmapCharRec(4,6,-1,-4,9,ch178data);
+
+/* char: 0xb1 */
+
+static final byte[] ch177data = {
+(byte) 0xfe,(byte) 0x0,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xfe,(byte) 0x10,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch177 = new BitmapCharRec(7,9,-1,-1,9,ch177data);
+
+/* char: 0xb0 */
+
+static final byte[] ch176data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch176 = new BitmapCharRec(4,4,-3,-6,9,ch176data);
+
+/* char: 0xaf */
+
+static final byte[] ch175data = {
+(byte) 0xfc,
+};
+
+static final BitmapCharRec ch175 = new BitmapCharRec(6,1,-1,-9,9,ch175data);
+
+/* char: 0xae */
+
+static final byte[] ch174data = {
+(byte) 0x3c,(byte) 0x42,(byte) 0xa5,(byte) 0xa9,(byte) 0xbd,(byte) 0xa5,(byte) 0xb9,(byte) 0x42,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch174 = new BitmapCharRec(8,9,0,-1,9,ch174data);
+
+/* char: 0xad */
+
+static final byte[] ch173data = {
+(byte) 0xfc,
+};
+
+static final BitmapCharRec ch173 = new BitmapCharRec(6,1,-1,-4,9,ch173data);
+
+/* char: 0xac */
+
+static final byte[] ch172data = {
+(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch172 = new BitmapCharRec(6,4,-1,-2,9,ch172data);
+
+/* char: 0xab */
+
+static final byte[] ch171data = {
+(byte) 0x12,(byte) 0x24,(byte) 0x48,(byte) 0x90,(byte) 0x90,(byte) 0x48,(byte) 0x24,(byte) 0x12,
+};
+
+static final BitmapCharRec ch171 = new BitmapCharRec(7,8,-1,-1,9,ch171data);
+
+/* char: 0xaa */
+
+static final byte[] ch170data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0x78,(byte) 0x90,(byte) 0x70,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch170 = new BitmapCharRec(5,7,-3,-3,9,ch170data);
+
+/* char: 0xa9 */
+
+static final byte[] ch169data = {
+(byte) 0x3c,(byte) 0x42,(byte) 0x99,(byte) 0xa5,(byte) 0xa1,(byte) 0xa5,(byte) 0x99,(byte) 0x42,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch169 = new BitmapCharRec(8,9,0,-1,9,ch169data);
+
+/* char: 0xa8 */
+
+static final byte[] ch168data = {
+(byte) 0xa0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch168 = new BitmapCharRec(3,2,-3,-9,9,ch168data);
+
+/* char: 0xa7 */
+
+static final byte[] ch167data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x8,(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x80,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch167 = new BitmapCharRec(5,11,-2,1,9,ch167data);
+
+/* char: 0xa6 */
+
+static final byte[] ch166data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch166 = new BitmapCharRec(1,11,-4,1,9,ch166data);
+
+/* char: 0xa5 */
+
+static final byte[] ch165data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x7c,(byte) 0x10,(byte) 0x7c,(byte) 0x28,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch165 = new BitmapCharRec(7,10,-1,0,9,ch165data);
+
+/* char: 0xa4 */
+
+static final byte[] ch164data = {
+(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x44,(byte) 0x7c,(byte) 0x82,
+};
+
+static final BitmapCharRec ch164 = new BitmapCharRec(7,6,-1,-3,9,ch164data);
+
+/* char: 0xa3 */
+
+static final byte[] ch163data = {
+(byte) 0x5c,(byte) 0xa2,(byte) 0x60,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x22,(byte) 0x1c,
+};
+
+static final BitmapCharRec ch163 = new BitmapCharRec(7,10,-1,0,9,ch163data);
+
+/* char: 0xa2 */
+
+static final byte[] ch162data = {
+(byte) 0x40,(byte) 0x78,(byte) 0xa4,(byte) 0xa0,(byte) 0x90,(byte) 0x94,(byte) 0x78,(byte) 0x8,
+};
+
+static final BitmapCharRec ch162 = new BitmapCharRec(6,8,-1,0,9,ch162data);
+
+/* char: 0xa1 */
+
+static final byte[] ch161data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch161 = new BitmapCharRec(1,11,-4,0,9,ch161data);
+
+/* char: 0x7e '~' */
+
+static final byte[] ch126data = {
+(byte) 0x8c,(byte) 0x92,(byte) 0x62,
+};
+
+static final BitmapCharRec ch126 = new BitmapCharRec(7,3,-1,-7,9,ch126data);
+
+/* char: 0x7d '}' */
+
+static final byte[] ch125data = {
+(byte) 0xe0,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x20,(byte) 0x18,(byte) 0x18,(byte) 0x20,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch125 = new BitmapCharRec(5,12,-1,1,9,ch125data);
+
+/* char: 0x7c '|' */
+
+static final byte[] ch124data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch124 = new BitmapCharRec(1,12,-4,1,9,ch124data);
+
+/* char: 0x7b '{' */
+
+static final byte[] ch123data = {
+(byte) 0x38,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0xc0,(byte) 0xc0,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x38,
+};
+
+static final BitmapCharRec ch123 = new BitmapCharRec(5,12,-3,1,9,ch123data);
+
+/* char: 0x7a 'z' */
+
+static final byte[] ch122data = {
+(byte) 0xfe,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch122 = new BitmapCharRec(7,7,-1,0,9,ch122data);
+
+/* char: 0x79 'y' */
+
+static final byte[] ch121data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x4,(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,
+};
+
+static final BitmapCharRec ch121 = new BitmapCharRec(6,10,-1,3,9,ch121data);
+
+/* char: 0x78 'x' */
+
+static final byte[] ch120data = {
+(byte) 0x82,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0x82,
+};
+
+static final BitmapCharRec ch120 = new BitmapCharRec(7,7,-1,0,9,ch120data);
+
+/* char: 0x77 'w' */
+
+static final byte[] ch119data = {
+(byte) 0x44,(byte) 0xaa,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch119 = new BitmapCharRec(7,7,-1,0,9,ch119data);
+
+/* char: 0x76 'v' */
+
+static final byte[] ch118data = {
+(byte) 0x10,(byte) 0x28,(byte) 0x28,(byte) 0x44,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch118 = new BitmapCharRec(7,7,-1,0,9,ch118data);
+
+/* char: 0x75 'u' */
+
+static final byte[] ch117data = {
+(byte) 0x7a,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,
+};
+
+static final BitmapCharRec ch117 = new BitmapCharRec(7,7,-1,0,9,ch117data);
+
+/* char: 0x74 't' */
+
+static final byte[] ch116data = {
+(byte) 0x1c,(byte) 0x22,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xfc,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch116 = new BitmapCharRec(7,9,-1,0,9,ch116data);
+
+/* char: 0x73 's' */
+
+static final byte[] ch115data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x2,(byte) 0x7c,(byte) 0x80,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch115 = new BitmapCharRec(7,7,-1,0,9,ch115data);
+
+/* char: 0x72 'r' */
+
+static final byte[] ch114data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x42,(byte) 0x62,(byte) 0x9c,
+};
+
+static final BitmapCharRec ch114 = new BitmapCharRec(7,7,-1,0,9,ch114data);
+
+/* char: 0x71 'q' */
+
+static final byte[] ch113data = {
+(byte) 0x2,(byte) 0x2,(byte) 0x2,(byte) 0x7a,(byte) 0x86,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x86,(byte) 0x7a,
+};
+
+static final BitmapCharRec ch113 = new BitmapCharRec(7,10,-1,3,9,ch113data);
+
+/* char: 0x70 'p' */
+
+static final byte[] ch112data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xbc,(byte) 0xc2,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xc2,(byte) 0xbc,
+};
+
+static final BitmapCharRec ch112 = new BitmapCharRec(7,10,-1,3,9,ch112data);
+
+/* char: 0x6f 'o' */
+
+static final byte[] ch111data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch111 = new BitmapCharRec(7,7,-1,0,9,ch111data);
+
+/* char: 0x6e 'n' */
+
+static final byte[] ch110data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xc2,(byte) 0xbc,
+};
+
+static final BitmapCharRec ch110 = new BitmapCharRec(7,7,-1,0,9,ch110data);
+
+/* char: 0x6d 'm' */
+
+static final byte[] ch109data = {
+(byte) 0x82,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0xec,
+};
+
+static final BitmapCharRec ch109 = new BitmapCharRec(7,7,-1,0,9,ch109data);
+
+/* char: 0x6c 'l' */
+
+static final byte[] ch108data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch108 = new BitmapCharRec(5,10,-2,0,9,ch108data);
+
+/* char: 0x6b 'k' */
+
+static final byte[] ch107data = {
+(byte) 0x82,(byte) 0x8c,(byte) 0xb0,(byte) 0xc0,(byte) 0xb0,(byte) 0x8c,(byte) 0x82,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch107 = new BitmapCharRec(7,10,-1,0,9,ch107data);
+
+/* char: 0x6a 'j' */
+
+static final byte[] ch106data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0x1c,(byte) 0x0,(byte) 0x0,(byte) 0xc,
+};
+
+static final BitmapCharRec ch106 = new BitmapCharRec(6,13,-1,3,9,ch106data);
+
+/* char: 0x69 'i' */
+
+static final byte[] ch105data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch105 = new BitmapCharRec(5,10,-2,0,9,ch105data);
+
+/* char: 0x68 'h' */
+
+static final byte[] ch104data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xc2,(byte) 0xbc,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch104 = new BitmapCharRec(7,10,-1,0,9,ch104data);
+
+/* char: 0x67 'g' */
+
+static final byte[] ch103data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x80,(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x7a,
+};
+
+static final BitmapCharRec ch103 = new BitmapCharRec(7,10,-1,3,9,ch103data);
+
+/* char: 0x66 'f' */
+
+static final byte[] ch102data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x22,(byte) 0x22,(byte) 0x1c,
+};
+
+static final BitmapCharRec ch102 = new BitmapCharRec(7,10,-1,0,9,ch102data);
+
+/* char: 0x65 'e' */
+
+static final byte[] ch101data = {
+(byte) 0x7c,(byte) 0x80,(byte) 0x80,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch101 = new BitmapCharRec(7,7,-1,0,9,ch101data);
+
+/* char: 0x64 'd' */
+
+static final byte[] ch100data = {
+(byte) 0x7a,(byte) 0x86,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x86,(byte) 0x7a,(byte) 0x2,(byte) 0x2,(byte) 0x2,
+};
+
+static final BitmapCharRec ch100 = new BitmapCharRec(7,10,-1,0,9,ch100data);
+
+/* char: 0x63 'c' */
+
+static final byte[] ch99data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch99 = new BitmapCharRec(7,7,-1,0,9,ch99data);
+
+/* char: 0x62 'b' */
+
+static final byte[] ch98data = {
+(byte) 0xbc,(byte) 0xc2,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xc2,(byte) 0xbc,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch98 = new BitmapCharRec(7,10,-1,0,9,ch98data);
+
+/* char: 0x61 'a' */
+
+static final byte[] ch97data = {
+(byte) 0x7a,(byte) 0x86,(byte) 0x82,(byte) 0x7e,(byte) 0x2,(byte) 0x2,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch97 = new BitmapCharRec(7,7,-1,0,9,ch97data);
+
+/* char: 0x60 '`' */
+
+static final byte[] ch96data = {
+(byte) 0x10,(byte) 0x20,(byte) 0x40,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch96 = new BitmapCharRec(4,4,-3,-6,9,ch96data);
+
+/* char: 0x5f '_' */
+
+static final byte[] ch95data = {
+(byte) 0xff,
+};
+
+static final BitmapCharRec ch95 = new BitmapCharRec(8,1,0,1,9,ch95data);
+
+/* char: 0x5e '^' */
+
+static final byte[] ch94data = {
+(byte) 0x82,(byte) 0x44,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch94 = new BitmapCharRec(7,4,-1,-6,9,ch94data);
+
+/* char: 0x5d ']' */
+
+static final byte[] ch93data = {
+(byte) 0xf0,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch93 = new BitmapCharRec(4,12,-2,1,9,ch93data);
+
+/* char: 0x5c '\' */
+
+static final byte[] ch92data = {
+(byte) 0x2,(byte) 0x4,(byte) 0x4,(byte) 0x8,(byte) 0x10,(byte) 0x10,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch92 = new BitmapCharRec(7,10,-1,0,9,ch92data);
+
+/* char: 0x5b '[' */
+
+static final byte[] ch91data = {
+(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch91 = new BitmapCharRec(4,12,-3,1,9,ch91data);
+
+/* char: 0x5a 'Z' */
+
+static final byte[] ch90data = {
+(byte) 0xfe,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0x2,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch90 = new BitmapCharRec(7,10,-1,0,9,ch90data);
+
+/* char: 0x59 'Y' */
+
+static final byte[] ch89data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch89 = new BitmapCharRec(7,10,-1,0,9,ch89data);
+
+/* char: 0x58 'X' */
+
+static final byte[] ch88data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch88 = new BitmapCharRec(7,10,-1,0,9,ch88data);
+
+/* char: 0x57 'W' */
+
+static final byte[] ch87data = {
+(byte) 0x44,(byte) 0xaa,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch87 = new BitmapCharRec(7,10,-1,0,9,ch87data);
+
+/* char: 0x56 'V' */
+
+static final byte[] ch86data = {
+(byte) 0x10,(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0x82,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch86 = new BitmapCharRec(7,10,-1,0,9,ch86data);
+
+/* char: 0x55 'U' */
+
+static final byte[] ch85data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch85 = new BitmapCharRec(7,10,-1,0,9,ch85data);
+
+/* char: 0x54 'T' */
+
+static final byte[] ch84data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch84 = new BitmapCharRec(7,10,-1,0,9,ch84data);
+
+/* char: 0x53 'S' */
+
+static final byte[] ch83data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x2,(byte) 0xc,(byte) 0x70,(byte) 0x80,(byte) 0x82,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch83 = new BitmapCharRec(7,10,-1,0,9,ch83data);
+
+/* char: 0x52 'R' */
+
+static final byte[] ch82data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x84,(byte) 0x88,(byte) 0x90,(byte) 0xfc,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch82 = new BitmapCharRec(7,10,-1,0,9,ch82data);
+
+/* char: 0x51 'Q' */
+
+static final byte[] ch81data = {
+(byte) 0x6,(byte) 0x8,(byte) 0x7c,(byte) 0x92,(byte) 0xa2,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch81 = new BitmapCharRec(7,12,-1,2,9,ch81data);
+
+/* char: 0x50 'P' */
+
+static final byte[] ch80data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch80 = new BitmapCharRec(7,10,-1,0,9,ch80data);
+
+/* char: 0x4f 'O' */
+
+static final byte[] ch79data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch79 = new BitmapCharRec(7,10,-1,0,9,ch79data);
+
+/* char: 0x4e 'N' */
+
+static final byte[] ch78data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x86,(byte) 0x8a,(byte) 0x92,(byte) 0xa2,(byte) 0xc2,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch78 = new BitmapCharRec(7,10,-1,0,9,ch78data);
+
+/* char: 0x4d 'M' */
+
+static final byte[] ch77data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x92,(byte) 0x92,(byte) 0xaa,(byte) 0xaa,(byte) 0xc6,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch77 = new BitmapCharRec(7,10,-1,0,9,ch77data);
+
+/* char: 0x4c 'L' */
+
+static final byte[] ch76data = {
+(byte) 0xfe,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch76 = new BitmapCharRec(7,10,-1,0,9,ch76data);
+
+/* char: 0x4b 'K' */
+
+static final byte[] ch75data = {
+(byte) 0x82,(byte) 0x84,(byte) 0x88,(byte) 0x90,(byte) 0xa0,(byte) 0xe0,(byte) 0x90,(byte) 0x88,(byte) 0x84,(byte) 0x82,
+};
+
+static final BitmapCharRec ch75 = new BitmapCharRec(7,10,-1,0,9,ch75data);
+
+/* char: 0x4a 'J' */
+
+static final byte[] ch74data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0x1e,
+};
+
+static final BitmapCharRec ch74 = new BitmapCharRec(7,10,-1,0,9,ch74data);
+
+/* char: 0x49 'I' */
+
+static final byte[] ch73data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch73 = new BitmapCharRec(5,10,-2,0,9,ch73data);
+
+/* char: 0x48 'H' */
+
+static final byte[] ch72data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch72 = new BitmapCharRec(7,10,-1,0,9,ch72data);
+
+/* char: 0x47 'G' */
+
+static final byte[] ch71data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x8e,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch71 = new BitmapCharRec(7,10,-1,0,9,ch71data);
+
+/* char: 0x46 'F' */
+
+static final byte[] ch70data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x78,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch70 = new BitmapCharRec(7,10,-1,0,9,ch70data);
+
+/* char: 0x45 'E' */
+
+static final byte[] ch69data = {
+(byte) 0xfe,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x78,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch69 = new BitmapCharRec(7,10,-1,0,9,ch69data);
+
+/* char: 0x44 'D' */
+
+static final byte[] ch68data = {
+(byte) 0xfc,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch68 = new BitmapCharRec(7,10,-1,0,9,ch68data);
+
+/* char: 0x43 'C' */
+
+static final byte[] ch67data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch67 = new BitmapCharRec(7,10,-1,0,9,ch67data);
+
+/* char: 0x42 'B' */
+
+static final byte[] ch66data = {
+(byte) 0xfc,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0x7c,(byte) 0x42,(byte) 0x42,(byte) 0x42,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch66 = new BitmapCharRec(7,10,-1,0,9,ch66data);
+
+/* char: 0x41 'A' */
+
+static final byte[] ch65data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch65 = new BitmapCharRec(7,10,-1,0,9,ch65data);
+
+/* char: 0x40 '@' */
+
+static final byte[] ch64data = {
+(byte) 0x7c,(byte) 0x80,(byte) 0x80,(byte) 0x9a,(byte) 0xa6,(byte) 0xa2,(byte) 0x9e,(byte) 0x82,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch64 = new BitmapCharRec(7,10,-1,0,9,ch64data);
+
+/* char: 0x3f '?' */
+
+static final byte[] ch63data = {
+(byte) 0x10,(byte) 0x0,(byte) 0x10,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0x2,(byte) 0x82,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch63 = new BitmapCharRec(7,10,-1,0,9,ch63data);
+
+/* char: 0x3e '>' */
+
+static final byte[] ch62data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x8,(byte) 0x10,(byte) 0x20,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch62 = new BitmapCharRec(5,10,-2,0,9,ch62data);
+
+/* char: 0x3d '=' */
+
+static final byte[] ch61data = {
+(byte) 0xfe,(byte) 0x0,(byte) 0x0,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch61 = new BitmapCharRec(7,4,-1,-2,9,ch61data);
+
+/* char: 0x3c '<' */
+
+static final byte[] ch60data = {
+(byte) 0x8,(byte) 0x10,(byte) 0x20,(byte) 0x40,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch60 = new BitmapCharRec(5,10,-2,0,9,ch60data);
+
+/* char: 0x3b ';' */
+
+static final byte[] ch59data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch59 = new BitmapCharRec(2,10,-4,3,9,ch59data);
+
+/* char: 0x3a ':' */
+
+static final byte[] ch58data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch58 = new BitmapCharRec(2,7,-4,0,9,ch58data);
+
+/* char: 0x39 '9' */
+
+static final byte[] ch57data = {
+(byte) 0x78,(byte) 0x4,(byte) 0x2,(byte) 0x2,(byte) 0x7a,(byte) 0x86,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch57 = new BitmapCharRec(7,10,-1,0,9,ch57data);
+
+/* char: 0x38 '8' */
+
+static final byte[] ch56data = {
+(byte) 0x38,(byte) 0x44,(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x38,(byte) 0x44,(byte) 0x82,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch56 = new BitmapCharRec(7,10,-1,0,9,ch56data);
+
+/* char: 0x37 '7' */
+
+static final byte[] ch55data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0x2,(byte) 0x2,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch55 = new BitmapCharRec(7,10,-1,0,9,ch55data);
+
+/* char: 0x36 '6' */
+
+static final byte[] ch54data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xc2,(byte) 0xbc,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch54 = new BitmapCharRec(7,10,-1,0,9,ch54data);
+
+/* char: 0x35 '5' */
+
+static final byte[] ch53data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x2,(byte) 0x2,(byte) 0x2,(byte) 0xc2,(byte) 0xbc,(byte) 0x80,(byte) 0x80,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch53 = new BitmapCharRec(7,10,-1,0,9,ch53data);
+
+/* char: 0x34 '4' */
+
+static final byte[] ch52data = {
+(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0xfe,(byte) 0x84,(byte) 0x44,(byte) 0x24,(byte) 0x14,(byte) 0xc,(byte) 0x4,
+};
+
+static final BitmapCharRec ch52 = new BitmapCharRec(7,10,-1,0,9,ch52data);
+
+/* char: 0x33 '3' */
+
+static final byte[] ch51data = {
+(byte) 0x7c,(byte) 0x82,(byte) 0x2,(byte) 0x2,(byte) 0x2,(byte) 0x1c,(byte) 0x8,(byte) 0x4,(byte) 0x2,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch51 = new BitmapCharRec(7,10,-1,0,9,ch51data);
+
+/* char: 0x32 '2' */
+
+static final byte[] ch50data = {
+(byte) 0xfe,(byte) 0x80,(byte) 0x40,(byte) 0x30,(byte) 0x8,(byte) 0x4,(byte) 0x2,(byte) 0x82,(byte) 0x82,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch50 = new BitmapCharRec(7,10,-1,0,9,ch50data);
+
+/* char: 0x31 '1' */
+
+static final byte[] ch49data = {
+(byte) 0xfe,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x90,(byte) 0x50,(byte) 0x30,(byte) 0x10,
+};
+
+static final BitmapCharRec ch49 = new BitmapCharRec(7,10,-1,0,9,ch49data);
+
+/* char: 0x30 '0' */
+
+static final byte[] ch48data = {
+(byte) 0x38,(byte) 0x44,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch48 = new BitmapCharRec(7,10,-1,0,9,ch48data);
+
+/* char: 0x2f '/' */
+
+static final byte[] ch47data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0x4,(byte) 0x2,
+};
+
+static final BitmapCharRec ch47 = new BitmapCharRec(7,10,-1,0,9,ch47data);
+
+/* char: 0x2e '.' */
+
+static final byte[] ch46data = {
+(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch46 = new BitmapCharRec(2,2,-4,0,9,ch46data);
+
+/* char: 0x2d '-' */
+
+static final byte[] ch45data = {
+(byte) 0xfe,
+};
+
+static final BitmapCharRec ch45 = new BitmapCharRec(7,1,-1,-4,9,ch45data);
+
+/* char: 0x2c ',' */
+
+static final byte[] ch44data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch44 = new BitmapCharRec(2,5,-4,3,9,ch44data);
+
+/* char: 0x2b '+' */
+
+static final byte[] ch43data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xfe,(byte) 0x10,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch43 = new BitmapCharRec(7,7,-1,-1,9,ch43data);
+
+/* char: 0x2a '*' */
+
+static final byte[] ch42data = {
+(byte) 0x10,(byte) 0x92,(byte) 0x54,(byte) 0x38,(byte) 0x54,(byte) 0x92,(byte) 0x10,
+};
+
+static final BitmapCharRec ch42 = new BitmapCharRec(7,7,-1,-1,9,ch42data);
+
+/* char: 0x29 ')' */
+
+static final byte[] ch41data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch41 = new BitmapCharRec(3,12,-3,1,9,ch41data);
+
+/* char: 0x28 '(' */
+
+static final byte[] ch40data = {
+(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch40 = new BitmapCharRec(3,12,-3,1,9,ch40data);
+
+/* char: 0x27 ''' */
+
+static final byte[] ch39data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x30,
+};
+
+static final BitmapCharRec ch39 = new BitmapCharRec(4,4,-3,-6,9,ch39data);
+
+/* char: 0x26 '&' */
+
+static final byte[] ch38data = {
+(byte) 0x62,(byte) 0x94,(byte) 0x88,(byte) 0x94,(byte) 0x62,(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch38 = new BitmapCharRec(7,10,-1,0,9,ch38data);
+
+/* char: 0x25 '%' */
+
+static final byte[] ch37data = {
+(byte) 0x84,(byte) 0x4a,(byte) 0x4a,(byte) 0x24,(byte) 0x10,(byte) 0x10,(byte) 0x48,(byte) 0xa4,(byte) 0xa4,(byte) 0x42,
+};
+
+static final BitmapCharRec ch37 = new BitmapCharRec(7,10,-1,0,9,ch37data);
+
+/* char: 0x24 '$' */
+
+static final byte[] ch36data = {
+(byte) 0x10,(byte) 0x7c,(byte) 0x92,(byte) 0x12,(byte) 0x12,(byte) 0x14,(byte) 0x38,(byte) 0x50,(byte) 0x90,(byte) 0x92,(byte) 0x7c,(byte) 0x10,
+};
+
+static final BitmapCharRec ch36 = new BitmapCharRec(7,12,-1,1,9,ch36data);
+
+/* char: 0x23 '#' */
+
+static final byte[] ch35data = {
+(byte) 0x48,(byte) 0x48,(byte) 0xfc,(byte) 0x48,(byte) 0x48,(byte) 0xfc,(byte) 0x48,(byte) 0x48,
+};
+
+static final BitmapCharRec ch35 = new BitmapCharRec(6,8,-1,-1,9,ch35data);
+
+/* char: 0x22 '"' */
+
+static final byte[] ch34data = {
+(byte) 0x90,(byte) 0x90,(byte) 0x90,
+};
+
+static final BitmapCharRec ch34 = new BitmapCharRec(4,3,-3,-7,9,ch34data);
+
+/* char: 0x21 '!' */
+
+static final byte[] ch33data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch33 = new BitmapCharRec(1,11,-4,0,9,ch33data);
+
+/* char: 0x1f */
+
+static final byte[] ch31data = {
+(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch31 = new BitmapCharRec(2,2,-4,-2,9,ch31data);
+
+/* char: 0x1e */
+
+static final byte[] ch30data = {
+(byte) 0x5c,(byte) 0xa2,(byte) 0x60,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x22,(byte) 0x1c,
+};
+
+static final BitmapCharRec ch30 = new BitmapCharRec(7,10,-1,0,9,ch30data);
+
+/* char: 0x1d */
+
+static final byte[] ch29data = {
+(byte) 0x80,(byte) 0x40,(byte) 0xfe,(byte) 0x10,(byte) 0xfe,(byte) 0x4,(byte) 0x2,
+};
+
+static final BitmapCharRec ch29 = new BitmapCharRec(7,7,-1,0,9,ch29data);
+
+/* char: 0x1c */
+
+static final byte[] ch28data = {
+(byte) 0x44,(byte) 0x24,(byte) 0x24,(byte) 0x24,(byte) 0x24,(byte) 0x24,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch28 = new BitmapCharRec(7,7,-1,0,9,ch28data);
+
+/* char: 0x1b */
+
+static final byte[] ch27data = {
+(byte) 0xfe,(byte) 0x0,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x8,(byte) 0x10,(byte) 0x20,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch27 = new BitmapCharRec(7,12,-1,2,9,ch27data);
+
+/* char: 0x1a */
+
+static final byte[] ch26data = {
+(byte) 0xfc,(byte) 0x0,(byte) 0x4,(byte) 0x8,(byte) 0x10,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x4,
+};
+
+static final BitmapCharRec ch26 = new BitmapCharRec(6,12,-2,2,9,ch26data);
+
+/* char: 0x19 */
+
+static final byte[] ch25data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch25 = new BitmapCharRec(1,15,-4,3,9,ch25data);
+
+/* char: 0x18 */
+
+static final byte[] ch24data = {
+(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0xff,(byte) 0x80,
+};
+
+static final BitmapCharRec ch24 = new BitmapCharRec(9,7,0,3,9,ch24data);
+
+/* char: 0x17 */
+
+static final byte[] ch23data = {
+(byte) 0xff,(byte) 0x80,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,
+(byte) 0x8,(byte) 0x0,
+};
+
+static final BitmapCharRec ch23 = new BitmapCharRec(9,9,0,-3,9,ch23data);
+
+/* char: 0x16 */
+
+static final byte[] ch22data = {
+(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0xf8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,
+};
+
+static final BitmapCharRec ch22 = new BitmapCharRec(5,15,0,3,9,ch22data);
+
+/* char: 0x15 */
+
+static final byte[] ch21data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch21 = new BitmapCharRec(5,15,-4,3,9,ch21data);
+
+/* char: 0x14 */
+
+static final byte[] ch20data = {
+(byte) 0xff,(byte) 0x80,
+};
+
+static final BitmapCharRec ch20 = new BitmapCharRec(9,1,0,1,9,ch20data);
+
+/* char: 0x13 */
+
+static final byte[] ch19data = {
+(byte) 0xff,(byte) 0x80,
+};
+
+static final BitmapCharRec ch19 = new BitmapCharRec(9,1,0,-1,9,ch19data);
+
+/* char: 0x12 */
+
+static final byte[] ch18data = {
+(byte) 0xff,(byte) 0x80,
+};
+
+static final BitmapCharRec ch18 = new BitmapCharRec(9,1,0,-3,9,ch18data);
+
+/* char: 0x11 */
+
+static final byte[] ch17data = {
+(byte) 0xff,(byte) 0x80,
+};
+
+static final BitmapCharRec ch17 = new BitmapCharRec(9,1,0,-5,9,ch17data);
+
+/* char: 0x10 */
+
+static final byte[] ch16data = {
+(byte) 0xff,(byte) 0x80,
+};
+
+static final BitmapCharRec ch16 = new BitmapCharRec(9,1,0,-7,9,ch16data);
+
+/* char: 0xf */
+
+static final byte[] ch15data = {
+(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0x8,(byte) 0x0,
+(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,
+};
+
+static final BitmapCharRec ch15 = new BitmapCharRec(9,15,0,3,9,ch15data);
+
+/* char: 0xe */
+
+static final byte[] ch14data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch14 = new BitmapCharRec(5,9,-4,-3,9,ch14data);
+
+/* char: 0xd */
+
+static final byte[] ch13data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch13 = new BitmapCharRec(5,7,-4,3,9,ch13data);
+
+/* char: 0xc */
+
+static final byte[] ch12data = {
+(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch12 = new BitmapCharRec(5,7,0,3,9,ch12data);
+
+/* char: 0xb */
+
+static final byte[] ch11data = {
+(byte) 0xf8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,
+};
+
+static final BitmapCharRec ch11 = new BitmapCharRec(5,9,0,-3,9,ch11data);
+
+/* char: 0xa */
+
+static final byte[] ch10data = {
+(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x3e,(byte) 0x0,(byte) 0x20,(byte) 0x50,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch10 = new BitmapCharRec(7,10,-1,2,9,ch10data);
+
+/* char: 0x9 */
+
+static final byte[] ch9data = {
+(byte) 0x3e,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x88,(byte) 0x98,(byte) 0xa8,(byte) 0xc8,(byte) 0x88,
+};
+
+static final BitmapCharRec ch9 = new BitmapCharRec(7,10,-1,2,9,ch9data);
+
+/* char: 0x8 */
+
+static final byte[] ch8data = {
+(byte) 0xfe,(byte) 0x10,(byte) 0x10,(byte) 0xfe,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch8 = new BitmapCharRec(7,6,-1,0,9,ch8data);
+
+/* char: 0x7 */
+
+static final byte[] ch7data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch7 = new BitmapCharRec(5,4,-2,-6,9,ch7data);
+
+/* char: 0x6 */
+
+static final byte[] ch6data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x3c,(byte) 0x20,(byte) 0x3e,(byte) 0x0,(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch6 = new BitmapCharRec(7,10,-1,2,9,ch6data);
+
+/* char: 0x5 */
+
+static final byte[] ch5data = {
+(byte) 0x22,(byte) 0x22,(byte) 0x3c,(byte) 0x22,(byte) 0x3c,(byte) 0x0,(byte) 0x78,(byte) 0x80,(byte) 0x80,(byte) 0x78,
+};
+
+static final BitmapCharRec ch5 = new BitmapCharRec(7,10,-1,2,9,ch5data);
+
+/* char: 0x4 */
+
+static final byte[] ch4data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x1c,(byte) 0x10,(byte) 0x1e,(byte) 0x80,(byte) 0x80,(byte) 0xe0,(byte) 0x80,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch4 = new BitmapCharRec(7,10,-1,2,9,ch4data);
+
+/* char: 0x3 */
+
+static final byte[] ch3data = {
+(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x3e,(byte) 0x0,(byte) 0x88,(byte) 0x88,(byte) 0xf8,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch3 = new BitmapCharRec(7,10,-1,2,9,ch3data);
+
+/* char: 0x2 */
+
+static final byte[] ch2data = {
+(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,(byte) 0x55,(byte) 0xaa,
+};
+
+static final BitmapCharRec ch2 = new BitmapCharRec(8,14,0,3,9,ch2data);
+
+/* char: 0x1 */
+
+static final byte[] ch1data = {
+(byte) 0x10,(byte) 0x38,(byte) 0x7c,(byte) 0xfe,(byte) 0x7c,(byte) 0x38,(byte) 0x10,
+};
+
+static final BitmapCharRec ch1 = new BitmapCharRec(7,7,-1,0,9,ch1data);
+
+static final BitmapCharRec[] chars = {
+ch0,
+ch1,
+ch2,
+ch3,
+ch4,
+ch5,
+ch6,
+ch7,
+ch8,
+ch9,
+ch10,
+ch11,
+ch12,
+ch13,
+ch14,
+ch15,
+ch16,
+ch17,
+ch18,
+ch19,
+ch20,
+ch21,
+ch22,
+ch23,
+ch24,
+ch25,
+ch26,
+ch27,
+ch28,
+ch29,
+ch30,
+ch31,
+ch32,
+ch33,
+ch34,
+ch35,
+ch36,
+ch37,
+ch38,
+ch39,
+ch40,
+ch41,
+ch42,
+ch43,
+ch44,
+ch45,
+ch46,
+ch47,
+ch48,
+ch49,
+ch50,
+ch51,
+ch52,
+ch53,
+ch54,
+ch55,
+ch56,
+ch57,
+ch58,
+ch59,
+ch60,
+ch61,
+ch62,
+ch63,
+ch64,
+ch65,
+ch66,
+ch67,
+ch68,
+ch69,
+ch70,
+ch71,
+ch72,
+ch73,
+ch74,
+ch75,
+ch76,
+ch77,
+ch78,
+ch79,
+ch80,
+ch81,
+ch82,
+ch83,
+ch84,
+ch85,
+ch86,
+ch87,
+ch88,
+ch89,
+ch90,
+ch91,
+ch92,
+ch93,
+ch94,
+ch95,
+ch96,
+ch97,
+ch98,
+ch99,
+ch100,
+ch101,
+ch102,
+ch103,
+ch104,
+ch105,
+ch106,
+ch107,
+ch108,
+ch109,
+ch110,
+ch111,
+ch112,
+ch113,
+ch114,
+ch115,
+ch116,
+ch117,
+ch118,
+ch119,
+ch120,
+ch121,
+ch122,
+ch123,
+ch124,
+ch125,
+ch126,
+ch127,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+ch160,
+ch161,
+ch162,
+ch163,
+ch164,
+ch165,
+ch166,
+ch167,
+ch168,
+ch169,
+ch170,
+ch171,
+ch172,
+ch173,
+ch174,
+ch175,
+ch176,
+ch177,
+ch178,
+ch179,
+ch180,
+ch181,
+ch182,
+ch183,
+ch184,
+ch185,
+ch186,
+ch187,
+ch188,
+ch189,
+ch190,
+ch191,
+ch192,
+ch193,
+ch194,
+ch195,
+ch196,
+ch197,
+ch198,
+ch199,
+ch200,
+ch201,
+ch202,
+ch203,
+ch204,
+ch205,
+ch206,
+ch207,
+ch208,
+ch209,
+ch210,
+ch211,
+ch212,
+ch213,
+ch214,
+ch215,
+ch216,
+ch217,
+ch218,
+ch219,
+ch220,
+ch221,
+ch222,
+ch223,
+ch224,
+ch225,
+ch226,
+ch227,
+ch228,
+ch229,
+ch230,
+ch231,
+ch232,
+ch233,
+ch234,
+ch235,
+ch236,
+ch237,
+ch238,
+ch239,
+ch240,
+ch241,
+ch242,
+ch243,
+ch244,
+ch245,
+ch246,
+ch247,
+ch248,
+ch249,
+ch250,
+ch251,
+ch252,
+ch253,
+ch254,
+ch255,
+};
+
+ public static final BitmapFontRec glutBitmap9By15 = new BitmapFontRec("-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1",
+ 256,
+ 0,
+ chars);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica10.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica10.java
new file mode 100644
index 000000000..b9c7e6e50
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica10.java
@@ -0,0 +1,1798 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+class GLUTBitmapHelvetica10 {
+
+/* GENERATED FILE -- DO NOT MODIFY */
+
+/* char: 0xff */
+
+static final byte[] ch255data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x60,(byte) 0xa0,(byte) 0xa0,(byte) 0x90,(byte) 0x90,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch255 = new BitmapCharRec(4,10,0,2,5,ch255data);
+
+/* char: 0xfe */
+
+static final byte[] ch254data = {
+(byte) 0x80,(byte) 0x80,(byte) 0xb0,(byte) 0xc8,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch254 = new BitmapCharRec(5,10,0,2,6,ch254data);
+
+/* char: 0xfd */
+
+static final byte[] ch253data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x60,(byte) 0xa0,(byte) 0xa0,(byte) 0x90,(byte) 0x90,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch253 = new BitmapCharRec(4,11,0,2,5,ch253data);
+
+/* char: 0xfc */
+
+static final byte[] ch252data = {
+(byte) 0x70,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch252 = new BitmapCharRec(4,8,0,0,5,ch252data);
+
+/* char: 0xfb */
+
+static final byte[] ch251data = {
+(byte) 0x70,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch251 = new BitmapCharRec(4,9,0,0,5,ch251data);
+
+/* char: 0xfa */
+
+static final byte[] ch250data = {
+(byte) 0x70,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x0,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch250 = new BitmapCharRec(4,9,0,0,5,ch250data);
+
+/* char: 0xf9 */
+
+static final byte[] ch249data = {
+(byte) 0x70,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch249 = new BitmapCharRec(4,9,0,0,5,ch249data);
+
+/* char: 0xf8 */
+
+static final byte[] ch248data = {
+(byte) 0x70,(byte) 0x88,(byte) 0xc8,(byte) 0xa8,(byte) 0x98,(byte) 0x74,
+};
+
+static final BitmapCharRec ch248 = new BitmapCharRec(6,6,0,0,6,ch248data);
+
+/* char: 0xf7 */
+
+static final byte[] ch247data = {
+(byte) 0x20,(byte) 0x0,(byte) 0xf8,(byte) 0x0,(byte) 0x20,
+};
+
+static final BitmapCharRec ch247 = new BitmapCharRec(5,5,0,-1,6,ch247data);
+
+/* char: 0xf6 */
+
+static final byte[] ch246data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch246 = new BitmapCharRec(5,8,0,0,6,ch246data);
+
+/* char: 0xf5 */
+
+static final byte[] ch245data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch245 = new BitmapCharRec(5,9,0,0,6,ch245data);
+
+/* char: 0xf4 */
+
+static final byte[] ch244data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch244 = new BitmapCharRec(5,9,0,0,6,ch244data);
+
+/* char: 0xf3 */
+
+static final byte[] ch243data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch243 = new BitmapCharRec(5,9,0,0,6,ch243data);
+
+/* char: 0xf2 */
+
+static final byte[] ch242data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch242 = new BitmapCharRec(5,9,0,0,6,ch242data);
+
+/* char: 0xf1 */
+
+static final byte[] ch241data = {
+(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0xe0,(byte) 0x0,(byte) 0xa0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch241 = new BitmapCharRec(4,9,0,0,5,ch241data);
+
+/* char: 0xf0 */
+
+static final byte[] ch240data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x78,(byte) 0x90,(byte) 0x60,(byte) 0x50,
+};
+
+static final BitmapCharRec ch240 = new BitmapCharRec(5,9,0,0,6,ch240data);
+
+/* char: 0xef */
+
+static final byte[] ch239data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch239 = new BitmapCharRec(3,8,0,0,2,ch239data);
+
+/* char: 0xee */
+
+static final byte[] ch238data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch238 = new BitmapCharRec(3,9,1,0,2,ch238data);
+
+/* char: 0xed */
+
+static final byte[] ch237data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch237 = new BitmapCharRec(2,9,0,0,2,ch237data);
+
+/* char: 0xec */
+
+static final byte[] ch236data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch236 = new BitmapCharRec(2,9,1,0,2,ch236data);
+
+/* char: 0xeb */
+
+static final byte[] ch235data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x80,(byte) 0xf0,(byte) 0x90,(byte) 0x60,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch235 = new BitmapCharRec(4,8,0,0,5,ch235data);
+
+/* char: 0xea */
+
+static final byte[] ch234data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x80,(byte) 0xf0,(byte) 0x90,(byte) 0x60,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch234 = new BitmapCharRec(4,9,0,0,5,ch234data);
+
+/* char: 0xe9 */
+
+static final byte[] ch233data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x80,(byte) 0xf0,(byte) 0x90,(byte) 0x60,(byte) 0x0,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch233 = new BitmapCharRec(4,9,0,0,5,ch233data);
+
+/* char: 0xe8 */
+
+static final byte[] ch232data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x80,(byte) 0xf0,(byte) 0x90,(byte) 0x60,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch232 = new BitmapCharRec(4,9,0,0,5,ch232data);
+
+/* char: 0xe7 */
+
+static final byte[] ch231data = {
+(byte) 0x60,(byte) 0x20,(byte) 0x60,(byte) 0x90,(byte) 0x80,(byte) 0x80,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch231 = new BitmapCharRec(4,8,0,2,5,ch231data);
+
+/* char: 0xe6 */
+
+static final byte[] ch230data = {
+(byte) 0x6c,(byte) 0x92,(byte) 0x90,(byte) 0x7e,(byte) 0x12,(byte) 0xec,
+};
+
+static final BitmapCharRec ch230 = new BitmapCharRec(7,6,0,0,8,ch230data);
+
+/* char: 0xe5 */
+
+static final byte[] ch229data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x70,(byte) 0x10,(byte) 0xe0,(byte) 0x20,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch229 = new BitmapCharRec(5,9,0,0,5,ch229data);
+
+/* char: 0xe4 */
+
+static final byte[] ch228data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x70,(byte) 0x10,(byte) 0xe0,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch228 = new BitmapCharRec(5,8,0,0,5,ch228data);
+
+/* char: 0xe3 */
+
+static final byte[] ch227data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x70,(byte) 0x10,(byte) 0xe0,(byte) 0x0,(byte) 0xa0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch227 = new BitmapCharRec(5,9,0,0,5,ch227data);
+
+/* char: 0xe2 */
+
+static final byte[] ch226data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x70,(byte) 0x10,(byte) 0xe0,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch226 = new BitmapCharRec(5,9,0,0,5,ch226data);
+
+/* char: 0xe1 */
+
+static final byte[] ch225data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x70,(byte) 0x10,(byte) 0xe0,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch225 = new BitmapCharRec(5,9,0,0,5,ch225data);
+
+/* char: 0xe0 */
+
+static final byte[] ch224data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x70,(byte) 0x10,(byte) 0xe0,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch224 = new BitmapCharRec(5,9,0,0,5,ch224data);
+
+/* char: 0xdf */
+
+static final byte[] ch223data = {
+(byte) 0xa0,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0xa0,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch223 = new BitmapCharRec(4,8,0,0,5,ch223data);
+
+/* char: 0xde */
+
+static final byte[] ch222data = {
+(byte) 0x80,(byte) 0x80,(byte) 0xf0,(byte) 0x88,(byte) 0x88,(byte) 0xf0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch222 = new BitmapCharRec(5,8,-1,0,7,ch222data);
+
+/* char: 0xdd */
+
+static final byte[] ch221data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x28,(byte) 0x44,(byte) 0x44,(byte) 0x82,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch221 = new BitmapCharRec(7,11,0,0,7,ch221data);
+
+/* char: 0xdc */
+
+static final byte[] ch220data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x48,
+};
+
+static final BitmapCharRec ch220 = new BitmapCharRec(6,10,-1,0,8,ch220data);
+
+/* char: 0xdb */
+
+static final byte[] ch219data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch219 = new BitmapCharRec(6,11,-1,0,8,ch219data);
+
+/* char: 0xda */
+
+static final byte[] ch218data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch218 = new BitmapCharRec(6,11,-1,0,8,ch218data);
+
+/* char: 0xd9 */
+
+static final byte[] ch217data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch217 = new BitmapCharRec(6,11,-1,0,8,ch217data);
+
+/* char: 0xd8 */
+
+static final byte[] ch216data = {
+(byte) 0x80,(byte) 0x78,(byte) 0xc4,(byte) 0xa4,(byte) 0xa4,(byte) 0x94,(byte) 0x94,(byte) 0x8c,(byte) 0x78,(byte) 0x4,
+};
+
+static final BitmapCharRec ch216 = new BitmapCharRec(6,10,-1,1,8,ch216data);
+
+/* char: 0xd7 */
+
+static final byte[] ch215data = {
+(byte) 0x88,(byte) 0x50,(byte) 0x20,(byte) 0x50,(byte) 0x88,
+};
+
+static final BitmapCharRec ch215 = new BitmapCharRec(5,5,0,-1,6,ch215data);
+
+/* char: 0xd6 */
+
+static final byte[] ch214data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x48,
+};
+
+static final BitmapCharRec ch214 = new BitmapCharRec(6,10,-1,0,8,ch214data);
+
+/* char: 0xd5 */
+
+static final byte[] ch213data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch213 = new BitmapCharRec(6,11,-1,0,8,ch213data);
+
+/* char: 0xd4 */
+
+static final byte[] ch212data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch212 = new BitmapCharRec(6,11,-1,0,8,ch212data);
+
+/* char: 0xd3 */
+
+static final byte[] ch211data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch211 = new BitmapCharRec(6,11,-1,0,8,ch211data);
+
+/* char: 0xd2 */
+
+static final byte[] ch210data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch210 = new BitmapCharRec(6,11,-1,0,8,ch210data);
+
+/* char: 0xd1 */
+
+static final byte[] ch209data = {
+(byte) 0x8c,(byte) 0x8c,(byte) 0x94,(byte) 0x94,(byte) 0xa4,(byte) 0xa4,(byte) 0xc4,(byte) 0xc4,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch209 = new BitmapCharRec(6,11,-1,0,8,ch209data);
+
+/* char: 0xd0 */
+
+static final byte[] ch208data = {
+(byte) 0x78,(byte) 0x44,(byte) 0x42,(byte) 0x42,(byte) 0xf2,(byte) 0x42,(byte) 0x44,(byte) 0x78,
+};
+
+static final BitmapCharRec ch208 = new BitmapCharRec(7,8,0,0,8,ch208data);
+
+/* char: 0xcf */
+
+static final byte[] ch207data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch207 = new BitmapCharRec(3,10,0,0,3,ch207data);
+
+/* char: 0xce */
+
+static final byte[] ch206data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch206 = new BitmapCharRec(3,11,0,0,3,ch206data);
+
+/* char: 0xcd */
+
+static final byte[] ch205data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch205 = new BitmapCharRec(2,11,-1,0,3,ch205data);
+
+/* char: 0xcc */
+
+static final byte[] ch204data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch204 = new BitmapCharRec(2,11,0,0,3,ch204data);
+
+/* char: 0xcb */
+
+static final byte[] ch203data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch203 = new BitmapCharRec(5,10,-1,0,7,ch203data);
+
+/* char: 0xca */
+
+static final byte[] ch202data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch202 = new BitmapCharRec(5,11,-1,0,7,ch202data);
+
+/* char: 0xc9 */
+
+static final byte[] ch201data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch201 = new BitmapCharRec(5,11,-1,0,7,ch201data);
+
+/* char: 0xc8 */
+
+static final byte[] ch200data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch200 = new BitmapCharRec(5,11,-1,0,7,ch200data);
+
+/* char: 0xc7 */
+
+static final byte[] ch199data = {
+(byte) 0x30,(byte) 0x10,(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch199 = new BitmapCharRec(6,10,-1,2,8,ch199data);
+
+/* char: 0xc6 */
+
+static final byte[] ch198data = {
+(byte) 0x8f,(byte) 0x80,(byte) 0x88,(byte) 0x0,(byte) 0x78,(byte) 0x0,(byte) 0x48,(byte) 0x0,(byte) 0x2f,(byte) 0x80,(byte) 0x28,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x1f,(byte) 0x80,
+};
+
+static final BitmapCharRec ch198 = new BitmapCharRec(9,8,0,0,10,ch198data);
+
+/* char: 0xc5 */
+
+static final byte[] ch197data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x28,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch197 = new BitmapCharRec(7,11,0,0,7,ch197data);
+
+/* char: 0xc4 */
+
+static final byte[] ch196data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x28,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x28,
+};
+
+static final BitmapCharRec ch196 = new BitmapCharRec(7,10,0,0,7,ch196data);
+
+/* char: 0xc3 */
+
+static final byte[] ch195data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x28,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x28,(byte) 0x14,
+};
+
+static final BitmapCharRec ch195 = new BitmapCharRec(7,11,0,0,7,ch195data);
+
+/* char: 0xc2 */
+
+static final byte[] ch194data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x28,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch194 = new BitmapCharRec(7,11,0,0,7,ch194data);
+
+/* char: 0xc1 */
+
+static final byte[] ch193data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x28,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch193 = new BitmapCharRec(7,11,0,0,7,ch193data);
+
+/* char: 0xc0 */
+
+static final byte[] ch192data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x28,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch192 = new BitmapCharRec(7,11,0,0,7,ch192data);
+
+/* char: 0xbf */
+
+static final byte[] ch191data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x0,(byte) 0x20,
+};
+
+static final BitmapCharRec ch191 = new BitmapCharRec(4,8,-1,2,6,ch191data);
+
+/* char: 0xbe */
+
+static final byte[] ch190data = {
+(byte) 0x21,(byte) 0x0,(byte) 0x17,(byte) 0x80,(byte) 0x13,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0xc8,(byte) 0x0,(byte) 0x24,(byte) 0x0,(byte) 0x44,(byte) 0x0,(byte) 0xe2,(byte) 0x0,
+};
+
+static final BitmapCharRec ch190 = new BitmapCharRec(9,8,0,0,9,ch190data);
+
+/* char: 0xbd */
+
+static final byte[] ch189data = {
+(byte) 0x27,(byte) 0x12,(byte) 0x15,(byte) 0xb,(byte) 0x48,(byte) 0x44,(byte) 0xc4,(byte) 0x42,
+};
+
+static final BitmapCharRec ch189 = new BitmapCharRec(8,8,0,0,9,ch189data);
+
+/* char: 0xbc */
+
+static final byte[] ch188data = {
+(byte) 0x21,(byte) 0x0,(byte) 0x17,(byte) 0x80,(byte) 0x13,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0x48,(byte) 0x0,(byte) 0x44,(byte) 0x0,(byte) 0xc4,(byte) 0x0,(byte) 0x42,(byte) 0x0,
+};
+
+static final BitmapCharRec ch188 = new BitmapCharRec(9,8,0,0,9,ch188data);
+
+/* char: 0xbb */
+
+static final byte[] ch187data = {
+(byte) 0xa0,(byte) 0x50,(byte) 0x28,(byte) 0x50,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch187 = new BitmapCharRec(5,5,0,0,6,ch187data);
+
+/* char: 0xba */
+
+static final byte[] ch186data = {
+(byte) 0xe0,(byte) 0x0,(byte) 0xe0,(byte) 0xa0,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch186 = new BitmapCharRec(3,5,0,-3,4,ch186data);
+
+/* char: 0xb9 */
+
+static final byte[] ch185data = {
+(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch185 = new BitmapCharRec(2,4,0,-3,3,ch185data);
+
+/* char: 0xb8 */
+
+static final byte[] ch184data = {
+(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch184 = new BitmapCharRec(2,2,0,2,3,ch184data);
+
+/* char: 0xb7 */
+
+static final byte[] ch183data = {
+(byte) 0xc0,
+};
+
+static final BitmapCharRec ch183 = new BitmapCharRec(2,1,0,-3,3,ch183data);
+
+/* char: 0xb6 */
+
+static final byte[] ch182data = {
+(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x68,(byte) 0xe8,(byte) 0xe8,(byte) 0xe8,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch182 = new BitmapCharRec(6,10,0,2,6,ch182data);
+
+/* char: 0xb5 */
+
+static final byte[] ch181data = {
+(byte) 0x80,(byte) 0x80,(byte) 0xf0,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,
+};
+
+static final BitmapCharRec ch181 = new BitmapCharRec(4,8,0,2,5,ch181data);
+
+/* char: 0xb4 */
+
+static final byte[] ch180data = {
+(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch180 = new BitmapCharRec(2,2,0,-6,3,ch180data);
+
+/* char: 0xb3 */
+
+static final byte[] ch179data = {
+(byte) 0xc0,(byte) 0x20,(byte) 0x40,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch179 = new BitmapCharRec(3,4,0,-3,3,ch179data);
+
+/* char: 0xb2 */
+
+static final byte[] ch178data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0xa0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch178 = new BitmapCharRec(3,4,0,-3,3,ch178data);
+
+/* char: 0xb1 */
+
+static final byte[] ch177data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch177 = new BitmapCharRec(5,7,0,0,6,ch177data);
+
+/* char: 0xb0 */
+
+static final byte[] ch176data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch176 = new BitmapCharRec(4,4,0,-3,4,ch176data);
+
+/* char: 0xaf */
+
+static final byte[] ch175data = {
+(byte) 0xe0,
+};
+
+static final BitmapCharRec ch175 = new BitmapCharRec(3,1,0,-7,3,ch175data);
+
+/* char: 0xae */
+
+static final byte[] ch174data = {
+(byte) 0x38,(byte) 0x44,(byte) 0xaa,(byte) 0xb2,(byte) 0xba,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch174 = new BitmapCharRec(7,7,-1,0,9,ch174data);
+
+/* char: 0xad */
+
+static final byte[] ch173data = {
+(byte) 0xe0,
+};
+
+static final BitmapCharRec ch173 = new BitmapCharRec(3,1,0,-3,4,ch173data);
+
+/* char: 0xac */
+
+static final byte[] ch172data = {
+(byte) 0x8,(byte) 0x8,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch172 = new BitmapCharRec(5,3,-1,-2,7,ch172data);
+
+/* char: 0xab */
+
+static final byte[] ch171data = {
+(byte) 0x28,(byte) 0x50,(byte) 0xa0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch171 = new BitmapCharRec(5,5,0,0,6,ch171data);
+
+/* char: 0xaa */
+
+static final byte[] ch170data = {
+(byte) 0xe0,(byte) 0x0,(byte) 0xa0,(byte) 0x20,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch170 = new BitmapCharRec(3,5,0,-3,4,ch170data);
+
+/* char: 0xa9 */
+
+static final byte[] ch169data = {
+(byte) 0x38,(byte) 0x44,(byte) 0x9a,(byte) 0xa2,(byte) 0x9a,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch169 = new BitmapCharRec(7,7,-1,0,9,ch169data);
+
+/* char: 0xa8 */
+
+static final byte[] ch168data = {
+(byte) 0xa0,
+};
+
+static final BitmapCharRec ch168 = new BitmapCharRec(3,1,0,-7,3,ch168data);
+
+/* char: 0xa7 */
+
+static final byte[] ch167data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x18,(byte) 0x70,(byte) 0xc8,(byte) 0x98,(byte) 0x70,(byte) 0xc0,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch167 = new BitmapCharRec(5,10,0,2,6,ch167data);
+
+/* char: 0xa6 */
+
+static final byte[] ch166data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch166 = new BitmapCharRec(1,10,-1,2,3,ch166data);
+
+/* char: 0xa5 */
+
+static final byte[] ch165data = {
+(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0xf8,(byte) 0x50,(byte) 0x50,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch165 = new BitmapCharRec(5,8,0,0,6,ch165data);
+
+/* char: 0xa4 */
+
+static final byte[] ch164data = {
+(byte) 0x90,(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,(byte) 0x90,
+};
+
+static final BitmapCharRec ch164 = new BitmapCharRec(4,6,0,-1,5,ch164data);
+
+/* char: 0xa3 */
+
+static final byte[] ch163data = {
+(byte) 0xb0,(byte) 0x48,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x40,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch163 = new BitmapCharRec(5,8,0,0,6,ch163data);
+
+/* char: 0xa2 */
+
+static final byte[] ch162data = {
+(byte) 0x40,(byte) 0x70,(byte) 0xa8,(byte) 0xa0,(byte) 0xa0,(byte) 0xa8,(byte) 0x70,(byte) 0x10,
+};
+
+static final BitmapCharRec ch162 = new BitmapCharRec(5,8,0,1,6,ch162data);
+
+/* char: 0xa1 */
+
+static final byte[] ch161data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch161 = new BitmapCharRec(1,8,-1,2,3,ch161data);
+
+/* char: 0xa0 */
+
+static final BitmapCharRec ch160 = new BitmapCharRec(0,0,0,0,3,null);
+
+/* char: 0x7e '~' */
+
+static final byte[] ch126data = {
+(byte) 0x98,(byte) 0x64,
+};
+
+static final BitmapCharRec ch126 = new BitmapCharRec(6,2,0,-3,7,ch126data);
+
+/* char: 0x7d '}' */
+
+static final byte[] ch125data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch125 = new BitmapCharRec(3,10,0,2,3,ch125data);
+
+/* char: 0x7c '|' */
+
+static final byte[] ch124data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch124 = new BitmapCharRec(1,10,-1,2,3,ch124data);
+
+/* char: 0x7b '{' */
+
+static final byte[] ch123data = {
+(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch123 = new BitmapCharRec(3,10,0,2,3,ch123data);
+
+/* char: 0x7a 'z' */
+
+static final byte[] ch122data = {
+(byte) 0xf0,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch122 = new BitmapCharRec(4,6,0,0,5,ch122data);
+
+/* char: 0x79 'y' */
+
+static final byte[] ch121data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x60,(byte) 0xa0,(byte) 0xa0,(byte) 0x90,(byte) 0x90,
+};
+
+static final BitmapCharRec ch121 = new BitmapCharRec(4,8,0,2,5,ch121data);
+
+/* char: 0x78 'x' */
+
+static final byte[] ch120data = {
+(byte) 0x88,(byte) 0x88,(byte) 0x50,(byte) 0x20,(byte) 0x50,(byte) 0x88,
+};
+
+static final BitmapCharRec ch120 = new BitmapCharRec(5,6,0,0,6,ch120data);
+
+/* char: 0x77 'w' */
+
+static final byte[] ch119data = {
+(byte) 0x28,(byte) 0x28,(byte) 0x54,(byte) 0x54,(byte) 0x92,(byte) 0x92,
+};
+
+static final BitmapCharRec ch119 = new BitmapCharRec(7,6,0,0,8,ch119data);
+
+/* char: 0x76 'v' */
+
+static final byte[] ch118data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x50,(byte) 0x50,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch118 = new BitmapCharRec(5,6,0,0,6,ch118data);
+
+/* char: 0x75 'u' */
+
+static final byte[] ch117data = {
+(byte) 0x70,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,
+};
+
+static final BitmapCharRec ch117 = new BitmapCharRec(4,6,0,0,5,ch117data);
+
+/* char: 0x74 't' */
+
+static final byte[] ch116data = {
+(byte) 0x60,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x40,(byte) 0x40,
+};
+
+static final BitmapCharRec ch116 = new BitmapCharRec(3,8,0,0,4,ch116data);
+
+/* char: 0x73 's' */
+
+static final byte[] ch115data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x10,(byte) 0x60,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch115 = new BitmapCharRec(4,6,0,0,5,ch115data);
+
+/* char: 0x72 'r' */
+
+static final byte[] ch114data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xc0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch114 = new BitmapCharRec(3,6,0,0,4,ch114data);
+
+/* char: 0x71 'q' */
+
+static final byte[] ch113data = {
+(byte) 0x8,(byte) 0x8,(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x98,(byte) 0x68,
+};
+
+static final BitmapCharRec ch113 = new BitmapCharRec(5,8,0,2,6,ch113data);
+
+/* char: 0x70 'p' */
+
+static final byte[] ch112data = {
+(byte) 0x80,(byte) 0x80,(byte) 0xb0,(byte) 0xc8,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,
+};
+
+static final BitmapCharRec ch112 = new BitmapCharRec(5,8,0,2,6,ch112data);
+
+/* char: 0x6f 'o' */
+
+static final byte[] ch111data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch111 = new BitmapCharRec(5,6,0,0,6,ch111data);
+
+/* char: 0x6e 'n' */
+
+static final byte[] ch110data = {
+(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,
+};
+
+static final BitmapCharRec ch110 = new BitmapCharRec(5,6,0,0,6,ch110data);
+
+/* char: 0x6d 'm' */
+
+static final byte[] ch109data = {
+(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0xec,
+};
+
+static final BitmapCharRec ch109 = new BitmapCharRec(7,6,0,0,8,ch109data);
+
+/* char: 0x6c 'l' */
+
+static final byte[] ch108data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch108 = new BitmapCharRec(1,8,0,0,2,ch108data);
+
+/* char: 0x6b 'k' */
+
+static final byte[] ch107data = {
+(byte) 0x90,(byte) 0x90,(byte) 0xa0,(byte) 0xc0,(byte) 0xa0,(byte) 0x90,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch107 = new BitmapCharRec(4,8,0,0,5,ch107data);
+
+/* char: 0x6a 'j' */
+
+static final byte[] ch106data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch106 = new BitmapCharRec(1,9,0,1,2,ch106data);
+
+/* char: 0x69 'i' */
+
+static final byte[] ch105data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch105 = new BitmapCharRec(1,8,0,0,2,ch105data);
+
+/* char: 0x68 'h' */
+
+static final byte[] ch104data = {
+(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch104 = new BitmapCharRec(5,8,0,0,6,ch104data);
+
+/* char: 0x67 'g' */
+
+static final byte[] ch103data = {
+(byte) 0x70,(byte) 0x8,(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x98,(byte) 0x68,
+};
+
+static final BitmapCharRec ch103 = new BitmapCharRec(5,8,0,2,6,ch103data);
+
+/* char: 0x66 'f' */
+
+static final byte[] ch102data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x40,(byte) 0x30,
+};
+
+static final BitmapCharRec ch102 = new BitmapCharRec(4,8,0,0,4,ch102data);
+
+/* char: 0x65 'e' */
+
+static final byte[] ch101data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x80,(byte) 0xf0,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch101 = new BitmapCharRec(4,6,0,0,5,ch101data);
+
+/* char: 0x64 'd' */
+
+static final byte[] ch100data = {
+(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x98,(byte) 0x68,(byte) 0x8,(byte) 0x8,
+};
+
+static final BitmapCharRec ch100 = new BitmapCharRec(5,8,0,0,6,ch100data);
+
+/* char: 0x63 'c' */
+
+static final byte[] ch99data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x80,(byte) 0x80,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch99 = new BitmapCharRec(4,6,0,0,5,ch99data);
+
+/* char: 0x62 'b' */
+
+static final byte[] ch98data = {
+(byte) 0xb0,(byte) 0xc8,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch98 = new BitmapCharRec(5,8,0,0,6,ch98data);
+
+/* char: 0x61 'a' */
+
+static final byte[] ch97data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x70,(byte) 0x10,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch97 = new BitmapCharRec(5,6,0,0,5,ch97data);
+
+/* char: 0x60 '`' */
+
+static final byte[] ch96data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch96 = new BitmapCharRec(2,3,0,-5,3,ch96data);
+
+/* char: 0x5f '_' */
+
+static final byte[] ch95data = {
+(byte) 0xfc,
+};
+
+static final BitmapCharRec ch95 = new BitmapCharRec(6,1,0,2,6,ch95data);
+
+/* char: 0x5e '^' */
+
+static final byte[] ch94data = {
+(byte) 0x88,(byte) 0x50,(byte) 0x50,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch94 = new BitmapCharRec(5,5,0,-3,6,ch94data);
+
+/* char: 0x5d ']' */
+
+static final byte[] ch93data = {
+(byte) 0xc0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch93 = new BitmapCharRec(2,10,0,2,3,ch93data);
+
+/* char: 0x5c '\' */
+
+static final byte[] ch92data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch92 = new BitmapCharRec(3,8,0,0,3,ch92data);
+
+/* char: 0x5b '[' */
+
+static final byte[] ch91data = {
+(byte) 0xc0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch91 = new BitmapCharRec(2,10,-1,2,3,ch91data);
+
+/* char: 0x5a 'Z' */
+
+static final byte[] ch90data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch90 = new BitmapCharRec(5,8,-1,0,7,ch90data);
+
+/* char: 0x59 'Y' */
+
+static final byte[] ch89data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x28,(byte) 0x44,(byte) 0x44,(byte) 0x82,
+};
+
+static final BitmapCharRec ch89 = new BitmapCharRec(7,8,0,0,7,ch89data);
+
+/* char: 0x58 'X' */
+
+static final byte[] ch88data = {
+(byte) 0x88,(byte) 0x88,(byte) 0x50,(byte) 0x50,(byte) 0x20,(byte) 0x50,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch88 = new BitmapCharRec(5,8,-1,0,7,ch88data);
+
+/* char: 0x57 'W' */
+
+static final byte[] ch87data = {
+(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x55,(byte) 0x0,(byte) 0x49,(byte) 0x0,(byte) 0x49,(byte) 0x0,(byte) 0x88,(byte) 0x80,(byte) 0x88,(byte) 0x80,
+};
+
+static final BitmapCharRec ch87 = new BitmapCharRec(9,8,0,0,9,ch87data);
+
+/* char: 0x56 'V' */
+
+static final byte[] ch86data = {
+(byte) 0x10,(byte) 0x28,(byte) 0x28,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch86 = new BitmapCharRec(7,8,0,0,7,ch86data);
+
+/* char: 0x55 'U' */
+
+static final byte[] ch85data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,
+};
+
+static final BitmapCharRec ch85 = new BitmapCharRec(6,8,-1,0,8,ch85data);
+
+/* char: 0x54 'T' */
+
+static final byte[] ch84data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch84 = new BitmapCharRec(5,8,0,0,5,ch84data);
+
+/* char: 0x53 'S' */
+
+static final byte[] ch83data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x8,(byte) 0x70,(byte) 0x80,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch83 = new BitmapCharRec(5,8,-1,0,7,ch83data);
+
+/* char: 0x52 'R' */
+
+static final byte[] ch82data = {
+(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xf0,(byte) 0x88,(byte) 0x88,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch82 = new BitmapCharRec(5,8,-1,0,7,ch82data);
+
+/* char: 0x51 'Q' */
+
+static final byte[] ch81data = {
+(byte) 0x2,(byte) 0x7c,(byte) 0x8c,(byte) 0x94,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch81 = new BitmapCharRec(7,9,-1,1,8,ch81data);
+
+/* char: 0x50 'P' */
+
+static final byte[] ch80data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf0,(byte) 0x88,(byte) 0x88,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch80 = new BitmapCharRec(5,8,-1,0,7,ch80data);
+
+/* char: 0x4f 'O' */
+
+static final byte[] ch79data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch79 = new BitmapCharRec(6,8,-1,0,8,ch79data);
+
+/* char: 0x4e 'N' */
+
+static final byte[] ch78data = {
+(byte) 0x8c,(byte) 0x8c,(byte) 0x94,(byte) 0x94,(byte) 0xa4,(byte) 0xa4,(byte) 0xc4,(byte) 0xc4,
+};
+
+static final BitmapCharRec ch78 = new BitmapCharRec(6,8,-1,0,8,ch78data);
+
+/* char: 0x4d 'M' */
+
+static final byte[] ch77data = {
+(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0xaa,(byte) 0xaa,(byte) 0xc6,(byte) 0xc6,(byte) 0x82,
+};
+
+static final BitmapCharRec ch77 = new BitmapCharRec(7,8,-1,0,9,ch77data);
+
+/* char: 0x4c 'L' */
+
+static final byte[] ch76data = {
+(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch76 = new BitmapCharRec(4,8,-1,0,6,ch76data);
+
+/* char: 0x4b 'K' */
+
+static final byte[] ch75data = {
+(byte) 0x88,(byte) 0x88,(byte) 0x90,(byte) 0x90,(byte) 0xe0,(byte) 0xa0,(byte) 0x90,(byte) 0x88,
+};
+
+static final BitmapCharRec ch75 = new BitmapCharRec(5,8,-1,0,7,ch75data);
+
+/* char: 0x4a 'J' */
+
+static final byte[] ch74data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch74 = new BitmapCharRec(4,8,0,0,5,ch74data);
+
+/* char: 0x49 'I' */
+
+static final byte[] ch73data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch73 = new BitmapCharRec(1,8,-1,0,3,ch73data);
+
+/* char: 0x48 'H' */
+
+static final byte[] ch72data = {
+(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xfc,(byte) 0x84,(byte) 0x84,(byte) 0x84,
+};
+
+static final BitmapCharRec ch72 = new BitmapCharRec(6,8,-1,0,8,ch72data);
+
+/* char: 0x47 'G' */
+
+static final byte[] ch71data = {
+(byte) 0x74,(byte) 0x8c,(byte) 0x84,(byte) 0x8c,(byte) 0x80,(byte) 0x80,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch71 = new BitmapCharRec(6,8,-1,0,8,ch71data);
+
+/* char: 0x46 'F' */
+
+static final byte[] ch70data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch70 = new BitmapCharRec(5,8,-1,0,6,ch70data);
+
+/* char: 0x45 'E' */
+
+static final byte[] ch69data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch69 = new BitmapCharRec(5,8,-1,0,7,ch69data);
+
+/* char: 0x44 'D' */
+
+static final byte[] ch68data = {
+(byte) 0xf0,(byte) 0x88,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x88,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch68 = new BitmapCharRec(6,8,-1,0,8,ch68data);
+
+/* char: 0x43 'C' */
+
+static final byte[] ch67data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch67 = new BitmapCharRec(6,8,-1,0,8,ch67data);
+
+/* char: 0x42 'B' */
+
+static final byte[] ch66data = {
+(byte) 0xf0,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xf0,(byte) 0x88,(byte) 0x88,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch66 = new BitmapCharRec(5,8,-1,0,7,ch66data);
+
+/* char: 0x41 'A' */
+
+static final byte[] ch65data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x28,(byte) 0x28,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch65 = new BitmapCharRec(7,8,0,0,7,ch65data);
+
+/* char: 0x40 '@' */
+
+static final byte[] ch64data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x40,(byte) 0x0,(byte) 0x9b,(byte) 0x0,(byte) 0xa4,(byte) 0x80,(byte) 0xa4,(byte) 0x80,(byte) 0xa2,(byte) 0x40,(byte) 0x92,(byte) 0x40,(byte) 0x4d,(byte) 0x40,
+(byte) 0x20,(byte) 0x80,(byte) 0x1f,(byte) 0x0,
+};
+
+static final BitmapCharRec ch64 = new BitmapCharRec(10,10,0,2,11,ch64data);
+
+/* char: 0x3f '?' */
+
+static final byte[] ch63data = {
+(byte) 0x40,(byte) 0x0,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch63 = new BitmapCharRec(4,8,-1,0,6,ch63data);
+
+/* char: 0x3e '>' */
+
+static final byte[] ch62data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch62 = new BitmapCharRec(3,5,-1,-1,6,ch62data);
+
+/* char: 0x3d '=' */
+
+static final byte[] ch61data = {
+(byte) 0xf0,(byte) 0x0,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch61 = new BitmapCharRec(4,3,0,-2,5,ch61data);
+
+/* char: 0x3c '<' */
+
+static final byte[] ch60data = {
+(byte) 0x20,(byte) 0x40,(byte) 0x80,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch60 = new BitmapCharRec(3,5,-1,-1,6,ch60data);
+
+/* char: 0x3b ';' */
+
+static final byte[] ch59data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch59 = new BitmapCharRec(2,8,0,2,3,ch59data);
+
+/* char: 0x3a ':' */
+
+static final byte[] ch58data = {
+(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch58 = new BitmapCharRec(1,6,-1,0,3,ch58data);
+
+/* char: 0x39 '9' */
+
+static final byte[] ch57data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x8,(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch57 = new BitmapCharRec(5,8,0,0,6,ch57data);
+
+/* char: 0x38 '8' */
+
+static final byte[] ch56data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch56 = new BitmapCharRec(5,8,0,0,6,ch56data);
+
+/* char: 0x37 '7' */
+
+static final byte[] ch55data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x10,(byte) 0x10,(byte) 0x8,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch55 = new BitmapCharRec(5,8,0,0,6,ch55data);
+
+/* char: 0x36 '6' */
+
+static final byte[] ch54data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,(byte) 0x80,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch54 = new BitmapCharRec(5,8,0,0,6,ch54data);
+
+/* char: 0x35 '5' */
+
+static final byte[] ch53data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x8,(byte) 0x8,(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch53 = new BitmapCharRec(5,8,0,0,6,ch53data);
+
+/* char: 0x34 '4' */
+
+static final byte[] ch52data = {
+(byte) 0x10,(byte) 0x10,(byte) 0xf8,(byte) 0x90,(byte) 0x50,(byte) 0x50,(byte) 0x30,(byte) 0x10,
+};
+
+static final BitmapCharRec ch52 = new BitmapCharRec(5,8,0,0,6,ch52data);
+
+/* char: 0x33 '3' */
+
+static final byte[] ch51data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x8,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch51 = new BitmapCharRec(5,8,0,0,6,ch51data);
+
+/* char: 0x32 '2' */
+
+static final byte[] ch50data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x40,(byte) 0x30,(byte) 0x8,(byte) 0x8,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch50 = new BitmapCharRec(5,8,0,0,6,ch50data);
+
+/* char: 0x31 '1' */
+
+static final byte[] ch49data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch49 = new BitmapCharRec(2,8,-1,0,6,ch49data);
+
+/* char: 0x30 '0' */
+
+static final byte[] ch48data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch48 = new BitmapCharRec(5,8,0,0,6,ch48data);
+
+/* char: 0x2f '/' */
+
+static final byte[] ch47data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch47 = new BitmapCharRec(3,8,0,0,3,ch47data);
+
+/* char: 0x2e '.' */
+
+static final byte[] ch46data = {
+(byte) 0x80,
+};
+
+static final BitmapCharRec ch46 = new BitmapCharRec(1,1,-1,0,3,ch46data);
+
+/* char: 0x2d '-' */
+
+static final byte[] ch45data = {
+(byte) 0xf8,
+};
+
+static final BitmapCharRec ch45 = new BitmapCharRec(5,1,-1,-3,7,ch45data);
+
+/* char: 0x2c ',' */
+
+static final byte[] ch44data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,
+};
+
+static final BitmapCharRec ch44 = new BitmapCharRec(2,3,0,2,3,ch44data);
+
+/* char: 0x2b '+' */
+
+static final byte[] ch43data = {
+(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch43 = new BitmapCharRec(5,5,0,-1,6,ch43data);
+
+/* char: 0x2a '*' */
+
+static final byte[] ch42data = {
+(byte) 0xa0,(byte) 0x40,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch42 = new BitmapCharRec(3,3,0,-5,4,ch42data);
+
+/* char: 0x29 ')' */
+
+static final byte[] ch41data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch41 = new BitmapCharRec(3,10,-1,2,4,ch41data);
+
+/* char: 0x28 '(' */
+
+static final byte[] ch40data = {
+(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch40 = new BitmapCharRec(3,10,0,2,4,ch40data);
+
+/* char: 0x27 ''' */
+
+static final byte[] ch39data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,
+};
+
+static final BitmapCharRec ch39 = new BitmapCharRec(2,3,-1,-5,3,ch39data);
+
+/* char: 0x26 '&' */
+
+static final byte[] ch38data = {
+(byte) 0x64,(byte) 0x98,(byte) 0x98,(byte) 0xa4,(byte) 0x60,(byte) 0x50,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch38 = new BitmapCharRec(6,8,-1,0,8,ch38data);
+
+/* char: 0x25 '%' */
+
+static final byte[] ch37data = {
+(byte) 0x26,(byte) 0x29,(byte) 0x16,(byte) 0x10,(byte) 0x8,(byte) 0x68,(byte) 0x94,(byte) 0x64,
+};
+
+static final BitmapCharRec ch37 = new BitmapCharRec(8,8,0,0,9,ch37data);
+
+/* char: 0x24 '$' */
+
+static final byte[] ch36data = {
+(byte) 0x20,(byte) 0x70,(byte) 0xa8,(byte) 0x28,(byte) 0x70,(byte) 0xa0,(byte) 0xa8,(byte) 0x70,(byte) 0x20,
+};
+
+static final BitmapCharRec ch36 = new BitmapCharRec(5,9,0,1,6,ch36data);
+
+/* char: 0x23 '#' */
+
+static final byte[] ch35data = {
+(byte) 0x50,(byte) 0x50,(byte) 0xf8,(byte) 0x28,(byte) 0x7c,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch35 = new BitmapCharRec(6,7,0,0,6,ch35data);
+
+/* char: 0x22 '"' */
+
+static final byte[] ch34data = {
+(byte) 0xa0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch34 = new BitmapCharRec(3,2,-1,-6,4,ch34data);
+
+/* char: 0x21 '!' */
+
+static final byte[] ch33data = {
+(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch33 = new BitmapCharRec(1,8,-1,0,3,ch33data);
+
+/* char: 0x20 ' ' */
+
+static final BitmapCharRec ch32 = new BitmapCharRec(0,0,0,0,3,null);
+
+static final BitmapCharRec[] chars = {
+ch32,
+ch33,
+ch34,
+ch35,
+ch36,
+ch37,
+ch38,
+ch39,
+ch40,
+ch41,
+ch42,
+ch43,
+ch44,
+ch45,
+ch46,
+ch47,
+ch48,
+ch49,
+ch50,
+ch51,
+ch52,
+ch53,
+ch54,
+ch55,
+ch56,
+ch57,
+ch58,
+ch59,
+ch60,
+ch61,
+ch62,
+ch63,
+ch64,
+ch65,
+ch66,
+ch67,
+ch68,
+ch69,
+ch70,
+ch71,
+ch72,
+ch73,
+ch74,
+ch75,
+ch76,
+ch77,
+ch78,
+ch79,
+ch80,
+ch81,
+ch82,
+ch83,
+ch84,
+ch85,
+ch86,
+ch87,
+ch88,
+ch89,
+ch90,
+ch91,
+ch92,
+ch93,
+ch94,
+ch95,
+ch96,
+ch97,
+ch98,
+ch99,
+ch100,
+ch101,
+ch102,
+ch103,
+ch104,
+ch105,
+ch106,
+ch107,
+ch108,
+ch109,
+ch110,
+ch111,
+ch112,
+ch113,
+ch114,
+ch115,
+ch116,
+ch117,
+ch118,
+ch119,
+ch120,
+ch121,
+ch122,
+ch123,
+ch124,
+ch125,
+ch126,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+ch160,
+ch161,
+ch162,
+ch163,
+ch164,
+ch165,
+ch166,
+ch167,
+ch168,
+ch169,
+ch170,
+ch171,
+ch172,
+ch173,
+ch174,
+ch175,
+ch176,
+ch177,
+ch178,
+ch179,
+ch180,
+ch181,
+ch182,
+ch183,
+ch184,
+ch185,
+ch186,
+ch187,
+ch188,
+ch189,
+ch190,
+ch191,
+ch192,
+ch193,
+ch194,
+ch195,
+ch196,
+ch197,
+ch198,
+ch199,
+ch200,
+ch201,
+ch202,
+ch203,
+ch204,
+ch205,
+ch206,
+ch207,
+ch208,
+ch209,
+ch210,
+ch211,
+ch212,
+ch213,
+ch214,
+ch215,
+ch216,
+ch217,
+ch218,
+ch219,
+ch220,
+ch221,
+ch222,
+ch223,
+ch224,
+ch225,
+ch226,
+ch227,
+ch228,
+ch229,
+ch230,
+ch231,
+ch232,
+ch233,
+ch234,
+ch235,
+ch236,
+ch237,
+ch238,
+ch239,
+ch240,
+ch241,
+ch242,
+ch243,
+ch244,
+ch245,
+ch246,
+ch247,
+ch248,
+ch249,
+ch250,
+ch251,
+ch252,
+ch253,
+ch254,
+ch255,
+};
+
+ public static final BitmapFontRec glutBitmapHelvetica10 = new BitmapFontRec("-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1",
+ 224,
+ 32,
+ chars);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica12.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica12.java
new file mode 100644
index 000000000..bc86f6216
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica12.java
@@ -0,0 +1,1808 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+class GLUTBitmapHelvetica12 {
+
+/* GENERATED FILE -- DO NOT MODIFY */
+
+/* char: 0xff */
+
+static final byte[] ch255data = {
+(byte) 0xc0,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x30,(byte) 0x50,(byte) 0x50,(byte) 0x48,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch255 = new BitmapCharRec(5,12,-1,3,7,ch255data);
+
+/* char: 0xfe */
+
+static final byte[] ch254data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xb0,(byte) 0xc8,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch254 = new BitmapCharRec(5,12,-1,3,7,ch254data);
+
+/* char: 0xfd */
+
+static final byte[] ch253data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x50,(byte) 0x50,(byte) 0x90,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch253 = new BitmapCharRec(5,13,-1,3,7,ch253data);
+
+/* char: 0xfc */
+
+static final byte[] ch252data = {
+(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch252 = new BitmapCharRec(5,9,-1,0,7,ch252data);
+
+/* char: 0xfb */
+
+static final byte[] ch251data = {
+(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch251 = new BitmapCharRec(5,10,-1,0,7,ch251data);
+
+/* char: 0xfa */
+
+static final byte[] ch250data = {
+(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch250 = new BitmapCharRec(5,10,-1,0,7,ch250data);
+
+/* char: 0xf9 */
+
+static final byte[] ch249data = {
+(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch249 = new BitmapCharRec(5,10,-1,0,7,ch249data);
+
+/* char: 0xf8 */
+
+static final byte[] ch248data = {
+(byte) 0xb8,(byte) 0x44,(byte) 0x64,(byte) 0x54,(byte) 0x4c,(byte) 0x44,(byte) 0x3a,
+};
+
+static final BitmapCharRec ch248 = new BitmapCharRec(7,7,0,0,7,ch248data);
+
+/* char: 0xf7 */
+
+static final byte[] ch247data = {
+(byte) 0x20,(byte) 0x0,(byte) 0xf8,(byte) 0x0,(byte) 0x20,
+};
+
+static final BitmapCharRec ch247 = new BitmapCharRec(5,5,-1,-1,7,ch247data);
+
+/* char: 0xf6 */
+
+static final byte[] ch246data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch246 = new BitmapCharRec(5,9,-1,0,7,ch246data);
+
+/* char: 0xf5 */
+
+static final byte[] ch245data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch245 = new BitmapCharRec(5,10,-1,0,7,ch245data);
+
+/* char: 0xf4 */
+
+static final byte[] ch244data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch244 = new BitmapCharRec(5,10,-1,0,7,ch244data);
+
+/* char: 0xf3 */
+
+static final byte[] ch243data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch243 = new BitmapCharRec(5,10,-1,0,7,ch243data);
+
+/* char: 0xf2 */
+
+static final byte[] ch242data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch242 = new BitmapCharRec(5,10,-1,0,7,ch242data);
+
+/* char: 0xf1 */
+
+static final byte[] ch241data = {
+(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch241 = new BitmapCharRec(5,10,-1,0,7,ch241data);
+
+/* char: 0xf0 */
+
+static final byte[] ch240data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x78,(byte) 0x8,(byte) 0x50,(byte) 0x30,(byte) 0x68,
+};
+
+static final BitmapCharRec ch240 = new BitmapCharRec(5,10,-1,0,7,ch240data);
+
+/* char: 0xef */
+
+static final byte[] ch239data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch239 = new BitmapCharRec(3,9,0,0,3,ch239data);
+
+/* char: 0xee */
+
+static final byte[] ch238data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch238 = new BitmapCharRec(3,10,0,0,3,ch238data);
+
+/* char: 0xed */
+
+static final byte[] ch237data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch237 = new BitmapCharRec(2,10,-1,0,3,ch237data);
+
+/* char: 0xec */
+
+static final byte[] ch236data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch236 = new BitmapCharRec(2,10,0,0,3,ch236data);
+
+/* char: 0xeb */
+
+static final byte[] ch235data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x80,(byte) 0xf8,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch235 = new BitmapCharRec(5,9,-1,0,7,ch235data);
+
+/* char: 0xea */
+
+static final byte[] ch234data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x80,(byte) 0xf8,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch234 = new BitmapCharRec(5,10,-1,0,7,ch234data);
+
+/* char: 0xe9 */
+
+static final byte[] ch233data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x80,(byte) 0xf8,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch233 = new BitmapCharRec(5,10,-1,0,7,ch233data);
+
+/* char: 0xe8 */
+
+static final byte[] ch232data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x80,(byte) 0xf8,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch232 = new BitmapCharRec(5,10,-1,0,7,ch232data);
+
+/* char: 0xe7 */
+
+static final byte[] ch231data = {
+(byte) 0x60,(byte) 0x10,(byte) 0x20,(byte) 0x70,(byte) 0x88,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch231 = new BitmapCharRec(5,10,-1,3,7,ch231data);
+
+/* char: 0xe6 */
+
+static final byte[] ch230data = {
+(byte) 0x77,(byte) 0x0,(byte) 0x88,(byte) 0x80,(byte) 0x88,(byte) 0x0,(byte) 0x7f,(byte) 0x80,(byte) 0x8,(byte) 0x80,(byte) 0x88,(byte) 0x80,(byte) 0x77,(byte) 0x0,
+};
+
+static final BitmapCharRec ch230 = new BitmapCharRec(9,7,-1,0,11,ch230data);
+
+/* char: 0xe5 */
+
+static final byte[] ch229data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x78,(byte) 0x8,(byte) 0x88,(byte) 0x70,(byte) 0x30,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch229 = new BitmapCharRec(6,10,-1,0,7,ch229data);
+
+/* char: 0xe4 */
+
+static final byte[] ch228data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x78,(byte) 0x8,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch228 = new BitmapCharRec(6,9,-1,0,7,ch228data);
+
+/* char: 0xe3 */
+
+static final byte[] ch227data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x78,(byte) 0x8,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch227 = new BitmapCharRec(6,10,-1,0,7,ch227data);
+
+/* char: 0xe2 */
+
+static final byte[] ch226data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x78,(byte) 0x8,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch226 = new BitmapCharRec(6,10,-1,0,7,ch226data);
+
+/* char: 0xe1 */
+
+static final byte[] ch225data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x78,(byte) 0x8,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch225 = new BitmapCharRec(6,10,-1,0,7,ch225data);
+
+/* char: 0xe0 */
+
+static final byte[] ch224data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x78,(byte) 0x8,(byte) 0x88,(byte) 0x70,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch224 = new BitmapCharRec(6,10,-1,0,7,ch224data);
+
+/* char: 0xdf */
+
+static final byte[] ch223data = {
+(byte) 0xb0,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xb0,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch223 = new BitmapCharRec(5,9,-1,0,7,ch223data);
+
+/* char: 0xde */
+
+static final byte[] ch222data = {
+(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xf8,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch222 = new BitmapCharRec(6,9,-1,0,8,ch222data);
+
+/* char: 0xdd */
+
+static final byte[] ch221data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0x44,(byte) 0x82,(byte) 0x82,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch221 = new BitmapCharRec(7,12,-1,0,9,ch221data);
+
+/* char: 0xdc */
+
+static final byte[] ch220data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x48,
+};
+
+static final BitmapCharRec ch220 = new BitmapCharRec(6,11,-1,0,8,ch220data);
+
+/* char: 0xdb */
+
+static final byte[] ch219data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch219 = new BitmapCharRec(6,12,-1,0,8,ch219data);
+
+/* char: 0xda */
+
+static final byte[] ch218data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch218 = new BitmapCharRec(6,12,-1,0,8,ch218data);
+
+/* char: 0xd9 */
+
+static final byte[] ch217data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch217 = new BitmapCharRec(6,12,-1,0,8,ch217data);
+
+/* char: 0xd8 */
+
+static final byte[] ch216data = {
+(byte) 0x80,(byte) 0x0,(byte) 0x5e,(byte) 0x0,(byte) 0x21,(byte) 0x0,(byte) 0x50,(byte) 0x80,(byte) 0x48,(byte) 0x80,(byte) 0x44,(byte) 0x80,(byte) 0x44,(byte) 0x80,(byte) 0x42,(byte) 0x80,
+(byte) 0x21,(byte) 0x0,(byte) 0x1e,(byte) 0x80,(byte) 0x0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch216 = new BitmapCharRec(10,11,0,1,10,ch216data);
+
+/* char: 0xd7 */
+
+static final byte[] ch215data = {
+(byte) 0x88,(byte) 0x50,(byte) 0x20,(byte) 0x50,(byte) 0x88,
+};
+
+static final BitmapCharRec ch215 = new BitmapCharRec(5,5,-1,-1,7,ch215data);
+
+/* char: 0xd6 */
+
+static final byte[] ch214data = {
+(byte) 0x3c,(byte) 0x42,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x42,(byte) 0x3c,(byte) 0x0,(byte) 0x24,
+};
+
+static final BitmapCharRec ch214 = new BitmapCharRec(8,11,-1,0,10,ch214data);
+
+/* char: 0xd5 */
+
+static final byte[] ch213data = {
+(byte) 0x3c,(byte) 0x42,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x42,(byte) 0x3c,(byte) 0x0,(byte) 0x28,(byte) 0x14,
+};
+
+static final BitmapCharRec ch213 = new BitmapCharRec(8,12,-1,0,10,ch213data);
+
+/* char: 0xd4 */
+
+static final byte[] ch212data = {
+(byte) 0x3c,(byte) 0x42,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x42,(byte) 0x3c,(byte) 0x0,(byte) 0x14,(byte) 0x8,
+};
+
+static final BitmapCharRec ch212 = new BitmapCharRec(8,12,-1,0,10,ch212data);
+
+/* char: 0xd3 */
+
+static final byte[] ch211data = {
+(byte) 0x3c,(byte) 0x42,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x42,(byte) 0x3c,(byte) 0x0,(byte) 0x8,(byte) 0x4,
+};
+
+static final BitmapCharRec ch211 = new BitmapCharRec(8,12,-1,0,10,ch211data);
+
+/* char: 0xd2 */
+
+static final byte[] ch210data = {
+(byte) 0x3c,(byte) 0x42,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x42,(byte) 0x3c,(byte) 0x0,(byte) 0x8,(byte) 0x10,
+};
+
+static final BitmapCharRec ch210 = new BitmapCharRec(8,12,-1,0,10,ch210data);
+
+/* char: 0xd1 */
+
+static final byte[] ch209data = {
+(byte) 0x82,(byte) 0x86,(byte) 0x8a,(byte) 0x8a,(byte) 0x92,(byte) 0xa2,(byte) 0xa2,(byte) 0xc2,(byte) 0x82,(byte) 0x0,(byte) 0x28,(byte) 0x14,
+};
+
+static final BitmapCharRec ch209 = new BitmapCharRec(7,12,-1,0,9,ch209data);
+
+/* char: 0xd0 */
+
+static final byte[] ch208data = {
+(byte) 0x7c,(byte) 0x42,(byte) 0x41,(byte) 0x41,(byte) 0xf1,(byte) 0x41,(byte) 0x41,(byte) 0x42,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch208 = new BitmapCharRec(8,9,0,0,9,ch208data);
+
+/* char: 0xcf */
+
+static final byte[] ch207data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch207 = new BitmapCharRec(3,11,0,0,3,ch207data);
+
+/* char: 0xce */
+
+static final byte[] ch206data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch206 = new BitmapCharRec(3,12,0,0,3,ch206data);
+
+/* char: 0xcd */
+
+static final byte[] ch205data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch205 = new BitmapCharRec(2,12,-1,0,3,ch205data);
+
+/* char: 0xcc */
+
+static final byte[] ch204data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch204 = new BitmapCharRec(2,12,0,0,3,ch204data);
+
+/* char: 0xcb */
+
+static final byte[] ch203data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x0,(byte) 0x28,
+};
+
+static final BitmapCharRec ch203 = new BitmapCharRec(6,11,-1,0,8,ch203data);
+
+/* char: 0xca */
+
+static final byte[] ch202data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x0,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch202 = new BitmapCharRec(6,12,-1,0,8,ch202data);
+
+/* char: 0xc9 */
+
+static final byte[] ch201data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch201 = new BitmapCharRec(6,12,-1,0,8,ch201data);
+
+/* char: 0xc8 */
+
+static final byte[] ch200data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch200 = new BitmapCharRec(6,12,-1,0,8,ch200data);
+
+/* char: 0xc7 */
+
+static final byte[] ch199data = {
+(byte) 0x30,(byte) 0x8,(byte) 0x8,(byte) 0x3c,(byte) 0x42,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x42,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch199 = new BitmapCharRec(7,12,-1,3,9,ch199data);
+
+/* char: 0xc6 */
+
+static final byte[] ch198data = {
+(byte) 0x8f,(byte) 0x80,(byte) 0x88,(byte) 0x0,(byte) 0x88,(byte) 0x0,(byte) 0x78,(byte) 0x0,(byte) 0x4f,(byte) 0x80,(byte) 0x48,(byte) 0x0,(byte) 0x28,(byte) 0x0,(byte) 0x28,(byte) 0x0,
+(byte) 0x1f,(byte) 0x80,
+};
+
+static final BitmapCharRec ch198 = new BitmapCharRec(9,9,-1,0,11,ch198data);
+
+/* char: 0xc5 */
+
+static final byte[] ch197data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch197 = new BitmapCharRec(7,12,-1,0,9,ch197data);
+
+/* char: 0xc4 */
+
+static final byte[] ch196data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x28,
+};
+
+static final BitmapCharRec ch196 = new BitmapCharRec(7,11,-1,0,9,ch196data);
+
+/* char: 0xc3 */
+
+static final byte[] ch195data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x28,(byte) 0x14,
+};
+
+static final BitmapCharRec ch195 = new BitmapCharRec(7,12,-1,0,9,ch195data);
+
+/* char: 0xc2 */
+
+static final byte[] ch194data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch194 = new BitmapCharRec(7,12,-1,0,9,ch194data);
+
+/* char: 0xc1 */
+
+static final byte[] ch193data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch193 = new BitmapCharRec(7,12,-1,0,9,ch193data);
+
+/* char: 0xc0 */
+
+static final byte[] ch192data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x10,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch192 = new BitmapCharRec(7,12,-1,0,9,ch192data);
+
+/* char: 0xbf */
+
+static final byte[] ch191data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x0,(byte) 0x20,
+};
+
+static final BitmapCharRec ch191 = new BitmapCharRec(5,9,-1,3,7,ch191data);
+
+/* char: 0xbe */
+
+static final byte[] ch190data = {
+(byte) 0x21,(byte) 0x0,(byte) 0x17,(byte) 0x80,(byte) 0x15,(byte) 0x0,(byte) 0xb,(byte) 0x0,(byte) 0xc9,(byte) 0x0,(byte) 0x24,(byte) 0x0,(byte) 0x44,(byte) 0x0,(byte) 0x22,(byte) 0x0,
+(byte) 0xe1,(byte) 0x0,
+};
+
+static final BitmapCharRec ch190 = new BitmapCharRec(9,9,0,0,10,ch190data);
+
+/* char: 0xbd */
+
+static final byte[] ch189data = {
+(byte) 0x47,(byte) 0x80,(byte) 0x22,(byte) 0x0,(byte) 0x11,(byte) 0x0,(byte) 0x14,(byte) 0x80,(byte) 0x4b,(byte) 0x0,(byte) 0x48,(byte) 0x0,(byte) 0x44,(byte) 0x0,(byte) 0xc2,(byte) 0x0,
+(byte) 0x41,(byte) 0x0,
+};
+
+static final BitmapCharRec ch189 = new BitmapCharRec(9,9,0,0,10,ch189data);
+
+/* char: 0xbc */
+
+static final byte[] ch188data = {
+(byte) 0x41,(byte) 0x0,(byte) 0x27,(byte) 0x80,(byte) 0x15,(byte) 0x0,(byte) 0x13,(byte) 0x0,(byte) 0x49,(byte) 0x0,(byte) 0x44,(byte) 0x0,(byte) 0x44,(byte) 0x0,(byte) 0xc2,(byte) 0x0,
+(byte) 0x41,(byte) 0x0,
+};
+
+static final BitmapCharRec ch188 = new BitmapCharRec(9,9,0,0,10,ch188data);
+
+/* char: 0xbb */
+
+static final byte[] ch187data = {
+(byte) 0xa0,(byte) 0x50,(byte) 0x28,(byte) 0x50,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch187 = new BitmapCharRec(5,5,-1,-1,7,ch187data);
+
+/* char: 0xba */
+
+static final byte[] ch186data = {
+(byte) 0xe0,(byte) 0x0,(byte) 0xe0,(byte) 0xa0,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch186 = new BitmapCharRec(3,5,-1,-4,5,ch186data);
+
+/* char: 0xb9 */
+
+static final byte[] ch185data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch185 = new BitmapCharRec(2,5,-1,-3,4,ch185data);
+
+/* char: 0xb8 */
+
+static final byte[] ch184data = {
+(byte) 0xc0,(byte) 0x20,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch184 = new BitmapCharRec(3,4,0,3,3,ch184data);
+
+/* char: 0xb7 */
+
+static final byte[] ch183data = {
+(byte) 0x80,
+};
+
+static final BitmapCharRec ch183 = new BitmapCharRec(1,1,-1,-3,3,ch183data);
+
+/* char: 0xb6 */
+
+static final byte[] ch182data = {
+(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x68,(byte) 0xe8,(byte) 0xe8,(byte) 0xe8,(byte) 0x68,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch182 = new BitmapCharRec(6,12,0,3,7,ch182data);
+
+/* char: 0xb5 */
+
+static final byte[] ch181data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xe8,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch181 = new BitmapCharRec(5,10,-1,3,7,ch181data);
+
+/* char: 0xb4 */
+
+static final byte[] ch180data = {
+(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch180 = new BitmapCharRec(2,2,0,-8,2,ch180data);
+
+/* char: 0xb3 */
+
+static final byte[] ch179data = {
+(byte) 0xc0,(byte) 0x20,(byte) 0x40,(byte) 0x20,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch179 = new BitmapCharRec(3,5,0,-3,4,ch179data);
+
+/* char: 0xb2 */
+
+static final byte[] ch178data = {
+(byte) 0xf0,(byte) 0x40,(byte) 0x20,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch178 = new BitmapCharRec(4,5,0,-3,4,ch178data);
+
+/* char: 0xb1 */
+
+static final byte[] ch177data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch177 = new BitmapCharRec(5,7,-1,0,7,ch177data);
+
+/* char: 0xb0 */
+
+static final byte[] ch176data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch176 = new BitmapCharRec(4,4,0,-4,5,ch176data);
+
+/* char: 0xaf */
+
+static final byte[] ch175data = {
+(byte) 0xf0,
+};
+
+static final BitmapCharRec ch175 = new BitmapCharRec(4,1,0,-8,4,ch175data);
+
+/* char: 0xae */
+
+static final byte[] ch174data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x41,(byte) 0x0,(byte) 0x94,(byte) 0x80,(byte) 0x94,(byte) 0x80,(byte) 0x98,(byte) 0x80,(byte) 0x94,(byte) 0x80,(byte) 0x9c,(byte) 0x80,(byte) 0x41,(byte) 0x0,
+(byte) 0x3e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch174 = new BitmapCharRec(9,9,-1,0,11,ch174data);
+
+/* char: 0xad */
+
+static final byte[] ch173data = {
+(byte) 0xf0,
+};
+
+static final BitmapCharRec ch173 = new BitmapCharRec(4,1,0,-3,5,ch173data);
+
+/* char: 0xac */
+
+static final byte[] ch172data = {
+(byte) 0x4,(byte) 0x4,(byte) 0x4,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch172 = new BitmapCharRec(6,4,-1,-2,8,ch172data);
+
+/* char: 0xab */
+
+static final byte[] ch171data = {
+(byte) 0x28,(byte) 0x50,(byte) 0xa0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch171 = new BitmapCharRec(5,5,-1,-1,7,ch171data);
+
+/* char: 0xaa */
+
+static final byte[] ch170data = {
+(byte) 0xe0,(byte) 0x0,(byte) 0xa0,(byte) 0x20,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch170 = new BitmapCharRec(3,5,-1,-4,5,ch170data);
+
+/* char: 0xa9 */
+
+static final byte[] ch169data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x41,(byte) 0x0,(byte) 0x9c,(byte) 0x80,(byte) 0xa2,(byte) 0x80,(byte) 0xa0,(byte) 0x80,(byte) 0xa2,(byte) 0x80,(byte) 0x9c,(byte) 0x80,(byte) 0x41,(byte) 0x0,
+(byte) 0x3e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch169 = new BitmapCharRec(9,9,-1,0,11,ch169data);
+
+/* char: 0xa8 */
+
+static final byte[] ch168data = {
+(byte) 0xa0,
+};
+
+static final BitmapCharRec ch168 = new BitmapCharRec(3,1,0,-8,3,ch168data);
+
+/* char: 0xa7 */
+
+static final byte[] ch167data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x8,(byte) 0x30,(byte) 0x48,(byte) 0x88,(byte) 0x88,(byte) 0x90,(byte) 0x60,(byte) 0x80,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch167 = new BitmapCharRec(5,12,0,3,6,ch167data);
+
+/* char: 0xa6 */
+
+static final byte[] ch166data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch166 = new BitmapCharRec(1,11,-1,2,3,ch166data);
+
+/* char: 0xa5 */
+
+static final byte[] ch165data = {
+(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x50,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch165 = new BitmapCharRec(5,9,-1,0,7,ch165data);
+
+/* char: 0xa4 */
+
+static final byte[] ch164data = {
+(byte) 0x84,(byte) 0x78,(byte) 0x48,(byte) 0x48,(byte) 0x78,(byte) 0x84,
+};
+
+static final BitmapCharRec ch164 = new BitmapCharRec(6,6,0,-1,7,ch164data);
+
+/* char: 0xa3 */
+
+static final byte[] ch163data = {
+(byte) 0xb0,(byte) 0x48,(byte) 0x20,(byte) 0x20,(byte) 0xf0,(byte) 0x40,(byte) 0x40,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch163 = new BitmapCharRec(5,9,-1,0,7,ch163data);
+
+/* char: 0xa2 */
+
+static final byte[] ch162data = {
+(byte) 0x40,(byte) 0x70,(byte) 0xc8,(byte) 0xa0,(byte) 0xa0,(byte) 0xa0,(byte) 0xa8,(byte) 0x70,(byte) 0x10,
+};
+
+static final BitmapCharRec ch162 = new BitmapCharRec(5,9,-1,1,7,ch162data);
+
+/* char: 0xa1 */
+
+static final byte[] ch161data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch161 = new BitmapCharRec(1,10,-1,3,3,ch161data);
+
+/* char: 0xa0 */
+
+static final BitmapCharRec ch160 = new BitmapCharRec(0,0,0,0,4,null);
+
+/* char: 0x7e '~' */
+
+static final byte[] ch126data = {
+(byte) 0x98,(byte) 0x64,
+};
+
+static final BitmapCharRec ch126 = new BitmapCharRec(6,2,0,-3,7,ch126data);
+
+/* char: 0x7d '}' */
+
+static final byte[] ch125data = {
+(byte) 0xc0,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x10,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch125 = new BitmapCharRec(4,12,0,3,4,ch125data);
+
+/* char: 0x7c '|' */
+
+static final byte[] ch124data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch124 = new BitmapCharRec(1,12,-1,3,3,ch124data);
+
+/* char: 0x7b '{' */
+
+static final byte[] ch123data = {
+(byte) 0x30,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x30,
+};
+
+static final BitmapCharRec ch123 = new BitmapCharRec(4,12,0,3,4,ch123data);
+
+/* char: 0x7a 'z' */
+
+static final byte[] ch122data = {
+(byte) 0xf0,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch122 = new BitmapCharRec(4,7,-1,0,6,ch122data);
+
+/* char: 0x79 'y' */
+
+static final byte[] ch121data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x50,(byte) 0x50,(byte) 0x90,(byte) 0x88,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch121 = new BitmapCharRec(5,10,-1,3,7,ch121data);
+
+/* char: 0x78 'x' */
+
+static final byte[] ch120data = {
+(byte) 0x84,(byte) 0x84,(byte) 0x48,(byte) 0x30,(byte) 0x30,(byte) 0x48,(byte) 0x84,
+};
+
+static final BitmapCharRec ch120 = new BitmapCharRec(6,7,0,0,6,ch120data);
+
+/* char: 0x77 'w' */
+
+static final byte[] ch119data = {
+(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x55,(byte) 0x0,(byte) 0x49,(byte) 0x0,(byte) 0x49,(byte) 0x0,(byte) 0x88,(byte) 0x80,(byte) 0x88,(byte) 0x80,
+};
+
+static final BitmapCharRec ch119 = new BitmapCharRec(9,7,0,0,9,ch119data);
+
+/* char: 0x76 'v' */
+
+static final byte[] ch118data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x50,(byte) 0x50,(byte) 0x88,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch118 = new BitmapCharRec(5,7,-1,0,7,ch118data);
+
+/* char: 0x75 'u' */
+
+static final byte[] ch117data = {
+(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,
+};
+
+static final BitmapCharRec ch117 = new BitmapCharRec(5,7,-1,0,7,ch117data);
+
+/* char: 0x74 't' */
+
+static final byte[] ch116data = {
+(byte) 0x60,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x40,(byte) 0x40,
+};
+
+static final BitmapCharRec ch116 = new BitmapCharRec(3,9,0,0,3,ch116data);
+
+/* char: 0x73 's' */
+
+static final byte[] ch115data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x10,(byte) 0x60,(byte) 0x80,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch115 = new BitmapCharRec(4,7,-1,0,6,ch115data);
+
+/* char: 0x72 'r' */
+
+static final byte[] ch114data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xc0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch114 = new BitmapCharRec(3,7,-1,0,4,ch114data);
+
+/* char: 0x71 'q' */
+
+static final byte[] ch113data = {
+(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x98,(byte) 0x68,
+};
+
+static final BitmapCharRec ch113 = new BitmapCharRec(5,10,-1,3,7,ch113data);
+
+/* char: 0x70 'p' */
+
+static final byte[] ch112data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xb0,(byte) 0xc8,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,
+};
+
+static final BitmapCharRec ch112 = new BitmapCharRec(5,10,-1,3,7,ch112data);
+
+/* char: 0x6f 'o' */
+
+static final byte[] ch111data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch111 = new BitmapCharRec(5,7,-1,0,7,ch111data);
+
+/* char: 0x6e 'n' */
+
+static final byte[] ch110data = {
+(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,
+};
+
+static final BitmapCharRec ch110 = new BitmapCharRec(5,7,-1,0,7,ch110data);
+
+/* char: 0x6d 'm' */
+
+static final byte[] ch109data = {
+(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0xda,(byte) 0xa4,
+};
+
+static final BitmapCharRec ch109 = new BitmapCharRec(7,7,-1,0,9,ch109data);
+
+/* char: 0x6c 'l' */
+
+static final byte[] ch108data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch108 = new BitmapCharRec(1,9,-1,0,3,ch108data);
+
+/* char: 0x6b 'k' */
+
+static final byte[] ch107data = {
+(byte) 0x88,(byte) 0x90,(byte) 0xa0,(byte) 0xc0,(byte) 0xc0,(byte) 0xa0,(byte) 0x90,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch107 = new BitmapCharRec(5,9,-1,0,6,ch107data);
+
+/* char: 0x6a 'j' */
+
+static final byte[] ch106data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch106 = new BitmapCharRec(2,12,0,3,3,ch106data);
+
+/* char: 0x69 'i' */
+
+static final byte[] ch105data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch105 = new BitmapCharRec(1,9,-1,0,3,ch105data);
+
+/* char: 0x68 'h' */
+
+static final byte[] ch104data = {
+(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch104 = new BitmapCharRec(5,9,-1,0,7,ch104data);
+
+/* char: 0x67 'g' */
+
+static final byte[] ch103data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x8,(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x98,(byte) 0x68,
+};
+
+static final BitmapCharRec ch103 = new BitmapCharRec(5,10,-1,3,7,ch103data);
+
+/* char: 0x66 'f' */
+
+static final byte[] ch102data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x40,(byte) 0x30,
+};
+
+static final BitmapCharRec ch102 = new BitmapCharRec(4,9,0,0,3,ch102data);
+
+/* char: 0x65 'e' */
+
+static final byte[] ch101data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x80,(byte) 0xf8,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch101 = new BitmapCharRec(5,7,-1,0,7,ch101data);
+
+/* char: 0x64 'd' */
+
+static final byte[] ch100data = {
+(byte) 0x68,(byte) 0x98,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x98,(byte) 0x68,(byte) 0x8,(byte) 0x8,
+};
+
+static final BitmapCharRec ch100 = new BitmapCharRec(5,9,-1,0,7,ch100data);
+
+/* char: 0x63 'c' */
+
+static final byte[] ch99data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch99 = new BitmapCharRec(5,7,-1,0,7,ch99data);
+
+/* char: 0x62 'b' */
+
+static final byte[] ch98data = {
+(byte) 0xb0,(byte) 0xc8,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch98 = new BitmapCharRec(5,9,-1,0,7,ch98data);
+
+/* char: 0x61 'a' */
+
+static final byte[] ch97data = {
+(byte) 0x74,(byte) 0x88,(byte) 0x88,(byte) 0x78,(byte) 0x8,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch97 = new BitmapCharRec(6,7,-1,0,7,ch97data);
+
+/* char: 0x60 '`' */
+
+static final byte[] ch96data = {
+(byte) 0xc0,(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch96 = new BitmapCharRec(2,3,0,-6,3,ch96data);
+
+/* char: 0x5f '_' */
+
+static final byte[] ch95data = {
+(byte) 0xfe,
+};
+
+static final BitmapCharRec ch95 = new BitmapCharRec(7,1,0,2,7,ch95data);
+
+/* char: 0x5e '^' */
+
+static final byte[] ch94data = {
+(byte) 0x88,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch94 = new BitmapCharRec(5,3,0,-5,6,ch94data);
+
+/* char: 0x5d ']' */
+
+static final byte[] ch93data = {
+(byte) 0xc0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch93 = new BitmapCharRec(2,12,0,3,3,ch93data);
+
+/* char: 0x5c '\' */
+
+static final byte[] ch92data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch92 = new BitmapCharRec(4,9,0,0,4,ch92data);
+
+/* char: 0x5b '[' */
+
+static final byte[] ch91data = {
+(byte) 0xc0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch91 = new BitmapCharRec(2,12,-1,3,3,ch91data);
+
+/* char: 0x5a 'Z' */
+
+static final byte[] ch90data = {
+(byte) 0xfe,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x4,(byte) 0x2,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch90 = new BitmapCharRec(7,9,-1,0,9,ch90data);
+
+/* char: 0x59 'Y' */
+
+static final byte[] ch89data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch89 = new BitmapCharRec(7,9,-1,0,9,ch89data);
+
+/* char: 0x58 'X' */
+
+static final byte[] ch88data = {
+(byte) 0x82,(byte) 0x44,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0x44,(byte) 0x82,
+};
+
+static final BitmapCharRec ch88 = new BitmapCharRec(7,9,-1,0,9,ch88data);
+
+/* char: 0x57 'W' */
+
+static final byte[] ch87data = {
+(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x55,(byte) 0x0,(byte) 0x55,(byte) 0x0,(byte) 0x49,(byte) 0x0,(byte) 0x88,(byte) 0x80,(byte) 0x88,(byte) 0x80,
+(byte) 0x88,(byte) 0x80,
+};
+
+static final BitmapCharRec ch87 = new BitmapCharRec(9,9,-1,0,11,ch87data);
+
+/* char: 0x56 'V' */
+
+static final byte[] ch86data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x28,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch86 = new BitmapCharRec(7,9,-1,0,9,ch86data);
+
+/* char: 0x55 'U' */
+
+static final byte[] ch85data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x84,
+};
+
+static final BitmapCharRec ch85 = new BitmapCharRec(6,9,-1,0,8,ch85data);
+
+/* char: 0x54 'T' */
+
+static final byte[] ch84data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch84 = new BitmapCharRec(7,9,0,0,7,ch84data);
+
+/* char: 0x53 'S' */
+
+static final byte[] ch83data = {
+(byte) 0x78,(byte) 0x84,(byte) 0x84,(byte) 0x4,(byte) 0x18,(byte) 0x60,(byte) 0x80,(byte) 0x84,(byte) 0x78,
+};
+
+static final BitmapCharRec ch83 = new BitmapCharRec(6,9,-1,0,8,ch83data);
+
+/* char: 0x52 'R' */
+
+static final byte[] ch82data = {
+(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0x88,(byte) 0xf8,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch82 = new BitmapCharRec(6,9,-1,0,8,ch82data);
+
+/* char: 0x51 'Q' */
+
+static final byte[] ch81data = {
+(byte) 0x3d,(byte) 0x42,(byte) 0x85,(byte) 0x89,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x42,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch81 = new BitmapCharRec(8,9,-1,0,10,ch81data);
+
+/* char: 0x50 'P' */
+
+static final byte[] ch80data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch80 = new BitmapCharRec(6,9,-1,0,8,ch80data);
+
+/* char: 0x4f 'O' */
+
+static final byte[] ch79data = {
+(byte) 0x3c,(byte) 0x42,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x81,(byte) 0x42,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch79 = new BitmapCharRec(8,9,-1,0,10,ch79data);
+
+/* char: 0x4e 'N' */
+
+static final byte[] ch78data = {
+(byte) 0x82,(byte) 0x86,(byte) 0x8a,(byte) 0x8a,(byte) 0x92,(byte) 0xa2,(byte) 0xa2,(byte) 0xc2,(byte) 0x82,
+};
+
+static final BitmapCharRec ch78 = new BitmapCharRec(7,9,-1,0,9,ch78data);
+
+/* char: 0x4d 'M' */
+
+static final byte[] ch77data = {
+(byte) 0x88,(byte) 0x80,(byte) 0x88,(byte) 0x80,(byte) 0x94,(byte) 0x80,(byte) 0x94,(byte) 0x80,(byte) 0xa2,(byte) 0x80,(byte) 0xa2,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,
+(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch77 = new BitmapCharRec(9,9,-1,0,11,ch77data);
+
+/* char: 0x4c 'L' */
+
+static final byte[] ch76data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch76 = new BitmapCharRec(5,9,-1,0,7,ch76data);
+
+/* char: 0x4b 'K' */
+
+static final byte[] ch75data = {
+(byte) 0x82,(byte) 0x84,(byte) 0x88,(byte) 0x90,(byte) 0xe0,(byte) 0xa0,(byte) 0x90,(byte) 0x88,(byte) 0x84,
+};
+
+static final BitmapCharRec ch75 = new BitmapCharRec(7,9,-1,0,8,ch75data);
+
+/* char: 0x4a 'J' */
+
+static final byte[] ch74data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,(byte) 0x8,
+};
+
+static final BitmapCharRec ch74 = new BitmapCharRec(5,9,-1,0,7,ch74data);
+
+/* char: 0x49 'I' */
+
+static final byte[] ch73data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch73 = new BitmapCharRec(1,9,-1,0,3,ch73data);
+
+/* char: 0x48 'H' */
+
+static final byte[] ch72data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0xfe,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,
+};
+
+static final BitmapCharRec ch72 = new BitmapCharRec(7,9,-1,0,9,ch72data);
+
+/* char: 0x47 'G' */
+
+static final byte[] ch71data = {
+(byte) 0x3a,(byte) 0x46,(byte) 0x82,(byte) 0x82,(byte) 0x8e,(byte) 0x80,(byte) 0x80,(byte) 0x42,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch71 = new BitmapCharRec(7,9,-1,0,9,ch71data);
+
+/* char: 0x46 'F' */
+
+static final byte[] ch70data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch70 = new BitmapCharRec(6,9,-1,0,8,ch70data);
+
+/* char: 0x45 'E' */
+
+static final byte[] ch69data = {
+(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch69 = new BitmapCharRec(6,9,-1,0,8,ch69data);
+
+/* char: 0x44 'D' */
+
+static final byte[] ch68data = {
+(byte) 0xf8,(byte) 0x84,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x84,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch68 = new BitmapCharRec(7,9,-1,0,9,ch68data);
+
+/* char: 0x43 'C' */
+
+static final byte[] ch67data = {
+(byte) 0x3c,(byte) 0x42,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x42,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch67 = new BitmapCharRec(7,9,-1,0,9,ch67data);
+
+/* char: 0x42 'B' */
+
+static final byte[] ch66data = {
+(byte) 0xf8,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xf8,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch66 = new BitmapCharRec(6,9,-1,0,8,ch66data);
+
+/* char: 0x41 'A' */
+
+static final byte[] ch65data = {
+(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x7c,(byte) 0x44,(byte) 0x44,(byte) 0x28,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch65 = new BitmapCharRec(7,9,-1,0,9,ch65data);
+
+/* char: 0x40 '@' */
+
+static final byte[] ch64data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x40,(byte) 0x0,(byte) 0x9b,(byte) 0x0,(byte) 0xa6,(byte) 0x80,(byte) 0xa2,(byte) 0x40,(byte) 0xa2,(byte) 0x40,(byte) 0x92,(byte) 0x40,(byte) 0x4d,(byte) 0x40,
+(byte) 0x60,(byte) 0x80,(byte) 0x1f,(byte) 0x0,
+};
+
+static final BitmapCharRec ch64 = new BitmapCharRec(10,10,-1,1,12,ch64data);
+
+/* char: 0x3f '?' */
+
+static final byte[] ch63data = {
+(byte) 0x20,(byte) 0x0,(byte) 0x20,(byte) 0x20,(byte) 0x10,(byte) 0x10,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch63 = new BitmapCharRec(5,9,-1,0,7,ch63data);
+
+/* char: 0x3e '>' */
+
+static final byte[] ch62data = {
+(byte) 0xc0,(byte) 0x30,(byte) 0xc,(byte) 0x30,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch62 = new BitmapCharRec(6,5,-1,-1,7,ch62data);
+
+/* char: 0x3d '=' */
+
+static final byte[] ch61data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch61 = new BitmapCharRec(5,3,-1,-2,7,ch61data);
+
+/* char: 0x3c '<' */
+
+static final byte[] ch60data = {
+(byte) 0xc,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc,
+};
+
+static final BitmapCharRec ch60 = new BitmapCharRec(6,5,0,-1,7,ch60data);
+
+/* char: 0x3b ';' */
+
+static final byte[] ch59data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch59 = new BitmapCharRec(2,8,0,2,3,ch59data);
+
+/* char: 0x3a ':' */
+
+static final byte[] ch58data = {
+(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch58 = new BitmapCharRec(1,6,-1,0,3,ch58data);
+
+/* char: 0x39 '9' */
+
+static final byte[] ch57data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x8,(byte) 0x8,(byte) 0x78,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch57 = new BitmapCharRec(5,9,-1,0,7,ch57data);
+
+/* char: 0x38 '8' */
+
+static final byte[] ch56data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch56 = new BitmapCharRec(5,9,-1,0,7,ch56data);
+
+/* char: 0x37 '7' */
+
+static final byte[] ch55data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x10,(byte) 0x10,(byte) 0x8,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch55 = new BitmapCharRec(5,9,-1,0,7,ch55data);
+
+/* char: 0x36 '6' */
+
+static final byte[] ch54data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0xc8,(byte) 0xb0,(byte) 0x80,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch54 = new BitmapCharRec(5,9,-1,0,7,ch54data);
+
+/* char: 0x35 '5' */
+
+static final byte[] ch53data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x8,(byte) 0x8,(byte) 0xf0,(byte) 0x80,(byte) 0x80,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch53 = new BitmapCharRec(5,9,-1,0,7,ch53data);
+
+/* char: 0x34 '4' */
+
+static final byte[] ch52data = {
+(byte) 0x8,(byte) 0x8,(byte) 0xfc,(byte) 0x88,(byte) 0x48,(byte) 0x28,(byte) 0x28,(byte) 0x18,(byte) 0x8,
+};
+
+static final BitmapCharRec ch52 = new BitmapCharRec(6,9,0,0,7,ch52data);
+
+/* char: 0x33 '3' */
+
+static final byte[] ch51data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x8,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch51 = new BitmapCharRec(5,9,-1,0,7,ch51data);
+
+/* char: 0x32 '2' */
+
+static final byte[] ch50data = {
+(byte) 0xf8,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x8,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch50 = new BitmapCharRec(5,9,-1,0,7,ch50data);
+
+/* char: 0x31 '1' */
+
+static final byte[] ch49data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xe0,(byte) 0x20,
+};
+
+static final BitmapCharRec ch49 = new BitmapCharRec(3,9,-1,0,7,ch49data);
+
+/* char: 0x30 '0' */
+
+static final byte[] ch48data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x88,(byte) 0x70,
+};
+
+static final BitmapCharRec ch48 = new BitmapCharRec(5,9,-1,0,7,ch48data);
+
+/* char: 0x2f '/' */
+
+static final byte[] ch47data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x10,(byte) 0x10,
+};
+
+static final BitmapCharRec ch47 = new BitmapCharRec(4,9,0,0,4,ch47data);
+
+/* char: 0x2e '.' */
+
+static final byte[] ch46data = {
+(byte) 0x80,
+};
+
+static final BitmapCharRec ch46 = new BitmapCharRec(1,1,-1,0,3,ch46data);
+
+/* char: 0x2d '-' */
+
+static final byte[] ch45data = {
+(byte) 0xf8,
+};
+
+static final BitmapCharRec ch45 = new BitmapCharRec(5,1,-1,-3,8,ch45data);
+
+/* char: 0x2c ',' */
+
+static final byte[] ch44data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,
+};
+
+static final BitmapCharRec ch44 = new BitmapCharRec(2,3,-1,2,4,ch44data);
+
+/* char: 0x2b '+' */
+
+static final byte[] ch43data = {
+(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch43 = new BitmapCharRec(5,5,-1,-1,7,ch43data);
+
+/* char: 0x2a '*' */
+
+static final byte[] ch42data = {
+(byte) 0xa0,(byte) 0x40,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch42 = new BitmapCharRec(3,3,-1,-6,5,ch42data);
+
+/* char: 0x29 ')' */
+
+static final byte[] ch41data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch41 = new BitmapCharRec(3,12,0,3,4,ch41data);
+
+/* char: 0x28 '(' */
+
+static final byte[] ch40data = {
+(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch40 = new BitmapCharRec(3,12,-1,3,4,ch40data);
+
+/* char: 0x27 ''' */
+
+static final byte[] ch39data = {
+(byte) 0x80,(byte) 0x40,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch39 = new BitmapCharRec(2,3,-1,-6,3,ch39data);
+
+/* char: 0x26 '&' */
+
+static final byte[] ch38data = {
+(byte) 0x72,(byte) 0x8c,(byte) 0x84,(byte) 0x8a,(byte) 0x50,(byte) 0x30,(byte) 0x48,(byte) 0x48,(byte) 0x30,
+};
+
+static final BitmapCharRec ch38 = new BitmapCharRec(7,9,-1,0,9,ch38data);
+
+/* char: 0x25 '%' */
+
+static final byte[] ch37data = {
+(byte) 0x23,(byte) 0x0,(byte) 0x14,(byte) 0x80,(byte) 0x14,(byte) 0x80,(byte) 0x13,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x68,(byte) 0x0,(byte) 0x94,(byte) 0x0,(byte) 0x94,(byte) 0x0,
+(byte) 0x62,(byte) 0x0,
+};
+
+static final BitmapCharRec ch37 = new BitmapCharRec(9,9,-1,0,11,ch37data);
+
+/* char: 0x24 '$' */
+
+static final byte[] ch36data = {
+(byte) 0x20,(byte) 0x70,(byte) 0xa8,(byte) 0xa8,(byte) 0x28,(byte) 0x70,(byte) 0xa0,(byte) 0xa8,(byte) 0x70,(byte) 0x20,
+};
+
+static final BitmapCharRec ch36 = new BitmapCharRec(5,10,-1,1,7,ch36data);
+
+/* char: 0x23 '#' */
+
+static final byte[] ch35data = {
+(byte) 0x50,(byte) 0x50,(byte) 0x50,(byte) 0xfc,(byte) 0x28,(byte) 0xfc,(byte) 0x28,(byte) 0x28,
+};
+
+static final BitmapCharRec ch35 = new BitmapCharRec(6,8,0,0,7,ch35data);
+
+/* char: 0x22 '"' */
+
+static final byte[] ch34data = {
+(byte) 0xa0,(byte) 0xa0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch34 = new BitmapCharRec(3,3,-1,-6,5,ch34data);
+
+/* char: 0x21 '!' */
+
+static final byte[] ch33data = {
+(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch33 = new BitmapCharRec(1,9,-1,0,3,ch33data);
+
+/* char: 0x20 ' ' */
+
+static final BitmapCharRec ch32 = new BitmapCharRec(0,0,0,0,4,null);
+
+static final BitmapCharRec[] chars = {
+ch32,
+ch33,
+ch34,
+ch35,
+ch36,
+ch37,
+ch38,
+ch39,
+ch40,
+ch41,
+ch42,
+ch43,
+ch44,
+ch45,
+ch46,
+ch47,
+ch48,
+ch49,
+ch50,
+ch51,
+ch52,
+ch53,
+ch54,
+ch55,
+ch56,
+ch57,
+ch58,
+ch59,
+ch60,
+ch61,
+ch62,
+ch63,
+ch64,
+ch65,
+ch66,
+ch67,
+ch68,
+ch69,
+ch70,
+ch71,
+ch72,
+ch73,
+ch74,
+ch75,
+ch76,
+ch77,
+ch78,
+ch79,
+ch80,
+ch81,
+ch82,
+ch83,
+ch84,
+ch85,
+ch86,
+ch87,
+ch88,
+ch89,
+ch90,
+ch91,
+ch92,
+ch93,
+ch94,
+ch95,
+ch96,
+ch97,
+ch98,
+ch99,
+ch100,
+ch101,
+ch102,
+ch103,
+ch104,
+ch105,
+ch106,
+ch107,
+ch108,
+ch109,
+ch110,
+ch111,
+ch112,
+ch113,
+ch114,
+ch115,
+ch116,
+ch117,
+ch118,
+ch119,
+ch120,
+ch121,
+ch122,
+ch123,
+ch124,
+ch125,
+ch126,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+ch160,
+ch161,
+ch162,
+ch163,
+ch164,
+ch165,
+ch166,
+ch167,
+ch168,
+ch169,
+ch170,
+ch171,
+ch172,
+ch173,
+ch174,
+ch175,
+ch176,
+ch177,
+ch178,
+ch179,
+ch180,
+ch181,
+ch182,
+ch183,
+ch184,
+ch185,
+ch186,
+ch187,
+ch188,
+ch189,
+ch190,
+ch191,
+ch192,
+ch193,
+ch194,
+ch195,
+ch196,
+ch197,
+ch198,
+ch199,
+ch200,
+ch201,
+ch202,
+ch203,
+ch204,
+ch205,
+ch206,
+ch207,
+ch208,
+ch209,
+ch210,
+ch211,
+ch212,
+ch213,
+ch214,
+ch215,
+ch216,
+ch217,
+ch218,
+ch219,
+ch220,
+ch221,
+ch222,
+ch223,
+ch224,
+ch225,
+ch226,
+ch227,
+ch228,
+ch229,
+ch230,
+ch231,
+ch232,
+ch233,
+ch234,
+ch235,
+ch236,
+ch237,
+ch238,
+ch239,
+ch240,
+ch241,
+ch242,
+ch243,
+ch244,
+ch245,
+ch246,
+ch247,
+ch248,
+ch249,
+ch250,
+ch251,
+ch252,
+ch253,
+ch254,
+ch255,
+};
+
+ public static final BitmapFontRec glutBitmapHelvetica12 = new BitmapFontRec("-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1",
+ 224,
+ 32,
+ chars);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica18.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica18.java
new file mode 100644
index 000000000..1b2e69ba4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapHelvetica18.java
@@ -0,0 +1,1917 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+class GLUTBitmapHelvetica18 {
+
+/* GENERATED FILE -- DO NOT MODIFY */
+
+/* char: 0xff */
+
+static final byte[] ch255data = {
+(byte) 0x70,(byte) 0x70,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x3c,(byte) 0x24,(byte) 0x66,(byte) 0x66,(byte) 0x66,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0x0,(byte) 0x66,
+(byte) 0x66,
+};
+
+static final BitmapCharRec ch255 = new BitmapCharRec(8,17,-1,4,10,ch255data);
+
+/* char: 0xfe */
+
+static final byte[] ch254data = {
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xde,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xe3,(byte) 0x0,(byte) 0xc1,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xe3,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xde,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch254 = new BitmapCharRec(9,18,-1,4,11,ch254data);
+
+/* char: 0xfd */
+
+static final byte[] ch253data = {
+(byte) 0x70,(byte) 0x70,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x3c,(byte) 0x24,(byte) 0x66,(byte) 0x66,(byte) 0x66,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0x0,(byte) 0x18,
+(byte) 0xc,(byte) 0x6,
+};
+
+static final BitmapCharRec ch253 = new BitmapCharRec(8,18,-1,4,10,ch253data);
+
+/* char: 0xfc */
+
+static final byte[] ch252data = {
+(byte) 0x73,(byte) 0xfb,(byte) 0xc7,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0x0,(byte) 0x66,(byte) 0x66,
+};
+
+static final BitmapCharRec ch252 = new BitmapCharRec(8,13,-1,0,10,ch252data);
+
+/* char: 0xfb */
+
+static final byte[] ch251data = {
+(byte) 0x73,(byte) 0xfb,(byte) 0xc7,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0x0,(byte) 0x66,(byte) 0x3c,(byte) 0x18,
+};
+
+static final BitmapCharRec ch251 = new BitmapCharRec(8,14,-1,0,10,ch251data);
+
+/* char: 0xfa */
+
+static final byte[] ch250data = {
+(byte) 0x73,(byte) 0xfb,(byte) 0xc7,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0x0,(byte) 0x18,(byte) 0xc,(byte) 0x6,
+};
+
+static final BitmapCharRec ch250 = new BitmapCharRec(8,14,-1,0,10,ch250data);
+
+/* char: 0xf9 */
+
+static final byte[] ch249data = {
+(byte) 0x73,(byte) 0xfb,(byte) 0xc7,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0x0,(byte) 0xc,(byte) 0x18,(byte) 0x30,
+};
+
+static final BitmapCharRec ch249 = new BitmapCharRec(8,14,-1,0,10,ch249data);
+
+/* char: 0xf8 */
+
+static final byte[] ch248data = {
+(byte) 0xce,(byte) 0x0,(byte) 0x7f,(byte) 0x80,(byte) 0x31,(byte) 0x80,(byte) 0x78,(byte) 0xc0,(byte) 0x6c,(byte) 0xc0,(byte) 0x66,(byte) 0xc0,(byte) 0x63,(byte) 0xc0,(byte) 0x31,(byte) 0x80,
+(byte) 0x3f,(byte) 0xc0,(byte) 0xe,(byte) 0x60,
+};
+
+static final BitmapCharRec ch248 = new BitmapCharRec(11,10,0,0,11,ch248data);
+
+/* char: 0xf7 */
+
+static final byte[] ch247data = {
+(byte) 0x18,(byte) 0x18,(byte) 0x0,(byte) 0xff,(byte) 0xff,(byte) 0x0,(byte) 0x18,(byte) 0x18,
+};
+
+static final BitmapCharRec ch247 = new BitmapCharRec(8,8,-1,-1,10,ch247data);
+
+/* char: 0xf6 */
+
+static final byte[] ch246data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x63,(byte) 0x0,
+(byte) 0x7f,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x36,(byte) 0x0,(byte) 0x36,(byte) 0x0,
+};
+
+static final BitmapCharRec ch246 = new BitmapCharRec(9,13,-1,0,11,ch246data);
+
+/* char: 0xf5 */
+
+static final byte[] ch245data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x63,(byte) 0x0,
+(byte) 0x7f,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x26,(byte) 0x0,(byte) 0x2d,(byte) 0x0,(byte) 0x19,(byte) 0x0,
+};
+
+static final BitmapCharRec ch245 = new BitmapCharRec(9,14,-1,0,11,ch245data);
+
+/* char: 0xf4 */
+
+static final byte[] ch244data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x63,(byte) 0x0,
+(byte) 0x7f,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0xc,(byte) 0x0,
+};
+
+static final BitmapCharRec ch244 = new BitmapCharRec(9,14,-1,0,11,ch244data);
+
+/* char: 0xf3 */
+
+static final byte[] ch243data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x63,(byte) 0x0,
+(byte) 0x7f,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+};
+
+static final BitmapCharRec ch243 = new BitmapCharRec(9,14,-1,0,11,ch243data);
+
+/* char: 0xf2 */
+
+static final byte[] ch242data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x63,(byte) 0x0,
+(byte) 0x7f,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x30,(byte) 0x0,
+};
+
+static final BitmapCharRec ch242 = new BitmapCharRec(9,14,-1,0,11,ch242data);
+
+/* char: 0xf1 */
+
+static final byte[] ch241data = {
+(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xe3,(byte) 0xdf,(byte) 0xce,(byte) 0x0,(byte) 0x4c,(byte) 0x5a,(byte) 0x32,
+};
+
+static final BitmapCharRec ch241 = new BitmapCharRec(8,14,-1,0,10,ch241data);
+
+/* char: 0xf0 */
+
+static final byte[] ch240data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x63,(byte) 0x0,
+(byte) 0x7f,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x4c,(byte) 0x0,(byte) 0x38,(byte) 0x0,(byte) 0x36,(byte) 0x0,(byte) 0x60,(byte) 0x0,
+};
+
+static final BitmapCharRec ch240 = new BitmapCharRec(9,14,-1,0,11,ch240data);
+
+/* char: 0xef */
+
+static final byte[] ch239data = {
+(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x0,(byte) 0xd8,(byte) 0xd8,
+};
+
+static final BitmapCharRec ch239 = new BitmapCharRec(5,13,0,0,4,ch239data);
+
+/* char: 0xee */
+
+static final byte[] ch238data = {
+(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x0,(byte) 0xcc,(byte) 0x78,(byte) 0x30,
+};
+
+static final BitmapCharRec ch238 = new BitmapCharRec(6,14,1,0,4,ch238data);
+
+/* char: 0xed */
+
+static final byte[] ch237data = {
+(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x0,(byte) 0xc0,(byte) 0x60,(byte) 0x30,
+};
+
+static final BitmapCharRec ch237 = new BitmapCharRec(4,14,0,0,4,ch237data);
+
+/* char: 0xec */
+
+static final byte[] ch236data = {
+(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x0,(byte) 0x30,(byte) 0x60,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch236 = new BitmapCharRec(4,14,0,0,4,ch236data);
+
+/* char: 0xeb */
+
+static final byte[] ch235data = {
+(byte) 0x3c,(byte) 0x7f,(byte) 0xe3,(byte) 0xc0,(byte) 0xc0,(byte) 0xff,(byte) 0xc3,(byte) 0xc3,(byte) 0x7e,(byte) 0x3c,(byte) 0x0,(byte) 0x36,(byte) 0x36,
+};
+
+static final BitmapCharRec ch235 = new BitmapCharRec(8,13,-1,0,10,ch235data);
+
+/* char: 0xea */
+
+static final byte[] ch234data = {
+(byte) 0x3c,(byte) 0x7f,(byte) 0xe3,(byte) 0xc0,(byte) 0xc0,(byte) 0xff,(byte) 0xc3,(byte) 0xc3,(byte) 0x7e,(byte) 0x3c,(byte) 0x0,(byte) 0x66,(byte) 0x3c,(byte) 0x18,
+};
+
+static final BitmapCharRec ch234 = new BitmapCharRec(8,14,-1,0,10,ch234data);
+
+/* char: 0xe9 */
+
+static final byte[] ch233data = {
+(byte) 0x3c,(byte) 0x7f,(byte) 0xe3,(byte) 0xc0,(byte) 0xc0,(byte) 0xff,(byte) 0xc3,(byte) 0xc3,(byte) 0x7e,(byte) 0x3c,(byte) 0x0,(byte) 0x18,(byte) 0xc,(byte) 0x6,
+};
+
+static final BitmapCharRec ch233 = new BitmapCharRec(8,14,-1,0,10,ch233data);
+
+/* char: 0xe8 */
+
+static final byte[] ch232data = {
+(byte) 0x3c,(byte) 0x7f,(byte) 0xe3,(byte) 0xc0,(byte) 0xc0,(byte) 0xff,(byte) 0xc3,(byte) 0xc3,(byte) 0x7e,(byte) 0x3c,(byte) 0x0,(byte) 0x18,(byte) 0x30,(byte) 0x60,
+};
+
+static final BitmapCharRec ch232 = new BitmapCharRec(8,14,-1,0,10,ch232data);
+
+/* char: 0xe7 */
+
+static final byte[] ch231data = {
+(byte) 0x78,(byte) 0x6c,(byte) 0xc,(byte) 0x38,(byte) 0x3e,(byte) 0x7f,(byte) 0x63,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x63,(byte) 0x7f,(byte) 0x3e,
+};
+
+static final BitmapCharRec ch231 = new BitmapCharRec(8,14,-1,4,10,ch231data);
+
+/* char: 0xe6 */
+
+static final byte[] ch230data = {
+(byte) 0x75,(byte) 0xe0,(byte) 0xef,(byte) 0xf8,(byte) 0xc7,(byte) 0x18,(byte) 0xc6,(byte) 0x0,(byte) 0xe6,(byte) 0x0,(byte) 0x7f,(byte) 0xf8,(byte) 0xe,(byte) 0x18,(byte) 0xc6,(byte) 0x18,
+(byte) 0xef,(byte) 0xf0,(byte) 0x7d,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch230 = new BitmapCharRec(13,10,-1,0,15,ch230data);
+
+/* char: 0xe5 */
+
+static final byte[] ch229data = {
+(byte) 0x76,(byte) 0xee,(byte) 0xc6,(byte) 0xc6,(byte) 0xe6,(byte) 0x7e,(byte) 0xe,(byte) 0xc6,(byte) 0xee,(byte) 0x7c,(byte) 0x38,(byte) 0x6c,(byte) 0x6c,(byte) 0x38,
+};
+
+static final BitmapCharRec ch229 = new BitmapCharRec(7,14,-1,0,9,ch229data);
+
+/* char: 0xe4 */
+
+static final byte[] ch228data = {
+(byte) 0x76,(byte) 0xee,(byte) 0xc6,(byte) 0xc6,(byte) 0xe6,(byte) 0x7e,(byte) 0xe,(byte) 0xc6,(byte) 0xee,(byte) 0x7c,(byte) 0x0,(byte) 0x6c,(byte) 0x6c,
+};
+
+static final BitmapCharRec ch228 = new BitmapCharRec(7,13,-1,0,9,ch228data);
+
+/* char: 0xe3 */
+
+static final byte[] ch227data = {
+(byte) 0x76,(byte) 0xee,(byte) 0xc6,(byte) 0xc6,(byte) 0xe6,(byte) 0x7e,(byte) 0xe,(byte) 0xc6,(byte) 0xee,(byte) 0x7c,(byte) 0x0,(byte) 0x4c,(byte) 0x5a,(byte) 0x32,
+};
+
+static final BitmapCharRec ch227 = new BitmapCharRec(7,14,-1,0,9,ch227data);
+
+/* char: 0xe2 */
+
+static final byte[] ch226data = {
+(byte) 0x76,(byte) 0xee,(byte) 0xc6,(byte) 0xc6,(byte) 0xe6,(byte) 0x7e,(byte) 0xe,(byte) 0xc6,(byte) 0xee,(byte) 0x7c,(byte) 0x0,(byte) 0x66,(byte) 0x3c,(byte) 0x18,
+};
+
+static final BitmapCharRec ch226 = new BitmapCharRec(7,14,-1,0,9,ch226data);
+
+/* char: 0xe1 */
+
+static final byte[] ch225data = {
+(byte) 0x76,(byte) 0xee,(byte) 0xc6,(byte) 0xc6,(byte) 0xe6,(byte) 0x7e,(byte) 0xe,(byte) 0xc6,(byte) 0xee,(byte) 0x7c,(byte) 0x0,(byte) 0x30,(byte) 0x18,(byte) 0xc,
+};
+
+static final BitmapCharRec ch225 = new BitmapCharRec(7,14,-1,0,9,ch225data);
+
+/* char: 0xe0 */
+
+static final byte[] ch224data = {
+(byte) 0x76,(byte) 0xee,(byte) 0xc6,(byte) 0xc6,(byte) 0xe6,(byte) 0x7e,(byte) 0xe,(byte) 0xc6,(byte) 0xee,(byte) 0x7c,(byte) 0x0,(byte) 0x18,(byte) 0x30,(byte) 0x60,
+};
+
+static final BitmapCharRec ch224 = new BitmapCharRec(7,14,-1,0,9,ch224data);
+
+/* char: 0xdf */
+
+static final byte[] ch223data = {
+(byte) 0xdc,(byte) 0xde,(byte) 0xc6,(byte) 0xc6,(byte) 0xc6,(byte) 0xc6,(byte) 0xdc,(byte) 0xdc,(byte) 0xc6,(byte) 0xc6,(byte) 0xc6,(byte) 0xc6,(byte) 0x7c,(byte) 0x38,
+};
+
+static final BitmapCharRec ch223 = new BitmapCharRec(7,14,-1,0,9,ch223data);
+
+/* char: 0xde */
+
+static final byte[] ch222data = {
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0xc1,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc1,(byte) 0xc0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch222 = new BitmapCharRec(10,14,-1,0,12,ch222data);
+
+/* char: 0xdd */
+
+static final byte[] ch221data = {
+(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x19,(byte) 0x80,
+(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0x0,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x1,(byte) 0x80,
+};
+
+static final BitmapCharRec ch221 = new BitmapCharRec(12,18,-1,0,14,ch221data);
+
+/* char: 0xdc */
+
+static final byte[] ch220data = {
+(byte) 0x1f,(byte) 0x0,(byte) 0x7f,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,
+(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0x0,(byte) 0x0,(byte) 0x19,(byte) 0x80,
+(byte) 0x19,(byte) 0x80,
+};
+
+static final BitmapCharRec ch220 = new BitmapCharRec(11,17,-1,0,13,ch220data);
+
+/* char: 0xdb */
+
+static final byte[] ch219data = {
+(byte) 0x1f,(byte) 0x0,(byte) 0x7f,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,
+(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0x0,(byte) 0x0,(byte) 0x19,(byte) 0x80,
+(byte) 0xf,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+};
+
+static final BitmapCharRec ch219 = new BitmapCharRec(11,18,-1,0,13,ch219data);
+
+/* char: 0xda */
+
+static final byte[] ch218data = {
+(byte) 0x1f,(byte) 0x0,(byte) 0x7f,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,
+(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0x0,(byte) 0x0,(byte) 0xc,(byte) 0x0,
+(byte) 0x6,(byte) 0x0,(byte) 0x3,(byte) 0x0,
+};
+
+static final BitmapCharRec ch218 = new BitmapCharRec(11,18,-1,0,13,ch218data);
+
+/* char: 0xd9 */
+
+static final byte[] ch217data = {
+(byte) 0x1f,(byte) 0x0,(byte) 0x7f,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,
+(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0x0,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0x0,
+};
+
+static final BitmapCharRec ch217 = new BitmapCharRec(11,18,-1,0,13,ch217data);
+
+/* char: 0xd8 */
+
+static final byte[] ch216data = {
+(byte) 0xc7,(byte) 0xc0,(byte) 0xff,(byte) 0xf0,(byte) 0x78,(byte) 0x38,(byte) 0x38,(byte) 0x18,(byte) 0x6c,(byte) 0x1c,(byte) 0x6e,(byte) 0xc,(byte) 0x67,(byte) 0xc,(byte) 0x63,(byte) 0x8c,
+(byte) 0x61,(byte) 0xcc,(byte) 0x70,(byte) 0xdc,(byte) 0x30,(byte) 0x78,(byte) 0x38,(byte) 0x38,(byte) 0x1f,(byte) 0xfc,(byte) 0x7,(byte) 0xcc,
+};
+
+static final BitmapCharRec ch216 = new BitmapCharRec(14,14,0,0,15,ch216data);
+
+/* char: 0xd7 */
+
+static final byte[] ch215data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x33,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x61,(byte) 0x80,
+(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch215 = new BitmapCharRec(10,9,0,0,10,ch215data);
+
+/* char: 0xd6 */
+
+static final byte[] ch214data = {
+(byte) 0xf,(byte) 0x80,(byte) 0x3f,(byte) 0xe0,(byte) 0x70,(byte) 0x70,(byte) 0x60,(byte) 0x30,(byte) 0xe0,(byte) 0x38,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,
+(byte) 0xc0,(byte) 0x18,(byte) 0xe0,(byte) 0x38,(byte) 0x60,(byte) 0x30,(byte) 0x70,(byte) 0x70,(byte) 0x3f,(byte) 0xe0,(byte) 0xf,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0xd,(byte) 0x80,
+(byte) 0xd,(byte) 0x80,
+};
+
+static final BitmapCharRec ch214 = new BitmapCharRec(13,17,-1,0,15,ch214data);
+
+/* char: 0xd5 */
+
+static final byte[] ch213data = {
+(byte) 0xf,(byte) 0x80,(byte) 0x3f,(byte) 0xe0,(byte) 0x70,(byte) 0x70,(byte) 0x60,(byte) 0x30,(byte) 0xe0,(byte) 0x38,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,
+(byte) 0xc0,(byte) 0x18,(byte) 0xe0,(byte) 0x38,(byte) 0x60,(byte) 0x30,(byte) 0x70,(byte) 0x70,(byte) 0x3f,(byte) 0xe0,(byte) 0xf,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x9,(byte) 0x80,
+(byte) 0xb,(byte) 0x40,(byte) 0x6,(byte) 0x40,
+};
+
+static final BitmapCharRec ch213 = new BitmapCharRec(13,18,-1,0,15,ch213data);
+
+/* char: 0xd4 */
+
+static final byte[] ch212data = {
+(byte) 0xf,(byte) 0x80,(byte) 0x3f,(byte) 0xe0,(byte) 0x70,(byte) 0x70,(byte) 0x60,(byte) 0x30,(byte) 0xe0,(byte) 0x38,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,
+(byte) 0xc0,(byte) 0x18,(byte) 0xe0,(byte) 0x38,(byte) 0x60,(byte) 0x30,(byte) 0x70,(byte) 0x70,(byte) 0x3f,(byte) 0xe0,(byte) 0xf,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0xc,(byte) 0xc0,
+(byte) 0x7,(byte) 0x80,(byte) 0x3,(byte) 0x0,
+};
+
+static final BitmapCharRec ch212 = new BitmapCharRec(13,18,-1,0,15,ch212data);
+
+/* char: 0xd3 */
+
+static final byte[] ch211data = {
+(byte) 0xf,(byte) 0x80,(byte) 0x3f,(byte) 0xe0,(byte) 0x70,(byte) 0x70,(byte) 0x60,(byte) 0x30,(byte) 0xe0,(byte) 0x38,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,
+(byte) 0xc0,(byte) 0x18,(byte) 0xe0,(byte) 0x38,(byte) 0x60,(byte) 0x30,(byte) 0x70,(byte) 0x70,(byte) 0x3f,(byte) 0xe0,(byte) 0xf,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x3,(byte) 0x0,
+(byte) 0x1,(byte) 0x80,(byte) 0x0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch211 = new BitmapCharRec(13,18,-1,0,15,ch211data);
+
+/* char: 0xd2 */
+
+static final byte[] ch210data = {
+(byte) 0xf,(byte) 0x80,(byte) 0x3f,(byte) 0xe0,(byte) 0x70,(byte) 0x70,(byte) 0x60,(byte) 0x30,(byte) 0xe0,(byte) 0x38,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,
+(byte) 0xc0,(byte) 0x18,(byte) 0xe0,(byte) 0x38,(byte) 0x60,(byte) 0x30,(byte) 0x70,(byte) 0x70,(byte) 0x3f,(byte) 0xe0,(byte) 0xf,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x3,(byte) 0x0,
+(byte) 0x6,(byte) 0x0,(byte) 0xc,(byte) 0x0,
+};
+
+static final BitmapCharRec ch210 = new BitmapCharRec(13,18,-1,0,15,ch210data);
+
+/* char: 0xd1 */
+
+static final byte[] ch209data = {
+(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xe0,(byte) 0xc1,(byte) 0xe0,(byte) 0xc1,(byte) 0xe0,(byte) 0xc3,(byte) 0x60,(byte) 0xc6,(byte) 0x60,(byte) 0xc6,(byte) 0x60,(byte) 0xcc,(byte) 0x60,
+(byte) 0xcc,(byte) 0x60,(byte) 0xd8,(byte) 0x60,(byte) 0xd8,(byte) 0x60,(byte) 0xf0,(byte) 0x60,(byte) 0xe0,(byte) 0x60,(byte) 0xe0,(byte) 0x60,(byte) 0x0,(byte) 0x0,(byte) 0x13,(byte) 0x0,
+(byte) 0x16,(byte) 0x80,(byte) 0xc,(byte) 0x80,
+};
+
+static final BitmapCharRec ch209 = new BitmapCharRec(11,18,-1,0,13,ch209data);
+
+/* char: 0xd0 */
+
+static final byte[] ch208data = {
+(byte) 0x7f,(byte) 0x80,(byte) 0x7f,(byte) 0xc0,(byte) 0x60,(byte) 0xe0,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x30,(byte) 0x60,(byte) 0x30,(byte) 0xfc,(byte) 0x30,(byte) 0xfc,(byte) 0x30,
+(byte) 0x60,(byte) 0x30,(byte) 0x60,(byte) 0x30,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0xe0,(byte) 0x7f,(byte) 0xc0,(byte) 0x7f,(byte) 0x80,
+};
+
+static final BitmapCharRec ch208 = new BitmapCharRec(12,14,0,0,13,ch208data);
+
+/* char: 0xcf */
+
+static final byte[] ch207data = {
+(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x0,(byte) 0xcc,
+(byte) 0xcc,
+};
+
+static final BitmapCharRec ch207 = new BitmapCharRec(6,17,0,0,6,ch207data);
+
+/* char: 0xce */
+
+static final byte[] ch206data = {
+(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x0,(byte) 0xcc,
+(byte) 0x78,(byte) 0x30,
+};
+
+static final BitmapCharRec ch206 = new BitmapCharRec(6,18,0,0,6,ch206data);
+
+/* char: 0xcd */
+
+static final byte[] ch205data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,
+(byte) 0x60,(byte) 0x30,
+};
+
+static final BitmapCharRec ch205 = new BitmapCharRec(4,18,-2,0,6,ch205data);
+
+/* char: 0xcc */
+
+static final byte[] ch204data = {
+(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x0,(byte) 0x30,
+(byte) 0x60,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch204 = new BitmapCharRec(4,18,0,0,6,ch204data);
+
+/* char: 0xcb */
+
+static final byte[] ch203data = {
+(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xff,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x33,(byte) 0x0,
+(byte) 0x33,(byte) 0x0,
+};
+
+static final BitmapCharRec ch203 = new BitmapCharRec(9,17,-1,0,11,ch203data);
+
+/* char: 0xca */
+
+static final byte[] ch202data = {
+(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xff,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x33,(byte) 0x0,
+(byte) 0x1e,(byte) 0x0,(byte) 0xc,(byte) 0x0,
+};
+
+static final BitmapCharRec ch202 = new BitmapCharRec(9,18,-1,0,11,ch202data);
+
+/* char: 0xc9 */
+
+static final byte[] ch201data = {
+(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xff,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0xc,(byte) 0x0,
+(byte) 0x6,(byte) 0x0,(byte) 0x3,(byte) 0x0,
+};
+
+static final BitmapCharRec ch201 = new BitmapCharRec(9,18,-1,0,11,ch201data);
+
+/* char: 0xc8 */
+
+static final byte[] ch200data = {
+(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xff,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0xc,(byte) 0x0,
+(byte) 0x18,(byte) 0x0,(byte) 0x30,(byte) 0x0,
+};
+
+static final BitmapCharRec ch200 = new BitmapCharRec(9,18,-1,0,11,ch200data);
+
+/* char: 0xc7 */
+
+static final byte[] ch199data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x1b,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0xe,(byte) 0x0,(byte) 0xf,(byte) 0x80,(byte) 0x3f,(byte) 0xe0,(byte) 0x70,(byte) 0x70,(byte) 0x60,(byte) 0x30,
+(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xe0,(byte) 0x0,(byte) 0x60,(byte) 0x30,(byte) 0x70,(byte) 0x70,
+(byte) 0x3f,(byte) 0xe0,(byte) 0xf,(byte) 0x80,
+};
+
+static final BitmapCharRec ch199 = new BitmapCharRec(12,18,-1,4,14,ch199data);
+
+/* char: 0xc6 */
+
+static final byte[] ch198data = {
+(byte) 0xc1,(byte) 0xff,(byte) 0xc1,(byte) 0xff,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x7f,(byte) 0x80,(byte) 0x3f,(byte) 0x80,(byte) 0x31,(byte) 0xfe,(byte) 0x31,(byte) 0xfe,
+(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0xd,(byte) 0x80,(byte) 0xd,(byte) 0x80,(byte) 0x7,(byte) 0xff,(byte) 0x7,(byte) 0xff,
+};
+
+static final BitmapCharRec ch198 = new BitmapCharRec(16,14,-1,0,18,ch198data);
+
+/* char: 0xc5 */
+
+static final byte[] ch197data = {
+(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x7f,(byte) 0xe0,(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,
+(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0xf,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x19,(byte) 0x80,
+(byte) 0x19,(byte) 0x80,(byte) 0xf,(byte) 0x0,
+};
+
+static final BitmapCharRec ch197 = new BitmapCharRec(12,18,0,0,12,ch197data);
+
+/* char: 0xc4 */
+
+static final byte[] ch196data = {
+(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x7f,(byte) 0xe0,(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,
+(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0xf,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x19,(byte) 0x80,
+(byte) 0x19,(byte) 0x80,
+};
+
+static final BitmapCharRec ch196 = new BitmapCharRec(12,17,0,0,12,ch196data);
+
+/* char: 0xc3 */
+
+static final byte[] ch195data = {
+(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x7f,(byte) 0xe0,(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,
+(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0xf,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x13,(byte) 0x0,
+(byte) 0x16,(byte) 0x80,(byte) 0xc,(byte) 0x80,
+};
+
+static final BitmapCharRec ch195 = new BitmapCharRec(12,18,0,0,12,ch195data);
+
+/* char: 0xc2 */
+
+static final byte[] ch194data = {
+(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x7f,(byte) 0xe0,(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,
+(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0xf,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x19,(byte) 0x80,
+(byte) 0xf,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+};
+
+static final BitmapCharRec ch194 = new BitmapCharRec(12,18,0,0,12,ch194data);
+
+/* char: 0xc1 */
+
+static final byte[] ch193data = {
+(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x7f,(byte) 0xe0,(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,
+(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0xf,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x1,(byte) 0x80,
+};
+
+static final BitmapCharRec ch193 = new BitmapCharRec(12,18,0,0,12,ch193data);
+
+/* char: 0xc0 */
+
+static final byte[] ch192data = {
+(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x7f,(byte) 0xe0,(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,
+(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0xf,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0x0,
+};
+
+static final BitmapCharRec ch192 = new BitmapCharRec(12,18,0,0,12,ch192data);
+
+/* char: 0xbf */
+
+static final byte[] ch191data = {
+(byte) 0x7c,(byte) 0xfe,(byte) 0xc6,(byte) 0xc6,(byte) 0xe0,(byte) 0x70,(byte) 0x38,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x0,(byte) 0x0,(byte) 0x18,(byte) 0x18,
+};
+
+static final BitmapCharRec ch191 = new BitmapCharRec(7,14,-1,4,10,ch191data);
+
+/* char: 0xbe */
+
+static final byte[] ch190data = {
+(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0xc,(byte) 0xfc,(byte) 0x6,(byte) 0xd8,(byte) 0x6,(byte) 0x78,(byte) 0x73,(byte) 0x38,(byte) 0xf9,(byte) 0x18,(byte) 0x99,(byte) 0x88,
+(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x98,(byte) 0x60,(byte) 0xf8,(byte) 0x30,(byte) 0x70,(byte) 0x30,
+};
+
+static final BitmapCharRec ch190 = new BitmapCharRec(14,13,0,0,15,ch190data);
+
+/* char: 0xbd */
+
+static final byte[] ch189data = {
+(byte) 0x30,(byte) 0xf8,(byte) 0x30,(byte) 0xf8,(byte) 0x18,(byte) 0x60,(byte) 0xc,(byte) 0x30,(byte) 0xc,(byte) 0x18,(byte) 0x66,(byte) 0x98,(byte) 0x62,(byte) 0xf8,(byte) 0x63,(byte) 0x70,
+(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xe0,(byte) 0xc0,(byte) 0xe0,(byte) 0x60,(byte) 0x60,(byte) 0x60,
+};
+
+static final BitmapCharRec ch189 = new BitmapCharRec(13,13,-1,0,15,ch189data);
+
+/* char: 0xbc */
+
+static final byte[] ch188data = {
+(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x19,(byte) 0xf8,(byte) 0xd,(byte) 0xb0,(byte) 0xc,(byte) 0xf0,(byte) 0x66,(byte) 0x70,(byte) 0x62,(byte) 0x30,(byte) 0x63,(byte) 0x10,
+(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xe0,(byte) 0xc0,(byte) 0xe0,(byte) 0x60,(byte) 0x60,(byte) 0x60,
+};
+
+static final BitmapCharRec ch188 = new BitmapCharRec(13,13,-1,0,15,ch188data);
+
+/* char: 0xbb */
+
+static final byte[] ch187data = {
+(byte) 0x90,(byte) 0xd8,(byte) 0x6c,(byte) 0x36,(byte) 0x36,(byte) 0x6c,(byte) 0xd8,(byte) 0x90,
+};
+
+static final BitmapCharRec ch187 = new BitmapCharRec(7,8,-1,-1,9,ch187data);
+
+/* char: 0xba */
+
+static final byte[] ch186data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0x70,(byte) 0xd8,(byte) 0x88,(byte) 0x88,(byte) 0xd8,(byte) 0x70,
+};
+
+static final BitmapCharRec ch186 = new BitmapCharRec(5,8,-1,-6,7,ch186data);
+
+/* char: 0xb9 */
+
+static final byte[] ch185data = {
+(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0xe0,(byte) 0xe0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch185 = new BitmapCharRec(3,8,-1,-5,6,ch185data);
+
+/* char: 0xb8 */
+
+static final byte[] ch184data = {
+(byte) 0xf0,(byte) 0xd8,(byte) 0x18,(byte) 0x70,(byte) 0x60,
+};
+
+static final BitmapCharRec ch184 = new BitmapCharRec(5,5,0,4,5,ch184data);
+
+/* char: 0xb7 */
+
+static final byte[] ch183data = {
+(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch183 = new BitmapCharRec(2,2,-1,-4,4,ch183data);
+
+/* char: 0xb6 */
+
+static final byte[] ch182data = {
+(byte) 0x12,(byte) 0x12,(byte) 0x12,(byte) 0x12,(byte) 0x12,(byte) 0x12,(byte) 0x12,(byte) 0x12,(byte) 0x12,(byte) 0x12,(byte) 0x32,(byte) 0x72,(byte) 0xf2,(byte) 0xf2,(byte) 0xf2,(byte) 0xf2,
+(byte) 0x72,(byte) 0x3f,
+};
+
+static final BitmapCharRec ch182 = new BitmapCharRec(8,18,-1,4,10,ch182data);
+
+/* char: 0xb5 */
+
+static final byte[] ch181data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xdb,(byte) 0xff,(byte) 0xe7,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,
+};
+
+static final BitmapCharRec ch181 = new BitmapCharRec(8,14,-1,4,10,ch181data);
+
+/* char: 0xb4 */
+
+static final byte[] ch180data = {
+(byte) 0xc0,(byte) 0x60,(byte) 0x30,
+};
+
+static final BitmapCharRec ch180 = new BitmapCharRec(4,3,0,-11,4,ch180data);
+
+/* char: 0xb3 */
+
+static final byte[] ch179data = {
+(byte) 0x70,(byte) 0xf8,(byte) 0x98,(byte) 0x30,(byte) 0x30,(byte) 0x98,(byte) 0xf8,(byte) 0x70,
+};
+
+static final BitmapCharRec ch179 = new BitmapCharRec(5,8,0,-5,6,ch179data);
+
+/* char: 0xb2 */
+
+static final byte[] ch178data = {
+(byte) 0xf8,(byte) 0xf8,(byte) 0x60,(byte) 0x30,(byte) 0x18,(byte) 0x98,(byte) 0xf8,(byte) 0x70,
+};
+
+static final BitmapCharRec ch178 = new BitmapCharRec(5,8,0,-5,6,ch178data);
+
+/* char: 0xb1 */
+
+static final byte[] ch177data = {
+(byte) 0xff,(byte) 0xff,(byte) 0x0,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0xff,(byte) 0xff,(byte) 0x18,(byte) 0x18,(byte) 0x18,
+};
+
+static final BitmapCharRec ch177 = new BitmapCharRec(8,11,-1,0,10,ch177data);
+
+/* char: 0xb0 */
+
+static final byte[] ch176data = {
+(byte) 0x70,(byte) 0xd8,(byte) 0x88,(byte) 0xd8,(byte) 0x70,
+};
+
+static final BitmapCharRec ch176 = new BitmapCharRec(5,5,-1,-8,7,ch176data);
+
+/* char: 0xaf */
+
+static final byte[] ch175data = {
+(byte) 0xf8,
+};
+
+static final BitmapCharRec ch175 = new BitmapCharRec(5,1,0,-12,5,ch175data);
+
+/* char: 0xae */
+
+static final byte[] ch174data = {
+(byte) 0xf,(byte) 0x80,(byte) 0x30,(byte) 0x60,(byte) 0x40,(byte) 0x10,(byte) 0x48,(byte) 0x50,(byte) 0x88,(byte) 0x88,(byte) 0x89,(byte) 0x8,(byte) 0x8f,(byte) 0x88,(byte) 0x88,(byte) 0x48,
+(byte) 0x88,(byte) 0x48,(byte) 0x4f,(byte) 0x90,(byte) 0x40,(byte) 0x10,(byte) 0x30,(byte) 0x60,(byte) 0xf,(byte) 0x80,
+};
+
+static final BitmapCharRec ch174 = new BitmapCharRec(13,13,-1,0,14,ch174data);
+
+/* char: 0xad */
+
+static final byte[] ch173data = {
+(byte) 0xf8,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch173 = new BitmapCharRec(5,2,-1,-4,7,ch173data);
+
+/* char: 0xac */
+
+static final byte[] ch172data = {
+(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,
+};
+
+static final BitmapCharRec ch172 = new BitmapCharRec(9,5,-1,-3,11,ch172data);
+
+/* char: 0xab */
+
+static final byte[] ch171data = {
+(byte) 0x12,(byte) 0x36,(byte) 0x6c,(byte) 0xd8,(byte) 0xd8,(byte) 0x6c,(byte) 0x36,(byte) 0x12,
+};
+
+static final BitmapCharRec ch171 = new BitmapCharRec(7,8,-1,-1,9,ch171data);
+
+/* char: 0xaa */
+
+static final byte[] ch170data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0x68,(byte) 0xd8,(byte) 0x48,(byte) 0x38,(byte) 0xc8,(byte) 0x70,
+};
+
+static final BitmapCharRec ch170 = new BitmapCharRec(5,8,-1,-6,7,ch170data);
+
+/* char: 0xa9 */
+
+static final byte[] ch169data = {
+(byte) 0xf,(byte) 0x80,(byte) 0x30,(byte) 0x60,(byte) 0x40,(byte) 0x10,(byte) 0x47,(byte) 0x10,(byte) 0x88,(byte) 0x88,(byte) 0x90,(byte) 0x8,(byte) 0x90,(byte) 0x8,(byte) 0x90,(byte) 0x8,
+(byte) 0x88,(byte) 0x88,(byte) 0x47,(byte) 0x10,(byte) 0x40,(byte) 0x10,(byte) 0x30,(byte) 0x60,(byte) 0xf,(byte) 0x80,
+};
+
+static final BitmapCharRec ch169 = new BitmapCharRec(13,13,-1,0,15,ch169data);
+
+/* char: 0xa8 */
+
+static final byte[] ch168data = {
+(byte) 0xd8,(byte) 0xd8,
+};
+
+static final BitmapCharRec ch168 = new BitmapCharRec(5,2,0,-11,6,ch168data);
+
+/* char: 0xa7 */
+
+static final byte[] ch167data = {
+(byte) 0x3c,(byte) 0x7e,(byte) 0xc3,(byte) 0xc3,(byte) 0x7,(byte) 0xe,(byte) 0x3e,(byte) 0x73,(byte) 0xe3,(byte) 0xc3,(byte) 0xc7,(byte) 0x6e,(byte) 0x7c,(byte) 0xf0,(byte) 0xc3,(byte) 0xc3,
+(byte) 0x7e,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch167 = new BitmapCharRec(8,18,-1,4,10,ch167data);
+
+/* char: 0xa6 */
+
+static final byte[] ch166data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,
+};
+
+static final BitmapCharRec ch166 = new BitmapCharRec(2,17,-1,3,4,ch166data);
+
+/* char: 0xa5 */
+
+static final byte[] ch165data = {
+(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0xff,(byte) 0x18,(byte) 0xff,(byte) 0x3c,(byte) 0x66,(byte) 0x66,(byte) 0x66,(byte) 0xc3,(byte) 0xc3,
+};
+
+static final BitmapCharRec ch165 = new BitmapCharRec(8,13,-1,0,10,ch165data);
+
+/* char: 0xa4 */
+
+static final byte[] ch164data = {
+(byte) 0xc3,(byte) 0xff,(byte) 0x66,(byte) 0x66,(byte) 0x66,(byte) 0xff,(byte) 0xc3,
+};
+
+static final BitmapCharRec ch164 = new BitmapCharRec(8,7,-1,-3,10,ch164data);
+
+/* char: 0xa3 */
+
+static final byte[] ch163data = {
+(byte) 0xdf,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0x60,(byte) 0x80,(byte) 0x30,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x7e,(byte) 0x0,(byte) 0x30,(byte) 0x0,
+(byte) 0x60,(byte) 0x0,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x3f,(byte) 0x0,(byte) 0x1e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch163 = new BitmapCharRec(9,13,0,0,10,ch163data);
+
+/* char: 0xa2 */
+
+static final byte[] ch162data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x3e,(byte) 0x7f,(byte) 0x6b,(byte) 0xc8,(byte) 0xc8,(byte) 0xc8,(byte) 0xc8,(byte) 0x6b,(byte) 0x7f,(byte) 0x3e,(byte) 0x4,(byte) 0x4,
+};
+
+static final BitmapCharRec ch162 = new BitmapCharRec(8,14,-1,2,10,ch162data);
+
+/* char: 0xa1 */
+
+static final byte[] ch161data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch161 = new BitmapCharRec(2,14,-2,4,6,ch161data);
+
+/* char: 0xa0 */
+
+static final BitmapCharRec ch160 = new BitmapCharRec(0,0,0,0,5,null);
+
+/* char: 0x7e '~' */
+
+static final byte[] ch126data = {
+(byte) 0xcc,(byte) 0x7e,(byte) 0x33,
+};
+
+static final BitmapCharRec ch126 = new BitmapCharRec(8,3,-1,-4,10,ch126data);
+
+/* char: 0x7d '}' */
+
+static final byte[] ch125data = {
+(byte) 0xc0,(byte) 0x60,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x18,(byte) 0xc,(byte) 0x18,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,
+(byte) 0x60,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch125 = new BitmapCharRec(6,18,0,4,6,ch125data);
+
+/* char: 0x7c '|' */
+
+static final byte[] ch124data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch124 = new BitmapCharRec(2,18,-1,4,4,ch124data);
+
+/* char: 0x7b '{' */
+
+static final byte[] ch123data = {
+(byte) 0xc,(byte) 0x18,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,
+(byte) 0x18,(byte) 0xc,
+};
+
+static final BitmapCharRec ch123 = new BitmapCharRec(6,18,0,4,6,ch123data);
+
+/* char: 0x7a 'z' */
+
+static final byte[] ch122data = {
+(byte) 0xfe,(byte) 0xfe,(byte) 0xc0,(byte) 0x60,(byte) 0x30,(byte) 0x18,(byte) 0xc,(byte) 0x6,(byte) 0xfe,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch122 = new BitmapCharRec(7,10,-1,0,9,ch122data);
+
+/* char: 0x79 'y' */
+
+static final byte[] ch121data = {
+(byte) 0x70,(byte) 0x70,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x3c,(byte) 0x24,(byte) 0x66,(byte) 0x66,(byte) 0x66,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,
+};
+
+static final BitmapCharRec ch121 = new BitmapCharRec(8,14,-1,4,10,ch121data);
+
+/* char: 0x78 'x' */
+
+static final byte[] ch120data = {
+(byte) 0xc3,(byte) 0xe7,(byte) 0x66,(byte) 0x3c,(byte) 0x18,(byte) 0x18,(byte) 0x3c,(byte) 0x66,(byte) 0xe7,(byte) 0xc3,
+};
+
+static final BitmapCharRec ch120 = new BitmapCharRec(8,10,-1,0,10,ch120data);
+
+/* char: 0x77 'w' */
+
+static final byte[] ch119data = {
+(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0x39,(byte) 0xc0,(byte) 0x29,(byte) 0x40,(byte) 0x69,(byte) 0x60,(byte) 0x66,(byte) 0x60,(byte) 0x66,(byte) 0x60,(byte) 0xc6,(byte) 0x30,
+(byte) 0xc6,(byte) 0x30,(byte) 0xc6,(byte) 0x30,
+};
+
+static final BitmapCharRec ch119 = new BitmapCharRec(12,10,-1,0,14,ch119data);
+
+/* char: 0x76 'v' */
+
+static final byte[] ch118data = {
+(byte) 0x18,(byte) 0x18,(byte) 0x3c,(byte) 0x24,(byte) 0x66,(byte) 0x66,(byte) 0x66,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,
+};
+
+static final BitmapCharRec ch118 = new BitmapCharRec(8,10,-1,0,10,ch118data);
+
+/* char: 0x75 'u' */
+
+static final byte[] ch117data = {
+(byte) 0x73,(byte) 0xfb,(byte) 0xc7,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,
+};
+
+static final BitmapCharRec ch117 = new BitmapCharRec(8,10,-1,0,10,ch117data);
+
+/* char: 0x74 't' */
+
+static final byte[] ch116data = {
+(byte) 0x18,(byte) 0x38,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0xfc,(byte) 0xfc,(byte) 0x30,(byte) 0x30,(byte) 0x30,
+};
+
+static final BitmapCharRec ch116 = new BitmapCharRec(6,13,0,0,6,ch116data);
+
+/* char: 0x73 's' */
+
+static final byte[] ch115data = {
+(byte) 0x78,(byte) 0xfc,(byte) 0xc6,(byte) 0x6,(byte) 0x3e,(byte) 0xfc,(byte) 0xc0,(byte) 0xc6,(byte) 0x7e,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch115 = new BitmapCharRec(7,10,-1,0,9,ch115data);
+
+/* char: 0x72 'r' */
+
+static final byte[] ch114data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xe0,(byte) 0xd8,(byte) 0xd8,
+};
+
+static final BitmapCharRec ch114 = new BitmapCharRec(5,10,-1,0,6,ch114data);
+
+/* char: 0x71 'q' */
+
+static final byte[] ch113data = {
+(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x3d,(byte) 0x80,(byte) 0x7f,(byte) 0x80,(byte) 0x63,(byte) 0x80,(byte) 0xc1,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x63,(byte) 0x80,(byte) 0x7f,(byte) 0x80,(byte) 0x3d,(byte) 0x80,
+};
+
+static final BitmapCharRec ch113 = new BitmapCharRec(9,14,-1,4,11,ch113data);
+
+/* char: 0x70 'p' */
+
+static final byte[] ch112data = {
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xde,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xe3,(byte) 0x0,(byte) 0xc1,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xe3,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xde,(byte) 0x0,
+};
+
+static final BitmapCharRec ch112 = new BitmapCharRec(9,14,-1,4,11,ch112data);
+
+/* char: 0x6f 'o' */
+
+static final byte[] ch111data = {
+(byte) 0x3e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x63,(byte) 0x0,
+(byte) 0x7f,(byte) 0x0,(byte) 0x3e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch111 = new BitmapCharRec(9,10,-1,0,11,ch111data);
+
+/* char: 0x6e 'n' */
+
+static final byte[] ch110data = {
+(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xe3,(byte) 0xdf,(byte) 0xce,
+};
+
+static final BitmapCharRec ch110 = new BitmapCharRec(8,10,-1,0,10,ch110data);
+
+/* char: 0x6d 'm' */
+
+static final byte[] ch109data = {
+(byte) 0xc6,(byte) 0x30,(byte) 0xc6,(byte) 0x30,(byte) 0xc6,(byte) 0x30,(byte) 0xc6,(byte) 0x30,(byte) 0xc6,(byte) 0x30,(byte) 0xc6,(byte) 0x30,(byte) 0xc6,(byte) 0x30,(byte) 0xe7,(byte) 0x30,
+(byte) 0xde,(byte) 0xf0,(byte) 0xcc,(byte) 0x60,
+};
+
+static final BitmapCharRec ch109 = new BitmapCharRec(12,10,-1,0,14,ch109data);
+
+/* char: 0x6c 'l' */
+
+static final byte[] ch108data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch108 = new BitmapCharRec(2,14,-1,0,4,ch108data);
+
+/* char: 0x6b 'k' */
+
+static final byte[] ch107data = {
+(byte) 0xc7,(byte) 0xc6,(byte) 0xce,(byte) 0xcc,(byte) 0xd8,(byte) 0xf8,(byte) 0xf0,(byte) 0xd8,(byte) 0xcc,(byte) 0xc6,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch107 = new BitmapCharRec(8,14,-1,0,9,ch107data);
+
+/* char: 0x6a 'j' */
+
+static final byte[] ch106data = {
+(byte) 0xe0,(byte) 0xf0,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x0,(byte) 0x0,
+(byte) 0x30,(byte) 0x30,
+};
+
+static final BitmapCharRec ch106 = new BitmapCharRec(4,18,1,4,4,ch106data);
+
+/* char: 0x69 'i' */
+
+static final byte[] ch105data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch105 = new BitmapCharRec(2,14,-1,0,4,ch105data);
+
+/* char: 0x68 'h' */
+
+static final byte[] ch104data = {
+(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xe3,(byte) 0xdf,(byte) 0xce,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch104 = new BitmapCharRec(8,14,-1,0,10,ch104data);
+
+/* char: 0x67 'g' */
+
+static final byte[] ch103data = {
+(byte) 0x1c,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x1,(byte) 0x80,(byte) 0x3d,(byte) 0x80,(byte) 0x7f,(byte) 0x80,(byte) 0x63,(byte) 0x80,(byte) 0xc1,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x7f,(byte) 0x80,(byte) 0x3d,(byte) 0x80,
+};
+
+static final BitmapCharRec ch103 = new BitmapCharRec(9,14,-1,4,11,ch103data);
+
+/* char: 0x66 'f' */
+
+static final byte[] ch102data = {
+(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0xfc,(byte) 0xfc,(byte) 0x30,(byte) 0x30,(byte) 0x3c,(byte) 0x1c,
+};
+
+static final BitmapCharRec ch102 = new BitmapCharRec(6,14,0,0,6,ch102data);
+
+/* char: 0x65 'e' */
+
+static final byte[] ch101data = {
+(byte) 0x3c,(byte) 0x7f,(byte) 0xe3,(byte) 0xc0,(byte) 0xc0,(byte) 0xff,(byte) 0xc3,(byte) 0xc3,(byte) 0x7e,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch101 = new BitmapCharRec(8,10,-1,0,10,ch101data);
+
+/* char: 0x64 'd' */
+
+static final byte[] ch100data = {
+(byte) 0x3d,(byte) 0x80,(byte) 0x7f,(byte) 0x80,(byte) 0x63,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x63,(byte) 0x80,
+(byte) 0x7f,(byte) 0x80,(byte) 0x3d,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,
+};
+
+static final BitmapCharRec ch100 = new BitmapCharRec(9,14,-1,0,11,ch100data);
+
+/* char: 0x63 'c' */
+
+static final byte[] ch99data = {
+(byte) 0x3e,(byte) 0x7f,(byte) 0x63,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x63,(byte) 0x7f,(byte) 0x3e,
+};
+
+static final BitmapCharRec ch99 = new BitmapCharRec(8,10,-1,0,10,ch99data);
+
+/* char: 0x62 'b' */
+
+static final byte[] ch98data = {
+(byte) 0xde,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xe3,(byte) 0x0,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xe3,(byte) 0x0,
+(byte) 0xff,(byte) 0x0,(byte) 0xde,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch98 = new BitmapCharRec(9,14,-1,0,11,ch98data);
+
+/* char: 0x61 'a' */
+
+static final byte[] ch97data = {
+(byte) 0x76,(byte) 0xee,(byte) 0xc6,(byte) 0xc6,(byte) 0xe6,(byte) 0x7e,(byte) 0xe,(byte) 0xc6,(byte) 0xee,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch97 = new BitmapCharRec(7,10,-1,0,9,ch97data);
+
+/* char: 0x60 '`' */
+
+static final byte[] ch96data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0x80,(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch96 = new BitmapCharRec(2,5,-1,-9,4,ch96data);
+
+/* char: 0x5f '_' */
+
+static final byte[] ch95data = {
+(byte) 0xff,(byte) 0xc0,(byte) 0xff,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch95 = new BitmapCharRec(10,2,0,4,10,ch95data);
+
+/* char: 0x5e '^' */
+
+static final byte[] ch94data = {
+(byte) 0x82,(byte) 0xc6,(byte) 0x6c,(byte) 0x38,(byte) 0x10,
+};
+
+static final BitmapCharRec ch94 = new BitmapCharRec(7,5,-1,-8,9,ch94data);
+
+/* char: 0x5d ']' */
+
+static final byte[] ch93data = {
+(byte) 0xf0,(byte) 0xf0,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,
+(byte) 0xf0,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch93 = new BitmapCharRec(4,18,0,4,5,ch93data);
+
+/* char: 0x5c '\' */
+
+static final byte[] ch92data = {
+(byte) 0x18,(byte) 0x18,(byte) 0x10,(byte) 0x10,(byte) 0x30,(byte) 0x30,(byte) 0x20,(byte) 0x20,(byte) 0x60,(byte) 0x60,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch92 = new BitmapCharRec(5,14,0,0,5,ch92data);
+
+/* char: 0x5b '[' */
+
+static final byte[] ch91data = {
+(byte) 0xf0,(byte) 0xf0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xf0,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch91 = new BitmapCharRec(4,18,-1,4,5,ch91data);
+
+/* char: 0x5a 'Z' */
+
+static final byte[] ch90data = {
+(byte) 0xff,(byte) 0xc0,(byte) 0xff,(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x1c,(byte) 0x0,(byte) 0xc,(byte) 0x0,
+(byte) 0x6,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x1,(byte) 0x80,(byte) 0x0,(byte) 0xc0,(byte) 0xff,(byte) 0xc0,(byte) 0xff,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch90 = new BitmapCharRec(10,14,-1,0,12,ch90data);
+
+/* char: 0x59 'Y' */
+
+static final byte[] ch89data = {
+(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x19,(byte) 0x80,
+(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,
+};
+
+static final BitmapCharRec ch89 = new BitmapCharRec(12,14,-1,0,14,ch89data);
+
+/* char: 0x58 'X' */
+
+static final byte[] ch88data = {
+(byte) 0xc0,(byte) 0x60,(byte) 0xe0,(byte) 0xe0,(byte) 0x60,(byte) 0xc0,(byte) 0x71,(byte) 0xc0,(byte) 0x31,(byte) 0x80,(byte) 0x1b,(byte) 0x0,(byte) 0xe,(byte) 0x0,(byte) 0xe,(byte) 0x0,
+(byte) 0x1b,(byte) 0x0,(byte) 0x31,(byte) 0x80,(byte) 0x71,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xe0,(byte) 0xe0,(byte) 0xc0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch88 = new BitmapCharRec(11,14,-1,0,13,ch88data);
+
+/* char: 0x57 'W' */
+
+static final byte[] ch87data = {
+(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x1c,(byte) 0x38,(byte) 0x34,(byte) 0x2c,(byte) 0x36,(byte) 0x6c,(byte) 0x36,(byte) 0x6c,(byte) 0x66,(byte) 0x66,(byte) 0x66,(byte) 0x66,
+(byte) 0x62,(byte) 0x46,(byte) 0x63,(byte) 0xc6,(byte) 0xc3,(byte) 0xc3,(byte) 0xc1,(byte) 0x83,(byte) 0xc1,(byte) 0x83,(byte) 0xc1,(byte) 0x83,
+};
+
+static final BitmapCharRec ch87 = new BitmapCharRec(16,14,-1,0,18,ch87data);
+
+/* char: 0x56 'V' */
+
+static final byte[] ch86data = {
+(byte) 0x6,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,
+(byte) 0x30,(byte) 0xc0,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,
+};
+
+static final BitmapCharRec ch86 = new BitmapCharRec(12,14,-1,0,14,ch86data);
+
+/* char: 0x55 'U' */
+
+static final byte[] ch85data = {
+(byte) 0x1f,(byte) 0x0,(byte) 0x7f,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,
+(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch85 = new BitmapCharRec(11,14,-1,0,13,ch85data);
+
+/* char: 0x54 'T' */
+
+static final byte[] ch84data = {
+(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,
+(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xff,(byte) 0xc0,(byte) 0xff,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch84 = new BitmapCharRec(10,14,-1,0,12,ch84data);
+
+/* char: 0x53 'S' */
+
+static final byte[] ch83data = {
+(byte) 0x3f,(byte) 0x0,(byte) 0x7f,(byte) 0xc0,(byte) 0xe0,(byte) 0xe0,(byte) 0xc0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0xe0,(byte) 0x3,(byte) 0xc0,(byte) 0x1f,(byte) 0x0,
+(byte) 0x7c,(byte) 0x0,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x60,(byte) 0xe0,(byte) 0xe0,(byte) 0x7f,(byte) 0xc0,(byte) 0x1f,(byte) 0x0,
+};
+
+static final BitmapCharRec ch83 = new BitmapCharRec(11,14,-1,0,13,ch83data);
+
+/* char: 0x52 'R' */
+
+static final byte[] ch82data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xff,(byte) 0x0,(byte) 0xff,(byte) 0x80,
+(byte) 0xc1,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc1,(byte) 0xc0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x0,
+};
+
+static final BitmapCharRec ch82 = new BitmapCharRec(10,14,-1,0,12,ch82data);
+
+/* char: 0x51 'Q' */
+
+static final byte[] ch81data = {
+(byte) 0x0,(byte) 0x30,(byte) 0xf,(byte) 0xb0,(byte) 0x3f,(byte) 0xe0,(byte) 0x70,(byte) 0xf0,(byte) 0x61,(byte) 0xb0,(byte) 0xe1,(byte) 0xb8,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,
+(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,(byte) 0xe0,(byte) 0x38,(byte) 0x60,(byte) 0x30,(byte) 0x70,(byte) 0x70,(byte) 0x3f,(byte) 0xe0,(byte) 0xf,(byte) 0x80,
+};
+
+static final BitmapCharRec ch81 = new BitmapCharRec(13,15,-1,1,15,ch81data);
+
+/* char: 0x50 'P' */
+
+static final byte[] ch80data = {
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xff,(byte) 0x80,
+(byte) 0xc1,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc1,(byte) 0xc0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x0,
+};
+
+static final BitmapCharRec ch80 = new BitmapCharRec(10,14,-1,0,12,ch80data);
+
+/* char: 0x4f 'O' */
+
+static final byte[] ch79data = {
+(byte) 0xf,(byte) 0x80,(byte) 0x3f,(byte) 0xe0,(byte) 0x70,(byte) 0x70,(byte) 0x60,(byte) 0x30,(byte) 0xe0,(byte) 0x38,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,(byte) 0xc0,(byte) 0x18,
+(byte) 0xc0,(byte) 0x18,(byte) 0xe0,(byte) 0x38,(byte) 0x60,(byte) 0x30,(byte) 0x70,(byte) 0x70,(byte) 0x3f,(byte) 0xe0,(byte) 0xf,(byte) 0x80,
+};
+
+static final BitmapCharRec ch79 = new BitmapCharRec(13,14,-1,0,15,ch79data);
+
+/* char: 0x4e 'N' */
+
+static final byte[] ch78data = {
+(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xe0,(byte) 0xc1,(byte) 0xe0,(byte) 0xc1,(byte) 0xe0,(byte) 0xc3,(byte) 0x60,(byte) 0xc6,(byte) 0x60,(byte) 0xc6,(byte) 0x60,(byte) 0xcc,(byte) 0x60,
+(byte) 0xcc,(byte) 0x60,(byte) 0xd8,(byte) 0x60,(byte) 0xf0,(byte) 0x60,(byte) 0xf0,(byte) 0x60,(byte) 0xe0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch78 = new BitmapCharRec(11,14,-1,0,13,ch78data);
+
+/* char: 0x4d 'M' */
+
+static final byte[] ch77data = {
+(byte) 0xc3,(byte) 0xc,(byte) 0xc3,(byte) 0xc,(byte) 0xc7,(byte) 0x8c,(byte) 0xc4,(byte) 0x8c,(byte) 0xcc,(byte) 0xcc,(byte) 0xcc,(byte) 0xcc,(byte) 0xd8,(byte) 0x6c,(byte) 0xd8,(byte) 0x6c,
+(byte) 0xf0,(byte) 0x3c,(byte) 0xf0,(byte) 0x3c,(byte) 0xe0,(byte) 0x1c,(byte) 0xe0,(byte) 0x1c,(byte) 0xc0,(byte) 0xc,(byte) 0xc0,(byte) 0xc,
+};
+
+static final BitmapCharRec ch77 = new BitmapCharRec(14,14,-1,0,16,ch77data);
+
+/* char: 0x4c 'L' */
+
+static final byte[] ch76data = {
+(byte) 0xff,(byte) 0xff,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch76 = new BitmapCharRec(8,14,-1,0,10,ch76data);
+
+/* char: 0x4b 'K' */
+
+static final byte[] ch75data = {
+(byte) 0xc0,(byte) 0x70,(byte) 0xc0,(byte) 0xe0,(byte) 0xc1,(byte) 0xc0,(byte) 0xc3,(byte) 0x80,(byte) 0xc7,(byte) 0x0,(byte) 0xce,(byte) 0x0,(byte) 0xfc,(byte) 0x0,(byte) 0xf8,(byte) 0x0,
+(byte) 0xdc,(byte) 0x0,(byte) 0xce,(byte) 0x0,(byte) 0xc7,(byte) 0x0,(byte) 0xc3,(byte) 0x80,(byte) 0xc1,(byte) 0xc0,(byte) 0xc0,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch75 = new BitmapCharRec(12,14,-1,0,13,ch75data);
+
+/* char: 0x4a 'J' */
+
+static final byte[] ch74data = {
+(byte) 0x3c,(byte) 0x7e,(byte) 0xe7,(byte) 0xc3,(byte) 0xc3,(byte) 0x3,(byte) 0x3,(byte) 0x3,(byte) 0x3,(byte) 0x3,(byte) 0x3,(byte) 0x3,(byte) 0x3,(byte) 0x3,
+};
+
+static final BitmapCharRec ch74 = new BitmapCharRec(8,14,-1,0,10,ch74data);
+
+/* char: 0x49 'I' */
+
+static final byte[] ch73data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch73 = new BitmapCharRec(2,14,-2,0,6,ch73data);
+
+/* char: 0x48 'H' */
+
+static final byte[] ch72data = {
+(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xff,(byte) 0xe0,(byte) 0xff,(byte) 0xe0,
+(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch72 = new BitmapCharRec(11,14,-1,0,13,ch72data);
+
+/* char: 0x47 'G' */
+
+static final byte[] ch71data = {
+(byte) 0xf,(byte) 0xb0,(byte) 0x3f,(byte) 0xf0,(byte) 0x70,(byte) 0x70,(byte) 0x60,(byte) 0x30,(byte) 0xe0,(byte) 0x30,(byte) 0xc1,(byte) 0xf0,(byte) 0xc1,(byte) 0xf0,(byte) 0xc0,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xe0,(byte) 0x30,(byte) 0x60,(byte) 0x30,(byte) 0x70,(byte) 0x70,(byte) 0x3f,(byte) 0xe0,(byte) 0xf,(byte) 0x80,
+};
+
+static final BitmapCharRec ch71 = new BitmapCharRec(12,14,-1,0,14,ch71data);
+
+/* char: 0x46 'F' */
+
+static final byte[] ch70data = {
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xff,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,
+};
+
+static final BitmapCharRec ch70 = new BitmapCharRec(9,14,-1,0,11,ch70data);
+
+/* char: 0x45 'E' */
+
+static final byte[] ch69data = {
+(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x0,(byte) 0xff,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,
+};
+
+static final BitmapCharRec ch69 = new BitmapCharRec(9,14,-1,0,11,ch69data);
+
+/* char: 0x44 'D' */
+
+static final byte[] ch68data = {
+(byte) 0xff,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0xc1,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,
+(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xc0,(byte) 0xc1,(byte) 0xc0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x0,
+};
+
+static final BitmapCharRec ch68 = new BitmapCharRec(11,14,-1,0,13,ch68data);
+
+/* char: 0x43 'C' */
+
+static final byte[] ch67data = {
+(byte) 0xf,(byte) 0x80,(byte) 0x3f,(byte) 0xe0,(byte) 0x70,(byte) 0x70,(byte) 0x60,(byte) 0x30,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xe0,(byte) 0x0,(byte) 0x60,(byte) 0x30,(byte) 0x70,(byte) 0x70,(byte) 0x3f,(byte) 0xe0,(byte) 0xf,(byte) 0x80,
+};
+
+static final BitmapCharRec ch67 = new BitmapCharRec(12,14,-1,0,14,ch67data);
+
+/* char: 0x42 'B' */
+
+static final byte[] ch66data = {
+(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0xc0,(byte) 0xc0,(byte) 0xe0,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xe0,(byte) 0xff,(byte) 0xc0,(byte) 0xff,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc1,(byte) 0xc0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x0,
+};
+
+static final BitmapCharRec ch66 = new BitmapCharRec(11,14,-1,0,13,ch66data);
+
+/* char: 0x41 'A' */
+
+static final byte[] ch65data = {
+(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x7f,(byte) 0xe0,(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0xc0,
+(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0xf,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+};
+
+static final BitmapCharRec ch65 = new BitmapCharRec(12,14,0,0,12,ch65data);
+
+/* char: 0x40 '@' */
+
+static final byte[] ch64data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1f,(byte) 0xf0,(byte) 0x38,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0x67,(byte) 0x70,(byte) 0xcf,(byte) 0xf8,(byte) 0xcc,(byte) 0xcc,(byte) 0xcc,(byte) 0x66,
+(byte) 0xcc,(byte) 0x66,(byte) 0xcc,(byte) 0x63,(byte) 0xc6,(byte) 0x33,(byte) 0x67,(byte) 0x73,(byte) 0x63,(byte) 0xb3,(byte) 0x30,(byte) 0x6,(byte) 0x1c,(byte) 0xe,(byte) 0xf,(byte) 0xfc,
+(byte) 0x3,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch64 = new BitmapCharRec(16,17,-1,3,18,ch64data);
+
+/* char: 0x3f '?' */
+
+static final byte[] ch63data = {
+(byte) 0x30,(byte) 0x30,(byte) 0x0,(byte) 0x0,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x38,(byte) 0x1c,(byte) 0xe,(byte) 0xc6,(byte) 0xc6,(byte) 0xfe,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch63 = new BitmapCharRec(7,14,-1,0,10,ch63data);
+
+/* char: 0x3e '>' */
+
+static final byte[] ch62data = {
+(byte) 0xc0,(byte) 0xf0,(byte) 0x3c,(byte) 0xe,(byte) 0x3,(byte) 0xe,(byte) 0x3c,(byte) 0xf0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch62 = new BitmapCharRec(8,9,-1,0,10,ch62data);
+
+/* char: 0x3d '=' */
+
+static final byte[] ch61data = {
+(byte) 0xfe,(byte) 0xfe,(byte) 0x0,(byte) 0x0,(byte) 0xfe,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch61 = new BitmapCharRec(7,6,-2,-2,11,ch61data);
+
+/* char: 0x3c '<' */
+
+static final byte[] ch60data = {
+(byte) 0x3,(byte) 0xf,(byte) 0x3c,(byte) 0x70,(byte) 0xc0,(byte) 0x70,(byte) 0x3c,(byte) 0xf,(byte) 0x3,
+};
+
+static final BitmapCharRec ch60 = new BitmapCharRec(8,9,-1,0,10,ch60data);
+
+/* char: 0x3b ';' */
+
+static final byte[] ch59data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch59 = new BitmapCharRec(2,13,-1,3,5,ch59data);
+
+/* char: 0x3a ':' */
+
+static final byte[] ch58data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch58 = new BitmapCharRec(2,10,-1,0,5,ch58data);
+
+/* char: 0x39 '9' */
+
+static final byte[] ch57data = {
+(byte) 0x7c,(byte) 0xfe,(byte) 0xc6,(byte) 0x3,(byte) 0x3,(byte) 0x3b,(byte) 0x7f,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc7,(byte) 0x7e,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch57 = new BitmapCharRec(8,13,-1,0,10,ch57data);
+
+/* char: 0x38 '8' */
+
+static final byte[] ch56data = {
+(byte) 0x3c,(byte) 0x7e,(byte) 0xe7,(byte) 0xc3,(byte) 0xc3,(byte) 0x66,(byte) 0x7e,(byte) 0x66,(byte) 0xc3,(byte) 0xc3,(byte) 0xe7,(byte) 0x7e,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch56 = new BitmapCharRec(8,13,-1,0,10,ch56data);
+
+/* char: 0x37 '7' */
+
+static final byte[] ch55data = {
+(byte) 0x60,(byte) 0x60,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x18,(byte) 0x18,(byte) 0xc,(byte) 0xc,(byte) 0x6,(byte) 0x3,(byte) 0xff,(byte) 0xff,
+};
+
+static final BitmapCharRec ch55 = new BitmapCharRec(8,13,-1,0,10,ch55data);
+
+/* char: 0x36 '6' */
+
+static final byte[] ch54data = {
+(byte) 0x3c,(byte) 0x7e,(byte) 0xe3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xfe,(byte) 0xdc,(byte) 0xc0,(byte) 0xc0,(byte) 0x63,(byte) 0x7f,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch54 = new BitmapCharRec(8,13,-1,0,10,ch54data);
+
+/* char: 0x35 '5' */
+
+static final byte[] ch53data = {
+(byte) 0x7c,(byte) 0xfe,(byte) 0xc7,(byte) 0xc3,(byte) 0x3,(byte) 0x3,(byte) 0xc7,(byte) 0xfe,(byte) 0xfc,(byte) 0xc0,(byte) 0xc0,(byte) 0xfe,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch53 = new BitmapCharRec(8,13,-1,0,10,ch53data);
+
+/* char: 0x34 '4' */
+
+static final byte[] ch52data = {
+(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0xc3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x33,(byte) 0x0,
+(byte) 0x33,(byte) 0x0,(byte) 0x1b,(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x7,(byte) 0x0,(byte) 0x3,(byte) 0x0,
+};
+
+static final BitmapCharRec ch52 = new BitmapCharRec(9,13,-1,0,10,ch52data);
+
+/* char: 0x33 '3' */
+
+static final byte[] ch51data = {
+(byte) 0x3c,(byte) 0x7e,(byte) 0xc7,(byte) 0xc3,(byte) 0x3,(byte) 0x7,(byte) 0x1e,(byte) 0x1c,(byte) 0x6,(byte) 0xc3,(byte) 0xc3,(byte) 0x7e,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch51 = new BitmapCharRec(8,13,-1,0,10,ch51data);
+
+/* char: 0x32 '2' */
+
+static final byte[] ch50data = {
+(byte) 0xff,(byte) 0xff,(byte) 0xc0,(byte) 0xe0,(byte) 0x70,(byte) 0x38,(byte) 0x1c,(byte) 0xe,(byte) 0x7,(byte) 0x3,(byte) 0xc3,(byte) 0xfe,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch50 = new BitmapCharRec(8,13,-1,0,10,ch50data);
+
+/* char: 0x31 '1' */
+
+static final byte[] ch49data = {
+(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0xf8,(byte) 0xf8,(byte) 0x18,
+};
+
+static final BitmapCharRec ch49 = new BitmapCharRec(5,13,-2,0,10,ch49data);
+
+/* char: 0x30 '0' */
+
+static final byte[] ch48data = {
+(byte) 0x3c,(byte) 0x7e,(byte) 0x66,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0xc3,(byte) 0x66,(byte) 0x7e,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch48 = new BitmapCharRec(8,13,-1,0,10,ch48data);
+
+/* char: 0x2f '/' */
+
+static final byte[] ch47data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0x40,(byte) 0x40,(byte) 0x60,(byte) 0x60,(byte) 0x20,(byte) 0x20,(byte) 0x30,(byte) 0x30,(byte) 0x10,(byte) 0x10,(byte) 0x18,(byte) 0x18,
+};
+
+static final BitmapCharRec ch47 = new BitmapCharRec(5,14,0,0,5,ch47data);
+
+/* char: 0x2e '.' */
+
+static final byte[] ch46data = {
+(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch46 = new BitmapCharRec(2,2,-1,0,5,ch46data);
+
+/* char: 0x2d '-' */
+
+static final byte[] ch45data = {
+(byte) 0xff,(byte) 0xff,
+};
+
+static final BitmapCharRec ch45 = new BitmapCharRec(8,2,-1,-4,11,ch45data);
+
+/* char: 0x2c ',' */
+
+static final byte[] ch44data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch44 = new BitmapCharRec(2,5,-1,3,5,ch44data);
+
+/* char: 0x2b '+' */
+
+static final byte[] ch43data = {
+(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0xff,(byte) 0xff,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,
+};
+
+static final BitmapCharRec ch43 = new BitmapCharRec(8,10,-1,0,10,ch43data);
+
+/* char: 0x2a '*' */
+
+static final byte[] ch42data = {
+(byte) 0x88,(byte) 0x70,(byte) 0x70,(byte) 0xf8,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch42 = new BitmapCharRec(5,6,-1,-8,7,ch42data);
+
+/* char: 0x29 ')' */
+
+static final byte[] ch41data = {
+(byte) 0x80,(byte) 0xc0,(byte) 0x60,(byte) 0x60,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x60,(byte) 0x60,
+(byte) 0xc0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch41 = new BitmapCharRec(4,18,-1,4,6,ch41data);
+
+/* char: 0x28 '(' */
+
+static final byte[] ch40data = {
+(byte) 0x10,(byte) 0x30,(byte) 0x60,(byte) 0x60,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x60,(byte) 0x60,
+(byte) 0x30,(byte) 0x10,
+};
+
+static final BitmapCharRec ch40 = new BitmapCharRec(4,18,-1,4,6,ch40data);
+
+/* char: 0x27 ''' */
+
+static final byte[] ch39data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch39 = new BitmapCharRec(2,5,-1,-9,4,ch39data);
+
+/* char: 0x26 '&' */
+
+static final byte[] ch38data = {
+(byte) 0x3c,(byte) 0x70,(byte) 0x7e,(byte) 0xe0,(byte) 0xe7,(byte) 0xc0,(byte) 0xc3,(byte) 0x80,(byte) 0xc3,(byte) 0xc0,(byte) 0xc6,(byte) 0xc0,(byte) 0xee,(byte) 0xc0,(byte) 0x7c,(byte) 0x0,
+(byte) 0x3c,(byte) 0x0,(byte) 0x66,(byte) 0x0,(byte) 0x66,(byte) 0x0,(byte) 0x7e,(byte) 0x0,(byte) 0x3c,(byte) 0x0,
+};
+
+static final BitmapCharRec ch38 = new BitmapCharRec(12,13,-1,0,13,ch38data);
+
+/* char: 0x25 '%' */
+
+static final byte[] ch37data = {
+(byte) 0x18,(byte) 0x78,(byte) 0x18,(byte) 0xfc,(byte) 0xc,(byte) 0xcc,(byte) 0xc,(byte) 0xcc,(byte) 0x6,(byte) 0xfc,(byte) 0x6,(byte) 0x78,(byte) 0x3,(byte) 0x0,(byte) 0x7b,(byte) 0x0,
+(byte) 0xfd,(byte) 0x80,(byte) 0xcd,(byte) 0x80,(byte) 0xcc,(byte) 0xc0,(byte) 0xfc,(byte) 0xc0,(byte) 0x78,(byte) 0x60,
+};
+
+static final BitmapCharRec ch37 = new BitmapCharRec(14,13,-1,0,16,ch37data);
+
+/* char: 0x24 '$' */
+
+static final byte[] ch36data = {
+(byte) 0x8,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0xeb,(byte) 0x80,(byte) 0xc9,(byte) 0x80,(byte) 0x9,(byte) 0x80,(byte) 0xf,(byte) 0x0,
+(byte) 0x3e,(byte) 0x0,(byte) 0x78,(byte) 0x0,(byte) 0xe8,(byte) 0x0,(byte) 0xc8,(byte) 0x0,(byte) 0xcb,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x8,(byte) 0x0,
+};
+
+static final BitmapCharRec ch36 = new BitmapCharRec(9,16,-1,2,10,ch36data);
+
+/* char: 0x23 '#' */
+
+static final byte[] ch35data = {
+(byte) 0x24,(byte) 0x0,(byte) 0x24,(byte) 0x0,(byte) 0x24,(byte) 0x0,(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0x80,(byte) 0x12,(byte) 0x0,(byte) 0x12,(byte) 0x0,(byte) 0x12,(byte) 0x0,
+(byte) 0x7f,(byte) 0xc0,(byte) 0x7f,(byte) 0xc0,(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,
+};
+
+static final BitmapCharRec ch35 = new BitmapCharRec(10,13,0,0,10,ch35data);
+
+/* char: 0x22 '"' */
+
+static final byte[] ch34data = {
+(byte) 0x90,(byte) 0x90,(byte) 0xd8,(byte) 0xd8,(byte) 0xd8,
+};
+
+static final BitmapCharRec ch34 = new BitmapCharRec(5,5,0,-9,5,ch34data);
+
+/* char: 0x21 '!' */
+
+static final byte[] ch33data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch33 = new BitmapCharRec(2,14,-2,0,6,ch33data);
+
+/* char: 0x20 ' ' */
+
+static final BitmapCharRec ch32 = new BitmapCharRec(0,0,0,0,5,null);
+
+static final BitmapCharRec[] chars = {
+ch32,
+ch33,
+ch34,
+ch35,
+ch36,
+ch37,
+ch38,
+ch39,
+ch40,
+ch41,
+ch42,
+ch43,
+ch44,
+ch45,
+ch46,
+ch47,
+ch48,
+ch49,
+ch50,
+ch51,
+ch52,
+ch53,
+ch54,
+ch55,
+ch56,
+ch57,
+ch58,
+ch59,
+ch60,
+ch61,
+ch62,
+ch63,
+ch64,
+ch65,
+ch66,
+ch67,
+ch68,
+ch69,
+ch70,
+ch71,
+ch72,
+ch73,
+ch74,
+ch75,
+ch76,
+ch77,
+ch78,
+ch79,
+ch80,
+ch81,
+ch82,
+ch83,
+ch84,
+ch85,
+ch86,
+ch87,
+ch88,
+ch89,
+ch90,
+ch91,
+ch92,
+ch93,
+ch94,
+ch95,
+ch96,
+ch97,
+ch98,
+ch99,
+ch100,
+ch101,
+ch102,
+ch103,
+ch104,
+ch105,
+ch106,
+ch107,
+ch108,
+ch109,
+ch110,
+ch111,
+ch112,
+ch113,
+ch114,
+ch115,
+ch116,
+ch117,
+ch118,
+ch119,
+ch120,
+ch121,
+ch122,
+ch123,
+ch124,
+ch125,
+ch126,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+ch160,
+ch161,
+ch162,
+ch163,
+ch164,
+ch165,
+ch166,
+ch167,
+ch168,
+ch169,
+ch170,
+ch171,
+ch172,
+ch173,
+ch174,
+ch175,
+ch176,
+ch177,
+ch178,
+ch179,
+ch180,
+ch181,
+ch182,
+ch183,
+ch184,
+ch185,
+ch186,
+ch187,
+ch188,
+ch189,
+ch190,
+ch191,
+ch192,
+ch193,
+ch194,
+ch195,
+ch196,
+ch197,
+ch198,
+ch199,
+ch200,
+ch201,
+ch202,
+ch203,
+ch204,
+ch205,
+ch206,
+ch207,
+ch208,
+ch209,
+ch210,
+ch211,
+ch212,
+ch213,
+ch214,
+ch215,
+ch216,
+ch217,
+ch218,
+ch219,
+ch220,
+ch221,
+ch222,
+ch223,
+ch224,
+ch225,
+ch226,
+ch227,
+ch228,
+ch229,
+ch230,
+ch231,
+ch232,
+ch233,
+ch234,
+ch235,
+ch236,
+ch237,
+ch238,
+ch239,
+ch240,
+ch241,
+ch242,
+ch243,
+ch244,
+ch245,
+ch246,
+ch247,
+ch248,
+ch249,
+ch250,
+ch251,
+ch252,
+ch253,
+ch254,
+ch255,
+};
+
+ public static final BitmapFontRec glutBitmapHelvetica18 = new BitmapFontRec("-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1",
+ 224,
+ 32,
+ chars);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapTimesRoman10.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapTimesRoman10.java
new file mode 100644
index 000000000..f753b56f7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapTimesRoman10.java
@@ -0,0 +1,1797 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+class GLUTBitmapTimesRoman10 {
+
+/* GENERATED FILE -- DO NOT MODIFY */
+
+/* char: 0xff */
+
+static final byte[] ch255data = {
+(byte) 0x80,(byte) 0xc0,(byte) 0x40,(byte) 0x60,(byte) 0xa0,(byte) 0x90,(byte) 0xb8,(byte) 0x0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch255 = new BitmapCharRec(5,9,0,2,5,ch255data);
+
+/* char: 0xfe */
+
+static final byte[] ch254data = {
+(byte) 0xc0,(byte) 0x80,(byte) 0xe0,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0xe0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch254 = new BitmapCharRec(4,9,0,2,5,ch254data);
+
+/* char: 0xfd */
+
+static final byte[] ch253data = {
+(byte) 0x80,(byte) 0xc0,(byte) 0x40,(byte) 0x60,(byte) 0xa0,(byte) 0x90,(byte) 0xb8,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch253 = new BitmapCharRec(5,10,0,2,5,ch253data);
+
+/* char: 0xfc */
+
+static final byte[] ch252data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch252 = new BitmapCharRec(5,7,0,0,5,ch252data);
+
+/* char: 0xfb */
+
+static final byte[] ch251data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch251 = new BitmapCharRec(5,8,0,0,5,ch251data);
+
+/* char: 0xfa */
+
+static final byte[] ch250data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x0,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch250 = new BitmapCharRec(5,8,0,0,5,ch250data);
+
+/* char: 0xf9 */
+
+static final byte[] ch249data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch249 = new BitmapCharRec(5,8,0,0,5,ch249data);
+
+/* char: 0xf8 */
+
+static final byte[] ch248data = {
+(byte) 0x80,(byte) 0x70,(byte) 0x48,(byte) 0x48,(byte) 0x48,(byte) 0x38,(byte) 0x4,
+};
+
+static final BitmapCharRec ch248 = new BitmapCharRec(6,7,1,1,5,ch248data);
+
+/* char: 0xf7 */
+
+static final byte[] ch247data = {
+(byte) 0x20,(byte) 0x0,(byte) 0xf8,(byte) 0x0,(byte) 0x20,
+};
+
+static final BitmapCharRec ch247 = new BitmapCharRec(5,5,0,0,6,ch247data);
+
+/* char: 0xf6 */
+
+static final byte[] ch246data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x60,(byte) 0x0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch246 = new BitmapCharRec(4,7,0,0,5,ch246data);
+
+/* char: 0xf5 */
+
+static final byte[] ch245data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x60,(byte) 0x0,(byte) 0xa0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch245 = new BitmapCharRec(4,8,0,0,5,ch245data);
+
+/* char: 0xf4 */
+
+static final byte[] ch244data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x60,(byte) 0x0,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch244 = new BitmapCharRec(4,8,0,0,5,ch244data);
+
+/* char: 0xf3 */
+
+static final byte[] ch243data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x60,(byte) 0x0,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch243 = new BitmapCharRec(4,8,0,0,5,ch243data);
+
+/* char: 0xf2 */
+
+static final byte[] ch242data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x60,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch242 = new BitmapCharRec(4,8,0,0,5,ch242data);
+
+/* char: 0xf1 */
+
+static final byte[] ch241data = {
+(byte) 0xd8,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0xe0,(byte) 0x0,(byte) 0xa0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch241 = new BitmapCharRec(5,8,0,0,5,ch241data);
+
+/* char: 0xf0 */
+
+static final byte[] ch240data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x70,(byte) 0xa0,(byte) 0x70,(byte) 0x40,
+};
+
+static final BitmapCharRec ch240 = new BitmapCharRec(4,8,0,0,5,ch240data);
+
+/* char: 0xef */
+
+static final byte[] ch239data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch239 = new BitmapCharRec(3,7,0,0,4,ch239data);
+
+/* char: 0xee */
+
+static final byte[] ch238data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x0,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch238 = new BitmapCharRec(3,8,0,0,4,ch238data);
+
+/* char: 0xed */
+
+static final byte[] ch237data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x0,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch237 = new BitmapCharRec(3,8,0,0,4,ch237data);
+
+/* char: 0xec */
+
+static final byte[] ch236data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x0,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch236 = new BitmapCharRec(3,8,0,0,4,ch236data);
+
+/* char: 0xeb */
+
+static final byte[] ch235data = {
+(byte) 0x60,(byte) 0x80,(byte) 0xc0,(byte) 0xa0,(byte) 0x60,(byte) 0x0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch235 = new BitmapCharRec(3,7,0,0,4,ch235data);
+
+/* char: 0xea */
+
+static final byte[] ch234data = {
+(byte) 0x60,(byte) 0x80,(byte) 0xc0,(byte) 0xa0,(byte) 0x60,(byte) 0x0,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch234 = new BitmapCharRec(3,8,0,0,4,ch234data);
+
+/* char: 0xe9 */
+
+static final byte[] ch233data = {
+(byte) 0x60,(byte) 0x80,(byte) 0xc0,(byte) 0xa0,(byte) 0x60,(byte) 0x0,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch233 = new BitmapCharRec(3,8,0,0,4,ch233data);
+
+/* char: 0xe8 */
+
+static final byte[] ch232data = {
+(byte) 0x60,(byte) 0x80,(byte) 0xc0,(byte) 0xa0,(byte) 0x60,(byte) 0x0,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch232 = new BitmapCharRec(3,8,0,0,4,ch232data);
+
+/* char: 0xe7 */
+
+static final byte[] ch231data = {
+(byte) 0xc0,(byte) 0x20,(byte) 0x40,(byte) 0x60,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x60,
+};
+
+static final BitmapCharRec ch231 = new BitmapCharRec(3,8,0,3,4,ch231data);
+
+/* char: 0xe6 */
+
+static final byte[] ch230data = {
+(byte) 0xd8,(byte) 0xa0,(byte) 0x70,(byte) 0x28,(byte) 0xd8,
+};
+
+static final BitmapCharRec ch230 = new BitmapCharRec(5,5,0,0,6,ch230data);
+
+/* char: 0xe5 */
+
+static final byte[] ch229data = {
+(byte) 0xe0,(byte) 0xa0,(byte) 0x60,(byte) 0x20,(byte) 0xc0,(byte) 0x40,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch229 = new BitmapCharRec(3,8,0,0,4,ch229data);
+
+/* char: 0xe4 */
+
+static final byte[] ch228data = {
+(byte) 0xe0,(byte) 0xa0,(byte) 0x60,(byte) 0x20,(byte) 0xc0,(byte) 0x0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch228 = new BitmapCharRec(3,7,0,0,4,ch228data);
+
+/* char: 0xe3 */
+
+static final byte[] ch227data = {
+(byte) 0xe0,(byte) 0xa0,(byte) 0x60,(byte) 0x20,(byte) 0xc0,(byte) 0x0,(byte) 0xa0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch227 = new BitmapCharRec(4,8,0,0,4,ch227data);
+
+/* char: 0xe2 */
+
+static final byte[] ch226data = {
+(byte) 0xe0,(byte) 0xa0,(byte) 0x60,(byte) 0x20,(byte) 0xc0,(byte) 0x0,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch226 = new BitmapCharRec(3,8,0,0,4,ch226data);
+
+/* char: 0xe1 */
+
+static final byte[] ch225data = {
+(byte) 0xe0,(byte) 0xa0,(byte) 0x60,(byte) 0x20,(byte) 0xc0,(byte) 0x0,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch225 = new BitmapCharRec(3,8,0,0,4,ch225data);
+
+/* char: 0xe0 */
+
+static final byte[] ch224data = {
+(byte) 0xe0,(byte) 0xa0,(byte) 0x60,(byte) 0x20,(byte) 0xc0,(byte) 0x0,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch224 = new BitmapCharRec(3,8,0,0,4,ch224data);
+
+/* char: 0xdf */
+
+static final byte[] ch223data = {
+(byte) 0xe0,(byte) 0x50,(byte) 0x50,(byte) 0x60,(byte) 0x50,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch223 = new BitmapCharRec(4,7,0,0,5,ch223data);
+
+/* char: 0xde */
+
+static final byte[] ch222data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x70,(byte) 0x48,(byte) 0x70,(byte) 0x40,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch222 = new BitmapCharRec(5,7,0,0,6,ch222data);
+
+/* char: 0xdd */
+
+static final byte[] ch221data = {
+(byte) 0x38,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x28,(byte) 0x44,(byte) 0xee,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch221 = new BitmapCharRec(7,10,0,0,8,ch221data);
+
+/* char: 0xdc */
+
+static final byte[] ch220data = {
+(byte) 0x38,(byte) 0x6c,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0xee,(byte) 0x0,(byte) 0x28,
+};
+
+static final BitmapCharRec ch220 = new BitmapCharRec(7,9,0,0,8,ch220data);
+
+/* char: 0xdb */
+
+static final byte[] ch219data = {
+(byte) 0x38,(byte) 0x6c,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0xee,(byte) 0x0,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch219 = new BitmapCharRec(7,10,0,0,8,ch219data);
+
+/* char: 0xda */
+
+static final byte[] ch218data = {
+(byte) 0x38,(byte) 0x6c,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0xee,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch218 = new BitmapCharRec(7,10,0,0,8,ch218data);
+
+/* char: 0xd9 */
+
+static final byte[] ch217data = {
+(byte) 0x38,(byte) 0x6c,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0xee,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch217 = new BitmapCharRec(7,10,0,0,8,ch217data);
+
+/* char: 0xd8 */
+
+static final byte[] ch216data = {
+(byte) 0x80,(byte) 0x7c,(byte) 0x66,(byte) 0x52,(byte) 0x52,(byte) 0x4a,(byte) 0x66,(byte) 0x3e,(byte) 0x1,
+};
+
+static final BitmapCharRec ch216 = new BitmapCharRec(8,9,0,1,8,ch216data);
+
+/* char: 0xd7 */
+
+static final byte[] ch215data = {
+(byte) 0x88,(byte) 0x50,(byte) 0x20,(byte) 0x50,(byte) 0x88,
+};
+
+static final BitmapCharRec ch215 = new BitmapCharRec(5,5,0,0,6,ch215data);
+
+/* char: 0xd6 */
+
+static final byte[] ch214data = {
+(byte) 0x78,(byte) 0xcc,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xcc,(byte) 0x78,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch214 = new BitmapCharRec(6,9,0,0,7,ch214data);
+
+/* char: 0xd5 */
+
+static final byte[] ch213data = {
+(byte) 0x78,(byte) 0xcc,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xcc,(byte) 0x78,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch213 = new BitmapCharRec(6,10,0,0,7,ch213data);
+
+/* char: 0xd4 */
+
+static final byte[] ch212data = {
+(byte) 0x78,(byte) 0xcc,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xcc,(byte) 0x78,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch212 = new BitmapCharRec(6,10,0,0,7,ch212data);
+
+/* char: 0xd3 */
+
+static final byte[] ch211data = {
+(byte) 0x78,(byte) 0xcc,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xcc,(byte) 0x78,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch211 = new BitmapCharRec(6,10,0,0,7,ch211data);
+
+/* char: 0xd2 */
+
+static final byte[] ch210data = {
+(byte) 0x78,(byte) 0xcc,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xcc,(byte) 0x78,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch210 = new BitmapCharRec(6,10,0,0,7,ch210data);
+
+/* char: 0xd1 */
+
+static final byte[] ch209data = {
+(byte) 0xe4,(byte) 0x4c,(byte) 0x4c,(byte) 0x54,(byte) 0x54,(byte) 0x64,(byte) 0xee,(byte) 0x0,(byte) 0x50,(byte) 0x28,
+};
+
+static final BitmapCharRec ch209 = new BitmapCharRec(7,10,0,0,8,ch209data);
+
+/* char: 0xd0 */
+
+static final byte[] ch208data = {
+(byte) 0xf8,(byte) 0x4c,(byte) 0x44,(byte) 0xe4,(byte) 0x44,(byte) 0x4c,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch208 = new BitmapCharRec(6,7,0,0,7,ch208data);
+
+/* char: 0xcf */
+
+static final byte[] ch207data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch207 = new BitmapCharRec(3,9,0,0,4,ch207data);
+
+/* char: 0xce */
+
+static final byte[] ch206data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x0,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch206 = new BitmapCharRec(3,10,0,0,4,ch206data);
+
+/* char: 0xcd */
+
+static final byte[] ch205data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x0,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch205 = new BitmapCharRec(3,10,0,0,4,ch205data);
+
+/* char: 0xcc */
+
+static final byte[] ch204data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x0,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch204 = new BitmapCharRec(3,10,0,0,4,ch204data);
+
+/* char: 0xcb */
+
+static final byte[] ch203data = {
+(byte) 0xf8,(byte) 0x48,(byte) 0x40,(byte) 0x70,(byte) 0x40,(byte) 0x48,(byte) 0xf8,(byte) 0x0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch203 = new BitmapCharRec(5,9,0,0,6,ch203data);
+
+/* char: 0xca */
+
+static final byte[] ch202data = {
+(byte) 0xf8,(byte) 0x48,(byte) 0x40,(byte) 0x70,(byte) 0x40,(byte) 0x48,(byte) 0xf8,(byte) 0x0,(byte) 0x50,(byte) 0x20,
+};
+
+static final BitmapCharRec ch202 = new BitmapCharRec(5,10,0,0,6,ch202data);
+
+/* char: 0xc9 */
+
+static final byte[] ch201data = {
+(byte) 0xf8,(byte) 0x48,(byte) 0x40,(byte) 0x70,(byte) 0x40,(byte) 0x48,(byte) 0xf8,(byte) 0x0,(byte) 0x20,(byte) 0x10,
+};
+
+static final BitmapCharRec ch201 = new BitmapCharRec(5,10,0,0,6,ch201data);
+
+/* char: 0xc8 */
+
+static final byte[] ch200data = {
+(byte) 0xf8,(byte) 0x48,(byte) 0x40,(byte) 0x70,(byte) 0x40,(byte) 0x48,(byte) 0xf8,(byte) 0x0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch200 = new BitmapCharRec(5,10,0,0,6,ch200data);
+
+/* char: 0xc7 */
+
+static final byte[] ch199data = {
+(byte) 0x60,(byte) 0x10,(byte) 0x20,(byte) 0x78,(byte) 0xc4,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xc4,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch199 = new BitmapCharRec(6,10,0,3,7,ch199data);
+
+/* char: 0xc6 */
+
+static final byte[] ch198data = {
+(byte) 0xef,(byte) 0x49,(byte) 0x78,(byte) 0x2e,(byte) 0x28,(byte) 0x39,(byte) 0x1f,
+};
+
+static final BitmapCharRec ch198 = new BitmapCharRec(8,7,0,0,9,ch198data);
+
+/* char: 0xc5 */
+
+static final byte[] ch197data = {
+(byte) 0xee,(byte) 0x44,(byte) 0x7c,(byte) 0x28,(byte) 0x28,(byte) 0x38,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch197 = new BitmapCharRec(7,10,0,0,8,ch197data);
+
+/* char: 0xc4 */
+
+static final byte[] ch196data = {
+(byte) 0xee,(byte) 0x44,(byte) 0x7c,(byte) 0x28,(byte) 0x28,(byte) 0x38,(byte) 0x10,(byte) 0x0,(byte) 0x28,
+};
+
+static final BitmapCharRec ch196 = new BitmapCharRec(7,9,0,0,8,ch196data);
+
+/* char: 0xc3 */
+
+static final byte[] ch195data = {
+(byte) 0xee,(byte) 0x44,(byte) 0x7c,(byte) 0x28,(byte) 0x28,(byte) 0x38,(byte) 0x10,(byte) 0x0,(byte) 0x28,(byte) 0x14,
+};
+
+static final BitmapCharRec ch195 = new BitmapCharRec(7,10,0,0,8,ch195data);
+
+/* char: 0xc2 */
+
+static final byte[] ch194data = {
+(byte) 0xee,(byte) 0x44,(byte) 0x7c,(byte) 0x28,(byte) 0x28,(byte) 0x38,(byte) 0x10,(byte) 0x0,(byte) 0x28,(byte) 0x10,
+};
+
+static final BitmapCharRec ch194 = new BitmapCharRec(7,10,0,0,8,ch194data);
+
+/* char: 0xc1 */
+
+static final byte[] ch193data = {
+(byte) 0xee,(byte) 0x44,(byte) 0x7c,(byte) 0x28,(byte) 0x28,(byte) 0x38,(byte) 0x10,(byte) 0x0,(byte) 0x10,(byte) 0x8,
+};
+
+static final BitmapCharRec ch193 = new BitmapCharRec(7,10,0,0,8,ch193data);
+
+/* char: 0xc0 */
+
+static final byte[] ch192data = {
+(byte) 0xee,(byte) 0x44,(byte) 0x7c,(byte) 0x28,(byte) 0x28,(byte) 0x38,(byte) 0x10,(byte) 0x0,(byte) 0x10,(byte) 0x20,
+};
+
+static final BitmapCharRec ch192 = new BitmapCharRec(7,10,0,0,8,ch192data);
+
+/* char: 0xbf */
+
+static final byte[] ch191data = {
+(byte) 0xe0,(byte) 0xa0,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch191 = new BitmapCharRec(3,7,0,2,4,ch191data);
+
+/* char: 0xbe */
+
+static final byte[] ch190data = {
+(byte) 0x44,(byte) 0x3e,(byte) 0x2c,(byte) 0xd4,(byte) 0x28,(byte) 0x48,(byte) 0xe4,
+};
+
+static final BitmapCharRec ch190 = new BitmapCharRec(7,7,0,0,8,ch190data);
+
+/* char: 0xbd */
+
+static final byte[] ch189data = {
+(byte) 0x4e,(byte) 0x24,(byte) 0x2a,(byte) 0xf6,(byte) 0x48,(byte) 0xc8,(byte) 0x44,
+};
+
+static final BitmapCharRec ch189 = new BitmapCharRec(7,7,0,0,8,ch189data);
+
+/* char: 0xbc */
+
+static final byte[] ch188data = {
+(byte) 0x44,(byte) 0x3e,(byte) 0x2c,(byte) 0xf4,(byte) 0x48,(byte) 0xc8,(byte) 0x44,
+};
+
+static final BitmapCharRec ch188 = new BitmapCharRec(7,7,0,0,8,ch188data);
+
+/* char: 0xbb */
+
+static final byte[] ch187data = {
+(byte) 0xa0,(byte) 0x50,(byte) 0x50,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch187 = new BitmapCharRec(4,4,0,-1,5,ch187data);
+
+/* char: 0xba */
+
+static final byte[] ch186data = {
+(byte) 0xe0,(byte) 0x0,(byte) 0x40,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch186 = new BitmapCharRec(3,5,0,-2,4,ch186data);
+
+/* char: 0xb9 */
+
+static final byte[] ch185data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch185 = new BitmapCharRec(3,4,0,-3,3,ch185data);
+
+/* char: 0xb8 */
+
+static final byte[] ch184data = {
+(byte) 0xc0,(byte) 0x20,(byte) 0x40,
+};
+
+static final BitmapCharRec ch184 = new BitmapCharRec(3,3,0,3,4,ch184data);
+
+/* char: 0xb7 */
+
+static final byte[] ch183data = {
+(byte) 0x80,
+};
+
+static final BitmapCharRec ch183 = new BitmapCharRec(1,1,0,-2,2,ch183data);
+
+/* char: 0xb6 */
+
+static final byte[] ch182data = {
+(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x28,(byte) 0x68,(byte) 0xe8,(byte) 0xe8,(byte) 0xe8,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch182 = new BitmapCharRec(6,9,0,2,6,ch182data);
+
+/* char: 0xb5 */
+
+static final byte[] ch181data = {
+(byte) 0x80,(byte) 0x80,(byte) 0xe8,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,
+};
+
+static final BitmapCharRec ch181 = new BitmapCharRec(5,7,0,2,5,ch181data);
+
+/* char: 0xb4 */
+
+static final byte[] ch180data = {
+(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch180 = new BitmapCharRec(2,2,0,-5,3,ch180data);
+
+/* char: 0xb3 */
+
+static final byte[] ch179data = {
+(byte) 0xc0,(byte) 0x20,(byte) 0x40,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch179 = new BitmapCharRec(3,4,0,-3,3,ch179data);
+
+/* char: 0xb2 */
+
+static final byte[] ch178data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0xa0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch178 = new BitmapCharRec(3,4,0,-3,3,ch178data);
+
+/* char: 0xb1 */
+
+static final byte[] ch177data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch177 = new BitmapCharRec(5,7,0,0,6,ch177data);
+
+/* char: 0xb0 */
+
+static final byte[] ch176data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch176 = new BitmapCharRec(4,4,0,-3,4,ch176data);
+
+/* char: 0xaf */
+
+static final byte[] ch175data = {
+(byte) 0xe0,
+};
+
+static final BitmapCharRec ch175 = new BitmapCharRec(3,1,0,-6,4,ch175data);
+
+/* char: 0xae */
+
+static final byte[] ch174data = {
+(byte) 0x38,(byte) 0x44,(byte) 0xaa,(byte) 0xb2,(byte) 0xba,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch174 = new BitmapCharRec(7,7,-1,0,9,ch174data);
+
+/* char: 0xad */
+
+static final byte[] ch173data = {
+(byte) 0xe0,
+};
+
+static final BitmapCharRec ch173 = new BitmapCharRec(3,1,0,-2,4,ch173data);
+
+/* char: 0xac */
+
+static final byte[] ch172data = {
+(byte) 0x8,(byte) 0x8,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch172 = new BitmapCharRec(5,3,-1,-1,7,ch172data);
+
+/* char: 0xab */
+
+static final byte[] ch171data = {
+(byte) 0x50,(byte) 0xa0,(byte) 0xa0,(byte) 0x50,
+};
+
+static final BitmapCharRec ch171 = new BitmapCharRec(4,4,0,-1,5,ch171data);
+
+/* char: 0xaa */
+
+static final byte[] ch170data = {
+(byte) 0xe0,(byte) 0x0,(byte) 0xa0,(byte) 0x20,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch170 = new BitmapCharRec(3,5,0,-2,4,ch170data);
+
+/* char: 0xa9 */
+
+static final byte[] ch169data = {
+(byte) 0x38,(byte) 0x44,(byte) 0x9a,(byte) 0xa2,(byte) 0x9a,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch169 = new BitmapCharRec(7,7,-1,0,9,ch169data);
+
+/* char: 0xa8 */
+
+static final byte[] ch168data = {
+(byte) 0xa0,
+};
+
+static final BitmapCharRec ch168 = new BitmapCharRec(3,1,-1,-6,5,ch168data);
+
+/* char: 0xa7 */
+
+static final byte[] ch167data = {
+(byte) 0xe0,(byte) 0x90,(byte) 0x20,(byte) 0x50,(byte) 0x90,(byte) 0xa0,(byte) 0x40,(byte) 0x90,(byte) 0x70,
+};
+
+static final BitmapCharRec ch167 = new BitmapCharRec(4,9,0,1,5,ch167data);
+
+/* char: 0xa6 */
+
+static final byte[] ch166data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch166 = new BitmapCharRec(1,7,0,0,2,ch166data);
+
+/* char: 0xa5 */
+
+static final byte[] ch165data = {
+(byte) 0x70,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0xd8,(byte) 0x50,(byte) 0x88,
+};
+
+static final BitmapCharRec ch165 = new BitmapCharRec(5,7,0,0,5,ch165data);
+
+/* char: 0xa4 */
+
+static final byte[] ch164data = {
+(byte) 0x88,(byte) 0x70,(byte) 0x50,(byte) 0x50,(byte) 0x70,(byte) 0x88,
+};
+
+static final BitmapCharRec ch164 = new BitmapCharRec(5,6,0,-1,5,ch164data);
+
+/* char: 0xa3 */
+
+static final byte[] ch163data = {
+(byte) 0xf0,(byte) 0xc8,(byte) 0x40,(byte) 0xe0,(byte) 0x40,(byte) 0x50,(byte) 0x30,
+};
+
+static final BitmapCharRec ch163 = new BitmapCharRec(5,7,0,0,5,ch163data);
+
+/* char: 0xa2 */
+
+static final byte[] ch162data = {
+(byte) 0x80,(byte) 0xe0,(byte) 0x90,(byte) 0x80,(byte) 0x90,(byte) 0x70,(byte) 0x10,
+};
+
+static final BitmapCharRec ch162 = new BitmapCharRec(4,7,0,1,5,ch162data);
+
+/* char: 0xa1 */
+
+static final byte[] ch161data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch161 = new BitmapCharRec(1,7,-1,2,3,ch161data);
+
+/* char: 0xa0 */
+
+static final BitmapCharRec ch160 = new BitmapCharRec(0,0,0,0,2,null);
+
+/* char: 0x7e '~' */
+
+static final byte[] ch126data = {
+(byte) 0x98,(byte) 0x64,
+};
+
+static final BitmapCharRec ch126 = new BitmapCharRec(6,2,0,-2,7,ch126data);
+
+/* char: 0x7d '}' */
+
+static final byte[] ch125data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch125 = new BitmapCharRec(3,9,0,2,4,ch125data);
+
+/* char: 0x7c '|' */
+
+static final byte[] ch124data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch124 = new BitmapCharRec(1,9,0,2,2,ch124data);
+
+/* char: 0x7b '{' */
+
+static final byte[] ch123data = {
+(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch123 = new BitmapCharRec(3,9,0,2,4,ch123data);
+
+/* char: 0x7a 'z' */
+
+static final byte[] ch122data = {
+(byte) 0xf0,(byte) 0x90,(byte) 0x40,(byte) 0x20,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch122 = new BitmapCharRec(4,5,0,0,5,ch122data);
+
+/* char: 0x79 'y' */
+
+static final byte[] ch121data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x30,(byte) 0x50,(byte) 0x48,(byte) 0xdc,
+};
+
+static final BitmapCharRec ch121 = new BitmapCharRec(6,7,1,2,5,ch121data);
+
+/* char: 0x78 'x' */
+
+static final byte[] ch120data = {
+(byte) 0xd8,(byte) 0x50,(byte) 0x20,(byte) 0x50,(byte) 0xd8,
+};
+
+static final BitmapCharRec ch120 = new BitmapCharRec(5,5,0,0,6,ch120data);
+
+/* char: 0x77 'w' */
+
+static final byte[] ch119data = {
+(byte) 0x28,(byte) 0x6c,(byte) 0x54,(byte) 0x92,(byte) 0xdb,
+};
+
+static final BitmapCharRec ch119 = new BitmapCharRec(8,5,0,0,8,ch119data);
+
+/* char: 0x76 'v' */
+
+static final byte[] ch118data = {
+(byte) 0x20,(byte) 0x60,(byte) 0x50,(byte) 0x90,(byte) 0xd8,
+};
+
+static final BitmapCharRec ch118 = new BitmapCharRec(5,5,0,0,5,ch118data);
+
+/* char: 0x75 'u' */
+
+static final byte[] ch117data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,
+};
+
+static final BitmapCharRec ch117 = new BitmapCharRec(5,5,0,0,5,ch117data);
+
+/* char: 0x74 't' */
+
+static final byte[] ch116data = {
+(byte) 0x30,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch116 = new BitmapCharRec(4,6,0,0,4,ch116data);
+
+/* char: 0x73 's' */
+
+static final byte[] ch115data = {
+(byte) 0xe0,(byte) 0x20,(byte) 0x60,(byte) 0x80,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch115 = new BitmapCharRec(3,5,0,0,4,ch115data);
+
+/* char: 0x72 'r' */
+
+static final byte[] ch114data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x60,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch114 = new BitmapCharRec(3,5,0,0,4,ch114data);
+
+/* char: 0x71 'q' */
+
+static final byte[] ch113data = {
+(byte) 0x38,(byte) 0x10,(byte) 0x70,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x70,
+};
+
+static final BitmapCharRec ch113 = new BitmapCharRec(5,7,0,2,5,ch113data);
+
+/* char: 0x70 'p' */
+
+static final byte[] ch112data = {
+(byte) 0xc0,(byte) 0x80,(byte) 0xe0,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch112 = new BitmapCharRec(4,7,0,2,5,ch112data);
+
+/* char: 0x6f 'o' */
+
+static final byte[] ch111data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch111 = new BitmapCharRec(4,5,0,0,5,ch111data);
+
+/* char: 0x6e 'n' */
+
+static final byte[] ch110data = {
+(byte) 0xd8,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch110 = new BitmapCharRec(5,5,0,0,5,ch110data);
+
+/* char: 0x6d 'm' */
+
+static final byte[] ch109data = {
+(byte) 0xdb,(byte) 0x92,(byte) 0x92,(byte) 0x92,(byte) 0xec,
+};
+
+static final BitmapCharRec ch109 = new BitmapCharRec(8,5,0,0,8,ch109data);
+
+/* char: 0x6c 'l' */
+
+static final byte[] ch108data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch108 = new BitmapCharRec(3,7,0,0,4,ch108data);
+
+/* char: 0x6b 'k' */
+
+static final byte[] ch107data = {
+(byte) 0x98,(byte) 0x90,(byte) 0xe0,(byte) 0xa0,(byte) 0x90,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch107 = new BitmapCharRec(5,7,0,0,5,ch107data);
+
+/* char: 0x6a 'j' */
+
+static final byte[] ch106data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch106 = new BitmapCharRec(2,9,0,2,3,ch106data);
+
+/* char: 0x69 'i' */
+
+static final byte[] ch105data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch105 = new BitmapCharRec(2,7,0,0,3,ch105data);
+
+/* char: 0x68 'h' */
+
+static final byte[] ch104data = {
+(byte) 0xd8,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0xe0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch104 = new BitmapCharRec(5,7,0,0,5,ch104data);
+
+/* char: 0x67 'g' */
+
+static final byte[] ch103data = {
+(byte) 0xe0,(byte) 0x90,(byte) 0x60,(byte) 0x40,(byte) 0xa0,(byte) 0xa0,(byte) 0x70,
+};
+
+static final BitmapCharRec ch103 = new BitmapCharRec(4,7,0,2,5,ch103data);
+
+/* char: 0x66 'f' */
+
+static final byte[] ch102data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,(byte) 0x40,(byte) 0x30,
+};
+
+static final BitmapCharRec ch102 = new BitmapCharRec(4,7,0,0,4,ch102data);
+
+/* char: 0x65 'e' */
+
+static final byte[] ch101data = {
+(byte) 0x60,(byte) 0x80,(byte) 0xc0,(byte) 0xa0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch101 = new BitmapCharRec(3,5,0,0,4,ch101data);
+
+/* char: 0x64 'd' */
+
+static final byte[] ch100data = {
+(byte) 0x68,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x70,(byte) 0x10,(byte) 0x30,
+};
+
+static final BitmapCharRec ch100 = new BitmapCharRec(5,7,0,0,5,ch100data);
+
+/* char: 0x63 'c' */
+
+static final byte[] ch99data = {
+(byte) 0x60,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x60,
+};
+
+static final BitmapCharRec ch99 = new BitmapCharRec(3,5,0,0,4,ch99data);
+
+/* char: 0x62 'b' */
+
+static final byte[] ch98data = {
+(byte) 0xe0,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0xe0,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch98 = new BitmapCharRec(4,7,0,0,5,ch98data);
+
+/* char: 0x61 'a' */
+
+static final byte[] ch97data = {
+(byte) 0xe0,(byte) 0xa0,(byte) 0x60,(byte) 0x20,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch97 = new BitmapCharRec(3,5,0,0,4,ch97data);
+
+/* char: 0x60 '`' */
+
+static final byte[] ch96data = {
+(byte) 0xc0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch96 = new BitmapCharRec(2,2,0,-5,3,ch96data);
+
+/* char: 0x5f '_' */
+
+static final byte[] ch95data = {
+(byte) 0xf8,
+};
+
+static final BitmapCharRec ch95 = new BitmapCharRec(5,1,0,3,5,ch95data);
+
+/* char: 0x5e '^' */
+
+static final byte[] ch94data = {
+(byte) 0xa0,(byte) 0xa0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch94 = new BitmapCharRec(3,3,-1,-4,5,ch94data);
+
+/* char: 0x5d ']' */
+
+static final byte[] ch93data = {
+(byte) 0xc0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch93 = new BitmapCharRec(2,9,0,2,3,ch93data);
+
+/* char: 0x5c '\' */
+
+static final byte[] ch92data = {
+(byte) 0x20,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch92 = new BitmapCharRec(3,7,0,0,3,ch92data);
+
+/* char: 0x5b '[' */
+
+static final byte[] ch91data = {
+(byte) 0xc0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch91 = new BitmapCharRec(2,9,0,2,3,ch91data);
+
+/* char: 0x5a 'Z' */
+
+static final byte[] ch90data = {
+(byte) 0xf8,(byte) 0x88,(byte) 0x40,(byte) 0x20,(byte) 0x10,(byte) 0x88,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch90 = new BitmapCharRec(5,7,0,0,6,ch90data);
+
+/* char: 0x59 'Y' */
+
+static final byte[] ch89data = {
+(byte) 0x38,(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x28,(byte) 0x44,(byte) 0xee,
+};
+
+static final BitmapCharRec ch89 = new BitmapCharRec(7,7,0,0,8,ch89data);
+
+/* char: 0x58 'X' */
+
+static final byte[] ch88data = {
+(byte) 0xee,(byte) 0x44,(byte) 0x28,(byte) 0x10,(byte) 0x28,(byte) 0x44,(byte) 0xee,
+};
+
+static final BitmapCharRec ch88 = new BitmapCharRec(7,7,0,0,8,ch88data);
+
+/* char: 0x57 'W' */
+
+static final byte[] ch87data = {
+(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x55,(byte) 0x0,(byte) 0x55,(byte) 0x0,(byte) 0xc9,(byte) 0x80,(byte) 0x88,(byte) 0x80,(byte) 0xdd,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch87 = new BitmapCharRec(10,7,0,0,10,ch87data);
+
+/* char: 0x56 'V' */
+
+static final byte[] ch86data = {
+(byte) 0x10,(byte) 0x10,(byte) 0x28,(byte) 0x28,(byte) 0x6c,(byte) 0x44,(byte) 0xee,
+};
+
+static final BitmapCharRec ch86 = new BitmapCharRec(7,7,0,0,8,ch86data);
+
+/* char: 0x55 'U' */
+
+static final byte[] ch85data = {
+(byte) 0x38,(byte) 0x6c,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0xee,
+};
+
+static final BitmapCharRec ch85 = new BitmapCharRec(7,7,0,0,8,ch85data);
+
+/* char: 0x54 'T' */
+
+static final byte[] ch84data = {
+(byte) 0x70,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xa8,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch84 = new BitmapCharRec(5,7,0,0,6,ch84data);
+
+/* char: 0x53 'S' */
+
+static final byte[] ch83data = {
+(byte) 0xe0,(byte) 0x90,(byte) 0x10,(byte) 0x60,(byte) 0xc0,(byte) 0x90,(byte) 0x70,
+};
+
+static final BitmapCharRec ch83 = new BitmapCharRec(4,7,0,0,5,ch83data);
+
+/* char: 0x52 'R' */
+
+static final byte[] ch82data = {
+(byte) 0xec,(byte) 0x48,(byte) 0x50,(byte) 0x70,(byte) 0x48,(byte) 0x48,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch82 = new BitmapCharRec(6,7,0,0,7,ch82data);
+
+/* char: 0x51 'Q' */
+
+static final byte[] ch81data = {
+(byte) 0xc,(byte) 0x18,(byte) 0x70,(byte) 0xcc,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xcc,(byte) 0x78,
+};
+
+static final BitmapCharRec ch81 = new BitmapCharRec(6,9,0,2,7,ch81data);
+
+/* char: 0x50 'P' */
+
+static final byte[] ch80data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x70,(byte) 0x48,(byte) 0x48,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch80 = new BitmapCharRec(5,7,0,0,6,ch80data);
+
+/* char: 0x4f 'O' */
+
+static final byte[] ch79data = {
+(byte) 0x78,(byte) 0xcc,(byte) 0x84,(byte) 0x84,(byte) 0x84,(byte) 0xcc,(byte) 0x78,
+};
+
+static final BitmapCharRec ch79 = new BitmapCharRec(6,7,0,0,7,ch79data);
+
+/* char: 0x4e 'N' */
+
+static final byte[] ch78data = {
+(byte) 0xe4,(byte) 0x4c,(byte) 0x4c,(byte) 0x54,(byte) 0x54,(byte) 0x64,(byte) 0xee,
+};
+
+static final BitmapCharRec ch78 = new BitmapCharRec(7,7,0,0,8,ch78data);
+
+/* char: 0x4d 'M' */
+
+static final byte[] ch77data = {
+(byte) 0xeb,(byte) 0x80,(byte) 0x49,(byte) 0x0,(byte) 0x55,(byte) 0x0,(byte) 0x55,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0xe3,(byte) 0x80,
+};
+
+static final BitmapCharRec ch77 = new BitmapCharRec(9,7,0,0,10,ch77data);
+
+/* char: 0x4c 'L' */
+
+static final byte[] ch76data = {
+(byte) 0xf8,(byte) 0x48,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch76 = new BitmapCharRec(5,7,0,0,6,ch76data);
+
+/* char: 0x4b 'K' */
+
+static final byte[] ch75data = {
+(byte) 0xec,(byte) 0x48,(byte) 0x50,(byte) 0x60,(byte) 0x50,(byte) 0x48,(byte) 0xec,
+};
+
+static final BitmapCharRec ch75 = new BitmapCharRec(6,7,0,0,7,ch75data);
+
+/* char: 0x4a 'J' */
+
+static final byte[] ch74data = {
+(byte) 0xc0,(byte) 0xa0,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x70,
+};
+
+static final BitmapCharRec ch74 = new BitmapCharRec(4,7,0,0,4,ch74data);
+
+/* char: 0x49 'I' */
+
+static final byte[] ch73data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch73 = new BitmapCharRec(3,7,0,0,4,ch73data);
+
+/* char: 0x48 'H' */
+
+static final byte[] ch72data = {
+(byte) 0xee,(byte) 0x44,(byte) 0x44,(byte) 0x7c,(byte) 0x44,(byte) 0x44,(byte) 0xee,
+};
+
+static final BitmapCharRec ch72 = new BitmapCharRec(7,7,0,0,8,ch72data);
+
+/* char: 0x47 'G' */
+
+static final byte[] ch71data = {
+(byte) 0x78,(byte) 0xc4,(byte) 0x84,(byte) 0x9c,(byte) 0x80,(byte) 0xc4,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch71 = new BitmapCharRec(6,7,0,0,7,ch71data);
+
+/* char: 0x46 'F' */
+
+static final byte[] ch70data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x70,(byte) 0x40,(byte) 0x48,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch70 = new BitmapCharRec(5,7,0,0,6,ch70data);
+
+/* char: 0x45 'E' */
+
+static final byte[] ch69data = {
+(byte) 0xf8,(byte) 0x48,(byte) 0x40,(byte) 0x70,(byte) 0x40,(byte) 0x48,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch69 = new BitmapCharRec(5,7,0,0,6,ch69data);
+
+/* char: 0x44 'D' */
+
+static final byte[] ch68data = {
+(byte) 0xf8,(byte) 0x4c,(byte) 0x44,(byte) 0x44,(byte) 0x44,(byte) 0x4c,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch68 = new BitmapCharRec(6,7,0,0,7,ch68data);
+
+/* char: 0x43 'C' */
+
+static final byte[] ch67data = {
+(byte) 0x78,(byte) 0xc4,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0xc4,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch67 = new BitmapCharRec(6,7,0,0,7,ch67data);
+
+/* char: 0x42 'B' */
+
+static final byte[] ch66data = {
+(byte) 0xf0,(byte) 0x48,(byte) 0x48,(byte) 0x70,(byte) 0x48,(byte) 0x48,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch66 = new BitmapCharRec(5,7,0,0,6,ch66data);
+
+/* char: 0x41 'A' */
+
+static final byte[] ch65data = {
+(byte) 0xee,(byte) 0x44,(byte) 0x7c,(byte) 0x28,(byte) 0x28,(byte) 0x38,(byte) 0x10,
+};
+
+static final BitmapCharRec ch65 = new BitmapCharRec(7,7,0,0,8,ch65data);
+
+/* char: 0x40 '@' */
+
+static final byte[] ch64data = {
+(byte) 0x3e,(byte) 0x40,(byte) 0x92,(byte) 0xad,(byte) 0xa5,(byte) 0xa5,(byte) 0x9d,(byte) 0x42,(byte) 0x3c,
+};
+
+static final BitmapCharRec ch64 = new BitmapCharRec(8,9,0,2,9,ch64data);
+
+/* char: 0x3f '?' */
+
+static final byte[] ch63data = {
+(byte) 0x40,(byte) 0x0,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0xa0,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch63 = new BitmapCharRec(3,7,0,0,4,ch63data);
+
+/* char: 0x3e '>' */
+
+static final byte[] ch62data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch62 = new BitmapCharRec(3,5,0,0,5,ch62data);
+
+/* char: 0x3d '=' */
+
+static final byte[] ch61data = {
+(byte) 0xf8,(byte) 0x0,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch61 = new BitmapCharRec(5,3,0,-1,6,ch61data);
+
+/* char: 0x3c '<' */
+
+static final byte[] ch60data = {
+(byte) 0x20,(byte) 0x40,(byte) 0x80,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch60 = new BitmapCharRec(3,5,-1,0,5,ch60data);
+
+/* char: 0x3b ';' */
+
+static final byte[] ch59data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch59 = new BitmapCharRec(1,7,-1,2,3,ch59data);
+
+/* char: 0x3a ':' */
+
+static final byte[] ch58data = {
+(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x80,
+};
+
+static final BitmapCharRec ch58 = new BitmapCharRec(1,5,-1,0,3,ch58data);
+
+/* char: 0x39 '9' */
+
+static final byte[] ch57data = {
+(byte) 0xc0,(byte) 0x20,(byte) 0x70,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch57 = new BitmapCharRec(4,7,0,0,5,ch57data);
+
+/* char: 0x38 '8' */
+
+static final byte[] ch56data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch56 = new BitmapCharRec(4,7,0,0,5,ch56data);
+
+/* char: 0x37 '7' */
+
+static final byte[] ch55data = {
+(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x90,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch55 = new BitmapCharRec(4,7,0,0,5,ch55data);
+
+/* char: 0x36 '6' */
+
+static final byte[] ch54data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0xe0,(byte) 0x40,(byte) 0x30,
+};
+
+static final BitmapCharRec ch54 = new BitmapCharRec(4,7,0,0,5,ch54data);
+
+/* char: 0x35 '5' */
+
+static final byte[] ch53data = {
+(byte) 0xe0,(byte) 0x90,(byte) 0x10,(byte) 0x10,(byte) 0xe0,(byte) 0x40,(byte) 0x70,
+};
+
+static final BitmapCharRec ch53 = new BitmapCharRec(4,7,0,0,5,ch53data);
+
+/* char: 0x34 '4' */
+
+static final byte[] ch52data = {
+(byte) 0x10,(byte) 0x10,(byte) 0xf8,(byte) 0x90,(byte) 0x50,(byte) 0x30,(byte) 0x10,
+};
+
+static final BitmapCharRec ch52 = new BitmapCharRec(5,7,0,0,5,ch52data);
+
+/* char: 0x33 '3' */
+
+static final byte[] ch51data = {
+(byte) 0xe0,(byte) 0x10,(byte) 0x10,(byte) 0x60,(byte) 0x10,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch51 = new BitmapCharRec(4,7,0,0,5,ch51data);
+
+/* char: 0x32 '2' */
+
+static final byte[] ch50data = {
+(byte) 0xf0,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x10,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch50 = new BitmapCharRec(4,7,0,0,5,ch50data);
+
+/* char: 0x31 '1' */
+
+static final byte[] ch49data = {
+(byte) 0xe0,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0xc0,(byte) 0x40,
+};
+
+static final BitmapCharRec ch49 = new BitmapCharRec(3,7,-1,0,5,ch49data);
+
+/* char: 0x30 '0' */
+
+static final byte[] ch48data = {
+(byte) 0x60,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x90,(byte) 0x60,
+};
+
+static final BitmapCharRec ch48 = new BitmapCharRec(4,7,0,0,5,ch48data);
+
+/* char: 0x2f '/' */
+
+static final byte[] ch47data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch47 = new BitmapCharRec(3,7,0,0,3,ch47data);
+
+/* char: 0x2e '.' */
+
+static final byte[] ch46data = {
+(byte) 0x80,
+};
+
+static final BitmapCharRec ch46 = new BitmapCharRec(1,1,-1,0,3,ch46data);
+
+/* char: 0x2d '-' */
+
+static final byte[] ch45data = {
+(byte) 0xf0,
+};
+
+static final BitmapCharRec ch45 = new BitmapCharRec(4,1,-1,-2,7,ch45data);
+
+/* char: 0x2c ',' */
+
+static final byte[] ch44data = {
+(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch44 = new BitmapCharRec(1,3,-1,2,3,ch44data);
+
+/* char: 0x2b '+' */
+
+static final byte[] ch43data = {
+(byte) 0x20,(byte) 0x20,(byte) 0xf8,(byte) 0x20,(byte) 0x20,
+};
+
+static final BitmapCharRec ch43 = new BitmapCharRec(5,5,0,0,6,ch43data);
+
+/* char: 0x2a '*' */
+
+static final byte[] ch42data = {
+(byte) 0xa0,(byte) 0x40,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch42 = new BitmapCharRec(3,3,0,-4,5,ch42data);
+
+/* char: 0x29 ')' */
+
+static final byte[] ch41data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch41 = new BitmapCharRec(3,9,0,2,4,ch41data);
+
+/* char: 0x28 '(' */
+
+static final byte[] ch40data = {
+(byte) 0x20,(byte) 0x40,(byte) 0x40,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x40,(byte) 0x40,(byte) 0x20,
+};
+
+static final BitmapCharRec ch40 = new BitmapCharRec(3,9,0,2,4,ch40data);
+
+/* char: 0x27 ''' */
+
+static final byte[] ch39data = {
+(byte) 0x40,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch39 = new BitmapCharRec(2,2,0,-5,3,ch39data);
+
+/* char: 0x26 '&' */
+
+static final byte[] ch38data = {
+(byte) 0x76,(byte) 0x8d,(byte) 0x98,(byte) 0x74,(byte) 0x6e,(byte) 0x50,(byte) 0x30,
+};
+
+static final BitmapCharRec ch38 = new BitmapCharRec(8,7,0,0,8,ch38data);
+
+/* char: 0x25 '%' */
+
+static final byte[] ch37data = {
+(byte) 0x44,(byte) 0x2a,(byte) 0x2a,(byte) 0x56,(byte) 0xa8,(byte) 0xa4,(byte) 0x7e,
+};
+
+static final BitmapCharRec ch37 = new BitmapCharRec(7,7,0,0,8,ch37data);
+
+/* char: 0x24 '$' */
+
+static final byte[] ch36data = {
+(byte) 0x20,(byte) 0xe0,(byte) 0x90,(byte) 0x10,(byte) 0x60,(byte) 0x80,(byte) 0x90,(byte) 0x70,(byte) 0x20,
+};
+
+static final BitmapCharRec ch36 = new BitmapCharRec(4,9,0,1,5,ch36data);
+
+/* char: 0x23 '#' */
+
+static final byte[] ch35data = {
+(byte) 0x50,(byte) 0x50,(byte) 0xf8,(byte) 0x50,(byte) 0xf8,(byte) 0x50,(byte) 0x50,
+};
+
+static final BitmapCharRec ch35 = new BitmapCharRec(5,7,0,0,5,ch35data);
+
+/* char: 0x22 '"' */
+
+static final byte[] ch34data = {
+(byte) 0xa0,(byte) 0xa0,
+};
+
+static final BitmapCharRec ch34 = new BitmapCharRec(3,2,0,-5,4,ch34data);
+
+/* char: 0x21 '!' */
+
+static final byte[] ch33data = {
+(byte) 0x80,(byte) 0x0,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80,
+};
+
+static final BitmapCharRec ch33 = new BitmapCharRec(1,7,-1,0,3,ch33data);
+
+/* char: 0x20 ' ' */
+
+static final BitmapCharRec ch32 = new BitmapCharRec(0,0,0,0,2,null);
+
+static final BitmapCharRec[] chars = {
+ch32,
+ch33,
+ch34,
+ch35,
+ch36,
+ch37,
+ch38,
+ch39,
+ch40,
+ch41,
+ch42,
+ch43,
+ch44,
+ch45,
+ch46,
+ch47,
+ch48,
+ch49,
+ch50,
+ch51,
+ch52,
+ch53,
+ch54,
+ch55,
+ch56,
+ch57,
+ch58,
+ch59,
+ch60,
+ch61,
+ch62,
+ch63,
+ch64,
+ch65,
+ch66,
+ch67,
+ch68,
+ch69,
+ch70,
+ch71,
+ch72,
+ch73,
+ch74,
+ch75,
+ch76,
+ch77,
+ch78,
+ch79,
+ch80,
+ch81,
+ch82,
+ch83,
+ch84,
+ch85,
+ch86,
+ch87,
+ch88,
+ch89,
+ch90,
+ch91,
+ch92,
+ch93,
+ch94,
+ch95,
+ch96,
+ch97,
+ch98,
+ch99,
+ch100,
+ch101,
+ch102,
+ch103,
+ch104,
+ch105,
+ch106,
+ch107,
+ch108,
+ch109,
+ch110,
+ch111,
+ch112,
+ch113,
+ch114,
+ch115,
+ch116,
+ch117,
+ch118,
+ch119,
+ch120,
+ch121,
+ch122,
+ch123,
+ch124,
+ch125,
+ch126,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+ch160,
+ch161,
+ch162,
+ch163,
+ch164,
+ch165,
+ch166,
+ch167,
+ch168,
+ch169,
+ch170,
+ch171,
+ch172,
+ch173,
+ch174,
+ch175,
+ch176,
+ch177,
+ch178,
+ch179,
+ch180,
+ch181,
+ch182,
+ch183,
+ch184,
+ch185,
+ch186,
+ch187,
+ch188,
+ch189,
+ch190,
+ch191,
+ch192,
+ch193,
+ch194,
+ch195,
+ch196,
+ch197,
+ch198,
+ch199,
+ch200,
+ch201,
+ch202,
+ch203,
+ch204,
+ch205,
+ch206,
+ch207,
+ch208,
+ch209,
+ch210,
+ch211,
+ch212,
+ch213,
+ch214,
+ch215,
+ch216,
+ch217,
+ch218,
+ch219,
+ch220,
+ch221,
+ch222,
+ch223,
+ch224,
+ch225,
+ch226,
+ch227,
+ch228,
+ch229,
+ch230,
+ch231,
+ch232,
+ch233,
+ch234,
+ch235,
+ch236,
+ch237,
+ch238,
+ch239,
+ch240,
+ch241,
+ch242,
+ch243,
+ch244,
+ch245,
+ch246,
+ch247,
+ch248,
+ch249,
+ch250,
+ch251,
+ch252,
+ch253,
+ch254,
+ch255,
+};
+
+ public static final BitmapFontRec glutBitmapTimesRoman10 = new BitmapFontRec("-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1",
+ 224,
+ 32,
+ chars);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapTimesRoman24.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapTimesRoman24.java
new file mode 100644
index 000000000..073e6e673
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTBitmapTimesRoman24.java
@@ -0,0 +1,2080 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+class GLUTBitmapTimesRoman24 {
+
+/* GENERATED FILE -- DO NOT MODIFY */
+
+/* char: 0xff */
+
+static final byte[] ch255data = {
+(byte) 0xe0,(byte) 0x0,(byte) 0xf0,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x4,(byte) 0x0,(byte) 0xe,(byte) 0x0,(byte) 0xe,(byte) 0x0,
+(byte) 0x1a,(byte) 0x0,(byte) 0x19,(byte) 0x0,(byte) 0x19,(byte) 0x0,(byte) 0x31,(byte) 0x0,(byte) 0x30,(byte) 0x80,(byte) 0x30,(byte) 0x80,(byte) 0x60,(byte) 0x80,(byte) 0x60,(byte) 0xc0,
+(byte) 0xf1,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x33,(byte) 0x0,
+};
+
+static final BitmapCharRec ch255 = new BitmapCharRec(11,21,0,5,11,ch255data);
+
+/* char: 0xfe */
+
+static final byte[] ch254data = {
+(byte) 0xf0,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x6e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,
+(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,
+(byte) 0x6e,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0xe0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch254 = new BitmapCharRec(10,22,-1,5,12,ch254data);
+
+/* char: 0xfd */
+
+static final byte[] ch253data = {
+(byte) 0xe0,(byte) 0x0,(byte) 0xf0,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x4,(byte) 0x0,(byte) 0xe,(byte) 0x0,(byte) 0xe,(byte) 0x0,
+(byte) 0x1a,(byte) 0x0,(byte) 0x19,(byte) 0x0,(byte) 0x19,(byte) 0x0,(byte) 0x31,(byte) 0x0,(byte) 0x30,(byte) 0x80,(byte) 0x30,(byte) 0x80,(byte) 0x60,(byte) 0x80,(byte) 0x60,(byte) 0xc0,
+(byte) 0xf1,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x3,(byte) 0x80,(byte) 0x1,(byte) 0x80,
+};
+
+static final BitmapCharRec ch253 = new BitmapCharRec(11,22,0,5,11,ch253data);
+
+/* char: 0xfc */
+
+static final byte[] ch252data = {
+(byte) 0x1c,(byte) 0xe0,(byte) 0x3e,(byte) 0xc0,(byte) 0x71,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xe1,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x33,(byte) 0x0,
+};
+
+static final BitmapCharRec ch252 = new BitmapCharRec(11,16,-1,0,13,ch252data);
+
+/* char: 0xfb */
+
+static final byte[] ch251data = {
+(byte) 0x1c,(byte) 0xe0,(byte) 0x3e,(byte) 0xc0,(byte) 0x71,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xe1,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x21,(byte) 0x0,(byte) 0x12,(byte) 0x0,(byte) 0x1e,(byte) 0x0,
+(byte) 0xc,(byte) 0x0,
+};
+
+static final BitmapCharRec ch251 = new BitmapCharRec(11,17,-1,0,13,ch251data);
+
+/* char: 0xfa */
+
+static final byte[] ch250data = {
+(byte) 0x1c,(byte) 0xe0,(byte) 0x3e,(byte) 0xc0,(byte) 0x71,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xe1,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x3,(byte) 0x80,
+(byte) 0x1,(byte) 0x80,
+};
+
+static final BitmapCharRec ch250 = new BitmapCharRec(11,17,-1,0,13,ch250data);
+
+/* char: 0xf9 */
+
+static final byte[] ch249data = {
+(byte) 0x1c,(byte) 0xe0,(byte) 0x3e,(byte) 0xc0,(byte) 0x71,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xe1,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x2,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x38,(byte) 0x0,
+(byte) 0x30,(byte) 0x0,
+};
+
+static final BitmapCharRec ch249 = new BitmapCharRec(11,17,-1,0,13,ch249data);
+
+/* char: 0xf8 */
+
+static final byte[] ch248data = {
+(byte) 0xc0,(byte) 0x0,(byte) 0xde,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x71,(byte) 0x80,(byte) 0xd0,(byte) 0xc0,(byte) 0xd8,(byte) 0xc0,(byte) 0xc8,(byte) 0xc0,(byte) 0xcc,(byte) 0xc0,
+(byte) 0xc4,(byte) 0xc0,(byte) 0xc6,(byte) 0xc0,(byte) 0x63,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x1e,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch248 = new BitmapCharRec(10,14,-1,1,12,ch248data);
+
+/* char: 0xf7 */
+
+static final byte[] ch247data = {
+(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xff,(byte) 0xf0,(byte) 0xff,(byte) 0xf0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,
+(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+};
+
+static final BitmapCharRec ch247 = new BitmapCharRec(12,10,-1,-2,14,ch247data);
+
+/* char: 0xf6 */
+
+static final byte[] ch246data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x1e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x33,(byte) 0x0,
+};
+
+static final BitmapCharRec ch246 = new BitmapCharRec(10,16,-1,0,12,ch246data);
+
+/* char: 0xf5 */
+
+static final byte[] ch245data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x1e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x27,(byte) 0x0,(byte) 0x1c,(byte) 0x80,
+};
+
+static final BitmapCharRec ch245 = new BitmapCharRec(10,16,-1,0,12,ch245data);
+
+/* char: 0xf4 */
+
+static final byte[] ch244data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x1e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x21,(byte) 0x0,(byte) 0x12,(byte) 0x0,(byte) 0x1e,(byte) 0x0,
+(byte) 0xc,(byte) 0x0,
+};
+
+static final BitmapCharRec ch244 = new BitmapCharRec(10,17,-1,0,12,ch244data);
+
+/* char: 0xf3 */
+
+static final byte[] ch243data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x1e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x3,(byte) 0x80,
+(byte) 0x1,(byte) 0x80,
+};
+
+static final BitmapCharRec ch243 = new BitmapCharRec(10,17,-1,0,12,ch243data);
+
+/* char: 0xf2 */
+
+static final byte[] ch242data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x1e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x2,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x38,(byte) 0x0,
+(byte) 0x30,(byte) 0x0,
+};
+
+static final BitmapCharRec ch242 = new BitmapCharRec(10,17,-1,0,12,ch242data);
+
+/* char: 0xf1 */
+
+static final byte[] ch241data = {
+(byte) 0xf1,(byte) 0xe0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0x60,(byte) 0xc0,(byte) 0x71,(byte) 0xc0,(byte) 0x6f,(byte) 0x80,(byte) 0xe7,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x27,(byte) 0x0,(byte) 0x1c,(byte) 0x80,
+};
+
+static final BitmapCharRec ch241 = new BitmapCharRec(11,16,-1,0,13,ch241data);
+
+/* char: 0xf0 */
+
+static final byte[] ch240data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x1f,(byte) 0x0,(byte) 0xc6,(byte) 0x0,(byte) 0x3c,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x71,(byte) 0x80,
+(byte) 0xc0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch240 = new BitmapCharRec(10,17,-1,0,12,ch240data);
+
+/* char: 0xef */
+
+static final byte[] ch239data = {
+(byte) 0x78,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x70,(byte) 0x0,(byte) 0x0,(byte) 0xcc,(byte) 0xcc,
+};
+
+static final BitmapCharRec ch239 = new BitmapCharRec(6,16,0,0,6,ch239data);
+
+/* char: 0xee */
+
+static final byte[] ch238data = {
+(byte) 0x78,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x70,(byte) 0x0,(byte) 0x84,(byte) 0x48,(byte) 0x78,
+(byte) 0x30,
+};
+
+static final BitmapCharRec ch238 = new BitmapCharRec(6,17,0,0,6,ch238data);
+
+/* char: 0xed */
+
+static final byte[] ch237data = {
+(byte) 0xf0,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0xe0,(byte) 0x0,(byte) 0x80,(byte) 0x60,(byte) 0x38,
+(byte) 0x18,
+};
+
+static final BitmapCharRec ch237 = new BitmapCharRec(5,17,-1,0,6,ch237data);
+
+/* char: 0xec */
+
+static final byte[] ch236data = {
+(byte) 0x78,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x70,(byte) 0x0,(byte) 0x8,(byte) 0x30,(byte) 0xe0,
+(byte) 0xc0,
+};
+
+static final BitmapCharRec ch236 = new BitmapCharRec(5,17,0,0,6,ch236data);
+
+/* char: 0xeb */
+
+static final byte[] ch235data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x70,(byte) 0x80,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0x41,(byte) 0x80,(byte) 0x63,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x33,(byte) 0x0,
+};
+
+static final BitmapCharRec ch235 = new BitmapCharRec(9,16,-1,0,11,ch235data);
+
+/* char: 0xea */
+
+static final byte[] ch234data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x70,(byte) 0x80,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0x41,(byte) 0x80,(byte) 0x63,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x21,(byte) 0x0,(byte) 0x12,(byte) 0x0,(byte) 0x1e,(byte) 0x0,
+(byte) 0xc,(byte) 0x0,
+};
+
+static final BitmapCharRec ch234 = new BitmapCharRec(9,17,-1,0,11,ch234data);
+
+/* char: 0xe9 */
+
+static final byte[] ch233data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x70,(byte) 0x80,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0x41,(byte) 0x80,(byte) 0x63,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x10,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x7,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,
+};
+
+static final BitmapCharRec ch233 = new BitmapCharRec(9,17,-1,0,11,ch233data);
+
+/* char: 0xe8 */
+
+static final byte[] ch232data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x70,(byte) 0x80,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0x41,(byte) 0x80,(byte) 0x63,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x4,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x70,(byte) 0x0,
+(byte) 0x60,(byte) 0x0,
+};
+
+static final BitmapCharRec ch232 = new BitmapCharRec(9,17,-1,0,11,ch232data);
+
+/* char: 0xe7 */
+
+static final byte[] ch231data = {
+(byte) 0x3c,(byte) 0x0,(byte) 0x66,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,
+(byte) 0x70,(byte) 0x80,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x41,(byte) 0x80,
+(byte) 0x63,(byte) 0x80,(byte) 0x1f,(byte) 0x0,
+};
+
+static final BitmapCharRec ch231 = new BitmapCharRec(9,18,-1,6,11,ch231data);
+
+/* char: 0xe6 */
+
+static final byte[] ch230data = {
+(byte) 0x70,(byte) 0xf0,(byte) 0xfb,(byte) 0xf8,(byte) 0xc7,(byte) 0x84,(byte) 0xc3,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x3b,(byte) 0x0,(byte) 0xf,(byte) 0xfc,
+(byte) 0x3,(byte) 0xc,(byte) 0x63,(byte) 0xc,(byte) 0x67,(byte) 0x98,(byte) 0x3c,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch230 = new BitmapCharRec(14,12,-1,0,16,ch230data);
+
+/* char: 0xe5 */
+
+static final byte[] ch229data = {
+(byte) 0x71,(byte) 0x80,(byte) 0xfb,(byte) 0x0,(byte) 0xc7,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x3b,(byte) 0x0,(byte) 0xf,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x67,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x1c,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,
+(byte) 0x1c,(byte) 0x0,
+};
+
+static final BitmapCharRec ch229 = new BitmapCharRec(9,17,-1,0,11,ch229data);
+
+/* char: 0xe4 */
+
+static final byte[] ch228data = {
+(byte) 0x71,(byte) 0x80,(byte) 0xfb,(byte) 0x0,(byte) 0xc7,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x3b,(byte) 0x0,(byte) 0xf,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x67,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x66,(byte) 0x0,(byte) 0x66,(byte) 0x0,
+};
+
+static final BitmapCharRec ch228 = new BitmapCharRec(9,16,-1,0,11,ch228data);
+
+/* char: 0xe3 */
+
+static final byte[] ch227data = {
+(byte) 0x71,(byte) 0x80,(byte) 0xfb,(byte) 0x0,(byte) 0xc7,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x3b,(byte) 0x0,(byte) 0xf,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x67,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x5c,(byte) 0x0,(byte) 0x3a,(byte) 0x0,
+};
+
+static final BitmapCharRec ch227 = new BitmapCharRec(9,16,-1,0,11,ch227data);
+
+/* char: 0xe2 */
+
+static final byte[] ch226data = {
+(byte) 0x71,(byte) 0x80,(byte) 0xfb,(byte) 0x0,(byte) 0xc7,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x3b,(byte) 0x0,(byte) 0xf,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x67,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x42,(byte) 0x0,(byte) 0x24,(byte) 0x0,(byte) 0x3c,(byte) 0x0,
+(byte) 0x18,(byte) 0x0,
+};
+
+static final BitmapCharRec ch226 = new BitmapCharRec(9,17,-1,0,11,ch226data);
+
+/* char: 0xe1 */
+
+static final byte[] ch225data = {
+(byte) 0x71,(byte) 0x80,(byte) 0xfb,(byte) 0x0,(byte) 0xc7,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x3b,(byte) 0x0,(byte) 0xf,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x67,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x10,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x7,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,
+};
+
+static final BitmapCharRec ch225 = new BitmapCharRec(9,17,-1,0,11,ch225data);
+
+/* char: 0xe0 */
+
+static final byte[] ch224data = {
+(byte) 0x71,(byte) 0x80,(byte) 0xfb,(byte) 0x0,(byte) 0xc7,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x3b,(byte) 0x0,(byte) 0xf,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x67,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x4,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x70,(byte) 0x0,
+(byte) 0x60,(byte) 0x0,
+};
+
+static final BitmapCharRec ch224 = new BitmapCharRec(9,17,-1,0,11,ch224data);
+
+/* char: 0xdf */
+
+static final byte[] ch223data = {
+(byte) 0xe7,(byte) 0x0,(byte) 0x6c,(byte) 0x80,(byte) 0x6c,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x61,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x63,(byte) 0x80,
+(byte) 0x67,(byte) 0x0,(byte) 0x6c,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x33,(byte) 0x0,
+(byte) 0x1e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch223 = new BitmapCharRec(10,17,-1,0,12,ch223data);
+
+/* char: 0xde */
+
+static final byte[] ch222data = {
+(byte) 0xfc,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0x70,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x18,
+(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x70,(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,
+(byte) 0xfc,(byte) 0x0,
+};
+
+static final BitmapCharRec ch222 = new BitmapCharRec(13,17,-1,0,15,ch222data);
+
+/* char: 0xdd */
+
+static final byte[] ch221data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x3,(byte) 0xc0,
+(byte) 0x3,(byte) 0x40,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0x20,(byte) 0xc,(byte) 0x30,(byte) 0x1c,(byte) 0x10,(byte) 0x18,(byte) 0x18,(byte) 0x38,(byte) 0x8,(byte) 0x30,(byte) 0xc,
+(byte) 0xfc,(byte) 0x3f,(byte) 0x0,(byte) 0x0,(byte) 0x1,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0x30,
+};
+
+static final BitmapCharRec ch221 = new BitmapCharRec(16,22,0,0,16,ch221data);
+
+/* char: 0xdc */
+
+static final byte[] ch220data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x30,(byte) 0x18,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0xfc,(byte) 0x1f,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x6,(byte) 0x30,(byte) 0x6,(byte) 0x30,
+};
+
+static final BitmapCharRec ch220 = new BitmapCharRec(16,21,-1,0,18,ch220data);
+
+/* char: 0xdb */
+
+static final byte[] ch219data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x30,(byte) 0x18,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0xfc,(byte) 0x1f,(byte) 0x0,(byte) 0x0,(byte) 0x8,(byte) 0x10,(byte) 0x6,(byte) 0x60,(byte) 0x3,(byte) 0xc0,(byte) 0x1,(byte) 0x80,
+};
+
+static final BitmapCharRec ch219 = new BitmapCharRec(16,22,-1,0,18,ch219data);
+
+/* char: 0xda */
+
+static final byte[] ch218data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x30,(byte) 0x18,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0xfc,(byte) 0x1f,(byte) 0x0,(byte) 0x0,(byte) 0x1,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0x30,
+};
+
+static final BitmapCharRec ch218 = new BitmapCharRec(16,22,-1,0,18,ch218data);
+
+/* char: 0xd9 */
+
+static final byte[] ch217data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x30,(byte) 0x18,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0xfc,(byte) 0x1f,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x40,(byte) 0x1,(byte) 0x80,(byte) 0x7,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+};
+
+static final BitmapCharRec ch217 = new BitmapCharRec(16,22,-1,0,18,ch217data);
+
+/* char: 0xd8 */
+
+static final byte[] ch216data = {
+(byte) 0x20,(byte) 0x0,(byte) 0x27,(byte) 0xe0,(byte) 0x1c,(byte) 0x38,(byte) 0x38,(byte) 0x1c,(byte) 0x68,(byte) 0x6,(byte) 0x64,(byte) 0x6,(byte) 0xc2,(byte) 0x3,(byte) 0xc2,(byte) 0x3,
+(byte) 0xc1,(byte) 0x3,(byte) 0xc1,(byte) 0x3,(byte) 0xc0,(byte) 0x83,(byte) 0xc0,(byte) 0x83,(byte) 0xc0,(byte) 0x43,(byte) 0x60,(byte) 0x46,(byte) 0x60,(byte) 0x26,(byte) 0x38,(byte) 0x1c,
+(byte) 0x1c,(byte) 0x38,(byte) 0x7,(byte) 0xe4,(byte) 0x0,(byte) 0x4,
+};
+
+static final BitmapCharRec ch216 = new BitmapCharRec(16,19,-1,1,18,ch216data);
+
+/* char: 0xd7 */
+
+static final byte[] ch215data = {
+(byte) 0x80,(byte) 0x40,(byte) 0xc0,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x33,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x33,(byte) 0x0,
+(byte) 0x61,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0x80,(byte) 0x40,
+};
+
+static final BitmapCharRec ch215 = new BitmapCharRec(10,11,-2,-1,14,ch215data);
+
+/* char: 0xd6 */
+
+static final byte[] ch214data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x38,(byte) 0x38,(byte) 0x1c,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,
+(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0x38,(byte) 0x1c,(byte) 0x1c,(byte) 0x38,
+(byte) 0x7,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0x60,
+};
+
+static final BitmapCharRec ch214 = new BitmapCharRec(16,21,-1,0,18,ch214data);
+
+/* char: 0xd5 */
+
+static final byte[] ch213data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x38,(byte) 0x38,(byte) 0x1c,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,
+(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0x38,(byte) 0x1c,(byte) 0x1c,(byte) 0x38,
+(byte) 0x7,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x4,(byte) 0xe0,(byte) 0x3,(byte) 0x90,
+};
+
+static final BitmapCharRec ch213 = new BitmapCharRec(16,21,-1,0,18,ch213data);
+
+/* char: 0xd4 */
+
+static final byte[] ch212data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x38,(byte) 0x38,(byte) 0x1c,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,
+(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0x38,(byte) 0x1c,(byte) 0x1c,(byte) 0x38,
+(byte) 0x7,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x8,(byte) 0x10,(byte) 0x6,(byte) 0x60,(byte) 0x3,(byte) 0xc0,(byte) 0x1,(byte) 0x80,
+};
+
+static final BitmapCharRec ch212 = new BitmapCharRec(16,22,-1,0,18,ch212data);
+
+/* char: 0xd3 */
+
+static final byte[] ch211data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x38,(byte) 0x38,(byte) 0x1c,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,
+(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0x38,(byte) 0x1c,(byte) 0x1c,(byte) 0x38,
+(byte) 0x7,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x1,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0x30,
+};
+
+static final BitmapCharRec ch211 = new BitmapCharRec(16,22,-1,0,18,ch211data);
+
+/* char: 0xd2 */
+
+static final byte[] ch210data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x38,(byte) 0x38,(byte) 0x1c,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,
+(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0x38,(byte) 0x1c,(byte) 0x1c,(byte) 0x38,
+(byte) 0x7,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x40,(byte) 0x1,(byte) 0x80,(byte) 0x7,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+};
+
+static final BitmapCharRec ch210 = new BitmapCharRec(16,22,-1,0,18,ch210data);
+
+/* char: 0xd1 */
+
+static final byte[] ch209data = {
+(byte) 0xf8,(byte) 0xc,(byte) 0x20,(byte) 0x1c,(byte) 0x20,(byte) 0x1c,(byte) 0x20,(byte) 0x34,(byte) 0x20,(byte) 0x64,(byte) 0x20,(byte) 0x64,(byte) 0x20,(byte) 0xc4,(byte) 0x21,(byte) 0x84,
+(byte) 0x21,(byte) 0x84,(byte) 0x23,(byte) 0x4,(byte) 0x26,(byte) 0x4,(byte) 0x26,(byte) 0x4,(byte) 0x2c,(byte) 0x4,(byte) 0x38,(byte) 0x4,(byte) 0x38,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0xf0,(byte) 0x1f,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x4,(byte) 0xe0,(byte) 0x3,(byte) 0x90,
+};
+
+static final BitmapCharRec ch209 = new BitmapCharRec(16,21,-1,0,18,ch209data);
+
+/* char: 0xd0 */
+
+static final byte[] ch208data = {
+(byte) 0x7f,(byte) 0xe0,(byte) 0x18,(byte) 0x38,(byte) 0x18,(byte) 0x1c,(byte) 0x18,(byte) 0x6,(byte) 0x18,(byte) 0x6,(byte) 0x18,(byte) 0x3,(byte) 0x18,(byte) 0x3,(byte) 0x18,(byte) 0x3,
+(byte) 0xff,(byte) 0x3,(byte) 0x18,(byte) 0x3,(byte) 0x18,(byte) 0x3,(byte) 0x18,(byte) 0x3,(byte) 0x18,(byte) 0x6,(byte) 0x18,(byte) 0x6,(byte) 0x18,(byte) 0x1c,(byte) 0x18,(byte) 0x38,
+(byte) 0x7f,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch208 = new BitmapCharRec(16,17,0,0,17,ch208data);
+
+/* char: 0xcf */
+
+static final byte[] ch207data = {
+(byte) 0xfc,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,
+(byte) 0xfc,(byte) 0x0,(byte) 0x0,(byte) 0xcc,(byte) 0xcc,
+};
+
+static final BitmapCharRec ch207 = new BitmapCharRec(6,21,-1,0,8,ch207data);
+
+/* char: 0xce */
+
+static final byte[] ch206data = {
+(byte) 0x7e,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,
+(byte) 0x7e,(byte) 0x0,(byte) 0x81,(byte) 0x66,(byte) 0x3c,(byte) 0x18,
+};
+
+static final BitmapCharRec ch206 = new BitmapCharRec(8,22,-1,0,8,ch206data);
+
+/* char: 0xcd */
+
+static final byte[] ch205data = {
+(byte) 0xfc,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,
+(byte) 0xfc,(byte) 0x0,(byte) 0x40,(byte) 0x30,(byte) 0x1c,(byte) 0xc,
+};
+
+static final BitmapCharRec ch205 = new BitmapCharRec(6,22,-1,0,8,ch205data);
+
+/* char: 0xcc */
+
+static final byte[] ch204data = {
+(byte) 0xfc,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,
+(byte) 0xfc,(byte) 0x0,(byte) 0x8,(byte) 0x30,(byte) 0xe0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch204 = new BitmapCharRec(6,22,-1,0,8,ch204data);
+
+/* char: 0xcb */
+
+static final byte[] ch203data = {
+(byte) 0xff,(byte) 0xf8,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x40,
+(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x30,
+(byte) 0xff,(byte) 0xf0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,
+};
+
+static final BitmapCharRec ch203 = new BitmapCharRec(13,21,-1,0,15,ch203data);
+
+/* char: 0xca */
+
+static final byte[] ch202data = {
+(byte) 0xff,(byte) 0xf8,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x40,
+(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x30,
+(byte) 0xff,(byte) 0xf0,(byte) 0x0,(byte) 0x0,(byte) 0x10,(byte) 0x20,(byte) 0xc,(byte) 0xc0,(byte) 0x7,(byte) 0x80,(byte) 0x3,(byte) 0x0,
+};
+
+static final BitmapCharRec ch202 = new BitmapCharRec(13,22,-1,0,15,ch202data);
+
+/* char: 0xc9 */
+
+static final byte[] ch201data = {
+(byte) 0xff,(byte) 0xf8,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x40,
+(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x30,
+(byte) 0xff,(byte) 0xf0,(byte) 0x0,(byte) 0x0,(byte) 0x4,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch201 = new BitmapCharRec(13,22,-1,0,15,ch201data);
+
+/* char: 0xc8 */
+
+static final byte[] ch200data = {
+(byte) 0xff,(byte) 0xf8,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x40,
+(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x30,
+(byte) 0xff,(byte) 0xf0,(byte) 0x0,(byte) 0x0,(byte) 0x1,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x1c,(byte) 0x0,(byte) 0x18,(byte) 0x0,
+};
+
+static final BitmapCharRec ch200 = new BitmapCharRec(13,22,-1,0,15,ch200data);
+
+/* char: 0xc7 */
+
+static final byte[] ch199data = {
+(byte) 0x7,(byte) 0x80,(byte) 0xc,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0x0,(byte) 0x1,(byte) 0x0,(byte) 0x7,(byte) 0xe0,(byte) 0x1e,(byte) 0x38,
+(byte) 0x38,(byte) 0x8,(byte) 0x60,(byte) 0x4,(byte) 0x60,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x60,(byte) 0x4,(byte) 0x60,(byte) 0x4,(byte) 0x38,(byte) 0xc,(byte) 0x1c,(byte) 0x3c,(byte) 0x7,(byte) 0xe4,
+};
+
+static final BitmapCharRec ch199 = new BitmapCharRec(14,23,-1,6,16,ch199data);
+
+/* char: 0xc6 */
+
+static final byte[] ch198data = {
+(byte) 0xf9,(byte) 0xff,(byte) 0xf0,(byte) 0x30,(byte) 0x60,(byte) 0x30,(byte) 0x10,(byte) 0x60,(byte) 0x10,(byte) 0x10,(byte) 0x60,(byte) 0x10,(byte) 0x18,(byte) 0x60,(byte) 0x0,(byte) 0x8,
+(byte) 0x60,(byte) 0x0,(byte) 0xf,(byte) 0xe0,(byte) 0x80,(byte) 0xc,(byte) 0x60,(byte) 0x80,(byte) 0x4,(byte) 0x7f,(byte) 0x80,(byte) 0x4,(byte) 0x60,(byte) 0x80,(byte) 0x6,(byte) 0x60,
+(byte) 0x80,(byte) 0x2,(byte) 0x60,(byte) 0x0,(byte) 0x2,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0x60,(byte) 0x20,(byte) 0x1,(byte) 0x60,(byte) 0x20,(byte) 0x1,(byte) 0xe0,(byte) 0x60,
+(byte) 0x3,(byte) 0xff,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch198 = new BitmapCharRec(20,17,0,0,21,ch198data);
+
+/* char: 0xc5 */
+
+static final byte[] ch197data = {
+(byte) 0xfc,(byte) 0x1f,(byte) 0x80,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0xc,(byte) 0x0,(byte) 0x8,
+(byte) 0xc,(byte) 0x0,(byte) 0xf,(byte) 0xf8,(byte) 0x0,(byte) 0xc,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x30,(byte) 0x0,(byte) 0x6,(byte) 0x30,
+(byte) 0x0,(byte) 0x2,(byte) 0x30,(byte) 0x0,(byte) 0x2,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,
+(byte) 0x0,(byte) 0x80,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0x2,(byte) 0x20,(byte) 0x0,(byte) 0x2,(byte) 0x20,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch197 = new BitmapCharRec(17,21,0,0,17,ch197data);
+
+/* char: 0xc4 */
+
+static final byte[] ch196data = {
+(byte) 0xfc,(byte) 0x1f,(byte) 0x80,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0xc,(byte) 0x0,(byte) 0x8,
+(byte) 0xc,(byte) 0x0,(byte) 0xf,(byte) 0xf8,(byte) 0x0,(byte) 0xc,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x30,(byte) 0x0,(byte) 0x6,(byte) 0x30,
+(byte) 0x0,(byte) 0x2,(byte) 0x30,(byte) 0x0,(byte) 0x2,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,
+(byte) 0x0,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x6,(byte) 0x30,(byte) 0x0,(byte) 0x6,(byte) 0x30,(byte) 0x0,
+};
+
+static final BitmapCharRec ch196 = new BitmapCharRec(17,21,0,0,17,ch196data);
+
+/* char: 0xc3 */
+
+static final byte[] ch195data = {
+(byte) 0xfc,(byte) 0x1f,(byte) 0x80,(byte) 0x30,(byte) 0x7,(byte) 0x0,(byte) 0x10,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0xc,(byte) 0x0,(byte) 0x8,
+(byte) 0xc,(byte) 0x0,(byte) 0xf,(byte) 0xf8,(byte) 0x0,(byte) 0xc,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x30,(byte) 0x0,(byte) 0x6,(byte) 0x30,
+(byte) 0x0,(byte) 0x2,(byte) 0x30,(byte) 0x0,(byte) 0x2,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,
+(byte) 0x0,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x4,(byte) 0xe0,(byte) 0x0,(byte) 0x3,(byte) 0x90,(byte) 0x0,
+};
+
+static final BitmapCharRec ch195 = new BitmapCharRec(17,21,0,0,17,ch195data);
+
+/* char: 0xc2 */
+
+static final byte[] ch194data = {
+(byte) 0xfc,(byte) 0x1f,(byte) 0x80,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0xc,(byte) 0x0,(byte) 0x8,
+(byte) 0xc,(byte) 0x0,(byte) 0xf,(byte) 0xf8,(byte) 0x0,(byte) 0xc,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x30,(byte) 0x0,(byte) 0x6,(byte) 0x30,
+(byte) 0x0,(byte) 0x2,(byte) 0x30,(byte) 0x0,(byte) 0x2,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,
+(byte) 0x0,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x8,(byte) 0x10,(byte) 0x0,(byte) 0x6,(byte) 0x60,(byte) 0x0,(byte) 0x3,(byte) 0xc0,(byte) 0x0,(byte) 0x1,
+(byte) 0x80,(byte) 0x0,
+};
+
+static final BitmapCharRec ch194 = new BitmapCharRec(17,22,0,0,17,ch194data);
+
+/* char: 0xc1 */
+
+static final byte[] ch193data = {
+(byte) 0xfc,(byte) 0x1f,(byte) 0x80,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0xc,(byte) 0x0,(byte) 0x8,
+(byte) 0xc,(byte) 0x0,(byte) 0xf,(byte) 0xf8,(byte) 0x0,(byte) 0xc,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x30,(byte) 0x0,(byte) 0x6,(byte) 0x30,
+(byte) 0x0,(byte) 0x2,(byte) 0x30,(byte) 0x0,(byte) 0x2,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,
+(byte) 0x0,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x1,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0x0,
+(byte) 0x30,(byte) 0x0,
+};
+
+static final BitmapCharRec ch193 = new BitmapCharRec(17,22,0,0,17,ch193data);
+
+/* char: 0xc0 */
+
+static final byte[] ch192data = {
+(byte) 0xfc,(byte) 0x1f,(byte) 0x80,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0xc,(byte) 0x0,(byte) 0x8,
+(byte) 0xc,(byte) 0x0,(byte) 0xf,(byte) 0xf8,(byte) 0x0,(byte) 0xc,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x30,(byte) 0x0,(byte) 0x6,(byte) 0x30,
+(byte) 0x0,(byte) 0x2,(byte) 0x30,(byte) 0x0,(byte) 0x2,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,
+(byte) 0x0,(byte) 0x80,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x20,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x3,(byte) 0x80,(byte) 0x0,(byte) 0x3,
+(byte) 0x0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch192 = new BitmapCharRec(17,22,0,0,17,ch192data);
+
+/* char: 0xbf */
+
+static final byte[] ch191data = {
+(byte) 0x3e,(byte) 0x63,(byte) 0xc1,(byte) 0xc3,(byte) 0xc3,(byte) 0xe0,(byte) 0x70,(byte) 0x30,(byte) 0x38,(byte) 0x18,(byte) 0x18,(byte) 0x8,(byte) 0x8,(byte) 0x0,(byte) 0x0,(byte) 0xc,
+(byte) 0xc,
+};
+
+static final BitmapCharRec ch191 = new BitmapCharRec(8,17,-1,5,11,ch191data);
+
+/* char: 0xbe */
+
+static final byte[] ch190data = {
+(byte) 0x18,(byte) 0x2,(byte) 0x0,(byte) 0x8,(byte) 0x2,(byte) 0x0,(byte) 0xc,(byte) 0x7f,(byte) 0x80,(byte) 0x4,(byte) 0x22,(byte) 0x0,(byte) 0x6,(byte) 0x32,(byte) 0x0,(byte) 0x3,
+(byte) 0x12,(byte) 0x0,(byte) 0x1,(byte) 0xa,(byte) 0x0,(byte) 0x71,(byte) 0x8e,(byte) 0x0,(byte) 0x88,(byte) 0x86,(byte) 0x0,(byte) 0x8c,(byte) 0xc2,(byte) 0x0,(byte) 0xc,(byte) 0x60,
+(byte) 0x0,(byte) 0x8,(byte) 0x20,(byte) 0x0,(byte) 0x30,(byte) 0x30,(byte) 0x0,(byte) 0x8,(byte) 0x10,(byte) 0x0,(byte) 0x8c,(byte) 0x18,(byte) 0x0,(byte) 0x4c,(byte) 0xc,(byte) 0x0,
+(byte) 0x38,(byte) 0x4,(byte) 0x0,
+};
+
+static final BitmapCharRec ch190 = new BitmapCharRec(17,17,0,0,18,ch190data);
+
+/* char: 0xbd */
+
+static final byte[] ch189data = {
+(byte) 0x30,(byte) 0x7e,(byte) 0x10,(byte) 0x22,(byte) 0x18,(byte) 0x10,(byte) 0x8,(byte) 0x18,(byte) 0xc,(byte) 0x8,(byte) 0x6,(byte) 0x4,(byte) 0x2,(byte) 0x6,(byte) 0xfb,(byte) 0x46,
+(byte) 0x21,(byte) 0x26,(byte) 0x21,(byte) 0x9c,(byte) 0x20,(byte) 0xc0,(byte) 0x20,(byte) 0x40,(byte) 0x20,(byte) 0x60,(byte) 0x20,(byte) 0x20,(byte) 0xa0,(byte) 0x30,(byte) 0x60,(byte) 0x18,
+(byte) 0x20,(byte) 0x8,
+};
+
+static final BitmapCharRec ch189 = new BitmapCharRec(15,17,-1,0,18,ch189data);
+
+/* char: 0xbc */
+
+static final byte[] ch188data = {
+(byte) 0x30,(byte) 0x4,(byte) 0x10,(byte) 0x4,(byte) 0x18,(byte) 0xff,(byte) 0x8,(byte) 0x44,(byte) 0xc,(byte) 0x64,(byte) 0x6,(byte) 0x24,(byte) 0x2,(byte) 0x14,(byte) 0xfb,(byte) 0x1c,
+(byte) 0x21,(byte) 0xc,(byte) 0x21,(byte) 0x84,(byte) 0x20,(byte) 0xc0,(byte) 0x20,(byte) 0x40,(byte) 0x20,(byte) 0x60,(byte) 0x20,(byte) 0x20,(byte) 0xa0,(byte) 0x30,(byte) 0x60,(byte) 0x18,
+(byte) 0x20,(byte) 0x8,
+};
+
+static final BitmapCharRec ch188 = new BitmapCharRec(16,17,-1,0,18,ch188data);
+
+/* char: 0xbb */
+
+static final byte[] ch187data = {
+(byte) 0x88,(byte) 0x0,(byte) 0xcc,(byte) 0x0,(byte) 0x66,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x19,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0x33,(byte) 0x0,(byte) 0x66,(byte) 0x0,
+(byte) 0xcc,(byte) 0x0,(byte) 0x88,(byte) 0x0,
+};
+
+static final BitmapCharRec ch187 = new BitmapCharRec(9,10,-2,-1,12,ch187data);
+
+/* char: 0xba */
+
+static final byte[] ch186data = {
+(byte) 0xfc,(byte) 0x0,(byte) 0x78,(byte) 0xcc,(byte) 0xcc,(byte) 0xcc,(byte) 0xcc,(byte) 0xcc,(byte) 0x78,
+};
+
+static final BitmapCharRec ch186 = new BitmapCharRec(6,9,-1,-8,8,ch186data);
+
+/* char: 0xb9 */
+
+static final byte[] ch185data = {
+(byte) 0xf8,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0x20,(byte) 0xa0,(byte) 0x60,(byte) 0x20,
+};
+
+static final BitmapCharRec ch185 = new BitmapCharRec(5,10,-1,-7,7,ch185data);
+
+/* char: 0xb8 */
+
+static final byte[] ch184data = {
+(byte) 0x78,(byte) 0xcc,(byte) 0xc,(byte) 0x3c,(byte) 0x30,(byte) 0x10,
+};
+
+static final BitmapCharRec ch184 = new BitmapCharRec(6,6,-1,6,8,ch184data);
+
+/* char: 0xb7 */
+
+static final byte[] ch183data = {
+(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch183 = new BitmapCharRec(2,2,-2,-6,6,ch183data);
+
+/* char: 0xb6 */
+
+static final byte[] ch182data = {
+(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,
+(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0x9,(byte) 0x0,(byte) 0x19,(byte) 0x0,(byte) 0x39,(byte) 0x0,(byte) 0x79,(byte) 0x0,(byte) 0x79,(byte) 0x0,(byte) 0xf9,(byte) 0x0,
+(byte) 0xf9,(byte) 0x0,(byte) 0xf9,(byte) 0x0,(byte) 0x79,(byte) 0x0,(byte) 0x79,(byte) 0x0,(byte) 0x39,(byte) 0x0,(byte) 0x1f,(byte) 0x80,
+};
+
+static final BitmapCharRec ch182 = new BitmapCharRec(9,22,-1,5,11,ch182data);
+
+/* char: 0xb5 */
+
+static final byte[] ch181data = {
+(byte) 0x40,(byte) 0x0,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x40,(byte) 0x0,(byte) 0x40,(byte) 0x0,(byte) 0x5c,(byte) 0xe0,(byte) 0x7e,(byte) 0xc0,(byte) 0x71,(byte) 0xc0,
+(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0xe1,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch181 = new BitmapCharRec(11,17,-1,5,13,ch181data);
+
+/* char: 0xb4 */
+
+static final byte[] ch180data = {
+(byte) 0x80,(byte) 0x60,(byte) 0x38,(byte) 0x18,
+};
+
+static final BitmapCharRec ch180 = new BitmapCharRec(5,4,-2,-13,8,ch180data);
+
+/* char: 0xb3 */
+
+static final byte[] ch179data = {
+(byte) 0x70,(byte) 0x88,(byte) 0x8c,(byte) 0xc,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x8c,(byte) 0x4c,(byte) 0x38,
+};
+
+static final BitmapCharRec ch179 = new BitmapCharRec(6,10,0,-7,7,ch179data);
+
+/* char: 0xb2 */
+
+static final byte[] ch178data = {
+(byte) 0xfc,(byte) 0x44,(byte) 0x20,(byte) 0x30,(byte) 0x10,(byte) 0x8,(byte) 0xc,(byte) 0x8c,(byte) 0x4c,(byte) 0x38,
+};
+
+static final BitmapCharRec ch178 = new BitmapCharRec(6,10,0,-7,7,ch178data);
+
+/* char: 0xb1 */
+
+static final byte[] ch177data = {
+(byte) 0xff,(byte) 0xf0,(byte) 0xff,(byte) 0xf0,(byte) 0x0,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+(byte) 0xff,(byte) 0xf0,(byte) 0xff,(byte) 0xf0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+};
+
+static final BitmapCharRec ch177 = new BitmapCharRec(12,15,-1,0,14,ch177data);
+
+/* char: 0xb0 */
+
+static final byte[] ch176data = {
+(byte) 0x38,(byte) 0x44,(byte) 0x82,(byte) 0x82,(byte) 0x82,(byte) 0x44,(byte) 0x38,
+};
+
+static final BitmapCharRec ch176 = new BitmapCharRec(7,7,-1,-10,9,ch176data);
+
+/* char: 0xaf */
+
+static final byte[] ch175data = {
+(byte) 0xfc,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch175 = new BitmapCharRec(6,2,-1,-14,8,ch175data);
+
+/* char: 0xae */
+
+static final byte[] ch174data = {
+(byte) 0x7,(byte) 0xf0,(byte) 0x0,(byte) 0x1c,(byte) 0x1c,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x60,(byte) 0x3,(byte) 0x0,(byte) 0x47,(byte) 0x19,(byte) 0x0,(byte) 0xc2,
+(byte) 0x31,(byte) 0x80,(byte) 0x82,(byte) 0x20,(byte) 0x80,(byte) 0x82,(byte) 0x40,(byte) 0x80,(byte) 0x83,(byte) 0xe0,(byte) 0x80,(byte) 0x82,(byte) 0x30,(byte) 0x80,(byte) 0x82,(byte) 0x10,
+(byte) 0x80,(byte) 0xc2,(byte) 0x11,(byte) 0x80,(byte) 0x42,(byte) 0x31,(byte) 0x0,(byte) 0x67,(byte) 0xe3,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x1c,(byte) 0x1c,(byte) 0x0,
+(byte) 0x7,(byte) 0xf0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch174 = new BitmapCharRec(17,17,-1,0,19,ch174data);
+
+/* char: 0xad */
+
+static final byte[] ch173data = {
+(byte) 0xfe,(byte) 0xfe,
+};
+
+static final BitmapCharRec ch173 = new BitmapCharRec(7,2,-1,-5,9,ch173data);
+
+/* char: 0xac */
+
+static final byte[] ch172data = {
+(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0xff,(byte) 0xf0,(byte) 0xff,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch172 = new BitmapCharRec(12,7,-1,-3,14,ch172data);
+
+/* char: 0xab */
+
+static final byte[] ch171data = {
+(byte) 0x8,(byte) 0x80,(byte) 0x19,(byte) 0x80,(byte) 0x33,(byte) 0x0,(byte) 0x66,(byte) 0x0,(byte) 0xcc,(byte) 0x0,(byte) 0xcc,(byte) 0x0,(byte) 0x66,(byte) 0x0,(byte) 0x33,(byte) 0x0,
+(byte) 0x19,(byte) 0x80,(byte) 0x8,(byte) 0x80,
+};
+
+static final BitmapCharRec ch171 = new BitmapCharRec(9,10,-2,-1,13,ch171data);
+
+/* char: 0xaa */
+
+static final byte[] ch170data = {
+(byte) 0x7e,(byte) 0x0,(byte) 0x76,(byte) 0xcc,(byte) 0xcc,(byte) 0x7c,(byte) 0xc,(byte) 0xcc,(byte) 0x78,
+};
+
+static final BitmapCharRec ch170 = new BitmapCharRec(7,9,0,-8,8,ch170data);
+
+/* char: 0xa9 */
+
+static final byte[] ch169data = {
+(byte) 0x7,(byte) 0xf0,(byte) 0x0,(byte) 0x1c,(byte) 0x1c,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x61,(byte) 0xc3,(byte) 0x0,(byte) 0x47,(byte) 0x71,(byte) 0x0,(byte) 0xc4,
+(byte) 0x19,(byte) 0x80,(byte) 0x8c,(byte) 0x0,(byte) 0x80,(byte) 0x88,(byte) 0x0,(byte) 0x80,(byte) 0x88,(byte) 0x0,(byte) 0x80,(byte) 0x88,(byte) 0x0,(byte) 0x80,(byte) 0x8c,(byte) 0x0,
+(byte) 0x80,(byte) 0xc4,(byte) 0x19,(byte) 0x80,(byte) 0x47,(byte) 0x31,(byte) 0x0,(byte) 0x61,(byte) 0xe3,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x1c,(byte) 0x1c,(byte) 0x0,
+(byte) 0x7,(byte) 0xf0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch169 = new BitmapCharRec(17,17,-1,0,19,ch169data);
+
+/* char: 0xa8 */
+
+static final byte[] ch168data = {
+(byte) 0xcc,(byte) 0xcc,
+};
+
+static final BitmapCharRec ch168 = new BitmapCharRec(6,2,-1,-14,8,ch168data);
+
+/* char: 0xa7 */
+
+static final byte[] ch167data = {
+(byte) 0x38,(byte) 0x64,(byte) 0x62,(byte) 0x6,(byte) 0xe,(byte) 0x1c,(byte) 0x38,(byte) 0x74,(byte) 0xe2,(byte) 0xc3,(byte) 0x83,(byte) 0x87,(byte) 0x4e,(byte) 0x3c,(byte) 0x38,(byte) 0x70,
+(byte) 0x60,(byte) 0x46,(byte) 0x26,(byte) 0x1c,
+};
+
+static final BitmapCharRec ch167 = new BitmapCharRec(8,20,-2,2,12,ch167data);
+
+/* char: 0xa6 */
+
+static final byte[] ch166data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,
+};
+
+static final BitmapCharRec ch166 = new BitmapCharRec(2,17,-2,0,6,ch166data);
+
+/* char: 0xa5 */
+
+static final byte[] ch165data = {
+(byte) 0xf,(byte) 0xc0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x1f,(byte) 0xe0,(byte) 0x3,(byte) 0x0,(byte) 0x1f,(byte) 0xe0,
+(byte) 0x3,(byte) 0x0,(byte) 0x7,(byte) 0x80,(byte) 0xc,(byte) 0x80,(byte) 0xc,(byte) 0xc0,(byte) 0x18,(byte) 0x40,(byte) 0x18,(byte) 0x60,(byte) 0x30,(byte) 0x20,(byte) 0x70,(byte) 0x30,
+(byte) 0xf8,(byte) 0x7c,
+};
+
+static final BitmapCharRec ch165 = new BitmapCharRec(14,17,0,0,14,ch165data);
+
+/* char: 0xa4 */
+
+static final byte[] ch164data = {
+(byte) 0xc0,(byte) 0x60,(byte) 0xee,(byte) 0xe0,(byte) 0x7f,(byte) 0xc0,(byte) 0x31,(byte) 0x80,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0x31,(byte) 0x80,(byte) 0x7f,(byte) 0xc0,(byte) 0xee,(byte) 0xe0,(byte) 0xc0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch164 = new BitmapCharRec(11,12,-1,-3,13,ch164data);
+
+/* char: 0xa3 */
+
+static final byte[] ch163data = {
+(byte) 0xe7,(byte) 0x80,(byte) 0xbe,(byte) 0xc0,(byte) 0x78,(byte) 0x40,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,
+(byte) 0x30,(byte) 0x0,(byte) 0xfc,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x31,(byte) 0x80,(byte) 0x19,(byte) 0x80,
+(byte) 0xf,(byte) 0x0,
+};
+
+static final BitmapCharRec ch163 = new BitmapCharRec(10,17,-1,0,12,ch163data);
+
+/* char: 0xa2 */
+
+static final byte[] ch162data = {
+(byte) 0x40,(byte) 0x0,(byte) 0x40,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x70,(byte) 0x80,(byte) 0xd0,(byte) 0x0,(byte) 0xc8,(byte) 0x0,(byte) 0xc8,(byte) 0x0,
+(byte) 0xc8,(byte) 0x0,(byte) 0xc4,(byte) 0x0,(byte) 0xc4,(byte) 0x0,(byte) 0x43,(byte) 0x80,(byte) 0x63,(byte) 0x80,(byte) 0x1f,(byte) 0x0,(byte) 0x1,(byte) 0x0,(byte) 0x1,(byte) 0x0,
+};
+
+static final BitmapCharRec ch162 = new BitmapCharRec(9,16,-1,2,12,ch162data);
+
+/* char: 0xa1 */
+
+static final byte[] ch161data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,
+(byte) 0xc0,
+};
+
+static final BitmapCharRec ch161 = new BitmapCharRec(2,17,-4,5,8,ch161data);
+
+/* char: 0xa0 */
+
+static final BitmapCharRec ch160 = new BitmapCharRec(0,0,0,0,6,null);
+
+/* char: 0x7e '~' */
+
+static final byte[] ch126data = {
+(byte) 0x83,(byte) 0x80,(byte) 0xc7,(byte) 0xc0,(byte) 0x7c,(byte) 0x60,(byte) 0x38,(byte) 0x20,
+};
+
+static final BitmapCharRec ch126 = new BitmapCharRec(11,4,-1,-5,13,ch126data);
+
+/* char: 0x7d '}' */
+
+static final byte[] ch125data = {
+(byte) 0xe0,(byte) 0x30,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x8,(byte) 0xc,(byte) 0x4,(byte) 0x3,(byte) 0x4,(byte) 0xc,(byte) 0x8,(byte) 0x18,
+(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x30,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch125 = new BitmapCharRec(8,22,-1,5,10,ch125data);
+
+/* char: 0x7c '|' */
+
+static final byte[] ch124data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,
+};
+
+static final BitmapCharRec ch124 = new BitmapCharRec(2,17,-2,0,6,ch124data);
+
+/* char: 0x7b '{' */
+
+static final byte[] ch123data = {
+(byte) 0x7,(byte) 0xc,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x10,(byte) 0x30,(byte) 0x20,(byte) 0xc0,(byte) 0x20,(byte) 0x30,(byte) 0x10,(byte) 0x18,
+(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0xc,(byte) 0x7,
+};
+
+static final BitmapCharRec ch123 = new BitmapCharRec(8,22,-1,5,10,ch123data);
+
+/* char: 0x7a 'z' */
+
+static final byte[] ch122data = {
+(byte) 0xff,(byte) 0xc3,(byte) 0x61,(byte) 0x70,(byte) 0x30,(byte) 0x38,(byte) 0x18,(byte) 0x1c,(byte) 0xe,(byte) 0x86,(byte) 0xc3,(byte) 0xff,
+};
+
+static final BitmapCharRec ch122 = new BitmapCharRec(8,12,-1,0,10,ch122data);
+
+/* char: 0x79 'y' */
+
+static final byte[] ch121data = {
+(byte) 0xe0,(byte) 0x0,(byte) 0xf0,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x8,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x4,(byte) 0x0,(byte) 0xe,(byte) 0x0,(byte) 0xe,(byte) 0x0,
+(byte) 0x1a,(byte) 0x0,(byte) 0x19,(byte) 0x0,(byte) 0x19,(byte) 0x0,(byte) 0x31,(byte) 0x0,(byte) 0x30,(byte) 0x80,(byte) 0x30,(byte) 0x80,(byte) 0x60,(byte) 0x80,(byte) 0x60,(byte) 0xc0,
+(byte) 0xf1,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch121 = new BitmapCharRec(11,17,0,5,11,ch121data);
+
+/* char: 0x78 'x' */
+
+static final byte[] ch120data = {
+(byte) 0xf1,(byte) 0xe0,(byte) 0x60,(byte) 0xc0,(byte) 0x21,(byte) 0x80,(byte) 0x33,(byte) 0x80,(byte) 0x1b,(byte) 0x0,(byte) 0xe,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x1a,(byte) 0x0,
+(byte) 0x39,(byte) 0x0,(byte) 0x31,(byte) 0x80,(byte) 0x60,(byte) 0xc0,(byte) 0xf1,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch120 = new BitmapCharRec(11,12,-1,0,13,ch120data);
+
+/* char: 0x77 'w' */
+
+static final byte[] ch119data = {
+(byte) 0x4,(byte) 0x10,(byte) 0x0,(byte) 0xe,(byte) 0x38,(byte) 0x0,(byte) 0xe,(byte) 0x38,(byte) 0x0,(byte) 0x1a,(byte) 0x28,(byte) 0x0,(byte) 0x1a,(byte) 0x64,(byte) 0x0,(byte) 0x19,
+(byte) 0x64,(byte) 0x0,(byte) 0x31,(byte) 0x64,(byte) 0x0,(byte) 0x30,(byte) 0xc2,(byte) 0x0,(byte) 0x30,(byte) 0xc2,(byte) 0x0,(byte) 0x60,(byte) 0xc2,(byte) 0x0,(byte) 0x60,(byte) 0xc3,
+(byte) 0x0,(byte) 0xf1,(byte) 0xe7,(byte) 0x80,
+};
+
+static final BitmapCharRec ch119 = new BitmapCharRec(17,12,0,0,17,ch119data);
+
+/* char: 0x76 'v' */
+
+static final byte[] ch118data = {
+(byte) 0x4,(byte) 0x0,(byte) 0xe,(byte) 0x0,(byte) 0xe,(byte) 0x0,(byte) 0x1a,(byte) 0x0,(byte) 0x19,(byte) 0x0,(byte) 0x19,(byte) 0x0,(byte) 0x31,(byte) 0x0,(byte) 0x30,(byte) 0x80,
+(byte) 0x30,(byte) 0x80,(byte) 0x60,(byte) 0x80,(byte) 0x60,(byte) 0xc0,(byte) 0xf1,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch118 = new BitmapCharRec(11,12,0,0,11,ch118data);
+
+/* char: 0x75 'u' */
+
+static final byte[] ch117data = {
+(byte) 0x1c,(byte) 0xe0,(byte) 0x3e,(byte) 0xc0,(byte) 0x71,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0xe1,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch117 = new BitmapCharRec(11,12,-1,0,13,ch117data);
+
+/* char: 0x74 't' */
+
+static final byte[] ch116data = {
+(byte) 0x1c,(byte) 0x32,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0xfe,(byte) 0x70,(byte) 0x30,(byte) 0x10,
+};
+
+static final BitmapCharRec ch116 = new BitmapCharRec(7,15,0,0,7,ch116data);
+
+/* char: 0x73 's' */
+
+static final byte[] ch115data = {
+(byte) 0xf8,(byte) 0xc6,(byte) 0x83,(byte) 0x3,(byte) 0x7,(byte) 0x1e,(byte) 0x7c,(byte) 0x70,(byte) 0xe0,(byte) 0xc2,(byte) 0x66,(byte) 0x3e,
+};
+
+static final BitmapCharRec ch115 = new BitmapCharRec(8,12,-1,0,10,ch115data);
+
+/* char: 0x72 'r' */
+
+static final byte[] ch114data = {
+(byte) 0xf0,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x76,(byte) 0x6e,(byte) 0xe6,
+};
+
+static final BitmapCharRec ch114 = new BitmapCharRec(7,12,-1,0,8,ch114data);
+
+/* char: 0x71 'q' */
+
+static final byte[] ch113data = {
+(byte) 0x3,(byte) 0xc0,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1d,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,
+(byte) 0x1d,(byte) 0x80,
+};
+
+static final BitmapCharRec ch113 = new BitmapCharRec(10,17,-1,5,12,ch113data);
+
+/* char: 0x70 'p' */
+
+static final byte[] ch112data = {
+(byte) 0xf0,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x6e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,
+(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,
+(byte) 0xee,(byte) 0x0,
+};
+
+static final BitmapCharRec ch112 = new BitmapCharRec(10,17,-1,5,12,ch112data);
+
+/* char: 0x6f 'o' */
+
+static final byte[] ch111data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x1e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch111 = new BitmapCharRec(10,12,-1,0,12,ch111data);
+
+/* char: 0x6e 'n' */
+
+static final byte[] ch110data = {
+(byte) 0xf1,(byte) 0xe0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0x60,(byte) 0xc0,(byte) 0x71,(byte) 0xc0,(byte) 0x6f,(byte) 0x80,(byte) 0xe7,(byte) 0x0,
+};
+
+static final BitmapCharRec ch110 = new BitmapCharRec(11,12,-1,0,13,ch110data);
+
+/* char: 0x6d 'm' */
+
+static final byte[] ch109data = {
+(byte) 0xf1,(byte) 0xe3,(byte) 0xc0,(byte) 0x60,(byte) 0xc1,(byte) 0x80,(byte) 0x60,(byte) 0xc1,(byte) 0x80,(byte) 0x60,(byte) 0xc1,(byte) 0x80,(byte) 0x60,(byte) 0xc1,(byte) 0x80,(byte) 0x60,
+(byte) 0xc1,(byte) 0x80,(byte) 0x60,(byte) 0xc1,(byte) 0x80,(byte) 0x60,(byte) 0xc1,(byte) 0x80,(byte) 0x60,(byte) 0xc1,(byte) 0x80,(byte) 0x71,(byte) 0xe3,(byte) 0x80,(byte) 0x6f,(byte) 0x9f,
+(byte) 0x0,(byte) 0xe7,(byte) 0xe,(byte) 0x0,
+};
+
+static final BitmapCharRec ch109 = new BitmapCharRec(18,12,-1,0,20,ch109data);
+
+/* char: 0x6c 'l' */
+
+static final byte[] ch108data = {
+(byte) 0xf0,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,
+(byte) 0xe0,
+};
+
+static final BitmapCharRec ch108 = new BitmapCharRec(4,17,-1,0,6,ch108data);
+
+/* char: 0x6b 'k' */
+
+static final byte[] ch107data = {
+(byte) 0xf3,(byte) 0xe0,(byte) 0x61,(byte) 0xc0,(byte) 0x63,(byte) 0x80,(byte) 0x67,(byte) 0x0,(byte) 0x6e,(byte) 0x0,(byte) 0x6c,(byte) 0x0,(byte) 0x78,(byte) 0x0,(byte) 0x68,(byte) 0x0,
+(byte) 0x64,(byte) 0x0,(byte) 0x66,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x67,(byte) 0xc0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,
+(byte) 0xe0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch107 = new BitmapCharRec(11,17,-1,0,12,ch107data);
+
+/* char: 0x6a 'j' */
+
+static final byte[] ch106data = {
+(byte) 0xc0,(byte) 0xe0,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,
+(byte) 0x70,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x30,(byte) 0x30,
+};
+
+static final BitmapCharRec ch106 = new BitmapCharRec(4,22,0,5,6,ch106data);
+
+/* char: 0x69 'i' */
+
+static final byte[] ch105data = {
+(byte) 0xf0,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0x60,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x60,
+(byte) 0x60,
+};
+
+static final BitmapCharRec ch105 = new BitmapCharRec(4,17,-1,0,6,ch105data);
+
+/* char: 0x68 'h' */
+
+static final byte[] ch104data = {
+(byte) 0xf1,(byte) 0xe0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0x60,(byte) 0xc0,(byte) 0x71,(byte) 0xc0,(byte) 0x6f,(byte) 0x80,(byte) 0x67,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,
+(byte) 0xe0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch104 = new BitmapCharRec(11,17,-1,0,13,ch104data);
+
+/* char: 0x67 'g' */
+
+static final byte[] ch103data = {
+(byte) 0x3f,(byte) 0x0,(byte) 0xf1,(byte) 0xc0,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x20,(byte) 0x60,(byte) 0x60,(byte) 0x3f,(byte) 0xc0,(byte) 0x7f,(byte) 0x0,(byte) 0x60,(byte) 0x0,
+(byte) 0x30,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x33,(byte) 0x0,
+(byte) 0x1f,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch103 = new BitmapCharRec(11,17,-1,5,12,ch103data);
+
+/* char: 0x66 'f' */
+
+static final byte[] ch102data = {
+(byte) 0x78,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0xfe,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x16,
+(byte) 0xe,
+};
+
+static final BitmapCharRec ch102 = new BitmapCharRec(7,17,0,0,7,ch102data);
+
+/* char: 0x65 'e' */
+
+static final byte[] ch101data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x70,(byte) 0x80,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xff,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0x41,(byte) 0x80,(byte) 0x63,(byte) 0x0,(byte) 0x1e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch101 = new BitmapCharRec(9,12,-1,0,11,ch101data);
+
+/* char: 0x64 'd' */
+
+static final byte[] ch100data = {
+(byte) 0x1e,(byte) 0xc0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0xc1,(byte) 0x80,
+(byte) 0xc1,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x1d,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,
+(byte) 0x3,(byte) 0x80,
+};
+
+static final BitmapCharRec ch100 = new BitmapCharRec(10,17,-1,0,12,ch100data);
+
+/* char: 0x63 'c' */
+
+static final byte[] ch99data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x7f,(byte) 0x0,(byte) 0x70,(byte) 0x80,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0x41,(byte) 0x80,(byte) 0x63,(byte) 0x80,(byte) 0x1f,(byte) 0x0,
+};
+
+static final BitmapCharRec ch99 = new BitmapCharRec(9,12,-1,0,11,ch99data);
+
+/* char: 0x62 'b' */
+
+static final byte[] ch98data = {
+(byte) 0x5e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,(byte) 0x60,(byte) 0xc0,
+(byte) 0x60,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x73,(byte) 0x80,(byte) 0x6e,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,
+(byte) 0xe0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch98 = new BitmapCharRec(10,17,-1,0,12,ch98data);
+
+/* char: 0x61 'a' */
+
+static final byte[] ch97data = {
+(byte) 0x71,(byte) 0x80,(byte) 0xfb,(byte) 0x0,(byte) 0xc7,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x3b,(byte) 0x0,(byte) 0xf,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x67,(byte) 0x0,(byte) 0x3e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch97 = new BitmapCharRec(9,12,-1,0,11,ch97data);
+
+/* char: 0x60 '`' */
+
+static final byte[] ch96data = {
+(byte) 0x60,(byte) 0xe0,(byte) 0x80,(byte) 0xc0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch96 = new BitmapCharRec(3,5,-2,-12,7,ch96data);
+
+/* char: 0x5f '_' */
+
+static final byte[] ch95data = {
+(byte) 0xff,(byte) 0xf8,(byte) 0xff,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch95 = new BitmapCharRec(13,2,0,5,13,ch95data);
+
+/* char: 0x5e '^' */
+
+static final byte[] ch94data = {
+(byte) 0x80,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x41,(byte) 0x0,(byte) 0x63,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x36,(byte) 0x0,(byte) 0x14,(byte) 0x0,(byte) 0x1c,(byte) 0x0,
+(byte) 0x8,(byte) 0x0,
+};
+
+static final BitmapCharRec ch94 = new BitmapCharRec(9,9,-1,-8,11,ch94data);
+
+/* char: 0x5d ']' */
+
+static final byte[] ch93data = {
+(byte) 0xf8,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,
+(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch93 = new BitmapCharRec(5,21,-1,4,8,ch93data);
+
+/* char: 0x5c '\' */
+
+static final byte[] ch92data = {
+(byte) 0x6,(byte) 0x6,(byte) 0x4,(byte) 0xc,(byte) 0xc,(byte) 0x8,(byte) 0x18,(byte) 0x18,(byte) 0x10,(byte) 0x30,(byte) 0x30,(byte) 0x20,(byte) 0x60,(byte) 0x60,(byte) 0x40,(byte) 0xc0,
+(byte) 0xc0,
+};
+
+static final BitmapCharRec ch92 = new BitmapCharRec(7,17,0,0,7,ch92data);
+
+/* char: 0x5b '[' */
+
+static final byte[] ch91data = {
+(byte) 0xf8,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch91 = new BitmapCharRec(5,21,-2,4,8,ch91data);
+
+/* char: 0x5a 'Z' */
+
+static final byte[] ch90data = {
+(byte) 0xff,(byte) 0xf8,(byte) 0xe0,(byte) 0x18,(byte) 0x70,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x38,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x1c,(byte) 0x0,(byte) 0xe,(byte) 0x0,
+(byte) 0x6,(byte) 0x0,(byte) 0x7,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x80,(byte) 0x1,(byte) 0xc0,(byte) 0x80,(byte) 0xc0,(byte) 0x80,(byte) 0xe0,(byte) 0xc0,(byte) 0x70,
+(byte) 0xff,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch90 = new BitmapCharRec(13,17,-1,0,15,ch90data);
+
+/* char: 0x59 'Y' */
+
+static final byte[] ch89data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x3,(byte) 0xc0,
+(byte) 0x3,(byte) 0x40,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0x20,(byte) 0xc,(byte) 0x30,(byte) 0x1c,(byte) 0x10,(byte) 0x18,(byte) 0x18,(byte) 0x38,(byte) 0x8,(byte) 0x30,(byte) 0xc,
+(byte) 0xfc,(byte) 0x3f,
+};
+
+static final BitmapCharRec ch89 = new BitmapCharRec(16,17,0,0,16,ch89data);
+
+/* char: 0x58 'X' */
+
+static final byte[] ch88data = {
+(byte) 0xfc,(byte) 0xf,(byte) 0xc0,(byte) 0x30,(byte) 0x3,(byte) 0x80,(byte) 0x18,(byte) 0x7,(byte) 0x0,(byte) 0x8,(byte) 0xe,(byte) 0x0,(byte) 0x4,(byte) 0xc,(byte) 0x0,(byte) 0x6,
+(byte) 0x18,(byte) 0x0,(byte) 0x2,(byte) 0x38,(byte) 0x0,(byte) 0x1,(byte) 0x70,(byte) 0x0,(byte) 0x0,(byte) 0xe0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x1,(byte) 0xc0,
+(byte) 0x0,(byte) 0x3,(byte) 0xa0,(byte) 0x0,(byte) 0x3,(byte) 0x10,(byte) 0x0,(byte) 0x6,(byte) 0x8,(byte) 0x0,(byte) 0xe,(byte) 0xc,(byte) 0x0,(byte) 0x1c,(byte) 0x6,(byte) 0x0,
+(byte) 0x7e,(byte) 0xf,(byte) 0x80,
+};
+
+static final BitmapCharRec ch88 = new BitmapCharRec(18,17,0,0,18,ch88data);
+
+/* char: 0x57 'W' */
+
+static final byte[] ch87data = {
+(byte) 0x1,(byte) 0x83,(byte) 0x0,(byte) 0x1,(byte) 0x83,(byte) 0x0,(byte) 0x1,(byte) 0x83,(byte) 0x80,(byte) 0x3,(byte) 0x87,(byte) 0x80,(byte) 0x3,(byte) 0x46,(byte) 0x80,(byte) 0x3,
+(byte) 0x46,(byte) 0xc0,(byte) 0x6,(byte) 0x46,(byte) 0x40,(byte) 0x6,(byte) 0x4c,(byte) 0x40,(byte) 0x6,(byte) 0x4c,(byte) 0x60,(byte) 0xc,(byte) 0x2c,(byte) 0x60,(byte) 0xc,(byte) 0x2c,
+(byte) 0x20,(byte) 0x18,(byte) 0x2c,(byte) 0x20,(byte) 0x18,(byte) 0x18,(byte) 0x30,(byte) 0x18,(byte) 0x18,(byte) 0x10,(byte) 0x30,(byte) 0x18,(byte) 0x10,(byte) 0x30,(byte) 0x18,(byte) 0x18,
+(byte) 0xfc,(byte) 0x7e,(byte) 0x7e,
+};
+
+static final BitmapCharRec ch87 = new BitmapCharRec(23,17,0,0,23,ch87data);
+
+/* char: 0x56 'V' */
+
+static final byte[] ch86data = {
+(byte) 0x1,(byte) 0x80,(byte) 0x0,(byte) 0x1,(byte) 0x80,(byte) 0x0,(byte) 0x1,(byte) 0x80,(byte) 0x0,(byte) 0x3,(byte) 0xc0,(byte) 0x0,(byte) 0x3,(byte) 0x40,(byte) 0x0,(byte) 0x3,
+(byte) 0x60,(byte) 0x0,(byte) 0x6,(byte) 0x20,(byte) 0x0,(byte) 0x6,(byte) 0x20,(byte) 0x0,(byte) 0x6,(byte) 0x30,(byte) 0x0,(byte) 0xc,(byte) 0x10,(byte) 0x0,(byte) 0xc,(byte) 0x18,
+(byte) 0x0,(byte) 0x18,(byte) 0x8,(byte) 0x0,(byte) 0x18,(byte) 0x8,(byte) 0x0,(byte) 0x18,(byte) 0xc,(byte) 0x0,(byte) 0x30,(byte) 0x4,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,
+(byte) 0xfc,(byte) 0x1f,(byte) 0x80,
+};
+
+static final BitmapCharRec ch86 = new BitmapCharRec(17,17,0,0,17,ch86data);
+
+/* char: 0x55 'U' */
+
+static final byte[] ch85data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x30,(byte) 0x18,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0xfc,(byte) 0x1f,
+};
+
+static final BitmapCharRec ch85 = new BitmapCharRec(16,17,-1,0,18,ch85data);
+
+/* char: 0x54 'T' */
+
+static final byte[] ch84data = {
+(byte) 0xf,(byte) 0xc0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x83,(byte) 0x4,(byte) 0x83,(byte) 0x4,(byte) 0xc3,(byte) 0xc,
+(byte) 0xff,(byte) 0xfc,
+};
+
+static final BitmapCharRec ch84 = new BitmapCharRec(14,17,-1,0,16,ch84data);
+
+/* char: 0x53 'S' */
+
+static final byte[] ch83data = {
+(byte) 0x9e,(byte) 0x0,(byte) 0xf1,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0x80,(byte) 0x60,(byte) 0x80,(byte) 0x60,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0xe0,(byte) 0x3,(byte) 0xc0,
+(byte) 0xf,(byte) 0x80,(byte) 0x1e,(byte) 0x0,(byte) 0x78,(byte) 0x0,(byte) 0xe0,(byte) 0x0,(byte) 0xc0,(byte) 0x40,(byte) 0xc0,(byte) 0x40,(byte) 0xc0,(byte) 0xc0,(byte) 0x63,(byte) 0xc0,
+(byte) 0x1e,(byte) 0x40,
+};
+
+static final BitmapCharRec ch83 = new BitmapCharRec(11,17,-1,0,13,ch83data);
+
+/* char: 0x52 'R' */
+
+static final byte[] ch82data = {
+(byte) 0xfc,(byte) 0x1e,(byte) 0x30,(byte) 0x1c,(byte) 0x30,(byte) 0x38,(byte) 0x30,(byte) 0x70,(byte) 0x30,(byte) 0x60,(byte) 0x30,(byte) 0xc0,(byte) 0x31,(byte) 0xc0,(byte) 0x33,(byte) 0x80,
+(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0x70,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x38,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x38,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x70,
+(byte) 0xff,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch82 = new BitmapCharRec(15,17,-1,0,16,ch82data);
+
+/* char: 0x51 'Q' */
+
+static final byte[] ch81data = {
+(byte) 0x0,(byte) 0xf,(byte) 0x0,(byte) 0x38,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0xe0,(byte) 0x1,(byte) 0xc0,(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x38,(byte) 0x38,(byte) 0x1c,
+(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,
+(byte) 0xc0,(byte) 0x3,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0x38,(byte) 0x1c,(byte) 0x1c,(byte) 0x38,(byte) 0x7,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch81 = new BitmapCharRec(16,22,-1,5,18,ch81data);
+
+/* char: 0x50 'P' */
+
+static final byte[] ch80data = {
+(byte) 0xfc,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,
+(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0x70,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x70,
+(byte) 0xff,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch80 = new BitmapCharRec(13,17,-1,0,15,ch80data);
+
+/* char: 0x4f 'O' */
+
+static final byte[] ch79data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1c,(byte) 0x38,(byte) 0x38,(byte) 0x1c,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,
+(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0xc0,(byte) 0x3,(byte) 0x60,(byte) 0x6,(byte) 0x60,(byte) 0x6,(byte) 0x38,(byte) 0x1c,(byte) 0x1c,(byte) 0x38,
+(byte) 0x7,(byte) 0xe0,
+};
+
+static final BitmapCharRec ch79 = new BitmapCharRec(16,17,-1,0,18,ch79data);
+
+/* char: 0x4e 'N' */
+
+static final byte[] ch78data = {
+(byte) 0xf8,(byte) 0xc,(byte) 0x20,(byte) 0x1c,(byte) 0x20,(byte) 0x1c,(byte) 0x20,(byte) 0x34,(byte) 0x20,(byte) 0x64,(byte) 0x20,(byte) 0x64,(byte) 0x20,(byte) 0xc4,(byte) 0x21,(byte) 0x84,
+(byte) 0x21,(byte) 0x84,(byte) 0x23,(byte) 0x4,(byte) 0x26,(byte) 0x4,(byte) 0x26,(byte) 0x4,(byte) 0x2c,(byte) 0x4,(byte) 0x38,(byte) 0x4,(byte) 0x38,(byte) 0x4,(byte) 0x30,(byte) 0x4,
+(byte) 0xf0,(byte) 0x1f,
+};
+
+static final BitmapCharRec ch78 = new BitmapCharRec(16,17,-1,0,18,ch78data);
+
+/* char: 0x4d 'M' */
+
+static final byte[] ch77data = {
+(byte) 0xf8,(byte) 0x21,(byte) 0xf8,(byte) 0x20,(byte) 0x60,(byte) 0x60,(byte) 0x20,(byte) 0x60,(byte) 0x60,(byte) 0x20,(byte) 0xd0,(byte) 0x60,(byte) 0x20,(byte) 0xd0,(byte) 0x60,(byte) 0x21,
+(byte) 0x88,(byte) 0x60,(byte) 0x21,(byte) 0x88,(byte) 0x60,(byte) 0x23,(byte) 0x8,(byte) 0x60,(byte) 0x23,(byte) 0x4,(byte) 0x60,(byte) 0x26,(byte) 0x4,(byte) 0x60,(byte) 0x26,(byte) 0x2,
+(byte) 0x60,(byte) 0x2c,(byte) 0x2,(byte) 0x60,(byte) 0x2c,(byte) 0x2,(byte) 0x60,(byte) 0x38,(byte) 0x1,(byte) 0x60,(byte) 0x38,(byte) 0x1,(byte) 0x60,(byte) 0x30,(byte) 0x0,(byte) 0xe0,
+(byte) 0xf0,(byte) 0x0,(byte) 0xf8,
+};
+
+static final BitmapCharRec ch77 = new BitmapCharRec(21,17,-1,0,22,ch77data);
+
+/* char: 0x4c 'L' */
+
+static final byte[] ch76data = {
+(byte) 0xff,(byte) 0xf8,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,
+(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,
+(byte) 0xfc,(byte) 0x0,
+};
+
+static final BitmapCharRec ch76 = new BitmapCharRec(13,17,-1,0,14,ch76data);
+
+/* char: 0x4b 'K' */
+
+static final byte[] ch75data = {
+(byte) 0xfc,(byte) 0x1f,(byte) 0x30,(byte) 0xe,(byte) 0x30,(byte) 0x1c,(byte) 0x30,(byte) 0x38,(byte) 0x30,(byte) 0x70,(byte) 0x30,(byte) 0xe0,(byte) 0x31,(byte) 0xc0,(byte) 0x33,(byte) 0x80,
+(byte) 0x3f,(byte) 0x0,(byte) 0x3e,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x31,(byte) 0x80,(byte) 0x30,(byte) 0xc0,(byte) 0x30,(byte) 0x60,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x18,
+(byte) 0xfc,(byte) 0x7e,
+};
+
+static final BitmapCharRec ch75 = new BitmapCharRec(16,17,-1,0,17,ch75data);
+
+/* char: 0x4a 'J' */
+
+static final byte[] ch74data = {
+(byte) 0x78,(byte) 0x0,(byte) 0xcc,(byte) 0x0,(byte) 0xc6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+(byte) 0x1f,(byte) 0x80,
+};
+
+static final BitmapCharRec ch74 = new BitmapCharRec(9,17,-1,0,11,ch74data);
+
+/* char: 0x49 'I' */
+
+static final byte[] ch73data = {
+(byte) 0xfc,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x30,
+(byte) 0xfc,
+};
+
+static final BitmapCharRec ch73 = new BitmapCharRec(6,17,-1,0,8,ch73data);
+
+/* char: 0x48 'H' */
+
+static final byte[] ch72data = {
+(byte) 0xfc,(byte) 0x1f,(byte) 0x80,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x30,
+(byte) 0x6,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x3f,(byte) 0xfe,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x30,(byte) 0x6,
+(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x30,(byte) 0x6,(byte) 0x0,
+(byte) 0xfc,(byte) 0x1f,(byte) 0x80,
+};
+
+static final BitmapCharRec ch72 = new BitmapCharRec(17,17,-1,0,19,ch72data);
+
+/* char: 0x47 'G' */
+
+static final byte[] ch71data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1e,(byte) 0x38,(byte) 0x38,(byte) 0x1c,(byte) 0x60,(byte) 0xc,(byte) 0x60,(byte) 0xc,(byte) 0xc0,(byte) 0xc,(byte) 0xc0,(byte) 0xc,(byte) 0xc0,(byte) 0x3f,
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x60,(byte) 0x4,(byte) 0x60,(byte) 0x4,(byte) 0x38,(byte) 0xc,(byte) 0x1c,(byte) 0x3c,
+(byte) 0x7,(byte) 0xe4,
+};
+
+static final BitmapCharRec ch71 = new BitmapCharRec(16,17,-1,0,18,ch71data);
+
+/* char: 0x46 'F' */
+
+static final byte[] ch70data = {
+(byte) 0xfc,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x20,(byte) 0x30,(byte) 0x20,
+(byte) 0x3f,(byte) 0xe0,(byte) 0x30,(byte) 0x20,(byte) 0x30,(byte) 0x20,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x30,
+(byte) 0xff,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch70 = new BitmapCharRec(12,17,-1,0,14,ch70data);
+
+/* char: 0x45 'E' */
+
+static final byte[] ch69data = {
+(byte) 0xff,(byte) 0xf8,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x8,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x40,
+(byte) 0x3f,(byte) 0xc0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x10,(byte) 0x30,(byte) 0x30,
+(byte) 0xff,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch69 = new BitmapCharRec(13,17,-1,0,15,ch69data);
+
+/* char: 0x44 'D' */
+
+static final byte[] ch68data = {
+(byte) 0xff,(byte) 0xc0,(byte) 0x30,(byte) 0x70,(byte) 0x30,(byte) 0x38,(byte) 0x30,(byte) 0xc,(byte) 0x30,(byte) 0xc,(byte) 0x30,(byte) 0x6,(byte) 0x30,(byte) 0x6,(byte) 0x30,(byte) 0x6,
+(byte) 0x30,(byte) 0x6,(byte) 0x30,(byte) 0x6,(byte) 0x30,(byte) 0x6,(byte) 0x30,(byte) 0x6,(byte) 0x30,(byte) 0xc,(byte) 0x30,(byte) 0xc,(byte) 0x30,(byte) 0x38,(byte) 0x30,(byte) 0x70,
+(byte) 0xff,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch68 = new BitmapCharRec(15,17,-1,0,17,ch68data);
+
+/* char: 0x43 'C' */
+
+static final byte[] ch67data = {
+(byte) 0x7,(byte) 0xe0,(byte) 0x1e,(byte) 0x38,(byte) 0x38,(byte) 0x8,(byte) 0x60,(byte) 0x4,(byte) 0x60,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,
+(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x60,(byte) 0x4,(byte) 0x60,(byte) 0x4,(byte) 0x38,(byte) 0xc,(byte) 0x1c,(byte) 0x3c,
+(byte) 0x7,(byte) 0xe4,
+};
+
+static final BitmapCharRec ch67 = new BitmapCharRec(14,17,-1,0,16,ch67data);
+
+/* char: 0x42 'B' */
+
+static final byte[] ch66data = {
+(byte) 0xff,(byte) 0xe0,(byte) 0x30,(byte) 0x78,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0xc,(byte) 0x30,(byte) 0xc,(byte) 0x30,(byte) 0xc,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x38,
+(byte) 0x3f,(byte) 0xe0,(byte) 0x30,(byte) 0x40,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x18,(byte) 0x30,(byte) 0x30,(byte) 0x30,(byte) 0x70,
+(byte) 0xff,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch66 = new BitmapCharRec(14,17,-1,0,16,ch66data);
+
+/* char: 0x41 'A' */
+
+static final byte[] ch65data = {
+(byte) 0xfc,(byte) 0x1f,(byte) 0x80,(byte) 0x30,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0x6,(byte) 0x0,(byte) 0x10,(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0xc,(byte) 0x0,(byte) 0x8,
+(byte) 0xc,(byte) 0x0,(byte) 0xf,(byte) 0xf8,(byte) 0x0,(byte) 0xc,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x18,(byte) 0x0,(byte) 0x4,(byte) 0x30,(byte) 0x0,(byte) 0x6,(byte) 0x30,
+(byte) 0x0,(byte) 0x2,(byte) 0x30,(byte) 0x0,(byte) 0x2,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0x60,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,
+(byte) 0x0,(byte) 0x80,(byte) 0x0,
+};
+
+static final BitmapCharRec ch65 = new BitmapCharRec(17,17,0,0,17,ch65data);
+
+/* char: 0x40 '@' */
+
+static final byte[] ch64data = {
+(byte) 0x3,(byte) 0xf0,(byte) 0x0,(byte) 0xe,(byte) 0xc,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x0,(byte) 0x61,(byte) 0xde,(byte) 0x0,(byte) 0x63,
+(byte) 0x7b,(byte) 0x0,(byte) 0xc6,(byte) 0x39,(byte) 0x80,(byte) 0xc6,(byte) 0x18,(byte) 0x80,(byte) 0xc6,(byte) 0x18,(byte) 0xc0,(byte) 0xc6,(byte) 0x18,(byte) 0x40,(byte) 0xc6,(byte) 0xc,
+(byte) 0x40,(byte) 0xc3,(byte) 0xc,(byte) 0x40,(byte) 0xc3,(byte) 0x8c,(byte) 0x40,(byte) 0xe1,(byte) 0xfc,(byte) 0x40,(byte) 0x60,(byte) 0xec,(byte) 0xc0,(byte) 0x70,(byte) 0x0,(byte) 0x80,
+(byte) 0x38,(byte) 0x1,(byte) 0x80,(byte) 0x1c,(byte) 0x3,(byte) 0x0,(byte) 0xf,(byte) 0xe,(byte) 0x0,(byte) 0x3,(byte) 0xf8,(byte) 0x0,
+};
+
+static final BitmapCharRec ch64 = new BitmapCharRec(18,20,-2,3,22,ch64data);
+
+/* char: 0x3f '?' */
+
+static final byte[] ch63data = {
+(byte) 0x30,(byte) 0x30,(byte) 0x0,(byte) 0x0,(byte) 0x10,(byte) 0x10,(byte) 0x10,(byte) 0x18,(byte) 0x18,(byte) 0xc,(byte) 0xe,(byte) 0x7,(byte) 0xc3,(byte) 0xc3,(byte) 0x83,(byte) 0xc6,
+(byte) 0x7c,
+};
+
+static final BitmapCharRec ch63 = new BitmapCharRec(8,17,-2,0,11,ch63data);
+
+/* char: 0x3e '>' */
+
+static final byte[] ch62data = {
+(byte) 0xc0,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0x1c,(byte) 0x0,(byte) 0x7,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0x60,(byte) 0x1,(byte) 0xc0,(byte) 0x7,(byte) 0x0,
+(byte) 0x1c,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0xc0,(byte) 0x0,
+};
+
+static final BitmapCharRec ch62 = new BitmapCharRec(11,11,-1,-1,13,ch62data);
+
+/* char: 0x3d '=' */
+
+static final byte[] ch61data = {
+(byte) 0xff,(byte) 0xf0,(byte) 0xff,(byte) 0xf0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xff,(byte) 0xf0,(byte) 0xff,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch61 = new BitmapCharRec(12,6,-1,-4,14,ch61data);
+
+/* char: 0x3c '<' */
+
+static final byte[] ch60data = {
+(byte) 0x0,(byte) 0x60,(byte) 0x1,(byte) 0xc0,(byte) 0x7,(byte) 0x0,(byte) 0x1c,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0x1c,(byte) 0x0,
+(byte) 0x7,(byte) 0x0,(byte) 0x1,(byte) 0xc0,(byte) 0x0,(byte) 0x60,
+};
+
+static final BitmapCharRec ch60 = new BitmapCharRec(11,11,-1,-1,13,ch60data);
+
+/* char: 0x3b ';' */
+
+static final byte[] ch59data = {
+(byte) 0xc0,(byte) 0x60,(byte) 0x20,(byte) 0xe0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch59 = new BitmapCharRec(3,14,-2,3,7,ch59data);
+
+/* char: 0x3a ':' */
+
+static final byte[] ch58data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch58 = new BitmapCharRec(2,11,-2,0,6,ch58data);
+
+/* char: 0x39 '9' */
+
+static final byte[] ch57data = {
+(byte) 0xf0,(byte) 0x0,(byte) 0x1c,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1d,(byte) 0x80,(byte) 0x73,(byte) 0xc0,
+(byte) 0x61,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc1,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x77,(byte) 0x80,
+(byte) 0x1e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch57 = new BitmapCharRec(10,17,-1,0,12,ch57data);
+
+/* char: 0x38 '8' */
+
+static final byte[] ch56data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x73,(byte) 0x80,(byte) 0xe1,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x41,(byte) 0xc0,(byte) 0x61,(byte) 0x80,
+(byte) 0x37,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x33,(byte) 0x0,
+(byte) 0x1e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch56 = new BitmapCharRec(10,17,-1,0,12,ch56data);
+
+/* char: 0x37 '7' */
+
+static final byte[] ch55data = {
+(byte) 0x18,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x4,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+(byte) 0x2,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x1,(byte) 0x0,(byte) 0x1,(byte) 0x80,(byte) 0x81,(byte) 0x80,(byte) 0xc0,(byte) 0xc0,(byte) 0xff,(byte) 0xc0,
+(byte) 0x7f,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch55 = new BitmapCharRec(10,17,-1,0,12,ch55data);
+
+/* char: 0x36 '6' */
+
+static final byte[] ch54data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x7b,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xe0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc1,(byte) 0x80,(byte) 0xf3,(byte) 0x80,(byte) 0xee,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x70,(byte) 0x0,(byte) 0x30,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0xe,(byte) 0x0,
+(byte) 0x3,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch54 = new BitmapCharRec(10,17,-1,0,12,ch54data);
+
+/* char: 0x35 '5' */
+
+static final byte[] ch53data = {
+(byte) 0x7e,(byte) 0x0,(byte) 0xe3,(byte) 0x80,(byte) 0xc1,(byte) 0x80,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x0,(byte) 0xc0,(byte) 0x1,(byte) 0xc0,
+(byte) 0x3,(byte) 0x80,(byte) 0xf,(byte) 0x80,(byte) 0x7e,(byte) 0x0,(byte) 0x78,(byte) 0x0,(byte) 0x60,(byte) 0x0,(byte) 0x20,(byte) 0x0,(byte) 0x20,(byte) 0x0,(byte) 0x1f,(byte) 0x80,
+(byte) 0x1f,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch53 = new BitmapCharRec(10,17,-1,0,12,ch53data);
+
+/* char: 0x34 '4' */
+
+static final byte[] ch52data = {
+(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0xff,(byte) 0xc0,(byte) 0xff,(byte) 0xc0,(byte) 0xc3,(byte) 0x0,(byte) 0x43,(byte) 0x0,
+(byte) 0x63,(byte) 0x0,(byte) 0x23,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x13,(byte) 0x0,(byte) 0x1b,(byte) 0x0,(byte) 0xb,(byte) 0x0,(byte) 0x7,(byte) 0x0,(byte) 0x7,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,
+};
+
+static final BitmapCharRec ch52 = new BitmapCharRec(10,17,-1,0,12,ch52data);
+
+/* char: 0x33 '3' */
+
+static final byte[] ch51data = {
+(byte) 0x78,(byte) 0x0,(byte) 0xe6,(byte) 0x0,(byte) 0xc3,(byte) 0x0,(byte) 0x1,(byte) 0x0,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x3,(byte) 0x80,
+(byte) 0x7,(byte) 0x0,(byte) 0x1e,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x83,(byte) 0x0,(byte) 0x83,(byte) 0x0,(byte) 0x47,(byte) 0x0,(byte) 0x7e,(byte) 0x0,
+(byte) 0x1c,(byte) 0x0,
+};
+
+static final BitmapCharRec ch51 = new BitmapCharRec(9,17,-1,0,12,ch51data);
+
+/* char: 0x32 '2' */
+
+static final byte[] ch50data = {
+(byte) 0xff,(byte) 0x80,(byte) 0xff,(byte) 0xc0,(byte) 0x60,(byte) 0x40,(byte) 0x30,(byte) 0x0,(byte) 0x18,(byte) 0x0,(byte) 0xc,(byte) 0x0,(byte) 0x4,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+(byte) 0x3,(byte) 0x0,(byte) 0x3,(byte) 0x0,(byte) 0x1,(byte) 0x80,(byte) 0x1,(byte) 0x80,(byte) 0x81,(byte) 0x80,(byte) 0x81,(byte) 0x80,(byte) 0x43,(byte) 0x80,(byte) 0x7f,(byte) 0x0,
+(byte) 0x1c,(byte) 0x0,
+};
+
+static final BitmapCharRec ch50 = new BitmapCharRec(10,17,-1,0,12,ch50data);
+
+/* char: 0x31 '1' */
+
+static final byte[] ch49data = {
+(byte) 0xff,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x18,(byte) 0x78,(byte) 0x18,
+(byte) 0x8,
+};
+
+static final BitmapCharRec ch49 = new BitmapCharRec(8,17,-2,0,12,ch49data);
+
+/* char: 0x30 '0' */
+
+static final byte[] ch48data = {
+(byte) 0x1e,(byte) 0x0,(byte) 0x33,(byte) 0x0,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0xe1,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x61,(byte) 0x80,(byte) 0x61,(byte) 0x80,(byte) 0x33,(byte) 0x0,
+(byte) 0x1e,(byte) 0x0,
+};
+
+static final BitmapCharRec ch48 = new BitmapCharRec(10,17,-1,0,12,ch48data);
+
+/* char: 0x2f '/' */
+
+static final byte[] ch47data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x60,(byte) 0x60,(byte) 0x20,(byte) 0x30,(byte) 0x30,(byte) 0x10,(byte) 0x18,(byte) 0x18,(byte) 0x8,(byte) 0xc,(byte) 0xc,(byte) 0x4,(byte) 0x6,
+(byte) 0x6,(byte) 0x3,(byte) 0x3,(byte) 0x3,
+};
+
+static final BitmapCharRec ch47 = new BitmapCharRec(8,20,1,3,7,ch47data);
+
+/* char: 0x2e '.' */
+
+static final byte[] ch46data = {
+(byte) 0xc0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch46 = new BitmapCharRec(2,2,-2,0,6,ch46data);
+
+/* char: 0x2d '-' */
+
+static final byte[] ch45data = {
+(byte) 0xff,(byte) 0xf0,(byte) 0xff,(byte) 0xf0,
+};
+
+static final BitmapCharRec ch45 = new BitmapCharRec(12,2,-1,-6,14,ch45data);
+
+/* char: 0x2c ',' */
+
+static final byte[] ch44data = {
+(byte) 0xc0,(byte) 0x60,(byte) 0x20,(byte) 0xe0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch44 = new BitmapCharRec(3,5,-2,3,7,ch44data);
+
+/* char: 0x2b '+' */
+
+static final byte[] ch43data = {
+(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0xff,(byte) 0xf0,(byte) 0xff,(byte) 0xf0,(byte) 0x6,(byte) 0x0,
+(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,(byte) 0x6,(byte) 0x0,
+};
+
+static final BitmapCharRec ch43 = new BitmapCharRec(12,12,-1,-1,14,ch43data);
+
+/* char: 0x2a '*' */
+
+static final byte[] ch42data = {
+(byte) 0x8,(byte) 0x0,(byte) 0x1c,(byte) 0x0,(byte) 0xc9,(byte) 0x80,(byte) 0xeb,(byte) 0x80,(byte) 0x1c,(byte) 0x0,(byte) 0xeb,(byte) 0x80,(byte) 0xc9,(byte) 0x80,(byte) 0x1c,(byte) 0x0,
+(byte) 0x8,(byte) 0x0,
+};
+
+static final BitmapCharRec ch42 = new BitmapCharRec(9,9,-2,-8,12,ch42data);
+
+/* char: 0x29 ')' */
+
+static final byte[] ch41data = {
+(byte) 0x80,(byte) 0x40,(byte) 0x20,(byte) 0x30,(byte) 0x10,(byte) 0x18,(byte) 0x18,(byte) 0xc,(byte) 0xc,(byte) 0xc,(byte) 0xc,(byte) 0xc,(byte) 0xc,(byte) 0xc,(byte) 0xc,(byte) 0x18,
+(byte) 0x18,(byte) 0x10,(byte) 0x30,(byte) 0x20,(byte) 0x40,(byte) 0x80,
+};
+
+static final BitmapCharRec ch41 = new BitmapCharRec(6,22,-1,5,8,ch41data);
+
+/* char: 0x28 '(' */
+
+static final byte[] ch40data = {
+(byte) 0x4,(byte) 0x8,(byte) 0x10,(byte) 0x30,(byte) 0x20,(byte) 0x60,(byte) 0x60,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0x60,
+(byte) 0x60,(byte) 0x20,(byte) 0x30,(byte) 0x10,(byte) 0x8,(byte) 0x4,
+};
+
+static final BitmapCharRec ch40 = new BitmapCharRec(6,22,-1,5,8,ch40data);
+
+/* char: 0x27 ''' */
+
+static final byte[] ch39data = {
+(byte) 0xc0,(byte) 0x60,(byte) 0x20,(byte) 0xe0,(byte) 0xc0,
+};
+
+static final BitmapCharRec ch39 = new BitmapCharRec(3,5,-3,-12,8,ch39data);
+
+/* char: 0x26 '&' */
+
+static final byte[] ch38data = {
+(byte) 0x3c,(byte) 0x3c,(byte) 0x7f,(byte) 0x7e,(byte) 0xe1,(byte) 0xe1,(byte) 0xc0,(byte) 0xc0,(byte) 0xc1,(byte) 0xc0,(byte) 0xc1,(byte) 0xa0,(byte) 0x63,(byte) 0x20,(byte) 0x37,(byte) 0x10,
+(byte) 0x1e,(byte) 0x18,(byte) 0xe,(byte) 0x3e,(byte) 0xf,(byte) 0x0,(byte) 0x1d,(byte) 0x80,(byte) 0x18,(byte) 0xc0,(byte) 0x18,(byte) 0x40,(byte) 0x18,(byte) 0x40,(byte) 0xc,(byte) 0xc0,
+(byte) 0x7,(byte) 0x80,
+};
+
+static final BitmapCharRec ch38 = new BitmapCharRec(16,17,-1,0,18,ch38data);
+
+/* char: 0x25 '%' */
+
+static final byte[] ch37data = {
+(byte) 0x30,(byte) 0x3c,(byte) 0x0,(byte) 0x18,(byte) 0x72,(byte) 0x0,(byte) 0xc,(byte) 0x61,(byte) 0x0,(byte) 0x4,(byte) 0x60,(byte) 0x80,(byte) 0x6,(byte) 0x60,(byte) 0x80,(byte) 0x3,
+(byte) 0x30,(byte) 0x80,(byte) 0x1,(byte) 0x19,(byte) 0x80,(byte) 0x1,(byte) 0x8f,(byte) 0x0,(byte) 0x78,(byte) 0xc0,(byte) 0x0,(byte) 0xe4,(byte) 0x40,(byte) 0x0,(byte) 0xc2,(byte) 0x60,
+(byte) 0x0,(byte) 0xc1,(byte) 0x30,(byte) 0x0,(byte) 0xc1,(byte) 0x10,(byte) 0x0,(byte) 0x61,(byte) 0x18,(byte) 0x0,(byte) 0x33,(byte) 0xfc,(byte) 0x0,(byte) 0x1e,(byte) 0xc,(byte) 0x0,
+};
+
+static final BitmapCharRec ch37 = new BitmapCharRec(17,16,-1,0,19,ch37data);
+
+/* char: 0x24 '$' */
+
+static final byte[] ch36data = {
+(byte) 0x4,(byte) 0x0,(byte) 0x4,(byte) 0x0,(byte) 0x3f,(byte) 0x0,(byte) 0xe5,(byte) 0xc0,(byte) 0xc4,(byte) 0xc0,(byte) 0x84,(byte) 0x60,(byte) 0x84,(byte) 0x60,(byte) 0x4,(byte) 0x60,
+(byte) 0x4,(byte) 0xe0,(byte) 0x7,(byte) 0xc0,(byte) 0x7,(byte) 0x80,(byte) 0x1e,(byte) 0x0,(byte) 0x3c,(byte) 0x0,(byte) 0x74,(byte) 0x0,(byte) 0x64,(byte) 0x0,(byte) 0x64,(byte) 0x20,
+(byte) 0x64,(byte) 0x60,(byte) 0x34,(byte) 0xe0,(byte) 0x1f,(byte) 0x80,(byte) 0x4,(byte) 0x0,(byte) 0x4,(byte) 0x0,
+};
+
+static final BitmapCharRec ch36 = new BitmapCharRec(11,21,0,2,12,ch36data);
+
+/* char: 0x23 '#' */
+
+static final byte[] ch35data = {
+(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0x22,(byte) 0x0,(byte) 0xff,(byte) 0xc0,(byte) 0xff,(byte) 0xc0,(byte) 0x11,(byte) 0x0,
+(byte) 0x11,(byte) 0x0,(byte) 0x11,(byte) 0x0,(byte) 0x7f,(byte) 0xe0,(byte) 0x7f,(byte) 0xe0,(byte) 0x8,(byte) 0x80,(byte) 0x8,(byte) 0x80,(byte) 0x8,(byte) 0x80,(byte) 0x8,(byte) 0x80,
+(byte) 0x8,(byte) 0x80,
+};
+
+static final BitmapCharRec ch35 = new BitmapCharRec(11,17,-1,0,13,ch35data);
+
+/* char: 0x22 '"' */
+
+static final byte[] ch34data = {
+(byte) 0x88,(byte) 0xcc,(byte) 0xcc,(byte) 0xcc,(byte) 0xcc,
+};
+
+static final BitmapCharRec ch34 = new BitmapCharRec(6,5,-1,-12,10,ch34data);
+
+/* char: 0x21 '!' */
+
+static final byte[] ch33data = {
+(byte) 0xc0,(byte) 0xc0,(byte) 0x0,(byte) 0x0,(byte) 0x0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,(byte) 0xc0,
+(byte) 0xc0,
+};
+
+static final BitmapCharRec ch33 = new BitmapCharRec(2,17,-3,0,8,ch33data);
+
+/* char: 0x20 ' ' */
+
+static final BitmapCharRec ch32 = new BitmapCharRec(0,0,0,0,6,null);
+
+static final BitmapCharRec[] chars = {
+ch32,
+ch33,
+ch34,
+ch35,
+ch36,
+ch37,
+ch38,
+ch39,
+ch40,
+ch41,
+ch42,
+ch43,
+ch44,
+ch45,
+ch46,
+ch47,
+ch48,
+ch49,
+ch50,
+ch51,
+ch52,
+ch53,
+ch54,
+ch55,
+ch56,
+ch57,
+ch58,
+ch59,
+ch60,
+ch61,
+ch62,
+ch63,
+ch64,
+ch65,
+ch66,
+ch67,
+ch68,
+ch69,
+ch70,
+ch71,
+ch72,
+ch73,
+ch74,
+ch75,
+ch76,
+ch77,
+ch78,
+ch79,
+ch80,
+ch81,
+ch82,
+ch83,
+ch84,
+ch85,
+ch86,
+ch87,
+ch88,
+ch89,
+ch90,
+ch91,
+ch92,
+ch93,
+ch94,
+ch95,
+ch96,
+ch97,
+ch98,
+ch99,
+ch100,
+ch101,
+ch102,
+ch103,
+ch104,
+ch105,
+ch106,
+ch107,
+ch108,
+ch109,
+ch110,
+ch111,
+ch112,
+ch113,
+ch114,
+ch115,
+ch116,
+ch117,
+ch118,
+ch119,
+ch120,
+ch121,
+ch122,
+ch123,
+ch124,
+ch125,
+ch126,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+null,
+ch160,
+ch161,
+ch162,
+ch163,
+ch164,
+ch165,
+ch166,
+ch167,
+ch168,
+ch169,
+ch170,
+ch171,
+ch172,
+ch173,
+ch174,
+ch175,
+ch176,
+ch177,
+ch178,
+ch179,
+ch180,
+ch181,
+ch182,
+ch183,
+ch184,
+ch185,
+ch186,
+ch187,
+ch188,
+ch189,
+ch190,
+ch191,
+ch192,
+ch193,
+ch194,
+ch195,
+ch196,
+ch197,
+ch198,
+ch199,
+ch200,
+ch201,
+ch202,
+ch203,
+ch204,
+ch205,
+ch206,
+ch207,
+ch208,
+ch209,
+ch210,
+ch211,
+ch212,
+ch213,
+ch214,
+ch215,
+ch216,
+ch217,
+ch218,
+ch219,
+ch220,
+ch221,
+ch222,
+ch223,
+ch224,
+ch225,
+ch226,
+ch227,
+ch228,
+ch229,
+ch230,
+ch231,
+ch232,
+ch233,
+ch234,
+ch235,
+ch236,
+ch237,
+ch238,
+ch239,
+ch240,
+ch241,
+ch242,
+ch243,
+ch244,
+ch245,
+ch246,
+ch247,
+ch248,
+ch249,
+ch250,
+ch251,
+ch252,
+ch253,
+ch254,
+ch255,
+};
+
+ public static final BitmapFontRec glutBitmapTimesRoman24 = new BitmapFontRec("-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1",
+ 224,
+ 32,
+ chars);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTStrokeMonoRoman.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTStrokeMonoRoman.java
new file mode 100644
index 000000000..b8296924e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTStrokeMonoRoman.java
@@ -0,0 +1,2491 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+class GLUTStrokeMonoRoman {
+
+/* GENERATED FILE -- DO NOT MODIFY */
+
+/* char: 33 '!' */
+
+static final CoordRec char33_stroke0[] = {
+ new CoordRec((float) 52.381, (float) 100 ),
+ new CoordRec((float) 52.381, (float) 33.3333 ),
+};
+
+static final CoordRec char33_stroke1[] = {
+ new CoordRec((float) 52.381, (float) 9.5238 ),
+ new CoordRec((float) 47.6191, (float) 4.7619 ),
+ new CoordRec((float) 52.381, (float) 0 ),
+ new CoordRec((float) 57.1429, (float) 4.7619 ),
+ new CoordRec((float) 52.381, (float) 9.5238 ),
+};
+
+static final StrokeRec char33[] = {
+ new StrokeRec( 2, char33_stroke0 ),
+ new StrokeRec( 5, char33_stroke1 ),
+};
+
+/* char: 34 '"' */
+
+static final CoordRec char34_stroke0[] = {
+ new CoordRec((float) 33.3334, (float) 100 ),
+ new CoordRec((float) 33.3334, (float) 66.6667 ),
+};
+
+static final CoordRec char34_stroke1[] = {
+ new CoordRec((float) 71.4286, (float) 100 ),
+ new CoordRec((float) 71.4286, (float) 66.6667 ),
+};
+
+static final StrokeRec char34[] = {
+ new StrokeRec( 2, char34_stroke0 ),
+ new StrokeRec( 2, char34_stroke1 ),
+};
+
+/* char: 35 '#' */
+
+static final CoordRec char35_stroke0[] = {
+ new CoordRec((float) 54.7619, (float) 119.048 ),
+ new CoordRec((float) 21.4286, (float) -33.3333 ),
+};
+
+static final CoordRec char35_stroke1[] = {
+ new CoordRec((float) 83.3334, (float) 119.048 ),
+ new CoordRec((float) 50, (float) -33.3333 ),
+};
+
+static final CoordRec char35_stroke2[] = {
+ new CoordRec((float) 21.4286, (float) 57.1429 ),
+ new CoordRec((float) 88.0952, (float) 57.1429 ),
+};
+
+static final CoordRec char35_stroke3[] = {
+ new CoordRec((float) 16.6667, (float) 28.5714 ),
+ new CoordRec((float) 83.3334, (float) 28.5714 ),
+};
+
+static final StrokeRec char35[] = {
+ new StrokeRec( 2, char35_stroke0 ),
+ new StrokeRec( 2, char35_stroke1 ),
+ new StrokeRec( 2, char35_stroke2 ),
+ new StrokeRec( 2, char35_stroke3 ),
+};
+
+/* char: 36 '$' */
+
+static final CoordRec char36_stroke0[] = {
+ new CoordRec((float) 42.8571, (float) 119.048 ),
+ new CoordRec((float) 42.8571, (float) -19.0476 ),
+};
+
+static final CoordRec char36_stroke1[] = {
+ new CoordRec((float) 61.9047, (float) 119.048 ),
+ new CoordRec((float) 61.9047, (float) -19.0476 ),
+};
+
+static final CoordRec char36_stroke2[] = {
+ new CoordRec((float) 85.7143, (float) 85.7143 ),
+ new CoordRec((float) 76.1905, (float) 95.2381 ),
+ new CoordRec((float) 61.9047, (float) 100 ),
+ new CoordRec((float) 42.8571, (float) 100 ),
+ new CoordRec((float) 28.5714, (float) 95.2381 ),
+ new CoordRec((float) 19.0476, (float) 85.7143 ),
+ new CoordRec((float) 19.0476, (float) 76.1905 ),
+ new CoordRec((float) 23.8095, (float) 66.6667 ),
+ new CoordRec((float) 28.5714, (float) 61.9048 ),
+ new CoordRec((float) 38.0952, (float) 57.1429 ),
+ new CoordRec((float) 66.6666, (float) 47.619 ),
+ new CoordRec((float) 76.1905, (float) 42.8571 ),
+ new CoordRec((float) 80.9524, (float) 38.0952 ),
+ new CoordRec((float) 85.7143, (float) 28.5714 ),
+ new CoordRec((float) 85.7143, (float) 14.2857 ),
+ new CoordRec((float) 76.1905, (float) 4.7619 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 42.8571, (float) 0 ),
+ new CoordRec((float) 28.5714, (float) 4.7619 ),
+ new CoordRec((float) 19.0476, (float) 14.2857 ),
+};
+
+static final StrokeRec char36[] = {
+ new StrokeRec( 2, char36_stroke0 ),
+ new StrokeRec( 2, char36_stroke1 ),
+ new StrokeRec( 20, char36_stroke2 ),
+};
+
+/* char: 37 '%' */
+
+static final CoordRec char37_stroke0[] = {
+ new CoordRec((float) 95.2381, (float) 100 ),
+ new CoordRec((float) 9.5238, (float) 0 ),
+};
+
+static final CoordRec char37_stroke1[] = {
+ new CoordRec((float) 33.3333, (float) 100 ),
+ new CoordRec((float) 42.8571, (float) 90.4762 ),
+ new CoordRec((float) 42.8571, (float) 80.9524 ),
+ new CoordRec((float) 38.0952, (float) 71.4286 ),
+ new CoordRec((float) 28.5714, (float) 66.6667 ),
+ new CoordRec((float) 19.0476, (float) 66.6667 ),
+ new CoordRec((float) 9.5238, (float) 76.1905 ),
+ new CoordRec((float) 9.5238, (float) 85.7143 ),
+ new CoordRec((float) 14.2857, (float) 95.2381 ),
+ new CoordRec((float) 23.8095, (float) 100 ),
+ new CoordRec((float) 33.3333, (float) 100 ),
+ new CoordRec((float) 42.8571, (float) 95.2381 ),
+ new CoordRec((float) 57.1428, (float) 90.4762 ),
+ new CoordRec((float) 71.4286, (float) 90.4762 ),
+ new CoordRec((float) 85.7143, (float) 95.2381 ),
+ new CoordRec((float) 95.2381, (float) 100 ),
+};
+
+static final CoordRec char37_stroke2[] = {
+ new CoordRec((float) 76.1905, (float) 33.3333 ),
+ new CoordRec((float) 66.6667, (float) 28.5714 ),
+ new CoordRec((float) 61.9048, (float) 19.0476 ),
+ new CoordRec((float) 61.9048, (float) 9.5238 ),
+ new CoordRec((float) 71.4286, (float) 0 ),
+ new CoordRec((float) 80.9524, (float) 0 ),
+ new CoordRec((float) 90.4762, (float) 4.7619 ),
+ new CoordRec((float) 95.2381, (float) 14.2857 ),
+ new CoordRec((float) 95.2381, (float) 23.8095 ),
+ new CoordRec((float) 85.7143, (float) 33.3333 ),
+ new CoordRec((float) 76.1905, (float) 33.3333 ),
+};
+
+static final StrokeRec char37[] = {
+ new StrokeRec( 2, char37_stroke0 ),
+ new StrokeRec( 16, char37_stroke1 ),
+ new StrokeRec( 11, char37_stroke2 ),
+};
+
+/* char: 38 '&' */
+
+static final CoordRec char38_stroke0[] = {
+ new CoordRec((float) 100, (float) 57.1429 ),
+ new CoordRec((float) 100, (float) 61.9048 ),
+ new CoordRec((float) 95.2381, (float) 66.6667 ),
+ new CoordRec((float) 90.4762, (float) 66.6667 ),
+ new CoordRec((float) 85.7143, (float) 61.9048 ),
+ new CoordRec((float) 80.9524, (float) 52.381 ),
+ new CoordRec((float) 71.4286, (float) 28.5714 ),
+ new CoordRec((float) 61.9048, (float) 14.2857 ),
+ new CoordRec((float) 52.3809, (float) 4.7619 ),
+ new CoordRec((float) 42.8571, (float) 0 ),
+ new CoordRec((float) 23.8095, (float) 0 ),
+ new CoordRec((float) 14.2857, (float) 4.7619 ),
+ new CoordRec((float) 9.5238, (float) 9.5238 ),
+ new CoordRec((float) 4.7619, (float) 19.0476 ),
+ new CoordRec((float) 4.7619, (float) 28.5714 ),
+ new CoordRec((float) 9.5238, (float) 38.0952 ),
+ new CoordRec((float) 14.2857, (float) 42.8571 ),
+ new CoordRec((float) 47.619, (float) 61.9048 ),
+ new CoordRec((float) 52.3809, (float) 66.6667 ),
+ new CoordRec((float) 57.1429, (float) 76.1905 ),
+ new CoordRec((float) 57.1429, (float) 85.7143 ),
+ new CoordRec((float) 52.3809, (float) 95.2381 ),
+ new CoordRec((float) 42.8571, (float) 100 ),
+ new CoordRec((float) 33.3333, (float) 95.2381 ),
+ new CoordRec((float) 28.5714, (float) 85.7143 ),
+ new CoordRec((float) 28.5714, (float) 76.1905 ),
+ new CoordRec((float) 33.3333, (float) 61.9048 ),
+ new CoordRec((float) 42.8571, (float) 47.619 ),
+ new CoordRec((float) 66.6667, (float) 14.2857 ),
+ new CoordRec((float) 76.1905, (float) 4.7619 ),
+ new CoordRec((float) 85.7143, (float) 0 ),
+ new CoordRec((float) 95.2381, (float) 0 ),
+ new CoordRec((float) 100, (float) 4.7619 ),
+ new CoordRec((float) 100, (float) 9.5238 ),
+};
+
+static final StrokeRec char38[] = {
+ new StrokeRec( 34, char38_stroke0 ),
+};
+
+/* char: 39 ''' */
+
+static final CoordRec char39_stroke0[] = {
+ new CoordRec((float) 52.381, (float) 100 ),
+ new CoordRec((float) 52.381, (float) 66.6667 ),
+};
+
+static final StrokeRec char39[] = {
+ new StrokeRec( 2, char39_stroke0 ),
+};
+
+/* char: 40 '(' */
+
+static final CoordRec char40_stroke0[] = {
+ new CoordRec((float) 69.0476, (float) 119.048 ),
+ new CoordRec((float) 59.5238, (float) 109.524 ),
+ new CoordRec((float) 50, (float) 95.2381 ),
+ new CoordRec((float) 40.4762, (float) 76.1905 ),
+ new CoordRec((float) 35.7143, (float) 52.381 ),
+ new CoordRec((float) 35.7143, (float) 33.3333 ),
+ new CoordRec((float) 40.4762, (float) 9.5238 ),
+ new CoordRec((float) 50, (float) -9.5238 ),
+ new CoordRec((float) 59.5238, (float) -23.8095 ),
+ new CoordRec((float) 69.0476, (float) -33.3333 ),
+};
+
+static final StrokeRec char40[] = {
+ new StrokeRec( 10, char40_stroke0 ),
+};
+
+/* char: 41 ')' */
+
+static final CoordRec char41_stroke0[] = {
+ new CoordRec((float) 35.7143, (float) 119.048 ),
+ new CoordRec((float) 45.2381, (float) 109.524 ),
+ new CoordRec((float) 54.7619, (float) 95.2381 ),
+ new CoordRec((float) 64.2857, (float) 76.1905 ),
+ new CoordRec((float) 69.0476, (float) 52.381 ),
+ new CoordRec((float) 69.0476, (float) 33.3333 ),
+ new CoordRec((float) 64.2857, (float) 9.5238 ),
+ new CoordRec((float) 54.7619, (float) -9.5238 ),
+ new CoordRec((float) 45.2381, (float) -23.8095 ),
+ new CoordRec((float) 35.7143, (float) -33.3333 ),
+};
+
+static final StrokeRec char41[] = {
+ new StrokeRec( 10, char41_stroke0 ),
+};
+
+/* char: 42 '*' */
+
+static final CoordRec char42_stroke0[] = {
+ new CoordRec((float) 52.381, (float) 71.4286 ),
+ new CoordRec((float) 52.381, (float) 14.2857 ),
+};
+
+static final CoordRec char42_stroke1[] = {
+ new CoordRec((float) 28.5715, (float) 57.1429 ),
+ new CoordRec((float) 76.1905, (float) 28.5714 ),
+};
+
+static final CoordRec char42_stroke2[] = {
+ new CoordRec((float) 76.1905, (float) 57.1429 ),
+ new CoordRec((float) 28.5715, (float) 28.5714 ),
+};
+
+static final StrokeRec char42[] = {
+ new StrokeRec( 2, char42_stroke0 ),
+ new StrokeRec( 2, char42_stroke1 ),
+ new StrokeRec( 2, char42_stroke2 ),
+};
+
+/* char: 43 '+' */
+
+static final CoordRec char43_stroke0[] = {
+ new CoordRec((float) 52.3809, (float) 85.7143 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+};
+
+static final CoordRec char43_stroke1[] = {
+ new CoordRec((float) 9.5238, (float) 42.8571 ),
+ new CoordRec((float) 95.2381, (float) 42.8571 ),
+};
+
+static final StrokeRec char43[] = {
+ new StrokeRec( 2, char43_stroke0 ),
+ new StrokeRec( 2, char43_stroke1 ),
+};
+
+/* char: 44 ',' */
+
+static final CoordRec char44_stroke0[] = {
+ new CoordRec((float) 57.1429, (float) 4.7619 ),
+ new CoordRec((float) 52.381, (float) 0 ),
+ new CoordRec((float) 47.6191, (float) 4.7619 ),
+ new CoordRec((float) 52.381, (float) 9.5238 ),
+ new CoordRec((float) 57.1429, (float) 4.7619 ),
+ new CoordRec((float) 57.1429, (float) -4.7619 ),
+ new CoordRec((float) 52.381, (float) -14.2857 ),
+ new CoordRec((float) 47.6191, (float) -19.0476 ),
+};
+
+static final StrokeRec char44[] = {
+ new StrokeRec( 8, char44_stroke0 ),
+};
+
+/* char: 45 '-' */
+
+static final CoordRec char45_stroke0[] = {
+ new CoordRec((float) 9.5238, (float) 42.8571 ),
+ new CoordRec((float) 95.2381, (float) 42.8571 ),
+};
+
+static final StrokeRec char45[] = {
+ new StrokeRec( 2, char45_stroke0 ),
+};
+
+/* char: 46 '.' */
+
+static final CoordRec char46_stroke0[] = {
+ new CoordRec((float) 52.381, (float) 9.5238 ),
+ new CoordRec((float) 47.6191, (float) 4.7619 ),
+ new CoordRec((float) 52.381, (float) 0 ),
+ new CoordRec((float) 57.1429, (float) 4.7619 ),
+ new CoordRec((float) 52.381, (float) 9.5238 ),
+};
+
+static final StrokeRec char46[] = {
+ new StrokeRec( 5, char46_stroke0 ),
+};
+
+/* char: 47 '/' */
+
+static final CoordRec char47_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) -14.2857 ),
+ new CoordRec((float) 85.7143, (float) 100 ),
+};
+
+static final StrokeRec char47[] = {
+ new StrokeRec( 2, char47_stroke0 ),
+};
+
+/* char: 48 '0' */
+
+static final CoordRec char48_stroke0[] = {
+ new CoordRec((float) 47.619, (float) 100 ),
+ new CoordRec((float) 33.3333, (float) 95.2381 ),
+ new CoordRec((float) 23.8095, (float) 80.9524 ),
+ new CoordRec((float) 19.0476, (float) 57.1429 ),
+ new CoordRec((float) 19.0476, (float) 42.8571 ),
+ new CoordRec((float) 23.8095, (float) 19.0476 ),
+ new CoordRec((float) 33.3333, (float) 4.7619 ),
+ new CoordRec((float) 47.619, (float) 0 ),
+ new CoordRec((float) 57.1428, (float) 0 ),
+ new CoordRec((float) 71.4286, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 19.0476 ),
+ new CoordRec((float) 85.7143, (float) 42.8571 ),
+ new CoordRec((float) 85.7143, (float) 57.1429 ),
+ new CoordRec((float) 80.9524, (float) 80.9524 ),
+ new CoordRec((float) 71.4286, (float) 95.2381 ),
+ new CoordRec((float) 57.1428, (float) 100 ),
+ new CoordRec((float) 47.619, (float) 100 ),
+};
+
+static final StrokeRec char48[] = {
+ new StrokeRec( 17, char48_stroke0 ),
+};
+
+/* char: 49 '1' */
+
+static final CoordRec char49_stroke0[] = {
+ new CoordRec((float) 40.4762, (float) 80.9524 ),
+ new CoordRec((float) 50, (float) 85.7143 ),
+ new CoordRec((float) 64.2857, (float) 100 ),
+ new CoordRec((float) 64.2857, (float) 0 ),
+};
+
+static final StrokeRec char49[] = {
+ new StrokeRec( 4, char49_stroke0 ),
+};
+
+/* char: 50 '2' */
+
+static final CoordRec char50_stroke0[] = {
+ new CoordRec((float) 23.8095, (float) 76.1905 ),
+ new CoordRec((float) 23.8095, (float) 80.9524 ),
+ new CoordRec((float) 28.5714, (float) 90.4762 ),
+ new CoordRec((float) 33.3333, (float) 95.2381 ),
+ new CoordRec((float) 42.8571, (float) 100 ),
+ new CoordRec((float) 61.9047, (float) 100 ),
+ new CoordRec((float) 71.4286, (float) 95.2381 ),
+ new CoordRec((float) 76.1905, (float) 90.4762 ),
+ new CoordRec((float) 80.9524, (float) 80.9524 ),
+ new CoordRec((float) 80.9524, (float) 71.4286 ),
+ new CoordRec((float) 76.1905, (float) 61.9048 ),
+ new CoordRec((float) 66.6666, (float) 47.619 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+ new CoordRec((float) 85.7143, (float) 0 ),
+};
+
+static final StrokeRec char50[] = {
+ new StrokeRec( 14, char50_stroke0 ),
+};
+
+/* char: 51 '3' */
+
+static final CoordRec char51_stroke0[] = {
+ new CoordRec((float) 28.5714, (float) 100 ),
+ new CoordRec((float) 80.9524, (float) 100 ),
+ new CoordRec((float) 52.3809, (float) 61.9048 ),
+ new CoordRec((float) 66.6666, (float) 61.9048 ),
+ new CoordRec((float) 76.1905, (float) 57.1429 ),
+ new CoordRec((float) 80.9524, (float) 52.381 ),
+ new CoordRec((float) 85.7143, (float) 38.0952 ),
+ new CoordRec((float) 85.7143, (float) 28.5714 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+ new CoordRec((float) 71.4286, (float) 4.7619 ),
+ new CoordRec((float) 57.1428, (float) 0 ),
+ new CoordRec((float) 42.8571, (float) 0 ),
+ new CoordRec((float) 28.5714, (float) 4.7619 ),
+ new CoordRec((float) 23.8095, (float) 9.5238 ),
+ new CoordRec((float) 19.0476, (float) 19.0476 ),
+};
+
+static final StrokeRec char51[] = {
+ new StrokeRec( 15, char51_stroke0 ),
+};
+
+/* char: 52 '4' */
+
+static final CoordRec char52_stroke0[] = {
+ new CoordRec((float) 64.2857, (float) 100 ),
+ new CoordRec((float) 16.6667, (float) 33.3333 ),
+ new CoordRec((float) 88.0952, (float) 33.3333 ),
+};
+
+static final CoordRec char52_stroke1[] = {
+ new CoordRec((float) 64.2857, (float) 100 ),
+ new CoordRec((float) 64.2857, (float) 0 ),
+};
+
+static final StrokeRec char52[] = {
+ new StrokeRec( 3, char52_stroke0 ),
+ new StrokeRec( 2, char52_stroke1 ),
+};
+
+/* char: 53 '5' */
+
+static final CoordRec char53_stroke0[] = {
+ new CoordRec((float) 76.1905, (float) 100 ),
+ new CoordRec((float) 28.5714, (float) 100 ),
+ new CoordRec((float) 23.8095, (float) 57.1429 ),
+ new CoordRec((float) 28.5714, (float) 61.9048 ),
+ new CoordRec((float) 42.8571, (float) 66.6667 ),
+ new CoordRec((float) 57.1428, (float) 66.6667 ),
+ new CoordRec((float) 71.4286, (float) 61.9048 ),
+ new CoordRec((float) 80.9524, (float) 52.381 ),
+ new CoordRec((float) 85.7143, (float) 38.0952 ),
+ new CoordRec((float) 85.7143, (float) 28.5714 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+ new CoordRec((float) 71.4286, (float) 4.7619 ),
+ new CoordRec((float) 57.1428, (float) 0 ),
+ new CoordRec((float) 42.8571, (float) 0 ),
+ new CoordRec((float) 28.5714, (float) 4.7619 ),
+ new CoordRec((float) 23.8095, (float) 9.5238 ),
+ new CoordRec((float) 19.0476, (float) 19.0476 ),
+};
+
+static final StrokeRec char53[] = {
+ new StrokeRec( 17, char53_stroke0 ),
+};
+
+/* char: 54 '6' */
+
+static final CoordRec char54_stroke0[] = {
+ new CoordRec((float) 78.5714, (float) 85.7143 ),
+ new CoordRec((float) 73.8096, (float) 95.2381 ),
+ new CoordRec((float) 59.5238, (float) 100 ),
+ new CoordRec((float) 50, (float) 100 ),
+ new CoordRec((float) 35.7143, (float) 95.2381 ),
+ new CoordRec((float) 26.1905, (float) 80.9524 ),
+ new CoordRec((float) 21.4286, (float) 57.1429 ),
+ new CoordRec((float) 21.4286, (float) 33.3333 ),
+ new CoordRec((float) 26.1905, (float) 14.2857 ),
+ new CoordRec((float) 35.7143, (float) 4.7619 ),
+ new CoordRec((float) 50, (float) 0 ),
+ new CoordRec((float) 54.7619, (float) 0 ),
+ new CoordRec((float) 69.0476, (float) 4.7619 ),
+ new CoordRec((float) 78.5714, (float) 14.2857 ),
+ new CoordRec((float) 83.3334, (float) 28.5714 ),
+ new CoordRec((float) 83.3334, (float) 33.3333 ),
+ new CoordRec((float) 78.5714, (float) 47.619 ),
+ new CoordRec((float) 69.0476, (float) 57.1429 ),
+ new CoordRec((float) 54.7619, (float) 61.9048 ),
+ new CoordRec((float) 50, (float) 61.9048 ),
+ new CoordRec((float) 35.7143, (float) 57.1429 ),
+ new CoordRec((float) 26.1905, (float) 47.619 ),
+ new CoordRec((float) 21.4286, (float) 33.3333 ),
+};
+
+static final StrokeRec char54[] = {
+ new StrokeRec( 23, char54_stroke0 ),
+};
+
+/* char: 55 '7' */
+
+static final CoordRec char55_stroke0[] = {
+ new CoordRec((float) 85.7143, (float) 100 ),
+ new CoordRec((float) 38.0952, (float) 0 ),
+};
+
+static final CoordRec char55_stroke1[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 85.7143, (float) 100 ),
+};
+
+static final StrokeRec char55[] = {
+ new StrokeRec( 2, char55_stroke0 ),
+ new StrokeRec( 2, char55_stroke1 ),
+};
+
+/* char: 56 '8' */
+
+static final CoordRec char56_stroke0[] = {
+ new CoordRec((float) 42.8571, (float) 100 ),
+ new CoordRec((float) 28.5714, (float) 95.2381 ),
+ new CoordRec((float) 23.8095, (float) 85.7143 ),
+ new CoordRec((float) 23.8095, (float) 76.1905 ),
+ new CoordRec((float) 28.5714, (float) 66.6667 ),
+ new CoordRec((float) 38.0952, (float) 61.9048 ),
+ new CoordRec((float) 57.1428, (float) 57.1429 ),
+ new CoordRec((float) 71.4286, (float) 52.381 ),
+ new CoordRec((float) 80.9524, (float) 42.8571 ),
+ new CoordRec((float) 85.7143, (float) 33.3333 ),
+ new CoordRec((float) 85.7143, (float) 19.0476 ),
+ new CoordRec((float) 80.9524, (float) 9.5238 ),
+ new CoordRec((float) 76.1905, (float) 4.7619 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 42.8571, (float) 0 ),
+ new CoordRec((float) 28.5714, (float) 4.7619 ),
+ new CoordRec((float) 23.8095, (float) 9.5238 ),
+ new CoordRec((float) 19.0476, (float) 19.0476 ),
+ new CoordRec((float) 19.0476, (float) 33.3333 ),
+ new CoordRec((float) 23.8095, (float) 42.8571 ),
+ new CoordRec((float) 33.3333, (float) 52.381 ),
+ new CoordRec((float) 47.619, (float) 57.1429 ),
+ new CoordRec((float) 66.6666, (float) 61.9048 ),
+ new CoordRec((float) 76.1905, (float) 66.6667 ),
+ new CoordRec((float) 80.9524, (float) 76.1905 ),
+ new CoordRec((float) 80.9524, (float) 85.7143 ),
+ new CoordRec((float) 76.1905, (float) 95.2381 ),
+ new CoordRec((float) 61.9047, (float) 100 ),
+ new CoordRec((float) 42.8571, (float) 100 ),
+};
+
+static final StrokeRec char56[] = {
+ new StrokeRec( 29, char56_stroke0 ),
+};
+
+/* char: 57 '9' */
+
+static final CoordRec char57_stroke0[] = {
+ new CoordRec((float) 83.3334, (float) 66.6667 ),
+ new CoordRec((float) 78.5714, (float) 52.381 ),
+ new CoordRec((float) 69.0476, (float) 42.8571 ),
+ new CoordRec((float) 54.7619, (float) 38.0952 ),
+ new CoordRec((float) 50, (float) 38.0952 ),
+ new CoordRec((float) 35.7143, (float) 42.8571 ),
+ new CoordRec((float) 26.1905, (float) 52.381 ),
+ new CoordRec((float) 21.4286, (float) 66.6667 ),
+ new CoordRec((float) 21.4286, (float) 71.4286 ),
+ new CoordRec((float) 26.1905, (float) 85.7143 ),
+ new CoordRec((float) 35.7143, (float) 95.2381 ),
+ new CoordRec((float) 50, (float) 100 ),
+ new CoordRec((float) 54.7619, (float) 100 ),
+ new CoordRec((float) 69.0476, (float) 95.2381 ),
+ new CoordRec((float) 78.5714, (float) 85.7143 ),
+ new CoordRec((float) 83.3334, (float) 66.6667 ),
+ new CoordRec((float) 83.3334, (float) 42.8571 ),
+ new CoordRec((float) 78.5714, (float) 19.0476 ),
+ new CoordRec((float) 69.0476, (float) 4.7619 ),
+ new CoordRec((float) 54.7619, (float) 0 ),
+ new CoordRec((float) 45.2381, (float) 0 ),
+ new CoordRec((float) 30.9524, (float) 4.7619 ),
+ new CoordRec((float) 26.1905, (float) 14.2857 ),
+};
+
+static final StrokeRec char57[] = {
+ new StrokeRec( 23, char57_stroke0 ),
+};
+
+/* char: 58 ':' */
+
+static final CoordRec char58_stroke0[] = {
+ new CoordRec((float) 52.381, (float) 66.6667 ),
+ new CoordRec((float) 47.6191, (float) 61.9048 ),
+ new CoordRec((float) 52.381, (float) 57.1429 ),
+ new CoordRec((float) 57.1429, (float) 61.9048 ),
+ new CoordRec((float) 52.381, (float) 66.6667 ),
+};
+
+static final CoordRec char58_stroke1[] = {
+ new CoordRec((float) 52.381, (float) 9.5238 ),
+ new CoordRec((float) 47.6191, (float) 4.7619 ),
+ new CoordRec((float) 52.381, (float) 0 ),
+ new CoordRec((float) 57.1429, (float) 4.7619 ),
+ new CoordRec((float) 52.381, (float) 9.5238 ),
+};
+
+static final StrokeRec char58[] = {
+ new StrokeRec( 5, char58_stroke0 ),
+ new StrokeRec( 5, char58_stroke1 ),
+};
+
+/* char: 59 ';' */
+
+static final CoordRec char59_stroke0[] = {
+ new CoordRec((float) 52.381, (float) 66.6667 ),
+ new CoordRec((float) 47.6191, (float) 61.9048 ),
+ new CoordRec((float) 52.381, (float) 57.1429 ),
+ new CoordRec((float) 57.1429, (float) 61.9048 ),
+ new CoordRec((float) 52.381, (float) 66.6667 ),
+};
+
+static final CoordRec char59_stroke1[] = {
+ new CoordRec((float) 57.1429, (float) 4.7619 ),
+ new CoordRec((float) 52.381, (float) 0 ),
+ new CoordRec((float) 47.6191, (float) 4.7619 ),
+ new CoordRec((float) 52.381, (float) 9.5238 ),
+ new CoordRec((float) 57.1429, (float) 4.7619 ),
+ new CoordRec((float) 57.1429, (float) -4.7619 ),
+ new CoordRec((float) 52.381, (float) -14.2857 ),
+ new CoordRec((float) 47.6191, (float) -19.0476 ),
+};
+
+static final StrokeRec char59[] = {
+ new StrokeRec( 5, char59_stroke0 ),
+ new StrokeRec( 8, char59_stroke1 ),
+};
+
+/* char: 60 '<' */
+
+static final CoordRec char60_stroke0[] = {
+ new CoordRec((float) 90.4762, (float) 85.7143 ),
+ new CoordRec((float) 14.2857, (float) 42.8571 ),
+ new CoordRec((float) 90.4762, (float) 0 ),
+};
+
+static final StrokeRec char60[] = {
+ new StrokeRec( 3, char60_stroke0 ),
+};
+
+/* char: 61 '=' */
+
+static final CoordRec char61_stroke0[] = {
+ new CoordRec((float) 9.5238, (float) 57.1429 ),
+ new CoordRec((float) 95.2381, (float) 57.1429 ),
+};
+
+static final CoordRec char61_stroke1[] = {
+ new CoordRec((float) 9.5238, (float) 28.5714 ),
+ new CoordRec((float) 95.2381, (float) 28.5714 ),
+};
+
+static final StrokeRec char61[] = {
+ new StrokeRec( 2, char61_stroke0 ),
+ new StrokeRec( 2, char61_stroke1 ),
+};
+
+/* char: 62 '>' */
+
+static final CoordRec char62_stroke0[] = {
+ new CoordRec((float) 14.2857, (float) 85.7143 ),
+ new CoordRec((float) 90.4762, (float) 42.8571 ),
+ new CoordRec((float) 14.2857, (float) 0 ),
+};
+
+static final StrokeRec char62[] = {
+ new StrokeRec( 3, char62_stroke0 ),
+};
+
+/* char: 63 '?' */
+
+static final CoordRec char63_stroke0[] = {
+ new CoordRec((float) 23.8095, (float) 76.1905 ),
+ new CoordRec((float) 23.8095, (float) 80.9524 ),
+ new CoordRec((float) 28.5714, (float) 90.4762 ),
+ new CoordRec((float) 33.3333, (float) 95.2381 ),
+ new CoordRec((float) 42.8571, (float) 100 ),
+ new CoordRec((float) 61.9047, (float) 100 ),
+ new CoordRec((float) 71.4285, (float) 95.2381 ),
+ new CoordRec((float) 76.1905, (float) 90.4762 ),
+ new CoordRec((float) 80.9524, (float) 80.9524 ),
+ new CoordRec((float) 80.9524, (float) 71.4286 ),
+ new CoordRec((float) 76.1905, (float) 61.9048 ),
+ new CoordRec((float) 71.4285, (float) 57.1429 ),
+ new CoordRec((float) 52.3809, (float) 47.619 ),
+ new CoordRec((float) 52.3809, (float) 33.3333 ),
+};
+
+static final CoordRec char63_stroke1[] = {
+ new CoordRec((float) 52.3809, (float) 9.5238 ),
+ new CoordRec((float) 47.619, (float) 4.7619 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+ new CoordRec((float) 57.1428, (float) 4.7619 ),
+ new CoordRec((float) 52.3809, (float) 9.5238 ),
+};
+
+static final StrokeRec char63[] = {
+ new StrokeRec( 14, char63_stroke0 ),
+ new StrokeRec( 5, char63_stroke1 ),
+};
+
+/* char: 64 '@' */
+
+static final CoordRec char64_stroke0[] = {
+ new CoordRec((float) 64.2857, (float) 52.381 ),
+ new CoordRec((float) 54.7619, (float) 57.1429 ),
+ new CoordRec((float) 45.2381, (float) 57.1429 ),
+ new CoordRec((float) 40.4762, (float) 47.619 ),
+ new CoordRec((float) 40.4762, (float) 42.8571 ),
+ new CoordRec((float) 45.2381, (float) 33.3333 ),
+ new CoordRec((float) 54.7619, (float) 33.3333 ),
+ new CoordRec((float) 64.2857, (float) 38.0952 ),
+};
+
+static final CoordRec char64_stroke1[] = {
+ new CoordRec((float) 64.2857, (float) 57.1429 ),
+ new CoordRec((float) 64.2857, (float) 38.0952 ),
+ new CoordRec((float) 69.0476, (float) 33.3333 ),
+ new CoordRec((float) 78.5714, (float) 33.3333 ),
+ new CoordRec((float) 83.3334, (float) 42.8571 ),
+ new CoordRec((float) 83.3334, (float) 47.619 ),
+ new CoordRec((float) 78.5714, (float) 61.9048 ),
+ new CoordRec((float) 69.0476, (float) 71.4286 ),
+ new CoordRec((float) 54.7619, (float) 76.1905 ),
+ new CoordRec((float) 50, (float) 76.1905 ),
+ new CoordRec((float) 35.7143, (float) 71.4286 ),
+ new CoordRec((float) 26.1905, (float) 61.9048 ),
+ new CoordRec((float) 21.4286, (float) 47.619 ),
+ new CoordRec((float) 21.4286, (float) 42.8571 ),
+ new CoordRec((float) 26.1905, (float) 28.5714 ),
+ new CoordRec((float) 35.7143, (float) 19.0476 ),
+ new CoordRec((float) 50, (float) 14.2857 ),
+ new CoordRec((float) 54.7619, (float) 14.2857 ),
+ new CoordRec((float) 69.0476, (float) 19.0476 ),
+};
+
+static final StrokeRec char64[] = {
+ new StrokeRec( 8, char64_stroke0 ),
+ new StrokeRec( 19, char64_stroke1 ),
+};
+
+/* char: 65 'A' */
+
+static final CoordRec char65_stroke0[] = {
+ new CoordRec((float) 52.3809, (float) 100 ),
+ new CoordRec((float) 14.2857, (float) 0 ),
+};
+
+static final CoordRec char65_stroke1[] = {
+ new CoordRec((float) 52.3809, (float) 100 ),
+ new CoordRec((float) 90.4762, (float) 0 ),
+};
+
+static final CoordRec char65_stroke2[] = {
+ new CoordRec((float) 28.5714, (float) 33.3333 ),
+ new CoordRec((float) 76.1905, (float) 33.3333 ),
+};
+
+static final StrokeRec char65[] = {
+ new StrokeRec( 2, char65_stroke0 ),
+ new StrokeRec( 2, char65_stroke1 ),
+ new StrokeRec( 2, char65_stroke2 ),
+};
+
+/* char: 66 'B' */
+
+static final CoordRec char66_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final CoordRec char66_stroke1[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 61.9047, (float) 100 ),
+ new CoordRec((float) 76.1905, (float) 95.2381 ),
+ new CoordRec((float) 80.9524, (float) 90.4762 ),
+ new CoordRec((float) 85.7143, (float) 80.9524 ),
+ new CoordRec((float) 85.7143, (float) 71.4286 ),
+ new CoordRec((float) 80.9524, (float) 61.9048 ),
+ new CoordRec((float) 76.1905, (float) 57.1429 ),
+ new CoordRec((float) 61.9047, (float) 52.381 ),
+};
+
+static final CoordRec char66_stroke2[] = {
+ new CoordRec((float) 19.0476, (float) 52.381 ),
+ new CoordRec((float) 61.9047, (float) 52.381 ),
+ new CoordRec((float) 76.1905, (float) 47.619 ),
+ new CoordRec((float) 80.9524, (float) 42.8571 ),
+ new CoordRec((float) 85.7143, (float) 33.3333 ),
+ new CoordRec((float) 85.7143, (float) 19.0476 ),
+ new CoordRec((float) 80.9524, (float) 9.5238 ),
+ new CoordRec((float) 76.1905, (float) 4.7619 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final StrokeRec char66[] = {
+ new StrokeRec( 2, char66_stroke0 ),
+ new StrokeRec( 9, char66_stroke1 ),
+ new StrokeRec( 10, char66_stroke2 ),
+};
+
+/* char: 67 'C' */
+
+static final CoordRec char67_stroke0[] = {
+ new CoordRec((float) 88.0952, (float) 76.1905 ),
+ new CoordRec((float) 83.3334, (float) 85.7143 ),
+ new CoordRec((float) 73.8096, (float) 95.2381 ),
+ new CoordRec((float) 64.2857, (float) 100 ),
+ new CoordRec((float) 45.2381, (float) 100 ),
+ new CoordRec((float) 35.7143, (float) 95.2381 ),
+ new CoordRec((float) 26.1905, (float) 85.7143 ),
+ new CoordRec((float) 21.4286, (float) 76.1905 ),
+ new CoordRec((float) 16.6667, (float) 61.9048 ),
+ new CoordRec((float) 16.6667, (float) 38.0952 ),
+ new CoordRec((float) 21.4286, (float) 23.8095 ),
+ new CoordRec((float) 26.1905, (float) 14.2857 ),
+ new CoordRec((float) 35.7143, (float) 4.7619 ),
+ new CoordRec((float) 45.2381, (float) 0 ),
+ new CoordRec((float) 64.2857, (float) 0 ),
+ new CoordRec((float) 73.8096, (float) 4.7619 ),
+ new CoordRec((float) 83.3334, (float) 14.2857 ),
+ new CoordRec((float) 88.0952, (float) 23.8095 ),
+};
+
+static final StrokeRec char67[] = {
+ new StrokeRec( 18, char67_stroke0 ),
+};
+
+/* char: 68 'D' */
+
+static final CoordRec char68_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final CoordRec char68_stroke1[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 52.3809, (float) 100 ),
+ new CoordRec((float) 66.6666, (float) 95.2381 ),
+ new CoordRec((float) 76.1905, (float) 85.7143 ),
+ new CoordRec((float) 80.9524, (float) 76.1905 ),
+ new CoordRec((float) 85.7143, (float) 61.9048 ),
+ new CoordRec((float) 85.7143, (float) 38.0952 ),
+ new CoordRec((float) 80.9524, (float) 23.8095 ),
+ new CoordRec((float) 76.1905, (float) 14.2857 ),
+ new CoordRec((float) 66.6666, (float) 4.7619 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final StrokeRec char68[] = {
+ new StrokeRec( 2, char68_stroke0 ),
+ new StrokeRec( 12, char68_stroke1 ),
+};
+
+/* char: 69 'E' */
+
+static final CoordRec char69_stroke0[] = {
+ new CoordRec((float) 21.4286, (float) 100 ),
+ new CoordRec((float) 21.4286, (float) 0 ),
+};
+
+static final CoordRec char69_stroke1[] = {
+ new CoordRec((float) 21.4286, (float) 100 ),
+ new CoordRec((float) 83.3334, (float) 100 ),
+};
+
+static final CoordRec char69_stroke2[] = {
+ new CoordRec((float) 21.4286, (float) 52.381 ),
+ new CoordRec((float) 59.5238, (float) 52.381 ),
+};
+
+static final CoordRec char69_stroke3[] = {
+ new CoordRec((float) 21.4286, (float) 0 ),
+ new CoordRec((float) 83.3334, (float) 0 ),
+};
+
+static final StrokeRec char69[] = {
+ new StrokeRec( 2, char69_stroke0 ),
+ new StrokeRec( 2, char69_stroke1 ),
+ new StrokeRec( 2, char69_stroke2 ),
+ new StrokeRec( 2, char69_stroke3 ),
+};
+
+/* char: 70 'F' */
+
+static final CoordRec char70_stroke0[] = {
+ new CoordRec((float) 21.4286, (float) 100 ),
+ new CoordRec((float) 21.4286, (float) 0 ),
+};
+
+static final CoordRec char70_stroke1[] = {
+ new CoordRec((float) 21.4286, (float) 100 ),
+ new CoordRec((float) 83.3334, (float) 100 ),
+};
+
+static final CoordRec char70_stroke2[] = {
+ new CoordRec((float) 21.4286, (float) 52.381 ),
+ new CoordRec((float) 59.5238, (float) 52.381 ),
+};
+
+static final StrokeRec char70[] = {
+ new StrokeRec( 2, char70_stroke0 ),
+ new StrokeRec( 2, char70_stroke1 ),
+ new StrokeRec( 2, char70_stroke2 ),
+};
+
+/* char: 71 'G' */
+
+static final CoordRec char71_stroke0[] = {
+ new CoordRec((float) 88.0952, (float) 76.1905 ),
+ new CoordRec((float) 83.3334, (float) 85.7143 ),
+ new CoordRec((float) 73.8096, (float) 95.2381 ),
+ new CoordRec((float) 64.2857, (float) 100 ),
+ new CoordRec((float) 45.2381, (float) 100 ),
+ new CoordRec((float) 35.7143, (float) 95.2381 ),
+ new CoordRec((float) 26.1905, (float) 85.7143 ),
+ new CoordRec((float) 21.4286, (float) 76.1905 ),
+ new CoordRec((float) 16.6667, (float) 61.9048 ),
+ new CoordRec((float) 16.6667, (float) 38.0952 ),
+ new CoordRec((float) 21.4286, (float) 23.8095 ),
+ new CoordRec((float) 26.1905, (float) 14.2857 ),
+ new CoordRec((float) 35.7143, (float) 4.7619 ),
+ new CoordRec((float) 45.2381, (float) 0 ),
+ new CoordRec((float) 64.2857, (float) 0 ),
+ new CoordRec((float) 73.8096, (float) 4.7619 ),
+ new CoordRec((float) 83.3334, (float) 14.2857 ),
+ new CoordRec((float) 88.0952, (float) 23.8095 ),
+ new CoordRec((float) 88.0952, (float) 38.0952 ),
+};
+
+static final CoordRec char71_stroke1[] = {
+ new CoordRec((float) 64.2857, (float) 38.0952 ),
+ new CoordRec((float) 88.0952, (float) 38.0952 ),
+};
+
+static final StrokeRec char71[] = {
+ new StrokeRec( 19, char71_stroke0 ),
+ new StrokeRec( 2, char71_stroke1 ),
+};
+
+/* char: 72 'H' */
+
+static final CoordRec char72_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final CoordRec char72_stroke1[] = {
+ new CoordRec((float) 85.7143, (float) 100 ),
+ new CoordRec((float) 85.7143, (float) 0 ),
+};
+
+static final CoordRec char72_stroke2[] = {
+ new CoordRec((float) 19.0476, (float) 52.381 ),
+ new CoordRec((float) 85.7143, (float) 52.381 ),
+};
+
+static final StrokeRec char72[] = {
+ new StrokeRec( 2, char72_stroke0 ),
+ new StrokeRec( 2, char72_stroke1 ),
+ new StrokeRec( 2, char72_stroke2 ),
+};
+
+/* char: 73 'I' */
+
+static final CoordRec char73_stroke0[] = {
+ new CoordRec((float) 52.381, (float) 100 ),
+ new CoordRec((float) 52.381, (float) 0 ),
+};
+
+static final StrokeRec char73[] = {
+ new StrokeRec( 2, char73_stroke0 ),
+};
+
+/* char: 74 'J' */
+
+static final CoordRec char74_stroke0[] = {
+ new CoordRec((float) 76.1905, (float) 100 ),
+ new CoordRec((float) 76.1905, (float) 23.8095 ),
+ new CoordRec((float) 71.4286, (float) 9.5238 ),
+ new CoordRec((float) 66.6667, (float) 4.7619 ),
+ new CoordRec((float) 57.1429, (float) 0 ),
+ new CoordRec((float) 47.6191, (float) 0 ),
+ new CoordRec((float) 38.0953, (float) 4.7619 ),
+ new CoordRec((float) 33.3334, (float) 9.5238 ),
+ new CoordRec((float) 28.5715, (float) 23.8095 ),
+ new CoordRec((float) 28.5715, (float) 33.3333 ),
+};
+
+static final StrokeRec char74[] = {
+ new StrokeRec( 10, char74_stroke0 ),
+};
+
+/* char: 75 'K' */
+
+static final CoordRec char75_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final CoordRec char75_stroke1[] = {
+ new CoordRec((float) 85.7143, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 33.3333 ),
+};
+
+static final CoordRec char75_stroke2[] = {
+ new CoordRec((float) 42.8571, (float) 57.1429 ),
+ new CoordRec((float) 85.7143, (float) 0 ),
+};
+
+static final StrokeRec char75[] = {
+ new StrokeRec( 2, char75_stroke0 ),
+ new StrokeRec( 2, char75_stroke1 ),
+ new StrokeRec( 2, char75_stroke2 ),
+};
+
+/* char: 76 'L' */
+
+static final CoordRec char76_stroke0[] = {
+ new CoordRec((float) 23.8095, (float) 100 ),
+ new CoordRec((float) 23.8095, (float) 0 ),
+};
+
+static final CoordRec char76_stroke1[] = {
+ new CoordRec((float) 23.8095, (float) 0 ),
+ new CoordRec((float) 80.9524, (float) 0 ),
+};
+
+static final StrokeRec char76[] = {
+ new StrokeRec( 2, char76_stroke0 ),
+ new StrokeRec( 2, char76_stroke1 ),
+};
+
+/* char: 77 'M' */
+
+static final CoordRec char77_stroke0[] = {
+ new CoordRec((float) 14.2857, (float) 100 ),
+ new CoordRec((float) 14.2857, (float) 0 ),
+};
+
+static final CoordRec char77_stroke1[] = {
+ new CoordRec((float) 14.2857, (float) 100 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+};
+
+static final CoordRec char77_stroke2[] = {
+ new CoordRec((float) 90.4762, (float) 100 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+};
+
+static final CoordRec char77_stroke3[] = {
+ new CoordRec((float) 90.4762, (float) 100 ),
+ new CoordRec((float) 90.4762, (float) 0 ),
+};
+
+static final StrokeRec char77[] = {
+ new StrokeRec( 2, char77_stroke0 ),
+ new StrokeRec( 2, char77_stroke1 ),
+ new StrokeRec( 2, char77_stroke2 ),
+ new StrokeRec( 2, char77_stroke3 ),
+};
+
+/* char: 78 'N' */
+
+static final CoordRec char78_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final CoordRec char78_stroke1[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 85.7143, (float) 0 ),
+};
+
+static final CoordRec char78_stroke2[] = {
+ new CoordRec((float) 85.7143, (float) 100 ),
+ new CoordRec((float) 85.7143, (float) 0 ),
+};
+
+static final StrokeRec char78[] = {
+ new StrokeRec( 2, char78_stroke0 ),
+ new StrokeRec( 2, char78_stroke1 ),
+ new StrokeRec( 2, char78_stroke2 ),
+};
+
+/* char: 79 'O' */
+
+static final CoordRec char79_stroke0[] = {
+ new CoordRec((float) 42.8571, (float) 100 ),
+ new CoordRec((float) 33.3333, (float) 95.2381 ),
+ new CoordRec((float) 23.8095, (float) 85.7143 ),
+ new CoordRec((float) 19.0476, (float) 76.1905 ),
+ new CoordRec((float) 14.2857, (float) 61.9048 ),
+ new CoordRec((float) 14.2857, (float) 38.0952 ),
+ new CoordRec((float) 19.0476, (float) 23.8095 ),
+ new CoordRec((float) 23.8095, (float) 14.2857 ),
+ new CoordRec((float) 33.3333, (float) 4.7619 ),
+ new CoordRec((float) 42.8571, (float) 0 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 71.4286, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+ new CoordRec((float) 85.7143, (float) 23.8095 ),
+ new CoordRec((float) 90.4762, (float) 38.0952 ),
+ new CoordRec((float) 90.4762, (float) 61.9048 ),
+ new CoordRec((float) 85.7143, (float) 76.1905 ),
+ new CoordRec((float) 80.9524, (float) 85.7143 ),
+ new CoordRec((float) 71.4286, (float) 95.2381 ),
+ new CoordRec((float) 61.9047, (float) 100 ),
+ new CoordRec((float) 42.8571, (float) 100 ),
+};
+
+static final StrokeRec char79[] = {
+ new StrokeRec( 21, char79_stroke0 ),
+};
+
+/* char: 80 'P' */
+
+static final CoordRec char80_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final CoordRec char80_stroke1[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 61.9047, (float) 100 ),
+ new CoordRec((float) 76.1905, (float) 95.2381 ),
+ new CoordRec((float) 80.9524, (float) 90.4762 ),
+ new CoordRec((float) 85.7143, (float) 80.9524 ),
+ new CoordRec((float) 85.7143, (float) 66.6667 ),
+ new CoordRec((float) 80.9524, (float) 57.1429 ),
+ new CoordRec((float) 76.1905, (float) 52.381 ),
+ new CoordRec((float) 61.9047, (float) 47.619 ),
+ new CoordRec((float) 19.0476, (float) 47.619 ),
+};
+
+static final StrokeRec char80[] = {
+ new StrokeRec( 2, char80_stroke0 ),
+ new StrokeRec( 10, char80_stroke1 ),
+};
+
+/* char: 81 'Q' */
+
+static final CoordRec char81_stroke0[] = {
+ new CoordRec((float) 42.8571, (float) 100 ),
+ new CoordRec((float) 33.3333, (float) 95.2381 ),
+ new CoordRec((float) 23.8095, (float) 85.7143 ),
+ new CoordRec((float) 19.0476, (float) 76.1905 ),
+ new CoordRec((float) 14.2857, (float) 61.9048 ),
+ new CoordRec((float) 14.2857, (float) 38.0952 ),
+ new CoordRec((float) 19.0476, (float) 23.8095 ),
+ new CoordRec((float) 23.8095, (float) 14.2857 ),
+ new CoordRec((float) 33.3333, (float) 4.7619 ),
+ new CoordRec((float) 42.8571, (float) 0 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 71.4286, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+ new CoordRec((float) 85.7143, (float) 23.8095 ),
+ new CoordRec((float) 90.4762, (float) 38.0952 ),
+ new CoordRec((float) 90.4762, (float) 61.9048 ),
+ new CoordRec((float) 85.7143, (float) 76.1905 ),
+ new CoordRec((float) 80.9524, (float) 85.7143 ),
+ new CoordRec((float) 71.4286, (float) 95.2381 ),
+ new CoordRec((float) 61.9047, (float) 100 ),
+ new CoordRec((float) 42.8571, (float) 100 ),
+};
+
+static final CoordRec char81_stroke1[] = {
+ new CoordRec((float) 57.1428, (float) 19.0476 ),
+ new CoordRec((float) 85.7143, (float) -9.5238 ),
+};
+
+static final StrokeRec char81[] = {
+ new StrokeRec( 21, char81_stroke0 ),
+ new StrokeRec( 2, char81_stroke1 ),
+};
+
+/* char: 82 'R' */
+
+static final CoordRec char82_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final CoordRec char82_stroke1[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 61.9047, (float) 100 ),
+ new CoordRec((float) 76.1905, (float) 95.2381 ),
+ new CoordRec((float) 80.9524, (float) 90.4762 ),
+ new CoordRec((float) 85.7143, (float) 80.9524 ),
+ new CoordRec((float) 85.7143, (float) 71.4286 ),
+ new CoordRec((float) 80.9524, (float) 61.9048 ),
+ new CoordRec((float) 76.1905, (float) 57.1429 ),
+ new CoordRec((float) 61.9047, (float) 52.381 ),
+ new CoordRec((float) 19.0476, (float) 52.381 ),
+};
+
+static final CoordRec char82_stroke2[] = {
+ new CoordRec((float) 52.3809, (float) 52.381 ),
+ new CoordRec((float) 85.7143, (float) 0 ),
+};
+
+static final StrokeRec char82[] = {
+ new StrokeRec( 2, char82_stroke0 ),
+ new StrokeRec( 10, char82_stroke1 ),
+ new StrokeRec( 2, char82_stroke2 ),
+};
+
+/* char: 83 'S' */
+
+static final CoordRec char83_stroke0[] = {
+ new CoordRec((float) 85.7143, (float) 85.7143 ),
+ new CoordRec((float) 76.1905, (float) 95.2381 ),
+ new CoordRec((float) 61.9047, (float) 100 ),
+ new CoordRec((float) 42.8571, (float) 100 ),
+ new CoordRec((float) 28.5714, (float) 95.2381 ),
+ new CoordRec((float) 19.0476, (float) 85.7143 ),
+ new CoordRec((float) 19.0476, (float) 76.1905 ),
+ new CoordRec((float) 23.8095, (float) 66.6667 ),
+ new CoordRec((float) 28.5714, (float) 61.9048 ),
+ new CoordRec((float) 38.0952, (float) 57.1429 ),
+ new CoordRec((float) 66.6666, (float) 47.619 ),
+ new CoordRec((float) 76.1905, (float) 42.8571 ),
+ new CoordRec((float) 80.9524, (float) 38.0952 ),
+ new CoordRec((float) 85.7143, (float) 28.5714 ),
+ new CoordRec((float) 85.7143, (float) 14.2857 ),
+ new CoordRec((float) 76.1905, (float) 4.7619 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 42.8571, (float) 0 ),
+ new CoordRec((float) 28.5714, (float) 4.7619 ),
+ new CoordRec((float) 19.0476, (float) 14.2857 ),
+};
+
+static final StrokeRec char83[] = {
+ new StrokeRec( 20, char83_stroke0 ),
+};
+
+/* char: 84 'T' */
+
+static final CoordRec char84_stroke0[] = {
+ new CoordRec((float) 52.3809, (float) 100 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+};
+
+static final CoordRec char84_stroke1[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 85.7143, (float) 100 ),
+};
+
+static final StrokeRec char84[] = {
+ new StrokeRec( 2, char84_stroke0 ),
+ new StrokeRec( 2, char84_stroke1 ),
+};
+
+/* char: 85 'U' */
+
+static final CoordRec char85_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 28.5714 ),
+ new CoordRec((float) 23.8095, (float) 14.2857 ),
+ new CoordRec((float) 33.3333, (float) 4.7619 ),
+ new CoordRec((float) 47.619, (float) 0 ),
+ new CoordRec((float) 57.1428, (float) 0 ),
+ new CoordRec((float) 71.4286, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+ new CoordRec((float) 85.7143, (float) 28.5714 ),
+ new CoordRec((float) 85.7143, (float) 100 ),
+};
+
+static final StrokeRec char85[] = {
+ new StrokeRec( 10, char85_stroke0 ),
+};
+
+/* char: 86 'V' */
+
+static final CoordRec char86_stroke0[] = {
+ new CoordRec((float) 14.2857, (float) 100 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+};
+
+static final CoordRec char86_stroke1[] = {
+ new CoordRec((float) 90.4762, (float) 100 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+};
+
+static final StrokeRec char86[] = {
+ new StrokeRec( 2, char86_stroke0 ),
+ new StrokeRec( 2, char86_stroke1 ),
+};
+
+/* char: 87 'W' */
+
+static final CoordRec char87_stroke0[] = {
+ new CoordRec((float) 4.7619, (float) 100 ),
+ new CoordRec((float) 28.5714, (float) 0 ),
+};
+
+static final CoordRec char87_stroke1[] = {
+ new CoordRec((float) 52.3809, (float) 100 ),
+ new CoordRec((float) 28.5714, (float) 0 ),
+};
+
+static final CoordRec char87_stroke2[] = {
+ new CoordRec((float) 52.3809, (float) 100 ),
+ new CoordRec((float) 76.1905, (float) 0 ),
+};
+
+static final CoordRec char87_stroke3[] = {
+ new CoordRec((float) 100, (float) 100 ),
+ new CoordRec((float) 76.1905, (float) 0 ),
+};
+
+static final StrokeRec char87[] = {
+ new StrokeRec( 2, char87_stroke0 ),
+ new StrokeRec( 2, char87_stroke1 ),
+ new StrokeRec( 2, char87_stroke2 ),
+ new StrokeRec( 2, char87_stroke3 ),
+};
+
+/* char: 88 'X' */
+
+static final CoordRec char88_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 85.7143, (float) 0 ),
+};
+
+static final CoordRec char88_stroke1[] = {
+ new CoordRec((float) 85.7143, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final StrokeRec char88[] = {
+ new StrokeRec( 2, char88_stroke0 ),
+ new StrokeRec( 2, char88_stroke1 ),
+};
+
+/* char: 89 'Y' */
+
+static final CoordRec char89_stroke0[] = {
+ new CoordRec((float) 14.2857, (float) 100 ),
+ new CoordRec((float) 52.3809, (float) 52.381 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+};
+
+static final CoordRec char89_stroke1[] = {
+ new CoordRec((float) 90.4762, (float) 100 ),
+ new CoordRec((float) 52.3809, (float) 52.381 ),
+};
+
+static final StrokeRec char89[] = {
+ new StrokeRec( 3, char89_stroke0 ),
+ new StrokeRec( 2, char89_stroke1 ),
+};
+
+/* char: 90 'Z' */
+
+static final CoordRec char90_stroke0[] = {
+ new CoordRec((float) 85.7143, (float) 100 ),
+ new CoordRec((float) 19.0476, (float) 0 ),
+};
+
+static final CoordRec char90_stroke1[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 85.7143, (float) 100 ),
+};
+
+static final CoordRec char90_stroke2[] = {
+ new CoordRec((float) 19.0476, (float) 0 ),
+ new CoordRec((float) 85.7143, (float) 0 ),
+};
+
+static final StrokeRec char90[] = {
+ new StrokeRec( 2, char90_stroke0 ),
+ new StrokeRec( 2, char90_stroke1 ),
+ new StrokeRec( 2, char90_stroke2 ),
+};
+
+/* char: 91 '[' */
+
+static final CoordRec char91_stroke0[] = {
+ new CoordRec((float) 35.7143, (float) 119.048 ),
+ new CoordRec((float) 35.7143, (float) -33.3333 ),
+};
+
+static final CoordRec char91_stroke1[] = {
+ new CoordRec((float) 40.4762, (float) 119.048 ),
+ new CoordRec((float) 40.4762, (float) -33.3333 ),
+};
+
+static final CoordRec char91_stroke2[] = {
+ new CoordRec((float) 35.7143, (float) 119.048 ),
+ new CoordRec((float) 69.0476, (float) 119.048 ),
+};
+
+static final CoordRec char91_stroke3[] = {
+ new CoordRec((float) 35.7143, (float) -33.3333 ),
+ new CoordRec((float) 69.0476, (float) -33.3333 ),
+};
+
+static final StrokeRec char91[] = {
+ new StrokeRec( 2, char91_stroke0 ),
+ new StrokeRec( 2, char91_stroke1 ),
+ new StrokeRec( 2, char91_stroke2 ),
+ new StrokeRec( 2, char91_stroke3 ),
+};
+
+/* char: 92 '\' */
+
+static final CoordRec char92_stroke0[] = {
+ new CoordRec((float) 19.0476, (float) 100 ),
+ new CoordRec((float) 85.7143, (float) -14.2857 ),
+};
+
+static final StrokeRec char92[] = {
+ new StrokeRec( 2, char92_stroke0 ),
+};
+
+/* char: 93 ']' */
+
+static final CoordRec char93_stroke0[] = {
+ new CoordRec((float) 64.2857, (float) 119.048 ),
+ new CoordRec((float) 64.2857, (float) -33.3333 ),
+};
+
+static final CoordRec char93_stroke1[] = {
+ new CoordRec((float) 69.0476, (float) 119.048 ),
+ new CoordRec((float) 69.0476, (float) -33.3333 ),
+};
+
+static final CoordRec char93_stroke2[] = {
+ new CoordRec((float) 35.7143, (float) 119.048 ),
+ new CoordRec((float) 69.0476, (float) 119.048 ),
+};
+
+static final CoordRec char93_stroke3[] = {
+ new CoordRec((float) 35.7143, (float) -33.3333 ),
+ new CoordRec((float) 69.0476, (float) -33.3333 ),
+};
+
+static final StrokeRec char93[] = {
+ new StrokeRec( 2, char93_stroke0 ),
+ new StrokeRec( 2, char93_stroke1 ),
+ new StrokeRec( 2, char93_stroke2 ),
+ new StrokeRec( 2, char93_stroke3 ),
+};
+
+/* char: 94 '^' */
+
+static final CoordRec char94_stroke0[] = {
+ new CoordRec((float) 52.3809, (float) 109.524 ),
+ new CoordRec((float) 14.2857, (float) 42.8571 ),
+};
+
+static final CoordRec char94_stroke1[] = {
+ new CoordRec((float) 52.3809, (float) 109.524 ),
+ new CoordRec((float) 90.4762, (float) 42.8571 ),
+};
+
+static final StrokeRec char94[] = {
+ new StrokeRec( 2, char94_stroke0 ),
+ new StrokeRec( 2, char94_stroke1 ),
+};
+
+/* char: 95 '_' */
+
+static final CoordRec char95_stroke0[] = {
+ new CoordRec((float) 0, (float) -33.3333 ),
+ new CoordRec((float) 104.762, (float) -33.3333 ),
+ new CoordRec((float) 104.762, (float) -28.5714 ),
+ new CoordRec((float) 0, (float) -28.5714 ),
+ new CoordRec((float) 0, (float) -33.3333 ),
+};
+
+static final StrokeRec char95[] = {
+ new StrokeRec( 5, char95_stroke0 ),
+};
+
+/* char: 96 '`' */
+
+static final CoordRec char96_stroke0[] = {
+ new CoordRec((float) 42.8572, (float) 100 ),
+ new CoordRec((float) 66.6667, (float) 71.4286 ),
+};
+
+static final CoordRec char96_stroke1[] = {
+ new CoordRec((float) 42.8572, (float) 100 ),
+ new CoordRec((float) 38.0953, (float) 95.2381 ),
+ new CoordRec((float) 66.6667, (float) 71.4286 ),
+};
+
+static final StrokeRec char96[] = {
+ new StrokeRec( 2, char96_stroke0 ),
+ new StrokeRec( 3, char96_stroke1 ),
+};
+
+/* char: 97 'a' */
+
+static final CoordRec char97_stroke0[] = {
+ new CoordRec((float) 80.9524, (float) 66.6667 ),
+ new CoordRec((float) 80.9524, (float) 0 ),
+};
+
+static final CoordRec char97_stroke1[] = {
+ new CoordRec((float) 80.9524, (float) 52.381 ),
+ new CoordRec((float) 71.4285, (float) 61.9048 ),
+ new CoordRec((float) 61.9047, (float) 66.6667 ),
+ new CoordRec((float) 47.619, (float) 66.6667 ),
+ new CoordRec((float) 38.0952, (float) 61.9048 ),
+ new CoordRec((float) 28.5714, (float) 52.381 ),
+ new CoordRec((float) 23.8095, (float) 38.0952 ),
+ new CoordRec((float) 23.8095, (float) 28.5714 ),
+ new CoordRec((float) 28.5714, (float) 14.2857 ),
+ new CoordRec((float) 38.0952, (float) 4.7619 ),
+ new CoordRec((float) 47.619, (float) 0 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 71.4285, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+};
+
+static final StrokeRec char97[] = {
+ new StrokeRec( 2, char97_stroke0 ),
+ new StrokeRec( 14, char97_stroke1 ),
+};
+
+/* char: 98 'b' */
+
+static final CoordRec char98_stroke0[] = {
+ new CoordRec((float) 23.8095, (float) 100 ),
+ new CoordRec((float) 23.8095, (float) 0 ),
+};
+
+static final CoordRec char98_stroke1[] = {
+ new CoordRec((float) 23.8095, (float) 52.381 ),
+ new CoordRec((float) 33.3333, (float) 61.9048 ),
+ new CoordRec((float) 42.8571, (float) 66.6667 ),
+ new CoordRec((float) 57.1428, (float) 66.6667 ),
+ new CoordRec((float) 66.6666, (float) 61.9048 ),
+ new CoordRec((float) 76.1905, (float) 52.381 ),
+ new CoordRec((float) 80.9524, (float) 38.0952 ),
+ new CoordRec((float) 80.9524, (float) 28.5714 ),
+ new CoordRec((float) 76.1905, (float) 14.2857 ),
+ new CoordRec((float) 66.6666, (float) 4.7619 ),
+ new CoordRec((float) 57.1428, (float) 0 ),
+ new CoordRec((float) 42.8571, (float) 0 ),
+ new CoordRec((float) 33.3333, (float) 4.7619 ),
+ new CoordRec((float) 23.8095, (float) 14.2857 ),
+};
+
+static final StrokeRec char98[] = {
+ new StrokeRec( 2, char98_stroke0 ),
+ new StrokeRec( 14, char98_stroke1 ),
+};
+
+/* char: 99 'c' */
+
+static final CoordRec char99_stroke0[] = {
+ new CoordRec((float) 80.9524, (float) 52.381 ),
+ new CoordRec((float) 71.4285, (float) 61.9048 ),
+ new CoordRec((float) 61.9047, (float) 66.6667 ),
+ new CoordRec((float) 47.619, (float) 66.6667 ),
+ new CoordRec((float) 38.0952, (float) 61.9048 ),
+ new CoordRec((float) 28.5714, (float) 52.381 ),
+ new CoordRec((float) 23.8095, (float) 38.0952 ),
+ new CoordRec((float) 23.8095, (float) 28.5714 ),
+ new CoordRec((float) 28.5714, (float) 14.2857 ),
+ new CoordRec((float) 38.0952, (float) 4.7619 ),
+ new CoordRec((float) 47.619, (float) 0 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 71.4285, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+};
+
+static final StrokeRec char99[] = {
+ new StrokeRec( 14, char99_stroke0 ),
+};
+
+/* char: 100 'd' */
+
+static final CoordRec char100_stroke0[] = {
+ new CoordRec((float) 80.9524, (float) 100 ),
+ new CoordRec((float) 80.9524, (float) 0 ),
+};
+
+static final CoordRec char100_stroke1[] = {
+ new CoordRec((float) 80.9524, (float) 52.381 ),
+ new CoordRec((float) 71.4285, (float) 61.9048 ),
+ new CoordRec((float) 61.9047, (float) 66.6667 ),
+ new CoordRec((float) 47.619, (float) 66.6667 ),
+ new CoordRec((float) 38.0952, (float) 61.9048 ),
+ new CoordRec((float) 28.5714, (float) 52.381 ),
+ new CoordRec((float) 23.8095, (float) 38.0952 ),
+ new CoordRec((float) 23.8095, (float) 28.5714 ),
+ new CoordRec((float) 28.5714, (float) 14.2857 ),
+ new CoordRec((float) 38.0952, (float) 4.7619 ),
+ new CoordRec((float) 47.619, (float) 0 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 71.4285, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+};
+
+static final StrokeRec char100[] = {
+ new StrokeRec( 2, char100_stroke0 ),
+ new StrokeRec( 14, char100_stroke1 ),
+};
+
+/* char: 101 'e' */
+
+static final CoordRec char101_stroke0[] = {
+ new CoordRec((float) 23.8095, (float) 38.0952 ),
+ new CoordRec((float) 80.9524, (float) 38.0952 ),
+ new CoordRec((float) 80.9524, (float) 47.619 ),
+ new CoordRec((float) 76.1905, (float) 57.1429 ),
+ new CoordRec((float) 71.4285, (float) 61.9048 ),
+ new CoordRec((float) 61.9047, (float) 66.6667 ),
+ new CoordRec((float) 47.619, (float) 66.6667 ),
+ new CoordRec((float) 38.0952, (float) 61.9048 ),
+ new CoordRec((float) 28.5714, (float) 52.381 ),
+ new CoordRec((float) 23.8095, (float) 38.0952 ),
+ new CoordRec((float) 23.8095, (float) 28.5714 ),
+ new CoordRec((float) 28.5714, (float) 14.2857 ),
+ new CoordRec((float) 38.0952, (float) 4.7619 ),
+ new CoordRec((float) 47.619, (float) 0 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 71.4285, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+};
+
+static final StrokeRec char101[] = {
+ new StrokeRec( 17, char101_stroke0 ),
+};
+
+/* char: 102 'f' */
+
+static final CoordRec char102_stroke0[] = {
+ new CoordRec((float) 71.4286, (float) 100 ),
+ new CoordRec((float) 61.9048, (float) 100 ),
+ new CoordRec((float) 52.381, (float) 95.2381 ),
+ new CoordRec((float) 47.6191, (float) 80.9524 ),
+ new CoordRec((float) 47.6191, (float) 0 ),
+};
+
+static final CoordRec char102_stroke1[] = {
+ new CoordRec((float) 33.3334, (float) 66.6667 ),
+ new CoordRec((float) 66.6667, (float) 66.6667 ),
+};
+
+static final StrokeRec char102[] = {
+ new StrokeRec( 5, char102_stroke0 ),
+ new StrokeRec( 2, char102_stroke1 ),
+};
+
+/* char: 103 'g' */
+
+static final CoordRec char103_stroke0[] = {
+ new CoordRec((float) 80.9524, (float) 66.6667 ),
+ new CoordRec((float) 80.9524, (float) -9.5238 ),
+ new CoordRec((float) 76.1905, (float) -23.8095 ),
+ new CoordRec((float) 71.4285, (float) -28.5714 ),
+ new CoordRec((float) 61.9047, (float) -33.3333 ),
+ new CoordRec((float) 47.619, (float) -33.3333 ),
+ new CoordRec((float) 38.0952, (float) -28.5714 ),
+};
+
+static final CoordRec char103_stroke1[] = {
+ new CoordRec((float) 80.9524, (float) 52.381 ),
+ new CoordRec((float) 71.4285, (float) 61.9048 ),
+ new CoordRec((float) 61.9047, (float) 66.6667 ),
+ new CoordRec((float) 47.619, (float) 66.6667 ),
+ new CoordRec((float) 38.0952, (float) 61.9048 ),
+ new CoordRec((float) 28.5714, (float) 52.381 ),
+ new CoordRec((float) 23.8095, (float) 38.0952 ),
+ new CoordRec((float) 23.8095, (float) 28.5714 ),
+ new CoordRec((float) 28.5714, (float) 14.2857 ),
+ new CoordRec((float) 38.0952, (float) 4.7619 ),
+ new CoordRec((float) 47.619, (float) 0 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 71.4285, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+};
+
+static final StrokeRec char103[] = {
+ new StrokeRec( 7, char103_stroke0 ),
+ new StrokeRec( 14, char103_stroke1 ),
+};
+
+/* char: 104 'h' */
+
+static final CoordRec char104_stroke0[] = {
+ new CoordRec((float) 26.1905, (float) 100 ),
+ new CoordRec((float) 26.1905, (float) 0 ),
+};
+
+static final CoordRec char104_stroke1[] = {
+ new CoordRec((float) 26.1905, (float) 47.619 ),
+ new CoordRec((float) 40.4762, (float) 61.9048 ),
+ new CoordRec((float) 50, (float) 66.6667 ),
+ new CoordRec((float) 64.2857, (float) 66.6667 ),
+ new CoordRec((float) 73.8095, (float) 61.9048 ),
+ new CoordRec((float) 78.5715, (float) 47.619 ),
+ new CoordRec((float) 78.5715, (float) 0 ),
+};
+
+static final StrokeRec char104[] = {
+ new StrokeRec( 2, char104_stroke0 ),
+ new StrokeRec( 7, char104_stroke1 ),
+};
+
+/* char: 105 'i' */
+
+static final CoordRec char105_stroke0[] = {
+ new CoordRec((float) 47.6191, (float) 100 ),
+ new CoordRec((float) 52.381, (float) 95.2381 ),
+ new CoordRec((float) 57.1429, (float) 100 ),
+ new CoordRec((float) 52.381, (float) 104.762 ),
+ new CoordRec((float) 47.6191, (float) 100 ),
+};
+
+static final CoordRec char105_stroke1[] = {
+ new CoordRec((float) 52.381, (float) 66.6667 ),
+ new CoordRec((float) 52.381, (float) 0 ),
+};
+
+static final StrokeRec char105[] = {
+ new StrokeRec( 5, char105_stroke0 ),
+ new StrokeRec( 2, char105_stroke1 ),
+};
+
+/* char: 106 'j' */
+
+static final CoordRec char106_stroke0[] = {
+ new CoordRec((float) 57.1429, (float) 100 ),
+ new CoordRec((float) 61.9048, (float) 95.2381 ),
+ new CoordRec((float) 66.6667, (float) 100 ),
+ new CoordRec((float) 61.9048, (float) 104.762 ),
+ new CoordRec((float) 57.1429, (float) 100 ),
+};
+
+static final CoordRec char106_stroke1[] = {
+ new CoordRec((float) 61.9048, (float) 66.6667 ),
+ new CoordRec((float) 61.9048, (float) -14.2857 ),
+ new CoordRec((float) 57.1429, (float) -28.5714 ),
+ new CoordRec((float) 47.6191, (float) -33.3333 ),
+ new CoordRec((float) 38.0953, (float) -33.3333 ),
+};
+
+static final StrokeRec char106[] = {
+ new StrokeRec( 5, char106_stroke0 ),
+ new StrokeRec( 5, char106_stroke1 ),
+};
+
+/* char: 107 'k' */
+
+static final CoordRec char107_stroke0[] = {
+ new CoordRec((float) 26.1905, (float) 100 ),
+ new CoordRec((float) 26.1905, (float) 0 ),
+};
+
+static final CoordRec char107_stroke1[] = {
+ new CoordRec((float) 73.8095, (float) 66.6667 ),
+ new CoordRec((float) 26.1905, (float) 19.0476 ),
+};
+
+static final CoordRec char107_stroke2[] = {
+ new CoordRec((float) 45.2381, (float) 38.0952 ),
+ new CoordRec((float) 78.5715, (float) 0 ),
+};
+
+static final StrokeRec char107[] = {
+ new StrokeRec( 2, char107_stroke0 ),
+ new StrokeRec( 2, char107_stroke1 ),
+ new StrokeRec( 2, char107_stroke2 ),
+};
+
+/* char: 108 'l' */
+
+static final CoordRec char108_stroke0[] = {
+ new CoordRec((float) 52.381, (float) 100 ),
+ new CoordRec((float) 52.381, (float) 0 ),
+};
+
+static final StrokeRec char108[] = {
+ new StrokeRec( 2, char108_stroke0 ),
+};
+
+/* char: 109 'm' */
+
+static final CoordRec char109_stroke0[] = {
+ new CoordRec((float) 0, (float) 66.6667 ),
+ new CoordRec((float) 0, (float) 0 ),
+};
+
+static final CoordRec char109_stroke1[] = {
+ new CoordRec((float) 0, (float) 47.619 ),
+ new CoordRec((float) 14.2857, (float) 61.9048 ),
+ new CoordRec((float) 23.8095, (float) 66.6667 ),
+ new CoordRec((float) 38.0952, (float) 66.6667 ),
+ new CoordRec((float) 47.619, (float) 61.9048 ),
+ new CoordRec((float) 52.381, (float) 47.619 ),
+ new CoordRec((float) 52.381, (float) 0 ),
+};
+
+static final CoordRec char109_stroke2[] = {
+ new CoordRec((float) 52.381, (float) 47.619 ),
+ new CoordRec((float) 66.6667, (float) 61.9048 ),
+ new CoordRec((float) 76.1905, (float) 66.6667 ),
+ new CoordRec((float) 90.4762, (float) 66.6667 ),
+ new CoordRec((float) 100, (float) 61.9048 ),
+ new CoordRec((float) 104.762, (float) 47.619 ),
+ new CoordRec((float) 104.762, (float) 0 ),
+};
+
+static final StrokeRec char109[] = {
+ new StrokeRec( 2, char109_stroke0 ),
+ new StrokeRec( 7, char109_stroke1 ),
+ new StrokeRec( 7, char109_stroke2 ),
+};
+
+/* char: 110 'n' */
+
+static final CoordRec char110_stroke0[] = {
+ new CoordRec((float) 26.1905, (float) 66.6667 ),
+ new CoordRec((float) 26.1905, (float) 0 ),
+};
+
+static final CoordRec char110_stroke1[] = {
+ new CoordRec((float) 26.1905, (float) 47.619 ),
+ new CoordRec((float) 40.4762, (float) 61.9048 ),
+ new CoordRec((float) 50, (float) 66.6667 ),
+ new CoordRec((float) 64.2857, (float) 66.6667 ),
+ new CoordRec((float) 73.8095, (float) 61.9048 ),
+ new CoordRec((float) 78.5715, (float) 47.619 ),
+ new CoordRec((float) 78.5715, (float) 0 ),
+};
+
+static final StrokeRec char110[] = {
+ new StrokeRec( 2, char110_stroke0 ),
+ new StrokeRec( 7, char110_stroke1 ),
+};
+
+/* char: 111 'o' */
+
+static final CoordRec char111_stroke0[] = {
+ new CoordRec((float) 45.2381, (float) 66.6667 ),
+ new CoordRec((float) 35.7143, (float) 61.9048 ),
+ new CoordRec((float) 26.1905, (float) 52.381 ),
+ new CoordRec((float) 21.4286, (float) 38.0952 ),
+ new CoordRec((float) 21.4286, (float) 28.5714 ),
+ new CoordRec((float) 26.1905, (float) 14.2857 ),
+ new CoordRec((float) 35.7143, (float) 4.7619 ),
+ new CoordRec((float) 45.2381, (float) 0 ),
+ new CoordRec((float) 59.5238, (float) 0 ),
+ new CoordRec((float) 69.0476, (float) 4.7619 ),
+ new CoordRec((float) 78.5714, (float) 14.2857 ),
+ new CoordRec((float) 83.3334, (float) 28.5714 ),
+ new CoordRec((float) 83.3334, (float) 38.0952 ),
+ new CoordRec((float) 78.5714, (float) 52.381 ),
+ new CoordRec((float) 69.0476, (float) 61.9048 ),
+ new CoordRec((float) 59.5238, (float) 66.6667 ),
+ new CoordRec((float) 45.2381, (float) 66.6667 ),
+};
+
+static final StrokeRec char111[] = {
+ new StrokeRec( 17, char111_stroke0 ),
+};
+
+/* char: 112 'p' */
+
+static final CoordRec char112_stroke0[] = {
+ new CoordRec((float) 23.8095, (float) 66.6667 ),
+ new CoordRec((float) 23.8095, (float) -33.3333 ),
+};
+
+static final CoordRec char112_stroke1[] = {
+ new CoordRec((float) 23.8095, (float) 52.381 ),
+ new CoordRec((float) 33.3333, (float) 61.9048 ),
+ new CoordRec((float) 42.8571, (float) 66.6667 ),
+ new CoordRec((float) 57.1428, (float) 66.6667 ),
+ new CoordRec((float) 66.6666, (float) 61.9048 ),
+ new CoordRec((float) 76.1905, (float) 52.381 ),
+ new CoordRec((float) 80.9524, (float) 38.0952 ),
+ new CoordRec((float) 80.9524, (float) 28.5714 ),
+ new CoordRec((float) 76.1905, (float) 14.2857 ),
+ new CoordRec((float) 66.6666, (float) 4.7619 ),
+ new CoordRec((float) 57.1428, (float) 0 ),
+ new CoordRec((float) 42.8571, (float) 0 ),
+ new CoordRec((float) 33.3333, (float) 4.7619 ),
+ new CoordRec((float) 23.8095, (float) 14.2857 ),
+};
+
+static final StrokeRec char112[] = {
+ new StrokeRec( 2, char112_stroke0 ),
+ new StrokeRec( 14, char112_stroke1 ),
+};
+
+/* char: 113 'q' */
+
+static final CoordRec char113_stroke0[] = {
+ new CoordRec((float) 80.9524, (float) 66.6667 ),
+ new CoordRec((float) 80.9524, (float) -33.3333 ),
+};
+
+static final CoordRec char113_stroke1[] = {
+ new CoordRec((float) 80.9524, (float) 52.381 ),
+ new CoordRec((float) 71.4285, (float) 61.9048 ),
+ new CoordRec((float) 61.9047, (float) 66.6667 ),
+ new CoordRec((float) 47.619, (float) 66.6667 ),
+ new CoordRec((float) 38.0952, (float) 61.9048 ),
+ new CoordRec((float) 28.5714, (float) 52.381 ),
+ new CoordRec((float) 23.8095, (float) 38.0952 ),
+ new CoordRec((float) 23.8095, (float) 28.5714 ),
+ new CoordRec((float) 28.5714, (float) 14.2857 ),
+ new CoordRec((float) 38.0952, (float) 4.7619 ),
+ new CoordRec((float) 47.619, (float) 0 ),
+ new CoordRec((float) 61.9047, (float) 0 ),
+ new CoordRec((float) 71.4285, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+};
+
+static final StrokeRec char113[] = {
+ new StrokeRec( 2, char113_stroke0 ),
+ new StrokeRec( 14, char113_stroke1 ),
+};
+
+/* char: 114 'r' */
+
+static final CoordRec char114_stroke0[] = {
+ new CoordRec((float) 33.3334, (float) 66.6667 ),
+ new CoordRec((float) 33.3334, (float) 0 ),
+};
+
+static final CoordRec char114_stroke1[] = {
+ new CoordRec((float) 33.3334, (float) 38.0952 ),
+ new CoordRec((float) 38.0953, (float) 52.381 ),
+ new CoordRec((float) 47.6191, (float) 61.9048 ),
+ new CoordRec((float) 57.1429, (float) 66.6667 ),
+ new CoordRec((float) 71.4286, (float) 66.6667 ),
+};
+
+static final StrokeRec char114[] = {
+ new StrokeRec( 2, char114_stroke0 ),
+ new StrokeRec( 5, char114_stroke1 ),
+};
+
+/* char: 115 's' */
+
+static final CoordRec char115_stroke0[] = {
+ new CoordRec((float) 78.5715, (float) 52.381 ),
+ new CoordRec((float) 73.8095, (float) 61.9048 ),
+ new CoordRec((float) 59.5238, (float) 66.6667 ),
+ new CoordRec((float) 45.2381, (float) 66.6667 ),
+ new CoordRec((float) 30.9524, (float) 61.9048 ),
+ new CoordRec((float) 26.1905, (float) 52.381 ),
+ new CoordRec((float) 30.9524, (float) 42.8571 ),
+ new CoordRec((float) 40.4762, (float) 38.0952 ),
+ new CoordRec((float) 64.2857, (float) 33.3333 ),
+ new CoordRec((float) 73.8095, (float) 28.5714 ),
+ new CoordRec((float) 78.5715, (float) 19.0476 ),
+ new CoordRec((float) 78.5715, (float) 14.2857 ),
+ new CoordRec((float) 73.8095, (float) 4.7619 ),
+ new CoordRec((float) 59.5238, (float) 0 ),
+ new CoordRec((float) 45.2381, (float) 0 ),
+ new CoordRec((float) 30.9524, (float) 4.7619 ),
+ new CoordRec((float) 26.1905, (float) 14.2857 ),
+};
+
+static final StrokeRec char115[] = {
+ new StrokeRec( 17, char115_stroke0 ),
+};
+
+/* char: 116 't' */
+
+static final CoordRec char116_stroke0[] = {
+ new CoordRec((float) 47.6191, (float) 100 ),
+ new CoordRec((float) 47.6191, (float) 19.0476 ),
+ new CoordRec((float) 52.381, (float) 4.7619 ),
+ new CoordRec((float) 61.9048, (float) 0 ),
+ new CoordRec((float) 71.4286, (float) 0 ),
+};
+
+static final CoordRec char116_stroke1[] = {
+ new CoordRec((float) 33.3334, (float) 66.6667 ),
+ new CoordRec((float) 66.6667, (float) 66.6667 ),
+};
+
+static final StrokeRec char116[] = {
+ new StrokeRec( 5, char116_stroke0 ),
+ new StrokeRec( 2, char116_stroke1 ),
+};
+
+/* char: 117 'u' */
+
+static final CoordRec char117_stroke0[] = {
+ new CoordRec((float) 26.1905, (float) 66.6667 ),
+ new CoordRec((float) 26.1905, (float) 19.0476 ),
+ new CoordRec((float) 30.9524, (float) 4.7619 ),
+ new CoordRec((float) 40.4762, (float) 0 ),
+ new CoordRec((float) 54.7619, (float) 0 ),
+ new CoordRec((float) 64.2857, (float) 4.7619 ),
+ new CoordRec((float) 78.5715, (float) 19.0476 ),
+};
+
+static final CoordRec char117_stroke1[] = {
+ new CoordRec((float) 78.5715, (float) 66.6667 ),
+ new CoordRec((float) 78.5715, (float) 0 ),
+};
+
+static final StrokeRec char117[] = {
+ new StrokeRec( 7, char117_stroke0 ),
+ new StrokeRec( 2, char117_stroke1 ),
+};
+
+/* char: 118 'v' */
+
+static final CoordRec char118_stroke0[] = {
+ new CoordRec((float) 23.8095, (float) 66.6667 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+};
+
+static final CoordRec char118_stroke1[] = {
+ new CoordRec((float) 80.9524, (float) 66.6667 ),
+ new CoordRec((float) 52.3809, (float) 0 ),
+};
+
+static final StrokeRec char118[] = {
+ new StrokeRec( 2, char118_stroke0 ),
+ new StrokeRec( 2, char118_stroke1 ),
+};
+
+/* char: 119 'w' */
+
+static final CoordRec char119_stroke0[] = {
+ new CoordRec((float) 14.2857, (float) 66.6667 ),
+ new CoordRec((float) 33.3333, (float) 0 ),
+};
+
+static final CoordRec char119_stroke1[] = {
+ new CoordRec((float) 52.3809, (float) 66.6667 ),
+ new CoordRec((float) 33.3333, (float) 0 ),
+};
+
+static final CoordRec char119_stroke2[] = {
+ new CoordRec((float) 52.3809, (float) 66.6667 ),
+ new CoordRec((float) 71.4286, (float) 0 ),
+};
+
+static final CoordRec char119_stroke3[] = {
+ new CoordRec((float) 90.4762, (float) 66.6667 ),
+ new CoordRec((float) 71.4286, (float) 0 ),
+};
+
+static final StrokeRec char119[] = {
+ new StrokeRec( 2, char119_stroke0 ),
+ new StrokeRec( 2, char119_stroke1 ),
+ new StrokeRec( 2, char119_stroke2 ),
+ new StrokeRec( 2, char119_stroke3 ),
+};
+
+/* char: 120 'x' */
+
+static final CoordRec char120_stroke0[] = {
+ new CoordRec((float) 26.1905, (float) 66.6667 ),
+ new CoordRec((float) 78.5715, (float) 0 ),
+};
+
+static final CoordRec char120_stroke1[] = {
+ new CoordRec((float) 78.5715, (float) 66.6667 ),
+ new CoordRec((float) 26.1905, (float) 0 ),
+};
+
+static final StrokeRec char120[] = {
+ new StrokeRec( 2, char120_stroke0 ),
+ new StrokeRec( 2, char120_stroke1 ),
+};
+
+/* char: 121 'y' */
+
+static final CoordRec char121_stroke0[] = {
+ new CoordRec((float) 26.1905, (float) 66.6667 ),
+ new CoordRec((float) 54.7619, (float) 0 ),
+};
+
+static final CoordRec char121_stroke1[] = {
+ new CoordRec((float) 83.3334, (float) 66.6667 ),
+ new CoordRec((float) 54.7619, (float) 0 ),
+ new CoordRec((float) 45.2381, (float) -19.0476 ),
+ new CoordRec((float) 35.7143, (float) -28.5714 ),
+ new CoordRec((float) 26.1905, (float) -33.3333 ),
+ new CoordRec((float) 21.4286, (float) -33.3333 ),
+};
+
+static final StrokeRec char121[] = {
+ new StrokeRec( 2, char121_stroke0 ),
+ new StrokeRec( 6, char121_stroke1 ),
+};
+
+/* char: 122 'z' */
+
+static final CoordRec char122_stroke0[] = {
+ new CoordRec((float) 78.5715, (float) 66.6667 ),
+ new CoordRec((float) 26.1905, (float) 0 ),
+};
+
+static final CoordRec char122_stroke1[] = {
+ new CoordRec((float) 26.1905, (float) 66.6667 ),
+ new CoordRec((float) 78.5715, (float) 66.6667 ),
+};
+
+static final CoordRec char122_stroke2[] = {
+ new CoordRec((float) 26.1905, (float) 0 ),
+ new CoordRec((float) 78.5715, (float) 0 ),
+};
+
+static final StrokeRec char122[] = {
+ new StrokeRec( 2, char122_stroke0 ),
+ new StrokeRec( 2, char122_stroke1 ),
+ new StrokeRec( 2, char122_stroke2 ),
+};
+
+/* char: 123 '{' */
+
+static final CoordRec char123_stroke0[] = {
+ new CoordRec((float) 64.2857, (float) 119.048 ),
+ new CoordRec((float) 54.7619, (float) 114.286 ),
+ new CoordRec((float) 50, (float) 109.524 ),
+ new CoordRec((float) 45.2381, (float) 100 ),
+ new CoordRec((float) 45.2381, (float) 90.4762 ),
+ new CoordRec((float) 50, (float) 80.9524 ),
+ new CoordRec((float) 54.7619, (float) 76.1905 ),
+ new CoordRec((float) 59.5238, (float) 66.6667 ),
+ new CoordRec((float) 59.5238, (float) 57.1429 ),
+ new CoordRec((float) 50, (float) 47.619 ),
+};
+
+static final CoordRec char123_stroke1[] = {
+ new CoordRec((float) 54.7619, (float) 114.286 ),
+ new CoordRec((float) 50, (float) 104.762 ),
+ new CoordRec((float) 50, (float) 95.2381 ),
+ new CoordRec((float) 54.7619, (float) 85.7143 ),
+ new CoordRec((float) 59.5238, (float) 80.9524 ),
+ new CoordRec((float) 64.2857, (float) 71.4286 ),
+ new CoordRec((float) 64.2857, (float) 61.9048 ),
+ new CoordRec((float) 59.5238, (float) 52.381 ),
+ new CoordRec((float) 40.4762, (float) 42.8571 ),
+ new CoordRec((float) 59.5238, (float) 33.3333 ),
+ new CoordRec((float) 64.2857, (float) 23.8095 ),
+ new CoordRec((float) 64.2857, (float) 14.2857 ),
+ new CoordRec((float) 59.5238, (float) 4.7619 ),
+ new CoordRec((float) 54.7619, (float) 0 ),
+ new CoordRec((float) 50, (float) -9.5238 ),
+ new CoordRec((float) 50, (float) -19.0476 ),
+ new CoordRec((float) 54.7619, (float) -28.5714 ),
+};
+
+static final CoordRec char123_stroke2[] = {
+ new CoordRec((float) 50, (float) 38.0952 ),
+ new CoordRec((float) 59.5238, (float) 28.5714 ),
+ new CoordRec((float) 59.5238, (float) 19.0476 ),
+ new CoordRec((float) 54.7619, (float) 9.5238 ),
+ new CoordRec((float) 50, (float) 4.7619 ),
+ new CoordRec((float) 45.2381, (float) -4.7619 ),
+ new CoordRec((float) 45.2381, (float) -14.2857 ),
+ new CoordRec((float) 50, (float) -23.8095 ),
+ new CoordRec((float) 54.7619, (float) -28.5714 ),
+ new CoordRec((float) 64.2857, (float) -33.3333 ),
+};
+
+static final StrokeRec char123[] = {
+ new StrokeRec( 10, char123_stroke0 ),
+ new StrokeRec( 17, char123_stroke1 ),
+ new StrokeRec( 10, char123_stroke2 ),
+};
+
+/* char: 124 '|' */
+
+static final CoordRec char124_stroke0[] = {
+ new CoordRec((float) 52.381, (float) 119.048 ),
+ new CoordRec((float) 52.381, (float) -33.3333 ),
+};
+
+static final StrokeRec char124[] = {
+ new StrokeRec( 2, char124_stroke0 ),
+};
+
+/* char: 125 '}' */
+
+static final CoordRec char125_stroke0[] = {
+ new CoordRec((float) 40.4762, (float) 119.048 ),
+ new CoordRec((float) 50, (float) 114.286 ),
+ new CoordRec((float) 54.7619, (float) 109.524 ),
+ new CoordRec((float) 59.5238, (float) 100 ),
+ new CoordRec((float) 59.5238, (float) 90.4762 ),
+ new CoordRec((float) 54.7619, (float) 80.9524 ),
+ new CoordRec((float) 50, (float) 76.1905 ),
+ new CoordRec((float) 45.2381, (float) 66.6667 ),
+ new CoordRec((float) 45.2381, (float) 57.1429 ),
+ new CoordRec((float) 54.7619, (float) 47.619 ),
+};
+
+static final CoordRec char125_stroke1[] = {
+ new CoordRec((float) 50, (float) 114.286 ),
+ new CoordRec((float) 54.7619, (float) 104.762 ),
+ new CoordRec((float) 54.7619, (float) 95.2381 ),
+ new CoordRec((float) 50, (float) 85.7143 ),
+ new CoordRec((float) 45.2381, (float) 80.9524 ),
+ new CoordRec((float) 40.4762, (float) 71.4286 ),
+ new CoordRec((float) 40.4762, (float) 61.9048 ),
+ new CoordRec((float) 45.2381, (float) 52.381 ),
+ new CoordRec((float) 64.2857, (float) 42.8571 ),
+ new CoordRec((float) 45.2381, (float) 33.3333 ),
+ new CoordRec((float) 40.4762, (float) 23.8095 ),
+ new CoordRec((float) 40.4762, (float) 14.2857 ),
+ new CoordRec((float) 45.2381, (float) 4.7619 ),
+ new CoordRec((float) 50, (float) 0 ),
+ new CoordRec((float) 54.7619, (float) -9.5238 ),
+ new CoordRec((float) 54.7619, (float) -19.0476 ),
+ new CoordRec((float) 50, (float) -28.5714 ),
+};
+
+static final CoordRec char125_stroke2[] = {
+ new CoordRec((float) 54.7619, (float) 38.0952 ),
+ new CoordRec((float) 45.2381, (float) 28.5714 ),
+ new CoordRec((float) 45.2381, (float) 19.0476 ),
+ new CoordRec((float) 50, (float) 9.5238 ),
+ new CoordRec((float) 54.7619, (float) 4.7619 ),
+ new CoordRec((float) 59.5238, (float) -4.7619 ),
+ new CoordRec((float) 59.5238, (float) -14.2857 ),
+ new CoordRec((float) 54.7619, (float) -23.8095 ),
+ new CoordRec((float) 50, (float) -28.5714 ),
+ new CoordRec((float) 40.4762, (float) -33.3333 ),
+};
+
+static final StrokeRec char125[] = {
+ new StrokeRec( 10, char125_stroke0 ),
+ new StrokeRec( 17, char125_stroke1 ),
+ new StrokeRec( 10, char125_stroke2 ),
+};
+
+/* char: 126 '~' */
+
+static final CoordRec char126_stroke0[] = {
+ new CoordRec((float) 9.5238, (float) 28.5714 ),
+ new CoordRec((float) 9.5238, (float) 38.0952 ),
+ new CoordRec((float) 14.2857, (float) 52.381 ),
+ new CoordRec((float) 23.8095, (float) 57.1429 ),
+ new CoordRec((float) 33.3333, (float) 57.1429 ),
+ new CoordRec((float) 42.8571, (float) 52.381 ),
+ new CoordRec((float) 61.9048, (float) 38.0952 ),
+ new CoordRec((float) 71.4286, (float) 33.3333 ),
+ new CoordRec((float) 80.9524, (float) 33.3333 ),
+ new CoordRec((float) 90.4762, (float) 38.0952 ),
+ new CoordRec((float) 95.2381, (float) 47.619 ),
+};
+
+static final CoordRec char126_stroke1[] = {
+ new CoordRec((float) 9.5238, (float) 38.0952 ),
+ new CoordRec((float) 14.2857, (float) 47.619 ),
+ new CoordRec((float) 23.8095, (float) 52.381 ),
+ new CoordRec((float) 33.3333, (float) 52.381 ),
+ new CoordRec((float) 42.8571, (float) 47.619 ),
+ new CoordRec((float) 61.9048, (float) 33.3333 ),
+ new CoordRec((float) 71.4286, (float) 28.5714 ),
+ new CoordRec((float) 80.9524, (float) 28.5714 ),
+ new CoordRec((float) 90.4762, (float) 33.3333 ),
+ new CoordRec((float) 95.2381, (float) 47.619 ),
+ new CoordRec((float) 95.2381, (float) 57.1429 ),
+};
+
+static final StrokeRec char126[] = {
+ new StrokeRec( 11, char126_stroke0 ),
+ new StrokeRec( 11, char126_stroke1 ),
+};
+
+/* char: 127 */
+
+static final CoordRec char127_stroke0[] = {
+ new CoordRec((float) 71.4286, (float) 100 ),
+ new CoordRec((float) 33.3333, (float) -33.3333 ),
+};
+
+static final CoordRec char127_stroke1[] = {
+ new CoordRec((float) 47.619, (float) 66.6667 ),
+ new CoordRec((float) 33.3333, (float) 61.9048 ),
+ new CoordRec((float) 23.8095, (float) 52.381 ),
+ new CoordRec((float) 19.0476, (float) 38.0952 ),
+ new CoordRec((float) 19.0476, (float) 23.8095 ),
+ new CoordRec((float) 23.8095, (float) 14.2857 ),
+ new CoordRec((float) 33.3333, (float) 4.7619 ),
+ new CoordRec((float) 47.619, (float) 0 ),
+ new CoordRec((float) 57.1428, (float) 0 ),
+ new CoordRec((float) 71.4286, (float) 4.7619 ),
+ new CoordRec((float) 80.9524, (float) 14.2857 ),
+ new CoordRec((float) 85.7143, (float) 28.5714 ),
+ new CoordRec((float) 85.7143, (float) 42.8571 ),
+ new CoordRec((float) 80.9524, (float) 52.381 ),
+ new CoordRec((float) 71.4286, (float) 61.9048 ),
+ new CoordRec((float) 57.1428, (float) 66.6667 ),
+ new CoordRec((float) 47.619, (float) 66.6667 ),
+};
+
+static final StrokeRec char127[] = {
+ new StrokeRec( 2, char127_stroke0 ),
+ new StrokeRec( 17, char127_stroke1 ),
+};
+
+static final StrokeCharRec chars[] = {
+ new StrokeCharRec(0, /* char0 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char1 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char2 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char3 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char4 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char5 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char6 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char7 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char8 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char9 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char10 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char11 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char12 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char13 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char14 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char15 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char16 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char17 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char18 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char19 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char20 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char21 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char22 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char23 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char24 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char25 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char26 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char27 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char28 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char29 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char30 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char31 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec(0, /* char32 */ null, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char33, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char34, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(4, char35, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char36, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char37, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char38, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char39, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char40, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char41, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char42, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char43, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char44, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char45, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char46, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char47, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char48, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char49, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char50, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char51, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char52, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char53, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char54, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char55, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char56, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char57, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char58, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char59, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char60, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char61, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char62, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char63, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char64, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char65, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char66, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char67, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char68, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(4, char69, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char70, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char71, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char72, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char73, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char74, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char75, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char76, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(4, char77, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char78, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char79, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char80, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char81, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char82, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char83, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char84, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char85, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char86, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(4, char87, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char88, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char89, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char90, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(4, char91, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char92, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(4, char93, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char94, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char95, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char96, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char97, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char98, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char99, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char100, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char101, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char102, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char103, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char104, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char105, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char106, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char107, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char108, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char109, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char110, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char111, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char112, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char113, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char114, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char115, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char116, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char117, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char118, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(4, char119, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char120, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char121, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char122, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char123, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(1, char124, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(3, char125, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char126, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec(2, char127, (float) 52.381, (float) 104.762 ),
+};
+
+public static final StrokeFontRec glutStrokeMonoRoman = new StrokeFontRec( "Roman", 128, chars, (float) 119.048, (float) -33.3333 );
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTStrokeRoman.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTStrokeRoman.java
new file mode 100644
index 000000000..94fa1c4fd
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUTStrokeRoman.java
@@ -0,0 +1,2491 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+class GLUTStrokeRoman {
+
+/* GENERATED FILE -- DO NOT MODIFY */
+
+/* char: 33 '!' */
+
+static final CoordRec char33_stroke0[] = {
+ new CoordRec((float) 13.3819, (float) 100),
+ new CoordRec((float) 13.3819, (float) 33.3333),
+};
+
+static final CoordRec char33_stroke1[] = {
+ new CoordRec((float) 13.3819, (float) 9.5238),
+ new CoordRec((float) 8.62, (float) 4.7619),
+ new CoordRec((float) 13.3819, (float) 0),
+ new CoordRec((float) 18.1438, (float) 4.7619),
+ new CoordRec((float) 13.3819, (float) 9.5238),
+};
+
+static final StrokeRec char33[] = {
+ new StrokeRec(2, char33_stroke0),
+ new StrokeRec(5, char33_stroke1),
+};
+
+/* char: 34 '"' */
+
+static final CoordRec char34_stroke0[] = {
+ new CoordRec((float) 4.02, (float) 100),
+ new CoordRec((float) 4.02, (float) 66.6667),
+};
+
+static final CoordRec char34_stroke1[] = {
+ new CoordRec((float) 42.1152, (float) 100),
+ new CoordRec((float) 42.1152, (float) 66.6667),
+};
+
+static final StrokeRec char34[] = {
+ new StrokeRec(2, char34_stroke0),
+ new StrokeRec(2, char34_stroke1),
+};
+
+/* char: 35 '#' */
+
+static final CoordRec char35_stroke0[] = {
+ new CoordRec((float) 41.2952, (float) 119.048),
+ new CoordRec((float) 7.9619, (float) -33.3333),
+};
+
+static final CoordRec char35_stroke1[] = {
+ new CoordRec((float) 69.8667, (float) 119.048),
+ new CoordRec((float) 36.5333, (float) -33.3333),
+};
+
+static final CoordRec char35_stroke2[] = {
+ new CoordRec((float) 7.9619, (float) 57.1429),
+ new CoordRec((float) 74.6286, (float) 57.1429),
+};
+
+static final CoordRec char35_stroke3[] = {
+ new CoordRec((float) 3.2, (float) 28.5714),
+ new CoordRec((float) 69.8667, (float) 28.5714),
+};
+
+static final StrokeRec char35[] = {
+ new StrokeRec(2, char35_stroke0),
+ new StrokeRec(2, char35_stroke1),
+ new StrokeRec(2, char35_stroke2),
+ new StrokeRec(2, char35_stroke3),
+};
+
+/* char: 36 '$' */
+
+static final CoordRec char36_stroke0[] = {
+ new CoordRec((float) 28.6295, (float) 119.048),
+ new CoordRec((float) 28.6295, (float) -19.0476),
+};
+
+static final CoordRec char36_stroke1[] = {
+ new CoordRec((float) 47.6771, (float) 119.048),
+ new CoordRec((float) 47.6771, (float) -19.0476),
+};
+
+static final CoordRec char36_stroke2[] = {
+ new CoordRec((float) 71.4867, (float) 85.7143),
+ new CoordRec((float) 61.9629, (float) 95.2381),
+ new CoordRec((float) 47.6771, (float) 100),
+ new CoordRec((float) 28.6295, (float) 100),
+ new CoordRec((float) 14.3438, (float) 95.2381),
+ new CoordRec((float) 4.82, (float) 85.7143),
+ new CoordRec((float) 4.82, (float) 76.1905),
+ new CoordRec((float) 9.5819, (float) 66.6667),
+ new CoordRec((float) 14.3438, (float) 61.9048),
+ new CoordRec((float) 23.8676, (float) 57.1429),
+ new CoordRec((float) 52.439, (float) 47.619),
+ new CoordRec((float) 61.9629, (float) 42.8571),
+ new CoordRec((float) 66.7248, (float) 38.0952),
+ new CoordRec((float) 71.4867, (float) 28.5714),
+ new CoordRec((float) 71.4867, (float) 14.2857),
+ new CoordRec((float) 61.9629, (float) 4.7619),
+ new CoordRec((float) 47.6771, (float) 0),
+ new CoordRec((float) 28.6295, (float) 0),
+ new CoordRec((float) 14.3438, (float) 4.7619),
+ new CoordRec((float) 4.82, (float) 14.2857),
+};
+
+static final StrokeRec char36[] = {
+ new StrokeRec(2, char36_stroke0),
+ new StrokeRec(2, char36_stroke1),
+ new StrokeRec(20, char36_stroke2),
+};
+
+/* char: 37 '%' */
+
+static final CoordRec char37_stroke0[] = {
+ new CoordRec((float) 92.0743, (float) 100),
+ new CoordRec((float) 6.36, (float) 0),
+};
+
+static final CoordRec char37_stroke1[] = {
+ new CoordRec((float) 30.1695, (float) 100),
+ new CoordRec((float) 39.6933, (float) 90.4762),
+ new CoordRec((float) 39.6933, (float) 80.9524),
+ new CoordRec((float) 34.9314, (float) 71.4286),
+ new CoordRec((float) 25.4076, (float) 66.6667),
+ new CoordRec((float) 15.8838, (float) 66.6667),
+ new CoordRec((float) 6.36, (float) 76.1905),
+ new CoordRec((float) 6.36, (float) 85.7143),
+ new CoordRec((float) 11.1219, (float) 95.2381),
+ new CoordRec((float) 20.6457, (float) 100),
+ new CoordRec((float) 30.1695, (float) 100),
+ new CoordRec((float) 39.6933, (float) 95.2381),
+ new CoordRec((float) 53.979, (float) 90.4762),
+ new CoordRec((float) 68.2648, (float) 90.4762),
+ new CoordRec((float) 82.5505, (float) 95.2381),
+ new CoordRec((float) 92.0743, (float) 100),
+};
+
+static final CoordRec char37_stroke2[] = {
+ new CoordRec((float) 73.0267, (float) 33.3333),
+ new CoordRec((float) 63.5029, (float) 28.5714),
+ new CoordRec((float) 58.741, (float) 19.0476),
+ new CoordRec((float) 58.741, (float) 9.5238),
+ new CoordRec((float) 68.2648, (float) 0),
+ new CoordRec((float) 77.7886, (float) 0),
+ new CoordRec((float) 87.3124, (float) 4.7619),
+ new CoordRec((float) 92.0743, (float) 14.2857),
+ new CoordRec((float) 92.0743, (float) 23.8095),
+ new CoordRec((float) 82.5505, (float) 33.3333),
+ new CoordRec((float) 73.0267, (float) 33.3333),
+};
+
+static final StrokeRec char37[] = {
+ new StrokeRec(2, char37_stroke0),
+ new StrokeRec(16, char37_stroke1),
+ new StrokeRec(11, char37_stroke2),
+};
+
+/* char: 38 '&' */
+
+static final CoordRec char38_stroke0[] = {
+ new CoordRec((float) 101.218, (float) 57.1429),
+ new CoordRec((float) 101.218, (float) 61.9048),
+ new CoordRec((float) 96.4562, (float) 66.6667),
+ new CoordRec((float) 91.6943, (float) 66.6667),
+ new CoordRec((float) 86.9324, (float) 61.9048),
+ new CoordRec((float) 82.1705, (float) 52.381),
+ new CoordRec((float) 72.6467, (float) 28.5714),
+ new CoordRec((float) 63.1229, (float) 14.2857),
+ new CoordRec((float) 53.599, (float) 4.7619),
+ new CoordRec((float) 44.0752, (float) 0),
+ new CoordRec((float) 25.0276, (float) 0),
+ new CoordRec((float) 15.5038, (float) 4.7619),
+ new CoordRec((float) 10.7419, (float) 9.5238),
+ new CoordRec((float) 5.98, (float) 19.0476),
+ new CoordRec((float) 5.98, (float) 28.5714),
+ new CoordRec((float) 10.7419, (float) 38.0952),
+ new CoordRec((float) 15.5038, (float) 42.8571),
+ new CoordRec((float) 48.8371, (float) 61.9048),
+ new CoordRec((float) 53.599, (float) 66.6667),
+ new CoordRec((float) 58.361, (float) 76.1905),
+ new CoordRec((float) 58.361, (float) 85.7143),
+ new CoordRec((float) 53.599, (float) 95.2381),
+ new CoordRec((float) 44.0752, (float) 100),
+ new CoordRec((float) 34.5514, (float) 95.2381),
+ new CoordRec((float) 29.7895, (float) 85.7143),
+ new CoordRec((float) 29.7895, (float) 76.1905),
+ new CoordRec((float) 34.5514, (float) 61.9048),
+ new CoordRec((float) 44.0752, (float) 47.619),
+ new CoordRec((float) 67.8848, (float) 14.2857),
+ new CoordRec((float) 77.4086, (float) 4.7619),
+ new CoordRec((float) 86.9324, (float) 0),
+ new CoordRec((float) 96.4562, (float) 0),
+ new CoordRec((float) 101.218, (float) 4.7619),
+ new CoordRec((float) 101.218, (float) 9.5238),
+};
+
+static final StrokeRec char38[] = {
+ new StrokeRec(34, char38_stroke0),
+};
+
+/* char: 39 ''' */
+
+static final CoordRec char39_stroke0[] = {
+ new CoordRec((float) 4.44, (float) 100),
+ new CoordRec((float) 4.44, (float) 66.6667),
+};
+
+static final StrokeRec char39[] = {
+ new StrokeRec(2, char39_stroke0),
+};
+
+/* char: 40 '(' */
+
+static final CoordRec char40_stroke0[] = {
+ new CoordRec((float) 40.9133, (float) 119.048),
+ new CoordRec((float) 31.3895, (float) 109.524),
+ new CoordRec((float) 21.8657, (float) 95.2381),
+ new CoordRec((float) 12.3419, (float) 76.1905),
+ new CoordRec((float) 7.58, (float) 52.381),
+ new CoordRec((float) 7.58, (float) 33.3333),
+ new CoordRec((float) 12.3419, (float) 9.5238),
+ new CoordRec((float) 21.8657, (float) -9.5238),
+ new CoordRec((float) 31.3895, (float) -23.8095),
+ new CoordRec((float) 40.9133, (float) -33.3333),
+};
+
+static final StrokeRec char40[] = {
+ new StrokeRec(10, char40_stroke0),
+};
+
+/* char: 41 ')' */
+
+static final CoordRec char41_stroke0[] = {
+ new CoordRec((float) 5.28, (float) 119.048),
+ new CoordRec((float) 14.8038, (float) 109.524),
+ new CoordRec((float) 24.3276, (float) 95.2381),
+ new CoordRec((float) 33.8514, (float) 76.1905),
+ new CoordRec((float) 38.6133, (float) 52.381),
+ new CoordRec((float) 38.6133, (float) 33.3333),
+ new CoordRec((float) 33.8514, (float) 9.5238),
+ new CoordRec((float) 24.3276, (float) -9.5238),
+ new CoordRec((float) 14.8038, (float) -23.8095),
+ new CoordRec((float) 5.28, (float) -33.3333),
+};
+
+static final StrokeRec char41[] = {
+ new StrokeRec(10, char41_stroke0),
+};
+
+/* char: 42 '*' */
+
+static final CoordRec char42_stroke0[] = {
+ new CoordRec((float) 30.7695, (float) 71.4286),
+ new CoordRec((float) 30.7695, (float) 14.2857),
+};
+
+static final CoordRec char42_stroke1[] = {
+ new CoordRec((float) 6.96, (float) 57.1429),
+ new CoordRec((float) 54.579, (float) 28.5714),
+};
+
+static final CoordRec char42_stroke2[] = {
+ new CoordRec((float) 54.579, (float) 57.1429),
+ new CoordRec((float) 6.96, (float) 28.5714),
+};
+
+static final StrokeRec char42[] = {
+ new StrokeRec(2, char42_stroke0),
+ new StrokeRec(2, char42_stroke1),
+ new StrokeRec(2, char42_stroke2),
+};
+
+/* char: 43 '+' */
+
+static final CoordRec char43_stroke0[] = {
+ new CoordRec((float) 48.8371, (float) 85.7143),
+ new CoordRec((float) 48.8371, (float) 0),
+};
+
+static final CoordRec char43_stroke1[] = {
+ new CoordRec((float) 5.98, (float) 42.8571),
+ new CoordRec((float) 91.6943, (float) 42.8571),
+};
+
+static final StrokeRec char43[] = {
+ new StrokeRec(2, char43_stroke0),
+ new StrokeRec(2, char43_stroke1),
+};
+
+/* char: 44 ',' */
+
+static final CoordRec char44_stroke0[] = {
+ new CoordRec((float) 18.2838, (float) 4.7619),
+ new CoordRec((float) 13.5219, (float) 0),
+ new CoordRec((float) 8.76, (float) 4.7619),
+ new CoordRec((float) 13.5219, (float) 9.5238),
+ new CoordRec((float) 18.2838, (float) 4.7619),
+ new CoordRec((float) 18.2838, (float) -4.7619),
+ new CoordRec((float) 13.5219, (float) -14.2857),
+ new CoordRec((float) 8.76, (float) -19.0476),
+};
+
+static final StrokeRec char44[] = {
+ new StrokeRec(8, char44_stroke0),
+};
+
+/* char: 45 '-' */
+
+static final CoordRec char45_stroke0[] = {
+ new CoordRec((float) 7.38, (float) 42.8571),
+ new CoordRec((float) 93.0943, (float) 42.8571),
+};
+
+static final StrokeRec char45[] = {
+ new StrokeRec(2, char45_stroke0),
+};
+
+/* char: 46 '.' */
+
+static final CoordRec char46_stroke0[] = {
+ new CoordRec((float) 13.1019, (float) 9.5238),
+ new CoordRec((float) 8.34, (float) 4.7619),
+ new CoordRec((float) 13.1019, (float) 0),
+ new CoordRec((float) 17.8638, (float) 4.7619),
+ new CoordRec((float) 13.1019, (float) 9.5238),
+};
+
+static final StrokeRec char46[] = {
+ new StrokeRec(5, char46_stroke0),
+};
+
+/* char: 47 '/' */
+
+static final CoordRec char47_stroke0[] = {
+ new CoordRec((float) 7.24, (float) -14.2857),
+ new CoordRec((float) 73.9067, (float) 100),
+};
+
+static final StrokeRec char47[] = {
+ new StrokeRec(2, char47_stroke0),
+};
+
+/* char: 48 '0' */
+
+static final CoordRec char48_stroke0[] = {
+ new CoordRec((float) 33.5514, (float) 100),
+ new CoordRec((float) 19.2657, (float) 95.2381),
+ new CoordRec((float) 9.7419, (float) 80.9524),
+ new CoordRec((float) 4.98, (float) 57.1429),
+ new CoordRec((float) 4.98, (float) 42.8571),
+ new CoordRec((float) 9.7419, (float) 19.0476),
+ new CoordRec((float) 19.2657, (float) 4.7619),
+ new CoordRec((float) 33.5514, (float) 0),
+ new CoordRec((float) 43.0752, (float) 0),
+ new CoordRec((float) 57.361, (float) 4.7619),
+ new CoordRec((float) 66.8848, (float) 19.0476),
+ new CoordRec((float) 71.6467, (float) 42.8571),
+ new CoordRec((float) 71.6467, (float) 57.1429),
+ new CoordRec((float) 66.8848, (float) 80.9524),
+ new CoordRec((float) 57.361, (float) 95.2381),
+ new CoordRec((float) 43.0752, (float) 100),
+ new CoordRec((float) 33.5514, (float) 100),
+};
+
+static final StrokeRec char48[] = {
+ new StrokeRec(17, char48_stroke0),
+};
+
+/* char: 49 '1' */
+
+static final CoordRec char49_stroke0[] = {
+ new CoordRec((float) 11.82, (float) 80.9524),
+ new CoordRec((float) 21.3438, (float) 85.7143),
+ new CoordRec((float) 35.6295, (float) 100),
+ new CoordRec((float) 35.6295, (float) 0),
+};
+
+static final StrokeRec char49[] = {
+ new StrokeRec(4, char49_stroke0),
+};
+
+/* char: 50 '2' */
+
+static final CoordRec char50_stroke0[] = {
+ new CoordRec((float) 10.1819, (float) 76.1905),
+ new CoordRec((float) 10.1819, (float) 80.9524),
+ new CoordRec((float) 14.9438, (float) 90.4762),
+ new CoordRec((float) 19.7057, (float) 95.2381),
+ new CoordRec((float) 29.2295, (float) 100),
+ new CoordRec((float) 48.2771, (float) 100),
+ new CoordRec((float) 57.801, (float) 95.2381),
+ new CoordRec((float) 62.5629, (float) 90.4762),
+ new CoordRec((float) 67.3248, (float) 80.9524),
+ new CoordRec((float) 67.3248, (float) 71.4286),
+ new CoordRec((float) 62.5629, (float) 61.9048),
+ new CoordRec((float) 53.039, (float) 47.619),
+ new CoordRec((float) 5.42, (float) 0),
+ new CoordRec((float) 72.0867, (float) 0),
+};
+
+static final StrokeRec char50[] = {
+ new StrokeRec(14, char50_stroke0),
+};
+
+/* char: 51 '3' */
+
+static final CoordRec char51_stroke0[] = {
+ new CoordRec((float) 14.5238, (float) 100),
+ new CoordRec((float) 66.9048, (float) 100),
+ new CoordRec((float) 38.3333, (float) 61.9048),
+ new CoordRec((float) 52.619, (float) 61.9048),
+ new CoordRec((float) 62.1429, (float) 57.1429),
+ new CoordRec((float) 66.9048, (float) 52.381),
+ new CoordRec((float) 71.6667, (float) 38.0952),
+ new CoordRec((float) 71.6667, (float) 28.5714),
+ new CoordRec((float) 66.9048, (float) 14.2857),
+ new CoordRec((float) 57.381, (float) 4.7619),
+ new CoordRec((float) 43.0952, (float) 0),
+ new CoordRec((float) 28.8095, (float) 0),
+ new CoordRec((float) 14.5238, (float) 4.7619),
+ new CoordRec((float) 9.7619, (float) 9.5238),
+ new CoordRec((float) 5, (float) 19.0476),
+};
+
+static final StrokeRec char51[] = {
+ new StrokeRec(15, char51_stroke0),
+};
+
+/* char: 52 '4' */
+
+static final CoordRec char52_stroke0[] = {
+ new CoordRec((float) 51.499, (float) 100),
+ new CoordRec((float) 3.88, (float) 33.3333),
+ new CoordRec((float) 75.3086, (float) 33.3333),
+};
+
+static final CoordRec char52_stroke1[] = {
+ new CoordRec((float) 51.499, (float) 100),
+ new CoordRec((float) 51.499, (float) 0),
+};
+
+static final StrokeRec char52[] = {
+ new StrokeRec(3, char52_stroke0),
+ new StrokeRec(2, char52_stroke1),
+};
+
+/* char: 53 '5' */
+
+static final CoordRec char53_stroke0[] = {
+ new CoordRec((float) 62.0029, (float) 100),
+ new CoordRec((float) 14.3838, (float) 100),
+ new CoordRec((float) 9.6219, (float) 57.1429),
+ new CoordRec((float) 14.3838, (float) 61.9048),
+ new CoordRec((float) 28.6695, (float) 66.6667),
+ new CoordRec((float) 42.9552, (float) 66.6667),
+ new CoordRec((float) 57.241, (float) 61.9048),
+ new CoordRec((float) 66.7648, (float) 52.381),
+ new CoordRec((float) 71.5267, (float) 38.0952),
+ new CoordRec((float) 71.5267, (float) 28.5714),
+ new CoordRec((float) 66.7648, (float) 14.2857),
+ new CoordRec((float) 57.241, (float) 4.7619),
+ new CoordRec((float) 42.9552, (float) 0),
+ new CoordRec((float) 28.6695, (float) 0),
+ new CoordRec((float) 14.3838, (float) 4.7619),
+ new CoordRec((float) 9.6219, (float) 9.5238),
+ new CoordRec((float) 4.86, (float) 19.0476),
+};
+
+static final StrokeRec char53[] = {
+ new StrokeRec(17, char53_stroke0),
+};
+
+/* char: 54 '6' */
+
+static final CoordRec char54_stroke0[] = {
+ new CoordRec((float) 62.7229, (float) 85.7143),
+ new CoordRec((float) 57.961, (float) 95.2381),
+ new CoordRec((float) 43.6752, (float) 100),
+ new CoordRec((float) 34.1514, (float) 100),
+ new CoordRec((float) 19.8657, (float) 95.2381),
+ new CoordRec((float) 10.3419, (float) 80.9524),
+ new CoordRec((float) 5.58, (float) 57.1429),
+ new CoordRec((float) 5.58, (float) 33.3333),
+ new CoordRec((float) 10.3419, (float) 14.2857),
+ new CoordRec((float) 19.8657, (float) 4.7619),
+ new CoordRec((float) 34.1514, (float) 0),
+ new CoordRec((float) 38.9133, (float) 0),
+ new CoordRec((float) 53.199, (float) 4.7619),
+ new CoordRec((float) 62.7229, (float) 14.2857),
+ new CoordRec((float) 67.4848, (float) 28.5714),
+ new CoordRec((float) 67.4848, (float) 33.3333),
+ new CoordRec((float) 62.7229, (float) 47.619),
+ new CoordRec((float) 53.199, (float) 57.1429),
+ new CoordRec((float) 38.9133, (float) 61.9048),
+ new CoordRec((float) 34.1514, (float) 61.9048),
+ new CoordRec((float) 19.8657, (float) 57.1429),
+ new CoordRec((float) 10.3419, (float) 47.619),
+ new CoordRec((float) 5.58, (float) 33.3333),
+};
+
+static final StrokeRec char54[] = {
+ new StrokeRec(23, char54_stroke0),
+};
+
+/* char: 55 '7' */
+
+static final CoordRec char55_stroke0[] = {
+ new CoordRec((float) 72.2267, (float) 100),
+ new CoordRec((float) 24.6076, (float) 0),
+};
+
+static final CoordRec char55_stroke1[] = {
+ new CoordRec((float) 5.56, (float) 100),
+ new CoordRec((float) 72.2267, (float) 100),
+};
+
+static final StrokeRec char55[] = {
+ new StrokeRec(2, char55_stroke0),
+ new StrokeRec(2, char55_stroke1),
+};
+
+/* char: 56 '8' */
+
+static final CoordRec char56_stroke0[] = {
+ new CoordRec((float) 29.4095, (float) 100),
+ new CoordRec((float) 15.1238, (float) 95.2381),
+ new CoordRec((float) 10.3619, (float) 85.7143),
+ new CoordRec((float) 10.3619, (float) 76.1905),
+ new CoordRec((float) 15.1238, (float) 66.6667),
+ new CoordRec((float) 24.6476, (float) 61.9048),
+ new CoordRec((float) 43.6952, (float) 57.1429),
+ new CoordRec((float) 57.981, (float) 52.381),
+ new CoordRec((float) 67.5048, (float) 42.8571),
+ new CoordRec((float) 72.2667, (float) 33.3333),
+ new CoordRec((float) 72.2667, (float) 19.0476),
+ new CoordRec((float) 67.5048, (float) 9.5238),
+ new CoordRec((float) 62.7429, (float) 4.7619),
+ new CoordRec((float) 48.4571, (float) 0),
+ new CoordRec((float) 29.4095, (float) 0),
+ new CoordRec((float) 15.1238, (float) 4.7619),
+ new CoordRec((float) 10.3619, (float) 9.5238),
+ new CoordRec((float) 5.6, (float) 19.0476),
+ new CoordRec((float) 5.6, (float) 33.3333),
+ new CoordRec((float) 10.3619, (float) 42.8571),
+ new CoordRec((float) 19.8857, (float) 52.381),
+ new CoordRec((float) 34.1714, (float) 57.1429),
+ new CoordRec((float) 53.219, (float) 61.9048),
+ new CoordRec((float) 62.7429, (float) 66.6667),
+ new CoordRec((float) 67.5048, (float) 76.1905),
+ new CoordRec((float) 67.5048, (float) 85.7143),
+ new CoordRec((float) 62.7429, (float) 95.2381),
+ new CoordRec((float) 48.4571, (float) 100),
+ new CoordRec((float) 29.4095, (float) 100),
+};
+
+static final StrokeRec char56[] = {
+ new StrokeRec(29, char56_stroke0),
+};
+
+/* char: 57 '9' */
+
+static final CoordRec char57_stroke0[] = {
+ new CoordRec((float) 68.5048, (float) 66.6667),
+ new CoordRec((float) 63.7429, (float) 52.381),
+ new CoordRec((float) 54.219, (float) 42.8571),
+ new CoordRec((float) 39.9333, (float) 38.0952),
+ new CoordRec((float) 35.1714, (float) 38.0952),
+ new CoordRec((float) 20.8857, (float) 42.8571),
+ new CoordRec((float) 11.3619, (float) 52.381),
+ new CoordRec((float) 6.6, (float) 66.6667),
+ new CoordRec((float) 6.6, (float) 71.4286),
+ new CoordRec((float) 11.3619, (float) 85.7143),
+ new CoordRec((float) 20.8857, (float) 95.2381),
+ new CoordRec((float) 35.1714, (float) 100),
+ new CoordRec((float) 39.9333, (float) 100),
+ new CoordRec((float) 54.219, (float) 95.2381),
+ new CoordRec((float) 63.7429, (float) 85.7143),
+ new CoordRec((float) 68.5048, (float) 66.6667),
+ new CoordRec((float) 68.5048, (float) 42.8571),
+ new CoordRec((float) 63.7429, (float) 19.0476),
+ new CoordRec((float) 54.219, (float) 4.7619),
+ new CoordRec((float) 39.9333, (float) 0),
+ new CoordRec((float) 30.4095, (float) 0),
+ new CoordRec((float) 16.1238, (float) 4.7619),
+ new CoordRec((float) 11.3619, (float) 14.2857),
+};
+
+static final StrokeRec char57[] = {
+ new StrokeRec(23, char57_stroke0),
+};
+
+/* char: 58 ':' */
+
+static final CoordRec char58_stroke0[] = {
+ new CoordRec((float) 14.0819, (float) 66.6667),
+ new CoordRec((float) 9.32, (float) 61.9048),
+ new CoordRec((float) 14.0819, (float) 57.1429),
+ new CoordRec((float) 18.8438, (float) 61.9048),
+ new CoordRec((float) 14.0819, (float) 66.6667),
+};
+
+static final CoordRec char58_stroke1[] = {
+ new CoordRec((float) 14.0819, (float) 9.5238),
+ new CoordRec((float) 9.32, (float) 4.7619),
+ new CoordRec((float) 14.0819, (float) 0),
+ new CoordRec((float) 18.8438, (float) 4.7619),
+ new CoordRec((float) 14.0819, (float) 9.5238),
+};
+
+static final StrokeRec char58[] = {
+ new StrokeRec(5, char58_stroke0),
+ new StrokeRec(5, char58_stroke1),
+};
+
+/* char: 59 ';' */
+
+static final CoordRec char59_stroke0[] = {
+ new CoordRec((float) 12.9619, (float) 66.6667),
+ new CoordRec((float) 8.2, (float) 61.9048),
+ new CoordRec((float) 12.9619, (float) 57.1429),
+ new CoordRec((float) 17.7238, (float) 61.9048),
+ new CoordRec((float) 12.9619, (float) 66.6667),
+};
+
+static final CoordRec char59_stroke1[] = {
+ new CoordRec((float) 17.7238, (float) 4.7619),
+ new CoordRec((float) 12.9619, (float) 0),
+ new CoordRec((float) 8.2, (float) 4.7619),
+ new CoordRec((float) 12.9619, (float) 9.5238),
+ new CoordRec((float) 17.7238, (float) 4.7619),
+ new CoordRec((float) 17.7238, (float) -4.7619),
+ new CoordRec((float) 12.9619, (float) -14.2857),
+ new CoordRec((float) 8.2, (float) -19.0476),
+};
+
+static final StrokeRec char59[] = {
+ new StrokeRec(5, char59_stroke0),
+ new StrokeRec(8, char59_stroke1),
+};
+
+/* char: 60 '<' */
+
+static final CoordRec char60_stroke0[] = {
+ new CoordRec((float) 79.2505, (float) 85.7143),
+ new CoordRec((float) 3.06, (float) 42.8571),
+ new CoordRec((float) 79.2505, (float) 0),
+};
+
+static final StrokeRec char60[] = {
+ new StrokeRec(3, char60_stroke0),
+};
+
+/* char: 61 '=' */
+
+static final CoordRec char61_stroke0[] = {
+ new CoordRec((float) 5.7, (float) 57.1429),
+ new CoordRec((float) 91.4143, (float) 57.1429),
+};
+
+static final CoordRec char61_stroke1[] = {
+ new CoordRec((float) 5.7, (float) 28.5714),
+ new CoordRec((float) 91.4143, (float) 28.5714),
+};
+
+static final StrokeRec char61[] = {
+ new StrokeRec(2, char61_stroke0),
+ new StrokeRec(2, char61_stroke1),
+};
+
+/* char: 62 '>' */
+
+static final CoordRec char62_stroke0[] = {
+ new CoordRec((float) 2.78, (float) 85.7143),
+ new CoordRec((float) 78.9705, (float) 42.8571),
+ new CoordRec((float) 2.78, (float) 0),
+};
+
+static final StrokeRec char62[] = {
+ new StrokeRec(3, char62_stroke0),
+};
+
+/* char: 63 '?' */
+
+static final CoordRec char63_stroke0[] = {
+ new CoordRec((float) 8.42, (float) 76.1905),
+ new CoordRec((float) 8.42, (float) 80.9524),
+ new CoordRec((float) 13.1819, (float) 90.4762),
+ new CoordRec((float) 17.9438, (float) 95.2381),
+ new CoordRec((float) 27.4676, (float) 100),
+ new CoordRec((float) 46.5152, (float) 100),
+ new CoordRec((float) 56.039, (float) 95.2381),
+ new CoordRec((float) 60.801, (float) 90.4762),
+ new CoordRec((float) 65.5629, (float) 80.9524),
+ new CoordRec((float) 65.5629, (float) 71.4286),
+ new CoordRec((float) 60.801, (float) 61.9048),
+ new CoordRec((float) 56.039, (float) 57.1429),
+ new CoordRec((float) 36.9914, (float) 47.619),
+ new CoordRec((float) 36.9914, (float) 33.3333),
+};
+
+static final CoordRec char63_stroke1[] = {
+ new CoordRec((float) 36.9914, (float) 9.5238),
+ new CoordRec((float) 32.2295, (float) 4.7619),
+ new CoordRec((float) 36.9914, (float) 0),
+ new CoordRec((float) 41.7533, (float) 4.7619),
+ new CoordRec((float) 36.9914, (float) 9.5238),
+};
+
+static final StrokeRec char63[] = {
+ new StrokeRec(14, char63_stroke0),
+ new StrokeRec(5, char63_stroke1),
+};
+
+/* char: 64 '@' */
+
+static final CoordRec char64_stroke0[] = {
+ new CoordRec((float) 49.2171, (float) 52.381),
+ new CoordRec((float) 39.6933, (float) 57.1429),
+ new CoordRec((float) 30.1695, (float) 57.1429),
+ new CoordRec((float) 25.4076, (float) 47.619),
+ new CoordRec((float) 25.4076, (float) 42.8571),
+ new CoordRec((float) 30.1695, (float) 33.3333),
+ new CoordRec((float) 39.6933, (float) 33.3333),
+ new CoordRec((float) 49.2171, (float) 38.0952),
+};
+
+static final CoordRec char64_stroke1[] = {
+ new CoordRec((float) 49.2171, (float) 57.1429),
+ new CoordRec((float) 49.2171, (float) 38.0952),
+ new CoordRec((float) 53.979, (float) 33.3333),
+ new CoordRec((float) 63.5029, (float) 33.3333),
+ new CoordRec((float) 68.2648, (float) 42.8571),
+ new CoordRec((float) 68.2648, (float) 47.619),
+ new CoordRec((float) 63.5029, (float) 61.9048),
+ new CoordRec((float) 53.979, (float) 71.4286),
+ new CoordRec((float) 39.6933, (float) 76.1905),
+ new CoordRec((float) 34.9314, (float) 76.1905),
+ new CoordRec((float) 20.6457, (float) 71.4286),
+ new CoordRec((float) 11.1219, (float) 61.9048),
+ new CoordRec((float) 6.36, (float) 47.619),
+ new CoordRec((float) 6.36, (float) 42.8571),
+ new CoordRec((float) 11.1219, (float) 28.5714),
+ new CoordRec((float) 20.6457, (float) 19.0476),
+ new CoordRec((float) 34.9314, (float) 14.2857),
+ new CoordRec((float) 39.6933, (float) 14.2857),
+ new CoordRec((float) 53.979, (float) 19.0476),
+};
+
+static final StrokeRec char64[] = {
+ new StrokeRec(8, char64_stroke0),
+ new StrokeRec(19, char64_stroke1),
+};
+
+/* char: 65 'A' */
+
+static final CoordRec char65_stroke0[] = {
+ new CoordRec((float) 40.5952, (float) 100),
+ new CoordRec((float) 2.5, (float) 0),
+};
+
+static final CoordRec char65_stroke1[] = {
+ new CoordRec((float) 40.5952, (float) 100),
+ new CoordRec((float) 78.6905, (float) 0),
+};
+
+static final CoordRec char65_stroke2[] = {
+ new CoordRec((float) 16.7857, (float) 33.3333),
+ new CoordRec((float) 64.4048, (float) 33.3333),
+};
+
+static final StrokeRec char65[] = {
+ new StrokeRec(2, char65_stroke0),
+ new StrokeRec(2, char65_stroke1),
+ new StrokeRec(2, char65_stroke2),
+};
+
+/* char: 66 'B' */
+
+static final CoordRec char66_stroke0[] = {
+ new CoordRec((float) 11.42, (float) 100),
+ new CoordRec((float) 11.42, (float) 0),
+};
+
+static final CoordRec char66_stroke1[] = {
+ new CoordRec((float) 11.42, (float) 100),
+ new CoordRec((float) 54.2771, (float) 100),
+ new CoordRec((float) 68.5629, (float) 95.2381),
+ new CoordRec((float) 73.3248, (float) 90.4762),
+ new CoordRec((float) 78.0867, (float) 80.9524),
+ new CoordRec((float) 78.0867, (float) 71.4286),
+ new CoordRec((float) 73.3248, (float) 61.9048),
+ new CoordRec((float) 68.5629, (float) 57.1429),
+ new CoordRec((float) 54.2771, (float) 52.381),
+};
+
+static final CoordRec char66_stroke2[] = {
+ new CoordRec((float) 11.42, (float) 52.381),
+ new CoordRec((float) 54.2771, (float) 52.381),
+ new CoordRec((float) 68.5629, (float) 47.619),
+ new CoordRec((float) 73.3248, (float) 42.8571),
+ new CoordRec((float) 78.0867, (float) 33.3333),
+ new CoordRec((float) 78.0867, (float) 19.0476),
+ new CoordRec((float) 73.3248, (float) 9.5238),
+ new CoordRec((float) 68.5629, (float) 4.7619),
+ new CoordRec((float) 54.2771, (float) 0),
+ new CoordRec((float) 11.42, (float) 0),
+};
+
+static final StrokeRec char66[] = {
+ new StrokeRec(2, char66_stroke0),
+ new StrokeRec(9, char66_stroke1),
+ new StrokeRec(10, char66_stroke2),
+};
+
+/* char: 67 'C' */
+
+static final CoordRec char67_stroke0[] = {
+ new CoordRec((float) 78.0886, (float) 76.1905),
+ new CoordRec((float) 73.3267, (float) 85.7143),
+ new CoordRec((float) 63.8029, (float) 95.2381),
+ new CoordRec((float) 54.279, (float) 100),
+ new CoordRec((float) 35.2314, (float) 100),
+ new CoordRec((float) 25.7076, (float) 95.2381),
+ new CoordRec((float) 16.1838, (float) 85.7143),
+ new CoordRec((float) 11.4219, (float) 76.1905),
+ new CoordRec((float) 6.66, (float) 61.9048),
+ new CoordRec((float) 6.66, (float) 38.0952),
+ new CoordRec((float) 11.4219, (float) 23.8095),
+ new CoordRec((float) 16.1838, (float) 14.2857),
+ new CoordRec((float) 25.7076, (float) 4.7619),
+ new CoordRec((float) 35.2314, (float) 0),
+ new CoordRec((float) 54.279, (float) 0),
+ new CoordRec((float) 63.8029, (float) 4.7619),
+ new CoordRec((float) 73.3267, (float) 14.2857),
+ new CoordRec((float) 78.0886, (float) 23.8095),
+};
+
+static final StrokeRec char67[] = {
+ new StrokeRec(18, char67_stroke0),
+};
+
+/* char: 68 'D' */
+
+static final CoordRec char68_stroke0[] = {
+ new CoordRec((float) 11.96, (float) 100),
+ new CoordRec((float) 11.96, (float) 0),
+};
+
+static final CoordRec char68_stroke1[] = {
+ new CoordRec((float) 11.96, (float) 100),
+ new CoordRec((float) 45.2933, (float) 100),
+ new CoordRec((float) 59.579, (float) 95.2381),
+ new CoordRec((float) 69.1029, (float) 85.7143),
+ new CoordRec((float) 73.8648, (float) 76.1905),
+ new CoordRec((float) 78.6267, (float) 61.9048),
+ new CoordRec((float) 78.6267, (float) 38.0952),
+ new CoordRec((float) 73.8648, (float) 23.8095),
+ new CoordRec((float) 69.1029, (float) 14.2857),
+ new CoordRec((float) 59.579, (float) 4.7619),
+ new CoordRec((float) 45.2933, (float) 0),
+ new CoordRec((float) 11.96, (float) 0),
+};
+
+static final StrokeRec char68[] = {
+ new StrokeRec(2, char68_stroke0),
+ new StrokeRec(12, char68_stroke1),
+};
+
+/* char: 69 'E' */
+
+static final CoordRec char69_stroke0[] = {
+ new CoordRec((float) 11.42, (float) 100),
+ new CoordRec((float) 11.42, (float) 0),
+};
+
+static final CoordRec char69_stroke1[] = {
+ new CoordRec((float) 11.42, (float) 100),
+ new CoordRec((float) 73.3248, (float) 100),
+};
+
+static final CoordRec char69_stroke2[] = {
+ new CoordRec((float) 11.42, (float) 52.381),
+ new CoordRec((float) 49.5152, (float) 52.381),
+};
+
+static final CoordRec char69_stroke3[] = {
+ new CoordRec((float) 11.42, (float) 0),
+ new CoordRec((float) 73.3248, (float) 0),
+};
+
+static final StrokeRec char69[] = {
+ new StrokeRec(2, char69_stroke0),
+ new StrokeRec(2, char69_stroke1),
+ new StrokeRec(2, char69_stroke2),
+ new StrokeRec(2, char69_stroke3),
+};
+
+/* char: 70 'F' */
+
+static final CoordRec char70_stroke0[] = {
+ new CoordRec((float) 11.42, (float) 100),
+ new CoordRec((float) 11.42, (float) 0),
+};
+
+static final CoordRec char70_stroke1[] = {
+ new CoordRec((float) 11.42, (float) 100),
+ new CoordRec((float) 73.3248, (float) 100),
+};
+
+static final CoordRec char70_stroke2[] = {
+ new CoordRec((float) 11.42, (float) 52.381),
+ new CoordRec((float) 49.5152, (float) 52.381),
+};
+
+static final StrokeRec char70[] = {
+ new StrokeRec(2, char70_stroke0),
+ new StrokeRec(2, char70_stroke1),
+ new StrokeRec(2, char70_stroke2),
+};
+
+/* char: 71 'G' */
+
+static final CoordRec char71_stroke0[] = {
+ new CoordRec((float) 78.4886, (float) 76.1905),
+ new CoordRec((float) 73.7267, (float) 85.7143),
+ new CoordRec((float) 64.2029, (float) 95.2381),
+ new CoordRec((float) 54.679, (float) 100),
+ new CoordRec((float) 35.6314, (float) 100),
+ new CoordRec((float) 26.1076, (float) 95.2381),
+ new CoordRec((float) 16.5838, (float) 85.7143),
+ new CoordRec((float) 11.8219, (float) 76.1905),
+ new CoordRec((float) 7.06, (float) 61.9048),
+ new CoordRec((float) 7.06, (float) 38.0952),
+ new CoordRec((float) 11.8219, (float) 23.8095),
+ new CoordRec((float) 16.5838, (float) 14.2857),
+ new CoordRec((float) 26.1076, (float) 4.7619),
+ new CoordRec((float) 35.6314, (float) 0),
+ new CoordRec((float) 54.679, (float) 0),
+ new CoordRec((float) 64.2029, (float) 4.7619),
+ new CoordRec((float) 73.7267, (float) 14.2857),
+ new CoordRec((float) 78.4886, (float) 23.8095),
+ new CoordRec((float) 78.4886, (float) 38.0952),
+};
+
+static final CoordRec char71_stroke1[] = {
+ new CoordRec((float) 54.679, (float) 38.0952),
+ new CoordRec((float) 78.4886, (float) 38.0952),
+};
+
+static final StrokeRec char71[] = {
+ new StrokeRec(19, char71_stroke0),
+ new StrokeRec(2, char71_stroke1),
+};
+
+/* char: 72 'H' */
+
+static final CoordRec char72_stroke0[] = {
+ new CoordRec((float) 11.42, (float) 100),
+ new CoordRec((float) 11.42, (float) 0),
+};
+
+static final CoordRec char72_stroke1[] = {
+ new CoordRec((float) 78.0867, (float) 100),
+ new CoordRec((float) 78.0867, (float) 0),
+};
+
+static final CoordRec char72_stroke2[] = {
+ new CoordRec((float) 11.42, (float) 52.381),
+ new CoordRec((float) 78.0867, (float) 52.381),
+};
+
+static final StrokeRec char72[] = {
+ new StrokeRec(2, char72_stroke0),
+ new StrokeRec(2, char72_stroke1),
+ new StrokeRec(2, char72_stroke2),
+};
+
+/* char: 73 'I' */
+
+static final CoordRec char73_stroke0[] = {
+ new CoordRec((float) 10.86, (float) 100),
+ new CoordRec((float) 10.86, (float) 0),
+};
+
+static final StrokeRec char73[] = {
+ new StrokeRec(2, char73_stroke0),
+};
+
+/* char: 74 'J' */
+
+static final CoordRec char74_stroke0[] = {
+ new CoordRec((float) 50.119, (float) 100),
+ new CoordRec((float) 50.119, (float) 23.8095),
+ new CoordRec((float) 45.3571, (float) 9.5238),
+ new CoordRec((float) 40.5952, (float) 4.7619),
+ new CoordRec((float) 31.0714, (float) 0),
+ new CoordRec((float) 21.5476, (float) 0),
+ new CoordRec((float) 12.0238, (float) 4.7619),
+ new CoordRec((float) 7.2619, (float) 9.5238),
+ new CoordRec((float) 2.5, (float) 23.8095),
+ new CoordRec((float) 2.5, (float) 33.3333),
+};
+
+static final StrokeRec char74[] = {
+ new StrokeRec(10, char74_stroke0),
+};
+
+/* char: 75 'K' */
+
+static final CoordRec char75_stroke0[] = {
+ new CoordRec((float) 11.28, (float) 100),
+ new CoordRec((float) 11.28, (float) 0),
+};
+
+static final CoordRec char75_stroke1[] = {
+ new CoordRec((float) 77.9467, (float) 100),
+ new CoordRec((float) 11.28, (float) 33.3333),
+};
+
+static final CoordRec char75_stroke2[] = {
+ new CoordRec((float) 35.0895, (float) 57.1429),
+ new CoordRec((float) 77.9467, (float) 0),
+};
+
+static final StrokeRec char75[] = {
+ new StrokeRec(2, char75_stroke0),
+ new StrokeRec(2, char75_stroke1),
+ new StrokeRec(2, char75_stroke2),
+};
+
+/* char: 76 'L' */
+
+static final CoordRec char76_stroke0[] = {
+ new CoordRec((float) 11.68, (float) 100),
+ new CoordRec((float) 11.68, (float) 0),
+};
+
+static final CoordRec char76_stroke1[] = {
+ new CoordRec((float) 11.68, (float) 0),
+ new CoordRec((float) 68.8229, (float) 0),
+};
+
+static final StrokeRec char76[] = {
+ new StrokeRec(2, char76_stroke0),
+ new StrokeRec(2, char76_stroke1),
+};
+
+/* char: 77 'M' */
+
+static final CoordRec char77_stroke0[] = {
+ new CoordRec((float) 10.86, (float) 100),
+ new CoordRec((float) 10.86, (float) 0),
+};
+
+static final CoordRec char77_stroke1[] = {
+ new CoordRec((float) 10.86, (float) 100),
+ new CoordRec((float) 48.9552, (float) 0),
+};
+
+static final CoordRec char77_stroke2[] = {
+ new CoordRec((float) 87.0505, (float) 100),
+ new CoordRec((float) 48.9552, (float) 0),
+};
+
+static final CoordRec char77_stroke3[] = {
+ new CoordRec((float) 87.0505, (float) 100),
+ new CoordRec((float) 87.0505, (float) 0),
+};
+
+static final StrokeRec char77[] = {
+ new StrokeRec(2, char77_stroke0),
+ new StrokeRec(2, char77_stroke1),
+ new StrokeRec(2, char77_stroke2),
+ new StrokeRec(2, char77_stroke3),
+};
+
+/* char: 78 'N' */
+
+static final CoordRec char78_stroke0[] = {
+ new CoordRec((float) 11.14, (float) 100),
+ new CoordRec((float) 11.14, (float) 0),
+};
+
+static final CoordRec char78_stroke1[] = {
+ new CoordRec((float) 11.14, (float) 100),
+ new CoordRec((float) 77.8067, (float) 0),
+};
+
+static final CoordRec char78_stroke2[] = {
+ new CoordRec((float) 77.8067, (float) 100),
+ new CoordRec((float) 77.8067, (float) 0),
+};
+
+static final StrokeRec char78[] = {
+ new StrokeRec(2, char78_stroke0),
+ new StrokeRec(2, char78_stroke1),
+ new StrokeRec(2, char78_stroke2),
+};
+
+/* char: 79 'O' */
+
+static final CoordRec char79_stroke0[] = {
+ new CoordRec((float) 34.8114, (float) 100),
+ new CoordRec((float) 25.2876, (float) 95.2381),
+ new CoordRec((float) 15.7638, (float) 85.7143),
+ new CoordRec((float) 11.0019, (float) 76.1905),
+ new CoordRec((float) 6.24, (float) 61.9048),
+ new CoordRec((float) 6.24, (float) 38.0952),
+ new CoordRec((float) 11.0019, (float) 23.8095),
+ new CoordRec((float) 15.7638, (float) 14.2857),
+ new CoordRec((float) 25.2876, (float) 4.7619),
+ new CoordRec((float) 34.8114, (float) 0),
+ new CoordRec((float) 53.859, (float) 0),
+ new CoordRec((float) 63.3829, (float) 4.7619),
+ new CoordRec((float) 72.9067, (float) 14.2857),
+ new CoordRec((float) 77.6686, (float) 23.8095),
+ new CoordRec((float) 82.4305, (float) 38.0952),
+ new CoordRec((float) 82.4305, (float) 61.9048),
+ new CoordRec((float) 77.6686, (float) 76.1905),
+ new CoordRec((float) 72.9067, (float) 85.7143),
+ new CoordRec((float) 63.3829, (float) 95.2381),
+ new CoordRec((float) 53.859, (float) 100),
+ new CoordRec((float) 34.8114, (float) 100),
+};
+
+static final StrokeRec char79[] = {
+ new StrokeRec(21, char79_stroke0),
+};
+
+/* char: 80 'P' */
+
+static final CoordRec char80_stroke0[] = {
+ new CoordRec((float) 12.1, (float) 100),
+ new CoordRec((float) 12.1, (float) 0),
+};
+
+static final CoordRec char80_stroke1[] = {
+ new CoordRec((float) 12.1, (float) 100),
+ new CoordRec((float) 54.9571, (float) 100),
+ new CoordRec((float) 69.2429, (float) 95.2381),
+ new CoordRec((float) 74.0048, (float) 90.4762),
+ new CoordRec((float) 78.7667, (float) 80.9524),
+ new CoordRec((float) 78.7667, (float) 66.6667),
+ new CoordRec((float) 74.0048, (float) 57.1429),
+ new CoordRec((float) 69.2429, (float) 52.381),
+ new CoordRec((float) 54.9571, (float) 47.619),
+ new CoordRec((float) 12.1, (float) 47.619),
+};
+
+static final StrokeRec char80[] = {
+ new StrokeRec(2, char80_stroke0),
+ new StrokeRec(10, char80_stroke1),
+};
+
+/* char: 81 'Q' */
+
+static final CoordRec char81_stroke0[] = {
+ new CoordRec((float) 33.8714, (float) 100),
+ new CoordRec((float) 24.3476, (float) 95.2381),
+ new CoordRec((float) 14.8238, (float) 85.7143),
+ new CoordRec((float) 10.0619, (float) 76.1905),
+ new CoordRec((float) 5.3, (float) 61.9048),
+ new CoordRec((float) 5.3, (float) 38.0952),
+ new CoordRec((float) 10.0619, (float) 23.8095),
+ new CoordRec((float) 14.8238, (float) 14.2857),
+ new CoordRec((float) 24.3476, (float) 4.7619),
+ new CoordRec((float) 33.8714, (float) 0),
+ new CoordRec((float) 52.919, (float) 0),
+ new CoordRec((float) 62.4429, (float) 4.7619),
+ new CoordRec((float) 71.9667, (float) 14.2857),
+ new CoordRec((float) 76.7286, (float) 23.8095),
+ new CoordRec((float) 81.4905, (float) 38.0952),
+ new CoordRec((float) 81.4905, (float) 61.9048),
+ new CoordRec((float) 76.7286, (float) 76.1905),
+ new CoordRec((float) 71.9667, (float) 85.7143),
+ new CoordRec((float) 62.4429, (float) 95.2381),
+ new CoordRec((float) 52.919, (float) 100),
+ new CoordRec((float) 33.8714, (float) 100),
+};
+
+static final CoordRec char81_stroke1[] = {
+ new CoordRec((float) 48.1571, (float) 19.0476),
+ new CoordRec((float) 76.7286, (float) -9.5238),
+};
+
+static final StrokeRec char81[] = {
+ new StrokeRec(21, char81_stroke0),
+ new StrokeRec(2, char81_stroke1),
+};
+
+/* char: 82 'R' */
+
+static final CoordRec char82_stroke0[] = {
+ new CoordRec((float) 11.68, (float) 100),
+ new CoordRec((float) 11.68, (float) 0),
+};
+
+static final CoordRec char82_stroke1[] = {
+ new CoordRec((float) 11.68, (float) 100),
+ new CoordRec((float) 54.5371, (float) 100),
+ new CoordRec((float) 68.8229, (float) 95.2381),
+ new CoordRec((float) 73.5848, (float) 90.4762),
+ new CoordRec((float) 78.3467, (float) 80.9524),
+ new CoordRec((float) 78.3467, (float) 71.4286),
+ new CoordRec((float) 73.5848, (float) 61.9048),
+ new CoordRec((float) 68.8229, (float) 57.1429),
+ new CoordRec((float) 54.5371, (float) 52.381),
+ new CoordRec((float) 11.68, (float) 52.381),
+};
+
+static final CoordRec char82_stroke2[] = {
+ new CoordRec((float) 45.0133, (float) 52.381),
+ new CoordRec((float) 78.3467, (float) 0),
+};
+
+static final StrokeRec char82[] = {
+ new StrokeRec(2, char82_stroke0),
+ new StrokeRec(10, char82_stroke1),
+ new StrokeRec(2, char82_stroke2),
+};
+
+/* char: 83 'S' */
+
+static final CoordRec char83_stroke0[] = {
+ new CoordRec((float) 74.6667, (float) 85.7143),
+ new CoordRec((float) 65.1429, (float) 95.2381),
+ new CoordRec((float) 50.8571, (float) 100),
+ new CoordRec((float) 31.8095, (float) 100),
+ new CoordRec((float) 17.5238, (float) 95.2381),
+ new CoordRec((float) 8, (float) 85.7143),
+ new CoordRec((float) 8, (float) 76.1905),
+ new CoordRec((float) 12.7619, (float) 66.6667),
+ new CoordRec((float) 17.5238, (float) 61.9048),
+ new CoordRec((float) 27.0476, (float) 57.1429),
+ new CoordRec((float) 55.619, (float) 47.619),
+ new CoordRec((float) 65.1429, (float) 42.8571),
+ new CoordRec((float) 69.9048, (float) 38.0952),
+ new CoordRec((float) 74.6667, (float) 28.5714),
+ new CoordRec((float) 74.6667, (float) 14.2857),
+ new CoordRec((float) 65.1429, (float) 4.7619),
+ new CoordRec((float) 50.8571, (float) 0),
+ new CoordRec((float) 31.8095, (float) 0),
+ new CoordRec((float) 17.5238, (float) 4.7619),
+ new CoordRec((float) 8, (float) 14.2857),
+};
+
+static final StrokeRec char83[] = {
+ new StrokeRec(20, char83_stroke0),
+};
+
+/* char: 84 'T' */
+
+static final CoordRec char84_stroke0[] = {
+ new CoordRec((float) 35.6933, (float) 100),
+ new CoordRec((float) 35.6933, (float) 0),
+};
+
+static final CoordRec char84_stroke1[] = {
+ new CoordRec((float) 2.36, (float) 100),
+ new CoordRec((float) 69.0267, (float) 100),
+};
+
+static final StrokeRec char84[] = {
+ new StrokeRec(2, char84_stroke0),
+ new StrokeRec(2, char84_stroke1),
+};
+
+/* char: 85 'U' */
+
+static final CoordRec char85_stroke0[] = {
+ new CoordRec((float) 11.54, (float) 100),
+ new CoordRec((float) 11.54, (float) 28.5714),
+ new CoordRec((float) 16.3019, (float) 14.2857),
+ new CoordRec((float) 25.8257, (float) 4.7619),
+ new CoordRec((float) 40.1114, (float) 0),
+ new CoordRec((float) 49.6352, (float) 0),
+ new CoordRec((float) 63.921, (float) 4.7619),
+ new CoordRec((float) 73.4448, (float) 14.2857),
+ new CoordRec((float) 78.2067, (float) 28.5714),
+ new CoordRec((float) 78.2067, (float) 100),
+};
+
+static final StrokeRec char85[] = {
+ new StrokeRec(10, char85_stroke0),
+};
+
+/* char: 86 'V' */
+
+static final CoordRec char86_stroke0[] = {
+ new CoordRec((float) 2.36, (float) 100),
+ new CoordRec((float) 40.4552, (float) 0),
+};
+
+static final CoordRec char86_stroke1[] = {
+ new CoordRec((float) 78.5505, (float) 100),
+ new CoordRec((float) 40.4552, (float) 0),
+};
+
+static final StrokeRec char86[] = {
+ new StrokeRec(2, char86_stroke0),
+ new StrokeRec(2, char86_stroke1),
+};
+
+/* char: 87 'W' */
+
+static final CoordRec char87_stroke0[] = {
+ new CoordRec((float) 2.22, (float) 100),
+ new CoordRec((float) 26.0295, (float) 0),
+};
+
+static final CoordRec char87_stroke1[] = {
+ new CoordRec((float) 49.839, (float) 100),
+ new CoordRec((float) 26.0295, (float) 0),
+};
+
+static final CoordRec char87_stroke2[] = {
+ new CoordRec((float) 49.839, (float) 100),
+ new CoordRec((float) 73.6486, (float) 0),
+};
+
+static final CoordRec char87_stroke3[] = {
+ new CoordRec((float) 97.4581, (float) 100),
+ new CoordRec((float) 73.6486, (float) 0),
+};
+
+static final StrokeRec char87[] = {
+ new StrokeRec(2, char87_stroke0),
+ new StrokeRec(2, char87_stroke1),
+ new StrokeRec(2, char87_stroke2),
+ new StrokeRec(2, char87_stroke3),
+};
+
+/* char: 88 'X' */
+
+static final CoordRec char88_stroke0[] = {
+ new CoordRec((float) 2.5, (float) 100),
+ new CoordRec((float) 69.1667, (float) 0),
+};
+
+static final CoordRec char88_stroke1[] = {
+ new CoordRec((float) 69.1667, (float) 100),
+ new CoordRec((float) 2.5, (float) 0),
+};
+
+static final StrokeRec char88[] = {
+ new StrokeRec(2, char88_stroke0),
+ new StrokeRec(2, char88_stroke1),
+};
+
+/* char: 89 'Y' */
+
+static final CoordRec char89_stroke0[] = {
+ new CoordRec((float) 1.52, (float) 100),
+ new CoordRec((float) 39.6152, (float) 52.381),
+ new CoordRec((float) 39.6152, (float) 0),
+};
+
+static final CoordRec char89_stroke1[] = {
+ new CoordRec((float) 77.7105, (float) 100),
+ new CoordRec((float) 39.6152, (float) 52.381),
+};
+
+static final StrokeRec char89[] = {
+ new StrokeRec(3, char89_stroke0),
+ new StrokeRec(2, char89_stroke1),
+};
+
+/* char: 90 'Z' */
+
+static final CoordRec char90_stroke0[] = {
+ new CoordRec((float) 69.1667, (float) 100),
+ new CoordRec((float) 2.5, (float) 0),
+};
+
+static final CoordRec char90_stroke1[] = {
+ new CoordRec((float) 2.5, (float) 100),
+ new CoordRec((float) 69.1667, (float) 100),
+};
+
+static final CoordRec char90_stroke2[] = {
+ new CoordRec((float) 2.5, (float) 0),
+ new CoordRec((float) 69.1667, (float) 0),
+};
+
+static final StrokeRec char90[] = {
+ new StrokeRec(2, char90_stroke0),
+ new StrokeRec(2, char90_stroke1),
+ new StrokeRec(2, char90_stroke2),
+};
+
+/* char: 91 '[' */
+
+static final CoordRec char91_stroke0[] = {
+ new CoordRec((float) 7.78, (float) 119.048),
+ new CoordRec((float) 7.78, (float) -33.3333),
+};
+
+static final CoordRec char91_stroke1[] = {
+ new CoordRec((float) 12.5419, (float) 119.048),
+ new CoordRec((float) 12.5419, (float) -33.3333),
+};
+
+static final CoordRec char91_stroke2[] = {
+ new CoordRec((float) 7.78, (float) 119.048),
+ new CoordRec((float) 41.1133, (float) 119.048),
+};
+
+static final CoordRec char91_stroke3[] = {
+ new CoordRec((float) 7.78, (float) -33.3333),
+ new CoordRec((float) 41.1133, (float) -33.3333),
+};
+
+static final StrokeRec char91[] = {
+ new StrokeRec(2, char91_stroke0),
+ new StrokeRec(2, char91_stroke1),
+ new StrokeRec(2, char91_stroke2),
+ new StrokeRec(2, char91_stroke3),
+};
+
+/* char: 92 '\' */
+
+static final CoordRec char92_stroke0[] = {
+ new CoordRec((float) 5.84, (float) 100),
+ new CoordRec((float) 72.5067, (float) -14.2857),
+};
+
+static final StrokeRec char92[] = {
+ new StrokeRec(2, char92_stroke0),
+};
+
+/* char: 93 ']' */
+
+static final CoordRec char93_stroke0[] = {
+ new CoordRec((float) 33.0114, (float) 119.048),
+ new CoordRec((float) 33.0114, (float) -33.3333),
+};
+
+static final CoordRec char93_stroke1[] = {
+ new CoordRec((float) 37.7733, (float) 119.048),
+ new CoordRec((float) 37.7733, (float) -33.3333),
+};
+
+static final CoordRec char93_stroke2[] = {
+ new CoordRec((float) 4.44, (float) 119.048),
+ new CoordRec((float) 37.7733, (float) 119.048),
+};
+
+static final CoordRec char93_stroke3[] = {
+ new CoordRec((float) 4.44, (float) -33.3333),
+ new CoordRec((float) 37.7733, (float) -33.3333),
+};
+
+static final StrokeRec char93[] = {
+ new StrokeRec(2, char93_stroke0),
+ new StrokeRec(2, char93_stroke1),
+ new StrokeRec(2, char93_stroke2),
+ new StrokeRec(2, char93_stroke3),
+};
+
+/* char: 94 '^' */
+
+static final CoordRec char94_stroke0[] = {
+ new CoordRec((float) 44.0752, (float) 109.524),
+ new CoordRec((float) 5.98, (float) 42.8571),
+};
+
+static final CoordRec char94_stroke1[] = {
+ new CoordRec((float) 44.0752, (float) 109.524),
+ new CoordRec((float) 82.1705, (float) 42.8571),
+};
+
+static final StrokeRec char94[] = {
+ new StrokeRec(2, char94_stroke0),
+ new StrokeRec(2, char94_stroke1),
+};
+
+/* char: 95 '_' */
+
+static final CoordRec char95_stroke0[] = {
+ new CoordRec((float)-1.1, (float) -33.3333),
+ new CoordRec((float) 103.662, (float) -33.3333),
+ new CoordRec((float) 103.662, (float) -28.5714),
+ new CoordRec((float)-1.1, (float) -28.5714),
+ new CoordRec((float)-1.1, (float) -33.3333),
+};
+
+static final StrokeRec char95[] = {
+ new StrokeRec(5, char95_stroke0),
+};
+
+/* char: 96 '`' */
+
+static final CoordRec char96_stroke0[] = {
+ new CoordRec((float) 33.0219, (float) 100),
+ new CoordRec((float) 56.8314, (float) 71.4286),
+};
+
+static final CoordRec char96_stroke1[] = {
+ new CoordRec((float) 33.0219, (float) 100),
+ new CoordRec((float) 28.26, (float) 95.2381),
+ new CoordRec((float) 56.8314, (float) 71.4286),
+};
+
+static final StrokeRec char96[] = {
+ new StrokeRec(2, char96_stroke0),
+ new StrokeRec(3, char96_stroke1),
+};
+
+/* char: 97 'a' */
+
+static final CoordRec char97_stroke0[] = {
+ new CoordRec((float) 63.8229, (float) 66.6667),
+ new CoordRec((float) 63.8229, (float) 0),
+};
+
+static final CoordRec char97_stroke1[] = {
+ new CoordRec((float) 63.8229, (float) 52.381),
+ new CoordRec((float) 54.299, (float) 61.9048),
+ new CoordRec((float) 44.7752, (float) 66.6667),
+ new CoordRec((float) 30.4895, (float) 66.6667),
+ new CoordRec((float) 20.9657, (float) 61.9048),
+ new CoordRec((float) 11.4419, (float) 52.381),
+ new CoordRec((float) 6.68, (float) 38.0952),
+ new CoordRec((float) 6.68, (float) 28.5714),
+ new CoordRec((float) 11.4419, (float) 14.2857),
+ new CoordRec((float) 20.9657, (float) 4.7619),
+ new CoordRec((float) 30.4895, (float) 0),
+ new CoordRec((float) 44.7752, (float) 0),
+ new CoordRec((float) 54.299, (float) 4.7619),
+ new CoordRec((float) 63.8229, (float) 14.2857),
+};
+
+static final StrokeRec char97[] = {
+ new StrokeRec(2, char97_stroke0),
+ new StrokeRec(14, char97_stroke1),
+};
+
+/* char: 98 'b' */
+
+static final CoordRec char98_stroke0[] = {
+ new CoordRec((float) 8.76, (float) 100),
+ new CoordRec((float) 8.76, (float) 0),
+};
+
+static final CoordRec char98_stroke1[] = {
+ new CoordRec((float) 8.76, (float) 52.381),
+ new CoordRec((float) 18.2838, (float) 61.9048),
+ new CoordRec((float) 27.8076, (float) 66.6667),
+ new CoordRec((float) 42.0933, (float) 66.6667),
+ new CoordRec((float) 51.6171, (float) 61.9048),
+ new CoordRec((float) 61.141, (float) 52.381),
+ new CoordRec((float) 65.9029, (float) 38.0952),
+ new CoordRec((float) 65.9029, (float) 28.5714),
+ new CoordRec((float) 61.141, (float) 14.2857),
+ new CoordRec((float) 51.6171, (float) 4.7619),
+ new CoordRec((float) 42.0933, (float) 0),
+ new CoordRec((float) 27.8076, (float) 0),
+ new CoordRec((float) 18.2838, (float) 4.7619),
+ new CoordRec((float) 8.76, (float) 14.2857),
+};
+
+static final StrokeRec char98[] = {
+ new StrokeRec(2, char98_stroke0),
+ new StrokeRec(14, char98_stroke1),
+};
+
+/* char: 99 'c' */
+
+static final CoordRec char99_stroke0[] = {
+ new CoordRec((float) 62.6629, (float) 52.381),
+ new CoordRec((float) 53.139, (float) 61.9048),
+ new CoordRec((float) 43.6152, (float) 66.6667),
+ new CoordRec((float) 29.3295, (float) 66.6667),
+ new CoordRec((float) 19.8057, (float) 61.9048),
+ new CoordRec((float) 10.2819, (float) 52.381),
+ new CoordRec((float) 5.52, (float) 38.0952),
+ new CoordRec((float) 5.52, (float) 28.5714),
+ new CoordRec((float) 10.2819, (float) 14.2857),
+ new CoordRec((float) 19.8057, (float) 4.7619),
+ new CoordRec((float) 29.3295, (float) 0),
+ new CoordRec((float) 43.6152, (float) 0),
+ new CoordRec((float) 53.139, (float) 4.7619),
+ new CoordRec((float) 62.6629, (float) 14.2857),
+};
+
+static final StrokeRec char99[] = {
+ new StrokeRec(14, char99_stroke0),
+};
+
+/* char: 100 'd' */
+
+static final CoordRec char100_stroke0[] = {
+ new CoordRec((float) 61.7829, (float) 100),
+ new CoordRec((float) 61.7829, (float) 0),
+};
+
+static final CoordRec char100_stroke1[] = {
+ new CoordRec((float) 61.7829, (float) 52.381),
+ new CoordRec((float) 52.259, (float) 61.9048),
+ new CoordRec((float) 42.7352, (float) 66.6667),
+ new CoordRec((float) 28.4495, (float) 66.6667),
+ new CoordRec((float) 18.9257, (float) 61.9048),
+ new CoordRec((float) 9.4019, (float) 52.381),
+ new CoordRec((float) 4.64, (float) 38.0952),
+ new CoordRec((float) 4.64, (float) 28.5714),
+ new CoordRec((float) 9.4019, (float) 14.2857),
+ new CoordRec((float) 18.9257, (float) 4.7619),
+ new CoordRec((float) 28.4495, (float) 0),
+ new CoordRec((float) 42.7352, (float) 0),
+ new CoordRec((float) 52.259, (float) 4.7619),
+ new CoordRec((float) 61.7829, (float) 14.2857),
+};
+
+static final StrokeRec char100[] = {
+ new StrokeRec(2, char100_stroke0),
+ new StrokeRec(14, char100_stroke1),
+};
+
+/* char: 101 'e' */
+
+static final CoordRec char101_stroke0[] = {
+ new CoordRec((float) 5.72, (float) 38.0952),
+ new CoordRec((float) 62.8629, (float) 38.0952),
+ new CoordRec((float) 62.8629, (float) 47.619),
+ new CoordRec((float) 58.101, (float) 57.1429),
+ new CoordRec((float) 53.339, (float) 61.9048),
+ new CoordRec((float) 43.8152, (float) 66.6667),
+ new CoordRec((float) 29.5295, (float) 66.6667),
+ new CoordRec((float) 20.0057, (float) 61.9048),
+ new CoordRec((float) 10.4819, (float) 52.381),
+ new CoordRec((float) 5.72, (float) 38.0952),
+ new CoordRec((float) 5.72, (float) 28.5714),
+ new CoordRec((float) 10.4819, (float) 14.2857),
+ new CoordRec((float) 20.0057, (float) 4.7619),
+ new CoordRec((float) 29.5295, (float) 0),
+ new CoordRec((float) 43.8152, (float) 0),
+ new CoordRec((float) 53.339, (float) 4.7619),
+ new CoordRec((float) 62.8629, (float) 14.2857),
+};
+
+static final StrokeRec char101[] = {
+ new StrokeRec(17, char101_stroke0),
+};
+
+/* char: 102 'f' */
+
+static final CoordRec char102_stroke0[] = {
+ new CoordRec((float) 38.7752, (float) 100),
+ new CoordRec((float) 29.2514, (float) 100),
+ new CoordRec((float) 19.7276, (float) 95.2381),
+ new CoordRec((float) 14.9657, (float) 80.9524),
+ new CoordRec((float) 14.9657, (float) 0),
+};
+
+static final CoordRec char102_stroke1[] = {
+ new CoordRec((float) 0.68, (float) 66.6667),
+ new CoordRec((float) 34.0133, (float) 66.6667),
+};
+
+static final StrokeRec char102[] = {
+ new StrokeRec(5, char102_stroke0),
+ new StrokeRec(2, char102_stroke1),
+};
+
+/* char: 103 'g' */
+
+static final CoordRec char103_stroke0[] = {
+ new CoordRec((float) 62.5029, (float) 66.6667),
+ new CoordRec((float) 62.5029, (float) -9.5238),
+ new CoordRec((float) 57.741, (float) -23.8095),
+ new CoordRec((float) 52.979, (float) -28.5714),
+ new CoordRec((float) 43.4552, (float) -33.3333),
+ new CoordRec((float) 29.1695, (float) -33.3333),
+ new CoordRec((float) 19.6457, (float) -28.5714),
+};
+
+static final CoordRec char103_stroke1[] = {
+ new CoordRec((float) 62.5029, (float) 52.381),
+ new CoordRec((float) 52.979, (float) 61.9048),
+ new CoordRec((float) 43.4552, (float) 66.6667),
+ new CoordRec((float) 29.1695, (float) 66.6667),
+ new CoordRec((float) 19.6457, (float) 61.9048),
+ new CoordRec((float) 10.1219, (float) 52.381),
+ new CoordRec((float) 5.36, (float) 38.0952),
+ new CoordRec((float) 5.36, (float) 28.5714),
+ new CoordRec((float) 10.1219, (float) 14.2857),
+ new CoordRec((float) 19.6457, (float) 4.7619),
+ new CoordRec((float) 29.1695, (float) 0),
+ new CoordRec((float) 43.4552, (float) 0),
+ new CoordRec((float) 52.979, (float) 4.7619),
+ new CoordRec((float) 62.5029, (float) 14.2857),
+};
+
+static final StrokeRec char103[] = {
+ new StrokeRec(7, char103_stroke0),
+ new StrokeRec(14, char103_stroke1),
+};
+
+/* char: 104 'h' */
+
+static final CoordRec char104_stroke0[] = {
+ new CoordRec((float) 9.6, (float) 100),
+ new CoordRec((float) 9.6, (float) 0),
+};
+
+static final CoordRec char104_stroke1[] = {
+ new CoordRec((float) 9.6, (float) 47.619),
+ new CoordRec((float) 23.8857, (float) 61.9048),
+ new CoordRec((float) 33.4095, (float) 66.6667),
+ new CoordRec((float) 47.6952, (float) 66.6667),
+ new CoordRec((float) 57.219, (float) 61.9048),
+ new CoordRec((float) 61.981, (float) 47.619),
+ new CoordRec((float) 61.981, (float) 0),
+};
+
+static final StrokeRec char104[] = {
+ new StrokeRec(2, char104_stroke0),
+ new StrokeRec(7, char104_stroke1),
+};
+
+/* char: 105 'i' */
+
+static final CoordRec char105_stroke0[] = {
+ new CoordRec((float) 10.02, (float) 100),
+ new CoordRec((float) 14.7819, (float) 95.2381),
+ new CoordRec((float) 19.5438, (float) 100),
+ new CoordRec((float) 14.7819, (float) 104.762),
+ new CoordRec((float) 10.02, (float) 100),
+};
+
+static final CoordRec char105_stroke1[] = {
+ new CoordRec((float) 14.7819, (float) 66.6667),
+ new CoordRec((float) 14.7819, (float) 0),
+};
+
+static final StrokeRec char105[] = {
+ new StrokeRec(5, char105_stroke0),
+ new StrokeRec(2, char105_stroke1),
+};
+
+/* char: 106 'j' */
+
+static final CoordRec char106_stroke0[] = {
+ new CoordRec((float) 17.3876, (float) 100),
+ new CoordRec((float) 22.1495, (float) 95.2381),
+ new CoordRec((float) 26.9114, (float) 100),
+ new CoordRec((float) 22.1495, (float) 104.762),
+ new CoordRec((float) 17.3876, (float) 100),
+};
+
+static final CoordRec char106_stroke1[] = {
+ new CoordRec((float) 22.1495, (float) 66.6667),
+ new CoordRec((float) 22.1495, (float) -14.2857),
+ new CoordRec((float) 17.3876, (float) -28.5714),
+ new CoordRec((float) 7.8638, (float) -33.3333),
+ new CoordRec((float)-1.66, (float) -33.3333),
+};
+
+static final StrokeRec char106[] = {
+ new StrokeRec(5, char106_stroke0),
+ new StrokeRec(5, char106_stroke1),
+};
+
+/* char: 107 'k' */
+
+static final CoordRec char107_stroke0[] = {
+ new CoordRec((float) 9.6, (float) 100),
+ new CoordRec((float) 9.6, (float) 0),
+};
+
+static final CoordRec char107_stroke1[] = {
+ new CoordRec((float) 57.219, (float) 66.6667),
+ new CoordRec((float) 9.6, (float) 19.0476),
+};
+
+static final CoordRec char107_stroke2[] = {
+ new CoordRec((float) 28.6476, (float) 38.0952),
+ new CoordRec((float) 61.981, (float) 0),
+};
+
+static final StrokeRec char107[] = {
+ new StrokeRec(2, char107_stroke0),
+ new StrokeRec(2, char107_stroke1),
+ new StrokeRec(2, char107_stroke2),
+};
+
+/* char: 108 'l' */
+
+static final CoordRec char108_stroke0[] = {
+ new CoordRec((float) 10.02, (float) 100),
+ new CoordRec((float) 10.02, (float) 0),
+};
+
+static final StrokeRec char108[] = {
+ new StrokeRec(2, char108_stroke0),
+};
+
+/* char: 109 'm' */
+
+static final CoordRec char109_stroke0[] = {
+ new CoordRec((float) 9.6, (float) 66.6667),
+ new CoordRec((float) 9.6, (float) 0),
+};
+
+static final CoordRec char109_stroke1[] = {
+ new CoordRec((float) 9.6, (float) 47.619),
+ new CoordRec((float) 23.8857, (float) 61.9048),
+ new CoordRec((float) 33.4095, (float) 66.6667),
+ new CoordRec((float) 47.6952, (float) 66.6667),
+ new CoordRec((float) 57.219, (float) 61.9048),
+ new CoordRec((float) 61.981, (float) 47.619),
+ new CoordRec((float) 61.981, (float) 0),
+};
+
+static final CoordRec char109_stroke2[] = {
+ new CoordRec((float) 61.981, (float) 47.619),
+ new CoordRec((float) 76.2667, (float) 61.9048),
+ new CoordRec((float) 85.7905, (float) 66.6667),
+ new CoordRec((float) 100.076, (float) 66.6667),
+ new CoordRec((float) 109.6, (float) 61.9048),
+ new CoordRec((float) 114.362, (float) 47.619),
+ new CoordRec((float) 114.362, (float) 0),
+};
+
+static final StrokeRec char109[] = {
+ new StrokeRec(2, char109_stroke0),
+ new StrokeRec(7, char109_stroke1),
+ new StrokeRec(7, char109_stroke2),
+};
+
+/* char: 110 'n' */
+
+static final CoordRec char110_stroke0[] = {
+ new CoordRec((float) 9.18, (float) 66.6667),
+ new CoordRec((float) 9.18, (float) 0),
+};
+
+static final CoordRec char110_stroke1[] = {
+ new CoordRec((float) 9.18, (float) 47.619),
+ new CoordRec((float) 23.4657, (float) 61.9048),
+ new CoordRec((float) 32.9895, (float) 66.6667),
+ new CoordRec((float) 47.2752, (float) 66.6667),
+ new CoordRec((float) 56.799, (float) 61.9048),
+ new CoordRec((float) 61.561, (float) 47.619),
+ new CoordRec((float) 61.561, (float) 0),
+};
+
+static final StrokeRec char110[] = {
+ new StrokeRec(2, char110_stroke0),
+ new StrokeRec(7, char110_stroke1),
+};
+
+/* char: 111 'o' */
+
+static final CoordRec char111_stroke0[] = {
+ new CoordRec((float) 28.7895, (float) 66.6667),
+ new CoordRec((float) 19.2657, (float) 61.9048),
+ new CoordRec((float) 9.7419, (float) 52.381),
+ new CoordRec((float) 4.98, (float) 38.0952),
+ new CoordRec((float) 4.98, (float) 28.5714),
+ new CoordRec((float) 9.7419, (float) 14.2857),
+ new CoordRec((float) 19.2657, (float) 4.7619),
+ new CoordRec((float) 28.7895, (float) 0),
+ new CoordRec((float) 43.0752, (float) 0),
+ new CoordRec((float) 52.599, (float) 4.7619),
+ new CoordRec((float) 62.1229, (float) 14.2857),
+ new CoordRec((float) 66.8848, (float) 28.5714),
+ new CoordRec((float) 66.8848, (float) 38.0952),
+ new CoordRec((float) 62.1229, (float) 52.381),
+ new CoordRec((float) 52.599, (float) 61.9048),
+ new CoordRec((float) 43.0752, (float) 66.6667),
+ new CoordRec((float) 28.7895, (float) 66.6667),
+};
+
+static final StrokeRec char111[] = {
+ new StrokeRec(17, char111_stroke0),
+};
+
+/* char: 112 'p' */
+
+static final CoordRec char112_stroke0[] = {
+ new CoordRec((float) 9.46, (float) 66.6667),
+ new CoordRec((float) 9.46, (float) -33.3333),
+};
+
+static final CoordRec char112_stroke1[] = {
+ new CoordRec((float) 9.46, (float) 52.381),
+ new CoordRec((float) 18.9838, (float) 61.9048),
+ new CoordRec((float) 28.5076, (float) 66.6667),
+ new CoordRec((float) 42.7933, (float) 66.6667),
+ new CoordRec((float) 52.3171, (float) 61.9048),
+ new CoordRec((float) 61.841, (float) 52.381),
+ new CoordRec((float) 66.6029, (float) 38.0952),
+ new CoordRec((float) 66.6029, (float) 28.5714),
+ new CoordRec((float) 61.841, (float) 14.2857),
+ new CoordRec((float) 52.3171, (float) 4.7619),
+ new CoordRec((float) 42.7933, (float) 0),
+ new CoordRec((float) 28.5076, (float) 0),
+ new CoordRec((float) 18.9838, (float) 4.7619),
+ new CoordRec((float) 9.46, (float) 14.2857),
+};
+
+static final StrokeRec char112[] = {
+ new StrokeRec(2, char112_stroke0),
+ new StrokeRec(14, char112_stroke1),
+};
+
+/* char: 113 'q' */
+
+static final CoordRec char113_stroke0[] = {
+ new CoordRec((float) 61.9829, (float) 66.6667),
+ new CoordRec((float) 61.9829, (float) -33.3333),
+};
+
+static final CoordRec char113_stroke1[] = {
+ new CoordRec((float) 61.9829, (float) 52.381),
+ new CoordRec((float) 52.459, (float) 61.9048),
+ new CoordRec((float) 42.9352, (float) 66.6667),
+ new CoordRec((float) 28.6495, (float) 66.6667),
+ new CoordRec((float) 19.1257, (float) 61.9048),
+ new CoordRec((float) 9.6019, (float) 52.381),
+ new CoordRec((float) 4.84, (float) 38.0952),
+ new CoordRec((float) 4.84, (float) 28.5714),
+ new CoordRec((float) 9.6019, (float) 14.2857),
+ new CoordRec((float) 19.1257, (float) 4.7619),
+ new CoordRec((float) 28.6495, (float) 0),
+ new CoordRec((float) 42.9352, (float) 0),
+ new CoordRec((float) 52.459, (float) 4.7619),
+ new CoordRec((float) 61.9829, (float) 14.2857),
+};
+
+static final StrokeRec char113[] = {
+ new StrokeRec(2, char113_stroke0),
+ new StrokeRec(14, char113_stroke1),
+};
+
+/* char: 114 'r' */
+
+static final CoordRec char114_stroke0[] = {
+ new CoordRec((float) 9.46, (float) 66.6667),
+ new CoordRec((float) 9.46, (float) 0),
+};
+
+static final CoordRec char114_stroke1[] = {
+ new CoordRec((float) 9.46, (float) 38.0952),
+ new CoordRec((float) 14.2219, (float) 52.381),
+ new CoordRec((float) 23.7457, (float) 61.9048),
+ new CoordRec((float) 33.2695, (float) 66.6667),
+ new CoordRec((float) 47.5552, (float) 66.6667),
+};
+
+static final StrokeRec char114[] = {
+ new StrokeRec(2, char114_stroke0),
+ new StrokeRec(5, char114_stroke1),
+};
+
+/* char: 115 's' */
+
+static final CoordRec char115_stroke0[] = {
+ new CoordRec((float) 57.081, (float) 52.381),
+ new CoordRec((float) 52.319, (float) 61.9048),
+ new CoordRec((float) 38.0333, (float) 66.6667),
+ new CoordRec((float) 23.7476, (float) 66.6667),
+ new CoordRec((float) 9.4619, (float) 61.9048),
+ new CoordRec((float) 4.7, (float) 52.381),
+ new CoordRec((float) 9.4619, (float) 42.8571),
+ new CoordRec((float) 18.9857, (float) 38.0952),
+ new CoordRec((float) 42.7952, (float) 33.3333),
+ new CoordRec((float) 52.319, (float) 28.5714),
+ new CoordRec((float) 57.081, (float) 19.0476),
+ new CoordRec((float) 57.081, (float) 14.2857),
+ new CoordRec((float) 52.319, (float) 4.7619),
+ new CoordRec((float) 38.0333, (float) 0),
+ new CoordRec((float) 23.7476, (float) 0),
+ new CoordRec((float) 9.4619, (float) 4.7619),
+ new CoordRec((float) 4.7, (float) 14.2857),
+};
+
+static final StrokeRec char115[] = {
+ new StrokeRec(17, char115_stroke0),
+};
+
+/* char: 116 't' */
+
+static final CoordRec char116_stroke0[] = {
+ new CoordRec((float) 14.8257, (float) 100),
+ new CoordRec((float) 14.8257, (float) 19.0476),
+ new CoordRec((float) 19.5876, (float) 4.7619),
+ new CoordRec((float) 29.1114, (float) 0),
+ new CoordRec((float) 38.6352, (float) 0),
+};
+
+static final CoordRec char116_stroke1[] = {
+ new CoordRec((float) 0.54, (float) 66.6667),
+ new CoordRec((float) 33.8733, (float) 66.6667),
+};
+
+static final StrokeRec char116[] = {
+ new StrokeRec(5, char116_stroke0),
+ new StrokeRec(2, char116_stroke1),
+};
+
+/* char: 117 'u' */
+
+static final CoordRec char117_stroke0[] = {
+ new CoordRec((float) 9.46, (float) 66.6667),
+ new CoordRec((float) 9.46, (float) 19.0476),
+ new CoordRec((float) 14.2219, (float) 4.7619),
+ new CoordRec((float) 23.7457, (float) 0),
+ new CoordRec((float) 38.0314, (float) 0),
+ new CoordRec((float) 47.5552, (float) 4.7619),
+ new CoordRec((float) 61.841, (float) 19.0476),
+};
+
+static final CoordRec char117_stroke1[] = {
+ new CoordRec((float) 61.841, (float) 66.6667),
+ new CoordRec((float) 61.841, (float) 0),
+};
+
+static final StrokeRec char117[] = {
+ new StrokeRec(7, char117_stroke0),
+ new StrokeRec(2, char117_stroke1),
+};
+
+/* char: 118 'v' */
+
+static final CoordRec char118_stroke0[] = {
+ new CoordRec((float) 1.8, (float) 66.6667),
+ new CoordRec((float) 30.3714, (float) 0),
+};
+
+static final CoordRec char118_stroke1[] = {
+ new CoordRec((float) 58.9429, (float) 66.6667),
+ new CoordRec((float) 30.3714, (float) 0),
+};
+
+static final StrokeRec char118[] = {
+ new StrokeRec(2, char118_stroke0),
+ new StrokeRec(2, char118_stroke1),
+};
+
+/* char: 119 'w' */
+
+static final CoordRec char119_stroke0[] = {
+ new CoordRec((float) 2.5, (float) 66.6667),
+ new CoordRec((float) 21.5476, (float) 0),
+};
+
+static final CoordRec char119_stroke1[] = {
+ new CoordRec((float) 40.5952, (float) 66.6667),
+ new CoordRec((float) 21.5476, (float) 0),
+};
+
+static final CoordRec char119_stroke2[] = {
+ new CoordRec((float) 40.5952, (float) 66.6667),
+ new CoordRec((float) 59.6429, (float) 0),
+};
+
+static final CoordRec char119_stroke3[] = {
+ new CoordRec((float) 78.6905, (float) 66.6667),
+ new CoordRec((float) 59.6429, (float) 0),
+};
+
+static final StrokeRec char119[] = {
+ new StrokeRec(2, char119_stroke0),
+ new StrokeRec(2, char119_stroke1),
+ new StrokeRec(2, char119_stroke2),
+ new StrokeRec(2, char119_stroke3),
+};
+
+/* char: 120 'x' */
+
+static final CoordRec char120_stroke0[] = {
+ new CoordRec((float) 1.66, (float) 66.6667),
+ new CoordRec((float) 54.041, (float) 0),
+};
+
+static final CoordRec char120_stroke1[] = {
+ new CoordRec((float) 54.041, (float) 66.6667),
+ new CoordRec((float) 1.66, (float) 0),
+};
+
+static final StrokeRec char120[] = {
+ new StrokeRec(2, char120_stroke0),
+ new StrokeRec(2, char120_stroke1),
+};
+
+/* char: 121 'y' */
+
+static final CoordRec char121_stroke0[] = {
+ new CoordRec((float) 6.5619, (float) 66.6667),
+ new CoordRec((float) 35.1333, (float) 0),
+};
+
+static final CoordRec char121_stroke1[] = {
+ new CoordRec((float) 63.7048, (float) 66.6667),
+ new CoordRec((float) 35.1333, (float) 0),
+ new CoordRec((float) 25.6095, (float) -19.0476),
+ new CoordRec((float) 16.0857, (float) -28.5714),
+ new CoordRec((float) 6.5619, (float) -33.3333),
+ new CoordRec((float) 1.8, (float) -33.3333),
+};
+
+static final StrokeRec char121[] = {
+ new StrokeRec(2, char121_stroke0),
+ new StrokeRec(6, char121_stroke1),
+};
+
+/* char: 122 'z' */
+
+static final CoordRec char122_stroke0[] = {
+ new CoordRec((float) 56.821, (float) 66.6667),
+ new CoordRec((float) 4.44, (float) 0),
+};
+
+static final CoordRec char122_stroke1[] = {
+ new CoordRec((float) 4.44, (float) 66.6667),
+ new CoordRec((float) 56.821, (float) 66.6667),
+};
+
+static final CoordRec char122_stroke2[] = {
+ new CoordRec((float) 4.44, (float) 0),
+ new CoordRec((float) 56.821, (float) 0),
+};
+
+static final StrokeRec char122[] = {
+ new StrokeRec(2, char122_stroke0),
+ new StrokeRec(2, char122_stroke1),
+ new StrokeRec(2, char122_stroke2),
+};
+
+/* char: 123 '{' */
+
+static final CoordRec char123_stroke0[] = {
+ new CoordRec((float) 31.1895, (float) 119.048),
+ new CoordRec((float) 21.6657, (float) 114.286),
+ new CoordRec((float) 16.9038, (float) 109.524),
+ new CoordRec((float) 12.1419, (float) 100),
+ new CoordRec((float) 12.1419, (float) 90.4762),
+ new CoordRec((float) 16.9038, (float) 80.9524),
+ new CoordRec((float) 21.6657, (float) 76.1905),
+ new CoordRec((float) 26.4276, (float) 66.6667),
+ new CoordRec((float) 26.4276, (float) 57.1429),
+ new CoordRec((float) 16.9038, (float) 47.619),
+};
+
+static final CoordRec char123_stroke1[] = {
+ new CoordRec((float) 21.6657, (float) 114.286),
+ new CoordRec((float) 16.9038, (float) 104.762),
+ new CoordRec((float) 16.9038, (float) 95.2381),
+ new CoordRec((float) 21.6657, (float) 85.7143),
+ new CoordRec((float) 26.4276, (float) 80.9524),
+ new CoordRec((float) 31.1895, (float) 71.4286),
+ new CoordRec((float) 31.1895, (float) 61.9048),
+ new CoordRec((float) 26.4276, (float) 52.381),
+ new CoordRec((float) 7.38, (float) 42.8571),
+ new CoordRec((float) 26.4276, (float) 33.3333),
+ new CoordRec((float) 31.1895, (float) 23.8095),
+ new CoordRec((float) 31.1895, (float) 14.2857),
+ new CoordRec((float) 26.4276, (float) 4.7619),
+ new CoordRec((float) 21.6657, (float) 0),
+ new CoordRec((float) 16.9038, (float) -9.5238),
+ new CoordRec((float) 16.9038, (float) -19.0476),
+ new CoordRec((float) 21.6657, (float) -28.5714),
+};
+
+static final CoordRec char123_stroke2[] = {
+ new CoordRec((float) 16.9038, (float) 38.0952),
+ new CoordRec((float) 26.4276, (float) 28.5714),
+ new CoordRec((float) 26.4276, (float) 19.0476),
+ new CoordRec((float) 21.6657, (float) 9.5238),
+ new CoordRec((float) 16.9038, (float) 4.7619),
+ new CoordRec((float) 12.1419, (float) -4.7619),
+ new CoordRec((float) 12.1419, (float) -14.2857),
+ new CoordRec((float) 16.9038, (float) -23.8095),
+ new CoordRec((float) 21.6657, (float) -28.5714),
+ new CoordRec((float) 31.1895, (float) -33.3333),
+};
+
+static final StrokeRec char123[] = {
+ new StrokeRec(10, char123_stroke0),
+ new StrokeRec(17, char123_stroke1),
+ new StrokeRec(10, char123_stroke2),
+};
+
+/* char: 124 '|' */
+
+static final CoordRec char124_stroke0[] = {
+ new CoordRec((float) 11.54, (float) 119.048),
+ new CoordRec((float) 11.54, (float) -33.3333),
+};
+
+static final StrokeRec char124[] = {
+ new StrokeRec(2, char124_stroke0),
+};
+
+/* char: 125 '}' */
+
+static final CoordRec char125_stroke0[] = {
+ new CoordRec((float) 9.18, (float) 119.048),
+ new CoordRec((float) 18.7038, (float) 114.286),
+ new CoordRec((float) 23.4657, (float) 109.524),
+ new CoordRec((float) 28.2276, (float) 100),
+ new CoordRec((float) 28.2276, (float) 90.4762),
+ new CoordRec((float) 23.4657, (float) 80.9524),
+ new CoordRec((float) 18.7038, (float) 76.1905),
+ new CoordRec((float) 13.9419, (float) 66.6667),
+ new CoordRec((float) 13.9419, (float) 57.1429),
+ new CoordRec((float) 23.4657, (float) 47.619),
+};
+
+static final CoordRec char125_stroke1[] = {
+ new CoordRec((float) 18.7038, (float) 114.286),
+ new CoordRec((float) 23.4657, (float) 104.762),
+ new CoordRec((float) 23.4657, (float) 95.2381),
+ new CoordRec((float) 18.7038, (float) 85.7143),
+ new CoordRec((float) 13.9419, (float) 80.9524),
+ new CoordRec((float) 9.18, (float) 71.4286),
+ new CoordRec((float) 9.18, (float) 61.9048),
+ new CoordRec((float) 13.9419, (float) 52.381),
+ new CoordRec((float) 32.9895, (float) 42.8571),
+ new CoordRec((float) 13.9419, (float) 33.3333),
+ new CoordRec((float) 9.18, (float) 23.8095),
+ new CoordRec((float) 9.18, (float) 14.2857),
+ new CoordRec((float) 13.9419, (float) 4.7619),
+ new CoordRec((float) 18.7038, (float) 0),
+ new CoordRec((float) 23.4657, (float) -9.5238),
+ new CoordRec((float) 23.4657, (float) -19.0476),
+ new CoordRec((float) 18.7038, (float) -28.5714),
+};
+
+static final CoordRec char125_stroke2[] = {
+ new CoordRec((float) 23.4657, (float) 38.0952),
+ new CoordRec((float) 13.9419, (float) 28.5714),
+ new CoordRec((float) 13.9419, (float) 19.0476),
+ new CoordRec((float) 18.7038, (float) 9.5238),
+ new CoordRec((float) 23.4657, (float) 4.7619),
+ new CoordRec((float) 28.2276, (float) -4.7619),
+ new CoordRec((float) 28.2276, (float) -14.2857),
+ new CoordRec((float) 23.4657, (float) -23.8095),
+ new CoordRec((float) 18.7038, (float) -28.5714),
+ new CoordRec((float) 9.18, (float) -33.3333),
+};
+
+static final StrokeRec char125[] = {
+ new StrokeRec(10, char125_stroke0),
+ new StrokeRec(17, char125_stroke1),
+ new StrokeRec(10, char125_stroke2),
+};
+
+/* char: 126 '~' */
+
+static final CoordRec char126_stroke0[] = {
+ new CoordRec((float) 2.92, (float) 28.5714),
+ new CoordRec((float) 2.92, (float) 38.0952),
+ new CoordRec((float) 7.6819, (float) 52.381),
+ new CoordRec((float) 17.2057, (float) 57.1429),
+ new CoordRec((float) 26.7295, (float) 57.1429),
+ new CoordRec((float) 36.2533, (float) 52.381),
+ new CoordRec((float) 55.301, (float) 38.0952),
+ new CoordRec((float) 64.8248, (float) 33.3333),
+ new CoordRec((float) 74.3486, (float) 33.3333),
+ new CoordRec((float) 83.8724, (float) 38.0952),
+ new CoordRec((float) 88.6343, (float) 47.619),
+};
+
+static final CoordRec char126_stroke1[] = {
+ new CoordRec((float) 2.92, (float) 38.0952),
+ new CoordRec((float) 7.6819, (float) 47.619),
+ new CoordRec((float) 17.2057, (float) 52.381),
+ new CoordRec((float) 26.7295, (float) 52.381),
+ new CoordRec((float) 36.2533, (float) 47.619),
+ new CoordRec((float) 55.301, (float) 33.3333),
+ new CoordRec((float) 64.8248, (float) 28.5714),
+ new CoordRec((float) 74.3486, (float) 28.5714),
+ new CoordRec((float) 83.8724, (float) 33.3333),
+ new CoordRec((float) 88.6343, (float) 47.619),
+ new CoordRec((float) 88.6343, (float) 57.1429),
+};
+
+static final StrokeRec char126[] = {
+ new StrokeRec(11, char126_stroke0),
+ new StrokeRec(11, char126_stroke1),
+};
+
+/* char: 127 */
+
+static final CoordRec char127_stroke0[] = {
+ new CoordRec((float) 52.381, (float) 100),
+ new CoordRec((float) 14.2857, (float) -33.3333),
+};
+
+static final CoordRec char127_stroke1[] = {
+ new CoordRec((float) 28.5714, (float) 66.6667),
+ new CoordRec((float) 14.2857, (float) 61.9048),
+ new CoordRec((float) 4.7619, (float) 52.381),
+ new CoordRec((float) 0, (float) 38.0952),
+ new CoordRec((float) 0, (float) 23.8095),
+ new CoordRec((float) 4.7619, (float) 14.2857),
+ new CoordRec((float) 14.2857, (float) 4.7619),
+ new CoordRec((float) 28.5714, (float) 0),
+ new CoordRec((float) 38.0952, (float) 0),
+ new CoordRec((float) 52.381, (float) 4.7619),
+ new CoordRec((float) 61.9048, (float) 14.2857),
+ new CoordRec((float) 66.6667, (float) 28.5714),
+ new CoordRec((float) 66.6667, (float) 42.8571),
+ new CoordRec((float) 61.9048, (float) 52.381),
+ new CoordRec((float) 52.381, (float) 61.9048),
+ new CoordRec((float) 38.0952, (float) 66.6667),
+ new CoordRec((float) 28.5714, (float) 66.6667),
+};
+
+static final StrokeRec char127[] = {
+ new StrokeRec(2, char127_stroke0),
+ new StrokeRec(17, char127_stroke1),
+};
+
+static final StrokeCharRec chars[] = {
+ new StrokeCharRec( 0, /* char0 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char1 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char2 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char3 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char4 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char5 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char6 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char7 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char8 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char9 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char10 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char11 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char12 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char13 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char14 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char15 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char16 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char17 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char18 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char19 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char20 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char21 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char22 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char23 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char24 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char25 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char26 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char27 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char28 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char29 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char30 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char31 */ null, (float) 0, (float) 0 ),
+ new StrokeCharRec( 0, /* char32 */ null, (float) 52.381, (float) 104.762 ),
+ new StrokeCharRec( 2, char33, (float) 13.3819, (float) 26.6238 ),
+ new StrokeCharRec( 2, char34, (float) 23.0676, (float) 51.4352 ),
+ new StrokeCharRec( 4, char35, (float) 36.5333, (float) 79.4886 ),
+ new StrokeCharRec( 3, char36, (float) 38.1533, (float) 76.2067 ),
+ new StrokeCharRec( 3, char37, (float) 49.2171, (float) 96.5743 ),
+ new StrokeCharRec( 1, char38, (float) 53.599, (float) 101.758 ),
+ new StrokeCharRec( 1, char39, (float) 4.44, (float) 13.62 ),
+ new StrokeCharRec( 1, char40, (float) 21.8657, (float) 47.1733 ),
+ new StrokeCharRec( 1, char41, (float) 24.3276, (float) 47.5333 ),
+ new StrokeCharRec( 3, char42, (float) 30.7695, (float) 59.439 ),
+ new StrokeCharRec( 2, char43, (float) 48.8371, (float) 97.2543 ),
+ new StrokeCharRec( 1, char44, (float) 13.5219, (float) 26.0638 ),
+ new StrokeCharRec( 1, char45, (float) 50.2371, (float) 100.754 ),
+ new StrokeCharRec( 1, char46, (float) 13.1019, (float) 26.4838 ),
+ new StrokeCharRec( 1, char47, (float) 40.5733, (float) 82.1067 ),
+ new StrokeCharRec( 1, char48, (float) 38.3133, (float) 77.0667 ),
+ new StrokeCharRec( 1, char49, (float) 30.8676, (float) 66.5295 ),
+ new StrokeCharRec( 1, char50, (float) 38.7533, (float) 77.6467 ),
+ new StrokeCharRec( 1, char51, (float) 38.3333, (float) 77.0467 ),
+ new StrokeCharRec( 2, char52, (float) 37.2133, (float) 80.1686 ),
+ new StrokeCharRec( 1, char53, (float) 38.1933, (float) 77.6867 ),
+ new StrokeCharRec( 1, char54, (float) 34.1514, (float) 73.8048 ),
+ new StrokeCharRec( 2, char55, (float) 38.8933, (float) 77.2267 ),
+ new StrokeCharRec( 1, char56, (float) 38.9333, (float) 77.6667 ),
+ new StrokeCharRec( 1, char57, (float) 39.9333, (float) 74.0648 ),
+ new StrokeCharRec( 2, char58, (float) 14.0819, (float) 26.2238 ),
+ new StrokeCharRec( 2, char59, (float) 12.9619, (float) 26.3038 ),
+ new StrokeCharRec( 1, char60, (float) 41.1552, (float) 81.6105 ),
+ new StrokeCharRec( 2, char61, (float) 48.5571, (float) 97.2543 ),
+ new StrokeCharRec( 1, char62, (float) 40.8752, (float) 81.6105 ),
+ new StrokeCharRec( 2, char63, (float) 36.9914, (float) 73.9029 ),
+ new StrokeCharRec( 2, char64, (float) 34.9314, (float) 74.3648 ),
+ new StrokeCharRec( 3, char65, (float) 40.5952, (float) 80.4905 ),
+ new StrokeCharRec( 3, char66, (float) 44.7533, (float) 83.6267 ),
+ new StrokeCharRec( 1, char67, (float) 39.9933, (float) 84.4886 ),
+ new StrokeCharRec( 2, char68, (float) 45.2933, (float) 85.2867 ),
+ new StrokeCharRec( 4, char69, (float) 39.9914, (float) 78.1848 ),
+ new StrokeCharRec( 3, char70, (float) 39.9914, (float) 78.7448 ),
+ new StrokeCharRec( 2, char71, (float) 40.3933, (float) 89.7686 ),
+ new StrokeCharRec( 3, char72, (float) 44.7533, (float) 89.0867 ),
+ new StrokeCharRec( 1, char73, (float) 10.86, (float) 21.3 ),
+ new StrokeCharRec( 1, char74, (float) 31.0714, (float) 59.999 ),
+ new StrokeCharRec( 3, char75, (float) 44.6133, (float) 79.3267 ),
+ new StrokeCharRec( 2, char76, (float) 40.2514, (float) 71.3229 ),
+ new StrokeCharRec( 4, char77, (float) 48.9552, (float) 97.2105 ),
+ new StrokeCharRec( 3, char78, (float) 44.4733, (float) 88.8067 ),
+ new StrokeCharRec( 1, char79, (float) 44.3352, (float) 88.8305 ),
+ new StrokeCharRec( 2, char80, (float) 45.4333, (float) 85.6667 ),
+ new StrokeCharRec( 2, char81, (float) 43.3952, (float) 88.0905 ),
+ new StrokeCharRec( 3, char82, (float) 45.0133, (float) 82.3667 ),
+ new StrokeCharRec( 1, char83, (float) 41.3333, (float) 80.8267 ),
+ new StrokeCharRec( 2, char84, (float) 35.6933, (float) 71.9467 ),
+ new StrokeCharRec( 1, char85, (float) 44.8733, (float) 89.4867 ),
+ new StrokeCharRec( 2, char86, (float) 40.4552, (float) 81.6105 ),
+ new StrokeCharRec( 4, char87, (float) 49.839, (float) 100.518 ),
+ new StrokeCharRec( 2, char88, (float) 35.8333, (float) 72.3667 ),
+ new StrokeCharRec( 2, char89, (float) 39.6152, (float) 79.6505 ),
+ new StrokeCharRec( 3, char90, (float) 35.8333, (float) 73.7467 ),
+ new StrokeCharRec( 4, char91, (float) 22.0657, (float) 46.1133 ),
+ new StrokeCharRec( 1, char92, (float) 39.1733, (float) 78.2067 ),
+ new StrokeCharRec( 4, char93, (float) 23.4876, (float) 46.3933 ),
+ new StrokeCharRec( 2, char94, (float) 44.0752, (float) 90.2305 ),
+ new StrokeCharRec( 1, char95, (float) 51.281, (float) 104.062 ),
+ new StrokeCharRec( 2, char96, (float) 42.5457, (float) 83.5714 ),
+ new StrokeCharRec( 2, char97, (float) 35.2514, (float) 66.6029 ),
+ new StrokeCharRec( 2, char98, (float) 37.3314, (float) 70.4629 ),
+ new StrokeCharRec( 1, char99, (float) 34.0914, (float) 68.9229 ),
+ new StrokeCharRec( 2, char100, (float) 33.2114, (float) 70.2629 ),
+ new StrokeCharRec( 1, char101, (float) 34.2914, (float) 68.5229 ),
+ new StrokeCharRec( 2, char102, (float) 14.9657, (float) 38.6552 ),
+ new StrokeCharRec( 2, char103, (float) 33.9314, (float) 70.9829 ),
+ new StrokeCharRec( 2, char104, (float) 33.4095, (float) 71.021 ),
+ new StrokeCharRec( 2, char105, (float) 14.7819, (float) 28.8638 ),
+ new StrokeCharRec( 2, char106, (float) 17.3876, (float) 36.2314 ),
+ new StrokeCharRec( 3, char107, (float) 33.4095, (float) 62.521 ),
+ new StrokeCharRec( 1, char108, (float) 10.02, (float) 19.34 ),
+ new StrokeCharRec( 3, char109, (float) 61.981, (float) 123.962 ),
+ new StrokeCharRec( 2, char110, (float) 32.9895, (float) 70.881 ),
+ new StrokeCharRec( 1, char111, (float) 33.5514, (float) 71.7448 ),
+ new StrokeCharRec( 2, char112, (float) 38.0314, (float) 70.8029 ),
+ new StrokeCharRec( 2, char113, (float) 33.4114, (float) 70.7429 ),
+ new StrokeCharRec( 2, char114, (float) 23.7457, (float) 49.4952 ),
+ new StrokeCharRec( 1, char115, (float) 28.5095, (float) 62.321 ),
+ new StrokeCharRec( 2, char116, (float) 14.8257, (float) 39.3152 ),
+ new StrokeCharRec( 2, char117, (float) 33.2695, (float) 71.161 ),
+ new StrokeCharRec( 2, char118, (float) 30.3714, (float) 60.6029 ),
+ new StrokeCharRec( 4, char119, (float) 40.5952, (float) 80.4905 ),
+ new StrokeCharRec( 2, char120, (float) 25.4695, (float) 56.401 ),
+ new StrokeCharRec( 2, char121, (float) 35.1333, (float) 66.0648 ),
+ new StrokeCharRec( 3, char122, (float) 28.2495, (float) 61.821 ),
+ new StrokeCharRec( 3, char123, (float) 21.6657, (float) 41.6295 ),
+ new StrokeCharRec( 1, char124, (float) 11.54, (float) 23.78 ),
+ new StrokeCharRec( 3, char125, (float) 18.7038, (float) 41.4695 ),
+ new StrokeCharRec( 2, char126, (float) 45.7771, (float) 91.2743 ),
+ new StrokeCharRec( 2, char127, (float) 33.3333, (float) 66.6667 ),
+};
+
+public static final StrokeFontRec glutStrokeRoman = new StrokeFontRec( "Roman", 128, chars, (float) 119.048, (float) -33.3333 );
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeCharRec.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeCharRec.java
new file mode 100644
index 000000000..af3d538ae
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeCharRec.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1998. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+class StrokeCharRec {
+ public int num_strokes;
+ public StrokeRec[] stroke;
+ public float center;
+ public float right;
+
+ public StrokeCharRec(int num_strokes,
+ StrokeRec[] stroke,
+ float center,
+ float right) {
+ this.num_strokes = num_strokes;
+ this.stroke = stroke;
+ this.center = center;
+ this.right = right;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeFontRec.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeFontRec.java
new file mode 100644
index 000000000..d3195f24d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeFontRec.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1998. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+class StrokeFontRec {
+ public String name;
+ public int num_chars;
+ public StrokeCharRec[] ch;
+ public float top;
+ public float bottom;
+
+ public StrokeFontRec(String name,
+ int num_chars,
+ StrokeCharRec[] ch,
+ float top,
+ float bottom) {
+ this.name = name;
+ this.num_chars = num_chars;
+ this.ch = ch;
+ this.top = top;
+ this.bottom = bottom;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeRec.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeRec.java
new file mode 100644
index 000000000..8796e8b08
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/StrokeRec.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.gl2;
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1998. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+class StrokeRec {
+ public int num_coords;
+ public CoordRec[] coord;
+
+ public StrokeRec(int num_coords,
+ CoordRec[] coord) {
+ this.num_coords = num_coords;
+ this.coord = coord;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/TileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/TileRenderer.java
new file mode 100755
index 000000000..714c134d4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/TileRenderer.java
@@ -0,0 +1,601 @@
+package com.jogamp.opengl.util.gl2;
+
+import java.awt.Dimension;
+import java.nio.Buffer;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import javax.media.opengl.glu.gl2.*;
+
+/**
+ * A fairly direct port of Brian Paul's tile rendering library, found
+ * at <a href = "http://www.mesa3d.org/brianp/TR.html">
+ * http://www.mesa3d.org/brianp/TR.html </a> . I've java-fied it, but
+ * the functionality is the same.
+ *
+ * Original code Copyright (C) 1997-2005 Brian Paul. Licensed under
+ * BSD-compatible terms with permission of the author. See LICENSE.txt
+ * for license information.
+ *
+ * @author ryanm
+ */
+public class TileRenderer
+{
+ private static final int DEFAULT_TILE_WIDTH = 256;
+
+ private static final int DEFAULT_TILE_HEIGHT = 256;
+
+ private static final int DEFAULT_TILE_BORDER = 0;
+
+ //
+ // Enumeration flags for accessing variables
+ //
+ // @author ryanm
+ //
+
+ /**
+ * The width of a tile
+ */
+ public static final int TR_TILE_WIDTH = 0;
+ /**
+ * The height of a tile
+ */
+ public static final int TR_TILE_HEIGHT = 1;
+ /**
+ * The width of the border around the tiles
+ */
+ public static final int TR_TILE_BORDER = 2;
+ /**
+ * The width of the final image
+ */
+ public static final int TR_IMAGE_WIDTH = 3;
+ /**
+ * The height of the final image
+ */
+ public static final int TR_IMAGE_HEIGHT = 4;
+ /**
+ * The number of rows of tiles
+ */
+ public static final int TR_ROWS = 5;
+ /**
+ * The number of columns of tiles
+ */
+ public static final int TR_COLUMNS = 6;
+ /**
+ * The current row number
+ */
+ public static final int TR_CURRENT_ROW = 7;
+ /**
+ * The current column number
+ */
+ public static final int TR_CURRENT_COLUMN = 8;
+ /**
+ * The width of the current tile
+ */
+ public static final int TR_CURRENT_TILE_WIDTH = 9;
+ /**
+ * The height of the current tile
+ */
+ public static final int TR_CURRENT_TILE_HEIGHT = 10;
+ /**
+ * The order that the rows are traversed
+ */
+ public static final int TR_ROW_ORDER = 11;
+
+
+ /**
+ * Indicates we are traversing rows from the top to the bottom
+ */
+ public static final int TR_TOP_TO_BOTTOM = 1;
+
+ /**
+ * Indicates we are traversing rows from the bottom to the top
+ */
+ public static final int TR_BOTTOM_TO_TOP = 2;
+
+ /* Final image parameters */
+ private Dimension imageSize = new Dimension();
+
+ private int imageFormat, imageType;
+
+ private Buffer imageBuffer;
+
+ /* Tile parameters */
+ private Dimension tileSize = new Dimension();
+
+ private Dimension tileSizeNB = new Dimension();
+
+ private int tileBorder;
+
+ private int tileFormat, tileType;
+
+ private Buffer tileBuffer;
+
+ /* Projection parameters */
+ private boolean perspective;
+
+ private double left;
+
+ private double right;
+
+ private double bottom;
+
+ private double top;
+
+ private double near;
+
+ private double far;
+
+ /* Misc */
+ private int rowOrder;
+
+ private int rows, columns;
+
+ private int currentTile;
+
+ private int currentTileWidth, currentTileHeight;
+
+ private int currentRow, currentColumn;
+
+ private int[] viewportSave = new int[ 4 ];
+
+ /**
+ * Creates a new TileRenderer object
+ */
+ public TileRenderer()
+ {
+ tileSize.width = DEFAULT_TILE_WIDTH;
+ tileSize.height = DEFAULT_TILE_HEIGHT;
+ tileBorder = DEFAULT_TILE_BORDER;
+ rowOrder = TR_BOTTOM_TO_TOP;
+ currentTile = -1;
+ }
+
+ /**
+ * Sets up the number of rows and columns needed
+ */
+ private void setup()
+ {
+ columns = ( imageSize.width + tileSizeNB.width - 1 ) / tileSizeNB.width;
+ rows = ( imageSize.height + tileSizeNB.height - 1 ) / tileSizeNB.height;
+ currentTile = 0;
+
+ assert columns >= 0;
+ assert rows >= 0;
+ }
+
+ /**
+ * Sets the size of the tiles to use in rendering. The actual
+ * effective size of the tile depends on the border size, ie (
+ * width - 2*border ) * ( height - 2 * border )
+ *
+ * @param width
+ * The width of the tiles. Must not be larger than the GL
+ * context
+ * @param height
+ * The height of the tiles. Must not be larger than the
+ * GL context
+ * @param border
+ * The width of the borders on each tile. This is needed
+ * to avoid artifacts when rendering lines or points with
+ * thickness > 1.
+ */
+ public void setTileSize( int width, int height, int border )
+ {
+ assert ( border >= 0 );
+ assert ( width >= 1 );
+ assert ( height >= 1 );
+ assert ( width >= 2 * border );
+ assert ( height >= 2 * border );
+
+ tileBorder = border;
+ tileSize.width = width;
+ tileSize.height = height;
+ tileSizeNB.width = width - 2 * border;
+ tileSizeNB.height = height - 2 * border;
+ setup();
+ }
+
+ /**
+ * Specify a buffer the tiles to be copied to. This is not
+ * necessary for the creation of the final image, but useful if you
+ * want to inspect each tile in turn.
+ *
+ * @param format
+ * Interpreted as in glReadPixels
+ * @param type
+ * Interpreted as in glReadPixels
+ * @param image
+ * The buffer itself. Must be large enough to contain a
+ * tile, minus any borders
+ */
+ public void setTileBuffer( int format, int type, Buffer image )
+ {
+ tileFormat = format;
+ tileType = type;
+ tileBuffer = image;
+ }
+
+ /**
+ * Sets the desired size of the final image
+ *
+ * @param width
+ * The width of the final image
+ * @param height
+ * The height of the final image
+ */
+ public void setImageSize( int width, int height )
+ {
+ imageSize.width = width;
+ imageSize.height = height;
+ setup();
+ }
+
+ /**
+ * Sets the buffer in which to store the final image
+ *
+ * @param format
+ * Interpreted as in glReadPixels
+ * @param type
+ * Interpreted as in glReadPixels
+ * @param image
+ * the buffer itself, must be large enough to hold the
+ * final image
+ */
+ public void setImageBuffer( int format, int type, Buffer image )
+ {
+ imageFormat = format;
+ imageType = type;
+ imageBuffer = image;
+ }
+
+ /**
+ * Gets the parameters of this TileRenderer object
+ *
+ * @param param
+ * The parameter that is to be retrieved
+ * @return the value of the parameter
+ */
+ public int getParam( int param )
+ {
+ switch (param) {
+ case TR_TILE_WIDTH:
+ return tileSize.width;
+ case TR_TILE_HEIGHT:
+ return tileSize.height;
+ case TR_TILE_BORDER:
+ return tileBorder;
+ case TR_IMAGE_WIDTH:
+ return imageSize.width;
+ case TR_IMAGE_HEIGHT:
+ return imageSize.height;
+ case TR_ROWS:
+ return rows;
+ case TR_COLUMNS:
+ return columns;
+ case TR_CURRENT_ROW:
+ if( currentTile < 0 )
+ return -1;
+ else
+ return currentRow;
+ case TR_CURRENT_COLUMN:
+ if( currentTile < 0 )
+ return -1;
+ else
+ return currentColumn;
+ case TR_CURRENT_TILE_WIDTH:
+ return currentTileWidth;
+ case TR_CURRENT_TILE_HEIGHT:
+ return currentTileHeight;
+ case TR_ROW_ORDER:
+ return rowOrder;
+ default:
+ throw new IllegalArgumentException("Invalid enumerant as argument");
+ }
+ }
+
+ /**
+ * Sets the order of row traversal
+ *
+ * @param order
+ * The row traversal order, must be
+ * eitherTR_TOP_TO_BOTTOM or TR_BOTTOM_TO_TOP
+ */
+ public void setRowOrder( int order )
+ {
+ if (order == TR_TOP_TO_BOTTOM || order == TR_BOTTOM_TO_TOP) {
+ rowOrder = order;
+ } else {
+ throw new IllegalArgumentException("Must pass TR_TOP_TO_BOTTOM or TR_BOTTOM_TO_TOP");
+ }
+ }
+
+ /**
+ * Sets the context to use an orthographic projection. Must be
+ * called before rendering the first tile
+ *
+ * @param left
+ * As in glOrtho
+ * @param right
+ * As in glOrtho
+ * @param bottom
+ * As in glOrtho
+ * @param top
+ * As in glOrtho
+ * @param zNear
+ * As in glOrtho
+ * @param zFar
+ * As in glOrtho
+ */
+ public void trOrtho( double left, double right, double bottom, double top, double zNear,
+ double zFar )
+ {
+ this.perspective = false;
+ this.left = left;
+ this.right = right;
+ this.bottom = bottom;
+ this.top = top;
+ this.near = zNear;
+ this.far = zFar;
+ }
+
+ /**
+ * Sets the perspective projection frustrum. Must be called before
+ * rendering the first tile
+ *
+ * @param left
+ * As in glFrustrum
+ * @param right
+ * As in glFrustrum
+ * @param bottom
+ * As in glFrustrum
+ * @param top
+ * As in glFrustrum
+ * @param zNear
+ * As in glFrustrum
+ * @param zFar
+ * As in glFrustrum
+ */
+ public void trFrustum( double left, double right, double bottom, double top, double zNear,
+ double zFar )
+ {
+ this.perspective = true;
+ this.left = left;
+ this.right = right;
+ this.bottom = bottom;
+ this.top = top;
+ this.near = zNear;
+ this.far = zFar;
+ }
+
+ /**
+ * Convenient way to specify a perspective projection
+ *
+ * @param fovy
+ * As in gluPerspective
+ * @param aspect
+ * As in gluPerspective
+ * @param zNear
+ * As in gluPerspective
+ * @param zFar
+ * As in gluPerspective
+ */
+ public void trPerspective( double fovy, double aspect, double zNear, double zFar )
+ {
+ double xmin, xmax, ymin, ymax;
+ ymax = zNear * Math.tan( fovy * 3.14159265 / 360.0 );
+ ymin = -ymax;
+ xmin = ymin * aspect;
+ xmax = ymax * aspect;
+ trFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
+ }
+
+ /**
+ * Begins rendering a tile. The projection matrix stack should be
+ * left alone after calling this
+ *
+ * @param gl
+ * The gl context
+ */
+ public void beginTile( GL2 gl )
+ {
+ if (currentTile <= 0) {
+ setup();
+ /*
+ * Save user's viewport, will be restored after last tile
+ * rendered
+ */
+ gl.glGetIntegerv( GL2.GL_VIEWPORT, viewportSave, 0 );
+ }
+
+ /* which tile (by row and column) we're about to render */
+ if (rowOrder == TR_BOTTOM_TO_TOP) {
+ currentRow = currentTile / columns;
+ currentColumn = currentTile % columns;
+ } else {
+ currentRow = rows - ( currentTile / columns ) - 1;
+ currentColumn = currentTile % columns;
+ }
+ assert ( currentRow < rows );
+ assert ( currentColumn < columns );
+
+ int border = tileBorder;
+
+ int th, tw;
+
+ /* Compute actual size of this tile with border */
+ if (currentRow < rows - 1) {
+ th = tileSize.height;
+ } else {
+ th = imageSize.height - ( rows - 1 ) * ( tileSizeNB.height ) + 2 * border;
+ }
+
+ if (currentColumn < columns - 1) {
+ tw = tileSize.width;
+ } else {
+ tw = imageSize.width - ( columns - 1 ) * ( tileSizeNB.width ) + 2 * border;
+ }
+
+ /* Save tile size, with border */
+ currentTileWidth = tw;
+ currentTileHeight = th;
+
+ gl.glViewport( 0, 0, tw, th );
+
+ /* save current matrix mode */
+ int[] matrixMode = new int[ 1 ];
+ gl.glGetIntegerv( GL2.GL_MATRIX_MODE, matrixMode, 0 );
+ gl.glMatrixMode( GL2.GL_PROJECTION );
+ gl.glLoadIdentity();
+
+ /* compute projection parameters */
+ double l =
+ left + ( right - left ) * ( currentColumn * tileSizeNB.width - border )
+ / imageSize.width;
+ double r = l + ( right - left ) * tw / imageSize.width;
+ double b =
+ bottom + ( top - bottom ) * ( currentRow * tileSizeNB.height - border )
+ / imageSize.height;
+ double t = b + ( top - bottom ) * th / imageSize.height;
+
+ if( perspective ) {
+ gl.glFrustum( l, r, b, t, near, far );
+ } else {
+ gl.glOrtho( l, r, b, t, near, far );
+ }
+
+ /* restore user's matrix mode */
+ gl.glMatrixMode( matrixMode[ 0 ] );
+ }
+
+ /**
+ * Must be called after rendering the scene
+ *
+ * @param gl
+ * the gl context
+ * @return true if there are more tiles to be rendered, false if
+ * the final image is complete
+ */
+ public boolean endTile( GL2 gl )
+ {
+ int[] prevRowLength = new int[ 1 ], prevSkipRows = new int[ 1 ], prevSkipPixels = new int[ 1 ], prevAlignment =
+ new int[ 1 ];
+
+ assert ( currentTile >= 0 );
+
+ // be sure OpenGL rendering is finished
+ gl.glFlush();
+
+ // save current glPixelStore values
+ gl.glGetIntegerv( GL2.GL_PACK_ROW_LENGTH, prevRowLength, 0 );
+ gl.glGetIntegerv( GL2.GL_PACK_SKIP_ROWS, prevSkipRows, 0 );
+ gl.glGetIntegerv( GL2.GL_PACK_SKIP_PIXELS, prevSkipPixels, 0 );
+ gl.glGetIntegerv( GL2.GL_PACK_ALIGNMENT, prevAlignment, 0 );
+
+ if( tileBuffer != null ) {
+ int srcX = tileBorder;
+ int srcY = tileBorder;
+ int srcWidth = tileSizeNB.width;
+ int srcHeight = tileSizeNB.height;
+ gl.glReadPixels( srcX, srcY, srcWidth, srcHeight, tileFormat, tileType, tileBuffer );
+ }
+
+ if( imageBuffer != null ) {
+ int srcX = tileBorder;
+ int srcY = tileBorder;
+ int srcWidth = currentTileWidth - 2 * tileBorder;
+ int srcHeight = currentTileHeight - 2 * tileBorder;
+ int destX = tileSizeNB.width * currentColumn;
+ int destY = tileSizeNB.height * currentRow;
+
+ /* setup pixel store for glReadPixels */
+ gl.glPixelStorei( GL2.GL_PACK_ROW_LENGTH, imageSize.width );
+ gl.glPixelStorei( GL2.GL_PACK_SKIP_ROWS, destY );
+ gl.glPixelStorei( GL2.GL_PACK_SKIP_PIXELS, destX );
+ gl.glPixelStorei( GL2.GL_PACK_ALIGNMENT, 1 );
+
+ /* read the tile into the final image */
+ gl.glReadPixels( srcX, srcY, srcWidth, srcHeight, imageFormat, imageType, imageBuffer );
+ }
+
+ /* restore previous glPixelStore values */
+ gl.glPixelStorei( GL2.GL_PACK_ROW_LENGTH, prevRowLength[ 0 ] );
+ gl.glPixelStorei( GL2.GL_PACK_SKIP_ROWS, prevSkipRows[ 0 ] );
+ gl.glPixelStorei( GL2.GL_PACK_SKIP_PIXELS, prevSkipPixels[ 0 ] );
+ gl.glPixelStorei( GL2.GL_PACK_ALIGNMENT, prevAlignment[ 0 ] );
+
+ /* increment tile counter, return 1 if more tiles left to render */
+ currentTile++;
+ if( currentTile >= rows * columns ) {
+ /* restore user's viewport */
+ gl.glViewport( viewportSave[ 0 ], viewportSave[ 1 ], viewportSave[ 2 ], viewportSave[ 3 ] );
+ currentTile = -1; /* all done */
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Tile rendering causes problems with using glRasterPos3f, so you
+ * should use this replacement instead
+ *
+ * @param x
+ * As in glRasterPos3f
+ * @param y
+ * As in glRasterPos3f
+ * @param z
+ * As in glRasterPos3f
+ * @param gl
+ * The gl context
+ * @param glu
+ * A GLUgl2 object
+ */
+ public void trRasterPos3f( float x, float y, float z, GL2 gl, GLUgl2 glu )
+ {
+ if (currentTile < 0) {
+ /* not doing tile rendering right now. Let OpenGL do this. */
+ gl.glRasterPos3f( x, y, z );
+ } else {
+ double[] modelview = new double[ 16 ], proj = new double[ 16 ];
+ int[] viewport = new int[ 4 ];
+ double[] win = new double[3];
+
+ /* Get modelview, projection and viewport */
+ gl.glGetDoublev( GL2.GL_MODELVIEW_MATRIX, modelview, 0 );
+ gl.glGetDoublev( GL2.GL_PROJECTION_MATRIX, proj, 0 );
+ viewport[ 0 ] = 0;
+ viewport[ 1 ] = 0;
+ viewport[ 2 ] = currentTileWidth;
+ viewport[ 3 ] = currentTileHeight;
+
+ /* Project object coord to window coordinate */
+ if( glu.gluProject( x, y, z, modelview, 0, proj, 0, viewport, 0, win, 0 ) ) {
+
+ /* set raster pos to window coord (0,0) */
+ gl.glMatrixMode( GL2.GL_MODELVIEW );
+ gl.glPushMatrix();
+ gl.glLoadIdentity();
+ gl.glMatrixMode( GL2.GL_PROJECTION );
+ gl.glPushMatrix();
+ gl.glLoadIdentity();
+ gl.glOrtho( 0.0, currentTileWidth, 0.0, currentTileHeight, 0.0, 1.0 );
+ gl.glRasterPos3d( 0.0, 0.0, -win[ 2 ] );
+
+ /*
+ * Now use empty bitmap to adjust raster position to
+ * (winX,winY)
+ */
+ {
+ byte[] bitmap = { 0 };
+ gl.glBitmap( 1, 1, 0.0f, 0.0f, ( float ) win[ 0 ], ( float ) win[ 1 ], bitmap , 0 );
+ }
+
+ /* restore original matrices */
+ gl.glPopMatrix(); /* proj */
+ gl.glMatrixMode( GL2.GL_MODELVIEW );
+ gl.glPopMatrix();
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/GLSLArrayHandler.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/GLSLArrayHandler.java
new file mode 100644
index 000000000..1119aa5ab
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/GLSLArrayHandler.java
@@ -0,0 +1,60 @@
+
+package com.jogamp.opengl.util.glsl;
+
+import javax.media.opengl.*;
+import javax.media.opengl.fixedfunc.*;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.glsl.ShaderState;
+import java.nio.*;
+
+public class GLSLArrayHandler implements GLArrayHandler {
+ private GLArrayDataEditable ad;
+
+ public GLSLArrayHandler(GLArrayDataEditable ad) {
+ this.ad = ad;
+ }
+
+ protected final void passVertexAttribPointer(GL2ES2 gl, ShaderState st) {
+ st.glVertexAttribPointer(gl, ad);
+ }
+
+ public void enableBuffer(GL gl, boolean enable) {
+ if(!gl.isGL2ES2()) {
+ throw new GLException("GLSLArrayHandler expects a GL2ES2 implementation");
+ }
+ GL2ES2 glsl = gl.getGL2ES2();
+ ShaderState st = ShaderState.getCurrent();
+ if(null==st) {
+ throw new GLException("No ShaderState current");
+ }
+
+ if(enable) {
+ st.glEnableVertexAttribArray(glsl, ad.getName());
+
+ Buffer buffer = ad.getBuffer();
+
+ if(ad.isVBO()) {
+ // always bind and refresh the VBO mgr,
+ // in case more than one gl*Pointer objects are in use
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, ad.getVBOName());
+ if(!ad.isBufferWritten()) {
+ if(null!=buffer) {
+ glsl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit() * ad.getComponentSize(), buffer, ad.getBufferUsage());
+ }
+ ad.setBufferWritten(true);
+ }
+ passVertexAttribPointer(glsl, st);
+ } else if(null!=buffer) {
+ passVertexAttribPointer(glsl, st);
+ ad.setBufferWritten(true);
+ }
+ } else {
+ if(ad.isVBO()) {
+ glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ }
+ st.glDisableVertexAttribArray(glsl, ad.getName());
+ }
+ }
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
new file mode 100644
index 000000000..d0e7ea29d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
@@ -0,0 +1,348 @@
+
+package com.jogamp.opengl.util.glsl;
+
+import com.jogamp.common.nio.Buffers;
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.impl.Debug;
+
+import java.util.*;
+import java.nio.*;
+import java.io.*;
+import java.net.*;
+import java.security.*;
+
+public class ShaderCode {
+ public static final boolean DEBUG = Debug.debug("GLSLCode");
+ public static final boolean DEBUG_CODE = Debug.isPropertyDefined("jogl.debug.GLSLCode", true, AccessController.getContext());
+
+ public static final String SUFFIX_VERTEX_SOURCE = "vp" ;
+ public static final String SUFFIX_VERTEX_BINARY = "bvp" ;
+ public static final String SUFFIX_FRAGMENT_SOURCE = "fp" ;
+ public static final String SUFFIX_FRAGMENT_BINARY = "bfp" ;
+
+ public static final String SUB_PATH_NVIDIA = "nvidia" ;
+
+ public ShaderCode(int type, int number, String[][] source) {
+ switch (type) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ break;
+ default:
+ throw new GLException("Unknown shader type: "+type);
+ }
+ shaderSource = source;
+ shaderBinaryFormat = -1;
+ shaderBinary = null;
+ shaderType = type;
+ shader = Buffers.newDirectIntBuffer(number);
+ id = getNextID();
+
+ if(DEBUG_CODE) {
+ System.out.println("Created: "+toString());
+ dumpShaderSource(System.out);
+ }
+ }
+
+ public ShaderCode(int type, int number, int binFormat, Buffer binary) {
+ switch (type) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ break;
+ default:
+ throw new GLException("Unknown shader type: "+type);
+ }
+ shaderSource = null;
+ shaderBinaryFormat = binFormat;
+ shaderBinary = binary;
+ shaderType = type;
+ shader = Buffers.newDirectIntBuffer(number);
+ id = getNextID();
+ }
+
+ public static ShaderCode create(GL2ES2 gl, int type, int number, Class context, String[] sourceFiles) {
+ if(!ShaderUtil.isShaderCompilerAvailable(gl)) return null;
+
+ String[][] shaderSources = null;
+ if(null!=sourceFiles) {
+ shaderSources = new String[sourceFiles.length][1];
+ for(int i=0; null!=shaderSources && i<sourceFiles.length; i++) {
+ shaderSources[i][0] = readShaderSource(context, sourceFiles[i]);
+ if(null == shaderSources[i][0]) {
+ shaderSources = null;
+ }
+ }
+ }
+ if(null==shaderSources) {
+ return null;
+ }
+ return new ShaderCode(type, number, shaderSources);
+ }
+
+ public static ShaderCode create(int type, int number, Class context, int binFormat, String binaryFile) {
+ ByteBuffer shaderBinary = null;
+ if(null!=binaryFile && 0<=binFormat) {
+ shaderBinary = readShaderBinary(context, binaryFile);
+ if(null == shaderBinary) {
+ binFormat = -1;
+ }
+ }
+ if(null==shaderBinary) {
+ return null;
+ }
+ return new ShaderCode(type, number, binFormat, shaderBinary);
+ }
+
+ public static String getFileSuffix(boolean binary, int type) {
+ switch (type) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ return binary?SUFFIX_VERTEX_BINARY:SUFFIX_VERTEX_SOURCE;
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ return binary?SUFFIX_FRAGMENT_BINARY:SUFFIX_FRAGMENT_SOURCE;
+ default:
+ throw new GLException("illegal shader type: "+type);
+ }
+ }
+
+ public static String getBinarySubPath(int binFormat) {
+ switch (binFormat) {
+ case GLES2.GL_NVIDIA_PLATFORM_BINARY_NV:
+ return SUB_PATH_NVIDIA;
+ default:
+ throw new GLException("unsupported binary format: "+binFormat);
+ }
+ }
+
+ public static ShaderCode create(GL2ES2 gl, int type, int number, Class context,
+ String srcRoot, String binRoot, String basename) {
+ ShaderCode res = null;
+ String srcFileName = null;
+ String binFileName = null;
+
+ if(ShaderUtil.isShaderCompilerAvailable(gl)) {
+ String srcPath[] = new String[1];
+ srcFileName = srcRoot + '/' + basename + "." + getFileSuffix(false, type);
+ srcPath[0] = srcFileName;
+ res = create(gl, type, number, context, srcPath);
+ if(null!=res) {
+ return res;
+ }
+ }
+ Set binFmts = ShaderUtil.getShaderBinaryFormats(gl);
+ for(Iterator iter=binFmts.iterator(); null==res && iter.hasNext(); ) {
+ int bFmt = ((Integer)(iter.next())).intValue();
+ String bFmtPath = getBinarySubPath(bFmt);
+ if(null==bFmtPath) continue;
+ binFileName = binRoot + '/' + bFmtPath + '/' + basename + "." + getFileSuffix(true, type);
+ res = create(type, number, context, bFmt, binFileName);
+ }
+
+ if(null==res) {
+ throw new GLException("No shader code found (source nor binary) for src: "+srcFileName+
+ ", bin: "+binFileName);
+ }
+
+ return res;
+ }
+
+ /**
+ * returns the uniq shader id as an integer
+ * @see #key()
+ */
+ public int id() { return id.intValue(); }
+
+ /**
+ * returns the uniq shader id as an Integer
+ *
+ * @see #id()
+ */
+ public Integer key() { return id; }
+
+ public int shaderType() { return shaderType; }
+ public String shaderTypeStr() { return shaderTypeStr(shaderType); }
+
+ public static String shaderTypeStr(int type) {
+ switch (type) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ return "VERTEX_SHADER";
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ return "FRAGMENT_SHADER";
+ }
+ return "UNKNOWN_SHADER";
+ }
+
+ public int shaderBinaryFormat() { return shaderBinaryFormat; }
+ public Buffer shaderBinary() { return shaderBinary; }
+ public String[][] shaderSource() { return shaderSource; }
+
+ public boolean isValid() { return valid; }
+
+ public IntBuffer shader() { return shader; }
+
+ public boolean compile(GL2ES2 gl) {
+ return compile(gl, null);
+ }
+ public boolean compile(GL2ES2 gl, PrintStream verboseOut) {
+ if(isValid()) return true;
+
+ // Create & Compile the vertex/fragment shader objects
+ if(null!=shaderSource) {
+ valid=ShaderUtil.createAndCompileShader(gl, shader, shaderType,
+ shaderSource, verboseOut);
+ } else if(null!=shaderBinary) {
+ valid=ShaderUtil.createAndLoadShader(gl, shader, shaderType,
+ shaderBinaryFormat, shaderBinary, verboseOut);
+ } else {
+ throw new GLException("no code (source or binary)");
+ }
+ return valid;
+ }
+
+ public void destroy(GL2ES2 gl) {
+ if(isValid()) {
+ if(null!=gl) {
+ ShaderUtil.deleteShader(gl, shader());
+ }
+ valid=false;
+ }
+ if(null!=shaderBinary) {
+ shaderBinary.clear();
+ shaderBinary=null;
+ }
+ shaderSource=null;
+ shaderBinaryFormat=-1;
+ shaderType=-1;
+ id=null;
+ }
+
+ public boolean equals(Object obj) {
+ if(this==obj) return true;
+ if(obj instanceof ShaderCode) {
+ return id()==((ShaderCode)obj).id();
+ }
+ return false;
+ }
+ public int hashCode() {
+ return id.intValue();
+ }
+ public String toString() {
+ StringBuffer buf = new StringBuffer("ShaderCode [id="+id+", type="+shaderTypeStr()+", valid="+valid+", shader: ");
+ for(int i=0; i<shader.remaining(); i++) {
+ buf.append(" "+shader.get(i));
+ }
+ if(null!=shaderSource) {
+ buf.append(", source]");
+ } else if(null!=shaderBinary) {
+ buf.append(", binary "+shaderBinary+"]");
+ }
+ return buf.toString();
+ }
+
+ public void dumpShaderSource(PrintStream out) {
+ if(null==shaderSource) {
+ out.println("<no shader source>");
+ return;
+ }
+ int sourceNum = (null!=shaderSource)?shaderSource.length:0;
+ int shaderNum = (null!=shader)?shader.capacity():0;
+ for(int i=0; i<shaderNum; i++) {
+ out.println("");
+ out.println("Shader #"+i+"/"+shaderNum+" name "+shader.get(i));
+ out.println("--------------------------------------------------------------");
+ if(i>=sourceNum) {
+ out.println("<no shader source>");
+ } else {
+ String[] src = shaderSource[i];
+ for(int j=0; j<src.length; j++) {
+ out.println("Segment "+j+"/"+src.length+" :");
+ out.println(src[j]);
+ out.println("");
+ }
+ }
+ out.println("--------------------------------------------------------------");
+ }
+ }
+
+ public static void readShaderSource(ClassLoader context, String path, URL url, StringBuffer result) {
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith("#include ")) {
+ String includeFile = line.substring(9).trim();
+ // Try relative path first
+ String next = Locator.getRelativeOf(path, includeFile);
+ URL nextURL = Locator.getResource(next, context);
+ if (nextURL == null) {
+ // Try absolute path
+ next = includeFile;
+ nextURL = Locator.getResource(next, context);
+ }
+ if (nextURL == null) {
+ // Fail
+ throw new FileNotFoundException("Can't find include file " + includeFile);
+ }
+ readShaderSource(context, next, nextURL, result);
+ } else {
+ result.append(line + "\n");
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String readShaderSource(Class context, String path) {
+ ClassLoader contextCL = (null!=context)?context.getClassLoader():null;
+ URL url = Locator.getResource(path, contextCL);
+ if (url == null && null!=context) {
+ // Try again by scoping the path within the class's package
+ String className = context.getName().replace('.', '/');
+ int lastSlash = className.lastIndexOf('/');
+ if (lastSlash >= 0) {
+ String tmpPath = className.substring(0, lastSlash + 1) + path;
+ url = Locator.getResource(tmpPath, contextCL);
+ if (url != null) {
+ path = tmpPath;
+ }
+ }
+ }
+ if (url == null) {
+ return null;
+ }
+ StringBuffer result = new StringBuffer();
+ readShaderSource(contextCL, path, url, result);
+ return result.toString();
+ }
+
+ public static ByteBuffer readShaderBinary(Class context, String path) {
+ try {
+ URL url = Locator.getResource(context, path);
+ if (url == null) {
+ return null;
+ }
+ return StreamUtil.readAll2Buffer(new BufferedInputStream(url.openStream()));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ protected String[][] shaderSource = null;
+ protected Buffer shaderBinary = null;
+ protected int shaderBinaryFormat = -1;
+ protected IntBuffer shader = null;
+ protected int shaderType = -1;
+ protected Integer id = null;
+
+ protected boolean valid=false;
+
+ private static synchronized Integer getNextID() {
+ return new Integer(nextID++);
+ }
+ protected static int nextID = 1;
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
new file mode 100644
index 000000000..430ed08ce
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
@@ -0,0 +1,215 @@
+
+package com.jogamp.opengl.util.glsl;
+
+import javax.media.opengl.*;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.io.PrintStream;
+
+public class ShaderProgram {
+ public ShaderProgram() {
+ id = getNextID();
+ }
+
+ public boolean linked() {
+ return programLinked;
+ }
+
+ public boolean inUse() {
+ return programInUse;
+ }
+
+ public int program() { return shaderProgram; }
+
+ /**
+ * returns the uniq shader id as an integer
+ * @see #key()
+ */
+ public int id() { return id.intValue(); }
+
+ /**
+ * returns the uniq shader id as an Integer
+ *
+ * @see #id()
+ */
+ public Integer key() { return id; }
+
+ /**
+ * Detaches all shader codes and deletes the program.
+ * Destroys the shader codes as well.
+ * Calls release(gl, true)
+ *
+ * @see #release(GL2ES2, boolean)
+ */
+ public synchronized void destroy(GL2ES2 gl) {
+ release(gl, true);
+ }
+
+ /**
+ * Detaches all shader codes and deletes the program.
+ * Calls release(gl, false)
+ *
+ * @see #release(GL2ES2, boolean)
+ */
+ public synchronized void release(GL2ES2 gl) {
+ release(gl, false);
+ }
+
+ /**
+ * Detaches all shader codes and deletes the program.
+ * If releaseShaderToo is true, destroys the shader codes as well.
+ */
+ public synchronized void release(GL2ES2 gl, boolean releaseShaderToo) {
+ glUseProgram(gl, false);
+ for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
+ ShaderCode shaderCode = (ShaderCode) iter.next();
+ ShaderUtil.detachShader(gl, shaderProgram, shaderCode.shader());
+ if(releaseShaderToo) {
+ shaderCode.destroy(gl);
+ }
+ }
+ shaderMap.clear();
+ gl.glDeleteProgram(shaderProgram);
+ shaderProgram=-1;
+ }
+
+ //
+ // ShaderCode handling
+ //
+
+ /**
+ * Adds a new shader to a this non running program.
+ *
+ * @return false if the program is in use, or the shader already exist,
+ * otherwise true.
+ */
+ public synchronized boolean add(ShaderCode shaderCode) {
+ if(shaderMap.containsKey(shaderCode.key())) return false;
+ shaderMap.put(shaderCode.key(), shaderCode);
+ return true;
+ }
+
+ public synchronized ShaderCode getShader(int id) {
+ return (ShaderCode) shaderMap.get(new Integer(id));
+ }
+
+ //
+ // Program handling
+ //
+
+ /**
+ * Replace a shader in a 'running' program.
+ * Refetches all previously bin/get attribute names
+ * and resets all attribute data as well
+ *
+ * @param gl
+ * @param oldShaderID the to be replace Shader
+ * @param newShader the new ShaderCode
+ * @param verboseOut the optional verbose outputstream
+ * @throws GLException is the program is not linked
+ *
+ * @see ShaderState#glEnableVertexAttribArray
+ * @see ShaderState#glDisableVertexAttribArray
+ * @see ShaderState#glVertexAttribPointer
+ * @see ShaderState#getVertexAttribPointer
+ * @see ShaderState#glReleaseAllVertexAttributes
+ * @see ShaderState#glResetAllVertexAttributes
+ * @see ShaderState#glResetAllVertexAttributes
+ * @see ShaderState#glResetAllVertexAttributes
+ */
+ public synchronized boolean glReplaceShader(GL2ES2 gl, int oldShaderID, ShaderCode newShader, PrintStream verboseOut) {
+ if(!programLinked) throw new GLException("Program is not linked");
+ boolean shaderWasInUse = programInUse;
+ glUseProgram(gl, false);
+ if(!newShader.compile(gl, verboseOut)) {
+ return false;
+ }
+ if(oldShaderID>=0) {
+ ShaderCode oldShader = (ShaderCode) shaderMap.remove(new Integer(oldShaderID));
+ if(null!=oldShader) {
+ ShaderUtil.detachShader(gl, shaderProgram, oldShader.shader());
+ }
+ }
+ add(newShader);
+
+ ShaderUtil.attachShader(gl, shaderProgram, newShader.shader());
+ gl.glLinkProgram(shaderProgram);
+ if ( ! ShaderUtil.isProgramValid(gl, shaderProgram, System.err) ) {
+ return false;
+ }
+
+ if(shaderWasInUse) {
+ glUseProgram(gl, true);
+ }
+ return true;
+ }
+
+ public synchronized boolean link(GL2ES2 gl, PrintStream verboseOut) {
+ if(programLinked) throw new GLException("Program is already linked");
+
+ if(0>shaderProgram) {
+ shaderProgram = gl.glCreateProgram();
+ }
+
+ for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
+ ShaderCode shaderCode = (ShaderCode) iter.next();
+ if(!shaderCode.compile(gl, verboseOut)) {
+ return false;
+ }
+ ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader());
+ }
+
+ // Link the program
+ gl.glLinkProgram(shaderProgram);
+
+ programLinked = ShaderUtil.isProgramValid(gl, shaderProgram, System.err);
+
+ return programLinked;
+ }
+
+ public boolean equals(Object obj) {
+ if(this==obj) return true;
+ if(obj instanceof ShaderCode) {
+ return id()==((ShaderCode)obj).id();
+ }
+ return false;
+ }
+ public int hashCode() {
+ return id.intValue();
+ }
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("ShaderProgram[id="+id);
+ buf.append(", linked="+programLinked+", inUse="+programInUse+", program: "+shaderProgram+", [");
+ for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
+ buf.append((ShaderCode) iter.next());
+ buf.append(" ");
+ }
+ buf.append("]");
+ return buf.toString();
+ }
+
+ protected synchronized void glUseProgram(GL2ES2 gl, boolean on) {
+ if(!programLinked) throw new GLException("Program is not linked");
+ if(programInUse==on) return;
+ gl.glUseProgram(on?shaderProgram:0);
+ programInUse = on;
+
+ //Throwable tX = new Throwable("Info: ShaderProgram.glUseProgram: "+on);
+ //tX.printStackTrace();
+
+ }
+
+ protected boolean programLinked = false;
+ protected boolean programInUse = false;
+ protected int shaderProgram=-1;
+ protected HashMap shaderMap = new HashMap();
+ protected Integer id = null;
+
+ private static synchronized Integer getNextID() {
+ return new Integer(nextID++);
+ }
+ protected static int nextID = 1;
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
new file mode 100644
index 000000000..86f9251b7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
@@ -0,0 +1,649 @@
+
+package com.jogamp.opengl.util.glsl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.Debug;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.security.*;
+
+public class ShaderState {
+ public static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.GLSLState", true, AccessController.getContext());
+
+ public ShaderState() {
+ }
+
+ public boolean verbose() { return verbose; }
+
+ public void setVerbose(boolean v) { verbose=v; }
+
+ /**
+ * Fetches the current shader state from the thread local storage (TLS)
+ *
+ * @see com.jogamp.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrent()
+ */
+ public static synchronized ShaderState getCurrent() {
+ GLContext current = GLContext.getCurrent();
+ if(null==current) {
+ throw new GLException("No context is current on this thread");
+ }
+ return (ShaderState) current.getAttachedObject(ShaderState.class.getName());
+ }
+
+ /**
+ * Turns the shader program on or off.<br>
+ * Puts this ShaderState to to the thread local storage (TLS),
+ * if <code>on</code> is <code>true</code>.
+ *
+ * @see com.jogamp.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrent()
+ */
+ public synchronized void glUseProgram(GL2ES2 gl, boolean on) {
+ if(on) {
+ if(null!=shaderProgram) {
+ shaderProgram.glUseProgram(gl, true);
+ } else {
+ throw new GLException("No program is attached");
+ }
+ // update the current ShaderState to the TLS ..
+ gl.getContext().putAttachedObject(ShaderState.class.getName(), this);
+ } else if(null!=shaderProgram) {
+ shaderProgram.glUseProgram(gl, false);
+ }
+ }
+
+ public boolean linked() {
+ return (null!=shaderProgram)?shaderProgram.linked():false;
+ }
+
+ public boolean inUse() {
+ return (null!=shaderProgram)?shaderProgram.inUse():false;
+ }
+
+ /**
+ * Attach or switch a shader program
+ *
+ * Attaching a shader program the first time,
+ * as well as switching to another program on the fly,
+ * while managing all attribute and uniform data.
+ */
+ public synchronized void attachShaderProgram(GL2ES2 gl, ShaderProgram prog) {
+ boolean prgInUse = false; // earmarked state
+
+ if(DEBUG) {
+ int curId = (null!=shaderProgram)?shaderProgram.id():-1;
+ int newId = (null!=prog)?prog.id():-1;
+ System.err.println("Info: attachShaderProgram: "+curId+" -> "+newId+"\n\t"+shaderProgram+"\n\t"+prog);
+ if(verbose) {
+ Throwable tX = new Throwable("Info: attachShaderProgram: Trace");
+ tX.printStackTrace();
+ }
+ }
+ if(null!=shaderProgram) {
+ if(shaderProgram.equals(prog)) {
+ // nothing to do ..
+ if(DEBUG) {
+ System.err.println("Info: attachShaderProgram: NOP: equal id: "+shaderProgram.id());
+ }
+ return;
+ }
+ prgInUse = shaderProgram.inUse();
+ shaderProgram.glUseProgram(gl, false);
+ }
+
+ // register new one
+ shaderProgram = prog;
+
+ if(null!=shaderProgram) {
+ // reinstall all data ..
+ shaderProgram.glUseProgram(gl, true);
+ glResetAllVertexAttributes(gl);
+ glResetAllUniforms(gl);
+ if(!prgInUse) {
+ shaderProgram.glUseProgram(gl, false);
+ }
+ }
+ if(DEBUG) {
+ System.err.println("Info: attachShaderProgram: END");
+ }
+ }
+
+ public ShaderProgram shaderProgram() { return shaderProgram; }
+
+ /**
+ * Calls release(gl, true, true)
+ *
+ * @see #glReleaseAllVertexAttributes
+ * @see #glReleaseAllUniforms
+ * @see #release(GL2ES2, boolean, boolean)
+ */
+ public synchronized void destroy(GL2ES2 gl) {
+ release(gl, true, true);
+ }
+
+ /**
+ * Calls release(gl, false, false)
+ *
+ * @see #glReleaseAllVertexAttributes
+ * @see #glReleaseAllUniforms
+ * @see #release(GL2ES2, boolean, boolean)
+ */
+ public synchronized void releaseAllData(GL2ES2 gl) {
+ release(gl, false, false);
+ }
+
+ /**
+ * @see #glReleaseAllVertexAttributes
+ * @see #glReleaseAllUniforms
+ * @see ShaderProgram#release(GL2ES2, boolean)
+ */
+ public synchronized void release(GL2ES2 gl, boolean releaseProgramToo, boolean releaseShaderToo) {
+ boolean prgInUse = false;
+ if(null!=shaderProgram) {
+ prgInUse = shaderProgram.inUse();
+ if(!prgInUse) {
+ shaderProgram.glUseProgram(gl, true);
+ }
+ }
+ glReleaseAllVertexAttributes(gl);
+ glReleaseAllUniforms(gl);
+ if(null!=shaderProgram) {
+ if(releaseProgramToo) {
+ shaderProgram.release(gl, releaseShaderToo);
+ } else if(!prgInUse) {
+ shaderProgram.glUseProgram(gl, false);
+ }
+ }
+ }
+
+ //
+ // Shader attribute handling
+ //
+
+ /**
+ * Binds an attribute to the shader.
+ * This must be done before the program is linked !
+ * n name - 1 idx, where name is a uniq key
+ *
+ * @throws GLException is the program is already linked
+ *
+ * @see #glBindAttribLocation
+ * @see javax.media.opengl.GL2ES2#glBindAttribLocation
+ * @see #glGetAttribLocation
+ * @see javax.media.opengl.GL2ES2#glGetAttribLocation
+ * @see #getAttribLocation
+ * @see ShaderProgram#glReplaceShader
+ */
+ public void glBindAttribLocation(GL2ES2 gl, int index, String name) {
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ if(shaderProgram.linked()) throw new GLException("Program is already linked");
+ Integer idx = new Integer(index);
+ if(!attribMap2Idx.containsKey(name)) {
+ attribMap2Idx.put(name, idx);
+ gl.glBindAttribLocation(shaderProgram.program(), index, name);
+ }
+ }
+
+ /**
+ * Gets the index of a shader attribute.
+ * This must be done after the program is linked !
+ *
+ * @return -1 if there is no such attribute available,
+ * otherwise >= 0
+ * @throws GLException is the program is not linked
+ *
+ * @see #glBindAttribLocation
+ * @see javax.media.opengl.GL2ES2#glBindAttribLocation
+ * @see #glGetAttribLocation
+ * @see javax.media.opengl.GL2ES2#glGetAttribLocation
+ * @see #getAttribLocation
+ * @see ShaderProgram#glReplaceShader
+ */
+ public int glGetAttribLocation(GL2ES2 gl, String name) {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
+ int index = getAttribLocation(name);
+ if(0>index) {
+ index = gl.glGetAttribLocation(shaderProgram.program(), name);
+ if(0<=index) {
+ Integer idx = new Integer(index);
+ attribMap2Idx.put(name, idx);
+ if(DEBUG) {
+ System.err.println("Info: glGetAttribLocation: "+name+", loc: "+index);
+ }
+ } else if(verbose) {
+ Throwable tX = new Throwable("Info: glGetAttribLocation failed, no location for: "+name+", index: "+index);
+ tX.printStackTrace();
+ }
+ }
+ return index;
+ }
+
+ protected int getAttribLocation(String name) {
+ Integer idx = (Integer) attribMap2Idx.get(name);
+ return (null!=idx)?idx.intValue():-1;
+ }
+
+
+ //
+ // Enabled Vertex Arrays and its data
+ //
+
+ /**
+ * Enable a vertex attribute array
+ *
+ * Even if the attribute is not found in the current shader,
+ * it is stored in this state.
+ *
+ * @return false, if the name is not found, otherwise true
+ *
+ * @throws GLException if the program is not in use
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see ShaderProgram#glReplaceShader
+ */
+ public boolean glEnableVertexAttribArray(GL2ES2 gl, String name) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ enabledVertexAttribArraySet.add(name);
+ int index = glGetAttribLocation(gl, name);
+ if(0>index) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glEnableVertexAttribArray failed, no index for: "+name);
+ tX.printStackTrace();
+ }
+ return false;
+ }
+ if(DEBUG) {
+ System.err.println("Info: glEnableVertexAttribArray: "+name+", loc: "+index);
+ }
+ gl.glEnableVertexAttribArray(index);
+ return true;
+ }
+
+ public boolean isVertexAttribArrayEnabled(String name) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ return enabledVertexAttribArraySet.contains(name);
+ }
+
+ /**
+ * Disables a vertex attribute array
+ *
+ * Even if the attribute is not found in the current shader,
+ * it is removed from this state.
+ *
+ * @return false, if the name is not found, otherwise true
+ *
+ * @throws GLException if the program is not in use
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see ShaderProgram#glReplaceShader
+ */
+ public boolean glDisableVertexAttribArray(GL2ES2 gl, String name) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ enabledVertexAttribArraySet.remove(name);
+ int index = glGetAttribLocation(gl, name);
+ if(0>index) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glDisableVertexAttribArray failed, no index for: "+name);
+ tX.printStackTrace();
+ }
+ return false;
+ }
+ if(DEBUG) {
+ System.err.println("Info: glDisableVertexAttribArray: "+name);
+ }
+ gl.glDisableVertexAttribArray(index);
+ return true;
+ }
+
+ /**
+ * Set the vertex attribute data.
+ * Enable the attribute, if it is not enabled yet.
+ *
+ * Even if the attribute is not found in the current shader,
+ * it is stored in this state.
+ *
+ * @param data the GLArrayData's name must match the attributes one,
+ * it's index will be set with the attribute's location,
+ * if found.
+ *
+ * @return false, if the name is not found, otherwise true
+ *
+ * @throws GLException if the program is not in use
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see ShaderProgram#glReplaceShader
+ */
+ public boolean glVertexAttribPointer(GL2ES2 gl, GLArrayData data) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ if(!enabledVertexAttribArraySet.contains(data.getName())) {
+ if(!glEnableVertexAttribArray(gl, data.getName())) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glVertexAttribPointer: couldn't enable: "+data);
+ tX.printStackTrace();
+ }
+ }
+ }
+ int index = getAttribLocation(data.getName());
+ if(0>index) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glVertexAttribPointer failed, no index for: "+data);
+ tX.printStackTrace();
+ }
+ }
+ data.setLocation(index);
+ vertexAttribMap2Data.put(data.getName(), data);
+ if(0<=index) {
+ // only pass the data, if the attribute exists in the current shader
+ if(DEBUG) {
+ System.err.println("Info: glVertexAttribPointer: "+data);
+ }
+ gl.glVertexAttribPointer(data);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Get the vertex attribute data, previously set.
+ *
+ * @return the GLArrayData object, null if not previously set.
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see ShaderProgram#glReplaceShader
+ */
+ public GLArrayData getVertexAttribPointer(String name) {
+ return (GLArrayData) vertexAttribMap2Data.get(name);
+ }
+
+ /**
+ * Releases all mapped vertex attribute data,
+ * disables all enabled attributes and loses all indices
+ *
+ * @throws GLException is the program is not in use but the shaderProgram is set
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see ShaderProgram#glReplaceShader
+ */
+ public void glReleaseAllVertexAttributes(GL2ES2 gl) {
+ if(null!=shaderProgram) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ for(Iterator iter = vertexAttribMap2Data.keySet().iterator(); iter.hasNext(); ) {
+ if(!glDisableVertexAttribArray(gl, (String) iter.next())) {
+ throw new GLException("Internal Error: mapped vertex attribute couldn't be disabled");
+ }
+ }
+ for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
+ if(!glDisableVertexAttribArray(gl, (String) iter.next())) {
+ throw new GLException("Internal Error: prev enabled vertex attribute couldn't be disabled");
+ }
+ }
+ }
+ vertexAttribMap2Data.clear();
+ enabledVertexAttribArraySet.clear();
+ attribMap2Idx.clear();
+ }
+
+ /**
+ * Disables all vertex attribute arrays.
+ *
+ * Their enabled stated will be removed from this state only
+ * if 'removeFromState' is true.
+ *
+ * This method purpose is more for debugging.
+ *
+ * @throws GLException is the program is not in use but the shaderProgram is set
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see ShaderProgram#glReplaceShader
+ */
+ public void glDisableAllVertexAttributeArrays(GL2ES2 gl, boolean removeFromState) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+
+ for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
+ String name = (String) iter.next();
+ if(removeFromState) {
+ enabledVertexAttribArraySet.remove(name);
+ }
+ int index = glGetAttribLocation(gl, name);
+ if(0<=index) {
+ gl.glDisableVertexAttribArray(index);
+ }
+ }
+ }
+
+ /**
+ * Reset all previously enabled mapped vertex attribute data,
+ * incl enabling them
+ *
+ * @throws GLException is the program is not in use
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see ShaderProgram#glReplaceShader
+ */
+ public void glResetAllVertexAttributes(GL2ES2 gl) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ attribMap2Idx.clear();
+
+ /**
+ *
+ for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
+ glEnableVertexAttribArray(gl, (String) iter.next());
+ }
+ for(Iterator iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
+ GLArrayData data = (GLArrayData) iter.next();
+
+ ...
+ } */
+
+ for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
+ // get new location ..
+ String name = (String) iter.next();
+ int loc = glGetAttribLocation(gl, name);
+
+ // get & update data ..
+ GLArrayData data = getVertexAttribPointer(name);
+ data.setLocation(loc);
+ vertexAttribMap2Data.put(name, data);
+
+ if(0>loc) {
+ // not used in shader
+ continue;
+ }
+
+ // enable attrib, VBO and pass location/data
+ gl.glEnableVertexAttribArray(loc);
+
+ if( data.isVBO() ) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, data.getVBOName());
+ }
+
+ gl.glVertexAttribPointer(data);
+ }
+ }
+
+ //
+ // Shader Uniform handling
+ //
+
+ /**
+ * Gets the index of a shader uniform.
+ * This must be done when the program is in use !
+ *
+ * @return -1 if there is no such attribute available,
+ * otherwise >= 0
+
+ * @throws GLException is the program is not linked
+ *
+ * @see #glGetUniformLocation
+ * @see javax.media.opengl.GL2ES2#glGetUniformLocation
+ * @see #getUniformLocation
+ * @see ShaderProgram#glReplaceShader
+ */
+ protected int glGetUniformLocation(GL2ES2 gl, String name) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ int index = getUniformLocation(name);
+ if(0>index) {
+ index = gl.glGetUniformLocation(shaderProgram.program(), name);
+ if(0<=index) {
+ Integer idx = new Integer(index);
+ uniformMap2Idx.put(name, idx);
+ } else if(verbose) {
+ Throwable tX = new Throwable("Info: glUniform failed, no location for: "+name+", index: "+index);
+ tX.printStackTrace();
+ }
+ }
+ return index;
+ }
+
+ protected int getUniformLocation(String name) {
+ Integer idx = (Integer) uniformMap2Idx.get(name);
+ return (null!=idx)?idx.intValue():-1;
+ }
+
+ /**
+ * Set the uniform data.
+ *
+ * Even if the uniform is not found in the current shader,
+ * it is stored in this state.
+ *
+ * @param data the GLUniforms's name must match the uniform one,
+ * it's index will be set with the uniforms's location,
+ * if found.
+ *
+ *
+ * @return false, if the name is not found, otherwise true
+ *
+ * @throws GLException if the program is not in use
+ *
+ * @see #glGetUniformLocation
+ * @see javax.media.opengl.GL2ES2#glGetUniformLocation
+ * @see #getUniformLocation
+ * @see ShaderProgram#glReplaceShader
+ */
+ public boolean glUniform(GL2ES2 gl, GLUniformData data) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ int location = glGetUniformLocation(gl, data.getName());
+ data.setLocation(location);
+ uniformMap2Data.put(data.getName(), data);
+ if(0<=location) {
+ // only pass the data, if the uniform exists in the current shader
+ if(DEBUG) {
+ System.err.println("Info: glUniform: "+data);
+ }
+ gl.glUniform(data);
+ }
+ return true;
+ }
+
+ /**
+ * Get the uniform data, previously set.
+ *
+ * @return the GLUniformData object, null if not previously set.
+ */
+ public GLUniformData getUniform(String name) {
+ return (GLUniformData) uniformMap2Data.get(name);
+ }
+
+ /**
+ * Releases all mapped uniform data
+ * and loses all indices
+ *
+ * @throws GLException is the program is not in use
+ */
+ public void glReleaseAllUniforms(GL2ES2 gl) {
+ uniformMap2Data.clear();
+ uniformMap2Idx.clear();
+ }
+
+ /**
+ * Reset all previously mapped uniform data
+ *
+ * @throws GLException is the program is not in use
+ */
+ public void glResetAllUniforms(GL2ES2 gl) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ uniformMap2Idx.clear();
+ for(Iterator iter = uniformMap2Data.values().iterator(); iter.hasNext(); ) {
+ glUniform(gl, (GLUniformData) iter.next());
+ }
+ }
+
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("ShaderState[");
+ buf.append(shaderProgram.toString());
+ buf.append(",EnabledStates: [");
+ for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
+ buf.append("\n ");
+ buf.append((String)iter.next());
+ }
+ buf.append("], [");
+ for(Iterator iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
+ GLArrayData data = (GLArrayData) iter.next();
+ if(data.getLocation()>=0) {
+ buf.append("\n ");
+ buf.append(data);
+ }
+ }
+ buf.append("], [");
+ for(Iterator iter=uniformMap2Data.values().iterator(); iter.hasNext(); ) {
+ GLUniformData data = (GLUniformData) iter.next();
+ if(data.getLocation()>=0) {
+ buf.append("\n ");
+ buf.append(data);
+ }
+ }
+ buf.append("]");
+ return buf.toString();
+ }
+
+ protected boolean verbose = false;
+ protected ShaderProgram shaderProgram=null;
+ protected HashMap attribMap2Idx = new HashMap();
+ protected HashSet enabledVertexAttribArraySet = new HashSet();
+ protected HashMap vertexAttribMap2Data = new HashMap();
+ protected HashMap uniformMap2Idx = new HashMap();
+ protected HashMap uniformMap2Data = new HashMap();
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
new file mode 100644
index 000000000..c7e845953
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.opengl.util.glsl;
+
+import java.io.PrintStream;
+import java.nio.*;
+import java.util.*;
+
+import javax.media.opengl.*;
+
+public class ShaderUtil {
+ static abstract class Impl {
+ public abstract String getShaderInfoLog(GL gl, int shaderObj);
+ public abstract String getProgramInfoLog(GL gl, int programObj);
+ public abstract boolean isShaderStatusValid(GL gl, int shaderObj, int name);
+ public abstract boolean isShaderStatusValid(GL gl, int shaderObj, int name, PrintStream verboseOut);
+ public abstract boolean isShaderStatusValid(GL gl, IntBuffer shaders, int name);
+ public abstract boolean isShaderStatusValid(GL gl, IntBuffer shaders, int name, PrintStream verboseOut);
+ public abstract boolean isProgramStatusValid(GL gl, int programObj, int name);
+ public abstract boolean isProgramValid(GL gl, int programObj);
+ public abstract boolean isProgramValid(GL gl, int programObj, PrintStream verboseOut);
+ public abstract void createShader(GL gl, int type, IntBuffer shaders);
+ public abstract Set getShaderBinaryFormats(GL gl);
+ public abstract boolean isShaderCompilerAvailable(GL gl);
+ public abstract void shaderSource(GL gl, int shader, java.lang.String[] source);
+ public abstract void shaderSource(GL gl, IntBuffer shaders, java.lang.String[][] sources);
+ public abstract void shaderBinary(GL gl, IntBuffer shaders, int binFormat, java.nio.Buffer bin);
+ public abstract void compileShader(GL gl, IntBuffer shaders);
+ public abstract void attachShader(GL gl, int program, IntBuffer shaders);
+ public abstract void detachShader(GL gl, int program, IntBuffer shaders);
+ public abstract void deleteShader(GL gl, IntBuffer shaders);
+
+ public abstract boolean createAndLoadShader(GL gl, IntBuffer shader, int shaderType,
+ int binFormat, java.nio.Buffer bin,
+ PrintStream verboseOut);
+
+ public abstract boolean createAndCompileShader(GL gl, IntBuffer shader, int shaderType,
+ java.lang.String[][] sources,
+ PrintStream verboseOut);
+ }
+
+ static class GL2ES2Impl extends Impl {
+ public String getShaderInfoLog(GL _gl, int shaderObj) {
+ GL2ES2 gl = _gl.getGL2ES2();
+ int[] infoLogLength=new int[1];
+ gl.glGetShaderiv(shaderObj, gl.GL_INFO_LOG_LENGTH, infoLogLength, 0);
+
+ if(infoLogLength[0]==0) {
+ return "(no info log)";
+ }
+ int[] charsWritten=new int[1];
+ byte[] infoLogBytes = new byte[infoLogLength[0]];
+ gl.glGetShaderInfoLog(shaderObj, infoLogLength[0], charsWritten, 0, infoLogBytes, 0);
+
+ return new String(infoLogBytes, 0, charsWritten[0]);
+ }
+
+ public String getProgramInfoLog(GL _gl, int programObj) {
+ GL2ES2 gl = _gl.getGL2ES2();
+ int[] infoLogLength=new int[1];
+ gl.glGetProgramiv(programObj, gl.GL_INFO_LOG_LENGTH, infoLogLength, 0);
+
+ if(infoLogLength[0]==0) {
+ return "(no info log)";
+ }
+ int[] charsWritten=new int[1];
+ byte[] infoLogBytes = new byte[infoLogLength[0]];
+ gl.glGetProgramInfoLog(programObj, infoLogLength[0], charsWritten, 0, infoLogBytes, 0);
+
+ return new String(infoLogBytes, 0, charsWritten[0]);
+ }
+
+ public boolean isShaderStatusValid(GL _gl, int shaderObj, int name) {
+ return isShaderStatusValid(_gl, shaderObj, name, null);
+ }
+
+ public boolean isShaderStatusValid(GL _gl, int shaderObj, int name, PrintStream verboseOut) {
+ GL2ES2 gl = _gl.getGL2ES2();
+ int[] ires = new int[1];
+ gl.glGetShaderiv(shaderObj, name, ires, 0);
+
+ boolean res = ires[0]==1;
+ if(!res && null!=verboseOut) {
+ verboseOut.println("Shader status invalid: "+ getShaderInfoLog(gl, shaderObj));
+ }
+ return res;
+ }
+
+ public boolean isShaderStatusValid(GL _gl, IntBuffer shaders, int name) {
+ return isShaderStatusValid(_gl, shaders, name, null);
+ }
+
+ public boolean isShaderStatusValid(GL _gl, IntBuffer shaders, int name, PrintStream verboseOut) {
+ boolean res = true;
+ for (int i = shaders.position(); i < shaders.limit(); i++) {
+ res = isShaderStatusValid(_gl, shaders.get(i), name, verboseOut) && res;
+ }
+ return res;
+ }
+
+ public boolean isProgramStatusValid(GL _gl, int programObj, int name) {
+ GL2ES2 gl = _gl.getGL2ES2();
+ int[] ires = new int[1];
+ gl.glGetProgramiv(programObj, name, ires, 0);
+
+ return ires[0]==1;
+ }
+
+ public boolean isProgramValid(GL _gl, int programObj) {
+ return isProgramValid(_gl, programObj, null);
+ }
+
+ public boolean isProgramValid(GL _gl, int programObj, PrintStream verboseOut) {
+ GL2ES2 gl = _gl.getGL2ES2();
+ int[] ires = new int[1];
+ if(!gl.glIsProgram(programObj)) {
+ if(null!=verboseOut) {
+ verboseOut.println("Program name invalid: "+programObj);
+ }
+ return false;
+ }
+ if(!isProgramStatusValid(gl, programObj, gl.GL_LINK_STATUS)) {
+ if(null!=verboseOut) {
+ verboseOut.println("Program link failed: "+programObj+"\n\t"+ getProgramInfoLog(gl, programObj));
+ }
+ return false;
+ }
+ if ( !gl.isGLES2() || isShaderCompilerAvailable(gl) ) {
+ // failed on APX2500 (ES2.0, no compiler) for valid programs
+ gl.glValidateProgram(programObj);
+ if(!isProgramStatusValid(gl, programObj, gl.GL_VALIDATE_STATUS)) {
+ if(null!=verboseOut) {
+ verboseOut.println("Program validation failed: "+programObj+"\n\t"+ getProgramInfoLog(gl, programObj));
+ }
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void createShader(GL _gl, int type, IntBuffer shaders) {
+ GL2ES2 gl = _gl.getGL2ES2();
+ for (int i = shaders.position(); i < shaders.limit(); i++) {
+ shaders.put(i, gl.glCreateShader(type));
+ }
+ }
+
+ private Boolean shaderCompilerAvailable = null;
+ private Set shaderBinaryFormats = null;
+
+ public Set getShaderBinaryFormats(GL _gl) {
+ GL2ES2 gl = _gl.getGL2ES2();
+ if(null==shaderBinaryFormats) {
+ if(gl.getContext()!=GLContext.getCurrent()) {
+ return new HashSet(0); // bail out
+ }
+
+ int[] param = new int[1];
+ shaderBinaryFormats = new HashSet();
+
+ if (gl.isGLES2()) {
+ gl.glGetIntegerv(GL2ES2.GL_NUM_SHADER_BINARY_FORMATS, param, 0);
+ int numFormats = param[0];
+ if(numFormats>0) {
+ int[] formats = new int[numFormats];
+ gl.glGetIntegerv(GL2ES2.GL_SHADER_BINARY_FORMATS, formats, 0);
+ for(int i=0; i<numFormats; i++) {
+ shaderBinaryFormats.add(new Integer(formats[i]));
+ }
+ }
+ }
+ }
+ return shaderBinaryFormats;
+ }
+
+
+ public boolean isShaderCompilerAvailable(GL _gl) {
+ GL2ES2 gl = _gl.getGL2ES2();
+ if(null==shaderCompilerAvailable) {
+ if(gl.getContext()!=GLContext.getCurrent()) {
+ return false; // bail out
+ }
+ Set bfs = getShaderBinaryFormats(gl);
+ if(gl.isGLES2()) {
+ byte[] param = new byte[1];
+ gl.glGetBooleanv(GL2ES2.GL_SHADER_COMPILER, param, 0);
+ boolean v = param[0]!=(byte)0x00;
+ if(!v && bfs.size()==0) {
+ // no supported binary formats, hence a compiler must be available!
+ v = true;
+ }
+ shaderCompilerAvailable = new Boolean(v);
+ } else if( gl.isGL2ES2() ) {
+ shaderCompilerAvailable = new Boolean(true);
+ } else {
+ throw new GLException("Invalid OpenGL profile");
+ }
+ }
+ return shaderCompilerAvailable.booleanValue();
+ }
+
+ public void shaderSource(GL _gl, int shader, java.lang.String[] source)
+ {
+ GL2ES2 gl = _gl.getGL2ES2();
+ if(!isShaderCompilerAvailable(_gl)) {
+ throw new GLException("No compiler is available");
+ }
+
+ int count = (null!=source)?source.length:0;
+ if(count==0) {
+ throw new GLException("No sources specified");
+ }
+
+ int[] lengths = new int[count];
+ for(int i=0; i<count; i++) {
+ lengths[i] = source[i].length();
+ }
+ gl.glShaderSource(shader, count, source, lengths, 0);
+ }
+
+ public void shaderSource(GL _gl, IntBuffer shaders, java.lang.String[][] sources)
+ {
+ int sourceNum = (null!=sources)?sources.length:0;
+ int shaderNum = (null!=shaders)?shaders.remaining():0;
+ if(shaderNum<=0 || sourceNum<=0 || shaderNum!=sourceNum) {
+ throw new GLException("Invalid number of shaders and/or sources: shaders="+
+ shaderNum+", sources="+sourceNum);
+ }
+ for(int i=0; i<sourceNum; i++) {
+ shaderSource(_gl, shaders.get(shaders.position() + i), sources[i]);
+ }
+ }
+
+ public void shaderBinary(GL _gl, IntBuffer shaders, int binFormat, java.nio.Buffer bin)
+ {
+ GL2ES2 gl = _gl.getGL2ES2();
+ if(getShaderBinaryFormats(gl).size()<=0) {
+ throw new GLException("No binary formats are supported");
+ }
+
+ int shaderNum = shaders.remaining();
+ if(shaderNum<=0) {
+ throw new GLException("No shaders specified");
+ }
+ if(null==bin) {
+ throw new GLException("Null shader binary");
+ }
+ int binLength = bin.remaining();
+ if(0>=binLength) {
+ throw new GLException("Empty shader binary (remaining == 0)");
+ }
+ gl.glShaderBinary(shaderNum, shaders, binFormat, bin, binLength);
+ }
+
+ public void compileShader(GL _gl, IntBuffer shaders)
+ {
+ GL2ES2 gl = _gl.getGL2ES2();
+ for (int i = shaders.position(); i < shaders.limit(); i++) {
+ gl.glCompileShader(shaders.get(i));
+ }
+ }
+
+ public void attachShader(GL _gl, int program, IntBuffer shaders)
+ {
+ GL2ES2 gl = _gl.getGL2ES2();
+ for (int i = shaders.position(); i < shaders.limit(); i++) {
+ gl.glAttachShader(program, shaders.get(i));
+ }
+ }
+
+ public void detachShader(GL _gl, int program, IntBuffer shaders)
+ {
+ GL2ES2 gl = _gl.getGL2ES2();
+ for (int i = shaders.position(); i < shaders.limit(); i++) {
+ gl.glDetachShader(program, shaders.get(i));
+ }
+ }
+
+ public void deleteShader(GL _gl, IntBuffer shaders)
+ {
+ GL2ES2 gl = _gl.getGL2ES2();
+ for (int i = shaders.position(); i < shaders.limit(); i++) {
+ gl.glDeleteShader(shaders.get(i));
+
+ }
+ }
+
+ public boolean createAndLoadShader(GL _gl, IntBuffer shader, int shaderType,
+ int binFormat, java.nio.Buffer bin,
+ PrintStream verboseOut)
+ {
+ GL2ES2 gl = _gl.getGL2ES2();
+ int err = gl.glGetError(); // flush previous errors ..
+ if(err!=GL.GL_NO_ERROR && null!=verboseOut) {
+ verboseOut.println("createAndLoadShader: Pre GL Error: 0x"+Integer.toHexString(err));
+ }
+
+ createShader(gl, shaderType, shader);
+ err = gl.glGetError();
+ if(err!=GL.GL_NO_ERROR) {
+ throw new GLException("createAndLoadShader: CreateShader failed, GL Error: 0x"+Integer.toHexString(err));
+ }
+
+
+ shaderBinary(gl, shader, binFormat, bin);
+
+ err = gl.glGetError();
+ if(err!=GL.GL_NO_ERROR && null!=verboseOut) {
+ verboseOut.println("createAndLoadShader: ShaderBinary failed, GL Error: 0x"+Integer.toHexString(err));
+ }
+ return err == GL.GL_NO_ERROR;
+ }
+
+ public boolean createAndCompileShader(GL _gl, IntBuffer shader, int shaderType,
+ java.lang.String[][] sources,
+ PrintStream verboseOut)
+ {
+ GL2ES2 gl = _gl.getGL2ES2();
+ int err = gl.glGetError(); // flush previous errors ..
+ if(err!=GL.GL_NO_ERROR && null!=verboseOut) {
+ verboseOut.println("createAndCompileShader: Pre GL Error: 0x"+Integer.toHexString(err));
+ }
+
+ createShader(gl, shaderType, shader);
+ err = gl.glGetError();
+ if(err!=GL.GL_NO_ERROR) {
+ throw new GLException("createAndCompileShader: CreateShader failed, GL Error: 0x"+Integer.toHexString(err));
+ }
+
+ shaderSource(gl, shader, sources);
+ err = gl.glGetError();
+ if(err!=GL.GL_NO_ERROR) {
+ throw new GLException("createAndCompileShader: ShaderSource failed, GL Error: 0x"+Integer.toHexString(err));
+ }
+
+ compileShader(gl, shader);
+ err = gl.glGetError();
+ if(err!=GL.GL_NO_ERROR && null!=verboseOut) {
+ verboseOut.println("createAndCompileShader: CompileShader failed, GL Error: 0x"+Integer.toHexString(err));
+ }
+
+ return isShaderStatusValid(gl, shader, gl.GL_COMPILE_STATUS, verboseOut) && err == GL.GL_NO_ERROR;
+ }
+
+ }
+
+ public static String getShaderInfoLog(GL gl, int shaderObj) {
+ return getImpl(gl).getShaderInfoLog(gl, shaderObj);
+ }
+
+ public static String getProgramInfoLog(GL gl, int programObj) {
+ return getImpl(gl).getProgramInfoLog(gl, programObj);
+ }
+
+ public static boolean isShaderStatusValid(GL gl, int shaderObj, int name) {
+ return getImpl(gl).isShaderStatusValid(gl, shaderObj, name);
+ }
+
+ public static boolean isShaderStatusValid(GL gl, int shaderObj, int name, PrintStream verboseOut) {
+ return getImpl(gl).isShaderStatusValid(gl, shaderObj, name, verboseOut);
+ }
+
+ public static boolean isShaderStatusValid(GL gl, IntBuffer shaders, int name) {
+ return getImpl(gl).isShaderStatusValid(gl, shaders, name);
+ }
+
+ public static boolean isShaderStatusValid(GL gl, IntBuffer shaders, int name, PrintStream verboseOut) {
+ return getImpl(gl).isShaderStatusValid(gl, shaders, name, verboseOut);
+ }
+
+ public static boolean isProgramStatusValid(GL gl, int programObj, int name) {
+ return getImpl(gl).isProgramStatusValid(gl, programObj, name);
+ }
+
+ public static boolean isProgramValid(GL gl, int programObj) {
+ return getImpl(gl).isProgramValid(gl, programObj);
+ }
+
+ public static boolean isProgramValid(GL gl, int programObj, PrintStream verboseOut) {
+ return getImpl(gl).isProgramValid(gl, programObj, verboseOut);
+ }
+
+ public static void createShader(GL gl, int type, IntBuffer shaders) {
+ getImpl(gl).createShader(gl, type, shaders);
+ }
+
+ public static Set getShaderBinaryFormats(GL gl) {
+ return getImpl(gl).getShaderBinaryFormats(gl);
+ }
+
+ public static boolean isShaderCompilerAvailable(GL gl) {
+ return getImpl(gl).isShaderCompilerAvailable(gl);
+ }
+
+ public static void shaderSource(GL gl, int shader, java.lang.String[] source) {
+ getImpl(gl).shaderSource(gl, shader, source);
+ }
+
+ public static void shaderSource(GL gl, IntBuffer shaders, java.lang.String[][] sources) {
+ getImpl(gl).shaderSource(gl, shaders, sources);
+ }
+
+ public static void shaderBinary(GL gl, IntBuffer shaders, int binFormat, java.nio.Buffer bin) {
+ getImpl(gl).shaderBinary(gl, shaders, binFormat, bin);
+ }
+
+ public static void compileShader(GL gl, IntBuffer shaders) {
+ getImpl(gl).compileShader(gl, shaders);
+ }
+
+ public static void attachShader(GL gl, int program, IntBuffer shaders) {
+ getImpl(gl).attachShader(gl, program, shaders);
+ }
+
+ public static void detachShader(GL gl, int program, IntBuffer shaders) {
+ getImpl(gl).detachShader(gl, program, shaders);
+ }
+
+ public static void deleteShader(GL gl, IntBuffer shaders) {
+ getImpl(gl).deleteShader(gl, shaders);
+ }
+
+ public static boolean createAndLoadShader(GL gl, IntBuffer shader, int shaderType,
+ int binFormat, java.nio.Buffer bin,
+ PrintStream verboseOut) {
+ return getImpl(gl).createAndLoadShader(gl, shader, shaderType, binFormat, bin, verboseOut);
+ }
+
+ public static boolean createAndCompileShader(GL gl, IntBuffer shader, int shaderType,
+ java.lang.String[][] sources,
+ PrintStream verboseOut) {
+ return getImpl(gl).createAndCompileShader(gl, shader, shaderType, sources, verboseOut);
+ }
+
+ private static Impl getImpl(GL _gl) {
+ GL2ES2 gl = _gl.getGL2ES2();
+ GLContext context = gl.getContext();
+ Impl impl = (Impl) context.getAttachedObject(ShaderUtil.class.getName());
+ if (impl == null) {
+ impl = new GL2ES2Impl();
+ context.putAttachedObject(ShaderUtil.class.getName(), impl);
+ }
+ return impl;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java
new file mode 100644
index 000000000..7ec4ac50e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package com.jogamp.opengl.util.glsl.fixedfunc;
+
+import javax.media.opengl.*;
+import javax.media.opengl.fixedfunc.*;
+
+import com.jogamp.opengl.util.glsl.fixedfunc.impl.*;
+
+/**
+ * Tool to pipeline GL2ES2 into a fixed function emulation implementing GL2ES1.
+ */
+public class FixedFuncUtil {
+ /**
+ * @return If gl is a GL2ES1 and force is false, return the type cast object,
+ * otherwise create a fixed function emulation pipeline with the GL2ES2 impl.
+ * @throws GLException if the GL object is neither GL2ES1 nor GL2ES2
+ */
+ public static final GL2ES1 getFixedFuncImpl(GL gl, boolean force) {
+ if(!force && gl.isGL2ES1()) {
+ return gl.getGL2ES1();
+ } else if(gl.isGL2ES2()) {
+ GL2ES2 es2 = gl.getGL2ES2();
+ FixedFuncHook hook = new FixedFuncHook(es2);
+ FixedFuncImpl impl = new FixedFuncImpl(es2, hook);
+ gl.getContext().setGL(impl);
+ return impl;
+ }
+ throw new GLException("GL Object is neither GL2ES1 nor GL2ES2: "+gl.getContext());
+ }
+
+ /**
+ * @return If gl is a GL2ES1, return the type cast object,
+ * otherwise create a fixed function emulation pipeline with the GL2ES2 impl.
+ * @throws GLException if the GL object is neither GL2ES1 nor GL2ES2
+ */
+ public static final GL2ES1 getFixedFuncImpl(GL gl) {
+ return getFixedFuncImpl(gl, false);
+ }
+
+ /**
+ * Mapping fixed function (client) array indices to
+ * GLSL array attribute names.
+ *
+ * Useful for uniq mapping of canonical array index names as listed.
+ *
+ * @see #mgl_Vertex
+ * @see javax.media.opengl.fixedfunc.GLPointerFunc#GL_VERTEX_ARRAY
+ * @see #mgl_Normal
+ * @see javax.media.opengl.fixedfunc.GLPointerFunc#GL_NORMAL_ARRAY
+ * @see #mgl_Color
+ * @see javax.media.opengl.fixedfunc.GLPointerFunc#GL_COLOR_ARRAY
+ * @see #mgl_MultiTexCoord
+ * @see javax.media.opengl.fixedfunc.GLPointerFunc#GL_TEXTURE_COORD_ARRAY
+ * @see javax.media.opengl.fixedfunc.GLPointerFunc#glEnableClientState
+ * @see javax.media.opengl.fixedfunc.GLPointerFunc#glVertexPointer
+ * @see javax.media.opengl.fixedfunc.GLPointerFunc#glColorPointer
+ * @see javax.media.opengl.fixedfunc.GLPointerFunc#glNormalPointer
+ * @see javax.media.opengl.fixedfunc.GLPointerFunc#glTexCoordPointer
+ */
+ public static String getPredefinedArrayIndexName(int glArrayIndex) {
+ return FixedFuncPipeline.getPredefinedArrayIndexName(glArrayIndex);
+ }
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL2#GL_VERTEX_ARRAY
+ */
+ public static final String mgl_Vertex = FixedFuncPipeline.mgl_Vertex;
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL2#GL_NORMAL_ARRAY
+ */
+ public static final String mgl_Normal = FixedFuncPipeline.mgl_Normal;
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL2#GL_COLOR_ARRAY
+ */
+ public static final String mgl_Color = FixedFuncPipeline.mgl_Color;
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL2#GL_TEXTURE_COORD_ARRAY
+ */
+ public static final String mgl_MultiTexCoord = FixedFuncPipeline.mgl_MultiTexCoord;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/FixedFuncHook.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/FixedFuncHook.java
new file mode 100755
index 000000000..b8e3922a4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/FixedFuncHook.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package com.jogamp.opengl.util.glsl.fixedfunc.impl;
+
+import javax.media.opengl.*;
+import javax.media.opengl.fixedfunc.*;
+import javax.media.opengl.glu.*;
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.glsl.*;
+import java.nio.*;
+
+public class FixedFuncHook implements GLLightingFunc, GLMatrixFunc, GLPointerFunc {
+ public static final int MAX_TEXTURE_UNITS = 8;
+
+ protected FixedFuncPipeline fixedFunction=null;
+ protected PMVMatrix pmvMatrix=null;
+ protected GL2ES2 gl=null;
+
+ public FixedFuncHook (GL2ES2 gl) {
+ this(gl, null);
+ }
+
+ public FixedFuncHook (GL2ES2 gl, PMVMatrix matrix) {
+ this.gl = gl;
+ pmvMatrix = (null!=matrix)?matrix:new PMVMatrix();
+
+ fixedFunction = new FixedFuncPipeline(gl, pmvMatrix);
+ }
+
+ public FixedFuncHook(GL2ES2 gl, PMVMatrix matrix,
+ Class shaderRootClass, String shaderSrcRoot, String shaderBinRoot,
+ String vertexColorFile,
+ String vertexColorLightFile,
+ String fragmentColorFile,
+ String fragmentColorTextureFile) {
+ this.gl = gl;
+ pmvMatrix = matrix;
+
+ fixedFunction = new FixedFuncPipeline(gl, pmvMatrix,
+ shaderRootClass, shaderSrcRoot, shaderBinRoot,
+ vertexColorFile, vertexColorLightFile, fragmentColorFile, fragmentColorTextureFile);
+ }
+
+ public void destroy() {
+ fixedFunction.destroy(gl);
+ fixedFunction = null;
+ }
+
+ public PMVMatrix getMatrix() { return pmvMatrix; }
+
+ //
+ // FixedFuncHookIf - hooks
+ //
+ public void glDrawArrays(int mode, int first, int count) {
+ fixedFunction.validate(gl);
+ gl.glDrawArrays(mode, first, count);
+ }
+ public void glDrawElements(int mode, int count, int type, java.nio.Buffer indices) {
+ fixedFunction.validate(gl);
+ gl.glDrawElements(mode, count, type, indices);
+ }
+ public void glDrawElements(int mode, int count, int type, long indices_buffer_offset) {
+ fixedFunction.validate(gl);
+ gl.glDrawElements(mode, count, type, indices_buffer_offset);
+ }
+
+ public void glActiveTexture(int texture) {
+ fixedFunction.glActiveTexture(gl, texture);
+ gl.glActiveTexture(texture);
+ }
+ public void glEnable(int cap) {
+ if(fixedFunction.glEnable(gl, cap, true)) {
+ gl.glEnable(cap);
+ }
+ }
+ public void glDisable(int cap) {
+ if(fixedFunction.glEnable(gl, cap, false)) {
+ gl.glDisable(cap);
+ }
+ }
+ public void glCullFace(int faceName) {
+ fixedFunction.glCullFace(gl, faceName);
+ gl.glCullFace(faceName);
+ }
+
+ public void glGetFloatv(int pname, java.nio.FloatBuffer params) {
+ if(pmvMatrix.isMatrixGetName(pname)) {
+ pmvMatrix.glGetFloatv(pname, params);
+ return;
+ }
+ gl.glGetFloatv(pname, params);
+ }
+ public void glGetFloatv(int pname, float[] params, int params_offset) {
+ if(pmvMatrix.isMatrixGetName(pname)) {
+ pmvMatrix.glGetFloatv(pname, params, params_offset);
+ return;
+ }
+ gl.glGetFloatv(pname, params, params_offset);
+ }
+ public void glGetIntegerv(int pname, IntBuffer params) {
+ if(pmvMatrix.isMatrixGetName(pname)) {
+ pmvMatrix.glGetIntegerv(pname, params);
+ return;
+ }
+ gl.glGetIntegerv(pname, params);
+ }
+ public void glGetIntegerv(int pname, int[] params, int params_offset) {
+ if(pmvMatrix.isMatrixGetName(pname)) {
+ pmvMatrix.glGetIntegerv(pname, params, params_offset);
+ return;
+ }
+ gl.glGetIntegerv(pname, params, params_offset);
+ }
+
+ //
+ // MatrixIf
+ //
+ public int glGetMatrixMode() {
+ return pmvMatrix.glGetMatrixMode();
+ }
+ public void glMatrixMode(int mode) {
+ pmvMatrix.glMatrixMode(mode);
+ }
+ public void glLoadMatrixf(java.nio.FloatBuffer m) {
+ pmvMatrix.glLoadMatrixf(m);
+ }
+ public void glLoadMatrixf(float[] m, int m_offset) {
+ glLoadMatrixf(GLBuffers.newDirectFloatBuffer(m, m_offset));
+ }
+ public void glPopMatrix() {
+ pmvMatrix.glPopMatrix();
+ }
+ public void glPushMatrix() {
+ pmvMatrix.glPushMatrix();
+ }
+ public void glLoadIdentity() {
+ pmvMatrix.glLoadIdentity();
+ }
+ public void glMultMatrixf(java.nio.FloatBuffer m) {
+ pmvMatrix.glMultMatrixf(m);
+ }
+ public void glMultMatrixf(float[] m, int m_offset) {
+ glMultMatrixf(GLBuffers.newDirectFloatBuffer(m, m_offset));
+ }
+ public void glTranslatef(float x, float y, float z) {
+ pmvMatrix.glTranslatef(x, y, z);
+ }
+ public void glRotatef(float angdeg, float x, float y, float z) {
+ pmvMatrix.glRotatef(angdeg, x, y, z);
+ }
+ public void glScalef(float x, float y, float z) {
+ pmvMatrix.glScalef(x, y, z);
+ }
+ public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) {
+ pmvMatrix.glOrthof(left, right, bottom, top, zNear, zFar);
+ }
+ public void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar) {
+ pmvMatrix.glFrustumf(left, right, bottom, top, zNear, zFar);
+ }
+
+ //
+ // LightingIf
+ //
+ public void glColor4f(float red, float green, float blue, float alpha) {
+ fixedFunction.glColor4fv(gl, GLBuffers.newDirectFloatBuffer(new float[] { red, green, blue, alpha }));
+ }
+
+ public void glLightfv(int light, int pname, java.nio.FloatBuffer params) {
+ fixedFunction.glLightfv(gl, light, pname, params);
+ }
+ public void glLightfv(int light, int pname, float[] params, int params_offset) {
+ glLightfv(light, pname, GLBuffers.newDirectFloatBuffer(params, params_offset));
+ }
+ public void glMaterialfv(int face, int pname, java.nio.FloatBuffer params) {
+ fixedFunction.glMaterialfv(gl, face, pname, params);
+ }
+ public void glMaterialfv(int face, int pname, float[] params, int params_offset) {
+ glMaterialfv(face, pname, GLBuffers.newDirectFloatBuffer(params, params_offset));
+ }
+ public void glMaterialf(int face, int pname, float param) {
+ glMaterialfv(face, pname, GLBuffers.newDirectFloatBuffer(new float[] { param }));
+ }
+ public void glShadeModel(int mode) {
+ fixedFunction.glShadeModel(gl, mode);
+ }
+
+ //
+ // PointerIf
+ //
+ public void glEnableClientState(int glArrayIndex) {
+ fixedFunction.glEnableClientState(gl, glArrayIndex);
+ }
+ public void glDisableClientState(int glArrayIndex) {
+ fixedFunction.glDisableClientState(gl, glArrayIndex);
+ }
+
+ public void glVertexPointer(GLArrayData array) {
+ if(array.isVBO()) {
+ if(!gl.glIsVBOArrayEnabled()) {
+ throw new GLException("VBO array is not enabled: "+array);
+ }
+ } else {
+ if(gl.glIsVBOArrayEnabled()) {
+ throw new GLException("VBO array is not disabled: "+array);
+ }
+ Buffers.rangeCheck(array.getBuffer(), 1);
+ if (!Buffers.isDirect(array.getBuffer())) {
+ throw new GLException("Argument \"pointer\" was not a direct buffer"); }
+ }
+ fixedFunction.glVertexPointer(gl, array);
+ }
+
+ public void glVertexPointer(int size, int type, int stride, java.nio.Buffer pointer) {
+ glVertexPointer(GLArrayDataWrapper.createFixed(gl, GL_VERTEX_ARRAY, size, type, false, stride, pointer, 0, 0));
+ }
+ public void glVertexPointer(int size, int type, int stride, long pointer_buffer_offset) {
+ int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
+ if(vboName==0) {
+ throw new GLException("no GL_ARRAY_BUFFER VBO bound");
+ }
+ glVertexPointer(GLArrayDataWrapper.createFixed(gl, GL_VERTEX_ARRAY, size, type, false,
+ stride, null, vboName, pointer_buffer_offset));
+ }
+
+ public void glColorPointer(GLArrayData array) {
+ if(array.isVBO()) {
+ if(!gl.glIsVBOArrayEnabled()) {
+ throw new GLException("VBO array is not enabled: "+array);
+ }
+ } else {
+ if(gl.glIsVBOArrayEnabled()) {
+ throw new GLException("VBO array is not disabled: "+array);
+ }
+ Buffers.rangeCheck(array.getBuffer(), 1);
+ if (!Buffers.isDirect(array.getBuffer())) {
+ throw new GLException("Argument \"pointer\" was not a direct buffer"); }
+ }
+ fixedFunction.glColorPointer(gl, array);
+ }
+ public void glColorPointer(int size, int type, int stride, java.nio.Buffer pointer) {
+ glColorPointer(GLArrayDataWrapper.createFixed(gl, GL_COLOR_ARRAY, size, type, false,
+ stride, pointer, 0, 0));
+ }
+ public void glColorPointer(int size, int type, int stride, long pointer_buffer_offset) {
+ int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
+ if(vboName==0) {
+ throw new GLException("no GL_ARRAY_BUFFER VBO bound");
+ }
+ glColorPointer(GLArrayDataWrapper.createFixed(gl, GL_COLOR_ARRAY, size, type, false,
+ stride, null, vboName, pointer_buffer_offset));
+ }
+
+ public void glNormalPointer(GLArrayData array) {
+ if(array.getComponentNumber()!=3) {
+ throw new GLException("Only 3 components per normal allowed");
+ }
+ if(array.isVBO()) {
+ if(!gl.glIsVBOArrayEnabled()) {
+ throw new GLException("VBO array is not enabled: "+array);
+ }
+ } else {
+ if(gl.glIsVBOArrayEnabled()) {
+ throw new GLException("VBO array is not disabled: "+array);
+ }
+ Buffers.rangeCheck(array.getBuffer(), 1);
+ if (!Buffers.isDirect(array.getBuffer())) {
+ throw new GLException("Argument \"pointer\" was not a direct buffer"); }
+ }
+ fixedFunction.glNormalPointer(gl, array);
+ }
+ public void glNormalPointer(int type, int stride, java.nio.Buffer pointer) {
+ glNormalPointer(GLArrayDataWrapper.createFixed(gl, GL_NORMAL_ARRAY, 3, type, false,
+ stride, pointer, 0, 0));
+ }
+ public void glNormalPointer(int type, int stride, long pointer_buffer_offset) {
+ int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
+ if(vboName==0) {
+ throw new GLException("no GL_ARRAY_BUFFER VBO bound");
+ }
+ glNormalPointer(GLArrayDataWrapper.createFixed(gl, GL_NORMAL_ARRAY, 3, type, false,
+ stride, null, vboName, pointer_buffer_offset));
+ }
+
+ public void glTexCoordPointer(GLArrayData array) {
+ if(array.isVBO()) {
+ if(!gl.glIsVBOArrayEnabled()) {
+ throw new GLException("VBO array is not enabled: "+array);
+ }
+ } else {
+ if(gl.glIsVBOArrayEnabled()) {
+ throw new GLException("VBO array is not disabled: "+array);
+ }
+ Buffers.rangeCheck(array.getBuffer(), 1);
+ if (!Buffers.isDirect(array.getBuffer())) {
+ throw new GLException("Argument \"pointer\" was not a direct buffer"); }
+ }
+ fixedFunction.glTexCoordPointer(gl, array);
+ }
+ public void glTexCoordPointer(int size, int type, int stride, java.nio.Buffer pointer) {
+ glTexCoordPointer(
+ GLArrayDataWrapper.createFixed(gl, GL_TEXTURE_COORD_ARRAY, size, type, false, stride, pointer, 0,0));
+ }
+ public void glTexCoordPointer(int size, int type, int stride, long pointer_buffer_offset) {
+ int vboName = gl.glGetBoundBuffer(GL.GL_ARRAY_BUFFER);
+ if(vboName==0) {
+ throw new GLException("no GL_ARRAY_BUFFER VBO bound");
+ }
+ glTexCoordPointer(
+ GLArrayDataWrapper.createFixed(gl, GL_TEXTURE_COORD_ARRAY, size, type, false,
+ stride, null, vboName, pointer_buffer_offset) );
+ }
+
+ public final String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append(getClass().getName()+" (");
+ if(null!=pmvMatrix) {
+ buf.append(", matrixDirty: "+pmvMatrix.isDirty());
+ }
+ buf.append("\n\t, FixedFunction: "+fixedFunction);
+ buf.append(gl);
+ buf.append(" )");
+
+ return buf.toString();
+ }
+
+}
+
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/FixedFuncPipeline.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/FixedFuncPipeline.java
new file mode 100644
index 000000000..529e4567b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/FixedFuncPipeline.java
@@ -0,0 +1,554 @@
+
+package com.jogamp.opengl.util.glsl.fixedfunc.impl;
+
+import com.jogamp.common.nio.Buffers;
+import javax.media.opengl.*;
+import javax.media.opengl.fixedfunc.*;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.glsl.*;
+import java.nio.*;
+
+public class FixedFuncPipeline {
+ public static final int MAX_TEXTURE_UNITS = 8;
+ public static final int MAX_LIGHTS = 8;
+
+ // We can't have any dependencies on the FixedFuncUtil class for build bootstrapping reasons
+ public static final String mgl_Vertex = "mgl_Vertex";
+ public static final String mgl_Normal = "mgl_Normal";
+ public static final String mgl_Color = "mgl_Color";
+ public static final String mgl_MultiTexCoord = "mgl_MultiTexCoord" ;
+
+ public static String getPredefinedArrayIndexName(int glArrayIndex) {
+ switch(glArrayIndex) {
+ case GLPointerFunc.GL_VERTEX_ARRAY:
+ return mgl_Vertex;
+ case GLPointerFunc.GL_NORMAL_ARRAY:
+ return mgl_Normal;
+ case GLPointerFunc.GL_COLOR_ARRAY:
+ return mgl_Color;
+ case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+ return mgl_MultiTexCoord;
+ }
+ return null;
+ }
+
+ public FixedFuncPipeline(GL2ES2 gl, PMVMatrix pmvMatrix) {
+ init(gl, pmvMatrix, FixedFuncPipeline.class, shaderSrcRootDef, shaderBinRootDef,
+ vertexColorFileDef, vertexColorLightFileDef, fragmentColorFileDef, fragmentColorTextureFileDef);
+ }
+ public FixedFuncPipeline(GL2ES2 gl, PMVMatrix pmvMatrix, Class shaderRootClass, String shaderSrcRoot, String shaderBinRoot,
+ String vertexColorFile,
+ String vertexColorLightFile,
+ String fragmentColorFile,
+ String fragmentColorTextureFile) {
+ init(gl, pmvMatrix, shaderRootClass, shaderSrcRoot, shaderBinRoot,
+ vertexColorFile, vertexColorLightFile, fragmentColorFile, fragmentColorTextureFile);
+ }
+
+ public boolean verbose() { return verbose; }
+
+ public void setVerbose(boolean v) { verbose=v; }
+
+ public boolean isValid() {
+ return shaderState.linked();
+ }
+
+ public ShaderState getShaderState() {
+ return shaderState;
+ }
+
+ public int getActiveTextureUnit() {
+ return activeTextureUnit;
+ }
+
+ public String getArrayIndexName(int glArrayIndex) {
+ String name = getPredefinedArrayIndexName(glArrayIndex);
+ switch(glArrayIndex) {
+ case GLPointerFunc.GL_VERTEX_ARRAY:
+ case GLPointerFunc.GL_NORMAL_ARRAY:
+ case GLPointerFunc.GL_COLOR_ARRAY:
+ break;
+ case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+ name = name + activeTextureUnit;
+ }
+ return name;
+ }
+
+ public void destroy(GL2ES2 gl) {
+ shaderProgramColor.release(gl, true);
+ shaderProgramColorLight.release(gl, true);
+ shaderProgramColorTexture.release(gl, true);
+ shaderProgramColorTextureLight.release(gl, true);
+ shaderState.destroy(gl);
+ }
+
+ public void glEnableClientState(GL2ES2 gl, int glArrayIndex) {
+ shaderState.glUseProgram(gl, true);
+
+ shaderState.glEnableVertexAttribArray(gl, getArrayIndexName(glArrayIndex));
+ // textureCoordsEnabled |= (1 << activeTextureUnit);
+ if ( textureCoordsEnabled.get(activeTextureUnit) != 1 ) {
+ textureCoordsEnabled.put(activeTextureUnit, 1);
+ textureCoordsEnabledDirty = true;
+ }
+ }
+
+ public void glDisableClientState(GL2ES2 gl, int glArrayIndex) {
+ shaderState.glUseProgram(gl, true);
+
+ shaderState.glDisableVertexAttribArray(gl, getArrayIndexName(glArrayIndex));
+ // textureCoordsEnabled &= ~(1 << activeTextureUnit);
+ if ( textureCoordsEnabled.get(activeTextureUnit) != 0 ) {
+ textureCoordsEnabled.put(activeTextureUnit, 0);
+ textureCoordsEnabledDirty = true;
+ }
+ }
+
+ public void glVertexPointer(GL2ES2 gl, GLArrayData data) {
+ shaderState.glUseProgram(gl, true);
+ shaderState.glVertexAttribPointer(gl, data);
+ }
+
+ public void glColorPointer(GL2ES2 gl, GLArrayData data) {
+ shaderState.glUseProgram(gl, true);
+ shaderState.glVertexAttribPointer(gl, data);
+ }
+
+ public void glColor4fv(GL2ES2 gl, FloatBuffer data ) {
+ shaderState.glUseProgram(gl, true);
+ GLUniformData ud = shaderState.getUniform(mgl_ColorStatic);
+ if(null!=ud) {
+ ud.setData(data);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+
+ public void glNormalPointer(GL2ES2 gl, GLArrayData data) {
+ shaderState.glUseProgram(gl, true);
+ shaderState.glVertexAttribPointer(gl, data);
+ }
+
+ public void glTexCoordPointer(GL2ES2 gl, GLArrayData data) {
+ shaderState.glUseProgram(gl, true);
+ data.setName( getArrayIndexName(data.getIndex()) );
+ shaderState.glVertexAttribPointer(gl, data);
+ }
+
+ public void glLightfv(GL2ES2 gl, int light, int pname, java.nio.FloatBuffer params) {
+ shaderState.glUseProgram(gl, true);
+ light -=GLLightingFunc.GL_LIGHT0;
+ if(0 <= light && light < MAX_LIGHTS) {
+ GLUniformData ud = null;
+ switch(pname) {
+ case GLLightingFunc.GL_AMBIENT:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].ambient");
+ break;
+ case GLLightingFunc.GL_DIFFUSE:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].diffuse");
+ break;
+ case GLLightingFunc.GL_SPECULAR:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].specular");
+ break;
+ case GLLightingFunc.GL_POSITION:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].position");
+ break;
+ case GLLightingFunc.GL_SPOT_DIRECTION:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].spotDirection");
+ break;
+ case GLLightingFunc.GL_SPOT_EXPONENT:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].spotExponent");
+ break;
+ case GLLightingFunc.GL_SPOT_CUTOFF:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].spotCutoff");
+ break;
+ case GLLightingFunc.GL_CONSTANT_ATTENUATION:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].constantAttenuation");
+ break;
+ case GLLightingFunc.GL_LINEAR_ATTENUATION:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].linearAttenuation");
+ break;
+ case GLLightingFunc.GL_QUADRATIC_ATTENUATION:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].quadraticAttenuation");
+ break;
+ default:
+ if(verbose) {
+ System.err.println("glLightfv pname not within [GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_POSITION GL_SPOT_DIRECTION]: "+pname);
+ }
+ return;
+ }
+ if(null!=ud) {
+ ud.setData(params);
+ shaderState.glUniform(gl, ud);
+ }
+ } else if(verbose) {
+ System.err.println("glLightfv light not within [0.."+MAX_LIGHTS+"]: "+light);
+ }
+ }
+
+ public void glMaterialfv(GL2ES2 gl, int face, int pname, java.nio.FloatBuffer params) {
+ shaderState.glUseProgram(gl, true);
+
+ switch (face) {
+ case GL.GL_FRONT:
+ case GL.GL_FRONT_AND_BACK:
+ break;
+ case GL.GL_BACK:
+ if(verbose) {
+ System.err.println("glMaterialfv face GL_BACK currently not supported");
+ }
+ break;
+ default:
+ }
+
+ GLUniformData ud = null;
+ switch(pname) {
+ case GLLightingFunc.GL_AMBIENT:
+ ud = shaderState.getUniform(mgl_FrontMaterial+".ambient");
+ break;
+ case GLLightingFunc.GL_AMBIENT_AND_DIFFUSE:
+ glMaterialfv(gl, face, GLLightingFunc.GL_AMBIENT, params);
+ // fall through intended ..
+ case GLLightingFunc.GL_DIFFUSE:
+ ud = shaderState.getUniform(mgl_FrontMaterial+".diffuse");
+ break;
+ case GLLightingFunc.GL_SPECULAR:
+ ud = shaderState.getUniform(mgl_FrontMaterial+".specular");
+ break;
+ case GLLightingFunc.GL_EMISSION:
+ ud = shaderState.getUniform(mgl_FrontMaterial+".emission");
+ break;
+ case GLLightingFunc.GL_SHININESS:
+ ud = shaderState.getUniform(mgl_FrontMaterial+".shininess");
+ break;
+ default:
+ if(verbose) {
+ System.err.println("glMaterialfv pname not within [GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_EMISSION GL_SHININESS]: "+pname);
+ }
+ return;
+ }
+ if(null!=ud) {
+ ud.setData(params);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+
+ public void glShadeModel(GL2ES2 gl, int mode) {
+ shaderState.glUseProgram(gl, true);
+ GLUniformData ud = shaderState.getUniform(mgl_ShadeModel);
+ if(null!=ud) {
+ ud.setData(mode);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+
+ public void glActiveTexture(GL2ES2 gl, int textureUnit) {
+ textureUnit -= GL.GL_TEXTURE0;
+ if(0 <= textureUnit && textureUnit<MAX_TEXTURE_UNITS) {
+ shaderState.glUseProgram(gl, true);
+ GLUniformData ud;
+ ud = shaderState.getUniform(mgl_ActiveTexture);
+ if(null!=ud) {
+ ud.setData(textureUnit);
+ shaderState.glUniform(gl, ud);
+ }
+ ud = shaderState.getUniform(mgl_ActiveTextureIdx);
+ if(null!=ud) {
+ ud.setData(textureUnit);
+ shaderState.glUniform(gl, ud);
+ }
+ activeTextureUnit = textureUnit;
+ } else {
+ throw new GLException("glActivateTexture textureUnit not within GL_TEXTURE0 + [0.."+MAX_TEXTURE_UNITS+"]: "+textureUnit);
+ }
+ }
+
+ /**
+ * @return false if digested in regard to GL2ES2 spec,
+ * eg this call must not be passed to an underlying ES2 implementation.
+ * true if this call shall be passed to an underlying GL2ES2/ES2 implementation as well.
+ */
+ public boolean glEnable(GL2ES2 gl, int cap, boolean enable) {
+ switch(cap) {
+ case GL.GL_TEXTURE_2D:
+ textureEnabled=enable;
+ return true;
+ case GLLightingFunc.GL_LIGHTING:
+ lightingEnabled=enable;
+ return false;
+ case GL.GL_CULL_FACE:
+ cullFace=Math.abs(cullFace);
+ if(!enable) {
+ cullFace*=-1;
+ }
+ return true;
+ }
+
+ int light = cap - GLLightingFunc.GL_LIGHT0;
+ if(0 <= light && light < MAX_LIGHTS) {
+ if ( (lightsEnabled.get(light)==1) != enable ) {
+ lightsEnabled.put(light, enable?1:0);
+ lightsEnabledDirty = true;
+ return false;
+ }
+ }
+ return true; // pass it on ..
+ }
+
+ public void glCullFace(GL2ES2 gl, int faceName) {
+ switch(faceName) {
+ case GL.GL_FRONT:
+ faceName = 1; break;
+ case GL.GL_BACK:
+ faceName = 2; break;
+ case GL.GL_FRONT_AND_BACK:
+ faceName = 3; break;
+ }
+ if(0>cullFace) {
+ faceName *= -1;
+ }
+ cullFace = faceName;
+ }
+
+ public void validate(GL2ES2 gl) {
+ shaderState.glUseProgram(gl, true);
+ GLUniformData ud;
+ if(pmvMatrix.update()) {
+ ud = shaderState.getUniform(mgl_PMVMatrix);
+ if(null!=ud) {
+ // same data object ..
+ shaderState.glUniform(gl, ud);
+ } else {
+ throw new GLException("Failed to update: mgl_PMVMatrix");
+ }
+ ud = shaderState.getUniform(mgl_NormalMatrix);
+ if(null!=ud) {
+ // same data object ..
+ shaderState.glUniform(gl, ud);
+ }
+ }
+ ud = shaderState.getUniform(mgl_ColorEnabled);
+ if(null!=ud) {
+ int ca = (shaderState.isVertexAttribArrayEnabled(mgl_Color)==true)?1:0;
+ if(ca!=ud.intValue()) {
+ ud.setData(ca);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+ ud = shaderState.getUniform(mgl_CullFace);
+ if(null!=ud) {
+ if(cullFace!=ud.intValue()) {
+ ud.setData(cullFace);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+
+ if(lightsEnabledDirty) {
+ ud = shaderState.getUniform(mgl_LightsEnabled);
+ if(null!=ud) {
+ // same data object
+ shaderState.glUniform(gl, ud);
+ }
+ lightsEnabledDirty=false;
+ }
+
+ if(textureCoordsEnabledDirty) {
+ ud = shaderState.getUniform(mgl_TexCoordEnabled);
+ if(null!=ud) {
+ // same data object
+ shaderState.glUniform(gl, ud);
+ }
+ textureCoordsEnabledDirty=false;
+ }
+
+ if(textureEnabled) {
+ if(lightingEnabled) {
+ shaderState.attachShaderProgram(gl, shaderProgramColorTextureLight);
+ } else {
+ shaderState.attachShaderProgram(gl, shaderProgramColorTexture);
+ }
+ } else {
+ if(lightingEnabled) {
+ shaderState.attachShaderProgram(gl, shaderProgramColorLight);
+ } else {
+ shaderState.attachShaderProgram(gl, shaderProgramColor);
+ }
+ }
+ if(DEBUG) {
+ System.err.println("validate: "+this);
+ }
+ }
+
+ public String toString() {
+ return "FixedFuncPipeline[pmv: "+pmvMatrix+
+ ", textureEnabled: "+textureEnabled+
+ ", textureCoordsEnabled: "+textureCoordsEnabled+
+ ", lightingEnabled: "+lightingEnabled+
+ ", lightsEnabled: "+lightsEnabled+
+ "\n\t, shaderProgramColor: "+shaderProgramColor+
+ "\n\t, shaderProgramColorTexture: "+shaderProgramColorTexture+
+ "\n\t, shaderProgramColorLight: "+shaderProgramColorLight+
+ "\n\t, shaderProgramColorTextureLight: "+shaderProgramColorTextureLight+
+ "\n\t, ShaderState: "+shaderState+
+ "]";
+ }
+
+ protected void init(GL2ES2 gl, PMVMatrix pmvMatrix, Class shaderRootClass, String shaderSrcRoot, String shaderBinRoot,
+ String vertexColorFile,
+ String vertexColorLightFile,
+ String fragmentColorFile,
+ String fragmentColorTextureFile)
+ {
+ if(null==pmvMatrix) {
+ throw new GLException("PMVMatrix is null");
+ }
+ this.pmvMatrix=pmvMatrix;
+ this.shaderState=new ShaderState();
+ this.shaderState.setVerbose(verbose);
+ ShaderCode vertexColor, vertexColorLight, fragmentColor, fragmentColorTexture;
+
+ vertexColor = ShaderCode.create( gl, gl.GL_VERTEX_SHADER, 1, shaderRootClass,
+ shaderSrcRoot, shaderBinRoot, vertexColorFile);
+
+ vertexColorLight = ShaderCode.create( gl, gl.GL_VERTEX_SHADER, 1, shaderRootClass,
+ shaderSrcRoot, shaderBinRoot, vertexColorLightFile);
+
+ fragmentColor = ShaderCode.create( gl, gl.GL_FRAGMENT_SHADER, 1, shaderRootClass,
+ shaderSrcRoot, shaderBinRoot, fragmentColorFile);
+
+ fragmentColorTexture = ShaderCode.create( gl, gl.GL_FRAGMENT_SHADER, 1, shaderRootClass,
+ shaderSrcRoot, shaderBinRoot, fragmentColorTextureFile);
+
+ shaderProgramColor = new ShaderProgram();
+ shaderProgramColor.add(vertexColor);
+ shaderProgramColor.add(fragmentColor);
+ if(!shaderProgramColor.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColor program: "+shaderProgramColor);
+ }
+
+ shaderProgramColorTexture = new ShaderProgram();
+ shaderProgramColorTexture.add(vertexColor);
+ shaderProgramColorTexture.add(fragmentColorTexture);
+ if(!shaderProgramColorTexture.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorTexture program: "+shaderProgramColorTexture);
+ }
+
+ shaderProgramColorLight = new ShaderProgram();
+ shaderProgramColorLight.add(vertexColorLight);
+ shaderProgramColorLight.add(fragmentColor);
+ if(!shaderProgramColorLight.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorLight);
+ }
+
+ shaderProgramColorTextureLight = new ShaderProgram();
+ shaderProgramColorTextureLight.add(vertexColorLight);
+ shaderProgramColorTextureLight.add(fragmentColorTexture);
+ if(!shaderProgramColorTextureLight.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorTextureLight);
+ }
+
+ shaderState.attachShaderProgram(gl, shaderProgramColor);
+ shaderState.glUseProgram(gl, true);
+
+ // mandatory ..
+ if(!shaderState.glUniform(gl, new GLUniformData(mgl_PMVMatrix, 4, 4, pmvMatrix.glGetPMvMviMatrixf()))) {
+ throw new GLException("Error setting PMVMatrix in shader: "+this);
+ }
+
+ // optional parameter ..
+ shaderState.glUniform(gl, new GLUniformData(mgl_NormalMatrix, 3, 3, pmvMatrix.glGetNormalMatrixf()));
+
+ shaderState.glUniform(gl, new GLUniformData(mgl_ColorEnabled, 0));
+ shaderState.glUniform(gl, new GLUniformData(mgl_ColorStatic, 4, zero4f));
+ shaderState.glUniform(gl, new GLUniformData(mgl_TexCoordEnabled, 1, textureCoordsEnabled));
+ shaderState.glUniform(gl, new GLUniformData(mgl_ActiveTexture, activeTextureUnit));
+ shaderState.glUniform(gl, new GLUniformData(mgl_ActiveTextureIdx, activeTextureUnit));
+ shaderState.glUniform(gl, new GLUniformData(mgl_ShadeModel, 0));
+ shaderState.glUniform(gl, new GLUniformData(mgl_CullFace, cullFace));
+ for(int i=0; i<MAX_LIGHTS; i++) {
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].ambient", 4, defAmbient));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].diffuse", 4, defDiffuse));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].specular", 4, defSpecular));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].position", 4, defPosition));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].spotDirection", 3, defSpotDir));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].spotExponent", defSpotExponent));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].spotCutoff", defSpotCutoff));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].constantAttenuation", defConstantAtten));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].linearAttenuation", defLinearAtten));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].quadraticAttenuation", defQuadraticAtten));
+ }
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightsEnabled, 1, lightsEnabled));
+ shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".ambient", 4, defMatAmbient));
+ shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".diffuse", 4, defMatDiffuse));
+ shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".specular", 4, defMatSpecular));
+ shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".emission", 4, defMatEmission));
+ shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".shininess", defMatShininess));
+
+ shaderState.glUseProgram(gl, false);
+ }
+
+ protected static final boolean DEBUG=false;
+ protected boolean verbose=false;
+
+ protected boolean textureEnabled=false;
+ protected IntBuffer textureCoordsEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 });
+ protected boolean textureCoordsEnabledDirty = false;
+ protected int activeTextureUnit=0;
+
+ protected int cullFace=-2; // <=0 disabled, 1: front, 2: back (default, but disabled), 3: front & back
+
+ protected boolean lightingEnabled=false;
+ protected IntBuffer lightsEnabled = Buffers.newDirectIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 });
+ protected boolean lightsEnabledDirty = false;
+
+ protected PMVMatrix pmvMatrix;
+ protected ShaderState shaderState;
+ protected ShaderProgram shaderProgramColor;
+ protected ShaderProgram shaderProgramColorTexture;
+ protected ShaderProgram shaderProgramColorLight;
+ protected ShaderProgram shaderProgramColorTextureLight;
+
+ // uniforms ..
+ protected static final String mgl_PMVMatrix = "mgl_PMVMatrix"; // m4fv[3]
+ protected static final String mgl_NormalMatrix = "mgl_NormalMatrix"; // m4fv
+ protected static final String mgl_ColorEnabled = "mgl_ColorEnabled"; // 1i
+ protected static final String mgl_ColorStatic = "mgl_ColorStatic"; // 4fv
+
+ protected static final String mgl_LightSource = "mgl_LightSource"; // struct mgl_LightSourceParameters[MAX_LIGHTS]
+ protected static final String mgl_FrontMaterial = "mgl_FrontMaterial"; // struct mgl_MaterialParameters
+ protected static final String mgl_LightsEnabled = "mgl_LightsEnabled"; // int mgl_LightsEnabled[MAX_LIGHTS];
+
+ protected static final String mgl_ShadeModel = "mgl_ShadeModel"; // 1i
+
+ protected static final String mgl_TexCoordEnabled = "mgl_TexCoordEnabled"; // int mgl_TexCoordEnabled[MAX_TEXTURE_UNITS];
+ protected static final String mgl_ActiveTexture = "mgl_ActiveTexture"; // 1i
+ protected static final String mgl_ActiveTextureIdx = "mgl_ActiveTextureIdx";// 1i
+
+ protected static final String mgl_CullFace = "mgl_CullFace"; // 1i
+
+ protected static final FloatBuffer zero4f = Buffers.newDirectFloatBuffer(new float[] { 0.0f, 0.0f, 0.0f, 0.0f });
+
+ public static final FloatBuffer defAmbient = Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 0f, 1f });
+ public static final FloatBuffer defDiffuse = zero4f;
+ public static final FloatBuffer defSpecular= zero4f;
+ public static final FloatBuffer defPosition= Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 1f, 0f });
+ public static final FloatBuffer defSpotDir = Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, -1f });
+ public static final float defSpotExponent = 0f;
+ public static final float defSpotCutoff = 180f;
+ public static final float defConstantAtten = 1f;
+ public static final float defLinearAtten = 0f;
+ public static final float defQuadraticAtten= 0f;
+
+ public static final FloatBuffer defMatAmbient = Buffers.newDirectFloatBuffer(new float[] { 0.2f, 0.2f, 0.2f, 1.0f });
+ public static final FloatBuffer defMatDiffuse = Buffers.newDirectFloatBuffer(new float[] { 0.8f, 0.8f, 0.8f, 1.0f });
+ public static final FloatBuffer defMatSpecular= Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 0f, 1f});
+ public static final FloatBuffer defMatEmission= Buffers.newDirectFloatBuffer(new float[] { 0f, 0f, 0f, 1f});
+ public static final float defMatShininess = 0f;
+
+ protected static final String vertexColorFileDef = "FixedFuncColor";
+ protected static final String vertexColorLightFileDef = "FixedFuncColorLight";
+ protected static final String fragmentColorFileDef = "FixedFuncColor";
+ protected static final String fragmentColorTextureFileDef = "FixedFuncColorTexture";
+ protected static final String shaderSrcRootDef = "shaders" ;
+ protected static final String shaderBinRootDef = "shaders/bin" ;
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColor.fp b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColor.fp
new file mode 100644
index 000000000..408ff7251
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColor.fp
@@ -0,0 +1,16 @@
+#include es_precision.glsl
+
+#include mgl_uniform.glsl
+#include mgl_varying.glsl
+
+void main (void)
+{
+ if( mgl_CullFace > 0 &&
+ ( ( mgl_CullFace == 1 && gl_FrontFacing ) ||
+ ( mgl_CullFace == 2 && !gl_FrontFacing ) ||
+ ( mgl_CullFace == 3 ) ) ) {
+ discard;
+ }
+ gl_FragColor = frontColor;
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColor.vp b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColor.vp
new file mode 100644
index 000000000..346e40196
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColor.vp
@@ -0,0 +1,22 @@
+#include es_precision.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_attribute.glsl
+#include mgl_varying.glsl
+
+#include mgl_settexcoord.vp
+
+void main(void)
+{
+ if(mgl_ColorEnabled>0) {
+ frontColor=mgl_Color;
+ } else {
+ frontColor=mgl_ColorStatic;
+ }
+
+ gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * mgl_Vertex;
+
+ setTexCoord(gl_Position);
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColorLight.vp b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColorLight.vp
new file mode 100644
index 000000000..ce203cfb9
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColorLight.vp
@@ -0,0 +1,70 @@
+#include es_precision.glsl
+#include mgl_lightdef.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_uniform_light.glsl
+#include mgl_attribute.glsl
+#include mgl_varying.glsl
+
+#include mgl_settexcoord.vp
+
+void main(void)
+{
+ vec4 position;
+ vec3 normal, lightDir, cameraDir, halfDir;
+ vec4 ambient, diffuse, specular;
+ float NdotL, NdotHV, dist, attenuation;
+ int i;
+
+ position = mgl_PMVMatrix[1] * mgl_Vertex; // vertex eye position
+
+ normal = normalize(mgl_NormalMatrix * mgl_Normal);
+ // cameraPosition: (mgl_PMVMatrix[2] * vec4(0,0,0,1.0)).xyz
+ cameraDir = normalize( (mgl_PMVMatrix[2] * vec4(0,0,0,1.0)).xyz - mgl_Vertex.xyz );
+
+ ambient = vec4(0,0,0,0);
+ diffuse = vec4(0,0,0,0);
+ specular = vec4(0,0,0,0);
+
+ bool lightEnabled = false;
+
+ for(i=0; i<MAX_LIGHTS; i++) {
+ if( 0!= mgl_LightsEnabled[i] ) {
+ lightEnabled = true;
+ ambient += mgl_LightSource[i].ambient;
+ lightDir = mgl_LightSource[i].position.xyz - position.xyz;
+ dist = length(lightDir);
+ lightDir = normalize(lightDir);
+ attenuation = 1.0 / (
+ mgl_LightSource[i].constantAttenuation+
+ mgl_LightSource[i].linearAttenuation * dist +
+ mgl_LightSource[i].quadraticAttenuation * dist * dist );
+ NdotL = max(0.0, dot(normal, lightDir));
+ diffuse += mgl_LightSource[i].diffuse * NdotL * attenuation;
+ if (NdotL != 0.0) {
+ halfDir = normalize (lightDir + cameraDir);
+ NdotHV = max(0.0, dot(normal, halfDir));
+ specular += mgl_LightSource[i].specular *
+ pow(NdotHV,mgl_FrontMaterial.shininess) * attenuation;
+ }
+ }
+ }
+ ambient += mgl_FrontMaterial.ambient;
+ diffuse *= mgl_FrontMaterial.diffuse;
+ specular *= mgl_FrontMaterial.specular;
+
+ if(mgl_ColorEnabled>0) {
+ frontColor=mgl_Color;
+ } else {
+ frontColor=mgl_ColorStatic;
+ }
+ if( lightEnabled ) {
+ frontColor *= ambient + diffuse + specular;
+ }
+
+ gl_Position = mgl_PMVMatrix[0] * position;
+
+ setTexCoord(gl_Position);
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColorTexture.fp b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColorTexture.fp
new file mode 100644
index 000000000..86e6ace73
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/FixedFuncColorTexture.fp
@@ -0,0 +1,47 @@
+
+#include es_precision.glsl
+#include mgl_lightdef.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_varying.glsl
+
+vec4 getTexColor(in sampler2D tex, in int idx) {
+ vec4 coord;
+ if(idx==0) {
+ coord= mgl_TexCoords[0];
+ } else if(idx==1) {
+ coord= mgl_TexCoords[1];
+ } else if(idx==2) {
+ coord= mgl_TexCoords[2];
+ } else if(idx==3) {
+ coord= mgl_TexCoords[3];
+ } else if(idx==4) {
+ coord= mgl_TexCoords[4];
+ } else if(idx==5) {
+ coord= mgl_TexCoords[5];
+ } else if(idx==6) {
+ coord= mgl_TexCoords[6];
+ } else {
+ coord= mgl_TexCoords[7];
+ }
+ return texture2D(tex, coord.st);
+}
+
+void main (void)
+{
+ if( mgl_CullFace > 0 &&
+ ( ( mgl_CullFace == 1 && gl_FrontFacing ) ||
+ ( mgl_CullFace == 2 && !gl_FrontFacing ) ||
+ ( mgl_CullFace == 3 ) ) ) {
+ discard;
+ }
+
+ vec4 texColor = getTexColor(mgl_ActiveTexture,mgl_ActiveTextureIdx);
+
+ if(length(texColor.rgb)>0.0) {
+ gl_FragColor = vec4(frontColor.rgb*texColor.rgb, frontColor.a) ;
+ } else {
+ gl_FragColor = frontColor;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColor.bfp b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColor.bfp
new file mode 100755
index 000000000..3ebaaee1d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColor.bfp
Binary files differ
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColor.bvp b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColor.bvp
new file mode 100755
index 000000000..279ef72c7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColor.bvp
Binary files differ
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColorLight.bvp b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColorLight.bvp
new file mode 100755
index 000000000..5a9deea71
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColorLight.bvp
Binary files differ
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColorTexture.bfp b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColorTexture.bfp
new file mode 100755
index 000000000..ce1397fe1
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/bin/nvidia/FixedFuncColorTexture.bfp
Binary files differ
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/es_precision.glsl b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/es_precision.glsl
new file mode 100644
index 000000000..fd6abe54e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/es_precision.glsl
@@ -0,0 +1,14 @@
+#ifndef es_precision_glsl
+#define es_precision_glsl
+
+#ifdef GL_ES
+ #define MEDIUMP mediump
+ #define HIGHP highp
+ #define LOWP lowp
+#else
+ #define MEDIUMP
+ #define HIGHP
+ #define LOWP
+#endif
+
+#endif // es_precision_glsl
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_attribute.glsl b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_attribute.glsl
new file mode 100644
index 000000000..b09bdb05a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_attribute.glsl
@@ -0,0 +1,19 @@
+
+#ifndef mgl_attribute_glsl
+#define mgl_attribute_glsl
+
+#include es_precision.glsl
+
+attribute HIGHP vec4 mgl_Vertex;
+attribute HIGHP vec3 mgl_Normal;
+attribute HIGHP vec4 mgl_Color;
+attribute HIGHP vec4 mgl_MultiTexCoord0;
+attribute HIGHP vec4 mgl_MultiTexCoord1;
+attribute HIGHP vec4 mgl_MultiTexCoord2;
+attribute HIGHP vec4 mgl_MultiTexCoord3;
+attribute HIGHP vec4 mgl_MultiTexCoord4;
+attribute HIGHP vec4 mgl_MultiTexCoord5;
+attribute HIGHP vec4 mgl_MultiTexCoord6;
+attribute HIGHP vec4 mgl_MultiTexCoord7;
+
+#endif // mgl_attribute_glsl
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_const.glsl b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_const.glsl
new file mode 100644
index 000000000..1a464a1cb
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_const.glsl
@@ -0,0 +1,10 @@
+
+#ifndef mgl_const_glsl
+#define mgl_const_glsl
+
+#include es_precision.glsl
+
+const LOWP int MAX_TEXTURE_UNITS = 8; // <=gl_MaxTextureImageUnits
+const LOWP int MAX_LIGHTS = 8;
+
+#endif // mgl_const_glsl
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_lightdef.glsl b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_lightdef.glsl
new file mode 100644
index 000000000..98e214139
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_lightdef.glsl
@@ -0,0 +1,26 @@
+#ifndef mgl_lightdef_glsl
+#define mgl_lightdef_glsl
+
+struct mgl_LightSourceParameters {
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 specular;
+ vec4 position;
+ // vec4 halfVector; // is computed here
+ vec3 spotDirection;
+ float spotExponent;
+ float spotCutoff; // (range: [0.0,90.0], 180.0)
+ //float spotCosCutoff; // (range: [1.0,0.0],-1.0)
+ float constantAttenuation;
+ float linearAttenuation;
+ float quadraticAttenuation;
+};
+struct mgl_MaterialParameters {
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 specular;
+ vec4 emission;
+ float shininess;
+};
+
+#endif // mgl_lightdef_glsl
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_settexcoord.vp b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_settexcoord.vp
new file mode 100644
index 000000000..1efe328d0
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_settexcoord.vp
@@ -0,0 +1,35 @@
+#ifndef mgl_settexcoord_vp
+#define mgl_settexcoord_vp
+
+#include es_precision.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_attribute.glsl
+#include mgl_varying.glsl
+
+void setTexCoord(in vec4 defpos) {
+ /**
+ * bitwise operator not supported on APX 2500 ES 2.0
+ *
+ mgl_TexCoords[0] = ( 0 != (mgl_TexCoordEnabled & 1) ) ? mgl_MultiTexCoord0 : defpos;
+ mgl_TexCoords[1] = ( 0 != (mgl_TexCoordEnabled & 2) ) ? mgl_MultiTexCoord1 : defpos;
+ mgl_TexCoords[2] = ( 0 != (mgl_TexCoordEnabled & 4) ) ? mgl_MultiTexCoord2 : defpos;
+ mgl_TexCoords[3] = ( 0 != (mgl_TexCoordEnabled & 8) ) ? mgl_MultiTexCoord3 : defpos;
+ mgl_TexCoords[4] = ( 0 != (mgl_TexCoordEnabled & 16) ) ? mgl_MultiTexCoord4 : defpos;
+ mgl_TexCoords[5] = ( 0 != (mgl_TexCoordEnabled & 32) ) ? mgl_MultiTexCoord5 : defpos;
+ mgl_TexCoords[6] = ( 0 != (mgl_TexCoordEnabled & 64) ) ? mgl_MultiTexCoord6 : defpos;
+ mgl_TexCoords[7] = ( 0 != (mgl_TexCoordEnabled & 128) ) ? mgl_MultiTexCoord7 : defpos;
+ */
+
+ mgl_TexCoords[0] = ( 0 != mgl_TexCoordEnabled[0] ) ? mgl_MultiTexCoord0 : defpos;
+ mgl_TexCoords[1] = ( 0 != mgl_TexCoordEnabled[1] ) ? mgl_MultiTexCoord1 : defpos;
+ mgl_TexCoords[2] = ( 0 != mgl_TexCoordEnabled[2] ) ? mgl_MultiTexCoord2 : defpos;
+ mgl_TexCoords[3] = ( 0 != mgl_TexCoordEnabled[3] ) ? mgl_MultiTexCoord3 : defpos;
+ mgl_TexCoords[4] = ( 0 != mgl_TexCoordEnabled[4] ) ? mgl_MultiTexCoord4 : defpos;
+ mgl_TexCoords[5] = ( 0 != mgl_TexCoordEnabled[5] ) ? mgl_MultiTexCoord5 : defpos;
+ mgl_TexCoords[6] = ( 0 != mgl_TexCoordEnabled[6] ) ? mgl_MultiTexCoord6 : defpos;
+ mgl_TexCoords[7] = ( 0 != mgl_TexCoordEnabled[7] ) ? mgl_MultiTexCoord7 : defpos;
+}
+
+#endif // mgl_settexcoord_vp
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_uniform.glsl b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_uniform.glsl
new file mode 100644
index 000000000..d8b3c7f95
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_uniform.glsl
@@ -0,0 +1,18 @@
+
+#ifndef mgl_uniform_glsl
+#define mgl_uniform_glsl
+
+#include es_precision.glsl
+
+#include mgl_const.glsl
+
+uniform HIGHP mat4 mgl_PMVMatrix[3]; // P, Mv, and Mvi
+uniform HIGHP mat3 mgl_NormalMatrix; // transpose(inverse(ModelView)).3x3
+uniform LOWP int mgl_ColorEnabled;
+uniform HIGHP vec4 mgl_ColorStatic;
+uniform LOWP int mgl_TexCoordEnabled[MAX_TEXTURE_UNITS];
+uniform sampler2D mgl_ActiveTexture;
+uniform LOWP int mgl_ActiveTextureIdx;
+uniform LOWP int mgl_CullFace;
+
+#endif // mgl_uniform_glsl
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_uniform_light.glsl b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_uniform_light.glsl
new file mode 100644
index 000000000..0dedb5d5d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_uniform_light.glsl
@@ -0,0 +1,15 @@
+
+#ifndef mgl_uniform_light_glsl
+#define mgl_uniform_light_glsl
+
+#include es_precision.glsl
+
+#include mgl_const.glsl
+#include mgl_lightdef.glsl
+
+uniform LOWP int mgl_LightsEnabled[MAX_LIGHTS];
+
+uniform mgl_LightSourceParameters mgl_LightSource[MAX_LIGHTS];
+uniform mgl_MaterialParameters mgl_FrontMaterial;
+
+#endif // mgl_uniform_light_glsl
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_varying.glsl b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_varying.glsl
new file mode 100644
index 000000000..fc9f735d1
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/mgl_varying.glsl
@@ -0,0 +1,12 @@
+
+#ifndef mgl_varying_glsl
+#define mgl_varying_glsl
+
+#include es_precision.glsl
+
+#include mgl_const.glsl
+
+varying vec4 frontColor;
+varying vec4 mgl_TexCoords[MAX_TEXTURE_UNITS];
+
+#endif // mgl_varying_glsl
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/scripts/nvidia-apx/glslc-ff.bat b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/scripts/nvidia-apx/glslc-ff.bat
new file mode 100755
index 000000000..8a2114e07
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/scripts/nvidia-apx/glslc-ff.bat
@@ -0,0 +1,9 @@
+REM
+REM You have to call it from the 'shaders' directory, e.g.:
+REM scripts\nvidia-apx\glslc-ff.bat
+REM
+IF !"%JOGLDIR%"==""! GOTO YESPATH
+set JOGLDIR=..\lib
+:YESPATH
+
+java -cp %JOGLDIR%\jogl.core.jar;%JOGLDIR%\jogl.gles2.jar;%JOGLDIR%\jogl.fixed.jar;%JOGLDIR%\jogl.sdk.jar com.jogamp.opengl.util.glsl.sdk.CompileShaderNVidia FixedFuncColor.fp FixedFuncColorTexture.fp FixedFuncColorLight.vp FixedFuncColor.vp
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/scripts/nvidia-apx/glslc.bat b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/scripts/nvidia-apx/glslc.bat
new file mode 100755
index 000000000..c7ca0a8b7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/impl/shaders/scripts/nvidia-apx/glslc.bat
@@ -0,0 +1,9 @@
+REM
+REM You have to call it from the 'shaders' directory, e.g.:
+REM scripts\nvidia-apx\glslc.bat <FileName>
+REM
+IF !"%JOGLDIR%"==""! GOTO YESPATH
+set JOGLDIR=..\lib
+:YESPATH
+
+java -cp %JOGLDIR%\jogl.core.jar;%JOGLDIR%\jogl.gles2.jar;%JOGLDIR%\jogl.fixed.jar;%JOGLDIR%\jogl.sdk.jar com.jogamp.opengl.util.glsl.sdk.CompileShaderNVidia %1
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java
new file mode 100755
index 000000000..a0eed50ea
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShader.java
@@ -0,0 +1,185 @@
+package com.jogamp.opengl.util.glsl.sdk;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.glsl.*;
+
+import java.io.*;
+import java.net.*;
+
+/**
+ * Precompiles a shader into a vendor binary format. Input is the
+ * resource name of the shader, such as
+ * "com/jogamp/opengl/impl/glsl/fixed/shader/a.fp".
+ * Output is "com/jogamp/opengl/impl/glsl/fixed/shader/bin/nvidia/a.bfp".
+ *
+ * All path and suffixes are determined by the ShaderCode class,
+ * which ensures runtime compatibility.
+ *
+ * @see com.jogamp.opengl.util.glsl.ShaderCode
+ */
+
+public abstract class CompileShader {
+
+ public abstract int getBinaryFormat();
+
+ public abstract File getSDKCompilerDir();
+
+ public abstract String getVertexShaderCompiler();
+
+ public abstract String getFragmentShaderCompiler();
+
+ public void processOneShader(String resourceName)
+ throws IOException, UnsupportedEncodingException, InterruptedException
+ {
+ int type = -1;
+ String outName=null;
+ int suffixLen = -1;
+ if(resourceName.endsWith(ShaderCode.getFileSuffix(false, GL2ES2.GL_FRAGMENT_SHADER))) {
+ suffixLen = 2;
+ type = GL2ES2.GL_FRAGMENT_SHADER;
+ } else if(resourceName.endsWith(".frag")) {
+ suffixLen = 4;
+ type = GL2ES2.GL_FRAGMENT_SHADER;
+ } else if(resourceName.endsWith(ShaderCode.getFileSuffix(false, GL2ES2.GL_VERTEX_SHADER))) {
+ suffixLen = 2;
+ type = GL2ES2.GL_VERTEX_SHADER;
+ } else if(resourceName.endsWith(".vert")) {
+ suffixLen = 4;
+ type = GL2ES2.GL_VERTEX_SHADER;
+ }
+ String justName = basename(resourceName);
+ outName = justName.substring(0, justName.length() - suffixLen) +
+ ShaderCode.getFileSuffix(true, type);
+ URL resourceURL = Locator.getResource(null, resourceName);
+ String dirName = dirname(resourceURL.getPath());
+
+ outName = dirName + File.separator + "bin" + File.separator +
+ ShaderCode.getBinarySubPath(getBinaryFormat()) + File.separator +
+ outName;
+ processOneShader(resourceName, outName, type);
+ }
+
+ public void processOneShader(String resourceName, String outName, int type)
+ throws IOException, UnsupportedEncodingException, InterruptedException
+ {
+ URL resourceURL = Locator.getResource(null, resourceName);
+ String dirName = dirname(resourceURL.getPath());
+
+ String shader = ShaderCode.readShaderSource(null, resourceName);
+ if(null==shader) {
+ System.err.println("Can't find shader source " + resourceName + " - ignored");
+ return;
+ }
+ System.err.println("Preprocessing: "+ resourceName+", in dir: "+dirName);
+ String justName = basename(resourceName);
+ String processor;
+ switch (type) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ processor = getVertexShaderCompiler();
+ break;
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ processor = getFragmentShaderCompiler();
+ break;
+ default:
+ throw new GLException("Unknown shader type: "+type);
+ }
+ File outputFile = new File(outName);
+
+ // Write shader to a file in java.io.tmpdir
+ File tmpDir = new File(dirName+File.separator+"tmp");
+ tmpDir.mkdirs();
+ File tmpFile = new File(tmpDir, justName);
+ Writer writer = new BufferedWriter(new FileWriter(tmpFile));
+ writer.write(shader, 0, shader.length());
+ writer.flush();
+ writer.close();
+ System.err.println("Preprocessed: "+ tmpFile.getAbsolutePath());
+
+ File processorDir = getSDKCompilerDir();
+
+ System.err.println("SDK: "+ processorDir.getAbsolutePath() + ", compiler: "+processor);
+
+ System.err.println("Output: "+ outputFile.getAbsolutePath());
+
+ // Run the tool
+ Process process = Runtime.getRuntime().exec(new String[] {
+ processorDir.getAbsolutePath() + File.separator + processor,
+ tmpFile.getAbsolutePath(),
+ outputFile.getAbsolutePath()
+ }); // , null, processorDir);
+ new StreamMonitor(process.getInputStream());
+ new StreamMonitor(process.getErrorStream());
+ process.waitFor();
+ // Delete the temporary file
+ // tmpFile.delete();
+ }
+
+ protected static String basename(String path) {
+ int lastSlash = path.lastIndexOf("/");
+ if (lastSlash < 0) {
+ lastSlash = path.lastIndexOf("\\");
+ }
+ String basename;
+ if (lastSlash < 0) {
+ basename = path;
+ } else {
+ basename = path.substring(lastSlash + 1);
+ }
+ return basename;
+ }
+
+ protected static String dirname(String path) {
+ int lastSlash = path.lastIndexOf("/");
+ if (lastSlash < 0) {
+ lastSlash = path.lastIndexOf("\\");
+ }
+ String dirname;
+ if (lastSlash < 0) {
+ dirname = new String();
+ } else {
+ dirname = path.substring(0, lastSlash + 1);
+ }
+ return dirname;
+ }
+
+ public void run(String[] args) {
+ try {
+ for (int i = 0; i < args.length; i++) {
+ processOneShader(args[i]);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static class StreamMonitor implements Runnable {
+ private InputStream istream;
+ public StreamMonitor(InputStream stream) {
+ istream = stream;
+ new Thread(this, "Output Reader Thread").start();
+ }
+
+ public void run()
+ {
+ byte[] buffer = new byte[4096];
+ try {
+ int numRead = 0;
+ do {
+ numRead = istream.read(buffer);
+ if (numRead > 0) {
+ System.out.write(buffer, 0, numRead);
+ System.out.flush();
+ }
+ } while (numRead >= 0);
+ }
+ catch (IOException e) {
+ try {
+ istream.close();
+ } catch (IOException e2) {
+ }
+ // Should allow clean exit when process shuts down
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShaderNVidia.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShaderNVidia.java
new file mode 100755
index 000000000..8eb9ef579
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/sdk/CompileShaderNVidia.java
@@ -0,0 +1,53 @@
+package com.jogamp.opengl.util.glsl.sdk;
+
+import javax.media.opengl.*;
+
+import java.io.*;
+
+/** Precompiles a shader into NVidia binary format. Input is the
+ resource name of the shader, such as
+ "com/jogamp/opengl/impl/glsl/fixed/shader/a.fp".
+ Output is "com/jogamp/opengl/impl/glsl/fixed/shader/bin/nvidia/a.bfp". */
+
+public class CompileShaderNVidia extends CompileShader {
+ private static final String NVAPSDK;
+
+ static {
+ String nvapSDKProp = System.getProperty("NVAPSDK");
+ if (nvapSDKProp != null) {
+ NVAPSDK = nvapSDKProp;
+ } else {
+ NVAPSDK = "C:\\nvap_sdk_0_3_x";
+ }
+ }
+
+ public int getBinaryFormat() {
+ return GLES2.GL_NVIDIA_PLATFORM_BINARY_NV;
+ }
+
+ public File getSDKCompilerDir() {
+ File compilerDir = new File( NVAPSDK + File.separator + "tools" + File.separator );
+ File compilerFile = new File( compilerDir, getVertexShaderCompiler());
+ if(!compilerFile.exists()) {
+ compilerDir = new File( NVAPSDK );
+ compilerFile = new File( compilerDir, getVertexShaderCompiler());
+ }
+ if(!compilerFile.exists()) {
+ throw new GLException("Can't find compiler: "+getVertexShaderCompiler() + " in : " +
+ NVAPSDK+", "+NVAPSDK + File.separator + "tools");
+ }
+ return compilerDir;
+ }
+
+ public String getVertexShaderCompiler() {
+ return "glslv.bat";
+ }
+
+ public String getFragmentShaderCompiler() {
+ return "glslf.bat";
+ }
+
+ public static void main(String[] args) {
+ new CompileShaderNVidia().run(args);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/packrect/BackingStoreManager.java b/src/jogl/classes/com/jogamp/opengl/util/packrect/BackingStoreManager.java
new file mode 100755
index 000000000..7b6a1b479
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/packrect/BackingStoreManager.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.packrect;
+
+/** This interface must be implemented by the end user and is called
+ in response to events like addition of rectangles into the
+ RectanglePacker. It is used both when a full re-layout must be
+ done as well as when the data in the backing store must be copied
+ to a new one. */
+
+public interface BackingStoreManager {
+ public Object allocateBackingStore(int w, int h);
+ public void deleteBackingStore(Object backingStore);
+
+ /** Indication whether this BackingStoreManager supports compaction;
+ in other words, the allocation of a new backing store and
+ movement of the contents of the backing store from the old to
+ the new one. If it does not, then RectanglePacker.add() may
+ throw an exception if additionFailed() can not make enough room
+ available. If an implementation returns false, this also implies
+ that the backing store can not grow, so that preExpand() will
+ never be called. */
+ public boolean canCompact();
+
+ /** Notification that expansion of the backing store is about to be
+ done due to addition of the given rectangle. Gives the manager a
+ chance to do some compaction and potentially remove old entries
+ from the backing store, if it acts like a least-recently-used
+ cache. This method receives as argument the number of attempts
+ so far to add the given rectangle. Manager should return true if
+ the RectanglePacker should retry the addition (which may result
+ in this method being called again, with an increased attempt
+ number) or false if the RectanglePacker should just expand the
+ backing store. The caller should not call RectanglePacker.add()
+ in its preExpand() method. */
+ public boolean preExpand(Rect cause, int attemptNumber);
+
+ /** Notification that addition of the given Rect failed because a
+ maximum size was set in the RectanglePacker and the backing
+ store could not be expanded, or because compaction (and,
+ therefore, implicitly expansion) was not supported. Should
+ return false if the manager can do nothing more to handle the
+ failed addition, which will cause a RuntimeException to be
+ thrown from the RectanglePacker. */
+ public boolean additionFailed(Rect cause, int attemptNumber);
+
+ /** Notification that movement is starting. */
+ public void beginMovement(Object oldBackingStore, Object newBackingStore);
+
+ /** Tells the manager to move the contents of the given rect from
+ the old location on the old backing store to the new location on
+ the new backing store. The backing stores can be identical in
+ the case of compacting the existing backing store instead of
+ reallocating it. */
+ public void move(Object oldBackingStore,
+ Rect oldLocation,
+ Object newBackingStore,
+ Rect newLocation);
+
+ /** Notification that movement is ending. */
+ public void endMovement(Object oldBackingStore, Object newBackingStore);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/packrect/Level.java b/src/jogl/classes/com/jogamp/opengl/util/packrect/Level.java
new file mode 100755
index 000000000..5ba3f7330
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/packrect/Level.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.packrect;
+
+import java.util.*;
+
+public class Level {
+ private int width;
+ private int height;
+ private int yPos;
+ private LevelSet holder;
+
+ private List/*<Rect>*/ rects = new ArrayList/*<Rect>*/();
+ private List/*<Rect>*/ freeList;
+ private int nextAddX;
+
+ static class RectXComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ Rect r1 = (Rect) o1;
+ Rect r2 = (Rect) o2;
+ return r1.x() - r2.x();
+ }
+
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+ }
+ private static final Comparator rectXComparator = new RectXComparator();
+
+ public Level(int width, int height, int yPos, LevelSet holder) {
+ this.width = width;
+ this.height = height;
+ this.yPos = yPos;
+ this.holder = holder;
+ }
+
+ public int w() { return width; }
+ public int h() { return height; }
+ public int yPos() { return yPos; }
+
+ /** Tries to add the given rectangle to this level only allowing
+ non-disruptive changes like trivial expansion of the last level
+ in the RectanglePacker and allocation from the free list. More
+ disruptive changes like compaction of the level must be
+ requested explicitly. */
+ public boolean add(Rect rect) {
+ if (rect.h() > height) {
+ // See whether it's worth trying to expand vertically
+ if (nextAddX + rect.w() > width) {
+ return false;
+ }
+
+ // See whether we're the last level and can expand
+ if (!holder.canExpand(this, rect.h())) {
+ return false;
+ }
+
+ // Trivially expand and try the allocation
+ holder.expand(this, height, rect.h());
+ height = rect.h();
+ }
+
+ // See whether we can add at the end
+ if (nextAddX + rect.w() <= width) {
+ rect.setPosition(nextAddX, yPos);
+ rects.add(rect);
+ nextAddX += rect.w();
+ return true;
+ }
+
+ // See whether we can add from the free list
+ if (freeList != null) {
+ Rect candidate = null;
+ for (Iterator iter = freeList.iterator(); iter.hasNext(); ) {
+ Rect cur = (Rect) iter.next();
+ if (cur.canContain(rect)) {
+ candidate = cur;
+ break;
+ }
+ }
+
+ if (candidate != null) {
+ // Remove the candidate from the free list
+ freeList.remove(candidate);
+ // Set up and add the real rect
+ rect.setPosition(candidate.x(), candidate.y());
+ rects.add(rect);
+ // Re-add any remaining free space
+ if (candidate.w() > rect.w()) {
+ candidate.setPosition(candidate.x() + rect.w(), candidate.y());
+ candidate.setSize(candidate.w() - rect.w(), height);
+ freeList.add(candidate);
+ }
+
+ coalesceFreeList();
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /** Removes the given Rect from this Level. */
+ public boolean remove(Rect rect) {
+ if (!rects.remove(rect))
+ return false;
+
+ // If this is the rightmost rectangle, instead of adding its space
+ // to the free list, we can just decrease the nextAddX
+ if (rect.maxX() + 1 == nextAddX) {
+ nextAddX -= rect.w();
+ } else {
+ if (freeList == null) {
+ freeList = new ArrayList/*<Rect>*/();
+ }
+ freeList.add(new Rect(rect.x(), rect.y(), rect.w(), height, null));
+ coalesceFreeList();
+ }
+
+ return true;
+ }
+
+ /** Indicates whether this Level contains no rectangles. */
+ public boolean isEmpty() {
+ return rects.isEmpty();
+ }
+
+ /** Indicates whether this Level could satisfy an allocation request
+ if it were compacted. */
+ public boolean couldAllocateIfCompacted(Rect rect) {
+ if (rect.h() > height)
+ return false;
+ if (freeList == null)
+ return false;
+ int freeListWidth = 0;
+ for (Iterator iter = freeList.iterator(); iter.hasNext(); ) {
+ Rect cur = (Rect) iter.next();
+ freeListWidth += cur.w();
+ }
+ // Add on the remaining space at the end
+ freeListWidth += (width - nextAddX);
+ return (freeListWidth >= rect.w());
+ }
+
+ public void compact(Object backingStore, BackingStoreManager manager) {
+ Collections.sort(rects, rectXComparator);
+ int nextCompactionDest = 0;
+ manager.beginMovement(backingStore, backingStore);
+ for (Iterator iter = rects.iterator(); iter.hasNext(); ) {
+ Rect cur = (Rect) iter.next();
+ if (cur.x() != nextCompactionDest) {
+ manager.move(backingStore, cur,
+ backingStore, new Rect(nextCompactionDest, cur.y(), cur.w(), cur.h(), null));
+ cur.setPosition(nextCompactionDest, cur.y());
+ }
+ nextCompactionDest += cur.w();
+ }
+ nextAddX = nextCompactionDest;
+ freeList.clear();
+ manager.endMovement(backingStore, backingStore);
+ }
+
+ public Iterator iterator() {
+ return rects.iterator();
+ }
+
+ /** Visits all Rects contained in this Level. */
+ public void visit(RectVisitor visitor) {
+ for (Iterator iter = rects.iterator(); iter.hasNext(); ) {
+ Rect rect = (Rect) iter.next();
+ visitor.visit(rect);
+ }
+ }
+
+ /** Updates the references to the Rect objects in this Level with
+ the "next locations" of those Rects. This is actually used to
+ update the new Rects in a newly laid-out LevelSet with the
+ original Rects. */
+ public void updateRectangleReferences() {
+ for (int i = 0; i < rects.size(); i++) {
+ Rect cur = (Rect) rects.get(i);
+ Rect next = cur.getNextLocation();
+ next.setPosition(cur.x(), cur.y());
+ if (cur.w() != next.w() || cur.h() != next.h())
+ throw new RuntimeException("Unexpected disparity in rectangle sizes during updateRectangleReferences");
+ rects.set(i, next);
+ }
+ }
+
+ private void coalesceFreeList() {
+ if (freeList == null)
+ return;
+ if (freeList.isEmpty())
+ return;
+
+ // Try to coalesce adjacent free blocks in the free list
+ Collections.sort(freeList, rectXComparator);
+ int i = 0;
+ while (i < freeList.size() - 1) {
+ Rect r1 = (Rect) freeList.get(i);
+ Rect r2 = (Rect) freeList.get(i+1);
+ if (r1.maxX() + 1 == r2.x()) {
+ // Coalesce r1 and r2 into one block
+ freeList.remove(i+1);
+ r1.setSize(r1.w() + r2.w(), r1.h());
+ } else {
+ ++i;
+ }
+ }
+ // See whether the last block bumps up against the addition point
+ Rect last = (Rect) freeList.get(freeList.size() - 1);
+ if (last.maxX() + 1 == nextAddX) {
+ nextAddX -= last.w();
+ freeList.remove(freeList.size() - 1);
+ }
+ if (freeList.isEmpty()) {
+ freeList = null;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Debugging functionality
+ //
+
+ public void dumpFreeSpace() {
+ int freeListWidth = 0;
+ for (Iterator iter = freeList.iterator(); iter.hasNext(); ) {
+ Rect cur = (Rect) iter.next();
+ System.err.println(" Free rectangle at " + cur);
+ freeListWidth += cur.w();
+ }
+ // Add on the remaining space at the end
+ System.err.println(" Remaining free space " + (width - nextAddX));
+ freeListWidth += (width - nextAddX);
+ System.err.println(" Total free space " + freeListWidth);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/packrect/LevelSet.java b/src/jogl/classes/com/jogamp/opengl/util/packrect/LevelSet.java
new file mode 100755
index 000000000..6783aec3b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/packrect/LevelSet.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.packrect;
+
+import java.util.*;
+
+/** Manages a list of Levels; this is the core data structure
+ contained within the RectanglePacker and encompasses the storage
+ algorithm for the contained Rects. */
+
+public class LevelSet {
+ // Maintained in sorted order by increasing Y coordinate
+ private List/*<Level>*/ levels = new ArrayList/*<Level>*/();
+ private int nextAddY;
+ private int w;
+ private int h;
+
+ /** A LevelSet manages all of the backing store for a region of a
+ specified width and height. */
+ public LevelSet(int w, int h) {
+ this.w = w;
+ this.h = h;
+ }
+
+ public int w() { return w; }
+ public int h() { return h; }
+
+ /** Returns true if the given rectangle was successfully added to
+ the LevelSet given its current dimensions, false if not. Caller
+ is responsible for performing compaction, expansion, etc. as a
+ consequence. */
+ public boolean add(Rect rect) {
+ if (rect.w() > w)
+ return false;
+
+ // Go in reverse order through the levels seeing whether we can
+ // trivially satisfy the allocation request
+ for (int i = levels.size() - 1; i >= 0; --i) {
+ Level level = (Level) levels.get(i);
+ if (level.add(rect))
+ return true;
+ }
+
+ // See whether compaction could satisfy this allocation. This
+ // increases the computational complexity of the addition process,
+ // but prevents us from expanding unnecessarily.
+ for (int i = levels.size() - 1; i >= 0; --i) {
+ Level level = (Level) levels.get(i);
+ if (level.couldAllocateIfCompacted(rect))
+ return false;
+ }
+
+ // OK, we need to either add a new Level or expand the backing
+ // store. Try to add a new Level.
+ if (nextAddY + rect.h() > h)
+ return false;
+
+ Level newLevel = new Level(w, rect.h(), nextAddY, this);
+ levels.add(newLevel);
+ nextAddY += rect.h();
+ boolean res = newLevel.add(rect);
+ if (!res)
+ throw new RuntimeException("Unexpected failure in addition to new Level");
+ return true;
+ }
+
+ /** Removes the given Rect from this LevelSet. */
+ public boolean remove(Rect rect) {
+ for (int i = levels.size() - 1; i >= 0; --i) {
+ Level level = (Level) levels.get(i);
+ if (level.remove(rect))
+ return true;
+ }
+
+ return false;
+ }
+
+ /** Allocates the given Rectangle, performing compaction of a Level
+ if necessary. This is the correct fallback path to {@link
+ #add(Rect)} above. Returns true if allocated successfully, false
+ otherwise (indicating the need to expand the backing store). */
+ public boolean compactAndAdd(Rect rect,
+ Object backingStore,
+ BackingStoreManager manager) {
+ for (int i = levels.size() - 1; i >= 0; --i) {
+ Level level = (Level) levels.get(i);
+ if (level.couldAllocateIfCompacted(rect)) {
+ level.compact(backingStore, manager);
+ boolean res = level.add(rect);
+ if (!res)
+ throw new RuntimeException("Unexpected failure to add after compaction");
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /** Indicates whether it's legal to trivially increase the height of
+ the given Level. This is only possible if it's the last Level
+ added and there's enough room in the backing store. */
+ public boolean canExpand(Level level, int height) {
+ if (levels.isEmpty())
+ return false; // Should not happen
+ if (levels.get(levels.size() - 1) == level &&
+ (h - nextAddY >= height - level.h()))
+ return true;
+ return false;
+ }
+
+ public void expand(Level level, int oldHeight, int newHeight) {
+ nextAddY += (newHeight - oldHeight);
+ }
+
+ /** Gets the used height of the levels in this LevelSet. */
+ public int getUsedHeight() {
+ return nextAddY;
+ }
+
+ /** Sets the height of this LevelSet. It is only legal to reduce the
+ height to greater than or equal to the currently used height. */
+ public void setHeight(int height) throws IllegalArgumentException {
+ if (height < getUsedHeight()) {
+ throw new IllegalArgumentException("May not reduce height below currently used height");
+ }
+ h = height;
+ }
+
+ /** Returns the vertical fragmentation ratio of this LevelSet. This
+ is defined as the ratio of the sum of the heights of all
+ completely empty Levels divided by the overall used height of
+ the LevelSet. A high vertical fragmentation ratio indicates that
+ it may be profitable to perform a compaction. */
+ public float verticalFragmentationRatio() {
+ int freeHeight = 0;
+ int usedHeight = getUsedHeight();
+ if (usedHeight == 0)
+ return 0.0f;
+ for (Iterator iter = iterator(); iter.hasNext(); ) {
+ Level level = (Level) iter.next();
+ if (level.isEmpty()) {
+ freeHeight += level.h();
+ }
+ }
+ return (float) freeHeight / (float) usedHeight;
+ }
+
+ public Iterator iterator() {
+ return levels.iterator();
+ }
+
+ /** Visits all Rects contained in this LevelSet. */
+ public void visit(RectVisitor visitor) {
+ for (Iterator iter = levels.iterator(); iter.hasNext(); ) {
+ Level level = (Level) iter.next();
+ level.visit(visitor);
+ }
+ }
+
+ /** Updates the references to the Rect objects in this LevelSet with
+ the "next locations" of those Rects. This is actually used to
+ update the new Rects in a newly laid-out LevelSet with the
+ original Rects. */
+ public void updateRectangleReferences() {
+ for (Iterator iter = levels.iterator(); iter.hasNext(); ) {
+ Level level = (Level) iter.next();
+ level.updateRectangleReferences();
+ }
+ }
+
+ /** Clears out all Levels stored in this LevelSet. */
+ public void clear() {
+ levels.clear();
+ nextAddY = 0;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/packrect/Rect.java b/src/jogl/classes/com/jogamp/opengl/util/packrect/Rect.java
new file mode 100755
index 000000000..6206c4a11
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/packrect/Rect.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.packrect;
+
+/** Represents a rectangular region on the backing store. The edges of
+ the rectangle are the infinitely thin region between adjacent
+ pixels on the screen. The origin of the rectangle is its
+ upper-left corner. It is inclusive of the pixels on the top and
+ left edges and exclusive of the pixels on the bottom and right
+ edges. For example, a rect at position (0, 0) and of size (1, 1)
+ would include only the pixel at (0, 0). <P>
+
+ Negative coordinates and sizes are not supported, since they make
+ no sense in the context of the packer, which deals only with
+ positively sized regions. <P>
+
+ This class contains a user data field for efficient hookup to
+ external data structures as well as enough other hooks to
+ efficiently plug into the rectangle packer. */
+
+public class Rect {
+ private int x;
+ private int y;
+ private int w;
+ private int h;
+
+ // The level we're currently installed in in the parent
+ // RectanglePacker, or null if not hooked in to the table yet
+ private Level level;
+
+ // The user's object this rectangle represents.
+ private Object userData;
+
+ // Used transiently during re-layout of the backing store (when
+ // there is no room left due either to fragmentation or just being
+ // out of space)
+ private Rect nextLocation;
+
+ public Rect() {
+ this(null);
+ }
+
+ public Rect(Object userData) {
+ this(0, 0, 0, 0, userData);
+ }
+
+ public Rect(int x, int y, int w, int h, Object userData) {
+ setPosition(x, y);
+ setSize(w, h);
+ setUserData(userData);
+ }
+
+ public int x() { return x; }
+ public int y() { return y; }
+ public int w() { return w; }
+ public int h() { return h; }
+ public Object getUserData() { return userData; }
+ public Rect getNextLocation() { return nextLocation; }
+
+ public void setPosition(int x, int y) {
+ if (x < 0)
+ throw new IllegalArgumentException("Negative x");
+ if (y < 0)
+ throw new IllegalArgumentException("Negative y");
+ this.x = x;
+ this.y = y;
+ }
+
+ public void setSize(int w, int h) throws IllegalArgumentException {
+ if (w < 0)
+ throw new IllegalArgumentException("Negative width");
+ if (h < 0)
+ throw new IllegalArgumentException("Negative height");
+ this.w = w;
+ this.h = h;
+ }
+
+ public void setUserData(Object obj) { userData = obj; }
+ public void setNextLocation(Rect nextLocation) { this.nextLocation = nextLocation; }
+
+ // Helpers for computations.
+
+ /** Returns the maximum x-coordinate contained within this
+ rectangle. Note that this returns a different result than Java
+ 2D's rectangles; for a rectangle of position (0, 0) and size (1,
+ 1) this will return 0, not 1. Returns -1 if the width of this
+ rectangle is 0. */
+ public int maxX() {
+ if (w() < 1)
+ return -1;
+ return x() + w() - 1;
+ }
+
+ /** Returns the maximum y-coordinate contained within this
+ rectangle. Note that this returns a different result than Java
+ 2D's rectangles; for a rectangle of position (0, 0) and size (1,
+ 1) this will return 0, not 1. Returns -1 if the height of this
+ rectangle is 0. */
+ public int maxY() {
+ if (h() < 1)
+ return -1;
+ return y() + h() - 1;
+ }
+
+ public boolean canContain(Rect other) {
+ return (w() >= other.w() &&
+ h() >= other.h());
+ }
+
+ public String toString() {
+ return "[Rect x: " + x() + " y: " + y() + " w: " + w() + " h: " + h() + "]";
+ }
+
+ // Unclear whether it's a good idea to override hashCode and equals
+ // for these objects
+ /*
+ public boolean equals(Object other) {
+ if (other == null || (!(other instanceof Rect))) {
+ return false;
+ }
+
+ Rect r = (Rect) other;
+ return (this.x() == r.x() &&
+ this.y() == r.y() &&
+ this.w() == r.w() &&
+ this.h() == r.h());
+ }
+
+ public int hashCode() {
+ return (x + y * 13 + w * 17 + h * 23);
+ }
+ */
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/packrect/RectVisitor.java b/src/jogl/classes/com/jogamp/opengl/util/packrect/RectVisitor.java
new file mode 100755
index 000000000..49cfc82e6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/packrect/RectVisitor.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.packrect;
+
+/** Iteration construct without exposing the internals of the
+ RectanglePacker and without implementing a complex Iterator. */
+
+public interface RectVisitor {
+ public void visit(Rect rect);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/packrect/RectanglePacker.java b/src/jogl/classes/com/jogamp/opengl/util/packrect/RectanglePacker.java
new file mode 100755
index 000000000..1496a04a6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/packrect/RectanglePacker.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.packrect;
+
+import java.util.*;
+
+/** Packs rectangles supplied by the user (typically representing
+ image regions) into a larger backing store rectangle (typically
+ representing a large texture). Supports automatic compaction of
+ the space on the backing store, and automatic expansion of the
+ backing store, when necessary. */
+
+public class RectanglePacker {
+ private BackingStoreManager manager;
+ private Object backingStore;
+ private LevelSet levels;
+ private float EXPANSION_FACTOR = 0.5f;
+ private float SHRINK_FACTOR = 0.3f;
+
+ private int initialWidth;
+ private int initialHeight;
+
+ private int maxWidth = -1;
+ private int maxHeight = -1;
+
+ static class RectHComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ Rect r1 = (Rect) o1;
+ Rect r2 = (Rect) o2;
+ return r2.h() - r1.h();
+ }
+
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+ }
+ private static final Comparator rectHComparator = new RectHComparator();
+
+ public RectanglePacker(BackingStoreManager manager,
+ int initialWidth,
+ int initialHeight) {
+ this.manager = manager;
+ levels = new LevelSet(initialWidth, initialHeight);
+ this.initialWidth = initialWidth;
+ this.initialHeight = initialHeight;
+ }
+
+ public Object getBackingStore() {
+ if (backingStore == null) {
+ backingStore = manager.allocateBackingStore(levels.w(), levels.h());
+ }
+
+ return backingStore;
+ }
+
+ /** Sets up a maximum width and height for the backing store. These
+ are optional and if not specified the backing store will grow as
+ necessary. Setting up a maximum width and height introduces the
+ possibility that additions will fail; these are handled with the
+ BackingStoreManager's allocationFailed notification. */
+ public void setMaxSize(int maxWidth, int maxHeight) {
+ this.maxWidth = maxWidth;
+ this.maxHeight = maxHeight;
+ }
+
+ /** Decides upon an (x, y) position for the given rectangle (leaving
+ its width and height unchanged) and places it on the backing
+ store. May provoke re-layout of other Rects already added. If
+ the BackingStoreManager does not support compaction, and {@link
+ BackingStoreManager#preExpand BackingStoreManager.preExpand}
+ does not clear enough space for the incoming rectangle, then
+ this method will throw a RuntimeException. */
+ public void add(Rect rect) throws RuntimeException {
+ // Allocate backing store if we don't have any yet
+ if (backingStore == null)
+ backingStore = manager.allocateBackingStore(levels.w(), levels.h());
+
+ int attemptNumber = 0;
+ boolean tryAgain = false;
+
+ do {
+ // Try to allocate
+ if (levels.add(rect))
+ return;
+
+ if (manager.canCompact()) {
+ // Try to allocate with horizontal compaction
+ if (levels.compactAndAdd(rect, backingStore, manager))
+ return;
+ // Let the manager have a chance at potentially evicting some entries
+ tryAgain = manager.preExpand(rect, attemptNumber++);
+ } else {
+ tryAgain = manager.additionFailed(rect, attemptNumber++);
+ }
+ } while (tryAgain);
+
+ if (!manager.canCompact()) {
+ throw new RuntimeException("BackingStoreManager does not support compaction or expansion, and didn't clear space for new rectangle");
+ }
+
+ compactImpl(rect);
+
+ // Retry the addition of the incoming rectangle
+ add(rect);
+ // Done
+ }
+
+ /** Removes the given rectangle from this RectanglePacker. */
+ public void remove(Rect rect) {
+ levels.remove(rect);
+ }
+
+ /** Visits all Rects contained in this RectanglePacker. */
+ public void visit(RectVisitor visitor) {
+ levels.visit(visitor);
+ }
+
+ /** Returns the vertical fragmentation ratio of this
+ RectanglePacker. This is defined as the ratio of the sum of the
+ heights of all completely empty Levels divided by the overall
+ used height of the LevelSet. A high vertical fragmentation ratio
+ indicates that it may be profitable to perform a compaction. */
+ public float verticalFragmentationRatio() {
+ return levels.verticalFragmentationRatio();
+ }
+
+ /** Forces a compaction cycle, which typically results in allocating
+ a new backing store and copying all entries to it. */
+ public void compact() {
+ compactImpl(null);
+ }
+
+ // The "cause" rect may be null
+ private void compactImpl(Rect cause) {
+ // Have to either expand, compact or both. Need to figure out what
+ // direction to go. Prefer to expand vertically. Expand
+ // horizontally only if rectangle being added is too wide. FIXME:
+ // may want to consider rebalancing the width and height to be
+ // more equal if it turns out we keep expanding in the vertical
+ // direction.
+ boolean done = false;
+ int newWidth = levels.w();
+ int newHeight = levels.h();
+ LevelSet nextLevelSet = null;
+ int attemptNumber = 0;
+ boolean needAdditionFailureNotification = false;
+
+ while (!done) {
+ if (cause != null) {
+ if (cause.w() > newWidth) {
+ newWidth = cause.w();
+ } else {
+ newHeight = (int) (newHeight * (1.0f + EXPANSION_FACTOR));
+ }
+ }
+
+ // Clamp to maximum values
+ needAdditionFailureNotification = false;
+ if (maxWidth > 0 && newWidth > maxWidth) {
+ newWidth = maxWidth;
+ needAdditionFailureNotification = true;
+ }
+ if (maxHeight > 0 && newHeight > maxHeight) {
+ newHeight = maxHeight;
+ needAdditionFailureNotification = true;
+ }
+
+ nextLevelSet = new LevelSet(newWidth, newHeight);
+
+ // Make copies of all existing rectangles
+ List/*<Rect>*/ newRects = new ArrayList/*<Rect>*/();
+ for (Iterator i1 = levels.iterator(); i1.hasNext(); ) {
+ Level level = (Level) i1.next();
+ for (Iterator i2 = level.iterator(); i2.hasNext(); ) {
+ Rect cur = (Rect) i2.next();
+ Rect newRect = new Rect(0, 0, cur.w(), cur.h(), null);
+ cur.setNextLocation(newRect);
+ // Hook up the reverse mapping too for easier replacement
+ newRect.setNextLocation(cur);
+ newRects.add(newRect);
+ }
+ }
+ // Sort them by decreasing height (note: this isn't really
+ // guaranteed to improve the chances of a successful layout)
+ Collections.sort(newRects, rectHComparator);
+ // Try putting all of these rectangles into the new level set
+ done = true;
+ for (Iterator iter = newRects.iterator(); iter.hasNext(); ) {
+ if (!nextLevelSet.add((Rect) iter.next())) {
+ done = false;
+ break;
+ }
+ }
+
+ if (done && cause != null) {
+ // Try to add the new rectangle as well
+ if (nextLevelSet.add(cause)) {
+ // We're OK
+ } else {
+ done = false;
+ }
+ }
+
+ // Don't send addition failure notifications if we're only doing
+ // a compaction
+ if (!done && needAdditionFailureNotification && cause != null) {
+ manager.additionFailed(cause, attemptNumber);
+ }
+ ++attemptNumber;
+ }
+
+ // See whether the implicit compaction that just occurred has
+ // yielded excess empty space.
+ if (nextLevelSet.getUsedHeight() > 0 &&
+ nextLevelSet.getUsedHeight() < nextLevelSet.h() * SHRINK_FACTOR) {
+ int shrunkHeight = Math.max(initialHeight,
+ (int) (nextLevelSet.getUsedHeight() * (1.0f + EXPANSION_FACTOR)));
+ if (maxHeight > 0 && shrunkHeight > maxHeight) {
+ shrunkHeight = maxHeight;
+ }
+ nextLevelSet.setHeight(shrunkHeight);
+ }
+
+ // If we temporarily added the new rectangle to the new LevelSet,
+ // take it out since we don't "really" add it here but in add(), above
+ if (cause != null) {
+ nextLevelSet.remove(cause);
+ }
+
+ // OK, now we have a new layout and a mapping from the old to the
+ // new locations of rectangles on the backing store. Allocate a
+ // new backing store, move the contents over and deallocate the
+ // old one.
+ Object newBackingStore = manager.allocateBackingStore(nextLevelSet.w(),
+ nextLevelSet.h());
+ manager.beginMovement(backingStore, newBackingStore);
+ for (Iterator i1 = levels.iterator(); i1.hasNext(); ) {
+ Level level = (Level) i1.next();
+ for (Iterator i2 = level.iterator(); i2.hasNext(); ) {
+ Rect cur = (Rect) i2.next();
+ manager.move(backingStore, cur,
+ newBackingStore, cur.getNextLocation());
+ }
+ }
+ // Replace references to temporary rectangles with original ones
+ nextLevelSet.updateRectangleReferences();
+ manager.endMovement(backingStore, newBackingStore);
+ // Now delete the old backing store
+ manager.deleteBackingStore(backingStore);
+ // Update to new versions of backing store and LevelSet
+ backingStore = newBackingStore;
+ levels = nextLevelSet;
+ }
+
+ /** Clears all Rects contained in this RectanglePacker. */
+ public void clear() {
+ levels.clear();
+ }
+
+ /** Disposes the backing store allocated by the
+ BackingStoreManager. This RectanglePacker may no longer be used
+ after calling this method. */
+ public void dispose() {
+ if (backingStore != null)
+ manager.deleteBackingStore(backingStore);
+ backingStore = null;
+ levels = null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/packrect/package.html b/src/jogl/classes/com/jogamp/opengl/util/packrect/package.html
new file mode 100755
index 000000000..c1c5db477
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/packrect/package.html
@@ -0,0 +1,9 @@
+<BODY>
+This package implements a rectangle packing algorithm suitable for
+tracking the placement of multiple rectangles inside a larger one. It
+is useful for cases such as placing the contents of multiple windows
+on a larger backing store texture for a compositing window manager;
+placing multiple rasterized strings in a texture map for quick
+rendering to the screen; and many other situations where it is useful
+to carve up a larger texture into smaller pieces dynamically. <P>
+</BODY>
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
new file mode 100755
index 000000000..57ac0d45a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -0,0 +1,1120 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.util.texture;
+
+import java.nio.*;
+import java.security.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import javax.media.nativewindow.NativeWindowFactory;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.util.texture.*;
+import com.jogamp.opengl.util.texture.spi.*;
+
+/**
+ * Represents an OpenGL texture object. Contains convenience routines
+ * for enabling/disabling OpenGL texture state, binding this texture,
+ * and computing texture coordinates for both the entire image as well
+ * as a sub-image.
+ *
+ * <p><a name="nonpow2"><b>Non-power-of-two restrictions</b></a>
+ * <br> When creating an OpenGL texture object, the Texture class will
+ * attempt to leverage the <a
+ * href="http://www.opengl.org/registry/specs/ARB/texture_non_power_of_two.txt">GL_ARB_texture_non_power_of_two</a>
+ * and <a
+ * href="http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt">GL_ARB_texture_rectangle</a>
+ * extensions (in that order) whenever possible. If neither extension
+ * is available, the Texture class will simply upload a non-pow2-sized
+ * image into a standard pow2-sized texture (without any special
+ * scaling). Since the choice of extension (or whether one is used at
+ * all) depends on the user's machine configuration, developers are
+ * recommended to use {@link #getImageTexCoords} and {@link
+ * #getSubImageTexCoords}, as those methods will calculate the
+ * appropriate texture coordinates for the situation.
+ *
+ * <p>One caveat in this approach is that certain texture wrap modes
+ * (e.g. <code>GL_REPEAT</code>) are not legal when the GL_ARB_texture_rectangle
+ * extension is in use. Another issue to be aware of is that in the
+ * default pow2 scenario, if the original image does not have pow2
+ * dimensions, then wrapping may not work as one might expect since
+ * the image does not extend to the edges of the pow2 texture. If
+ * texture wrapping is important, it is recommended to use only
+ * pow2-sized images with the Texture class.
+ *
+ * <p><a name="perftips"><b>Performance Tips</b></a>
+ * <br> For best performance, try to avoid calling {@link #enable} /
+ * {@link #bind} / {@link #disable} any more than necessary. For
+ * example, applications using many Texture objects in the same scene
+ * may want to reduce the number of calls to both {@link #enable} and
+ * {@link #disable}. To do this it is necessary to call {@link
+ * #getTarget} to make sure the OpenGL texture target is the same for
+ * all of the Texture objects in use; non-power-of-two textures using
+ * the GL_ARB_texture_rectangle extension use a different target than
+ * power-of-two textures using the GL_TEXTURE_2D target. Note that
+ * when switching between textures it is necessary to call {@link
+ * #bind}, but when drawing many triangles all using the same texture,
+ * for best performance only one call to {@link #bind} should be made.
+ *
+ * <p><a name="premult"><b>Alpha premultiplication and blending</b></a>
+ * <br> The mathematically correct way to perform blending in OpenGL
+ * (with the SrcOver "source over destination" mode, or any other
+ * Porter-Duff rule) is to use "premultiplied color components", which
+ * means the R/G/ B color components have already been multiplied by
+ * the alpha value. To make things easier for developers, the Texture
+ * class will automatically convert non-premultiplied image data into
+ * premultiplied data when storing it into an OpenGL texture. As a
+ * result, it is important to use the correct blending function; for
+ * example, the SrcOver rule is expressed as:
+<pre>
+ gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA);
+</pre>
+ * Also, when using a texture function like <code>GL_MODULATE</code> where
+ * the current color plays a role, it is important to remember to make
+ * sure that the color is specified in a premultiplied form, for
+ * example:
+<pre>
+ float a = ...;
+ float r = r * a;
+ float g = g * a;
+ float b = b * a;
+ gl.glColor4f(r, g, b, a);
+</pre>
+ *
+ * For reference, here is a list of the Porter-Duff compositing rules
+ * and the associated OpenGL blend functions (source and destination
+ * factors) to use in the face of premultiplied alpha:
+ *
+<CENTER>
+<TABLE WIDTH="75%">
+<TR> <TD> Rule <TD> Source <TD> Dest
+<TR> <TD> Clear <TD> GL_ZERO <TD> GL_ZERO
+<TR> <TD> Src <TD> GL_ONE <TD> GL_ZERO
+<TR> <TD> SrcOver <TD> GL_ONE <TD> GL_ONE_MINUS_SRC_ALPHA
+<TR> <TD> DstOver <TD> GL_ONE_MINUS_DST_ALPHA <TD> GL_ONE
+<TR> <TD> SrcIn <TD> GL_DST_ALPHA <TD> GL_ZERO
+<TR> <TD> DstIn <TD> GL_ZERO <TD> GL_SRC_ALPHA
+<TR> <TD> SrcOut <TD> GL_ONE_MINUS_DST_ALPHA <TD> GL_ZERO
+<TR> <TD> DstOut <TD> GL_ZERO <TD> GL_ONE_MINUS_SRC_ALPHA
+<TR> <TD> Dst <TD> GL_ZERO <TD> GL_ONE
+<TR> <TD> SrcAtop <TD> GL_DST_ALPHA <TD> GL_ONE_MINUS_SRC_ALPHA
+<TR> <TD> DstAtop <TD> GL_ONE_MINUS_DST_ALPHA <TD> GL_SRC_ALPHA
+<TR> <TD> AlphaXor <TD> GL_ONE_MINUS_DST_ALPHA <TD> GL_ONE_MINUS_SRC_ALPHA
+</TABLE>
+</CENTER>
+ *
+ * @author Chris Campbell
+ * @author Kenneth Russell
+ */
+public class Texture {
+ /** The GL target type. */
+ private int target;
+ /** The GL texture ID. */
+ private int texID;
+ /** The width of the texture. */
+ private int texWidth;
+ /** The height of the texture. */
+ private int texHeight;
+ /** The width of the image. */
+ private int imgWidth;
+ /** The height of the image. */
+ private int imgHeight;
+ /** The original aspect ratio of the image, before any rescaling
+ that might have occurred due to using the GLU mipmap routines. */
+ private float aspectRatio;
+ /** Indicates whether the TextureData requires a vertical flip of
+ the texture coords. */
+ private boolean mustFlipVertically;
+ /** Indicates whether we're using automatic mipmap generation
+ support (GL_GENERATE_MIPMAP). */
+ private boolean usingAutoMipmapGeneration;
+
+ /** The texture coordinates corresponding to the entire image. */
+ private TextureCoords coords;
+
+ /** An estimate of the amount of texture memory this texture consumes. */
+ private int estimatedMemorySize;
+
+ private static final AccessControlContext localACC = AccessController.getContext();
+
+ private static final boolean DEBUG = Debug.debug("Texture");
+ private static final boolean VERBOSE = Debug.verbose();
+
+ // For testing alternate code paths on more capable hardware
+ private static final boolean disableNPOT = Debug.isPropertyDefined("jogl.texture.nonpot", true, localACC);
+ private static final boolean disableTexRect = Debug.isPropertyDefined("jogl.texture.notexrect", true, localACC);
+
+ public Texture(TextureData data) throws GLException {
+ texID = 0;
+ updateImage(data);
+ }
+
+ // Constructor for use when creating e.g. cube maps, where there is
+ // no initial texture data
+ public Texture(int target) throws GLException {
+ texID = 0;
+ this.target = target;
+ }
+
+ // Package-private constructor for creating a texture object which wraps
+ // an existing texture ID from another package
+ Texture(int textureID,
+ int target,
+ int texWidth,
+ int texHeight,
+ int imgWidth,
+ int imgHeight,
+ boolean mustFlipVertically) {
+ this.texID = textureID;
+ this.target = target;
+ this.mustFlipVertically = mustFlipVertically;
+ this.texWidth = texWidth;
+ this.texHeight = texHeight;
+ setImageSize(imgWidth, imgHeight, target);
+ }
+
+ /**
+ * Enables this texture's target (e.g., GL_TEXTURE_2D) in the
+ * current GL context's state. This method is a shorthand equivalent
+ * of the following OpenGL code:
+ <pre>
+ gl.glEnable(texture.getTarget());
+ </pre>
+ *
+ * See the <a href="#perftips">performance tips</a> above for hints
+ * on how to maximize performance when using many Texture objects.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void enable() throws GLException {
+ GLContext.getCurrentGL().glEnable(target);
+ }
+
+ /**
+ * Disables this texture's target (e.g., GL_TEXTURE_2D) in the
+ * current GL context's state. This method is a shorthand equivalent
+ * of the following OpenGL code:
+ <pre>
+ gl.glDisable(texture.getTarget());
+ </pre>
+ *
+ * See the <a href="#perftips">performance tips</a> above for hints
+ * on how to maximize performance when using many Texture objects.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void disable() throws GLException {
+ GLContext.getCurrentGL().glDisable(target);
+ }
+
+ /**
+ * Binds this texture to the current GL context. This method is a
+ * shorthand equivalent of the following OpenGL code:
+ <pre>
+ gl.glBindTexture(texture.getTarget(), texture.getTextureObject());
+ </pre>
+ *
+ * See the <a href="#perftips">performance tips</a> above for hints
+ * on how to maximize performance when using many Texture objects.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void bind() throws GLException {
+ validateTexID(null, true);
+ GLContext.getCurrentGL().glBindTexture(target, texID);
+ }
+
+ /**
+ * Disposes the native resources used by this texture object.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ * @deprecated use destroy(GL)
+ */
+ public void dispose() throws GLException {
+ destroy(GLContext.getCurrentGL());
+ }
+
+ /**
+ * Disposes the native resources used by this texture object.
+ *
+ * @throws GLException if any OpenGL-related errors occurred
+ * @deprecated use destroy(GL)
+ */
+ public void dispose(GL gl) throws GLException {
+ destroy(gl);
+ }
+
+ /**
+ * Destroys the native resources used by this texture object.
+ *
+ * @throws GLException if any OpenGL-related errors occurred
+ */
+ public void destroy(GL gl) throws GLException {
+ if(0<texID) {
+ gl.glDeleteTextures(1, new int[] {texID}, 0);
+ texID = 0;
+ }
+ }
+
+ /**
+ * Returns the OpenGL "target" of this texture.
+ *
+ * @return the OpenGL target of this texture
+ * @see javax.media.opengl.GL#GL_TEXTURE_2D
+ * @see javax.media.opengl.GL2#GL_TEXTURE_RECTANGLE_ARB
+ */
+ public int getTarget() {
+ return target;
+ }
+
+ /**
+ * Returns the width of the allocated OpenGL texture in pixels.
+ * Note that the texture width will be greater than or equal to the
+ * width of the image contained within.
+ *
+ * @return the width of the texture
+ */
+ public int getWidth() {
+ return texWidth;
+ }
+
+ /**
+ * Returns the height of the allocated OpenGL texture in pixels.
+ * Note that the texture height will be greater than or equal to the
+ * height of the image contained within.
+ *
+ * @return the height of the texture
+ */
+ public int getHeight() {
+ return texHeight;
+ }
+
+ /**
+ * Returns the width of the image contained within this texture.
+ * Note that for non-power-of-two textures in particular this may
+ * not be equal to the result of {@link #getWidth}. It is
+ * recommended that applications call {@link #getImageTexCoords} and
+ * {@link #getSubImageTexCoords} rather than using this API
+ * directly.
+ *
+ * @return the width of the image
+ */
+ public int getImageWidth() {
+ return imgWidth;
+ }
+
+ /**
+ * Returns the height of the image contained within this texture.
+ * Note that for non-power-of-two textures in particular this may
+ * not be equal to the result of {@link #getHeight}. It is
+ * recommended that applications call {@link #getImageTexCoords} and
+ * {@link #getSubImageTexCoords} rather than using this API
+ * directly.
+ *
+ * @return the height of the image
+ */
+ public int getImageHeight() {
+ return imgHeight;
+ }
+
+ /**
+ * Returns the original aspect ratio of the image, defined as (image
+ * width) / (image height), before any scaling that might have
+ * occurred as a result of using the GLU mipmap routines.
+ */
+ public float getAspectRatio() {
+ return aspectRatio;
+ }
+
+ /**
+ * Returns the set of texture coordinates corresponding to the
+ * entire image. If the TextureData indicated that the texture
+ * coordinates must be flipped vertically, the returned
+ * TextureCoords will take that into account.
+ *
+ * @return the texture coordinates corresponding to the entire image
+ */
+ public TextureCoords getImageTexCoords() {
+ return coords;
+ }
+
+ /**
+ * Returns the set of texture coordinates corresponding to the
+ * specified sub-image. The (x1, y1) and (x2, y2) points are
+ * specified in terms of pixels starting from the lower-left of the
+ * image. (x1, y1) should specify the lower-left corner of the
+ * sub-image and (x2, y2) the upper-right corner of the sub-image.
+ * If the TextureData indicated that the texture coordinates must be
+ * flipped vertically, the returned TextureCoords will take that
+ * into account; this should not be handled by the end user in the
+ * specification of the y1 and y2 coordinates.
+ *
+ * @return the texture coordinates corresponding to the specified sub-image
+ */
+ public TextureCoords getSubImageTexCoords(int x1, int y1, int x2, int y2) {
+ if (target == GL2.GL_TEXTURE_RECTANGLE_ARB) {
+ if (mustFlipVertically) {
+ return new TextureCoords(x1, texHeight - y1, x2, texHeight - y2);
+ } else {
+ return new TextureCoords(x1, y1, x2, y2);
+ }
+ } else {
+ float tx1 = (float)x1 / (float)texWidth;
+ float ty1 = (float)y1 / (float)texHeight;
+ float tx2 = (float)x2 / (float)texWidth;
+ float ty2 = (float)y2 / (float)texHeight;
+ if (mustFlipVertically) {
+ float yMax = (float) imgHeight / (float) texHeight;
+ return new TextureCoords(tx1, yMax - ty1, tx2, yMax - ty2);
+ } else {
+ return new TextureCoords(tx1, ty1, tx2, ty2);
+ }
+ }
+ }
+
+ /**
+ * Updates the entire content area of this texture using the data in
+ * the given image.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void updateImage(TextureData data) throws GLException {
+ updateImage(data, 0);
+ }
+
+ /**
+ * Indicates whether this texture's texture coordinates must be
+ * flipped vertically in order to properly display the texture. This
+ * is handled automatically by {@link #getImageTexCoords
+ * getImageTexCoords} and {@link #getSubImageTexCoords
+ * getSubImageTexCoords}, but applications may generate or otherwise
+ * produce texture coordinates which must be corrected.
+ */
+ public boolean getMustFlipVertically() {
+ return mustFlipVertically;
+ }
+
+ /**
+ * Updates the content area of the specified target of this texture
+ * using the data in the given image. In general this is intended
+ * for construction of cube maps.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void updateImage(TextureData data, int target) throws GLException {
+ GL gl = GLContext.getCurrentGL();
+ validateTexID(gl, true);
+
+ imgWidth = data.getWidth();
+ imgHeight = data.getHeight();
+ aspectRatio = (float) imgWidth / (float) imgHeight;
+ mustFlipVertically = data.getMustFlipVertically();
+
+ int texTarget = 0;
+ int texParamTarget = this.target;
+
+ // See whether we have automatic mipmap generation support
+ boolean haveAutoMipmapGeneration =
+ (gl.isExtensionAvailable("GL_VERSION_1_4") ||
+ gl.isExtensionAvailable("GL_SGIS_generate_mipmap"));
+
+ // Indicate to the TextureData what functionality is available
+ data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
+ data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));
+
+ // Indicates whether both width and height are power of two
+ boolean isPOT = isPowerOfTwo(imgWidth) && isPowerOfTwo(imgHeight);
+
+ // Note that automatic mipmap generation doesn't work for
+ // GL_ARB_texture_rectangle
+ if (!isPOT && !haveNPOT(gl)) {
+ haveAutoMipmapGeneration = false;
+ }
+
+ boolean expandingCompressedTexture = false;
+ boolean done = false;
+ if (data.getMipmap() && !haveAutoMipmapGeneration) {
+ // GLU always scales the texture's dimensions to be powers of
+ // two. It also doesn't really matter exactly what the texture
+ // width and height are because the texture coords are always
+ // between 0.0 and 1.0.
+ imgWidth = nextPowerOfTwo(imgWidth);
+ imgHeight = nextPowerOfTwo(imgHeight);
+ texWidth = imgWidth;
+ texHeight = imgHeight;
+ texTarget = GL.GL_TEXTURE_2D;
+ done = true;
+ }
+
+ if (!done && preferTexRect(gl) && !isPOT &&
+ haveTexRect(gl) && !data.isDataCompressed() && !gl.isGL3() && !gl.isGLES()) {
+ // GL_ARB_texture_rectangle does not work for compressed textures
+ if (DEBUG) {
+ System.err.println("Using GL_ARB_texture_rectangle preferentially on this hardware");
+ }
+
+ texWidth = imgWidth;
+ texHeight = imgHeight;
+ texTarget = GL2.GL_TEXTURE_RECTANGLE_ARB;
+ done = true;
+ }
+
+ if (!done && (isPOT || haveNPOT(gl))) {
+ if (DEBUG) {
+ if (isPOT) {
+ System.err.println("Power-of-two texture");
+ } else {
+ System.err.println("Using GL_ARB_texture_non_power_of_two");
+ }
+ }
+
+ texWidth = imgWidth;
+ texHeight = imgHeight;
+ texTarget = GL.GL_TEXTURE_2D;
+ done = true;
+ }
+
+ if (!done && haveTexRect(gl) && !data.isDataCompressed() && !gl.isGL3() && !gl.isGLES()) {
+ // GL_ARB_texture_rectangle does not work for compressed textures
+ if (DEBUG) {
+ System.err.println("Using GL_ARB_texture_rectangle");
+ }
+
+ texWidth = imgWidth;
+ texHeight = imgHeight;
+ texTarget = GL2.GL_TEXTURE_RECTANGLE_ARB;
+ done = true;
+ }
+
+ if (!done) {
+ // If we receive non-power-of-two compressed texture data and
+ // don't have true hardware support for compressed textures, we
+ // can fake this support by producing an empty "compressed"
+ // texture image, using glCompressedTexImage2D with that to
+ // allocate the texture, and glCompressedTexSubImage2D with the
+ // incoming data.
+ if (data.isDataCompressed()) {
+ if (data.getMipmapData() != null) {
+
+ // We don't currently support expanding of compressed,
+ // mipmapped non-power-of-two textures to the nearest power
+ // of two; the obvious port of the non-mipmapped code didn't
+ // work
+ throw new GLException("Mipmapped non-power-of-two compressed textures only supported on OpenGL 2.0 hardware (GL_ARB_texture_non_power_of_two)");
+ }
+
+ expandingCompressedTexture = true;
+ }
+
+ if (DEBUG) {
+ System.err.println("Expanding texture to power-of-two dimensions");
+ }
+
+ if (data.getBorder() != 0) {
+ throw new RuntimeException("Scaling up a non-power-of-two texture which has a border won't work");
+ }
+ texWidth = nextPowerOfTwo(imgWidth);
+ texHeight = nextPowerOfTwo(imgHeight);
+ texTarget = GL.GL_TEXTURE_2D;
+ }
+
+ texParamTarget = texTarget;
+ setImageSize(imgWidth, imgHeight, texTarget);
+
+ if (target != 0) {
+ // Allow user to override auto detection and skip bind step (for
+ // cubemap construction)
+ texTarget = target;
+ if (this.target == 0) {
+ throw new GLException("Override of target failed; no target specified yet");
+ }
+ texParamTarget = this.target;
+ gl.glBindTexture(texParamTarget, texID);
+ } else {
+ gl.glBindTexture(texTarget, texID);
+ }
+
+ if (data.getMipmap() && !haveAutoMipmapGeneration) {
+ int[] align = new int[1];
+ gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, align, 0); // save alignment
+ gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, data.getAlignment());
+
+ if (data.isDataCompressed()) {
+ throw new GLException("May not request mipmap generation for compressed textures");
+ }
+
+ try {
+ // FIXME: may need check for GLUnsupportedException
+ GLU glu = GLU.createGLU(gl);
+ glu.gluBuild2DMipmaps(texTarget, data.getInternalFormat(),
+ data.getWidth(), data.getHeight(),
+ data.getPixelFormat(), data.getPixelType(), data.getBuffer());
+ } finally {
+ gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore alignment
+ }
+ } else {
+ checkCompressedTextureExtensions(data);
+ Buffer[] mipmapData = data.getMipmapData();
+ if (mipmapData != null) {
+ int width = texWidth;
+ int height = texHeight;
+ for (int i = 0; i < mipmapData.length; i++) {
+ if (data.isDataCompressed()) {
+ // Need to use glCompressedTexImage2D directly to allocate and fill this image
+ // Avoid spurious memory allocation when possible
+ gl.glCompressedTexImage2D(texTarget, i, data.getInternalFormat(),
+ width, height, data.getBorder(),
+ mipmapData[i].remaining(), mipmapData[i]);
+ } else {
+ // Allocate texture image at this level
+ gl.glTexImage2D(texTarget, i, data.getInternalFormat(),
+ width, height, data.getBorder(),
+ data.getPixelFormat(), data.getPixelType(), null);
+ updateSubImageImpl(data, texTarget, i, 0, 0, 0, 0, data.getWidth(), data.getHeight());
+ }
+
+ width = Math.max(width / 2, 1);
+ height = Math.max(height / 2, 1);
+ }
+ } else {
+ if (data.isDataCompressed()) {
+ if (!expandingCompressedTexture) {
+ // Need to use glCompressedTexImage2D directly to allocate and fill this image
+ // Avoid spurious memory allocation when possible
+ gl.glCompressedTexImage2D(texTarget, 0, data.getInternalFormat(),
+ texWidth, texHeight, data.getBorder(),
+ data.getBuffer().capacity(), data.getBuffer());
+ } else {
+ ByteBuffer buf = DDSImage.allocateBlankBuffer(texWidth,
+ texHeight,
+ data.getInternalFormat());
+ gl.glCompressedTexImage2D(texTarget, 0, data.getInternalFormat(),
+ texWidth, texHeight, data.getBorder(),
+ buf.capacity(), buf);
+ updateSubImageImpl(data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
+ }
+ } else {
+ if (data.getMipmap() && haveAutoMipmapGeneration && gl.isGL2ES1()) {
+ // For now, only use hardware mipmapping for uncompressed 2D
+ // textures where the user hasn't explicitly specified
+ // mipmap data; don't know about interactions between
+ // GL_GENERATE_MIPMAP and glCompressedTexImage2D
+ gl.glTexParameteri(texParamTarget, GL2ES1.GL_GENERATE_MIPMAP, GL.GL_TRUE);
+ usingAutoMipmapGeneration = true;
+ }
+
+ gl.glTexImage2D(texTarget, 0, data.getInternalFormat(),
+ texWidth, texHeight, data.getBorder(),
+ data.getPixelFormat(), data.getPixelType(), null);
+ updateSubImageImpl(data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
+ }
+ }
+ }
+
+ int minFilter = (data.getMipmap() ? GL.GL_LINEAR_MIPMAP_LINEAR : GL.GL_LINEAR);
+ int magFilter = GL.GL_LINEAR;
+ int wrapMode = (gl.isExtensionAvailable("GL_VERSION_1_2") || !gl.isGL2()) ? GL.GL_CLAMP_TO_EDGE : GL2.GL_CLAMP;
+
+ // REMIND: figure out what to do for GL_TEXTURE_RECTANGLE_ARB
+ if (texTarget != GL2.GL_TEXTURE_RECTANGLE_ARB) {
+ gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_MIN_FILTER, minFilter);
+ gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_MAG_FILTER, magFilter);
+ gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_WRAP_S, wrapMode);
+ gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_WRAP_T, wrapMode);
+ if (this.target == GL2.GL_TEXTURE_CUBE_MAP) {
+ gl.glTexParameteri(texParamTarget, GL2.GL_TEXTURE_WRAP_R, wrapMode);
+ }
+ }
+
+ // Don't overwrite target if we're loading e.g. faces of a cube
+ // map
+ if ((this.target == 0) ||
+ (this.target == GL.GL_TEXTURE_2D) ||
+ (this.target == GL2.GL_TEXTURE_RECTANGLE_ARB)) {
+ this.target = texTarget;
+ }
+
+ // This estimate will be wrong for cube maps
+ estimatedMemorySize = data.getEstimatedMemorySize();
+ }
+
+ /**
+ * Updates a subregion of the content area of this texture using the
+ * given data. If automatic mipmap generation is in use (see {@link
+ * #isUsingAutoMipmapGeneration isUsingAutoMipmapGeneration}),
+ * updates to the base (level 0) mipmap will cause the lower-level
+ * mipmaps to be regenerated, and updates to other mipmap levels
+ * will be ignored. Otherwise, if automatic mipmap generation is not
+ * in use, only updates the specified mipmap level and does not
+ * re-generate mipmaps if they were originally produced or loaded.
+ *
+ * @param data the image data to be uploaded to this texture
+ * @param mipmapLevel the mipmap level of the texture to set. If
+ * this is non-zero and the TextureData contains mipmap data, the
+ * appropriate mipmap level will be selected.
+ * @param x the x offset (in pixels) relative to the lower-left corner
+ * of this texture
+ * @param y the y offset (in pixels) relative to the lower-left corner
+ * of this texture
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void updateSubImage(TextureData data, int mipmapLevel, int x, int y) throws GLException {
+ if (usingAutoMipmapGeneration && mipmapLevel != 0) {
+ // When we're using mipmap generation via GL_GENERATE_MIPMAP, we
+ // don't need to update other mipmap levels
+ return;
+ }
+ bind();
+ updateSubImageImpl(data, target, mipmapLevel, x, y, 0, 0, data.getWidth(), data.getHeight());
+ }
+
+ /**
+ * Updates a subregion of the content area of this texture using the
+ * specified sub-region of the given data. If automatic mipmap
+ * generation is in use (see {@link #isUsingAutoMipmapGeneration
+ * isUsingAutoMipmapGeneration}), updates to the base (level 0)
+ * mipmap will cause the lower-level mipmaps to be regenerated, and
+ * updates to other mipmap levels will be ignored. Otherwise, if
+ * automatic mipmap generation is not in use, only updates the
+ * specified mipmap level and does not re-generate mipmaps if they
+ * were originally produced or loaded. This method is only supported
+ * for uncompressed TextureData sources.
+ *
+ * @param data the image data to be uploaded to this texture
+ * @param mipmapLevel the mipmap level of the texture to set. If
+ * this is non-zero and the TextureData contains mipmap data, the
+ * appropriate mipmap level will be selected.
+ * @param dstx the x offset (in pixels) relative to the lower-left corner
+ * of this texture where the update will be applied
+ * @param dsty the y offset (in pixels) relative to the lower-left corner
+ * of this texture where the update will be applied
+ * @param srcx the x offset (in pixels) relative to the lower-left corner
+ * of the supplied TextureData from which to fetch the update rectangle
+ * @param srcy the y offset (in pixels) relative to the lower-left corner
+ * of the supplied TextureData from which to fetch the update rectangle
+ * @param width the width (in pixels) of the rectangle to be updated
+ * @param height the height (in pixels) of the rectangle to be updated
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void updateSubImage(TextureData data, int mipmapLevel,
+ int dstx, int dsty,
+ int srcx, int srcy,
+ int width, int height) throws GLException {
+ if (data.isDataCompressed()) {
+ throw new GLException("updateSubImage specifying a sub-rectangle is not supported for compressed TextureData");
+ }
+ if (usingAutoMipmapGeneration && mipmapLevel != 0) {
+ // When we're using mipmap generation via GL_GENERATE_MIPMAP, we
+ // don't need to update other mipmap levels
+ return;
+ }
+ bind();
+ updateSubImageImpl(data, target, mipmapLevel, dstx, dsty, srcx, srcy, width, height);
+ }
+
+ /**
+ * Sets the OpenGL floating-point texture parameter for the
+ * texture's target. This gives control over parameters such as
+ * GL_TEXTURE_MAX_ANISOTROPY_EXT. Causes this texture to be bound to
+ * the current texture state.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void setTexParameterf(int parameterName,
+ float value) {
+ bind();
+ GL gl = GLContext.getCurrentGL();
+ gl.glTexParameterf(target, parameterName, value);
+ }
+
+ /**
+ * Sets the OpenGL multi-floating-point texture parameter for the
+ * texture's target. Causes this texture to be bound to the current
+ * texture state.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void setTexParameterfv(int parameterName,
+ FloatBuffer params) {
+ bind();
+ GL gl = GLContext.getCurrentGL();
+ gl.glTexParameterfv(target, parameterName, params);
+ }
+
+ /**
+ * Sets the OpenGL multi-floating-point texture parameter for the
+ * texture's target. Causes this texture to be bound to the current
+ * texture state.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void setTexParameterfv(int parameterName,
+ float[] params, int params_offset) {
+ bind();
+ GL gl = GLContext.getCurrentGL();
+ gl.glTexParameterfv(target, parameterName, params, params_offset);
+ }
+
+ /**
+ * Sets the OpenGL integer texture parameter for the texture's
+ * target. This gives control over parameters such as
+ * GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T, which by default are set
+ * to GL_CLAMP_TO_EDGE if OpenGL 1.2 is supported on the current
+ * platform and GL_CLAMP if not. Causes this texture to be bound to
+ * the current texture state.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void setTexParameteri(int parameterName,
+ int value) {
+ bind();
+ GL gl = GLContext.getCurrentGL();
+ gl.glTexParameteri(target, parameterName, value);
+ }
+
+ /**
+ * Sets the OpenGL multi-integer texture parameter for the texture's
+ * target. Causes this texture to be bound to the current texture
+ * state.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void setTexParameteriv(int parameterName,
+ IntBuffer params) {
+ bind();
+ GL gl = GLContext.getCurrentGL();
+ gl.glTexParameteriv(target, parameterName, params);
+ }
+
+ /**
+ * Sets the OpenGL multi-integer texture parameter for the texture's
+ * target. Causes this texture to be bound to the current texture
+ * state.
+ *
+ * @throws GLException if no OpenGL context was current or if any
+ * OpenGL-related errors occurred
+ */
+ public void setTexParameteriv(int parameterName,
+ int[] params, int params_offset) {
+ bind();
+ GL gl = GLContext.getCurrentGL();
+ gl.glTexParameteriv(target, parameterName, params, params_offset);
+ }
+
+ /**
+ * Returns the underlying OpenGL texture object for this texture.
+ * Most applications will not need to access this, since it is
+ * handled automatically by the bind() and dispose() APIs.
+ */
+ public int getTextureObject() {
+ validateTexID(null, false);
+ return texID;
+ }
+
+ /** Returns an estimate of the amount of texture memory in bytes
+ this Texture consumes. It should only be treated as an estimate;
+ most applications should not need to query this but instead let
+ the OpenGL implementation page textures in and out as
+ necessary. */
+ public int getEstimatedMemorySize() {
+ return estimatedMemorySize;
+ }
+
+ /** Indicates whether this Texture is using automatic mipmap
+ generation (via the OpenGL texture parameter
+ GL_GENERATE_MIPMAP). This will automatically be used when
+ mipmapping is requested via the TextureData and either OpenGL
+ 1.4 or the GL_SGIS_generate_mipmap extension is available. If
+ so, updates to the base image (mipmap level 0) will
+ automatically propagate down to the lower mipmap levels. Manual
+ updates of the mipmap data at these lower levels will be
+ ignored. */
+ public boolean isUsingAutoMipmapGeneration() {
+ return usingAutoMipmapGeneration;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ /**
+ * Returns true if the given value is a power of two.
+ *
+ * @return true if the given value is a power of two, false otherwise
+ */
+ private static boolean isPowerOfTwo(int val) {
+ return ((val & (val - 1)) == 0);
+ }
+
+ /**
+ * Returns the nearest power of two that is larger than the given value.
+ * If the given value is already a power of two, this method will simply
+ * return that value.
+ *
+ * @param val the value
+ * @return the next power of two
+ */
+ private static int nextPowerOfTwo(int val) {
+ int ret = 1;
+ while (ret < val) {
+ ret <<= 1;
+ }
+ return ret;
+ }
+
+ /**
+ * Updates the actual image dimensions; usually only called from
+ * <code>updateImage</code>.
+ */
+ private void setImageSize(int width, int height, int target) {
+ imgWidth = width;
+ imgHeight = height;
+ if (target == GL2.GL_TEXTURE_RECTANGLE_ARB) {
+ if (mustFlipVertically) {
+ coords = new TextureCoords(0, imgHeight, imgWidth, 0);
+ } else {
+ coords = new TextureCoords(0, 0, imgWidth, imgHeight);
+ }
+ } else {
+ if (mustFlipVertically) {
+ coords = new TextureCoords(0, (float) imgHeight / (float) texHeight,
+ (float) imgWidth / (float) texWidth, 0);
+ } else {
+ coords = new TextureCoords(0, 0,
+ (float) imgWidth / (float) texWidth,
+ (float) imgHeight / (float) texHeight);
+ }
+ }
+ }
+
+ private void updateSubImageImpl(TextureData data, int newTarget, int mipmapLevel,
+ int dstx, int dsty,
+ int srcx, int srcy, int width, int height) throws GLException {
+ GL gl = GLContext.getCurrentGL();
+ data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
+ data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));
+
+ Buffer buffer = data.getBuffer();
+ if (buffer == null && data.getMipmapData() == null) {
+ // Assume user just wanted to get the Texture object allocated
+ return;
+ }
+
+ int rowlen = data.getRowLength();
+ int dataWidth = data.getWidth();
+ int dataHeight = data.getHeight();
+ if (data.getMipmapData() != null) {
+ // Compute the width, height and row length at the specified mipmap level
+ // Note we do not support specification of the row length for
+ // mipmapped textures at this point
+ for (int i = 0; i < mipmapLevel; i++) {
+ width = Math.max(width / 2, 1);
+ height = Math.max(height / 2, 1);
+
+ dataWidth = Math.max(dataWidth / 2, 1);
+ dataHeight = Math.max(dataHeight / 2, 1);
+ }
+ rowlen = 0;
+ buffer = data.getMipmapData()[mipmapLevel];
+ }
+
+ // Clip incoming rectangles to what is available both on this
+ // texture and in the incoming TextureData
+ if (srcx < 0) {
+ width += srcx;
+ srcx = 0;
+ }
+ if (srcy < 0) {
+ height += srcy;
+ srcy = 0;
+ }
+ // NOTE: not sure whether the following two are the correct thing to do
+ if (dstx < 0) {
+ width += dstx;
+ dstx = 0;
+ }
+ if (dsty < 0) {
+ height += dsty;
+ dsty = 0;
+ }
+
+ if (srcx + width > dataWidth) {
+ width = dataWidth - srcx;
+ }
+ if (srcy + height > dataHeight) {
+ height = dataHeight - srcy;
+ }
+ if (dstx + width > texWidth) {
+ width = texWidth - dstx;
+ }
+ if (dsty + height > texHeight) {
+ height = texHeight - dsty;
+ }
+
+ checkCompressedTextureExtensions(data);
+
+ if (data.isDataCompressed()) {
+ gl.glCompressedTexSubImage2D(newTarget, mipmapLevel,
+ dstx, dsty, width, height,
+ data.getInternalFormat(),
+ buffer.remaining(), buffer);
+ } else {
+ int[] align = { 0 };
+ int[] rowLength = { 0 };
+ int[] skipRows = { 0 };
+ int[] skipPixels = { 0 };
+ gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, align, 0); // save alignment
+ if(gl.isGL2GL3()) {
+ gl.glGetIntegerv(GL2GL3.GL_UNPACK_ROW_LENGTH, rowLength, 0); // save row length
+ gl.glGetIntegerv(GL2GL3.GL_UNPACK_SKIP_ROWS, skipRows, 0); // save skipped rows
+ gl.glGetIntegerv(GL2GL3.GL_UNPACK_SKIP_PIXELS, skipPixels, 0); // save skipped pixels
+ }
+ gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, data.getAlignment());
+ if (DEBUG && VERBOSE) {
+ System.out.println("Row length = " + rowlen);
+ System.out.println("skip pixels = " + srcx);
+ System.out.println("skip rows = " + srcy);
+ System.out.println("dstx = " + dstx);
+ System.out.println("dsty = " + dsty);
+ System.out.println("width = " + width);
+ System.out.println("height = " + height);
+ }
+ if(gl.isGL2GL3()) {
+ gl.glPixelStorei(GL2GL3.GL_UNPACK_ROW_LENGTH, rowlen);
+ gl.glPixelStorei(GL2GL3.GL_UNPACK_SKIP_ROWS, srcy);
+ gl.glPixelStorei(GL2GL3.GL_UNPACK_SKIP_PIXELS, srcx);
+ } else {
+ if ( rowlen!=0 && rowlen!=width &&
+ srcy!=0 && srcx!=0 ) {
+ throw new GLException("rowlen and/or x/y offset only available for GL2");
+ }
+ }
+
+ gl.glTexSubImage2D(newTarget, mipmapLevel,
+ dstx, dsty, width, height,
+ data.getPixelFormat(), data.getPixelType(),
+ buffer);
+ gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore alignment
+ if(gl.isGL2GL3()) {
+ gl.glPixelStorei(GL2GL3.GL_UNPACK_ROW_LENGTH, rowLength[0]); // restore row length
+ gl.glPixelStorei(GL2GL3.GL_UNPACK_SKIP_ROWS, skipRows[0]); // restore skipped rows
+ gl.glPixelStorei(GL2GL3.GL_UNPACK_SKIP_PIXELS, skipPixels[0]); // restore skipped pixels
+ }
+ }
+ }
+
+ private void checkCompressedTextureExtensions(TextureData data) {
+ GL gl = GLContext.getCurrentGL();
+ if (data.isDataCompressed()) {
+ switch (data.getInternalFormat()) {
+ case GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ if (!gl.isExtensionAvailable("GL_EXT_texture_compression_s3tc") &&
+ !gl.isExtensionAvailable("GL_NV_texture_compression_vtc")) {
+ throw new GLException("DXTn compressed textures not supported by this graphics card");
+ }
+ break;
+ default:
+ // FI1027GXME: should test availability of more texture
+ // compression extensions here
+ break;
+ }
+ }
+ }
+
+ private void validateTexID(GL gl, boolean throwException) {
+ if( 0 < texID ) return;
+ if(null==gl) {
+ GLContext ctx = GLContext.getCurrent();
+ if(null!=ctx) {
+ gl = ctx.getGL();
+ } else if(throwException) {
+ throw new GLException("No context current, can't create texture ID");
+ }
+ }
+
+ if(null!=gl) {
+ int[] tmp = new int[1];
+ gl.glGenTextures(1, tmp, 0);
+ texID = tmp[0];
+ }
+ }
+
+ // Helper routines for disabling certain codepaths
+ private static boolean haveNPOT(GL gl) {
+ return (!disableNPOT &&
+ ( gl.isGLES2() ||
+ gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two") ) );
+ }
+
+ private static boolean haveTexRect(GL gl) {
+ return (!disableTexRect &&
+ TextureIO.isTexRectEnabled() &&
+ gl.isExtensionAvailable("GL_ARB_texture_rectangle"));
+ }
+
+ private static boolean preferTexRect(GL gl) {
+ // Prefer GL_ARB_texture_rectangle on ATI hardware on Mac OS X
+ // due to software fallbacks
+
+ if (NativeWindowFactory.TYPE_MACOSX.equals(NativeWindowFactory.getNativeWindowType(false))) {
+ String vendor = gl.glGetString(GL.GL_VENDOR);
+ if (vendor != null && vendor.startsWith("ATI")) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureCoords.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureCoords.java
new file mode 100755
index 000000000..8d8b3679d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureCoords.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.util.texture;
+
+/** Specifies texture coordinates for a rectangular area of a
+ texture. Note that some textures are inherently flipped vertically
+ from OpenGL's standard coordinate system. This class takes care of
+ this vertical flip so that the "bottom" and "top" coordinates may
+ sometimes be reversed. From the point of view of code rendering
+ textured polygons, it can always map the bottom and left texture
+ coordinates from the TextureCoords to the lower left point of the
+ textured polygon and achieve correct results. */
+
+public class TextureCoords {
+ // These represent the lower-left point
+ private float left;
+ private float bottom;
+ // These represent the upper-right point
+ private float right;
+ private float top;
+
+ public TextureCoords(float left, float bottom,
+ float right, float top) {
+ this.left = left;
+ this.bottom = bottom;
+ this.right = right;
+ this.top = top;
+ }
+
+ /** Returns the leftmost (x) texture coordinate of this
+ rectangle. */
+ public float left() { return left; }
+
+ /** Returns the rightmost (x) texture coordinate of this
+ rectangle. */
+ public float right() { return right; }
+
+ /** Returns the bottommost (y) texture coordinate of this
+ rectangle. */
+ public float bottom() { return bottom; }
+
+ /** Returns the topmost (y) texture coordinate of this
+ rectangle. */
+ public float top() { return top; }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
new file mode 100755
index 000000000..f598422bf
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.util.texture;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.*;
+
+/**
+ * Represents the data for an OpenGL texture. This is separated from
+ * the notion of a Texture to support things like streaming in of
+ * textures in a background thread without requiring an OpenGL context
+ * to be current on that thread.
+ *
+ * @author Chris Campbell
+ * @author Kenneth Russell
+ * @author Sven Gothel
+ */
+
+public class TextureData {
+ protected int width;
+ protected int height;
+ private int border;
+ protected int pixelFormat;
+ protected int pixelType;
+ protected int internalFormat; // perhaps inferred from pixelFormat?
+ protected boolean mipmap; // indicates whether mipmaps should be generated
+ // (ignored if mipmaps are supplied from the file)
+ private boolean dataIsCompressed;
+ protected boolean mustFlipVertically; // Must flip texture coordinates
+ // vertically to get OpenGL output
+ // to look correct
+ protected Buffer buffer; // the actual data...
+ private Buffer[] mipmapData; // ...or a series of mipmaps
+ private Flusher flusher;
+ protected int rowLength;
+ protected int alignment; // 1, 2, or 4 bytes
+ protected int estimatedMemorySize;
+
+ // These booleans are a concession to the AWTTextureData subclass
+ protected boolean haveEXTABGR;
+ protected boolean haveGL12;
+ protected GLProfile glProfile;
+
+ /**
+ * Constructs a new TextureData object with the specified parameters
+ * and data contained in the given Buffer. The optional Flusher can
+ * be used to clean up native resources associated with this
+ * TextureData when processing is complete; for example, closing of
+ * memory-mapped files that might otherwise require a garbage
+ * collection to reclaim and close.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param internalFormat the OpenGL internal format for the
+ * resulting texture; must be specified, may
+ * not be 0
+ * @param width the width in pixels of the texture
+ * @param height the height in pixels of the texture
+ * @param border the number of pixels of border this texture
+ * data has (0 or 1)
+ * @param pixelFormat the OpenGL pixel format for the
+ * resulting texture; must be specified, may
+ * not be 0
+ * @param pixelType the OpenGL type of the pixels of the texture
+ * @param mipmap indicates whether mipmaps should be
+ * autogenerated (using GLU) for the resulting
+ * texture. Currently if mipmap is true then
+ * dataIsCompressed may not be true.
+ * @param dataIsCompressed indicates whether the texture data is in
+ * compressed form
+ * (e.g. GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
+ * @param mustFlipVertically indicates whether the texture
+ * coordinates must be flipped vertically
+ * in order to properly display the
+ * texture
+ * @param buffer the buffer containing the texture data
+ * @param flusher optional flusher to perform cleanup tasks
+ * upon call to flush()
+ *
+ * @throws IllegalArgumentException if any parameters of the texture
+ * data were invalid, such as requesting mipmap generation for a
+ * compressed texture
+ */
+ public TextureData(GLProfile glp,
+ int internalFormat,
+ int width,
+ int height,
+ int border,
+ int pixelFormat,
+ int pixelType,
+ boolean mipmap,
+ boolean dataIsCompressed,
+ boolean mustFlipVertically,
+ Buffer buffer,
+ Flusher flusher) throws IllegalArgumentException {
+ if (mipmap && dataIsCompressed) {
+ throw new IllegalArgumentException("Can not generate mipmaps for compressed textures");
+ }
+
+ this.glProfile = glp;
+ this.width = width;
+ this.height = height;
+ this.border = border;
+ this.pixelFormat = pixelFormat;
+ this.pixelType = pixelType;
+ this.internalFormat = internalFormat;
+ this.mipmap = mipmap;
+ this.dataIsCompressed = dataIsCompressed;
+ this.mustFlipVertically = mustFlipVertically;
+ this.buffer = buffer;
+ this.flusher = flusher;
+ alignment = 1; // FIXME: is this correct enough in all situations?
+ estimatedMemorySize = estimatedMemorySize(buffer);
+ }
+
+ /**
+ * Constructs a new TextureData object with the specified parameters
+ * and data for multiple mipmap levels contained in the given array
+ * of Buffers. The optional Flusher can be used to clean up native
+ * resources associated with this TextureData when processing is
+ * complete; for example, closing of memory-mapped files that might
+ * otherwise require a garbage collection to reclaim and close.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param internalFormat the OpenGL internal format for the
+ * resulting texture; must be specified, may
+ * not be 0
+ * @param width the width in pixels of the topmost mipmap
+ * level of the texture
+ * @param height the height in pixels of the topmost mipmap
+ * level of the texture
+ * @param border the number of pixels of border this texture
+ * data has (0 or 1)
+ * @param pixelFormat the OpenGL pixel format for the
+ * resulting texture; must be specified, may
+ * not be 0
+ * @param pixelType the OpenGL type of the pixels of the texture
+ * @param dataIsCompressed indicates whether the texture data is in
+ * compressed form
+ * (e.g. GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
+ * @param mustFlipVertically indicates whether the texture
+ * coordinates must be flipped vertically
+ * in order to properly display the
+ * texture
+ * @param mipmapData the buffers containing all mipmap levels
+ * of the texture's data
+ * @param flusher optional flusher to perform cleanup tasks
+ * upon call to flush()
+ *
+ * @throws IllegalArgumentException if any parameters of the texture
+ * data were invalid, such as requesting mipmap generation for a
+ * compressed texture
+ */
+ public TextureData(GLProfile glp,
+ int internalFormat,
+ int width,
+ int height,
+ int border,
+ int pixelFormat,
+ int pixelType,
+ boolean dataIsCompressed,
+ boolean mustFlipVertically,
+ Buffer[] mipmapData,
+ Flusher flusher) throws IllegalArgumentException {
+ this.glProfile = glp;
+ this.width = width;
+ this.height = height;
+ this.border = border;
+ this.pixelFormat = pixelFormat;
+ this.pixelType = pixelType;
+ this.internalFormat = internalFormat;
+ this.dataIsCompressed = dataIsCompressed;
+ this.mustFlipVertically = mustFlipVertically;
+ this.mipmapData = (Buffer[]) mipmapData.clone();
+ this.flusher = flusher;
+ alignment = 1; // FIXME: is this correct enough in all situations?
+ for (int i = 0; i < mipmapData.length; i++) {
+ estimatedMemorySize += estimatedMemorySize(mipmapData[i]);
+ }
+ }
+
+ /** Used only by subclasses */
+ protected TextureData(GLProfile glp) { this.glProfile = glp; }
+
+ /** Returns the width in pixels of the texture data. */
+ public int getWidth() { return width; }
+ /** Returns the height in pixels of the texture data. */
+ public int getHeight() { return height; }
+ /** Returns the border in pixels of the texture data. */
+ public int getBorder() {
+ return border;
+ }
+ /** Returns the intended OpenGL pixel format of the texture data. */
+ public int getPixelFormat() {
+ return pixelFormat;
+ }
+ /** Returns the intended OpenGL pixel type of the texture data. */
+ public int getPixelType() {
+ return pixelType;
+ }
+ /** Returns the intended OpenGL internal format of the texture data. */
+ public int getInternalFormat() {
+ return internalFormat;
+ }
+ /** Returns whether mipmaps should be generated for the texture data. */
+ public boolean getMipmap() {
+ return mipmap;
+ }
+ /** Indicates whether the texture data is in compressed form. */
+ public boolean isDataCompressed() {
+ return dataIsCompressed;
+ }
+ /** Indicates whether the texture coordinates must be flipped
+ vertically for proper display. */
+ public boolean getMustFlipVertically() {
+ return mustFlipVertically;
+ }
+ /** Returns the texture data, or null if it is specified as a set of mipmaps. */
+ public Buffer getBuffer() {
+ return buffer;
+ }
+ /** Returns all mipmap levels for the texture data, or null if it is
+ specified as a single image. */
+ public Buffer[] getMipmapData() {
+ return mipmapData;
+ }
+ /** Returns the required byte alignment for the texture data. */
+ public int getAlignment() {
+ return alignment;
+ }
+ /** Returns the row length needed for correct GL_UNPACK_ROW_LENGTH
+ specification. This is currently only supported for
+ non-mipmapped, non-compressed textures. */
+ public int getRowLength() {
+ return rowLength;
+ }
+
+ /** Sets the width in pixels of the texture data. */
+ public void setWidth(int width) { this.width = width; }
+ /** Sets the height in pixels of the texture data. */
+ public void setHeight(int height) { this.height = height; }
+ /** Sets the border in pixels of the texture data. */
+ public void setBorder(int border) { this.border = border; }
+ /** Sets the intended OpenGL pixel format of the texture data. */
+ public void setPixelFormat(int pixelFormat) { this.pixelFormat = pixelFormat; }
+ /** Sets the intended OpenGL pixel type of the texture data. */
+ public void setPixelType(int pixelType) { this.pixelType = pixelType; }
+ /** Sets the intended OpenGL internal format of the texture data. */
+ public void setInternalFormat(int internalFormat) { this.internalFormat = internalFormat; }
+ /** Sets whether mipmaps should be generated for the texture data. */
+ public void setMipmap(boolean mipmap) { this.mipmap = mipmap; }
+ /** Sets whether the texture data is in compressed form. */
+ public void setIsDataCompressed(boolean compressed) { this.dataIsCompressed = compressed; }
+ /** Sets whether the texture coordinates must be flipped vertically
+ for proper display. */
+ public void setMustFlipVertically(boolean mustFlipVertically) { this.mustFlipVertically = mustFlipVertically; }
+ /** Sets the texture data. */
+ public void setBuffer(Buffer buffer) {
+ this.buffer = buffer;
+ estimatedMemorySize = estimatedMemorySize(buffer);
+ }
+ /** Sets the required byte alignment for the texture data. */
+ public void setAlignment(int alignment) { this.alignment = alignment; }
+ /** Sets the row length needed for correct GL_UNPACK_ROW_LENGTH
+ specification. This is currently only supported for
+ non-mipmapped, non-compressed textures. */
+ public void setRowLength(int rowLength) { this.rowLength = rowLength; }
+ /** Indicates to this TextureData whether the GL_EXT_abgr extension
+ is available. Used for optimization along some code paths to
+ avoid data copies. */
+ public void setHaveEXTABGR(boolean haveEXTABGR) {
+ this.haveEXTABGR = haveEXTABGR;
+ }
+ /** Indicates to this TextureData whether OpenGL version 1.2 is
+ available. If not, falls back to relatively inefficient code
+ paths for several input data types (several kinds of packed
+ pixel formats, in particular). */
+ public void setHaveGL12(boolean haveGL12) {
+ this.haveGL12 = haveGL12;
+ }
+
+ /** Returns the GLProfile this texture data is intended and created for. */
+ public GLProfile getGLProfile() { return glProfile; }
+
+ /** Returns an estimate of the amount of memory in bytes this
+ TextureData will consume once uploaded to the graphics card. It
+ should only be treated as an estimate; most applications should
+ not need to query this but instead let the OpenGL implementation
+ page textures in and out as necessary. */
+ public int getEstimatedMemorySize() {
+ return estimatedMemorySize;
+ }
+
+ /** Flushes resources associated with this TextureData by calling
+ Flusher.flush(). */
+ public void flush() {
+ if (flusher != null) {
+ flusher.flush();
+ flusher = null;
+ }
+ }
+
+ /** Calls flush()
+ * @see #flush()
+ */
+ public void destroy() {
+ flush();
+ }
+
+ /** Defines a callback mechanism to allow the user to explicitly
+ deallocate native resources (memory-mapped files, etc.)
+ associated with a particular TextureData. */
+ public static interface Flusher {
+ /** Flushes any native resources associated with this
+ TextureData. */
+ public void flush();
+ }
+
+ public String toString() {
+ return "TextureData["+width+"x"+height+", internFormat "+internalFormat+", pixelFormat "+pixelFormat+", pixelType "+pixelType+", border "+border+", estSize "+estimatedMemorySize+", alignment "+alignment+", rowlen "+rowLength;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ protected static int estimatedMemorySize(Buffer buffer) {
+ if (buffer == null) {
+ return 0;
+ }
+ return buffer.capacity() * GLBuffers.sizeOfBufferElem(buffer);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javame_cdc_fp b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javame_cdc_fp
new file mode 100755
index 000000000..dbd194d21
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javame_cdc_fp
@@ -0,0 +1,1256 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture;
+
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+import java.util.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import com.jogamp.opengl.impl.Debug;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.texture.spi.*;
+
+/** <P> Provides input and output facilities for both loading OpenGL
+ textures from disk and streams as well as writing textures already
+ in memory back to disk. </P>
+
+ <P> The TextureIO class supports an arbitrary number of plug-in
+ readers and writers via TextureProviders and TextureWriters.
+ TextureProviders know how to produce TextureData objects from
+ files, InputStreams and URLs. TextureWriters know how to write
+ TextureData objects to disk in various file formats. The
+ TextureData class represents the raw data of the texture before it
+ has been converted to an OpenGL texture object. The Texture class
+ represents the OpenGL texture object and provides easy facilities
+ for using the texture. </P>
+
+ <P> There are several built-in TextureProviders and TextureWriters
+ supplied with the TextureIO implementation. The most basic
+ provider uses the platform's Image I/O facilities to read in a
+ BufferedImage and convert it to a texture. This is the baseline
+ provider and is registered so that it is the last one consulted.
+ All others are asked first to open a given file. </P>
+
+ <P> There are three other providers registered by default as of
+ the time of this writing. One handles SGI RGB (".sgi", ".rgb")
+ images from both files and streams. One handles DirectDraw Surface
+ (".dds") images read from files, though can not read these images
+ from streams. One handles Targa (".tga") images read from both
+ files and streams. These providers are executed in an arbitrary
+ order. Some of these providers require the file's suffix to either
+ be specified via the newTextureData methods or for the file to be
+ named with the appropriate suffix. In general a file suffix should
+ be provided to the newTexture and newTextureData methods if at all
+ possible. </P>
+
+ <P> Note that additional TextureProviders, if reading images from
+ InputStreams, must use the mark()/reset() methods on InputStream
+ when probing for e.g. magic numbers at the head of the file to
+ make sure not to disturb the state of the InputStream for
+ downstream TextureProviders. </P>
+
+ <P> There are analogous TextureWriters provided for writing
+ textures back to disk if desired. As of this writing, there are
+ four TextureWriters registered by default: one for Targa files,
+ one for SGI RGB files, one for DirectDraw surface (.dds) files,
+ and one for ImageIO-supplied formats such as .jpg and .png. Some
+ of these writers have certain limitations such as only being able
+ to write out textures stored in GL_RGB or GL_RGBA format. The DDS
+ writer supports fetching and writing to disk of texture data in
+ DXTn compressed format. Whether this will occur is dependent on
+ whether the texture's internal format is one of the DXTn
+ compressed formats and whether the target file is .dds format.
+*/
+
+public class TextureIO {
+ /** Constant which can be used as a file suffix to indicate a
+ DirectDraw Surface file. */
+ public static final String DDS = "dds";
+
+ /** Constant which can be used as a file suffix to indicate an SGI
+ RGB file. */
+ public static final String SGI = "sgi";
+
+ /** Constant which can be used as a file suffix to indicate an SGI
+ RGB file. */
+ public static final String SGI_RGB = "rgb";
+
+ /** Constant which can be used as a file suffix to indicate a GIF
+ file. */
+ public static final String GIF = "gif";
+
+ /** Constant which can be used as a file suffix to indicate a JPEG
+ file. */
+ public static final String JPG = "jpg";
+
+ /** Constant which can be used as a file suffix to indicate a PNG
+ file. */
+ public static final String PNG = "png";
+
+ /** Constant which can be used as a file suffix to indicate a Targa
+ file. */
+ public static final String TGA = "tga";
+
+ /** Constant which can be used as a file suffix to indicate a TIFF
+ file. */
+ public static final String TIFF = "tiff";
+
+ private static final boolean DEBUG = Debug.debug("TextureIO");
+
+ // For manually disabling the use of the texture rectangle
+ // extensions so you know the texture target is GL_TEXTURE_2D; this
+ // is useful for shader writers (thanks to Chris Campbell for this
+ // observation)
+ private static boolean texRectEnabled = true;
+
+ //----------------------------------------------------------------------
+ // methods that *do not* require a current context
+ // These methods assume RGB or RGBA textures.
+ // Some texture providers may not recognize the file format unless
+ // the fileSuffix is specified, so it is strongly recommended to
+ // specify it wherever it is known.
+ // Some texture providers may also only support one kind of input,
+ // i.e., reading from a file as opposed to a stream.
+
+ /**
+ * Creates a TextureData from the given file. Does no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param file the file from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the file, or null if none of the
+ * registered texture providers could read the file
+ * @throws IOException if an error occurred while reading the file
+ */
+ public static TextureData newTextureData(GLProfile glp, File file,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (fileSuffix == null) {
+ fileSuffix = FileUtil.getFileSuffix(file);
+ }
+ return newTextureDataImpl(glp, file, 0, 0, mipmap, fileSuffix);
+ }
+
+ /**
+ * Creates a TextureData from the given stream. Does no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param stream the stream from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the stream, or null if none of the
+ * registered texture providers could read the stream
+ * @throws IOException if an error occurred while reading the stream
+ */
+ public static TextureData newTextureData(GLProfile glp, InputStream stream,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ return newTextureDataImpl(glp, stream, 0, 0, mipmap, fileSuffix);
+ }
+
+ /**
+ * Creates a TextureData from the given URL. Does no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param url the URL from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the URL, or null if none of the
+ * registered texture providers could read the URL
+ * @throws IOException if an error occurred while reading the URL
+ */
+ public static TextureData newTextureData(GLProfile glp, URL url,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (fileSuffix == null) {
+ fileSuffix = FileUtil.getFileSuffix(url.getPath());
+ }
+ return newTextureDataImpl(glp, url, 0, 0, mipmap, fileSuffix);
+ }
+
+ //----------------------------------------------------------------------
+ // These methods make no assumption about the OpenGL internal format
+ // or pixel format of the texture; they must be specified by the
+ // user. It is not allowed to supply 0 (indicating no preference)
+ // for either the internalFormat or the pixelFormat;
+ // IllegalArgumentException will be thrown in this case.
+
+ /**
+ * Creates a TextureData from the given file, using the specified
+ * OpenGL internal format and pixel format for the texture which
+ * will eventually result. The internalFormat and pixelFormat must
+ * be specified and may not be zero; to use default values, use the
+ * variant of this method which does not take these arguments. Does
+ * no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param file the file from which to read the texture data
+ * @param internalFormat the OpenGL internal format of the texture
+ * which will eventually result from the TextureData
+ * @param pixelFormat the OpenGL pixel format of the texture
+ * which will eventually result from the TextureData
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the file, or null if none of the
+ * registered texture providers could read the file
+ * @throws IllegalArgumentException if either internalFormat or
+ * pixelFormat was 0
+ * @throws IOException if an error occurred while reading the file
+ */
+ public static TextureData newTextureData(GLProfile glp, File file,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException, IllegalArgumentException {
+ if ((internalFormat == 0) || (pixelFormat == 0)) {
+ throw new IllegalArgumentException("internalFormat and pixelFormat must be non-zero");
+ }
+
+ if (fileSuffix == null) {
+ fileSuffix = FileUtil.getFileSuffix(file);
+ }
+
+ return newTextureDataImpl(glp, file, internalFormat, pixelFormat, mipmap, fileSuffix);
+ }
+
+ /**
+ * Creates a TextureData from the given stream, using the specified
+ * OpenGL internal format and pixel format for the texture which
+ * will eventually result. The internalFormat and pixelFormat must
+ * be specified and may not be zero; to use default values, use the
+ * variant of this method which does not take these arguments. Does
+ * no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param stream the stream from which to read the texture data
+ * @param internalFormat the OpenGL internal format of the texture
+ * which will eventually result from the TextureData
+ * @param pixelFormat the OpenGL pixel format of the texture
+ * which will eventually result from the TextureData
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the stream, or null if none of the
+ * registered texture providers could read the stream
+ * @throws IllegalArgumentException if either internalFormat or
+ * pixelFormat was 0
+ * @throws IOException if an error occurred while reading the stream
+ */
+ public static TextureData newTextureData(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException, IllegalArgumentException {
+ if ((internalFormat == 0) || (pixelFormat == 0)) {
+ throw new IllegalArgumentException("internalFormat and pixelFormat must be non-zero");
+ }
+
+ return newTextureDataImpl(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
+ }
+
+ /**
+ * Creates a TextureData from the given URL, using the specified
+ * OpenGL internal format and pixel format for the texture which
+ * will eventually result. The internalFormat and pixelFormat must
+ * be specified and may not be zero; to use default values, use the
+ * variant of this method which does not take these arguments. Does
+ * no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param url the URL from which to read the texture data
+ * @param internalFormat the OpenGL internal format of the texture
+ * which will eventually result from the TextureData
+ * @param pixelFormat the OpenGL pixel format of the texture
+ * which will eventually result from the TextureData
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the URL, or null if none of the
+ * registered texture providers could read the URL
+ * @throws IllegalArgumentException if either internalFormat or
+ * pixelFormat was 0
+ * @throws IOException if an error occurred while reading the URL
+ */
+ public static TextureData newTextureData(GLProfile glp, URL url,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException, IllegalArgumentException {
+ if ((internalFormat == 0) || (pixelFormat == 0)) {
+ throw new IllegalArgumentException("internalFormat and pixelFormat must be non-zero");
+ }
+
+ if (fileSuffix == null) {
+ fileSuffix = FileUtil.getFileSuffix(url.getPath());
+ }
+
+ return newTextureDataImpl(glp, url, internalFormat, pixelFormat, mipmap, fileSuffix);
+ }
+
+ //----------------------------------------------------------------------
+ // methods that *do* require a current context
+ //
+
+ /**
+ * Creates an OpenGL texture object from the specified TextureData
+ * using the current OpenGL context.
+ *
+ * @param data the texture data to turn into an OpenGL texture
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ * @throws IllegalArgumentException if the passed TextureData was null
+ */
+ public static Texture newTexture(TextureData data) throws GLException, IllegalArgumentException {
+ if (data == null) {
+ throw new IllegalArgumentException("Null TextureData");
+ }
+ return new Texture(data);
+ }
+
+ /**
+ * Creates an OpenGL texture object from the specified file using
+ * the current OpenGL context.
+ *
+ * @param file the file from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @throws IOException if an error occurred while reading the file
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ */
+ public static Texture newTexture(File file, boolean mipmap) throws IOException, GLException {
+ GLProfile glp = GLContext.getCurrentGL().getGLProfile();
+ TextureData data = newTextureData(glp, file, mipmap, FileUtil.getFileSuffix(file));
+ Texture texture = newTexture(data);
+ data.flush();
+ return texture;
+ }
+
+ /**
+ * Creates an OpenGL texture object from the specified stream using
+ * the current OpenGL context.
+ *
+ * @param stream the stream from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @throws IOException if an error occurred while reading the stream
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ */
+ public static Texture newTexture(InputStream stream, boolean mipmap, String fileSuffix) throws IOException, GLException {
+ GLProfile glp = GLContext.getCurrentGL().getGLProfile();
+ TextureData data = newTextureData(glp, stream, mipmap, fileSuffix);
+ Texture texture = newTexture(data);
+ data.flush();
+ return texture;
+ }
+
+ /**
+ * Creates an OpenGL texture object from the specified URL using the
+ * current OpenGL context.
+ *
+ * @param url the URL from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @throws IOException if an error occurred while reading the URL
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ */
+ public static Texture newTexture(URL url, boolean mipmap, String fileSuffix) throws IOException, GLException {
+ if (fileSuffix == null) {
+ fileSuffix = FileUtil.getFileSuffix(url.getPath());
+ }
+ GLProfile glp = GLContext.getCurrentGL().getGLProfile();
+ TextureData data = newTextureData(glp, url, mipmap, fileSuffix);
+ Texture texture = newTexture(data);
+ data.flush();
+ return texture;
+ }
+
+ /**
+ * Creates an OpenGL texture object associated with the given OpenGL
+ * texture target using the current OpenGL context. The texture has
+ * no initial data. This is used, for example, to construct cube
+ * maps out of multiple TextureData objects.
+ *
+ * @param target the OpenGL target type, eg GL.GL_TEXTURE_2D,
+ * GL.GL_TEXTURE_RECTANGLE_ARB
+ *
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ */
+ public static Texture newTexture(int target) throws GLException {
+ return new Texture(target);
+ }
+
+ /**
+ * Wraps an OpenGL texture ID from an external library and allows
+ * some of the base methods from the Texture class, such as
+ * binding and querying of texture coordinates, to be used with
+ * it. Attempts to update such textures' contents will yield
+ * undefined results.
+ *
+ * @param textureID the OpenGL texture object to wrap
+ * @param target the OpenGL texture target, eg GL.GL_TEXTURE_2D,
+ * GL2.GL_TEXTURE_RECTANGLE
+ * @param texWidth the width of the texture in pixels
+ * @param texHeight the height of the texture in pixels
+ * @param imgWidth the width of the image within the texture in
+ * pixels (if the content is a sub-rectangle in the upper
+ * left corner); otherwise, pass in texWidth
+ * @param imgHeight the height of the image within the texture in
+ * pixels (if the content is a sub-rectangle in the upper
+ * left corner); otherwise, pass in texHeight
+ * @param mustFlipVertically indicates whether the texture
+ * coordinates must be flipped vertically
+ * in order to properly display the
+ * texture
+ */
+ public static Texture newTexture(int textureID,
+ int target,
+ int texWidth,
+ int texHeight,
+ int imgWidth,
+ int imgHeight,
+ boolean mustFlipVertically) {
+ return new Texture(textureID,
+ target,
+ texWidth,
+ texHeight,
+ imgWidth,
+ imgHeight,
+ mustFlipVertically);
+ }
+
+ /**
+ * Writes the given texture to a file. The type of the file is
+ * inferred from its suffix. An OpenGL context must be current in
+ * order to fetch the texture data back from the OpenGL pipeline.
+ * This method causes the specified Texture to be bound to the
+ * GL_TEXTURE_2D state. If no suitable writer for the requested file
+ * format was found, throws an IOException. <P>
+ *
+ * Reasonable attempts are made to produce good results in the
+ * resulting images. The Targa, SGI and ImageIO writers produce
+ * results in the correct vertical orientation for those file
+ * formats. The DDS writer performs no vertical flip of the data,
+ * even in uncompressed mode. (It is impossible to perform such a
+ * vertical flip with compressed data.) Applications should keep
+ * this in mind when using this routine to save textures to disk for
+ * later re-loading. <P>
+ *
+ * Any mipmaps for the specified texture are currently discarded
+ * when it is written to disk, regardless of whether the underlying
+ * file format supports multiple mipmaps in a given file.
+ *
+ * @throws IOException if an error occurred during writing or no
+ * suitable writer was found
+ * @throws GLException if no OpenGL context was current or an
+ * OpenGL-related error occurred
+ */
+ public static void write(Texture texture, File file) throws IOException, GLException {
+ if (texture.getTarget() != GL.GL_TEXTURE_2D) {
+ throw new GLException("Only GL_TEXTURE_2D textures are supported");
+ }
+
+ // First fetch the texture data
+ GL _gl = GLContext.getCurrentGL();
+ if (!_gl.isGL2()) {
+ throw new GLException("Only GL2 supports fetching compressed images, GL: " + _gl);
+ }
+ GL2 gl = _gl.getGL2();
+
+ texture.bind();
+ int internalFormat = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_INTERNAL_FORMAT);
+ int width = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_WIDTH);
+ int height = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_HEIGHT);
+ int border = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_BORDER);
+ TextureData data = null;
+ if (internalFormat == GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ internalFormat == GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
+ internalFormat == GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
+ internalFormat == GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) {
+ // Fetch using glGetCompressedTexImage
+ int size = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_COMPRESSED_IMAGE_SIZE);
+ ByteBuffer res = ByteBuffer.wrap(new byte[size]);
+ gl.glGetCompressedTexImage(GL.GL_TEXTURE_2D, 0, res);
+ data = new TextureData(gl.getGLProfile(), internalFormat, width, height, border, internalFormat, GL.GL_UNSIGNED_BYTE,
+ false, true, true, res, null);
+ } else {
+ int bytesPerPixel = 0;
+ int fetchedFormat = 0;
+ switch (internalFormat) {
+ case GL.GL_RGB:
+ case GL2.GL_BGR:
+ case GL.GL_RGB8:
+ bytesPerPixel = 3;
+ fetchedFormat = GL.GL_RGB;
+ break;
+ case GL.GL_RGBA:
+ case GL2.GL_BGRA:
+ case GL2.GL_ABGR_EXT:
+ case GL.GL_RGBA8:
+ bytesPerPixel = 4;
+ fetchedFormat = GL.GL_RGBA;
+ break;
+ default:
+ throw new IOException("Unsupported texture internal format 0x" + Integer.toHexString(internalFormat));
+ }
+
+ // Fetch using glGetTexImage
+ int packAlignment = glGetInteger(GL.GL_PACK_ALIGNMENT);
+ int packRowLength = glGetInteger(GL2.GL_PACK_ROW_LENGTH);
+ int packSkipRows = glGetInteger(GL2.GL_PACK_SKIP_ROWS);
+ int packSkipPixels = glGetInteger(GL2.GL_PACK_SKIP_PIXELS);
+ int packSwapBytes = glGetInteger(GL2.GL_PACK_SWAP_BYTES);
+
+ gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, 0);
+
+ ByteBuffer res = ByteBuffer.wrap(new byte[(width + (2 * border)) *
+ (height + (2 * border)) *
+ bytesPerPixel]);
+ if (DEBUG) {
+ System.out.println("Allocated buffer of size " + res.remaining() + " for fetched image (" +
+ ((fetchedFormat == GL.GL_RGB) ? "GL_RGB" : "GL_RGBA") + ")");
+ }
+ gl.glGetTexImage(GL.GL_TEXTURE_2D, 0, fetchedFormat, GL.GL_UNSIGNED_BYTE, res);
+
+ gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, packAlignment);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, packRowLength);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, packSkipRows);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, packSkipPixels);
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, packSwapBytes);
+
+ data = new TextureData(gl.getGLProfile(), internalFormat, width, height, border, fetchedFormat, GL.GL_UNSIGNED_BYTE,
+ false, false, false, res, null);
+
+ if (DEBUG) {
+ System.out.println("data.getPixelFormat() = " +
+ ((data.getPixelFormat() == GL.GL_RGB) ? "GL_RGB" : "GL_RGBA"));
+ }
+ }
+
+ write(data, file);
+ }
+
+ public static void write(TextureData data, File file) throws IOException, GLException {
+ for (Iterator iter = textureWriters.iterator(); iter.hasNext(); ) {
+ TextureWriter writer = (TextureWriter) iter.next();
+ if (writer.write(file, data)) {
+ return;
+ }
+ }
+
+ throw new IOException("No suitable texture writer found for "+file.getAbsolutePath());
+ }
+
+ //----------------------------------------------------------------------
+ // SPI support
+ //
+
+ /** Adds a TextureProvider to support reading of a new file
+ format. */
+ public static void addTextureProvider(TextureProvider provider) {
+ // Must always add at the front so the ImageIO provider is last,
+ // so we don't accidentally use it instead of a user's possibly
+ // more optimal provider
+ textureProviders.add(0, provider);
+ }
+
+ /** Adds a TextureWriter to support writing of a new file
+ format. */
+ public static void addTextureWriter(TextureWriter writer) {
+ // Must always add at the front so the ImageIO writer is last,
+ // so we don't accidentally use it instead of a user's possibly
+ // more optimal writer
+ textureWriters.add(0, writer);
+ }
+
+ //---------------------------------------------------------------------------
+ // Global disabling of texture rectangle extension
+ //
+
+ /** Toggles the use of the GL_ARB_texture_rectangle extension by the
+ TextureIO classes. By default, on hardware supporting this
+ extension, the TextureIO classes may use the
+ GL_ARB_texture_rectangle extension for non-power-of-two
+ textures. (If the hardware supports the
+ GL_ARB_texture_non_power_of_two extension, that one is
+ preferred.) In some situations, for example when writing
+ shaders, it is advantageous to force the texture target to
+ always be GL_TEXTURE_2D in order to have one version of the
+ shader, even at the expense of texture memory in the case where
+ NPOT textures are not supported. This method allows the use of
+ the GL_ARB_texture_rectangle extension to be turned off globally
+ for this purpose. The default is that the use of the extension
+ is enabled. */
+ public static void setTexRectEnabled(boolean enabled) {
+ texRectEnabled = enabled;
+ }
+
+ /** Indicates whether the GL_ARB_texture_rectangle extension is
+ allowed to be used for non-power-of-two textures; see {@link
+ #setTexRectEnabled setTexRectEnabled}. */
+ public static boolean isTexRectEnabled() {
+ return texRectEnabled;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static List/*<TextureProvider>*/ textureProviders = new ArrayList/*<TextureProvider>*/();
+ private static List/*<TextureWriter>*/ textureWriters = new ArrayList/*<TextureWriter>*/();
+
+ static {
+ /*
+ if(GLProfile.isAWTJOGLAvailable()) {
+ // ImageIO provider, the fall-back, must be the first one added
+ try {
+ // Use reflection to avoid compile-time dependencies on AWT-related classes
+ TextureProvider provider = (TextureProvider)
+ Class.forName("com.jogamp.opengl.util.texture.spi.awt.IIOTextureProvider").newInstance();
+ addTextureProvider(provider);
+ } catch (Exception e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ }
+ }
+ }
+ */
+
+ // Other special-case providers
+ addTextureProvider(new DDSTextureProvider());
+ addTextureProvider(new SGITextureProvider());
+ addTextureProvider(new TGATextureProvider());
+
+ /*
+ // ImageIO writer, the fall-back, must be the first one added
+ if(GLProfile.isAWTJOGLAvailable()) {
+ try {
+ // Use reflection to avoid compile-time dependencies on AWT-related classes
+ TextureWriter writer = (TextureWriter)
+ Class.forName("com.jogamp.opengl.util.texture.spi.awt.IIOTextureWriter").newInstance();
+ addTextureWriter(writer);
+ } catch (Exception e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ }
+ }
+ }
+ */
+
+ // Other special-case writers
+ addTextureWriter(new DDSTextureWriter());
+ addTextureWriter(new SGITextureWriter());
+ addTextureWriter(new TGATextureWriter());
+ addTextureWriter(new NetPbmTextureWriter());
+ }
+
+ // Implementation methods
+ private static TextureData newTextureDataImpl(GLProfile glp, File file,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (file == null) {
+ throw new IOException("File was null");
+ }
+
+ fileSuffix = toLowerCase(fileSuffix);
+
+ for (Iterator iter = textureProviders.iterator(); iter.hasNext(); ) {
+ TextureProvider provider = (TextureProvider) iter.next();
+ TextureData data = provider.newTextureData(glp, file,
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ fileSuffix);
+ if (data != null) {
+ return data;
+ }
+ }
+
+ throw new IOException("No suitable reader for given file "+file.getAbsolutePath());
+ }
+
+ private static TextureData newTextureDataImpl(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (stream == null) {
+ throw new IOException("Stream was null");
+ }
+
+ fileSuffix = toLowerCase(fileSuffix);
+
+ // Note: use of BufferedInputStream works around 4764639/4892246
+ if (!(stream instanceof BufferedInputStream)) {
+ stream = new BufferedInputStream(stream);
+ }
+
+ for (Iterator iter = textureProviders.iterator(); iter.hasNext(); ) {
+ TextureProvider provider = (TextureProvider) iter.next();
+ TextureData data = provider.newTextureData(glp, stream,
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ fileSuffix);
+ if (data != null) {
+ return data;
+ }
+ }
+
+ throw new IOException("No suitable reader for given stream");
+ }
+
+ private static TextureData newTextureDataImpl(GLProfile glp, URL url,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (url == null) {
+ throw new IOException("URL was null");
+ }
+
+ fileSuffix = toLowerCase(fileSuffix);
+
+ for (Iterator iter = textureProviders.iterator(); iter.hasNext(); ) {
+ TextureProvider provider = (TextureProvider) iter.next();
+ TextureData data = provider.newTextureData(glp, url,
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ fileSuffix);
+ if (data != null) {
+ return data;
+ }
+ }
+
+ throw new IOException("No suitable reader for given URL "+url);
+ }
+
+ //----------------------------------------------------------------------
+ // DDS provider -- supports files only for now
+ static class DDSTextureProvider implements TextureProvider {
+ public TextureData newTextureData(GLProfile glp, File file,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (DDS.equals(fileSuffix) ||
+ DDS.equals(FileUtil.getFileSuffix(file))) {
+ DDSImage image = DDSImage.read(file);
+ return newTextureData(glp, image, internalFormat, pixelFormat, mipmap);
+ }
+
+ return null;
+ }
+
+ public TextureData newTextureData(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (DDS.equals(fileSuffix) ||
+ DDSImage.isDDSImage(stream)) {
+ DDSImage image = DDSImage.read(stream);
+ return newTextureData(glp, image, internalFormat, pixelFormat, mipmap);
+ }
+
+ return null;
+ }
+
+ public TextureData newTextureData(GLProfile glp, URL url,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ InputStream stream = new BufferedInputStream(url.openStream());
+ try {
+ return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
+ } finally {
+ stream.close();
+ }
+ }
+
+ private TextureData newTextureData(GLProfile glp, final DDSImage image,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap) {
+ DDSImage.ImageInfo info = image.getMipMap(0);
+ if (pixelFormat == 0) {
+ switch (image.getPixelFormat()) {
+ case DDSImage.D3DFMT_R8G8B8:
+ pixelFormat = GL.GL_RGB;
+ break;
+ default:
+ pixelFormat = GL.GL_RGBA;
+ break;
+ }
+ }
+ if (info.isCompressed()) {
+ switch (info.getCompressionFormat()) {
+ case DDSImage.D3DFMT_DXT1:
+ internalFormat = GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+ break;
+ case DDSImage.D3DFMT_DXT3:
+ internalFormat = GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ break;
+ case DDSImage.D3DFMT_DXT5:
+ internalFormat = GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ break;
+ default:
+ throw new RuntimeException("Unsupported DDS compression format \"" +
+ DDSImage.getCompressionFormatName(info.getCompressionFormat()) + "\"");
+ }
+ }
+ if (internalFormat == 0) {
+ switch (image.getPixelFormat()) {
+ case DDSImage.D3DFMT_R8G8B8:
+ pixelFormat = GL.GL_RGB;
+ break;
+ default:
+ pixelFormat = GL.GL_RGBA;
+ break;
+ }
+ }
+ TextureData.Flusher flusher = new TextureData.Flusher() {
+ public void flush() {
+ image.close();
+ }
+ };
+ TextureData data;
+ if (mipmap && image.getNumMipMaps() > 0) {
+ Buffer[] mipmapData = new Buffer[image.getNumMipMaps()];
+ for (int i = 0; i < image.getNumMipMaps(); i++) {
+ mipmapData[i] = image.getMipMap(i).getData();
+ }
+ data = new TextureData(glp, internalFormat,
+ info.getWidth(),
+ info.getHeight(),
+ 0,
+ pixelFormat,
+ GL.GL_UNSIGNED_BYTE,
+ info.isCompressed(),
+ true,
+ mipmapData,
+ flusher);
+ } else {
+ // Fix this up for the end user because we can't generate
+ // mipmaps for compressed textures
+ mipmap = false;
+ data = new TextureData(glp, internalFormat,
+ info.getWidth(),
+ info.getHeight(),
+ 0,
+ pixelFormat,
+ GL.GL_UNSIGNED_BYTE,
+ mipmap,
+ info.isCompressed(),
+ true,
+ info.getData(),
+ flusher);
+ }
+ return data;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Base class for SGI RGB and TGA image providers
+ static abstract class StreamBasedTextureProvider implements TextureProvider {
+ public TextureData newTextureData(GLProfile glp, File file,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ InputStream inStream = new BufferedInputStream(new FileInputStream(file));
+ try {
+ // The SGIImage and TGAImage implementations use InputStreams
+ // anyway so there isn't much point in having a separate code
+ // path for files
+ return newTextureData(glp, inStream,
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ ((fileSuffix != null) ? fileSuffix : FileUtil.getFileSuffix(file)));
+ } finally {
+ inStream.close();
+ }
+ }
+
+ public TextureData newTextureData(GLProfile glp, URL url,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ InputStream stream = new BufferedInputStream(url.openStream());
+ try {
+ return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
+ } finally {
+ stream.close();
+ }
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // SGI RGB image provider
+ static class SGITextureProvider extends StreamBasedTextureProvider {
+ public TextureData newTextureData(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (SGI.equals(fileSuffix) ||
+ SGI_RGB.equals(fileSuffix) ||
+ SGIImage.isSGIImage(stream)) {
+ SGIImage image = SGIImage.read(stream);
+ if (pixelFormat == 0) {
+ pixelFormat = image.getFormat();
+ }
+ if (internalFormat == 0) {
+ internalFormat = image.getFormat();
+ }
+ return new TextureData(glp, internalFormat,
+ image.getWidth(),
+ image.getHeight(),
+ 0,
+ pixelFormat,
+ GL.GL_UNSIGNED_BYTE,
+ mipmap,
+ false,
+ false,
+ ByteBuffer.wrap(image.getData()),
+ null);
+ }
+
+ return null;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // TGA (Targa) image provider
+ static class TGATextureProvider extends StreamBasedTextureProvider {
+ public TextureData newTextureData(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (TGA.equals(fileSuffix)) {
+ TGAImage image = TGAImage.read(stream);
+ if (pixelFormat == 0) {
+ pixelFormat = image.getGLFormat();
+ }
+ if (internalFormat == 0) {
+ GL gl = GLContext.getCurrentGL();
+ if(gl.isGL2()) {
+ internalFormat = GL.GL_RGBA8;
+ } else {
+ internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA:GL.GL_RGB;
+ }
+ }
+ return new TextureData(glp, internalFormat,
+ image.getWidth(),
+ image.getHeight(),
+ 0,
+ pixelFormat,
+ GL.GL_UNSIGNED_BYTE,
+ mipmap,
+ false,
+ false,
+ image.getData(),
+ null);
+ }
+
+ return null;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // DDS texture writer
+ //
+ static class DDSTextureWriter implements TextureWriter {
+ public boolean write(File file,
+ TextureData data) throws IOException {
+ if (DDS.equals(FileUtil.getFileSuffix(file))) {
+ // See whether the DDS writer can handle this TextureData
+ int pixelFormat = data.getPixelFormat();
+ int pixelType = data.getPixelType();
+ if (pixelType != GL.GL_BYTE &&
+ pixelType != GL.GL_UNSIGNED_BYTE) {
+ throw new IOException("DDS writer only supports byte / unsigned byte textures");
+ }
+
+ int d3dFormat = 0;
+ // FIXME: some of these are probably not completely correct and would require swizzling
+ switch (pixelFormat) {
+ case GL.GL_RGB: d3dFormat = DDSImage.D3DFMT_R8G8B8; break;
+ case GL.GL_RGBA: d3dFormat = DDSImage.D3DFMT_A8R8G8B8; break;
+ case GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT: d3dFormat = DDSImage.D3DFMT_DXT1; break;
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: throw new IOException("RGBA DXT1 not yet supported");
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: d3dFormat = DDSImage.D3DFMT_DXT3; break;
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: d3dFormat = DDSImage.D3DFMT_DXT5; break;
+ default: throw new IOException("Unsupported pixel format 0x" + Integer.toHexString(pixelFormat) + " by DDS writer");
+ }
+
+ ByteBuffer[] mipmaps = null;
+ if (data.getMipmapData() != null) {
+ mipmaps = new ByteBuffer[data.getMipmapData().length];
+ for (int i = 0; i < mipmaps.length; i++) {
+ mipmaps[i] = (ByteBuffer) data.getMipmapData()[i];
+ }
+ } else {
+ mipmaps = new ByteBuffer[] { (ByteBuffer) data.getBuffer() };
+ }
+
+ DDSImage image = DDSImage.createFromData(d3dFormat,
+ data.getWidth(),
+ data.getHeight(),
+ mipmaps);
+ image.write(file);
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // SGI (rgb) texture writer
+ //
+ static class SGITextureWriter implements TextureWriter {
+ public boolean write(File file,
+ TextureData data) throws IOException {
+ String fileSuffix = FileUtil.getFileSuffix(file);
+ if (SGI.equals(fileSuffix) ||
+ SGI_RGB.equals(fileSuffix)) {
+ // See whether the SGI writer can handle this TextureData
+ int pixelFormat = data.getPixelFormat();
+ int pixelType = data.getPixelType();
+ if ((pixelFormat == GL.GL_RGB ||
+ pixelFormat == GL.GL_RGBA) &&
+ (pixelType == GL.GL_BYTE ||
+ pixelType == GL.GL_UNSIGNED_BYTE)) {
+ ByteBuffer buf = ((data.getBuffer() != null) ?
+ (ByteBuffer) data.getBuffer() :
+ (ByteBuffer) data.getMipmapData()[0]);
+ byte[] bytes;
+ if (buf.hasArray()) {
+ bytes = buf.array();
+ } else {
+ buf.rewind();
+ bytes = new byte[buf.remaining()];
+ buf.get(bytes);
+ buf.rewind();
+ }
+
+ SGIImage image = SGIImage.createFromData(data.getWidth(),
+ data.getHeight(),
+ (pixelFormat == GL.GL_RGBA),
+ bytes);
+ image.write(file, false);
+ return true;
+ }
+
+ throw new IOException("SGI writer doesn't support this pixel format / type (only GL_RGB/A + bytes)");
+ }
+
+ return false;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // TGA (Targa) texture writer
+
+ static class TGATextureWriter implements TextureWriter {
+ public boolean write(File file,
+ TextureData data) throws IOException {
+ if (TGA.equals(FileUtil.getFileSuffix(file))) {
+ // See whether the TGA writer can handle this TextureData
+ int pixelFormat = data.getPixelFormat();
+ int pixelType = data.getPixelType();
+ if ((pixelFormat == GL.GL_RGB ||
+ pixelFormat == GL.GL_RGBA) &&
+ (pixelType == GL.GL_BYTE ||
+ pixelType == GL.GL_UNSIGNED_BYTE)) {
+ ByteBuffer buf = ((data.getBuffer() != null) ?
+ (ByteBuffer) data.getBuffer() :
+ (ByteBuffer) data.getMipmapData()[0]);
+ // Must reverse order of red and blue channels to get correct results
+ int skip = ((pixelFormat == GL.GL_RGB) ? 3 : 4);
+ for (int i = 0; i < buf.remaining(); i += skip) {
+ byte red = buf.get(i + 0);
+ byte blue = buf.get(i + 2);
+ buf.put(i + 0, blue);
+ buf.put(i + 2, red);
+ }
+
+ TGAImage image = TGAImage.createFromData(data.getWidth(),
+ data.getHeight(),
+ (pixelFormat == GL.GL_RGBA),
+ false,
+ ((data.getBuffer() != null) ?
+ (ByteBuffer) data.getBuffer() :
+ (ByteBuffer) data.getMipmapData()[0]));
+ image.write(file);
+ return true;
+ }
+
+ throw new IOException("TGA writer doesn't support this pixel format / type (only GL_RGB/A + bytes)");
+ }
+
+ return false;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Helper routines
+ //
+
+ private static int glGetInteger(int pname) {
+ int[] tmp = new int[1];
+ GL gl = GLContext.getCurrentGL();
+ gl.glGetIntegerv(pname, tmp, 0);
+ return tmp[0];
+ }
+
+ private static int glGetTexLevelParameteri(GL2 gl, int target, int level, int pname) {
+ int[] tmp = new int[1];
+ gl.glGetTexLevelParameteriv(target, 0, pname, tmp, 0);
+ return tmp[0];
+ }
+
+ private static String toLowerCase(String arg) {
+ if (arg == null) {
+ return null;
+ }
+
+ return arg.toLowerCase();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javase b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javase
new file mode 100755
index 000000000..3e6f66f10
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javase
@@ -0,0 +1,1258 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture;
+
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+import java.util.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import com.jogamp.opengl.impl.Debug;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.texture.spi.*;
+
+/** <P> Provides input and output facilities for both loading OpenGL
+ textures from disk and streams as well as writing textures already
+ in memory back to disk. </P>
+
+ <P> The TextureIO class supports an arbitrary number of plug-in
+ readers and writers via TextureProviders and TextureWriters.
+ TextureProviders know how to produce TextureData objects from
+ files, InputStreams and URLs. TextureWriters know how to write
+ TextureData objects to disk in various file formats. The
+ TextureData class represents the raw data of the texture before it
+ has been converted to an OpenGL texture object. The Texture class
+ represents the OpenGL texture object and provides easy facilities
+ for using the texture. </P>
+
+ <P> There are several built-in TextureProviders and TextureWriters
+ supplied with the TextureIO implementation. The most basic
+ provider uses the platform's Image I/O facilities to read in a
+ BufferedImage and convert it to a texture. This is the baseline
+ provider and is registered so that it is the last one consulted.
+ All others are asked first to open a given file. </P>
+
+ <P> There are three other providers registered by default as of
+ the time of this writing. One handles SGI RGB (".sgi", ".rgb")
+ images from both files and streams. One handles DirectDraw Surface
+ (".dds") images read from files, though can not read these images
+ from streams. One handles Targa (".tga") images read from both
+ files and streams. These providers are executed in an arbitrary
+ order. Some of these providers require the file's suffix to either
+ be specified via the newTextureData methods or for the file to be
+ named with the appropriate suffix. In general a file suffix should
+ be provided to the newTexture and newTextureData methods if at all
+ possible. </P>
+
+ <P> Note that additional TextureProviders, if reading images from
+ InputStreams, must use the mark()/reset() methods on InputStream
+ when probing for e.g. magic numbers at the head of the file to
+ make sure not to disturb the state of the InputStream for
+ downstream TextureProviders. </P>
+
+ <P> There are analogous TextureWriters provided for writing
+ textures back to disk if desired. As of this writing, there are
+ four TextureWriters registered by default: one for Targa files,
+ one for SGI RGB files, one for DirectDraw surface (.dds) files,
+ and one for ImageIO-supplied formats such as .jpg and .png. Some
+ of these writers have certain limitations such as only being able
+ to write out textures stored in GL_RGB or GL_RGBA format. The DDS
+ writer supports fetching and writing to disk of texture data in
+ DXTn compressed format. Whether this will occur is dependent on
+ whether the texture's internal format is one of the DXTn
+ compressed formats and whether the target file is .dds format.
+*/
+
+public class TextureIO {
+ /** Constant which can be used as a file suffix to indicate a
+ DirectDraw Surface file. */
+ public static final String DDS = "dds";
+
+ /** Constant which can be used as a file suffix to indicate an SGI
+ RGB file. */
+ public static final String SGI = "sgi";
+
+ /** Constant which can be used as a file suffix to indicate an SGI
+ RGB file. */
+ public static final String SGI_RGB = "rgb";
+
+ /** Constant which can be used as a file suffix to indicate a GIF
+ file. */
+ public static final String GIF = "gif";
+
+ /** Constant which can be used as a file suffix to indicate a JPEG
+ file. */
+ public static final String JPG = "jpg";
+
+ /** Constant which can be used as a file suffix to indicate a PNG
+ file. */
+ public static final String PNG = "png";
+
+ /** Constant which can be used as a file suffix to indicate a Targa
+ file. */
+ public static final String TGA = "tga";
+
+ /** Constant which can be used as a file suffix to indicate a TIFF
+ file. */
+ public static final String TIFF = "tiff";
+
+ private static final boolean DEBUG = Debug.debug("TextureIO");
+
+ // For manually disabling the use of the texture rectangle
+ // extensions so you know the texture target is GL_TEXTURE_2D; this
+ // is useful for shader writers (thanks to Chris Campbell for this
+ // observation)
+ private static boolean texRectEnabled = true;
+
+ //----------------------------------------------------------------------
+ // methods that *do not* require a current context
+ // These methods assume RGB or RGBA textures.
+ // Some texture providers may not recognize the file format unless
+ // the fileSuffix is specified, so it is strongly recommended to
+ // specify it wherever it is known.
+ // Some texture providers may also only support one kind of input,
+ // i.e., reading from a file as opposed to a stream.
+
+ /**
+ * Creates a TextureData from the given file. Does no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param file the file from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the file, or null if none of the
+ * registered texture providers could read the file
+ * @throws IOException if an error occurred while reading the file
+ */
+ public static TextureData newTextureData(GLProfile glp, File file,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (fileSuffix == null) {
+ fileSuffix = FileUtil.getFileSuffix(file);
+ }
+ return newTextureDataImpl(glp, file, 0, 0, mipmap, fileSuffix);
+ }
+
+ /**
+ * Creates a TextureData from the given stream. Does no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param stream the stream from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the stream, or null if none of the
+ * registered texture providers could read the stream
+ * @throws IOException if an error occurred while reading the stream
+ */
+ public static TextureData newTextureData(GLProfile glp, InputStream stream,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ return newTextureDataImpl(glp, stream, 0, 0, mipmap, fileSuffix);
+ }
+
+ /**
+ * Creates a TextureData from the given URL. Does no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param url the URL from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the URL, or null if none of the
+ * registered texture providers could read the URL
+ * @throws IOException if an error occurred while reading the URL
+ */
+ public static TextureData newTextureData(GLProfile glp, URL url,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (fileSuffix == null) {
+ fileSuffix = FileUtil.getFileSuffix(url.getPath());
+ }
+ return newTextureDataImpl(glp, url, 0, 0, mipmap, fileSuffix);
+ }
+
+ //----------------------------------------------------------------------
+ // These methods make no assumption about the OpenGL internal format
+ // or pixel format of the texture; they must be specified by the
+ // user. It is not allowed to supply 0 (indicating no preference)
+ // for either the internalFormat or the pixelFormat;
+ // IllegalArgumentException will be thrown in this case.
+
+ /**
+ * Creates a TextureData from the given file, using the specified
+ * OpenGL internal format and pixel format for the texture which
+ * will eventually result. The internalFormat and pixelFormat must
+ * be specified and may not be zero; to use default values, use the
+ * variant of this method which does not take these arguments. Does
+ * no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param file the file from which to read the texture data
+ * @param internalFormat the OpenGL internal format of the texture
+ * which will eventually result from the TextureData
+ * @param pixelFormat the OpenGL pixel format of the texture
+ * which will eventually result from the TextureData
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the file, or null if none of the
+ * registered texture providers could read the file
+ * @throws IllegalArgumentException if either internalFormat or
+ * pixelFormat was 0
+ * @throws IOException if an error occurred while reading the file
+ */
+ public static TextureData newTextureData(GLProfile glp, File file,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException, IllegalArgumentException {
+ if ((internalFormat == 0) || (pixelFormat == 0)) {
+ throw new IllegalArgumentException("internalFormat and pixelFormat must be non-zero");
+ }
+
+ if (fileSuffix == null) {
+ fileSuffix = FileUtil.getFileSuffix(file);
+ }
+
+ return newTextureDataImpl(glp, file, internalFormat, pixelFormat, mipmap, fileSuffix);
+ }
+
+ /**
+ * Creates a TextureData from the given stream, using the specified
+ * OpenGL internal format and pixel format for the texture which
+ * will eventually result. The internalFormat and pixelFormat must
+ * be specified and may not be zero; to use default values, use the
+ * variant of this method which does not take these arguments. Does
+ * no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param stream the stream from which to read the texture data
+ * @param internalFormat the OpenGL internal format of the texture
+ * which will eventually result from the TextureData
+ * @param pixelFormat the OpenGL pixel format of the texture
+ * which will eventually result from the TextureData
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the stream, or null if none of the
+ * registered texture providers could read the stream
+ * @throws IllegalArgumentException if either internalFormat or
+ * pixelFormat was 0
+ * @throws IOException if an error occurred while reading the stream
+ */
+ public static TextureData newTextureData(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException, IllegalArgumentException {
+ if ((internalFormat == 0) || (pixelFormat == 0)) {
+ throw new IllegalArgumentException("internalFormat and pixelFormat must be non-zero");
+ }
+
+ return newTextureDataImpl(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
+ }
+
+ /**
+ * Creates a TextureData from the given URL, using the specified
+ * OpenGL internal format and pixel format for the texture which
+ * will eventually result. The internalFormat and pixelFormat must
+ * be specified and may not be zero; to use default values, use the
+ * variant of this method which does not take these arguments. Does
+ * no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param url the URL from which to read the texture data
+ * @param internalFormat the OpenGL internal format of the texture
+ * which will eventually result from the TextureData
+ * @param pixelFormat the OpenGL pixel format of the texture
+ * which will eventually result from the TextureData
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @return the texture data from the URL, or null if none of the
+ * registered texture providers could read the URL
+ * @throws IllegalArgumentException if either internalFormat or
+ * pixelFormat was 0
+ * @throws IOException if an error occurred while reading the URL
+ */
+ public static TextureData newTextureData(GLProfile glp, URL url,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException, IllegalArgumentException {
+ if ((internalFormat == 0) || (pixelFormat == 0)) {
+ throw new IllegalArgumentException("internalFormat and pixelFormat must be non-zero");
+ }
+
+ if (fileSuffix == null) {
+ fileSuffix = FileUtil.getFileSuffix(url.getPath());
+ }
+
+ return newTextureDataImpl(glp, url, internalFormat, pixelFormat, mipmap, fileSuffix);
+ }
+
+ //----------------------------------------------------------------------
+ // methods that *do* require a current context
+ //
+
+ /**
+ * Creates an OpenGL texture object from the specified TextureData
+ * using the current OpenGL context.
+ *
+ * @param data the texture data to turn into an OpenGL texture
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ * @throws IllegalArgumentException if the passed TextureData was null
+ */
+ public static Texture newTexture(TextureData data) throws GLException, IllegalArgumentException {
+ if (data == null) {
+ throw new IllegalArgumentException("Null TextureData");
+ }
+ return new Texture(data);
+ }
+
+ /**
+ * Creates an OpenGL texture object from the specified file using
+ * the current OpenGL context.
+ *
+ * @param file the file from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @throws IOException if an error occurred while reading the file
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ */
+ public static Texture newTexture(File file, boolean mipmap) throws IOException, GLException {
+ GLProfile glp = GLContext.getCurrentGL().getGLProfile();
+ TextureData data = newTextureData(glp, file, mipmap, FileUtil.getFileSuffix(file));
+ Texture texture = newTexture(data);
+ data.flush();
+ return texture;
+ }
+
+ /**
+ * Creates an OpenGL texture object from the specified stream using
+ * the current OpenGL context.
+ *
+ * @param stream the stream from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @throws IOException if an error occurred while reading the stream
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ */
+ public static Texture newTexture(InputStream stream, boolean mipmap, String fileSuffix) throws IOException, GLException {
+ GLProfile glp = GLContext.getCurrentGL().getGLProfile();
+ TextureData data = newTextureData(glp, stream, mipmap, fileSuffix);
+ Texture texture = newTexture(data);
+ data.flush();
+ return texture;
+ }
+
+ /**
+ * Creates an OpenGL texture object from the specified URL using the
+ * current OpenGL context.
+ *
+ * @param url the URL from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @param fileSuffix the suffix of the file name to be used as a
+ * hint of the file format to the underlying
+ * texture provider, or null if none and should be
+ * auto-detected (some texture providers do not
+ * support this)
+ * @throws IOException if an error occurred while reading the URL
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ */
+ public static Texture newTexture(URL url, boolean mipmap, String fileSuffix) throws IOException, GLException {
+ if (fileSuffix == null) {
+ fileSuffix = FileUtil.getFileSuffix(url.getPath());
+ }
+ GLProfile glp = GLContext.getCurrentGL().getGLProfile();
+ TextureData data = newTextureData(glp, url, mipmap, fileSuffix);
+ Texture texture = newTexture(data);
+ data.flush();
+ return texture;
+ }
+
+ /**
+ * Creates an OpenGL texture object associated with the given OpenGL
+ * texture target using the current OpenGL context. The texture has
+ * no initial data. This is used, for example, to construct cube
+ * maps out of multiple TextureData objects.
+ *
+ * @param target the OpenGL target type, eg GL.GL_TEXTURE_2D,
+ * GL.GL_TEXTURE_RECTANGLE_ARB
+ *
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ */
+ public static Texture newTexture(int target) throws GLException {
+ return new Texture(target);
+ }
+
+ /**
+ * Wraps an OpenGL texture ID from an external library and allows
+ * some of the base methods from the Texture class, such as
+ * binding and querying of texture coordinates, to be used with
+ * it. Attempts to update such textures' contents will yield
+ * undefined results.
+ *
+ * @param textureID the OpenGL texture object to wrap
+ * @param target the OpenGL texture target, eg GL.GL_TEXTURE_2D,
+ * GL2.GL_TEXTURE_RECTANGLE
+ * @param texWidth the width of the texture in pixels
+ * @param texHeight the height of the texture in pixels
+ * @param imgWidth the width of the image within the texture in
+ * pixels (if the content is a sub-rectangle in the upper
+ * left corner); otherwise, pass in texWidth
+ * @param imgHeight the height of the image within the texture in
+ * pixels (if the content is a sub-rectangle in the upper
+ * left corner); otherwise, pass in texHeight
+ * @param mustFlipVertically indicates whether the texture
+ * coordinates must be flipped vertically
+ * in order to properly display the
+ * texture
+ */
+ public static Texture newTexture(int textureID,
+ int target,
+ int texWidth,
+ int texHeight,
+ int imgWidth,
+ int imgHeight,
+ boolean mustFlipVertically) {
+ return new Texture(textureID,
+ target,
+ texWidth,
+ texHeight,
+ imgWidth,
+ imgHeight,
+ mustFlipVertically);
+ }
+
+ /**
+ * Writes the given texture to a file. The type of the file is
+ * inferred from its suffix. An OpenGL context must be current in
+ * order to fetch the texture data back from the OpenGL pipeline.
+ * This method causes the specified Texture to be bound to the
+ * GL_TEXTURE_2D state. If no suitable writer for the requested file
+ * format was found, throws an IOException. <P>
+ *
+ * Reasonable attempts are made to produce good results in the
+ * resulting images. The Targa, SGI and ImageIO writers produce
+ * results in the correct vertical orientation for those file
+ * formats. The DDS writer performs no vertical flip of the data,
+ * even in uncompressed mode. (It is impossible to perform such a
+ * vertical flip with compressed data.) Applications should keep
+ * this in mind when using this routine to save textures to disk for
+ * later re-loading. <P>
+ *
+ * Any mipmaps for the specified texture are currently discarded
+ * when it is written to disk, regardless of whether the underlying
+ * file format supports multiple mipmaps in a given file.
+ *
+ * @throws IOException if an error occurred during writing or no
+ * suitable writer was found
+ * @throws GLException if no OpenGL context was current or an
+ * OpenGL-related error occurred
+ */
+ public static void write(Texture texture, File file) throws IOException, GLException {
+ if (texture.getTarget() != GL.GL_TEXTURE_2D) {
+ throw new GLException("Only GL_TEXTURE_2D textures are supported");
+ }
+
+ // First fetch the texture data
+ GL _gl = GLContext.getCurrentGL();
+ if (!_gl.isGL2()) {
+ throw new GLException("Only GL2 supports fetching compressed images, GL: " + _gl);
+ }
+ GL2 gl = _gl.getGL2();
+
+ texture.bind();
+ int internalFormat = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_INTERNAL_FORMAT);
+ int width = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_WIDTH);
+ int height = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_HEIGHT);
+ int border = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_BORDER);
+ TextureData data = null;
+ if (internalFormat == GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ internalFormat == GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
+ internalFormat == GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
+ internalFormat == GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) {
+ // Fetch using glGetCompressedTexImage
+ int size = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_COMPRESSED_IMAGE_SIZE);
+ ByteBuffer res = ByteBuffer.allocate(size);
+ gl.glGetCompressedTexImage(GL.GL_TEXTURE_2D, 0, res);
+ data = new TextureData(gl.getGLProfile(), internalFormat, width, height, border, internalFormat, GL.GL_UNSIGNED_BYTE,
+ false, true, true, res, null);
+ } else {
+ int bytesPerPixel = 0;
+ int fetchedFormat = 0;
+ switch (internalFormat) {
+ case GL.GL_RGB:
+ case GL2.GL_BGR:
+ case GL.GL_RGB8:
+ bytesPerPixel = 3;
+ fetchedFormat = GL.GL_RGB;
+ break;
+ case GL.GL_RGBA:
+ case GL2.GL_BGRA:
+ case GL2.GL_ABGR_EXT:
+ case GL.GL_RGBA8:
+ bytesPerPixel = 4;
+ fetchedFormat = GL.GL_RGBA;
+ break;
+ default:
+ throw new IOException("Unsupported texture internal format 0x" + Integer.toHexString(internalFormat));
+ }
+
+ // Fetch using glGetTexImage
+ int packAlignment = glGetInteger(GL.GL_PACK_ALIGNMENT);
+ int packRowLength = glGetInteger(GL2.GL_PACK_ROW_LENGTH);
+ int packSkipRows = glGetInteger(GL2.GL_PACK_SKIP_ROWS);
+ int packSkipPixels = glGetInteger(GL2.GL_PACK_SKIP_PIXELS);
+ int packSwapBytes = glGetInteger(GL2.GL_PACK_SWAP_BYTES);
+
+ gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, 0);
+
+ ByteBuffer res = ByteBuffer.allocate((width + (2 * border)) *
+ (height + (2 * border)) *
+ bytesPerPixel);
+ if (DEBUG) {
+ System.out.println("Allocated buffer of size " + res.remaining() + " for fetched image (" +
+ ((fetchedFormat == GL.GL_RGB) ? "GL_RGB" : "GL_RGBA") + ")");
+ }
+ gl.glGetTexImage(GL.GL_TEXTURE_2D, 0, fetchedFormat, GL.GL_UNSIGNED_BYTE, res);
+
+ gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, packAlignment);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, packRowLength);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, packSkipRows);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, packSkipPixels);
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, packSwapBytes);
+
+ data = new TextureData(gl.getGLProfile(), internalFormat, width, height, border, fetchedFormat, GL.GL_UNSIGNED_BYTE,
+ false, false, false, res, null);
+
+ if (DEBUG) {
+ System.out.println("data.getPixelFormat() = " +
+ ((data.getPixelFormat() == GL.GL_RGB) ? "GL_RGB" : "GL_RGBA"));
+ }
+ }
+
+ write(data, file);
+ }
+
+ public static void write(TextureData data, File file) throws IOException, GLException {
+ for (Iterator iter = textureWriters.iterator(); iter.hasNext(); ) {
+ TextureWriter writer = (TextureWriter) iter.next();
+ if (writer.write(file, data)) {
+ return;
+ }
+ }
+
+ throw new IOException("No suitable texture writer found for "+file.getAbsolutePath());
+ }
+
+ //----------------------------------------------------------------------
+ // SPI support
+ //
+
+ /** Adds a TextureProvider to support reading of a new file
+ format. */
+ public static void addTextureProvider(TextureProvider provider) {
+ // Must always add at the front so the ImageIO provider is last,
+ // so we don't accidentally use it instead of a user's possibly
+ // more optimal provider
+ textureProviders.add(0, provider);
+ }
+
+ /** Adds a TextureWriter to support writing of a new file
+ format. */
+ public static void addTextureWriter(TextureWriter writer) {
+ // Must always add at the front so the ImageIO writer is last,
+ // so we don't accidentally use it instead of a user's possibly
+ // more optimal writer
+ textureWriters.add(0, writer);
+ }
+
+ //---------------------------------------------------------------------------
+ // Global disabling of texture rectangle extension
+ //
+
+ /** Toggles the use of the GL_ARB_texture_rectangle extension by the
+ TextureIO classes. By default, on hardware supporting this
+ extension, the TextureIO classes may use the
+ GL_ARB_texture_rectangle extension for non-power-of-two
+ textures. (If the hardware supports the
+ GL_ARB_texture_non_power_of_two extension, that one is
+ preferred.) In some situations, for example when writing
+ shaders, it is advantageous to force the texture target to
+ always be GL_TEXTURE_2D in order to have one version of the
+ shader, even at the expense of texture memory in the case where
+ NPOT textures are not supported. This method allows the use of
+ the GL_ARB_texture_rectangle extension to be turned off globally
+ for this purpose. The default is that the use of the extension
+ is enabled. */
+ public static void setTexRectEnabled(boolean enabled) {
+ texRectEnabled = enabled;
+ }
+
+ /** Indicates whether the GL_ARB_texture_rectangle extension is
+ allowed to be used for non-power-of-two textures; see {@link
+ #setTexRectEnabled setTexRectEnabled}. */
+ public static boolean isTexRectEnabled() {
+ return texRectEnabled;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static List/*<TextureProvider>*/ textureProviders = new ArrayList/*<TextureProvider>*/();
+ private static List/*<TextureWriter>*/ textureWriters = new ArrayList/*<TextureWriter>*/();
+
+ static {
+ // ImageIO provider, the fall-back, must be the first one added
+ if(GLProfile.isAWTJOGLAvailable()) {
+ try {
+ // Use reflection to avoid compile-time dependencies on AWT-related classes
+ TextureProvider provider = (TextureProvider)
+ Class.forName("com.jogamp.opengl.util.texture.spi.awt.IIOTextureProvider").newInstance();
+ addTextureProvider(provider);
+ } catch (Exception e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ // Other special-case providers
+ addTextureProvider(new DDSTextureProvider());
+ addTextureProvider(new SGITextureProvider());
+ addTextureProvider(new TGATextureProvider());
+
+ // ImageIO writer, the fall-back, must be the first one added
+ if(GLProfile.isAWTJOGLAvailable()) {
+ try {
+ // Use reflection to avoid compile-time dependencies on AWT-related classes
+ TextureWriter writer = (TextureWriter)
+ Class.forName("com.jogamp.opengl.util.texture.spi.awt.IIOTextureWriter").newInstance();
+ addTextureWriter(writer);
+ } catch (Exception e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ }
+ } catch (Error e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ // Other special-case writers
+ addTextureWriter(new DDSTextureWriter());
+ addTextureWriter(new SGITextureWriter());
+ addTextureWriter(new TGATextureWriter());
+ addTextureWriter(new NetPbmTextureWriter());
+ }
+
+ // Implementation methods
+ private static TextureData newTextureDataImpl(GLProfile glp, File file,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (file == null) {
+ throw new IOException("File was null");
+ }
+
+ fileSuffix = toLowerCase(fileSuffix);
+
+ for (Iterator iter = textureProviders.iterator(); iter.hasNext(); ) {
+ TextureProvider provider = (TextureProvider) iter.next();
+ TextureData data = provider.newTextureData(glp, file,
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ fileSuffix);
+ if (data != null) {
+ return data;
+ }
+ }
+
+ throw new IOException("No suitable reader for given file "+file.getAbsolutePath());
+ }
+
+ private static TextureData newTextureDataImpl(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (stream == null) {
+ throw new IOException("Stream was null");
+ }
+
+ fileSuffix = toLowerCase(fileSuffix);
+
+ // Note: use of BufferedInputStream works around 4764639/4892246
+ if (!(stream instanceof BufferedInputStream)) {
+ stream = new BufferedInputStream(stream);
+ }
+
+ for (Iterator iter = textureProviders.iterator(); iter.hasNext(); ) {
+ TextureProvider provider = (TextureProvider) iter.next();
+ TextureData data = provider.newTextureData(glp, stream,
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ fileSuffix);
+ if (data != null) {
+ return data;
+ }
+ }
+
+ throw new IOException("No suitable reader for given stream");
+ }
+
+ private static TextureData newTextureDataImpl(GLProfile glp, URL url,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (url == null) {
+ throw new IOException("URL was null");
+ }
+
+ fileSuffix = toLowerCase(fileSuffix);
+
+ for (Iterator iter = textureProviders.iterator(); iter.hasNext(); ) {
+ TextureProvider provider = (TextureProvider) iter.next();
+ TextureData data = provider.newTextureData(glp, url,
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ fileSuffix);
+ if (data != null) {
+ return data;
+ }
+ }
+
+ throw new IOException("No suitable reader for given URL "+url);
+ }
+
+ //----------------------------------------------------------------------
+ // DDS provider -- supports files only for now
+ static class DDSTextureProvider implements TextureProvider {
+ public TextureData newTextureData(GLProfile glp, File file,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (DDS.equals(fileSuffix) ||
+ DDS.equals(FileUtil.getFileSuffix(file))) {
+ DDSImage image = DDSImage.read(file);
+ return newTextureData(glp, image, internalFormat, pixelFormat, mipmap);
+ }
+
+ return null;
+ }
+
+ public TextureData newTextureData(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (DDS.equals(fileSuffix) ||
+ DDSImage.isDDSImage(stream)) {
+ byte[] data = StreamUtil.readAll2Array(stream);
+ ByteBuffer buf = ByteBuffer.wrap(data);
+ DDSImage image = DDSImage.read(buf);
+ return newTextureData(glp, image, internalFormat, pixelFormat, mipmap);
+ }
+
+ return null;
+ }
+
+ public TextureData newTextureData(GLProfile glp, URL url,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ InputStream stream = new BufferedInputStream(url.openStream());
+ try {
+ return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
+ } finally {
+ stream.close();
+ }
+ }
+
+ private TextureData newTextureData(GLProfile glp, final DDSImage image,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap) {
+ DDSImage.ImageInfo info = image.getMipMap(0);
+ if (pixelFormat == 0) {
+ switch (image.getPixelFormat()) {
+ case DDSImage.D3DFMT_R8G8B8:
+ pixelFormat = GL.GL_RGB;
+ break;
+ default:
+ pixelFormat = GL.GL_RGBA;
+ break;
+ }
+ }
+ if (info.isCompressed()) {
+ switch (info.getCompressionFormat()) {
+ case DDSImage.D3DFMT_DXT1:
+ internalFormat = GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+ break;
+ case DDSImage.D3DFMT_DXT3:
+ internalFormat = GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ break;
+ case DDSImage.D3DFMT_DXT5:
+ internalFormat = GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ break;
+ default:
+ throw new RuntimeException("Unsupported DDS compression format \"" +
+ DDSImage.getCompressionFormatName(info.getCompressionFormat()) + "\"");
+ }
+ }
+ if (internalFormat == 0) {
+ switch (image.getPixelFormat()) {
+ case DDSImage.D3DFMT_R8G8B8:
+ pixelFormat = GL.GL_RGB;
+ break;
+ default:
+ pixelFormat = GL.GL_RGBA;
+ break;
+ }
+ }
+ TextureData.Flusher flusher = new TextureData.Flusher() {
+ public void flush() {
+ image.close();
+ }
+ };
+ TextureData data;
+ if (mipmap && image.getNumMipMaps() > 0) {
+ Buffer[] mipmapData = new Buffer[image.getNumMipMaps()];
+ for (int i = 0; i < image.getNumMipMaps(); i++) {
+ mipmapData[i] = image.getMipMap(i).getData();
+ }
+ data = new TextureData(glp, internalFormat,
+ info.getWidth(),
+ info.getHeight(),
+ 0,
+ pixelFormat,
+ GL.GL_UNSIGNED_BYTE,
+ info.isCompressed(),
+ true,
+ mipmapData,
+ flusher);
+ } else {
+ // Fix this up for the end user because we can't generate
+ // mipmaps for compressed textures
+ mipmap = false;
+ data = new TextureData(glp, internalFormat,
+ info.getWidth(),
+ info.getHeight(),
+ 0,
+ pixelFormat,
+ GL.GL_UNSIGNED_BYTE,
+ mipmap,
+ info.isCompressed(),
+ true,
+ info.getData(),
+ flusher);
+ }
+ return data;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Base class for SGI RGB and TGA image providers
+ static abstract class StreamBasedTextureProvider implements TextureProvider {
+ public TextureData newTextureData(GLProfile glp, File file,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ InputStream inStream = new BufferedInputStream(new FileInputStream(file));
+ try {
+ // The SGIImage and TGAImage implementations use InputStreams
+ // anyway so there isn't much point in having a separate code
+ // path for files
+ return newTextureData(glp, inStream,
+ internalFormat,
+ pixelFormat,
+ mipmap,
+ ((fileSuffix != null) ? fileSuffix : FileUtil.getFileSuffix(file)));
+ } finally {
+ inStream.close();
+ }
+ }
+
+ public TextureData newTextureData(GLProfile glp, URL url,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ InputStream stream = new BufferedInputStream(url.openStream());
+ try {
+ return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
+ } finally {
+ stream.close();
+ }
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // SGI RGB image provider
+ static class SGITextureProvider extends StreamBasedTextureProvider {
+ public TextureData newTextureData(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (SGI.equals(fileSuffix) ||
+ SGI_RGB.equals(fileSuffix) ||
+ SGIImage.isSGIImage(stream)) {
+ SGIImage image = SGIImage.read(stream);
+ if (pixelFormat == 0) {
+ pixelFormat = image.getFormat();
+ }
+ if (internalFormat == 0) {
+ internalFormat = image.getFormat();
+ }
+ return new TextureData(glp, internalFormat,
+ image.getWidth(),
+ image.getHeight(),
+ 0,
+ pixelFormat,
+ GL.GL_UNSIGNED_BYTE,
+ mipmap,
+ false,
+ false,
+ ByteBuffer.wrap(image.getData()),
+ null);
+ }
+
+ return null;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // TGA (Targa) image provider
+ static class TGATextureProvider extends StreamBasedTextureProvider {
+ public TextureData newTextureData(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ if (TGA.equals(fileSuffix)) {
+ TGAImage image = TGAImage.read(stream);
+ if (pixelFormat == 0) {
+ pixelFormat = image.getGLFormat();
+ }
+ if (internalFormat == 0) {
+ GL gl = GLContext.getCurrentGL();
+ if(gl.isGL2()) {
+ internalFormat = GL.GL_RGBA8;
+ } else {
+ internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA:GL.GL_RGB;
+ }
+ }
+ return new TextureData(glp, internalFormat,
+ image.getWidth(),
+ image.getHeight(),
+ 0,
+ pixelFormat,
+ GL.GL_UNSIGNED_BYTE,
+ mipmap,
+ false,
+ false,
+ image.getData(),
+ null);
+ }
+
+ return null;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // DDS texture writer
+ //
+ static class DDSTextureWriter implements TextureWriter {
+ public boolean write(File file,
+ TextureData data) throws IOException {
+ if (DDS.equals(FileUtil.getFileSuffix(file))) {
+ // See whether the DDS writer can handle this TextureData
+ int pixelFormat = data.getPixelFormat();
+ int pixelType = data.getPixelType();
+ if (pixelType != GL.GL_BYTE &&
+ pixelType != GL.GL_UNSIGNED_BYTE) {
+ throw new IOException("DDS writer only supports byte / unsigned byte textures");
+ }
+
+ int d3dFormat = 0;
+ // FIXME: some of these are probably not completely correct and would require swizzling
+ switch (pixelFormat) {
+ case GL.GL_RGB: d3dFormat = DDSImage.D3DFMT_R8G8B8; break;
+ case GL.GL_RGBA: d3dFormat = DDSImage.D3DFMT_A8R8G8B8; break;
+ case GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT: d3dFormat = DDSImage.D3DFMT_DXT1; break;
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: throw new IOException("RGBA DXT1 not yet supported");
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: d3dFormat = DDSImage.D3DFMT_DXT3; break;
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: d3dFormat = DDSImage.D3DFMT_DXT5; break;
+ default: throw new IOException("Unsupported pixel format 0x" + Integer.toHexString(pixelFormat) + " by DDS writer");
+ }
+
+ ByteBuffer[] mipmaps = null;
+ if (data.getMipmapData() != null) {
+ mipmaps = new ByteBuffer[data.getMipmapData().length];
+ for (int i = 0; i < mipmaps.length; i++) {
+ mipmaps[i] = (ByteBuffer) data.getMipmapData()[i];
+ }
+ } else {
+ mipmaps = new ByteBuffer[] { (ByteBuffer) data.getBuffer() };
+ }
+
+ DDSImage image = DDSImage.createFromData(d3dFormat,
+ data.getWidth(),
+ data.getHeight(),
+ mipmaps);
+ image.write(file);
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // SGI (rgb) texture writer
+ //
+ static class SGITextureWriter implements TextureWriter {
+ public boolean write(File file,
+ TextureData data) throws IOException {
+ String fileSuffix = FileUtil.getFileSuffix(file);
+ if (SGI.equals(fileSuffix) ||
+ SGI_RGB.equals(fileSuffix)) {
+ // See whether the SGI writer can handle this TextureData
+ int pixelFormat = data.getPixelFormat();
+ int pixelType = data.getPixelType();
+ if ((pixelFormat == GL.GL_RGB ||
+ pixelFormat == GL.GL_RGBA) &&
+ (pixelType == GL.GL_BYTE ||
+ pixelType == GL.GL_UNSIGNED_BYTE)) {
+ ByteBuffer buf = ((data.getBuffer() != null) ?
+ (ByteBuffer) data.getBuffer() :
+ (ByteBuffer) data.getMipmapData()[0]);
+ byte[] bytes;
+ if (buf.hasArray()) {
+ bytes = buf.array();
+ } else {
+ buf.rewind();
+ bytes = new byte[buf.remaining()];
+ buf.get(bytes);
+ buf.rewind();
+ }
+
+ SGIImage image = SGIImage.createFromData(data.getWidth(),
+ data.getHeight(),
+ (pixelFormat == GL.GL_RGBA),
+ bytes);
+ image.write(file, false);
+ return true;
+ }
+
+ throw new IOException("SGI writer doesn't support this pixel format / type (only GL_RGB/A + bytes)");
+ }
+
+ return false;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // TGA (Targa) texture writer
+
+ static class TGATextureWriter implements TextureWriter {
+ public boolean write(File file,
+ TextureData data) throws IOException {
+ if (TGA.equals(FileUtil.getFileSuffix(file))) {
+ // See whether the TGA writer can handle this TextureData
+ int pixelFormat = data.getPixelFormat();
+ int pixelType = data.getPixelType();
+ if ((pixelFormat == GL.GL_RGB ||
+ pixelFormat == GL.GL_RGBA) &&
+ (pixelType == GL.GL_BYTE ||
+ pixelType == GL.GL_UNSIGNED_BYTE)) {
+ ByteBuffer buf = ((data.getBuffer() != null) ?
+ (ByteBuffer) data.getBuffer() :
+ (ByteBuffer) data.getMipmapData()[0]);
+ // Must reverse order of red and blue channels to get correct results
+ int skip = ((pixelFormat == GL.GL_RGB) ? 3 : 4);
+ for (int i = 0; i < buf.remaining(); i += skip) {
+ byte red = buf.get(i + 0);
+ byte blue = buf.get(i + 2);
+ buf.put(i + 0, blue);
+ buf.put(i + 2, red);
+ }
+
+ TGAImage image = TGAImage.createFromData(data.getWidth(),
+ data.getHeight(),
+ (pixelFormat == GL.GL_RGBA),
+ false,
+ ((data.getBuffer() != null) ?
+ (ByteBuffer) data.getBuffer() :
+ (ByteBuffer) data.getMipmapData()[0]));
+ image.write(file);
+ return true;
+ }
+
+ throw new IOException("TGA writer doesn't support this pixel format / type (only GL_RGB/A + bytes)");
+ }
+
+ return false;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Helper routines
+ //
+
+ private static int glGetInteger(int pname) {
+ int[] tmp = new int[1];
+ GL gl = GLContext.getCurrentGL();
+ gl.glGetIntegerv(pname, tmp, 0);
+ return tmp[0];
+ }
+
+ private static int glGetTexLevelParameteri(GL2 gl, int target, int level, int pname) {
+ int[] tmp = new int[1];
+ gl.glGetTexLevelParameteriv(target, 0, pname, tmp, 0);
+ return tmp[0];
+ }
+
+ private static String toLowerCase(String arg) {
+ if (arg == null) {
+ return null;
+ }
+
+ return arg.toLowerCase();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java b/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java
new file mode 100755
index 000000000..39ec74b97
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.util.texture.awt;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Transparency;
+import java.awt.color.*;
+import java.awt.image.*;
+import java.nio.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.texture.*;
+
+public class AWTTextureData extends TextureData {
+ // Mechanism for lazily converting input BufferedImages with custom
+ // ColorModels to standard ones for uploading to OpenGL, as well as
+ // backing off from the optimizations of hoping that either
+ // GL_EXT_abgr or OpenGL 1.2 are present
+ private BufferedImage imageForLazyCustomConversion;
+ private boolean expectingEXTABGR;
+ private boolean expectingGL12;
+
+ private static final ColorModel rgbaColorModel =
+ new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
+ new int[] {8, 8, 8, 8}, true, true,
+ Transparency.TRANSLUCENT,
+ DataBuffer.TYPE_BYTE);
+ private static final ColorModel rgbColorModel =
+ new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
+ new int[] {8, 8, 8, 0}, false, false,
+ Transparency.OPAQUE,
+ DataBuffer.TYPE_BYTE);
+
+
+ /**
+ * Constructs a new TextureData object with the specified parameters
+ * and data contained in the given BufferedImage. The resulting
+ * TextureData "wraps" the contents of the BufferedImage, so if a
+ * modification is made to the BufferedImage between the time the
+ * TextureData is constructed and when a Texture is made from the
+ * TextureData, that modification will be visible in the resulting
+ * Texture.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param internalFormat the OpenGL internal format for the
+ * resulting texture; may be 0, in which case
+ * it is inferred from the image's type
+ * @param pixelFormat the OpenGL internal format for the
+ * resulting texture; may be 0, in which case
+ * it is inferred from the image's type (note:
+ * this argument is currently always ignored)
+ * @param mipmap indicates whether mipmaps should be
+ * autogenerated (using GLU) for the resulting
+ * texture
+ * @param image the image containing the texture data
+ */
+ public AWTTextureData(GLProfile glp,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ BufferedImage image) {
+ super(glp);
+ if (internalFormat == 0) {
+ this.internalFormat = image.getColorModel().hasAlpha() ? GL.GL_RGBA : GL.GL_RGB;
+ } else {
+ this.internalFormat = internalFormat;
+ }
+ createFromImage(glp, image);
+ this.mipmap = mipmap;
+ if (buffer != null) {
+ estimatedMemorySize = estimatedMemorySize(buffer);
+ } else {
+ // In the lazy custom conversion case we don't yet have a buffer
+ if (imageForLazyCustomConversion != null) {
+ estimatedMemorySize = estimatedMemorySize(wrapImageDataBuffer(imageForLazyCustomConversion));
+ }
+ }
+ }
+
+ /** Returns the intended OpenGL pixel format of the texture data. */
+ public int getPixelFormat() {
+ if (imageForLazyCustomConversion != null) {
+ if (!((expectingEXTABGR && haveEXTABGR) ||
+ (expectingGL12 && haveGL12))) {
+ revertPixelFormatAndType();
+ }
+ }
+ return pixelFormat;
+ }
+ /** Returns the intended OpenGL pixel type of the texture data. */
+ public int getPixelType() {
+ if (imageForLazyCustomConversion != null) {
+ if (!((expectingEXTABGR && haveEXTABGR) ||
+ (expectingGL12 && haveGL12))) {
+ revertPixelFormatAndType();
+ }
+ }
+ return pixelType;
+ }
+
+ /** Returns the texture data, or null if it is specified as a set of mipmaps. */
+ public Buffer getBuffer() {
+ if (imageForLazyCustomConversion != null) {
+ if (!((expectingEXTABGR && haveEXTABGR) ||
+ (expectingGL12 && haveGL12))) {
+ revertPixelFormatAndType();
+ // Must present the illusion to the end user that we are simply
+ // wrapping the input BufferedImage
+ createFromCustom(imageForLazyCustomConversion);
+ }
+ }
+ return buffer;
+ }
+
+ private void createFromImage(GLProfile glp, BufferedImage image) {
+ pixelType = 0; // Determine from image
+ mustFlipVertically = true;
+
+ width = image.getWidth();
+ height = image.getHeight();
+
+ int scanlineStride;
+
+ SampleModel sm = image.getRaster().getSampleModel();
+ if (sm instanceof SinglePixelPackedSampleModel) {
+ scanlineStride =
+ ((SinglePixelPackedSampleModel)sm).getScanlineStride();
+ } else if (sm instanceof MultiPixelPackedSampleModel) {
+ scanlineStride =
+ ((MultiPixelPackedSampleModel)sm).getScanlineStride();
+ } else if (sm instanceof ComponentSampleModel) {
+ scanlineStride =
+ ((ComponentSampleModel)sm).getScanlineStride();
+ } else {
+ // This will only happen for TYPE_CUSTOM anyway
+ setupLazyCustomConversion(image);
+ return;
+ }
+
+ width = image.getWidth();
+ height = image.getHeight();
+
+ if (glp.isGL2GL3()) {
+ switch (image.getType()) {
+ case BufferedImage.TYPE_INT_RGB:
+ pixelFormat = GL2GL3.GL_BGRA;
+ pixelType = GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV;
+ rowLength = scanlineStride;
+ alignment = 4;
+ expectingGL12 = true;
+ setupLazyCustomConversion(image);
+ break;
+ case BufferedImage.TYPE_INT_ARGB_PRE:
+ pixelFormat = GL2GL3.GL_BGRA;
+ pixelType = GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV;
+ rowLength = scanlineStride;
+ alignment = 4;
+ expectingGL12 = true;
+ setupLazyCustomConversion(image);
+ break;
+ case BufferedImage.TYPE_INT_BGR:
+ pixelFormat = GL.GL_RGBA;
+ pixelType = GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV;
+ rowLength = scanlineStride;
+ alignment = 4;
+ expectingGL12 = true;
+ setupLazyCustomConversion(image);
+ break;
+ case BufferedImage.TYPE_3BYTE_BGR:
+ {
+ // we can pass the image data directly to OpenGL only if
+ // we have an integral number of pixels in each scanline
+ if ((scanlineStride % 3) == 0) {
+ pixelFormat = GL2GL3.GL_BGR;
+ pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride / 3;
+ alignment = 1;
+ } else {
+ setupLazyCustomConversion(image);
+ return;
+ }
+ }
+ break;
+ case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+ {
+ // we can pass the image data directly to OpenGL only if
+ // we have an integral number of pixels in each scanline
+ // and only if the GL_EXT_abgr extension is present
+
+ // NOTE: disabling this code path for now as it appears it's
+ // buggy at least on some NVidia drivers and doesn't perform
+ // the necessary byte swapping (FIXME: needs more
+ // investigation)
+ if ((scanlineStride % 4) == 0 && glp.isGL2() && false) {
+ pixelFormat = GL2.GL_ABGR_EXT;
+ pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride / 4;
+ alignment = 4;
+
+ // Store a reference to the original image for later in
+ // case it turns out that we don't have GL_EXT_abgr at the
+ // time we're going to do the texture upload to OpenGL
+ setupLazyCustomConversion(image);
+ expectingEXTABGR = true;
+ break;
+ } else {
+ setupLazyCustomConversion(image);
+ return;
+ }
+ }
+ case BufferedImage.TYPE_USHORT_565_RGB:
+ pixelFormat = GL.GL_RGB;
+ pixelType = GL.GL_UNSIGNED_SHORT_5_6_5;
+ rowLength = scanlineStride;
+ alignment = 2;
+ expectingGL12 = true;
+ setupLazyCustomConversion(image);
+ break;
+ case BufferedImage.TYPE_USHORT_555_RGB:
+ pixelFormat = GL2GL3.GL_BGRA;
+ pixelType = GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ rowLength = scanlineStride;
+ alignment = 2;
+ expectingGL12 = true;
+ setupLazyCustomConversion(image);
+ break;
+ case BufferedImage.TYPE_BYTE_GRAY:
+ pixelFormat = GL.GL_LUMINANCE;
+ pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride;
+ alignment = 1;
+ break;
+ case BufferedImage.TYPE_USHORT_GRAY:
+ pixelFormat = GL.GL_LUMINANCE;
+ pixelType = GL.GL_UNSIGNED_SHORT;
+ rowLength = scanlineStride;
+ alignment = 2;
+ break;
+ // Note: TYPE_INT_ARGB and TYPE_4BYTE_ABGR images go down the
+ // custom code path to satisfy the invariant that images with an
+ // alpha channel always go down with premultiplied alpha.
+ case BufferedImage.TYPE_INT_ARGB:
+ case BufferedImage.TYPE_4BYTE_ABGR:
+ case BufferedImage.TYPE_BYTE_BINARY:
+ case BufferedImage.TYPE_BYTE_INDEXED:
+ case BufferedImage.TYPE_CUSTOM:
+ default:
+ ColorModel cm = image.getColorModel();
+ if (cm.equals(rgbColorModel)) {
+ pixelFormat = GL.GL_RGB;
+ pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride / 3;
+ alignment = 1;
+ } else if (cm.equals(rgbaColorModel)) {
+ pixelFormat = GL.GL_RGBA;
+ pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride / 4; // FIXME: correct?
+ alignment = 4;
+ } else {
+ setupLazyCustomConversion(image);
+ return;
+ }
+ break;
+ }
+ } else {
+ switch (image.getType()) {
+ case BufferedImage.TYPE_INT_RGB:
+ pixelFormat = GL.GL_RGB;
+ pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride;
+ alignment = 3;
+ expectingGL12 = true;
+ setupLazyCustomConversion(image);
+ break;
+ case BufferedImage.TYPE_INT_ARGB_PRE:
+ throw new GLException("INT_ARGB_PRE n.a.");
+ case BufferedImage.TYPE_INT_BGR:
+ throw new GLException("INT_BGR n.a.");
+ case BufferedImage.TYPE_3BYTE_BGR:
+ throw new GLException("INT_BGR n.a.");
+ case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+ throw new GLException("INT_BGR n.a.");
+ case BufferedImage.TYPE_USHORT_565_RGB:
+ pixelFormat = GL.GL_RGB;
+ pixelType = GL.GL_UNSIGNED_SHORT_5_6_5;
+ rowLength = scanlineStride;
+ alignment = 2;
+ expectingGL12 = true;
+ setupLazyCustomConversion(image);
+ break;
+ case BufferedImage.TYPE_USHORT_555_RGB:
+ pixelFormat = GL.GL_RGBA;
+ pixelType = GL.GL_UNSIGNED_SHORT_5_5_5_1;
+ rowLength = scanlineStride;
+ alignment = 2;
+ expectingGL12 = true;
+ setupLazyCustomConversion(image);
+ break;
+ case BufferedImage.TYPE_BYTE_GRAY:
+ pixelFormat = GL.GL_LUMINANCE;
+ pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride;
+ alignment = 1;
+ break;
+ case BufferedImage.TYPE_USHORT_GRAY:
+ throw new GLException("USHORT_GRAY n.a.");
+ // Note: TYPE_INT_ARGB and TYPE_4BYTE_ABGR images go down the
+ // custom code path to satisfy the invariant that images with an
+ // alpha channel always go down with premultiplied alpha.
+ case BufferedImage.TYPE_INT_ARGB:
+ case BufferedImage.TYPE_4BYTE_ABGR:
+ case BufferedImage.TYPE_BYTE_BINARY:
+ case BufferedImage.TYPE_BYTE_INDEXED:
+ case BufferedImage.TYPE_CUSTOM:
+ default:
+ ColorModel cm = image.getColorModel();
+ if (cm.equals(rgbColorModel)) {
+ pixelFormat = GL.GL_RGB;
+ pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride / 3;
+ alignment = 1;
+ } else if (cm.equals(rgbaColorModel)) {
+ pixelFormat = GL.GL_RGBA;
+ pixelType = GL.GL_UNSIGNED_BYTE;
+ rowLength = scanlineStride / 4; // FIXME: correct?
+ alignment = 4;
+ } else {
+ setupLazyCustomConversion(image);
+ return;
+ }
+ break;
+ }
+ }
+
+ createNIOBufferFromImage(image);
+ }
+
+ private void setupLazyCustomConversion(BufferedImage image) {
+ imageForLazyCustomConversion = image;
+ boolean hasAlpha = image.getColorModel().hasAlpha();
+ if (pixelFormat == 0) {
+ pixelFormat = hasAlpha ? GL.GL_RGBA : GL.GL_RGB;
+ }
+ alignment = 1; // FIXME: do we need better?
+ rowLength = width; // FIXME: correct in all cases?
+
+ // Allow previously-selected pixelType (if any) to override that
+ // we can infer from the DataBuffer
+ DataBuffer data = image.getRaster().getDataBuffer();
+ if (data instanceof DataBufferByte || isPackedInt(image)) {
+ // Don't use GL_UNSIGNED_INT for BufferedImage packed int images
+ if (pixelType == 0) pixelType = GL.GL_UNSIGNED_BYTE;
+ } else if (data instanceof DataBufferDouble) {
+ throw new RuntimeException("DataBufferDouble rasters not supported by OpenGL");
+ } else if (data instanceof DataBufferFloat) {
+ if (pixelType == 0) pixelType = GL.GL_FLOAT;
+ } else if (data instanceof DataBufferInt) {
+ // FIXME: should we support signed ints?
+ if (pixelType == 0) pixelType = GL2GL3.GL_UNSIGNED_INT;
+ } else if (data instanceof DataBufferShort) {
+ if (pixelType == 0) pixelType = GL.GL_SHORT;
+ } else if (data instanceof DataBufferUShort) {
+ if (pixelType == 0) pixelType = GL.GL_UNSIGNED_SHORT;
+ } else {
+ throw new RuntimeException("Unexpected DataBuffer type?");
+ }
+ }
+
+ private void createFromCustom(BufferedImage image) {
+ int width = image.getWidth();
+ int height = image.getHeight();
+
+ // create a temporary image that is compatible with OpenGL
+ boolean hasAlpha = image.getColorModel().hasAlpha();
+ ColorModel cm = null;
+ int dataBufferType = image.getRaster().getDataBuffer().getDataType();
+ // Don't use integer components for packed int images
+ if (isPackedInt(image)) {
+ dataBufferType = DataBuffer.TYPE_BYTE;
+ }
+ if (dataBufferType == DataBuffer.TYPE_BYTE) {
+ cm = hasAlpha ? rgbaColorModel : rgbColorModel;
+ } else {
+ if (hasAlpha) {
+ cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
+ null, true, true,
+ Transparency.TRANSLUCENT,
+ dataBufferType);
+ } else {
+ cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
+ null, false, false,
+ Transparency.OPAQUE,
+ dataBufferType);
+ }
+ }
+
+ boolean premult = cm.isAlphaPremultiplied();
+ WritableRaster raster =
+ cm.createCompatibleWritableRaster(width, height);
+ BufferedImage texImage = new BufferedImage(cm, raster, premult, null);
+
+ // copy the source image into the temporary image
+ Graphics2D g = texImage.createGraphics();
+ g.setComposite(AlphaComposite.Src);
+ g.drawImage(image, 0, 0, null);
+ g.dispose();
+
+ // Wrap the buffer from the temporary image
+ createNIOBufferFromImage(texImage);
+ }
+
+ private boolean isPackedInt(BufferedImage image) {
+ int imgType = image.getType();
+ return (imgType == BufferedImage.TYPE_INT_RGB ||
+ imgType == BufferedImage.TYPE_INT_BGR ||
+ imgType == BufferedImage.TYPE_INT_ARGB ||
+ imgType == BufferedImage.TYPE_INT_ARGB_PRE);
+ }
+
+ private void revertPixelFormatAndType() {
+ // Knowing we don't have e.g. OpenGL 1.2 functionality available,
+ // and knowing we're in the process of doing the fallback code
+ // path, re-infer a vanilla pixel format and type compatible with
+ // OpenGL 1.1
+ pixelFormat = 0;
+ pixelType = 0;
+ setupLazyCustomConversion(imageForLazyCustomConversion);
+ }
+
+ private void createNIOBufferFromImage(BufferedImage image) {
+ buffer = wrapImageDataBuffer(image);
+ }
+
+ private Buffer wrapImageDataBuffer(BufferedImage image) {
+ //
+ // Note: Grabbing the DataBuffer will defeat Java2D's image
+ // management mechanism (as of JDK 5/6, at least). This shouldn't
+ // be a problem for most JOGL apps, but those that try to upload
+ // the image into an OpenGL texture and then use the same image in
+ // Java2D rendering might find the 2D rendering is not as fast as
+ // it could be.
+ //
+
+ DataBuffer data = image.getRaster().getDataBuffer();
+ if (data instanceof DataBufferByte) {
+ return ByteBuffer.wrap(((DataBufferByte) data).getData());
+ } else if (data instanceof DataBufferDouble) {
+ throw new RuntimeException("DataBufferDouble rasters not supported by OpenGL");
+ } else if (data instanceof DataBufferFloat) {
+ return FloatBuffer.wrap(((DataBufferFloat) data).getData());
+ } else if (data instanceof DataBufferInt) {
+ return IntBuffer.wrap(((DataBufferInt) data).getData());
+ } else if (data instanceof DataBufferShort) {
+ return ShortBuffer.wrap(((DataBufferShort) data).getData());
+ } else if (data instanceof DataBufferUShort) {
+ return ShortBuffer.wrap(((DataBufferUShort) data).getData());
+ } else {
+ throw new RuntimeException("Unexpected DataBuffer type?");
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureIO.java
new file mode 100644
index 000000000..fdd1365f7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureIO.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.awt;
+
+import java.awt.image.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.texture.*;
+
+public class AWTTextureIO extends TextureIO {
+ /**
+ * Creates a TextureData from the given BufferedImage. Does no
+ * OpenGL work.
+ * We assume a desktop GLProfile GL2GL3, otherwise use the other factory.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param image the BufferedImage containing the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture by autogenerating them
+ * @return the texture data from the image
+ *
+ * @see #newTextureData(GLProfile, BufferedImage, boolean)
+ */
+ public static TextureData newTextureData(GLProfile glp, BufferedImage image,
+ boolean mipmap) {
+ return newTextureDataImpl(glp, image, 0, 0, mipmap);
+ }
+
+ /**
+ * Creates a TextureData from the given BufferedImage, using the
+ * specified OpenGL internal format and pixel format for the texture
+ * which will eventually result. The internalFormat and pixelFormat
+ * must be specified and may not be zero; to use default values, use
+ * the variant of this method which does not take these
+ * arguments. Does no OpenGL work.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param image the BufferedImage containing the texture data
+ * @param internalFormat the OpenGL internal format of the texture
+ * which will eventually result from the TextureData
+ * @param pixelFormat the OpenGL pixel format of the texture
+ * which will eventually result from the TextureData
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ * @return the texture data from the image
+ * @throws IllegalArgumentException if either internalFormat or
+ * pixelFormat was 0
+ */
+ public static TextureData newTextureData(GLProfile glp, BufferedImage image,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap) throws IllegalArgumentException {
+ if ((internalFormat == 0) || (pixelFormat == 0)) {
+ throw new IllegalArgumentException("internalFormat and pixelFormat must be non-zero");
+ }
+
+ return newTextureDataImpl(glp, image, internalFormat, pixelFormat, mipmap);
+ }
+
+ /**
+ * Creates an OpenGL texture object from the specified BufferedImage
+ * using the current OpenGL context.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param image the BufferedImage from which to read the texture data
+ * @param mipmap whether mipmaps should be produced for this
+ * texture by autogenerating them
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ */
+ public static Texture newTexture(GLProfile glp, BufferedImage image, boolean mipmap) throws GLException {
+ TextureData data = newTextureData(glp, image, mipmap);
+ Texture texture = newTexture(data);
+ data.flush();
+ return texture;
+ }
+
+ private static TextureData newTextureDataImpl(GLProfile glp,
+ BufferedImage image,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap) {
+ return new AWTTextureData(glp, internalFormat, pixelFormat, mipmap, image);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java.javame_cdc_fp b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java.javame_cdc_fp
new file mode 100755
index 000000000..b18991dfc
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java.javame_cdc_fp
@@ -0,0 +1,889 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi;
+
+import java.io.*;
+import java.nio.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.texture.*;
+
+/** A reader and writer for DirectDraw Surface (.dds) files, which are
+ used to describe textures. These files can contain multiple mipmap
+ levels in one file. This class is currently minimal and does not
+ support all of the possible file formats. */
+
+public class DDSImage {
+
+ /** Simple class describing images and data; does not encapsulate
+ image format information. User is responsible for transmitting
+ that information in another way. */
+
+ public static class ImageInfo {
+ private ByteBuffer data;
+ private int width;
+ private int height;
+ private boolean isCompressed;
+ private int compressionFormat;
+
+ public ImageInfo(ByteBuffer data, int width, int height, boolean compressed, int compressionFormat) {
+ this.data = data; this.width = width; this.height = height;
+ this.isCompressed = compressed; this.compressionFormat = compressionFormat;
+ }
+ public int getWidth() { return width; }
+ public int getHeight() { return height; }
+ public ByteBuffer getData() { return data; }
+ public boolean isCompressed() { return isCompressed; }
+ public int getCompressionFormat() {
+ if (!isCompressed())
+ throw new RuntimeException("Should not call unless compressed");
+ return compressionFormat;
+ }
+ }
+
+ private ByteBuffer buf;
+ private Header header;
+
+ //
+ // Selected bits in header flags
+ //
+
+ public static final int DDSD_CAPS = 0x00000001; // Capacities are valid
+ public static final int DDSD_HEIGHT = 0x00000002; // Height is valid
+ public static final int DDSD_WIDTH = 0x00000004; // Width is valid
+ public static final int DDSD_PITCH = 0x00000008; // Pitch is valid
+ public static final int DDSD_BACKBUFFERCOUNT = 0x00000020; // Back buffer count is valid
+ public static final int DDSD_ZBUFFERBITDEPTH = 0x00000040; // Z-buffer bit depth is valid (shouldn't be used in DDSURFACEDESC2)
+ public static final int DDSD_ALPHABITDEPTH = 0x00000080; // Alpha bit depth is valid
+ public static final int DDSD_LPSURFACE = 0x00000800; // lpSurface is valid
+ public static final int DDSD_PIXELFORMAT = 0x00001000; // ddpfPixelFormat is valid
+ public static final int DDSD_MIPMAPCOUNT = 0x00020000; // Mip map count is valid
+ public static final int DDSD_LINEARSIZE = 0x00080000; // dwLinearSize is valid
+ public static final int DDSD_DEPTH = 0x00800000; // dwDepth is valid
+
+ public static final int DDPF_ALPHAPIXELS = 0x00000001; // Alpha channel is present
+ public static final int DDPF_ALPHA = 0x00000002; // Only contains alpha information
+ public static final int DDPF_FOURCC = 0x00000004; // FourCC code is valid
+ public static final int DDPF_PALETTEINDEXED4 = 0x00000008; // Surface is 4-bit color indexed
+ public static final int DDPF_PALETTEINDEXEDTO8 = 0x00000010; // Surface is indexed into a palette which stores indices
+ // into the destination surface's 8-bit palette
+ public static final int DDPF_PALETTEINDEXED8 = 0x00000020; // Surface is 8-bit color indexed
+ public static final int DDPF_RGB = 0x00000040; // RGB data is present
+ public static final int DDPF_COMPRESSED = 0x00000080; // Surface will accept pixel data in the format specified
+ // and compress it during the write
+ public static final int DDPF_RGBTOYUV = 0x00000100; // Surface will accept RGB data and translate it during
+ // the write to YUV data. The format of the data to be written
+ // will be contained in the pixel format structure. The DDPF_RGB
+ // flag will be set.
+ public static final int DDPF_YUV = 0x00000200; // Pixel format is YUV - YUV data in pixel format struct is valid
+ public static final int DDPF_ZBUFFER = 0x00000400; // Pixel format is a z buffer only surface
+ public static final int DDPF_PALETTEINDEXED1 = 0x00000800; // Surface is 1-bit color indexed
+ public static final int DDPF_PALETTEINDEXED2 = 0x00001000; // Surface is 2-bit color indexed
+ public static final int DDPF_ZPIXELS = 0x00002000; // Surface contains Z information in the pixels
+
+ // Selected bits in DDS capabilities flags
+ public static final int DDSCAPS_TEXTURE = 0x00001000; // Can be used as a texture
+ public static final int DDSCAPS_MIPMAP = 0x00400000; // Is one level of a mip-map
+ public static final int DDSCAPS_COMPLEX = 0x00000008; // Complex surface structure, such as a cube map
+
+ // Selected bits in DDS extended capabilities flags
+ public static final int DDSCAPS2_CUBEMAP = 0x00000200;
+ public static final int DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400;
+ public static final int DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800;
+ public static final int DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000;
+ public static final int DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000;
+ public static final int DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000;
+ public static final int DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000;
+
+ // Known pixel formats
+ public static final int D3DFMT_UNKNOWN = 0;
+ public static final int D3DFMT_R8G8B8 = 20;
+ public static final int D3DFMT_A8R8G8B8 = 21;
+ public static final int D3DFMT_X8R8G8B8 = 22;
+ // The following are also valid FourCC codes
+ public static final int D3DFMT_DXT1 = 0x31545844;
+ public static final int D3DFMT_DXT2 = 0x32545844;
+ public static final int D3DFMT_DXT3 = 0x33545844;
+ public static final int D3DFMT_DXT4 = 0x34545844;
+ public static final int D3DFMT_DXT5 = 0x35545844;
+
+ /** Reads a DirectDraw surface from the specified file name,
+ returning the resulting DDSImage.
+
+ @param filename File name
+ @return DDS image object
+ @throws java.io.IOException if an I/O exception occurred
+ */
+ public static DDSImage read(String filename) throws IOException {
+ return read(new File(filename));
+ }
+
+ /** Reads a DirectDraw surface from the specified file, returning
+ the resulting DDSImage.
+
+ @param file File object
+ @return DDS image object
+ @throws java.io.IOException if an I/O exception occurred
+ */
+ public static DDSImage read(File file) throws IOException {
+ DDSImage image = new DDSImage();
+ image.readFromFile(file);
+ return image;
+ }
+
+ /** Reads a DirectDraw surface from the specified InputStream, returning
+ the resulting DDSImage.
+
+ @param input Input stream
+ @return DDS image object
+ @throws java.io.IOException if an I/O exception occurred
+ */
+ public static DDSImage read(InputStream input) throws IOException {
+ DDSImage image = new DDSImage();
+ image.readFromStream(input);
+ return image;
+ }
+
+ /** Closes open files and resources associated with the open
+ DDSImage. No other methods may be called on this object once
+ this is called. */
+ public void close() {
+ }
+
+ /**
+ * Creates a new DDSImage from data supplied by the user. The
+ * resulting DDSImage can be written to disk using the write()
+ * method.
+ *
+ * @param d3dFormat the D3DFMT_ constant describing the data; it is
+ * assumed that it is packed tightly
+ * @param width the width in pixels of the topmost mipmap image
+ * @param height the height in pixels of the topmost mipmap image
+ * @param mipmapData the data for each mipmap level of the resulting
+ * DDSImage; either only one mipmap level should
+ * be specified, or they all must be
+ * @throws IllegalArgumentException if the data does not match the
+ * specified arguments
+ * @return DDS image object
+ */
+ public static DDSImage createFromData(int d3dFormat,
+ int width,
+ int height,
+ ByteBuffer[] mipmapData) throws IllegalArgumentException {
+ DDSImage image = new DDSImage();
+ image.initFromData(d3dFormat, width, height, mipmapData);
+ return image;
+ }
+
+ /** Determines from the magic number whether the given InputStream
+ points to a DDS image. The given InputStream must return true
+ from markSupported() and support a minimum of four bytes of
+ read-ahead.
+
+ @param in Stream to check
+ @return true if input stream is DDS image or false otherwise
+ @throws java.io.IOException if an I/O exception occurred
+ */
+ public static boolean isDDSImage(InputStream in) throws IOException {
+ if (!(in instanceof BufferedInputStream)) {
+ in = new BufferedInputStream(in);
+ }
+ if (!in.markSupported()) {
+ throw new IOException("Can not test non-destructively whether given InputStream is a DDS image");
+ }
+ in.mark(4);
+ int magic = 0;
+ for (int i = 0; i < 4; i++) {
+ int tmp = in.read();
+ if (tmp < 0) {
+ in.reset();
+ return false;
+ }
+ magic = ((magic >>> 8) | (tmp << 24));
+ }
+ in.reset();
+ return (magic == MAGIC);
+ }
+
+ /**
+ * Writes this DDSImage to the specified file name.
+ * @param filename File name to write to
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public void write(String filename) throws IOException {
+ write(new File(filename));
+ }
+
+ /**
+ * Writes this DDSImage to the specified file name.
+ * @param file File object to write to
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public void write(File file) throws IOException {
+ LEDataOutputStream output =
+ new LEDataOutputStream(new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))));
+ header.write(output);
+ output.write(buf.array());
+ output.close();
+ }
+
+ /** Test for presence/absence of surface description flags (DDSD_*)
+ * @param flag DDSD_* flags set to test
+ * @return true if flag present or false otherwise
+ */
+ public boolean isSurfaceDescFlagSet(int flag) {
+ return ((header.flags & flag) != 0);
+ }
+
+ /** Test for presence/absence of pixel format flags (DDPF_*) */
+ public boolean isPixelFormatFlagSet(int flag) {
+ return ((header.pfFlags & flag) != 0);
+ }
+
+ /** Gets the pixel format of this texture (D3DFMT_*) based on some
+ heuristics. Returns D3DFMT_UNKNOWN if could not recognize the
+ pixel format. */
+ public int getPixelFormat() {
+ if (isCompressed()) {
+ return getCompressionFormat();
+ } else if (isPixelFormatFlagSet(DDPF_RGB)) {
+ if (isPixelFormatFlagSet(DDPF_ALPHAPIXELS)) {
+ if (getDepth() == 32 &&
+ header.pfRBitMask == 0x00FF0000 &&
+ header.pfGBitMask == 0x0000FF00 &&
+ header.pfBBitMask == 0x000000FF &&
+ header.pfABitMask == 0xFF000000) {
+ return D3DFMT_A8R8G8B8;
+ }
+ } else {
+ if (getDepth() == 24 &&
+ header.pfRBitMask == 0x00FF0000 &&
+ header.pfGBitMask == 0x0000FF00 &&
+ header.pfBBitMask == 0x000000FF) {
+ return D3DFMT_R8G8B8;
+ } else if (getDepth() == 32 &&
+ header.pfRBitMask == 0x00FF0000 &&
+ header.pfGBitMask == 0x0000FF00 &&
+ header.pfBBitMask == 0x000000FF) {
+ return D3DFMT_X8R8G8B8;
+ }
+ }
+ }
+
+ return D3DFMT_UNKNOWN;
+ }
+
+ /**
+ * Indicates whether this texture is cubemap
+ * @return true if cubemap or false otherwise
+ */
+ public boolean isCubemap() {
+ return ((header.ddsCaps1 & DDSCAPS_COMPLEX) != 0) && ((header.ddsCaps2 & DDSCAPS2_CUBEMAP) != 0);
+ }
+
+ /**
+ * Indicates whethe this cubemap side present
+ * @param side Side to test
+ * @return true if side present or false otherwise
+ */
+ public boolean isCubemapSidePresent(int side) {
+ return isCubemap() && (header.ddsCaps2 & side) != 0;
+ }
+
+ /** Indicates whether this texture is compressed. */
+ public boolean isCompressed() {
+ return (isPixelFormatFlagSet(DDPF_FOURCC));
+ }
+
+ /** If this surface is compressed, returns the kind of compression
+ used (DXT1..DXT5). */
+ public int getCompressionFormat() {
+ return header.pfFourCC;
+ }
+
+ /** Width of the texture (or the top-most mipmap if mipmaps are
+ present) */
+ public int getWidth() {
+ return header.width;
+ }
+
+ /** Height of the texture (or the top-most mipmap if mipmaps are
+ present) */
+ public int getHeight() {
+ return header.height;
+ }
+
+ /** Total number of bits per pixel. Only valid if DDPF_RGB is
+ present. For A8R8G8B8, would be 32. */
+ public int getDepth() {
+ return header.pfRGBBitCount;
+ }
+
+ /** Number of mip maps in the texture */
+ public int getNumMipMaps() {
+ if (!isSurfaceDescFlagSet(DDSD_MIPMAPCOUNT)) {
+ return 0;
+ }
+ return header.mipMapCountOrAux;
+ }
+
+ /** Gets the <i>i</i>th mipmap data (0..getNumMipMaps() - 1)
+ * @param map Mipmap index
+ * @return Image object
+ */
+ public ImageInfo getMipMap(int map) {
+ return getMipMap( 0, map );
+ }
+
+ /**
+ * Gets the <i>i</i>th mipmap data (0..getNumMipMaps() - 1)
+ * @param side Cubemap side or 0 for 2D texture
+ * @param map Mipmap index
+ * @return Image object
+ */
+ public ImageInfo getMipMap(int side, int map) {
+ if (!isCubemap() && (side != 0)) {
+ throw new RuntimeException( "Illegal side for 2D texture: " + side );
+ }
+ if (isCubemap() && !isCubemapSidePresent(side)) {
+ throw new RuntimeException( "Illegal side, side not present: " + side );
+ }
+ if (getNumMipMaps() > 0 &&
+ ((map < 0) || (map >= getNumMipMaps()))) {
+ throw new RuntimeException("Illegal mipmap number " + map + " (0.." + (getNumMipMaps() - 1) + ")");
+ }
+
+ // Figure out how far to seek
+ int seek = 0;
+ if (isCubemap()) {
+ seek += sideShiftInBytes(side);
+ }
+ for (int i = 0; i < map; i++) {
+ seek += mipMapSizeInBytes(i);
+ }
+ buf.limit(seek + mipMapSizeInBytes(map));
+ buf.position(seek);
+ ByteBuffer next = buf.slice();
+ buf.position(0);
+ buf.limit(buf.capacity());
+ return new ImageInfo(next, mipMapWidth(map), mipMapHeight(map), isCompressed(), getCompressionFormat());
+ }
+
+ /** Returns an array of ImageInfos corresponding to all mipmap
+ levels of this DDS file.
+ @return Mipmap image objects set
+ */
+ public ImageInfo[] getAllMipMaps() {
+ return getAllMipMaps(0);
+ }
+
+ /**
+ * Returns an array of ImageInfos corresponding to all mipmap
+ * levels of this DDS file.
+ * @param side Cubemap side or 0 for 2D texture
+ * @return Mipmap image objects set
+ */
+ public ImageInfo[] getAllMipMaps( int side ) {
+ int numLevels = getNumMipMaps();
+ if (numLevels == 0) {
+ numLevels = 1;
+ }
+ ImageInfo[] result = new ImageInfo[numLevels];
+ for (int i = 0; i < numLevels; i++) {
+ result[i] = getMipMap(side, i);
+ }
+ return result;
+ }
+
+ /** Converts e.g. DXT1 compression format constant (see {@link
+ #getCompressionFormat}) into "DXT1".
+ @param compressionFormat Compression format constant
+ @return String format code
+ */
+ public static String getCompressionFormatName(int compressionFormat) {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < 4; i++) {
+ char c = (char) (compressionFormat & 0xFF);
+ buf.append(c);
+ compressionFormat = compressionFormat >> 8;
+ }
+ return buf.toString();
+ }
+
+ /** Allocates a temporary, empty ByteBuffer suitable for use in a
+ call to glCompressedTexImage2D. This is used by the Texture
+ class to expand non-power-of-two DDS compressed textures to
+ power-of-two sizes on hardware not supporting OpenGL 2.0 and the
+ NPOT texture extension. The specified OpenGL internal format
+ must be one of GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, or
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT.
+ */
+ public static ByteBuffer allocateBlankBuffer(int width,
+ int height,
+ int openGLInternalFormat) {
+ int size = width * height;
+ switch (openGLInternalFormat) {
+ case GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ size /= 2;
+ break;
+
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ break;
+
+ default:
+ throw new IllegalArgumentException("Illegal OpenGL texture internal format " +
+ openGLInternalFormat);
+ }
+ if (size == 0)
+ size = 1;
+ return GLBuffers.newDirectByteBuffer(size);
+ }
+
+ public void debugPrint() {
+ PrintStream tty = System.err;
+ tty.println("Compressed texture: " + isCompressed());
+ if (isCompressed()) {
+ int fmt = getCompressionFormat();
+ String name = getCompressionFormatName(fmt);
+ tty.println("Compression format: 0x" + Integer.toHexString(fmt) + " (" + name + ")");
+ }
+ tty.println("Width: " + header.width + " Height: " + header.height);
+ tty.println("header.pitchOrLinearSize: " + header.pitchOrLinearSize);
+ tty.println("header.pfRBitMask: 0x" + Integer.toHexString(header.pfRBitMask));
+ tty.println("header.pfGBitMask: 0x" + Integer.toHexString(header.pfGBitMask));
+ tty.println("header.pfBBitMask: 0x" + Integer.toHexString(header.pfBBitMask));
+ tty.println("SurfaceDesc flags:");
+ boolean recognizedAny = false;
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_CAPS, "DDSD_CAPS");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_HEIGHT, "DDSD_HEIGHT");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_WIDTH, "DDSD_WIDTH");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_PITCH, "DDSD_PITCH");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_BACKBUFFERCOUNT, "DDSD_BACKBUFFERCOUNT");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_ALPHABITDEPTH, "DDSD_ALPHABITDEPTH");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_LPSURFACE, "DDSD_LPSURFACE");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_MIPMAPCOUNT, "DDSD_MIPMAPCOUNT");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_LINEARSIZE, "DDSD_LINEARSIZE");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_DEPTH, "DDSD_DEPTH");
+ if (!recognizedAny) {
+ tty.println("(none)");
+ }
+ tty.println("Raw SurfaceDesc flags: 0x" + Integer.toHexString(header.flags));
+ tty.println("Pixel format flags:");
+ recognizedAny = false;
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_ALPHAPIXELS, "DDPF_ALPHAPIXELS");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_ALPHA, "DDPF_ALPHA");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_FOURCC, "DDPF_FOURCC");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_PALETTEINDEXED4, "DDPF_PALETTEINDEXED4");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_PALETTEINDEXEDTO8, "DDPF_PALETTEINDEXEDTO8");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_PALETTEINDEXED8, "DDPF_PALETTEINDEXED8");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_RGB, "DDPF_RGB");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_COMPRESSED, "DDPF_COMPRESSED");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_RGBTOYUV, "DDPF_RGBTOYUV");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_YUV, "DDPF_YUV");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_ZBUFFER, "DDPF_ZBUFFER");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_PALETTEINDEXED1, "DDPF_PALETTEINDEXED1");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_PALETTEINDEXED2, "DDPF_PALETTEINDEXED2");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_ZPIXELS, "DDPF_ZPIXELS");
+ if (!recognizedAny) {
+ tty.println("(none)");
+ }
+ tty.println("Raw pixel format flags: 0x" + Integer.toHexString(header.pfFlags));
+ tty.println("Depth: " + getDepth());
+ tty.println("Number of mip maps: " + getNumMipMaps());
+ int fmt = getPixelFormat();
+ tty.print("Pixel format: ");
+ switch (fmt) {
+ case D3DFMT_R8G8B8: tty.println("D3DFMT_R8G8B8"); break;
+ case D3DFMT_A8R8G8B8: tty.println("D3DFMT_A8R8G8B8"); break;
+ case D3DFMT_X8R8G8B8: tty.println("D3DFMT_X8R8G8B8"); break;
+ case D3DFMT_DXT1: tty.println("D3DFMT_DXT1"); break;
+ case D3DFMT_DXT2: tty.println("D3DFMT_DXT2"); break;
+ case D3DFMT_DXT3: tty.println("D3DFMT_DXT3"); break;
+ case D3DFMT_DXT4: tty.println("D3DFMT_DXT4"); break;
+ case D3DFMT_DXT5: tty.println("D3DFMT_DXT5"); break;
+ case D3DFMT_UNKNOWN: tty.println("D3DFMT_UNKNOWN"); break;
+ default: tty.println("(unknown pixel format " + fmt + ")"); break;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static final int MAGIC = 0x20534444;
+
+ static class Header {
+ int size; // size of the DDSURFACEDESC structure
+ int flags; // determines what fields are valid
+ int height; // height of surface to be created
+ int width; // width of input surface
+ int pitchOrLinearSize;
+ int backBufferCountOrDepth;
+ int mipMapCountOrAux; // number of mip-map levels requested (in this context)
+ int alphaBitDepth; // depth of alpha buffer requested
+ int reserved1; // reserved
+ int surface; // pointer to the associated surface memory
+ // NOTE: following two entries are from DDCOLORKEY data structure
+ // Are overlaid with color for empty cubemap faces (unused in this reader)
+ int colorSpaceLowValue;
+ int colorSpaceHighValue;
+ int destBltColorSpaceLowValue;
+ int destBltColorSpaceHighValue;
+ int srcOverlayColorSpaceLowValue;
+ int srcOverlayColorSpaceHighValue;
+ int srcBltColorSpaceLowValue;
+ int srcBltColorSpaceHighValue;
+ // NOTE: following entries are from DDPIXELFORMAT data structure
+ // Are overlaid with flexible vertex format description of vertex
+ // buffers (unused in this reader)
+ int pfSize; // size of DDPIXELFORMAT structure
+ int pfFlags; // pixel format flags
+ int pfFourCC; // (FOURCC code)
+ // Following five entries have multiple interpretations, not just
+ // RGBA (but that's all we support right now)
+ int pfRGBBitCount; // how many bits per pixel
+ int pfRBitMask; // mask for red bits
+ int pfGBitMask; // mask for green bits
+ int pfBBitMask; // mask for blue bits
+ int pfABitMask; // mask for alpha channel
+ int ddsCaps1; // Texture and mip-map flags
+ int ddsCaps2; // Advanced capabilities including cubemap support
+ int ddsCapsReserved1;
+ int ddsCapsReserved2;
+ int textureStage; // stage in multitexture cascade
+
+ void read(LEDataInputStream input) throws IOException {
+ int magic = input.readInt();
+ if (magic != MAGIC) {
+ throw new IOException("Incorrect magic number 0x" +
+ Integer.toHexString(magic) +
+ " (expected " + MAGIC + ")");
+ }
+
+ size = input.readInt();
+ flags = input.readInt();
+ height = input.readInt();
+ width = input.readInt();
+ pitchOrLinearSize = input.readInt();
+ backBufferCountOrDepth = input.readInt();
+ mipMapCountOrAux = input.readInt();
+ alphaBitDepth = input.readInt();
+ reserved1 = input.readInt();
+ surface = input.readInt();
+ colorSpaceLowValue = input.readInt();
+ colorSpaceHighValue = input.readInt();
+ destBltColorSpaceLowValue = input.readInt();
+ destBltColorSpaceHighValue = input.readInt();
+ srcOverlayColorSpaceLowValue = input.readInt();
+ srcOverlayColorSpaceHighValue = input.readInt();
+ srcBltColorSpaceLowValue = input.readInt();
+ srcBltColorSpaceHighValue = input.readInt();
+ pfSize = input.readInt();
+ pfFlags = input.readInt();
+ pfFourCC = input.readInt();
+ pfRGBBitCount = input.readInt();
+ pfRBitMask = input.readInt();
+ pfGBitMask = input.readInt();
+ pfBBitMask = input.readInt();
+ pfABitMask = input.readInt();
+ ddsCaps1 = input.readInt();
+ ddsCaps2 = input.readInt();
+ ddsCapsReserved1 = input.readInt();
+ ddsCapsReserved2 = input.readInt();
+ textureStage = input.readInt();
+ }
+
+ // buf must be in little-endian byte order
+ void write(LEDataOutputStream output) throws IOException {
+ output.writeInt(MAGIC);
+ output.writeInt(size);
+ output.writeInt(flags);
+ output.writeInt(height);
+ output.writeInt(width);
+ output.writeInt(pitchOrLinearSize);
+ output.writeInt(backBufferCountOrDepth);
+ output.writeInt(mipMapCountOrAux);
+ output.writeInt(alphaBitDepth);
+ output.writeInt(reserved1);
+ output.writeInt(surface);
+ output.writeInt(colorSpaceLowValue);
+ output.writeInt(colorSpaceHighValue);
+ output.writeInt(destBltColorSpaceLowValue);
+ output.writeInt(destBltColorSpaceHighValue);
+ output.writeInt(srcOverlayColorSpaceLowValue);
+ output.writeInt(srcOverlayColorSpaceHighValue);
+ output.writeInt(srcBltColorSpaceLowValue);
+ output.writeInt(srcBltColorSpaceHighValue);
+ output.writeInt(pfSize);
+ output.writeInt(pfFlags);
+ output.writeInt(pfFourCC);
+ output.writeInt(pfRGBBitCount);
+ output.writeInt(pfRBitMask);
+ output.writeInt(pfGBitMask);
+ output.writeInt(pfBBitMask);
+ output.writeInt(pfABitMask);
+ output.writeInt(ddsCaps1);
+ output.writeInt(ddsCaps2);
+ output.writeInt(ddsCapsReserved1);
+ output.writeInt(ddsCapsReserved2);
+ output.writeInt(textureStage);
+ }
+
+ private static int size() {
+ return 124;
+ }
+
+ private static int pfSize() {
+ return 32;
+ }
+
+ private static int writtenSize() {
+ return 128;
+ }
+ }
+
+ private DDSImage() {
+ }
+
+ private void readFromFile(File file) throws IOException {
+ readFromStream(new BufferedInputStream(new FileInputStream(file)));
+ }
+
+ private void readFromStream(InputStream input) throws IOException {
+ LEDataInputStream leInput = new LEDataInputStream(input);
+ header = new Header();
+ header.read(leInput);
+ fixupHeader();
+ buf = StreamUtil.readAll2Buffer(input);
+ }
+
+ private void initFromData(int d3dFormat,
+ int width,
+ int height,
+ ByteBuffer[] mipmapData) throws IllegalArgumentException {
+ // Check size of mipmap data compared against format, width and
+ // height
+ int topmostMipmapSize = width * height;
+ int pitchOrLinearSize = width;
+ boolean isCompressed = false;
+ switch (d3dFormat) {
+ case D3DFMT_R8G8B8: topmostMipmapSize *= 3; pitchOrLinearSize *= 3; break;
+ case D3DFMT_A8R8G8B8: topmostMipmapSize *= 4; pitchOrLinearSize *= 4; break;
+ case D3DFMT_X8R8G8B8: topmostMipmapSize *= 4; pitchOrLinearSize *= 4; break;
+ case D3DFMT_DXT1:
+ case D3DFMT_DXT2:
+ case D3DFMT_DXT3:
+ case D3DFMT_DXT4:
+ case D3DFMT_DXT5:
+ topmostMipmapSize = computeCompressedBlockSize(width, height, 1, d3dFormat);
+ pitchOrLinearSize = topmostMipmapSize;
+ isCompressed = true;
+ break;
+ default:
+ throw new IllegalArgumentException("d3dFormat must be one of the known formats");
+ }
+
+ // Now check the mipmaps against this size
+ int curSize = topmostMipmapSize;
+ int totalSize = 0;
+ for (int i = 0; i < mipmapData.length; i++) {
+ if (mipmapData[i].remaining() != curSize) {
+ throw new IllegalArgumentException("Mipmap level " + i +
+ " didn't match expected data size (expected " + curSize + ", got " +
+ mipmapData[i].remaining() + ")");
+ }
+ curSize /= 4;
+ totalSize += mipmapData[i].remaining();
+ }
+
+ // OK, create one large byte array to hold all of the mipmap data
+ byte[] data = new byte[totalSize];
+ ByteBuffer buf = ByteBuffer.wrap(data);
+ for (int i = 0; i < mipmapData.length; i++) {
+ buf.put(mipmapData[i]);
+ }
+ this.buf = buf;
+
+ // Allocate and initialize a Header
+ header = new Header();
+ header.size = Header.size();
+ header.flags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
+ if (mipmapData.length > 1) {
+ header.flags |= DDSD_MIPMAPCOUNT;
+ header.mipMapCountOrAux = mipmapData.length;
+ }
+ header.width = width;
+ header.height = height;
+ if (isCompressed) {
+ header.flags |= DDSD_LINEARSIZE;
+ header.pfFlags |= DDPF_FOURCC;
+ header.pfFourCC = d3dFormat;
+ } else {
+ header.flags |= DDSD_PITCH;
+ // Figure out the various settings from the pixel format
+ header.pfFlags |= DDPF_RGB;
+ switch (d3dFormat) {
+ case D3DFMT_R8G8B8: header.pfRGBBitCount = 24; break;
+ case D3DFMT_A8R8G8B8: header.pfRGBBitCount = 32; header.pfFlags |= DDPF_ALPHAPIXELS; break;
+ case D3DFMT_X8R8G8B8: header.pfRGBBitCount = 32; break;
+ }
+ header.pfRBitMask = 0x00FF0000;
+ header.pfGBitMask = 0x0000FF00;
+ header.pfBBitMask = 0x000000FF;
+ if (d3dFormat == D3DFMT_A8R8G8B8) {
+ header.pfABitMask = 0xFF000000;
+ }
+ }
+ header.pitchOrLinearSize = pitchOrLinearSize;
+ header.pfSize = Header.pfSize();
+ // Not sure whether we can get away with leaving the rest of the
+ // header blank
+ }
+
+ // Microsoft doesn't follow their own specifications and the
+ // simplest conversion using the DxTex tool to e.g. a DXT3 texture
+ // results in an illegal .dds file without either DDSD_PITCH or
+ // DDSD_LINEARSIZE set in the header's flags. This code, adapted
+ // from the DevIL library, fixes up the header in these situations.
+ private void fixupHeader() {
+ if (isCompressed() && !isSurfaceDescFlagSet(DDSD_LINEARSIZE)) {
+ // Figure out how big the linear size should be
+ int depth = header.backBufferCountOrDepth;
+ if (depth == 0) {
+ depth = 1;
+ }
+
+ header.pitchOrLinearSize = computeCompressedBlockSize(getWidth(), getHeight(), depth, getCompressionFormat());
+ header.flags |= DDSD_LINEARSIZE;
+ }
+ }
+
+ private static int computeCompressedBlockSize(int width,
+ int height,
+ int depth,
+ int compressionFormat) {
+ int blockSize = ((width + 3)/4) * ((height + 3)/4) * ((depth + 3)/4);
+ switch (compressionFormat) {
+ case D3DFMT_DXT1: blockSize *= 8; break;
+ default: blockSize *= 16; break;
+ }
+ return blockSize;
+ }
+
+ private int mipMapWidth(int map) {
+ int width = getWidth();
+ for (int i = 0; i < map; i++) {
+ width >>= 1;
+ }
+ return Math.max(width, 1);
+ }
+
+ private int mipMapHeight(int map) {
+ int height = getHeight();
+ for (int i = 0; i < map; i++) {
+ height >>= 1;
+ }
+ return Math.max(height, 1);
+ }
+
+ private int mipMapSizeInBytes(int map) {
+ int width = mipMapWidth(map);
+ int height = mipMapHeight(map);
+ if (isCompressed()) {
+ int blockSize = (getCompressionFormat() == D3DFMT_DXT1 ? 8 : 16);
+ return ((width+3)/4)*((height+3)/4)*blockSize;
+ } else {
+ return width * height * (getDepth() / 8);
+ }
+ }
+
+ private int sideSizeInBytes() {
+ int numLevels = getNumMipMaps();
+ if (numLevels == 0) {
+ numLevels = 1;
+ }
+
+ int size = 0;
+ for (int i = 0; i < numLevels; i++) {
+ size += mipMapSizeInBytes(i);
+ }
+
+ return size;
+ }
+
+ private int sideShiftInBytes(int side) {
+ int[] sides = {
+ DDSCAPS2_CUBEMAP_POSITIVEX,
+ DDSCAPS2_CUBEMAP_NEGATIVEX,
+ DDSCAPS2_CUBEMAP_POSITIVEY,
+ DDSCAPS2_CUBEMAP_NEGATIVEY,
+ DDSCAPS2_CUBEMAP_POSITIVEZ,
+ DDSCAPS2_CUBEMAP_NEGATIVEZ
+ };
+
+ int shift = 0;
+ int sideSize = sideSizeInBytes();
+ for (int i = 0; i < sides.length; i++) {
+ int temp = sides[i];
+ if ((temp & side) != 0) {
+ return shift;
+ }
+
+ shift += sideSize;
+ }
+
+ throw new RuntimeException("Illegal side: " + side);
+ }
+
+ private boolean printIfRecognized(PrintStream tty, int flags, int flag, String what) {
+ if ((flags & flag) != 0) {
+ tty.println(what);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java.javase b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java.javase
new file mode 100755
index 000000000..e3092162d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java.javase
@@ -0,0 +1,919 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.texture.*;
+
+/** A reader and writer for DirectDraw Surface (.dds) files, which are
+ used to describe textures. These files can contain multiple mipmap
+ levels in one file. This class is currently minimal and does not
+ support all of the possible file formats. */
+
+public class DDSImage {
+
+ /** Simple class describing images and data; does not encapsulate
+ image format information. User is responsible for transmitting
+ that information in another way. */
+
+ public static class ImageInfo {
+ private ByteBuffer data;
+ private int width;
+ private int height;
+ private boolean isCompressed;
+ private int compressionFormat;
+
+ public ImageInfo(ByteBuffer data, int width, int height, boolean compressed, int compressionFormat) {
+ this.data = data; this.width = width; this.height = height;
+ this.isCompressed = compressed; this.compressionFormat = compressionFormat;
+ }
+ public int getWidth() { return width; }
+ public int getHeight() { return height; }
+ public ByteBuffer getData() { return data; }
+ public boolean isCompressed() { return isCompressed; }
+ public int getCompressionFormat() {
+ if (!isCompressed())
+ throw new RuntimeException("Should not call unless compressed");
+ return compressionFormat;
+ }
+ }
+
+ private FileInputStream fis;
+ private FileChannel chan;
+ private ByteBuffer buf;
+ private Header header;
+
+ //
+ // Selected bits in header flags
+ //
+
+ public static final int DDSD_CAPS = 0x00000001; // Capacities are valid
+ public static final int DDSD_HEIGHT = 0x00000002; // Height is valid
+ public static final int DDSD_WIDTH = 0x00000004; // Width is valid
+ public static final int DDSD_PITCH = 0x00000008; // Pitch is valid
+ public static final int DDSD_BACKBUFFERCOUNT = 0x00000020; // Back buffer count is valid
+ public static final int DDSD_ZBUFFERBITDEPTH = 0x00000040; // Z-buffer bit depth is valid (shouldn't be used in DDSURFACEDESC2)
+ public static final int DDSD_ALPHABITDEPTH = 0x00000080; // Alpha bit depth is valid
+ public static final int DDSD_LPSURFACE = 0x00000800; // lpSurface is valid
+ public static final int DDSD_PIXELFORMAT = 0x00001000; // ddpfPixelFormat is valid
+ public static final int DDSD_MIPMAPCOUNT = 0x00020000; // Mip map count is valid
+ public static final int DDSD_LINEARSIZE = 0x00080000; // dwLinearSize is valid
+ public static final int DDSD_DEPTH = 0x00800000; // dwDepth is valid
+
+ public static final int DDPF_ALPHAPIXELS = 0x00000001; // Alpha channel is present
+ public static final int DDPF_ALPHA = 0x00000002; // Only contains alpha information
+ public static final int DDPF_FOURCC = 0x00000004; // FourCC code is valid
+ public static final int DDPF_PALETTEINDEXED4 = 0x00000008; // Surface is 4-bit color indexed
+ public static final int DDPF_PALETTEINDEXEDTO8 = 0x00000010; // Surface is indexed into a palette which stores indices
+ // into the destination surface's 8-bit palette
+ public static final int DDPF_PALETTEINDEXED8 = 0x00000020; // Surface is 8-bit color indexed
+ public static final int DDPF_RGB = 0x00000040; // RGB data is present
+ public static final int DDPF_COMPRESSED = 0x00000080; // Surface will accept pixel data in the format specified
+ // and compress it during the write
+ public static final int DDPF_RGBTOYUV = 0x00000100; // Surface will accept RGB data and translate it during
+ // the write to YUV data. The format of the data to be written
+ // will be contained in the pixel format structure. The DDPF_RGB
+ // flag will be set.
+ public static final int DDPF_YUV = 0x00000200; // Pixel format is YUV - YUV data in pixel format struct is valid
+ public static final int DDPF_ZBUFFER = 0x00000400; // Pixel format is a z buffer only surface
+ public static final int DDPF_PALETTEINDEXED1 = 0x00000800; // Surface is 1-bit color indexed
+ public static final int DDPF_PALETTEINDEXED2 = 0x00001000; // Surface is 2-bit color indexed
+ public static final int DDPF_ZPIXELS = 0x00002000; // Surface contains Z information in the pixels
+
+ // Selected bits in DDS capabilities flags
+ public static final int DDSCAPS_TEXTURE = 0x00001000; // Can be used as a texture
+ public static final int DDSCAPS_MIPMAP = 0x00400000; // Is one level of a mip-map
+ public static final int DDSCAPS_COMPLEX = 0x00000008; // Complex surface structure, such as a cube map
+
+ // Selected bits in DDS extended capabilities flags
+ public static final int DDSCAPS2_CUBEMAP = 0x00000200;
+ public static final int DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400;
+ public static final int DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800;
+ public static final int DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000;
+ public static final int DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000;
+ public static final int DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000;
+ public static final int DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000;
+
+ // Known pixel formats
+ public static final int D3DFMT_UNKNOWN = 0;
+ public static final int D3DFMT_R8G8B8 = 20;
+ public static final int D3DFMT_A8R8G8B8 = 21;
+ public static final int D3DFMT_X8R8G8B8 = 22;
+ // The following are also valid FourCC codes
+ public static final int D3DFMT_DXT1 = 0x31545844;
+ public static final int D3DFMT_DXT2 = 0x32545844;
+ public static final int D3DFMT_DXT3 = 0x33545844;
+ public static final int D3DFMT_DXT4 = 0x34545844;
+ public static final int D3DFMT_DXT5 = 0x35545844;
+
+ /** Reads a DirectDraw surface from the specified file name,
+ returning the resulting DDSImage.
+
+ @param filename File name
+ @return DDS image object
+ @throws java.io.IOException if an I/O exception occurred
+ */
+ public static DDSImage read(String filename) throws IOException {
+ return read(new File(filename));
+ }
+
+ /** Reads a DirectDraw surface from the specified file, returning
+ the resulting DDSImage.
+
+ @param file File object
+ @return DDS image object
+ @throws java.io.IOException if an I/O exception occurred
+ */
+ public static DDSImage read(File file) throws IOException {
+ DDSImage image = new DDSImage();
+ image.readFromFile(file);
+ return image;
+ }
+
+ /** Reads a DirectDraw surface from the specified ByteBuffer, returning
+ the resulting DDSImage.
+
+ @param buf Input data
+ @return DDS image object
+ @throws java.io.IOException if an I/O exception occurred
+ */
+ public static DDSImage read(ByteBuffer buf) throws IOException {
+ DDSImage image = new DDSImage();
+ image.readFromBuffer(buf);
+ return image;
+ }
+
+ /** Closes open files and resources associated with the open
+ DDSImage. No other methods may be called on this object once
+ this is called. */
+ public void close() {
+ try {
+ if (chan != null) {
+ chan.close();
+ chan = null;
+ }
+ if (fis != null) {
+ fis.close();
+ fis = null;
+ }
+ buf = null;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Creates a new DDSImage from data supplied by the user. The
+ * resulting DDSImage can be written to disk using the write()
+ * method.
+ *
+ * @param d3dFormat the D3DFMT_ constant describing the data; it is
+ * assumed that it is packed tightly
+ * @param width the width in pixels of the topmost mipmap image
+ * @param height the height in pixels of the topmost mipmap image
+ * @param mipmapData the data for each mipmap level of the resulting
+ * DDSImage; either only one mipmap level should
+ * be specified, or they all must be
+ * @throws IllegalArgumentException if the data does not match the
+ * specified arguments
+ * @return DDS image object
+ */
+ public static DDSImage createFromData(int d3dFormat,
+ int width,
+ int height,
+ ByteBuffer[] mipmapData) throws IllegalArgumentException {
+ DDSImage image = new DDSImage();
+ image.initFromData(d3dFormat, width, height, mipmapData);
+ return image;
+ }
+
+ /** Determines from the magic number whether the given InputStream
+ points to a DDS image. The given InputStream must return true
+ from markSupported() and support a minimum of four bytes of
+ read-ahead.
+
+ @param in Stream to check
+ @return true if input stream is DDS image or false otherwise
+ @throws java.io.IOException if an I/O exception occurred
+ */
+ public static boolean isDDSImage(InputStream in) throws IOException {
+ if (!(in instanceof BufferedInputStream)) {
+ in = new BufferedInputStream(in);
+ }
+ if (!in.markSupported()) {
+ throw new IOException("Can not test non-destructively whether given InputStream is a DDS image");
+ }
+ in.mark(4);
+ int magic = 0;
+ for (int i = 0; i < 4; i++) {
+ int tmp = in.read();
+ if (tmp < 0) {
+ in.reset();
+ return false;
+ }
+ magic = ((magic >>> 8) | (tmp << 24));
+ }
+ in.reset();
+ return (magic == MAGIC);
+ }
+
+ /**
+ * Writes this DDSImage to the specified file name.
+ * @param filename File name to write to
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public void write(String filename) throws IOException {
+ write(new File(filename));
+ }
+
+ /**
+ * Writes this DDSImage to the specified file name.
+ * @param file File object to write to
+ * @throws java.io.IOException if an I/O exception occurred
+ */
+ public void write(File file) throws IOException {
+ FileOutputStream stream = new FileOutputStream(file);
+ FileChannel chan = stream.getChannel();
+ // Create ByteBuffer for header in case the start of our
+ // ByteBuffer isn't actually memory-mapped
+ ByteBuffer hdr = ByteBuffer.allocate(Header.writtenSize());
+ hdr.order(ByteOrder.LITTLE_ENDIAN);
+ header.write(hdr);
+ hdr.rewind();
+ chan.write(hdr);
+ buf.position(Header.writtenSize());
+ chan.write(buf);
+ chan.force(true);
+ chan.close();
+ stream.close();
+ }
+
+ /** Test for presence/absence of surface description flags (DDSD_*)
+ * @param flag DDSD_* flags set to test
+ * @return true if flag present or false otherwise
+ */
+ public boolean isSurfaceDescFlagSet(int flag) {
+ return ((header.flags & flag) != 0);
+ }
+
+ /** Test for presence/absence of pixel format flags (DDPF_*) */
+ public boolean isPixelFormatFlagSet(int flag) {
+ return ((header.pfFlags & flag) != 0);
+ }
+
+ /** Gets the pixel format of this texture (D3DFMT_*) based on some
+ heuristics. Returns D3DFMT_UNKNOWN if could not recognize the
+ pixel format. */
+ public int getPixelFormat() {
+ if (isCompressed()) {
+ return getCompressionFormat();
+ } else if (isPixelFormatFlagSet(DDPF_RGB)) {
+ if (isPixelFormatFlagSet(DDPF_ALPHAPIXELS)) {
+ if (getDepth() == 32 &&
+ header.pfRBitMask == 0x00FF0000 &&
+ header.pfGBitMask == 0x0000FF00 &&
+ header.pfBBitMask == 0x000000FF &&
+ header.pfABitMask == 0xFF000000) {
+ return D3DFMT_A8R8G8B8;
+ }
+ } else {
+ if (getDepth() == 24 &&
+ header.pfRBitMask == 0x00FF0000 &&
+ header.pfGBitMask == 0x0000FF00 &&
+ header.pfBBitMask == 0x000000FF) {
+ return D3DFMT_R8G8B8;
+ } else if (getDepth() == 32 &&
+ header.pfRBitMask == 0x00FF0000 &&
+ header.pfGBitMask == 0x0000FF00 &&
+ header.pfBBitMask == 0x000000FF) {
+ return D3DFMT_X8R8G8B8;
+ }
+ }
+ }
+
+ return D3DFMT_UNKNOWN;
+ }
+
+ /**
+ * Indicates whether this texture is cubemap
+ * @return true if cubemap or false otherwise
+ */
+ public boolean isCubemap() {
+ return ((header.ddsCaps1 & DDSCAPS_COMPLEX) != 0) && ((header.ddsCaps2 & DDSCAPS2_CUBEMAP) != 0);
+ }
+
+ /**
+ * Indicates whethe this cubemap side present
+ * @param side Side to test
+ * @return true if side present or false otherwise
+ */
+ public boolean isCubemapSidePresent(int side) {
+ return isCubemap() && (header.ddsCaps2 & side) != 0;
+ }
+
+ /** Indicates whether this texture is compressed. */
+ public boolean isCompressed() {
+ return (isPixelFormatFlagSet(DDPF_FOURCC));
+ }
+
+ /** If this surface is compressed, returns the kind of compression
+ used (DXT1..DXT5). */
+ public int getCompressionFormat() {
+ return header.pfFourCC;
+ }
+
+ /** Width of the texture (or the top-most mipmap if mipmaps are
+ present) */
+ public int getWidth() {
+ return header.width;
+ }
+
+ /** Height of the texture (or the top-most mipmap if mipmaps are
+ present) */
+ public int getHeight() {
+ return header.height;
+ }
+
+ /** Total number of bits per pixel. Only valid if DDPF_RGB is
+ present. For A8R8G8B8, would be 32. */
+ public int getDepth() {
+ return header.pfRGBBitCount;
+ }
+
+ /** Number of mip maps in the texture */
+ public int getNumMipMaps() {
+ if (!isSurfaceDescFlagSet(DDSD_MIPMAPCOUNT)) {
+ return 0;
+ }
+ return header.mipMapCountOrAux;
+ }
+
+ /** Gets the <i>i</i>th mipmap data (0..getNumMipMaps() - 1)
+ * @param map Mipmap index
+ * @return Image object
+ */
+ public ImageInfo getMipMap(int map) {
+ return getMipMap( 0, map );
+ }
+
+ /**
+ * Gets the <i>i</i>th mipmap data (0..getNumMipMaps() - 1)
+ * @param side Cubemap side or 0 for 2D texture
+ * @param map Mipmap index
+ * @return Image object
+ */
+ public ImageInfo getMipMap(int side, int map) {
+ if (!isCubemap() && (side != 0)) {
+ throw new RuntimeException( "Illegal side for 2D texture: " + side );
+ }
+ if (isCubemap() && !isCubemapSidePresent(side)) {
+ throw new RuntimeException( "Illegal side, side not present: " + side );
+ }
+ if (getNumMipMaps() > 0 &&
+ ((map < 0) || (map >= getNumMipMaps()))) {
+ throw new RuntimeException("Illegal mipmap number " + map + " (0.." + (getNumMipMaps() - 1) + ")");
+ }
+
+ // Figure out how far to seek
+ int seek = Header.writtenSize();
+ if (isCubemap()) {
+ seek += sideShiftInBytes(side);
+ }
+ for (int i = 0; i < map; i++) {
+ seek += mipMapSizeInBytes(i);
+ }
+ buf.limit(seek + mipMapSizeInBytes(map));
+ buf.position(seek);
+ ByteBuffer next = buf.slice();
+ buf.position(0);
+ buf.limit(buf.capacity());
+ return new ImageInfo(next, mipMapWidth(map), mipMapHeight(map), isCompressed(), getCompressionFormat());
+ }
+
+ /** Returns an array of ImageInfos corresponding to all mipmap
+ levels of this DDS file.
+ @return Mipmap image objects set
+ */
+ public ImageInfo[] getAllMipMaps() {
+ return getAllMipMaps(0);
+ }
+
+ /**
+ * Returns an array of ImageInfos corresponding to all mipmap
+ * levels of this DDS file.
+ * @param side Cubemap side or 0 for 2D texture
+ * @return Mipmap image objects set
+ */
+ public ImageInfo[] getAllMipMaps( int side ) {
+ int numLevels = getNumMipMaps();
+ if (numLevels == 0) {
+ numLevels = 1;
+ }
+ ImageInfo[] result = new ImageInfo[numLevels];
+ for (int i = 0; i < numLevels; i++) {
+ result[i] = getMipMap(side, i);
+ }
+ return result;
+ }
+
+ /** Converts e.g. DXT1 compression format constant (see {@link
+ #getCompressionFormat}) into "DXT1".
+ @param compressionFormat Compression format constant
+ @return String format code
+ */
+ public static String getCompressionFormatName(int compressionFormat) {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < 4; i++) {
+ char c = (char) (compressionFormat & 0xFF);
+ buf.append(c);
+ compressionFormat = compressionFormat >> 8;
+ }
+ return buf.toString();
+ }
+
+ /** Allocates a temporary, empty ByteBuffer suitable for use in a
+ call to glCompressedTexImage2D. This is used by the Texture
+ class to expand non-power-of-two DDS compressed textures to
+ power-of-two sizes on hardware not supporting OpenGL 2.0 and the
+ NPOT texture extension. The specified OpenGL internal format
+ must be one of GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, or
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT.
+ */
+ public static ByteBuffer allocateBlankBuffer(int width,
+ int height,
+ int openGLInternalFormat) {
+ int size = width * height;
+ switch (openGLInternalFormat) {
+ case GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ size /= 2;
+ break;
+
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ break;
+
+ default:
+ throw new IllegalArgumentException("Illegal OpenGL texture internal format " +
+ openGLInternalFormat);
+ }
+ if (size == 0)
+ size = 1;
+ return GLBuffers.newDirectByteBuffer(size);
+ }
+
+ public void debugPrint() {
+ PrintStream tty = System.err;
+ tty.println("Compressed texture: " + isCompressed());
+ if (isCompressed()) {
+ int fmt = getCompressionFormat();
+ String name = getCompressionFormatName(fmt);
+ tty.println("Compression format: 0x" + Integer.toHexString(fmt) + " (" + name + ")");
+ }
+ tty.println("Width: " + header.width + " Height: " + header.height);
+ tty.println("header.pitchOrLinearSize: " + header.pitchOrLinearSize);
+ tty.println("header.pfRBitMask: 0x" + Integer.toHexString(header.pfRBitMask));
+ tty.println("header.pfGBitMask: 0x" + Integer.toHexString(header.pfGBitMask));
+ tty.println("header.pfBBitMask: 0x" + Integer.toHexString(header.pfBBitMask));
+ tty.println("SurfaceDesc flags:");
+ boolean recognizedAny = false;
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_CAPS, "DDSD_CAPS");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_HEIGHT, "DDSD_HEIGHT");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_WIDTH, "DDSD_WIDTH");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_PITCH, "DDSD_PITCH");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_BACKBUFFERCOUNT, "DDSD_BACKBUFFERCOUNT");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_ALPHABITDEPTH, "DDSD_ALPHABITDEPTH");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_LPSURFACE, "DDSD_LPSURFACE");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_PIXELFORMAT, "DDSD_PIXELFORMAT");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_MIPMAPCOUNT, "DDSD_MIPMAPCOUNT");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_LINEARSIZE, "DDSD_LINEARSIZE");
+ recognizedAny |= printIfRecognized(tty, header.flags, DDSD_DEPTH, "DDSD_DEPTH");
+ if (!recognizedAny) {
+ tty.println("(none)");
+ }
+ tty.println("Raw SurfaceDesc flags: 0x" + Integer.toHexString(header.flags));
+ tty.println("Pixel format flags:");
+ recognizedAny = false;
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_ALPHAPIXELS, "DDPF_ALPHAPIXELS");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_ALPHA, "DDPF_ALPHA");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_FOURCC, "DDPF_FOURCC");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_PALETTEINDEXED4, "DDPF_PALETTEINDEXED4");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_PALETTEINDEXEDTO8, "DDPF_PALETTEINDEXEDTO8");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_PALETTEINDEXED8, "DDPF_PALETTEINDEXED8");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_RGB, "DDPF_RGB");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_COMPRESSED, "DDPF_COMPRESSED");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_RGBTOYUV, "DDPF_RGBTOYUV");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_YUV, "DDPF_YUV");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_ZBUFFER, "DDPF_ZBUFFER");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_PALETTEINDEXED1, "DDPF_PALETTEINDEXED1");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_PALETTEINDEXED2, "DDPF_PALETTEINDEXED2");
+ recognizedAny |= printIfRecognized(tty, header.pfFlags, DDPF_ZPIXELS, "DDPF_ZPIXELS");
+ if (!recognizedAny) {
+ tty.println("(none)");
+ }
+ tty.println("Raw pixel format flags: 0x" + Integer.toHexString(header.pfFlags));
+ tty.println("Depth: " + getDepth());
+ tty.println("Number of mip maps: " + getNumMipMaps());
+ int fmt = getPixelFormat();
+ tty.print("Pixel format: ");
+ switch (fmt) {
+ case D3DFMT_R8G8B8: tty.println("D3DFMT_R8G8B8"); break;
+ case D3DFMT_A8R8G8B8: tty.println("D3DFMT_A8R8G8B8"); break;
+ case D3DFMT_X8R8G8B8: tty.println("D3DFMT_X8R8G8B8"); break;
+ case D3DFMT_DXT1: tty.println("D3DFMT_DXT1"); break;
+ case D3DFMT_DXT2: tty.println("D3DFMT_DXT2"); break;
+ case D3DFMT_DXT3: tty.println("D3DFMT_DXT3"); break;
+ case D3DFMT_DXT4: tty.println("D3DFMT_DXT4"); break;
+ case D3DFMT_DXT5: tty.println("D3DFMT_DXT5"); break;
+ case D3DFMT_UNKNOWN: tty.println("D3DFMT_UNKNOWN"); break;
+ default: tty.println("(unknown pixel format " + fmt + ")"); break;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static final int MAGIC = 0x20534444;
+
+ static class Header {
+ int size; // size of the DDSURFACEDESC structure
+ int flags; // determines what fields are valid
+ int height; // height of surface to be created
+ int width; // width of input surface
+ int pitchOrLinearSize;
+ int backBufferCountOrDepth;
+ int mipMapCountOrAux; // number of mip-map levels requested (in this context)
+ int alphaBitDepth; // depth of alpha buffer requested
+ int reserved1; // reserved
+ int surface; // pointer to the associated surface memory
+ // NOTE: following two entries are from DDCOLORKEY data structure
+ // Are overlaid with color for empty cubemap faces (unused in this reader)
+ int colorSpaceLowValue;
+ int colorSpaceHighValue;
+ int destBltColorSpaceLowValue;
+ int destBltColorSpaceHighValue;
+ int srcOverlayColorSpaceLowValue;
+ int srcOverlayColorSpaceHighValue;
+ int srcBltColorSpaceLowValue;
+ int srcBltColorSpaceHighValue;
+ // NOTE: following entries are from DDPIXELFORMAT data structure
+ // Are overlaid with flexible vertex format description of vertex
+ // buffers (unused in this reader)
+ int pfSize; // size of DDPIXELFORMAT structure
+ int pfFlags; // pixel format flags
+ int pfFourCC; // (FOURCC code)
+ // Following five entries have multiple interpretations, not just
+ // RGBA (but that's all we support right now)
+ int pfRGBBitCount; // how many bits per pixel
+ int pfRBitMask; // mask for red bits
+ int pfGBitMask; // mask for green bits
+ int pfBBitMask; // mask for blue bits
+ int pfABitMask; // mask for alpha channel
+ int ddsCaps1; // Texture and mip-map flags
+ int ddsCaps2; // Advanced capabilities including cubemap support
+ int ddsCapsReserved1;
+ int ddsCapsReserved2;
+ int textureStage; // stage in multitexture cascade
+
+ void read(ByteBuffer buf) throws IOException {
+ int magic = buf.getInt();
+ if (magic != MAGIC) {
+ throw new IOException("Incorrect magic number 0x" +
+ Integer.toHexString(magic) +
+ " (expected " + MAGIC + ")");
+ }
+
+ size = buf.getInt();
+ flags = buf.getInt();
+ height = buf.getInt();
+ width = buf.getInt();
+ pitchOrLinearSize = buf.getInt();
+ backBufferCountOrDepth = buf.getInt();
+ mipMapCountOrAux = buf.getInt();
+ alphaBitDepth = buf.getInt();
+ reserved1 = buf.getInt();
+ surface = buf.getInt();
+ colorSpaceLowValue = buf.getInt();
+ colorSpaceHighValue = buf.getInt();
+ destBltColorSpaceLowValue = buf.getInt();
+ destBltColorSpaceHighValue = buf.getInt();
+ srcOverlayColorSpaceLowValue = buf.getInt();
+ srcOverlayColorSpaceHighValue = buf.getInt();
+ srcBltColorSpaceLowValue = buf.getInt();
+ srcBltColorSpaceHighValue = buf.getInt();
+ pfSize = buf.getInt();
+ pfFlags = buf.getInt();
+ pfFourCC = buf.getInt();
+ pfRGBBitCount = buf.getInt();
+ pfRBitMask = buf.getInt();
+ pfGBitMask = buf.getInt();
+ pfBBitMask = buf.getInt();
+ pfABitMask = buf.getInt();
+ ddsCaps1 = buf.getInt();
+ ddsCaps2 = buf.getInt();
+ ddsCapsReserved1 = buf.getInt();
+ ddsCapsReserved2 = buf.getInt();
+ textureStage = buf.getInt();
+ }
+
+ // buf must be in little-endian byte order
+ void write(ByteBuffer buf) {
+ buf.putInt(MAGIC);
+ buf.putInt(size);
+ buf.putInt(flags);
+ buf.putInt(height);
+ buf.putInt(width);
+ buf.putInt(pitchOrLinearSize);
+ buf.putInt(backBufferCountOrDepth);
+ buf.putInt(mipMapCountOrAux);
+ buf.putInt(alphaBitDepth);
+ buf.putInt(reserved1);
+ buf.putInt(surface);
+ buf.putInt(colorSpaceLowValue);
+ buf.putInt(colorSpaceHighValue);
+ buf.putInt(destBltColorSpaceLowValue);
+ buf.putInt(destBltColorSpaceHighValue);
+ buf.putInt(srcOverlayColorSpaceLowValue);
+ buf.putInt(srcOverlayColorSpaceHighValue);
+ buf.putInt(srcBltColorSpaceLowValue);
+ buf.putInt(srcBltColorSpaceHighValue);
+ buf.putInt(pfSize);
+ buf.putInt(pfFlags);
+ buf.putInt(pfFourCC);
+ buf.putInt(pfRGBBitCount);
+ buf.putInt(pfRBitMask);
+ buf.putInt(pfGBitMask);
+ buf.putInt(pfBBitMask);
+ buf.putInt(pfABitMask);
+ buf.putInt(ddsCaps1);
+ buf.putInt(ddsCaps2);
+ buf.putInt(ddsCapsReserved1);
+ buf.putInt(ddsCapsReserved2);
+ buf.putInt(textureStage);
+ }
+
+ private static int size() {
+ return 124;
+ }
+
+ private static int pfSize() {
+ return 32;
+ }
+
+ private static int writtenSize() {
+ return 128;
+ }
+ }
+
+ private DDSImage() {
+ }
+
+ private void readFromFile(File file) throws IOException {
+ fis = new FileInputStream(file);
+ chan = fis.getChannel();
+ ByteBuffer buf = chan.map(FileChannel.MapMode.READ_ONLY,
+ 0, (int) file.length());
+ readFromBuffer(buf);
+ }
+
+ private void readFromBuffer(ByteBuffer buf) throws IOException {
+ this.buf = buf;
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ header = new Header();
+ header.read(buf);
+ fixupHeader();
+ }
+
+ private void initFromData(int d3dFormat,
+ int width,
+ int height,
+ ByteBuffer[] mipmapData) throws IllegalArgumentException {
+ // Check size of mipmap data compared against format, width and
+ // height
+ int topmostMipmapSize = width * height;
+ int pitchOrLinearSize = width;
+ boolean isCompressed = false;
+ switch (d3dFormat) {
+ case D3DFMT_R8G8B8: topmostMipmapSize *= 3; pitchOrLinearSize *= 3; break;
+ case D3DFMT_A8R8G8B8: topmostMipmapSize *= 4; pitchOrLinearSize *= 4; break;
+ case D3DFMT_X8R8G8B8: topmostMipmapSize *= 4; pitchOrLinearSize *= 4; break;
+ case D3DFMT_DXT1:
+ case D3DFMT_DXT2:
+ case D3DFMT_DXT3:
+ case D3DFMT_DXT4:
+ case D3DFMT_DXT5:
+ topmostMipmapSize = computeCompressedBlockSize(width, height, 1, d3dFormat);
+ pitchOrLinearSize = topmostMipmapSize;
+ isCompressed = true;
+ break;
+ default:
+ throw new IllegalArgumentException("d3dFormat must be one of the known formats");
+ }
+
+ // Now check the mipmaps against this size
+ int curSize = topmostMipmapSize;
+ int totalSize = 0;
+ for (int i = 0; i < mipmapData.length; i++) {
+ if (mipmapData[i].remaining() != curSize) {
+ throw new IllegalArgumentException("Mipmap level " + i +
+ " didn't match expected data size (expected " + curSize + ", got " +
+ mipmapData[i].remaining() + ")");
+ }
+ curSize /= 4;
+ totalSize += mipmapData[i].remaining();
+ }
+
+ // OK, create one large ByteBuffer to hold all of the mipmap data
+ totalSize += Header.writtenSize();
+ ByteBuffer buf = ByteBuffer.allocate(totalSize);
+ buf.position(Header.writtenSize());
+ for (int i = 0; i < mipmapData.length; i++) {
+ buf.put(mipmapData[i]);
+ }
+ this.buf = buf;
+
+ // Allocate and initialize a Header
+ header = new Header();
+ header.size = Header.size();
+ header.flags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
+ if (mipmapData.length > 1) {
+ header.flags |= DDSD_MIPMAPCOUNT;
+ header.mipMapCountOrAux = mipmapData.length;
+ }
+ header.width = width;
+ header.height = height;
+ if (isCompressed) {
+ header.flags |= DDSD_LINEARSIZE;
+ header.pfFlags |= DDPF_FOURCC;
+ header.pfFourCC = d3dFormat;
+ } else {
+ header.flags |= DDSD_PITCH;
+ // Figure out the various settings from the pixel format
+ header.pfFlags |= DDPF_RGB;
+ switch (d3dFormat) {
+ case D3DFMT_R8G8B8: header.pfRGBBitCount = 24; break;
+ case D3DFMT_A8R8G8B8: header.pfRGBBitCount = 32; header.pfFlags |= DDPF_ALPHAPIXELS; break;
+ case D3DFMT_X8R8G8B8: header.pfRGBBitCount = 32; break;
+ }
+ header.pfRBitMask = 0x00FF0000;
+ header.pfGBitMask = 0x0000FF00;
+ header.pfBBitMask = 0x000000FF;
+ if (d3dFormat == D3DFMT_A8R8G8B8) {
+ header.pfABitMask = 0xFF000000;
+ }
+ }
+ header.pitchOrLinearSize = pitchOrLinearSize;
+ header.pfSize = Header.pfSize();
+ // Not sure whether we can get away with leaving the rest of the
+ // header blank
+ }
+
+ // Microsoft doesn't follow their own specifications and the
+ // simplest conversion using the DxTex tool to e.g. a DXT3 texture
+ // results in an illegal .dds file without either DDSD_PITCH or
+ // DDSD_LINEARSIZE set in the header's flags. This code, adapted
+ // from the DevIL library, fixes up the header in these situations.
+ private void fixupHeader() {
+ if (isCompressed() && !isSurfaceDescFlagSet(DDSD_LINEARSIZE)) {
+ // Figure out how big the linear size should be
+ int depth = header.backBufferCountOrDepth;
+ if (depth == 0) {
+ depth = 1;
+ }
+
+ header.pitchOrLinearSize = computeCompressedBlockSize(getWidth(), getHeight(), depth, getCompressionFormat());
+ header.flags |= DDSD_LINEARSIZE;
+ }
+ }
+
+ private static int computeCompressedBlockSize(int width,
+ int height,
+ int depth,
+ int compressionFormat) {
+ int blockSize = ((width + 3)/4) * ((height + 3)/4) * ((depth + 3)/4);
+ switch (compressionFormat) {
+ case D3DFMT_DXT1: blockSize *= 8; break;
+ default: blockSize *= 16; break;
+ }
+ return blockSize;
+ }
+
+ private int mipMapWidth(int map) {
+ int width = getWidth();
+ for (int i = 0; i < map; i++) {
+ width >>= 1;
+ }
+ return Math.max(width, 1);
+ }
+
+ private int mipMapHeight(int map) {
+ int height = getHeight();
+ for (int i = 0; i < map; i++) {
+ height >>= 1;
+ }
+ return Math.max(height, 1);
+ }
+
+ private int mipMapSizeInBytes(int map) {
+ int width = mipMapWidth(map);
+ int height = mipMapHeight(map);
+ if (isCompressed()) {
+ int blockSize = (getCompressionFormat() == D3DFMT_DXT1 ? 8 : 16);
+ return ((width+3)/4)*((height+3)/4)*blockSize;
+ } else {
+ return width * height * (getDepth() / 8);
+ }
+ }
+
+ private int sideSizeInBytes() {
+ int numLevels = getNumMipMaps();
+ if (numLevels == 0) {
+ numLevels = 1;
+ }
+
+ int size = 0;
+ for (int i = 0; i < numLevels; i++) {
+ size += mipMapSizeInBytes(i);
+ }
+
+ return size;
+ }
+
+ private int sideShiftInBytes(int side) {
+ int[] sides = {
+ DDSCAPS2_CUBEMAP_POSITIVEX,
+ DDSCAPS2_CUBEMAP_NEGATIVEX,
+ DDSCAPS2_CUBEMAP_POSITIVEY,
+ DDSCAPS2_CUBEMAP_NEGATIVEY,
+ DDSCAPS2_CUBEMAP_POSITIVEZ,
+ DDSCAPS2_CUBEMAP_NEGATIVEZ
+ };
+
+ int shift = 0;
+ int sideSize = sideSizeInBytes();
+ for (int i = 0; i < sides.length; i++) {
+ int temp = sides[i];
+ if ((temp & side) != 0) {
+ return shift;
+ }
+
+ shift += sideSize;
+ }
+
+ throw new RuntimeException("Illegal side: " + side);
+ }
+
+ private boolean printIfRecognized(PrintStream tty, int flags, int flag, String what) {
+ if ((flags & flag) != 0) {
+ tty.println(what);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
new file mode 100755
index 000000000..d5f49599c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi;
+
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+
+/**
+ * Little Endian Data Input Stream.
+ *
+ * This class implements an input stream filter to allow reading
+ * of java native datatypes from an input stream which has those
+ * native datatypes stored in a little endian byte order.<p>
+ *
+ * This is the sister class of the DataInputStream which allows
+ * for reading of java native datatypes from an input stream with
+ * the datatypes stored in big endian byte order.<p>
+ *
+ * This class implements the minimum required and calls DataInputStream
+ * for some of the required methods for DataInput.<p>
+ *
+ * Not all methods are implemented due to lack of immediatte requirement
+ * for that functionality. It is not clear if it is ever going to be
+ * functionally required to be able to read UTF data in a LittleEndianManner<p>
+ *
+ * @author Robin Luiten
+ * @version 1.1 15/Dec/1997
+ */
+public class LEDataInputStream extends FilterInputStream implements DataInput
+{
+ /**
+ * To reuse some of the non endian dependent methods from
+ * DataInputStreams methods.
+ */
+ DataInputStream dataIn;
+
+ public LEDataInputStream(InputStream in)
+ {
+ super(in);
+ dataIn = new DataInputStream(in);
+ }
+
+ public void close() throws IOException
+ {
+ dataIn.close(); // better close as we create it.
+ // this will close underlying as well.
+ }
+
+ public synchronized final int read(byte b[]) throws IOException
+ {
+ return dataIn.read(b, 0, b.length);
+ }
+
+ public synchronized final int read(byte b[], int off, int len) throws IOException
+ {
+ int rl = dataIn.read(b, off, len);
+ return rl;
+ }
+
+ public final void readFully(byte b[]) throws IOException
+ {
+ dataIn.readFully(b, 0, b.length);
+ }
+
+ public final void readFully(byte b[], int off, int len) throws IOException
+ {
+ dataIn.readFully(b, off, len);
+ }
+
+ public final int skipBytes(int n) throws IOException
+ {
+ return dataIn.skipBytes(n);
+ }
+
+ public final boolean readBoolean() throws IOException
+ {
+ int ch = dataIn.read();
+ if (ch < 0)
+ throw new EOFException();
+ return (ch != 0);
+ }
+
+ public final byte readByte() throws IOException
+ {
+ int ch = dataIn.read();
+ if (ch < 0)
+ throw new EOFException();
+ return (byte)(ch);
+ }
+
+ public final int readUnsignedByte() throws IOException
+ {
+ int ch = dataIn.read();
+ if (ch < 0)
+ throw new EOFException();
+ return ch;
+ }
+
+ public final short readShort() throws IOException
+ {
+ int ch1 = dataIn.read();
+ int ch2 = dataIn.read();
+ if ((ch1 | ch2) < 0)
+ throw new EOFException();
+ return (short)((ch1 << 0) + (ch2 << 8));
+ }
+
+ public final int readUnsignedShort() throws IOException
+ {
+ int ch1 = dataIn.read();
+ int ch2 = dataIn.read();
+ if ((ch1 | ch2) < 0)
+ throw new EOFException();
+ return (ch1 << 0) + (ch2 << 8);
+ }
+
+ public final char readChar() throws IOException
+ {
+ int ch1 = dataIn.read();
+ int ch2 = dataIn.read();
+ if ((ch1 | ch2) < 0)
+ throw new EOFException();
+ return (char)((ch1 << 0) + (ch2 << 8));
+ }
+
+ public final int readInt() throws IOException
+ {
+ int ch1 = dataIn.read();
+ int ch2 = dataIn.read();
+ int ch3 = dataIn.read();
+ int ch4 = dataIn.read();
+ if ((ch1 | ch2 | ch3 | ch4) < 0)
+ throw new EOFException();
+ return ((ch1 << 0) + (ch2 << 8) + (ch3 << 16) + (ch4 << 24));
+ }
+
+ public final long readLong() throws IOException
+ {
+ int i1 = readInt();
+ int i2 = readInt();
+ return ((long)(i1) & 0xFFFFFFFFL) + (i2 << 32);
+ }
+
+ public final float readFloat() throws IOException
+ {
+ return Float.intBitsToFloat(readInt());
+ }
+
+ public final double readDouble() throws IOException
+ {
+ return Double.longBitsToDouble(readLong());
+ }
+
+ /**
+ * dont call this it is not implemented.
+ * @return empty new string
+ **/
+ public final String readLine() throws IOException
+ {
+ return new String();
+ }
+
+ /**
+ * dont call this it is not implemented
+ * @return empty new string
+ **/
+ public final String readUTF() throws IOException
+ {
+ return new String();
+ }
+
+ /**
+ * dont call this it is not implemented
+ * @return empty new string
+ **/
+ public final static String readUTF(DataInput in) throws IOException
+ {
+ return new String();
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataOutputStream.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataOutputStream.java
new file mode 100755
index 000000000..e1e1ca924
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataOutputStream.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.FilterOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * Little Endian Data Output Stream.
+ *
+ * This class implements an output stream filter to allow writing
+ * of java native datatypes to an output stream which has those
+ * native datatypes stored in a little endian byte order.<p>
+ *
+ * This is the sister class of the DataOutputStream which allows
+ * for writing of java native datatypes to an output stream with
+ * the datatypes stored in big endian byte order.<p>
+ *
+ * This class implements the minimum required and calls DataOutputStream
+ * for some of the required methods for DataOutput.<p>
+ *
+ * Not all methods are implemented due to lack of immediate requirement
+ * for that functionality. It is not clear if it is ever going to be
+ * functionally required to be able to read UTF data in a LittleEndianManner<p>
+ *
+ */
+public class LEDataOutputStream extends FilterOutputStream implements DataOutput
+{
+ /**
+ * To reuse some of the non endian dependent methods from
+ * DataOutputStream's methods.
+ */
+ DataOutputStream dataOut;
+
+ public LEDataOutputStream(OutputStream out)
+ {
+ super(out);
+ dataOut = new DataOutputStream(out);
+ }
+
+ public void close() throws IOException
+ {
+ dataOut.close(); // better close as we create it.
+ // this will close underlying as well.
+ }
+
+ public synchronized final void write(byte b[]) throws IOException
+ {
+ dataOut.write(b, 0, b.length);
+ }
+
+ public synchronized final void write(byte b[], int off, int len) throws IOException
+ {
+ dataOut.write(b, off, len);
+ }
+
+ public final void write(int b) throws IOException
+ {
+ dataOut.write(b);
+ }
+
+ public final void writeBoolean(boolean v) throws IOException
+ {
+ dataOut.writeBoolean(v);
+ }
+
+ public final void writeByte(int v) throws IOException
+ {
+ dataOut.writeByte(v);
+ }
+
+ /** Don't call this -- not implemented */
+ public final void writeBytes(String s) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public final void writeChar(int v) throws IOException
+ {
+ dataOut.writeChar(((v >> 8) & 0xff) |
+ ((v & 0xff) << 8));
+ }
+
+ /** Don't call this -- not implemented */
+ public final void writeChars(String s) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public final void writeDouble(double v) throws IOException
+ {
+ writeLong(Double.doubleToRawLongBits(v));
+ }
+
+ public final void writeFloat(float v) throws IOException
+ {
+ writeInt(Float.floatToRawIntBits(v));
+ }
+
+ public final void writeInt(int v) throws IOException
+ {
+ dataOut.writeInt((v >>> 24) |
+ ((v >>> 8) & 0xff00) |
+ ((v << 8) & 0x00ff00) |
+ (v << 24));
+ }
+
+ public final void writeLong(long v) throws IOException
+ {
+ writeInt((int) v);
+ writeInt((int) (v >>> 32));
+ }
+
+ public final void writeShort(int v) throws IOException
+ {
+ dataOut.writeShort(((v >> 8) & 0xff) |
+ ((v & 0xff) << 8));
+ }
+
+ /** Don't call this -- not implemented */
+ public final void writeUTF(String s) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java
new file mode 100644
index 000000000..499dce7fb
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi;
+
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.texture.*;
+import com.jogamp.opengl.util.texture.spi.*;
+
+public class NetPbmTextureWriter implements TextureWriter {
+ int magic;
+
+ public NetPbmTextureWriter() {
+ this(0); // auto
+ }
+
+ /**
+ * supported magic values are:<br>
+ * <pre>
+ * magic 0 - detect by file suffix (TextureIO compliant)
+ * magic 6 - PPM binary RGB
+ * magic 7 - PAM binary RGB or RGBA
+ * </pre>
+ */
+ public NetPbmTextureWriter(int magic) {
+ switch(magic) {
+ case 0:
+ case 6:
+ case 7:
+ break;
+ default:
+ throw new GLException("Unsupported magic: "+magic+", should be 0 (auto), 6 (PPM) or 7 (PAM)");
+ }
+ this.magic = magic;
+ }
+
+ public int getMagic() { return magic; }
+
+ public static final String PPM = "ppm";
+ public static final String PAM = "pam";
+
+ public String getSuffix() { return (magic==6)?PPM:PAM; }
+
+ public boolean write(File file,
+ TextureData data) throws IOException {
+
+ // file suffix selection
+ if (0==magic) {
+ if (PPM.equals(FileUtil.getFileSuffix(file))) {
+ magic = 6;
+ } else if (PAM.equals(FileUtil.getFileSuffix(file))) {
+ magic = 7;
+ } else {
+ return false;
+ }
+ }
+
+ int pixelFormat = data.getPixelFormat();
+ int pixelType = data.getPixelType();
+ if ((pixelFormat == GL.GL_RGB ||
+ pixelFormat == GL.GL_RGBA) &&
+ (pixelType == GL.GL_BYTE ||
+ pixelType == GL.GL_UNSIGNED_BYTE)) {
+
+ int comps = ( pixelFormat == GL.GL_RGBA ) ? 4 : 3 ;
+
+ if(magic==6 && comps==4) {
+ throw new IOException("NetPbmTextureWriter magic 6 (PPM) doesn't RGBA pixel format, use magic 7 (PAM)");
+ }
+
+ FileOutputStream fos = new FileOutputStream(file);
+
+ StringBuffer header = new StringBuffer();
+ header.append("P");
+ header.append(magic);
+ header.append("\n");
+ if(7==magic) {
+ header.append("WIDTH ");
+ }
+ header.append(data.getWidth());
+ if(7==magic) {
+ header.append("\nHEIGHT ");
+ } else {
+ header.append(" ");
+ }
+ header.append(data.getHeight());
+ if(7==magic) {
+ header.append("\nDEPTH ");
+ header.append(comps);
+ header.append("\nMAXVAL 255\nTUPLTYPE ");
+ if(pixelFormat == GL.GL_RGBA) {
+ header.append("RGB_ALPHA");
+ } else {
+ header.append("RGB");
+ }
+ header.append("\nENDHDR\n");
+ } else {
+ header.append("\n255\n");
+ }
+
+ fos.write(header.toString().getBytes());
+
+ ByteBuffer buf = (ByteBuffer) data.getBuffer();
+ if (buf == null) {
+ buf = (ByteBuffer) data.getMipmapData()[0];
+ }
+ buf.rewind();
+
+ byte[] bufArray = null;
+
+ try {
+ bufArray = buf.array();
+ } catch (Throwable t) {}
+ if(null==bufArray) {
+ bufArray = new byte[data.getWidth()*data.getHeight()*comps];
+ buf.get(bufArray);
+ buf.rewind();
+ }
+
+ fos.write(bufArray);
+ fos.close();
+
+ return true;
+ }
+
+ throw new IOException("NetPbmTextureWriter writer doesn't support this pixel format / type (only GL_RGB/A + bytes)");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
new file mode 100755
index 000000000..bb5040a31
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
@@ -0,0 +1,670 @@
+/*
+ * Portions Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi;
+
+import java.io.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.*;
+
+/** <p> Reads and writes SGI RGB/RGBA images. </p>
+
+ <p> Written from <a href =
+ "http://astronomy.swin.edu.au/~pbourke/dataformats/sgirgb/">Paul
+ Bourke's adaptation</a> of the <a href =
+ "http://astronomy.swin.edu.au/~pbourke/dataformats/sgirgb/sgiversion.html">SGI
+ specification</a>. </p>
+*/
+
+public class SGIImage {
+ private Header header;
+ private int format;
+ private byte[] data;
+ // Used for decoding RLE-compressed images
+ private int[] rowStart;
+ private int[] rowSize;
+ private int rleEnd;
+ private byte[] tmpData;
+ private byte[] tmpRead;
+
+ private static final int MAGIC = 474;
+
+ static class Header {
+ short magic; // IRIS image file magic number
+ // This should be decimal 474
+ byte storage; // Storage format
+ // 0 for uncompressed
+ // 1 for RLE compression
+ byte bpc; // Number of bytes per pixel channel
+ // Legally 1 or 2
+ short dimension; // Number of dimensions
+ // Legally 1, 2, or 3
+ // 1 means a single row, XSIZE long
+ // 2 means a single 2D image
+ // 3 means multiple 2D images
+ short xsize; // X size in pixels
+ short ysize; // Y size in pixels
+ short zsize; // Number of channels
+ // 1 indicates greyscale
+ // 3 indicates RGB
+ // 4 indicates RGB and Alpha
+ int pixmin; // Minimum pixel value
+ // This is the lowest pixel value in the image
+ int pixmax; // Maximum pixel value
+ // This is the highest pixel value in the image
+ int dummy; // Ignored
+ // Normally set to 0
+ String imagename; // Image name; 80 bytes long
+ // Must be null terminated, therefore at most 79 bytes
+ int colormap; // Colormap ID
+ // 0 - normal mode
+ // 1 - dithered, 3 mits for red and green, 2 for blue, obsolete
+ // 2 - index colour, obsolete
+ // 3 - not an image but a colourmap
+ // 404 bytes char DUMMY Ignored
+ // Should be set to 0, makes the header 512 bytes.
+
+ Header() {
+ magic = MAGIC;
+ }
+
+ Header(DataInputStream in) throws IOException {
+ magic = in.readShort();
+ storage = in.readByte();
+ bpc = in.readByte();
+ dimension = in.readShort();
+ xsize = in.readShort();
+ ysize = in.readShort();
+ zsize = in.readShort();
+ pixmin = in.readInt();
+ pixmax = in.readInt();
+ dummy = in.readInt();
+ byte[] tmpname = new byte[80];
+ in.read(tmpname);
+ int numChars = 0;
+ while (tmpname[numChars++] != 0);
+ imagename = new String(tmpname, 0, numChars);
+ colormap = in.readInt();
+ byte[] tmp = new byte[404];
+ in.read(tmp);
+ }
+
+ public String toString() {
+ return ("magic: " + magic +
+ " storage: " + (int) storage +
+ " bpc: " + (int) bpc +
+ " dimension: " + dimension +
+ " xsize: " + xsize +
+ " ysize: " + ysize +
+ " zsize: " + zsize +
+ " pixmin: " + pixmin +
+ " pixmax: " + pixmax +
+ " imagename: " + imagename +
+ " colormap: " + colormap);
+ }
+ }
+
+ private SGIImage(Header header) {
+ this.header = header;
+ }
+
+ /** Reads an SGI image from the specified file. */
+ public static SGIImage read(String filename) throws IOException {
+ return read(new FileInputStream(filename));
+ }
+
+ /** Reads an SGI image from the specified InputStream. */
+ public static SGIImage read(InputStream in) throws IOException {
+ DataInputStream dIn = new DataInputStream(new BufferedInputStream(in));
+
+ Header header = new Header(dIn);
+ SGIImage res = new SGIImage(header);
+ res.decodeImage(dIn);
+ return res;
+ }
+
+ /** Writes this SGIImage to the specified file name. If
+ flipVertically is set, outputs the scanlines from top to bottom
+ rather than the default bottom to top order. */
+ public void write(String filename, boolean flipVertically) throws IOException {
+ write(new File(filename), flipVertically);
+ }
+
+ /** Writes this SGIImage to the specified file. If flipVertically is
+ set, outputs the scanlines from top to bottom rather than the
+ default bottom to top order. */
+ public void write(File file, boolean flipVertically) throws IOException {
+ writeImage(file, data, header.xsize, header.ysize, header.zsize, flipVertically);
+ }
+
+ /** Creates an SGIImage from the specified data in either RGB or
+ RGBA format. */
+ public static SGIImage createFromData(int width,
+ int height,
+ boolean hasAlpha,
+ byte[] data) {
+ Header header = new Header();
+ header.xsize = (short) width;
+ header.ysize = (short) height;
+ header.zsize = (short) (hasAlpha ? 4 : 3);
+ SGIImage image = new SGIImage(header);
+ image.data = data;
+ return image;
+ }
+
+ /** Determines from the magic number whether the given InputStream
+ points to an SGI RGB image. The given InputStream must return
+ true from markSupported() and support a minimum of two bytes
+ of read-ahead. */
+ public static boolean isSGIImage(InputStream in) throws IOException {
+ if (!(in instanceof BufferedInputStream)) {
+ in = new BufferedInputStream(in);
+ }
+ if (!in.markSupported()) {
+ throw new IOException("Can not test non-destructively whether given InputStream is an SGI RGB image");
+ }
+ DataInputStream dIn = new DataInputStream(in);
+ dIn.mark(4);
+ short magic = dIn.readShort();
+ dIn.reset();
+ return (magic == MAGIC);
+ }
+
+ /** Returns the width of the image. */
+ public int getWidth() {
+ return header.xsize;
+ }
+
+ /** Returns the height of the image. */
+ public int getHeight() {
+ return header.ysize;
+ }
+
+ /** Returns the OpenGL format for this texture; e.g. GL.GL_RGB or GL.GL_RGBA. */
+ public int getFormat() {
+ return format;
+ }
+
+ /** Returns the raw data for this texture in the correct
+ (bottom-to-top) order for calls to glTexImage2D. */
+ public byte[] getData() { return data; }
+
+ public String toString() {
+ return header.toString();
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private void decodeImage(DataInputStream in) throws IOException {
+ if (header.storage == 1) {
+ // Read RLE compression data; row starts and sizes
+ int x = header.ysize * header.zsize;
+ rowStart = new int[x];
+ rowSize = new int[x];
+ rleEnd = 4 * 2 * x + 512;
+ for (int i = 0; i < x; i++) {
+ rowStart[i] = in.readInt();
+ }
+ for (int i = 0; i < x; i++) {
+ rowSize[i] = in.readInt();
+ }
+ tmpRead = new byte[header.xsize * 256];
+ }
+ tmpData = readAll(in);
+
+ int xsize = header.xsize;
+ int ysize = header.ysize;
+ int zsize = header.zsize;
+ int lptr = 0;
+
+ data = new byte[xsize * ysize * 4];
+ byte[] rbuf = new byte[xsize];
+ byte[] gbuf = new byte[xsize];
+ byte[] bbuf = new byte[xsize];
+ byte[] abuf = new byte[xsize];
+ for (int y = 0; y < ysize; y++) {
+ if (zsize >= 4) {
+ getRow(rbuf, y, 0);
+ getRow(gbuf, y, 1);
+ getRow(bbuf, y, 2);
+ getRow(abuf, y, 3);
+ rgbatorgba(rbuf, gbuf, bbuf, abuf, data, lptr);
+ } else if (zsize == 3) {
+ getRow(rbuf, y, 0);
+ getRow(gbuf, y, 1);
+ getRow(bbuf, y, 2);
+ rgbtorgba(rbuf, gbuf, bbuf, data, lptr);
+ } else if (zsize == 2) {
+ getRow(rbuf, y, 0);
+ getRow(abuf, y, 1);
+ latorgba(rbuf, abuf, data, lptr);
+ } else {
+ getRow(rbuf, y, 0);
+ bwtorgba(rbuf, data, lptr);
+ }
+ lptr += 4 * xsize;
+ }
+ rowStart = null;
+ rowSize = null;
+ tmpData = null;
+ tmpRead = null;
+ format = GL.GL_RGBA;
+ header.zsize = 4;
+ }
+
+ private void getRow(byte[] buf, int y, int z) {
+ if (header.storage == 1) {
+ int offs = rowStart[y + z * header.ysize] - rleEnd;
+ System.arraycopy(tmpData, offs, tmpRead, 0, rowSize[y + z * header.ysize]);
+ int iPtr = 0;
+ int oPtr = 0;
+ for (;;) {
+ byte pixel = tmpRead[iPtr++];
+ int count = (int) (pixel & 0x7F);
+ if (count == 0) {
+ return;
+ }
+ if ((pixel & 0x80) != 0) {
+ while ((count--) > 0) {
+ buf[oPtr++] = tmpRead[iPtr++];
+ }
+ } else {
+ pixel = tmpRead[iPtr++];
+ while ((count--) > 0) {
+ buf[oPtr++] = pixel;
+ }
+ }
+ }
+ } else {
+ int offs = (y * header.xsize) + (z * header.xsize * header.ysize);
+ System.arraycopy(tmpData, offs, buf, 0, header.xsize);
+ }
+ }
+
+ private void bwtorgba(byte[] b, byte[] dest, int lptr) {
+ for (int i = 0; i < b.length; i++) {
+ dest[4 * i + lptr + 0] = b[i];
+ dest[4 * i + lptr + 1] = b[i];
+ dest[4 * i + lptr + 2] = b[i];
+ dest[4 * i + lptr + 3] = (byte) 0xFF;
+ }
+ }
+
+ private void latorgba(byte[] b, byte[] a, byte[] dest, int lptr) {
+ for (int i = 0; i < b.length; i++) {
+ dest[4 * i + lptr + 0] = b[i];
+ dest[4 * i + lptr + 1] = b[i];
+ dest[4 * i + lptr + 2] = b[i];
+ dest[4 * i + lptr + 3] = a[i];
+ }
+ }
+
+ private void rgbtorgba(byte[] r, byte[] g, byte[] b, byte[] dest, int lptr) {
+ for (int i = 0; i < b.length; i++) {
+ dest[4 * i + lptr + 0] = r[i];
+ dest[4 * i + lptr + 1] = g[i];
+ dest[4 * i + lptr + 2] = b[i];
+ dest[4 * i + lptr + 3] = (byte) 0xFF;
+ }
+ }
+
+ private void rgbatorgba(byte[] r, byte[] g, byte[] b, byte[] a, byte[] dest, int lptr) {
+ for (int i = 0; i < b.length; i++) {
+ dest[4 * i + lptr + 0] = r[i];
+ dest[4 * i + lptr + 1] = g[i];
+ dest[4 * i + lptr + 2] = b[i];
+ dest[4 * i + lptr + 3] = a[i];
+ }
+ }
+
+ private static byte imgref(byte[] i,
+ int x,
+ int y,
+ int z,
+ int xs,
+ int ys,
+ int zs) {
+ return i[(xs*ys*z)+(xs*y)+x];
+ }
+
+
+ private void writeHeader(DataOutputStream stream,
+ int xsize, int ysize, int zsize, boolean rle) throws IOException {
+ // effects: outputs the 512-byte IRIS RGB header to STREAM, using xsize,
+ // ysize, and depth as the dimensions of the image. NOTE that
+ // the following defaults are used:
+ // STORAGE = 1 (storage format = RLE)
+ // BPC = 1 (# bytes/channel)
+ // DIMENSION = 3
+ // PIXMIN = 0
+ // PIXMAX = 255
+ // IMAGENAME = <80 nulls>
+ // COLORMAP = 0
+ // See ftp://ftp.sgi.com/pub/sgi/SGIIMAGESPEC for more details.
+
+ // write out MAGIC, STORAGE, BPC
+ stream.writeShort(474);
+ stream.write((rle ? 1 : 0));
+ stream.write(1);
+
+ // write out DIMENSION
+ stream.writeShort(3);
+
+ // write XSIZE, YSIZE, ZSIZE
+ stream.writeShort(xsize);
+ stream.writeShort(ysize);
+ stream.writeShort(zsize);
+
+ // write PIXMIN, PIXMAX
+ stream.writeInt(0);
+ stream.writeInt(255);
+
+ // write DUMMY
+ stream.writeInt(0);
+
+ // write IMAGENAME
+ for (int i = 0; i < 80; i++)
+ stream.write(0);
+
+ // write COLORMAP
+ stream.writeInt(0);
+
+ // write DUMMY (404 bytes)
+ for (int i = 0; i < 404; i++)
+ stream.write(0);
+ }
+
+ private void writeImage(File file,
+ byte[] data,
+ int xsize,
+ int ysize,
+ int zsize,
+ boolean yflip) throws IOException {
+ // Input data is in RGBRGBRGB or RGBARGBARGBA format; first unswizzle it
+ byte[] tmpData = new byte[xsize * ysize * zsize];
+ int dest = 0;
+ for (int i = 0; i < zsize; i++) {
+ for (int j = i; j < (xsize * ysize * zsize); j += zsize) {
+ tmpData[dest++] = data[j];
+ }
+ }
+ data = tmpData;
+
+ // requires: DATA must be an array of size XSIZE * YSIZE * ZSIZE,
+ // indexed in the following manner:
+ // data[0] ...data[xsize-1] == first row of first channel
+ // data[xsize]...data[2*xsize-1] == second row of first channel
+ // ... data[(ysize - 1) * xsize]...data[(ysize * xsize) - 1] ==
+ // last row of first channel
+ // Later channels follow the same format.
+ // *** NOTE that "first row" is defined by the BOTTOM ROW of
+ // the image. That is, the origin is in the lower left corner.
+ // effects: writes out an SGI image to FILE, RLE-compressed, INCLUDING
+ // header, of dimensions (xsize, ysize, zsize), and containing
+ // the data in DATA. If YFLIP is set, outputs the data in DATA
+ // in reverse order vertically (equivalent to a flip about the
+ // x axis).
+
+ // Build the offset tables
+ int[] starttab = new int[ysize * zsize];
+ int[] lengthtab = new int[ysize * zsize];
+
+ // Temporary buffer for holding RLE data.
+ // Note that this makes the assumption that RLE-compressed data will
+ // never exceed twice the size of the input data.
+ // There are surely formal proofs about how big the RLE buffer should
+ // be, as well as what the optimal look-ahead size is (i.e. don't switch
+ // copy/repeat modes for less than N repeats). However, I'm going from
+ // empirical evidence here; the break-even point seems to be a look-
+ // ahead of 3. (That is, if the three values following this one are all
+ // the same as the current value, switch to repeat mode.)
+ int lookahead = 3;
+ byte[] rlebuf = new byte[2 * xsize * ysize * zsize];
+
+ int cur_loc = 0; // current offset location.
+ int ptr = 0;
+ int total_size = 0;
+ int ystart = 0;
+ int yincr = 1;
+ int yend = ysize;
+
+ if (yflip) {
+ ystart = ysize - 1;
+ yend = -1;
+ yincr = -1;
+ }
+
+ boolean DEBUG = false;
+
+ for (int z = 0; z < zsize; z++) {
+ for (int y = ystart; y != yend; y += yincr) {
+ // RLE-compress each row.
+
+ int x = 0;
+ byte count = 0;
+ boolean repeat_mode = false;
+ boolean should_switch = false;
+ int start_ptr = ptr;
+ int num_ptr = ptr++;
+ byte repeat_val = 0;
+
+ while (x < xsize) {
+ // see if we should switch modes
+ should_switch = false;
+ if (repeat_mode) {
+ if (imgref(data, x, y, z, xsize, ysize, zsize) != repeat_val) {
+ should_switch = true;
+ }
+ } else {
+ // look ahead to see if we should switch to repeat mode.
+ // stay within the scanline for the lookahead
+ if ((x + lookahead) < xsize) {
+ should_switch = true;
+ for (int i = 1; i <= lookahead; i++) {
+ if (DEBUG)
+ System.err.println("left side was " + ((int) imgref(data, x, y, z, xsize, ysize, zsize)) +
+ ", right side was " + (int)imgref(data, x+i, y, z, xsize, ysize, zsize));
+
+ if (imgref(data, x, y, z, xsize, ysize, zsize) !=
+ imgref(data, x+i, y, z, xsize, ysize, zsize))
+ should_switch = false;
+ }
+ }
+ }
+
+ if (should_switch || (count == 127)) {
+ // update the number of elements we repeated/copied
+ if (x > 0) {
+ if (repeat_mode)
+ rlebuf[num_ptr] = count;
+ else
+ rlebuf[num_ptr] = (byte) (count | 0x80);
+ }
+ // perform mode switch if necessary; output repeat_val if
+ // switching FROM repeat mode, and set it if switching
+ // TO repeat mode.
+ if (repeat_mode) {
+ if (should_switch)
+ repeat_mode = false;
+ rlebuf[ptr++] = repeat_val;
+ } else {
+ if (should_switch)
+ repeat_mode = true;
+ repeat_val = imgref(data, x, y, z, xsize, ysize, zsize);
+ }
+
+ if (x > 0) {
+ // reset the number pointer
+ num_ptr = ptr++;
+ // reset number of bytes copied
+ count = 0;
+ }
+ }
+
+ // if not in repeat mode, copy element to ptr
+ if (!repeat_mode) {
+ rlebuf[ptr++] = imgref(data, x, y, z, xsize, ysize, zsize);
+ }
+ count++;
+
+ if (x == xsize - 1) {
+ // Need to store the number of pixels we copied/repeated.
+ if (repeat_mode) {
+ rlebuf[num_ptr] = count;
+ // If we ended the row in repeat mode, store the
+ // repeated value
+ rlebuf[ptr++] = repeat_val;
+ }
+ else
+ rlebuf[num_ptr] = (byte) (count | 0x80);
+
+ // output zero counter for the last value in the row
+ rlebuf[ptr++] = 0;
+ }
+
+ x++;
+ }
+ // output this row's length into the length table
+ int rowlen = ptr - start_ptr;
+ if (yflip)
+ lengthtab[ysize*z+(ysize-y-1)] = rowlen;
+ else
+ lengthtab[ysize*z+y] = rowlen;
+ // add to the start table, and update the current offset
+ if (yflip)
+ starttab[ysize*z+(ysize-y-1)] = cur_loc;
+ else
+ starttab[ysize*z+y] = cur_loc;
+ cur_loc += rowlen;
+ }
+ }
+
+ // Now we have the offset tables computed, as well as the RLE data.
+ // Output this information to the file.
+ total_size = ptr;
+
+ if (DEBUG)
+ System.err.println("total_size was " + total_size);
+
+ DataOutputStream stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
+
+ writeHeader(stream, xsize, ysize, zsize, true);
+
+ int SIZEOF_INT = 4;
+ for (int i = 0; i < (ysize * zsize); i++)
+ stream.writeInt(starttab[i] + 512 + (2 * ysize * zsize * SIZEOF_INT));
+ for (int i = 0; i < (ysize * zsize); i++)
+ stream.writeInt(lengthtab[i]);
+ for (int i = 0; i < total_size; i++)
+ stream.write(rlebuf[i]);
+
+ stream.close();
+ }
+
+ private byte[] readAll(DataInputStream in) throws IOException {
+ byte[] dest = new byte[16384];
+ int pos = 0;
+ int numRead = 0;
+
+ boolean done = false;
+
+ do {
+ numRead = in.read(dest, pos, dest.length - pos);
+ if (pos == dest.length) {
+ // Resize destination buffer
+ byte[] newDest = new byte[2 * dest.length];
+ System.arraycopy(dest, 0, newDest, 0, pos);
+ dest = newDest;
+ }
+ if (numRead > 0) {
+ pos += numRead;
+ }
+
+ done = ((numRead == -1) || (in.available() == 0));
+ } while (!done);
+
+ // Trim destination buffer
+ if (pos != dest.length) {
+ byte[] finalDest = new byte[pos];
+ System.arraycopy(dest, 0, finalDest, 0, pos);
+ dest = finalDest;
+ }
+
+ return dest;
+ }
+
+ // Test case
+ /*
+ import java.awt.image.*;
+ import javax.swing.*;
+
+ public static void main(String[] args) {
+ for (int i = 0; i < args.length; i++) {
+ try {
+ System.out.println(args[i] + ":");
+ SGIImage image = SGIImage.read(args[i]);
+ System.out.println(image);
+ BufferedImage img = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
+ WritableRaster raster = img.getRaster();
+ DataBufferByte db = (DataBufferByte) raster.getDataBuffer();
+ byte[] src = image.getData();
+ byte[] dest = db.getData();
+ for (int j = 0; j < src.length; j += 4) {
+ dest[j + 0] = src[j + 3];
+ dest[j + 1] = src[j + 2];
+ dest[j + 2] = src[j + 1];
+ dest[j + 3] = src[j + 0];
+ }
+ // System.arraycopy(src, 0, dest, 0, src.length);
+ ImageIcon icon = new ImageIcon(img);
+ JLabel label = new JLabel();
+ label.setIcon(icon);
+ JFrame frame = new JFrame(args[i]);
+ frame.getContentPane().add(label);
+ frame.pack();
+ frame.show();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ */
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java.javame_cdc_fp b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java.javame_cdc_fp
new file mode 100755
index 000000000..6e6e4ab04
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java.javame_cdc_fp
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi;
+
+import java.io.*;
+import java.nio.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.texture.spi.*;
+import com.jogamp.opengl.util.texture.*;
+
+/**
+ * Targa image reader and writer adapted from sources of the <a href =
+ * "http://java.sun.com/products/jimi/">Jimi</a> image I/O class library.
+ *
+ * <P>
+ *
+ * Image decoder for image data stored in TGA file format.
+ * Currently only the original TGA file format is supported. This is
+ * because the new TGA format has data at the end of the file, getting
+ * to the end of a file in an InputStream orient environment presents
+ * several difficulties which are avoided at the moment.
+ *
+ * <P>
+ *
+ * This is a simple decoder and is only setup to load a single image
+ * from the input stream
+ *
+ * <P>
+ *
+ * @author Robin Luiten
+ * @author Kenneth Russell
+ * @version $Revision: 1768 $
+ */
+
+public class TGAImage {
+ private Header header;
+ private int format;
+ private int bpp;
+ private ByteBuffer data;
+
+ private TGAImage(Header header) {
+ this.header = header;
+ }
+
+ /**
+ * This class reads in all of the TGA image header in addition it also
+ * reads in the imageID field as it is convenient to handle that here.
+ *
+ * @author Robin Luiten
+ * @version 1.1
+ */
+ public static class Header {
+ /** Set of possible file format TGA types */
+ public final static int TYPE_NEW = 0;
+ public final static int TYPE_OLD = 1;
+ public final static int TYPE_UNK = 2; // cant rewind stream so unknown for now.
+
+ /** Set of possible image types in TGA file */
+ public final static int NO_IMAGE = 0; // no image data
+ public final static int UCOLORMAPPED = 1; // uncompressed color mapped image
+ public final static int UTRUECOLOR = 2; // uncompressed true color image
+ public final static int UBLACKWHITE = 3; // uncompressed black and white image
+ public final static int COLORMAPPED = 9; // compressed color mapped image
+ public final static int TRUECOLOR = 10; // compressed true color image
+ public final static int BLACKWHITE = 11; // compressed black and white image
+
+ /** Field image descriptor bitfield values definitions */
+ public final static int ID_ATTRIBPERPIXEL = 0xF;
+ public final static int ID_RIGHTTOLEFT = 0x10;
+ public final static int ID_TOPTOBOTTOM = 0x20;
+ public final static int ID_INTERLEAVE = 0xC0;
+
+ /** Field image descriptor / interleave values */
+ public final static int I_NOTINTERLEAVED = 0;
+ public final static int I_TWOWAY = 1;
+ public final static int I_FOURWAY = 2;
+
+ /** Type of this TGA file format */
+ private int tgaType;
+
+ /** initial TGA image data fields */
+ private int idLength; // byte value
+ private int colorMapType; // byte value
+ private int imageType; // byte value
+
+ /** TGA image colour map fields */
+ private int firstEntryIndex;
+ private int colorMapLength;
+ private byte colorMapEntrySize;
+
+ /** TGA image specification fields */
+ private int xOrigin;
+ private int yOrigin;
+ private int width;
+ private int height;
+ private byte pixelDepth;
+ private byte imageDescriptor;
+
+ private byte[] imageIDbuf;
+ private String imageID;
+
+ // For construction from user data
+ Header() {
+ tgaType = TYPE_OLD; // dont try and get footer.
+ }
+
+ Header(LEDataInputStream in) throws IOException {
+ int ret;
+
+ tgaType = TYPE_OLD; // dont try and get footer.
+
+ // initial header fields
+ idLength = in.readUnsignedByte();
+ colorMapType = in.readUnsignedByte();
+ imageType = in.readUnsignedByte();
+
+ // color map header fields
+ firstEntryIndex = in.readUnsignedShort();
+ colorMapLength = in.readUnsignedShort();
+ colorMapEntrySize = in.readByte();
+
+ // TGA image specification fields
+ xOrigin = in.readUnsignedShort();
+ yOrigin = in.readUnsignedShort();
+ width = in.readUnsignedShort();
+ height = in.readUnsignedShort();
+ pixelDepth = in.readByte();
+ imageDescriptor = in.readByte();
+
+ if (idLength > 0) {
+ imageIDbuf = new byte[idLength];
+ in.read(imageIDbuf, 0, idLength);
+ imageID = new String(imageIDbuf, "US-ASCII");
+ }
+ }
+
+ public int tgaType() { return tgaType; }
+
+ /** initial TGA image data fields */
+ public int idLength() { return idLength; }
+ public int colorMapType() { return colorMapType; }
+ public int imageType() { return imageType; }
+
+ /** TGA image colour map fields */
+ public int firstEntryIndex() { return firstEntryIndex; }
+ public int colorMapLength() { return colorMapLength; }
+ public byte colorMapEntrySize() { return colorMapEntrySize; }
+
+ /** TGA image specification fields */
+ public int xOrigin() { return xOrigin; }
+ public int yOrigin() { return yOrigin; }
+ public int width() { return width; }
+ public int height() { return height; }
+ public byte pixelDepth() { return pixelDepth; }
+ public byte imageDescriptor() { return imageDescriptor; }
+
+ /** bitfields in imageDescriptor */
+ public byte attribPerPixel() { return (byte)(imageDescriptor & ID_ATTRIBPERPIXEL); }
+ public boolean rightToLeft() { return ((imageDescriptor & ID_RIGHTTOLEFT) != 0); }
+ public boolean topToBottom() { return ((imageDescriptor & ID_TOPTOBOTTOM) != 0); }
+ public byte interleave() { return (byte)((imageDescriptor & ID_INTERLEAVE) >> 6); }
+
+ public byte[] imageIDbuf() { return imageIDbuf; }
+ public String imageID() { return imageID; }
+
+ public String toString() {
+ return "TGA Header " +
+ " id length: " + idLength +
+ " color map type: "+ colorMapType +
+ " image type: "+ imageType +
+ " first entry index: " + firstEntryIndex +
+ " color map length: " + colorMapLength +
+ " color map entry size: " + colorMapEntrySize +
+ " x Origin: " + xOrigin +
+ " y Origin: " + yOrigin +
+ " width: "+ width +
+ " height: "+ height +
+ " pixel depth: "+ pixelDepth +
+ " image descriptor: "+ imageDescriptor +
+ (imageIDbuf == null ? "" : (" ID String: " + imageID));
+ }
+
+ public int size() { return 18 + idLength; }
+
+ private void write(LEDataOutputStream output) throws IOException {
+ output.write(idLength);
+ output.write(colorMapType);
+ output.write(imageType);
+ output.writeShort(firstEntryIndex);
+ output.writeShort(colorMapLength);
+ output.write(colorMapEntrySize);
+ output.writeShort(xOrigin);
+ output.writeShort(yOrigin);
+ output.writeShort(width);
+ output.writeShort(height);
+ output.write(pixelDepth);
+ output.write(imageDescriptor);
+ if (idLength > 0) {
+ try {
+ byte[] chars = imageID.getBytes("US-ASCII");
+ output.write(chars);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Identifies the image type of the tga image data and loads
+ * it into the JimiImage structure. This was taken from the
+ * prototype and modified for the new Jimi structure
+ */
+ private void decodeImage(LEDataInputStream dIn) throws IOException {
+ switch (header.imageType()) {
+ case Header.UCOLORMAPPED:
+ throw new IOException("TGADecoder Uncompressed Colormapped images not supported");
+
+ case Header.UTRUECOLOR: // pixelDepth 15, 16, 24 and 32
+ switch (header.pixelDepth) {
+ case 16:
+ throw new IOException("TGADecoder Compressed 16-bit True Color images not supported");
+
+ case 24:
+ case 32:
+ decodeRGBImageU24_32(dIn);
+ break;
+ }
+ break;
+
+ case Header.UBLACKWHITE:
+ throw new IOException("TGADecoder Uncompressed Grayscale images not supported");
+
+ case Header.COLORMAPPED:
+ throw new IOException("TGADecoder Compressed Colormapped images not supported");
+
+ case Header.TRUECOLOR:
+ throw new IOException("TGADecoder Compressed True Color images not supported");
+
+ case Header.BLACKWHITE:
+ throw new IOException("TGADecoder Compressed Grayscale images not supported");
+ }
+ }
+
+ /**
+ * This assumes that the body is for a 24 bit or 32 bit for a
+ * RGB or ARGB image respectively.
+ */
+ private void decodeRGBImageU24_32(LEDataInputStream dIn) throws IOException {
+ int i; // row index
+ int j; // column index
+ int y; // output row index
+ int raw; // index through the raw input buffer
+ int rawWidth = header.width() * (header.pixelDepth() / 8);
+ byte[] rawBuf = new byte[rawWidth];
+ byte[] tmpData = new byte[rawWidth * header.height()];
+
+ for (i = 0; i < header.height(); ++i) {
+ dIn.readFully(rawBuf, 0, rawWidth);
+
+ if (header.topToBottom())
+ y = header.height - i - 1; // range 0 to (header.height - 1)
+ else
+ y = i;
+
+ System.arraycopy(rawBuf, 0, tmpData, y * rawWidth, rawBuf.length);
+ }
+
+ GL gl = GLContext.getCurrentGL();
+ if (header.pixelDepth() == 24) {
+ bpp=3;
+ if(gl.isGL2GL3()) {
+ format = GL2GL3.GL_BGR;
+ } else {
+ format = GL.GL_RGB;
+ swapBGR(tmpData, rawWidth, header.height(), bpp);
+ }
+ } else {
+ assert header.pixelDepth() == 32;
+ bpp=4;
+
+ if(gl.isGL2GL3()) {
+ format = GL2GL3.GL_BGRA;
+ } else {
+ format = GL.GL_RGBA;
+ swapBGR(tmpData, rawWidth, header.height(), bpp);
+ }
+ }
+
+ data = ByteBuffer.wrap(tmpData);
+ }
+
+ private static void swapBGR(byte[] data, int bWidth, int height, int bpp) {
+ byte r,b;
+ int k;
+ for(int i=0; i<height; ++i) {
+ for(int j=0; j<bWidth; j+=bpp) {
+ k=i*bWidth+j;
+ b=data[k+0];
+ r=data[k+2];
+ data[k+0]=r;
+ data[k+2]=b;
+ }
+ }
+ }
+
+ /** Returns the width of the image. */
+ public int getWidth() { return header.width(); }
+
+ /** Returns the height of the image. */
+ public int getHeight() { return header.height(); }
+
+ /** Returns the OpenGL format for this texture; e.g. GL.GL_BGR or GL.GL_BGRA. */
+ public int getGLFormat() { return format; }
+
+ /** Returns the bytes per pixel */
+ public int getBytesPerPixel() { return bpp; }
+
+ /** Returns the raw data for this texture in the correct
+ (bottom-to-top) order for calls to glTexImage2D. */
+ public ByteBuffer getData() { return data; }
+
+ /** Reads a Targa image from the specified file. */
+ public static TGAImage read(String filename) throws IOException {
+ return read(new FileInputStream(filename));
+ }
+
+ /** Reads a Targa image from the specified InputStream. */
+ public static TGAImage read(InputStream in) throws IOException {
+ LEDataInputStream dIn = new LEDataInputStream(new BufferedInputStream(in));
+
+ Header header = new Header(dIn);
+ TGAImage res = new TGAImage(header);
+ res.decodeImage(dIn);
+ return res;
+ }
+
+ /** Writes the image in Targa format to the specified file name. */
+ public void write(String filename) throws IOException {
+ write(new File(filename));
+ }
+
+ /** Writes the image in Targa format to the specified file. */
+ public void write(File file) throws IOException {
+ LEDataOutputStream output =
+ new LEDataOutputStream(new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))));
+ header.write(output);
+ if (!data.isDirect()) {
+ output.write(data.array());
+ } else {
+ for (int i = 0; i < data.limit(); i++) {
+ output.write(data.get(i));
+ }
+ }
+ output.close();
+ }
+
+ /** Creates a TGAImage from data supplied by the end user. Shares
+ data with the passed ByteBuffer. Assumes the data is already in
+ the correct byte order for writing to disk, i.e., BGR or
+ BGRA. */
+ public static TGAImage createFromData(int width,
+ int height,
+ boolean hasAlpha,
+ boolean topToBottom,
+ ByteBuffer data) {
+ Header header = new Header();
+ header.imageType = Header.UTRUECOLOR;
+ header.width = width;
+ header.height = height;
+ header.pixelDepth = (byte) (hasAlpha ? 32 : 24);
+ header.imageDescriptor = (byte) (topToBottom ? Header.ID_TOPTOBOTTOM : 0);
+ // Note ID not supported
+ TGAImage ret = new TGAImage(header);
+ ret.data = data;
+ return ret;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java.javase b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java.javase
new file mode 100755
index 000000000..16ba538b5
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java.javase
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.texture.spi.*;
+import com.jogamp.opengl.util.texture.*;
+
+/**
+ * Targa image reader and writer adapted from sources of the <a href =
+ * "http://java.sun.com/products/jimi/">Jimi</a> image I/O class library.
+ *
+ * <P>
+ *
+ * Image decoder for image data stored in TGA file format.
+ * Currently only the original TGA file format is supported. This is
+ * because the new TGA format has data at the end of the file, getting
+ * to the end of a file in an InputStream orient environment presents
+ * several difficulties which are avoided at the moment.
+ *
+ * <P>
+ *
+ * This is a simple decoder and is only setup to load a single image
+ * from the input stream
+ *
+ * <P>
+ *
+ * @author Robin Luiten
+ * @author Kenneth Russell
+ * @version $Revision: 1768 $
+ */
+
+public class TGAImage {
+ private Header header;
+ private int format;
+ private int bpp;
+ private ByteBuffer data;
+
+ private TGAImage(Header header) {
+ this.header = header;
+ }
+
+ /**
+ * This class reads in all of the TGA image header in addition it also
+ * reads in the imageID field as it is convenient to handle that here.
+ *
+ * @author Robin Luiten
+ * @version 1.1
+ */
+ public static class Header {
+ /** Set of possible file format TGA types */
+ public final static int TYPE_NEW = 0;
+ public final static int TYPE_OLD = 1;
+ public final static int TYPE_UNK = 2; // cant rewind stream so unknown for now.
+
+ /** Set of possible image types in TGA file */
+ public final static int NO_IMAGE = 0; // no image data
+ public final static int UCOLORMAPPED = 1; // uncompressed color mapped image
+ public final static int UTRUECOLOR = 2; // uncompressed true color image
+ public final static int UBLACKWHITE = 3; // uncompressed black and white image
+ public final static int COLORMAPPED = 9; // compressed color mapped image
+ public final static int TRUECOLOR = 10; // compressed true color image
+ public final static int BLACKWHITE = 11; // compressed black and white image
+
+ /** Field image descriptor bitfield values definitions */
+ public final static int ID_ATTRIBPERPIXEL = 0xF;
+ public final static int ID_RIGHTTOLEFT = 0x10;
+ public final static int ID_TOPTOBOTTOM = 0x20;
+ public final static int ID_INTERLEAVE = 0xC0;
+
+ /** Field image descriptor / interleave values */
+ public final static int I_NOTINTERLEAVED = 0;
+ public final static int I_TWOWAY = 1;
+ public final static int I_FOURWAY = 2;
+
+ /** Type of this TGA file format */
+ private int tgaType;
+
+ /** initial TGA image data fields */
+ private int idLength; // byte value
+ private int colorMapType; // byte value
+ private int imageType; // byte value
+
+ /** TGA image colour map fields */
+ private int firstEntryIndex;
+ private int colorMapLength;
+ private byte colorMapEntrySize;
+
+ /** TGA image specification fields */
+ private int xOrigin;
+ private int yOrigin;
+ private int width;
+ private int height;
+ private byte pixelDepth;
+ private byte imageDescriptor;
+
+ private byte[] imageIDbuf;
+ private String imageID;
+
+ // For construction from user data
+ Header() {
+ tgaType = TYPE_OLD; // dont try and get footer.
+ }
+
+ Header(LEDataInputStream in) throws IOException {
+ int ret;
+
+ tgaType = TYPE_OLD; // dont try and get footer.
+
+ // initial header fields
+ idLength = in.readUnsignedByte();
+ colorMapType = in.readUnsignedByte();
+ imageType = in.readUnsignedByte();
+
+ // color map header fields
+ firstEntryIndex = in.readUnsignedShort();
+ colorMapLength = in.readUnsignedShort();
+ colorMapEntrySize = in.readByte();
+
+ // TGA image specification fields
+ xOrigin = in.readUnsignedShort();
+ yOrigin = in.readUnsignedShort();
+ width = in.readUnsignedShort();
+ height = in.readUnsignedShort();
+ pixelDepth = in.readByte();
+ imageDescriptor = in.readByte();
+
+ if (idLength > 0) {
+ imageIDbuf = new byte[idLength];
+ in.read(imageIDbuf, 0, idLength);
+ imageID = new String(imageIDbuf, "US-ASCII");
+ }
+ }
+
+ public int tgaType() { return tgaType; }
+
+ /** initial TGA image data fields */
+ public int idLength() { return idLength; }
+ public int colorMapType() { return colorMapType; }
+ public int imageType() { return imageType; }
+
+ /** TGA image colour map fields */
+ public int firstEntryIndex() { return firstEntryIndex; }
+ public int colorMapLength() { return colorMapLength; }
+ public byte colorMapEntrySize() { return colorMapEntrySize; }
+
+ /** TGA image specification fields */
+ public int xOrigin() { return xOrigin; }
+ public int yOrigin() { return yOrigin; }
+ public int width() { return width; }
+ public int height() { return height; }
+ public byte pixelDepth() { return pixelDepth; }
+ public byte imageDescriptor() { return imageDescriptor; }
+
+ /** bitfields in imageDescriptor */
+ public byte attribPerPixel() { return (byte)(imageDescriptor & ID_ATTRIBPERPIXEL); }
+ public boolean rightToLeft() { return ((imageDescriptor & ID_RIGHTTOLEFT) != 0); }
+ public boolean topToBottom() { return ((imageDescriptor & ID_TOPTOBOTTOM) != 0); }
+ public byte interleave() { return (byte)((imageDescriptor & ID_INTERLEAVE) >> 6); }
+
+ public byte[] imageIDbuf() { return imageIDbuf; }
+ public String imageID() { return imageID; }
+
+ public String toString() {
+ return "TGA Header " +
+ " id length: " + idLength +
+ " color map type: "+ colorMapType +
+ " image type: "+ imageType +
+ " first entry index: " + firstEntryIndex +
+ " color map length: " + colorMapLength +
+ " color map entry size: " + colorMapEntrySize +
+ " x Origin: " + xOrigin +
+ " y Origin: " + yOrigin +
+ " width: "+ width +
+ " height: "+ height +
+ " pixel depth: "+ pixelDepth +
+ " image descriptor: "+ imageDescriptor +
+ (imageIDbuf == null ? "" : (" ID String: " + imageID));
+ }
+
+ public int size() { return 18 + idLength; }
+
+ // buf must be in little-endian byte order
+ private void write(ByteBuffer buf) {
+ buf.put((byte) idLength);
+ buf.put((byte) colorMapType);
+ buf.put((byte) imageType);
+ buf.putShort((short) firstEntryIndex);
+ buf.putShort((short) colorMapLength);
+ buf.put((byte) colorMapEntrySize);
+ buf.putShort((short) xOrigin);
+ buf.putShort((short) yOrigin);
+ buf.putShort((short) width);
+ buf.putShort((short) height);
+ buf.put((byte) pixelDepth);
+ buf.put((byte) imageDescriptor);
+ if (idLength > 0) {
+ try {
+ byte[] chars = imageID.getBytes("US-ASCII");
+ buf.put(chars);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Identifies the image type of the tga image data and loads
+ * it into the JimiImage structure. This was taken from the
+ * prototype and modified for the new Jimi structure
+ */
+ private void decodeImage(LEDataInputStream dIn) throws IOException {
+ switch (header.imageType()) {
+ case Header.UCOLORMAPPED:
+ throw new IOException("TGADecoder Uncompressed Colormapped images not supported");
+
+ case Header.UTRUECOLOR: // pixelDepth 15, 16, 24 and 32
+ switch (header.pixelDepth) {
+ case 16:
+ throw new IOException("TGADecoder Compressed 16-bit True Color images not supported");
+
+ case 24:
+ case 32:
+ decodeRGBImageU24_32(dIn);
+ break;
+ }
+ break;
+
+ case Header.UBLACKWHITE:
+ throw new IOException("TGADecoder Uncompressed Grayscale images not supported");
+
+ case Header.COLORMAPPED:
+ throw new IOException("TGADecoder Compressed Colormapped images not supported");
+
+ case Header.TRUECOLOR:
+ throw new IOException("TGADecoder Compressed True Color images not supported");
+
+ case Header.BLACKWHITE:
+ throw new IOException("TGADecoder Compressed Grayscale images not supported");
+ }
+ }
+
+ /**
+ * This assumes that the body is for a 24 bit or 32 bit for a
+ * RGB or ARGB image respectively.
+ */
+ private void decodeRGBImageU24_32(LEDataInputStream dIn) throws IOException {
+ int i; // row index
+ int j; // column index
+ int y; // output row index
+ int raw; // index through the raw input buffer
+ int rawWidth = header.width() * (header.pixelDepth() / 8);
+ byte[] rawBuf = new byte[rawWidth];
+ byte[] tmpData = new byte[rawWidth * header.height()];
+
+ for (i = 0; i < header.height(); ++i) {
+ dIn.readFully(rawBuf, 0, rawWidth);
+
+ if (header.topToBottom())
+ y = header.height - i - 1; // range 0 to (header.height - 1)
+ else
+ y = i;
+
+ System.arraycopy(rawBuf, 0, tmpData, y * rawWidth, rawBuf.length);
+ }
+
+ GL gl = GLContext.getCurrentGL();
+ if (header.pixelDepth() == 24) {
+ bpp=3;
+ if(gl.isGL2GL3()) {
+ format = GL2GL3.GL_BGR;
+ } else {
+ format = GL.GL_RGB;
+ swapBGR(tmpData, rawWidth, header.height(), bpp);
+ }
+ } else {
+ assert header.pixelDepth() == 32;
+ bpp=4;
+
+ if(gl.isGL2GL3()) {
+ format = GL2GL3.GL_BGRA;
+ } else {
+ format = GL.GL_RGBA;
+ swapBGR(tmpData, rawWidth, header.height(), bpp);
+ }
+ }
+
+ data = ByteBuffer.wrap(tmpData);
+ }
+
+ private static void swapBGR(byte[] data, int bWidth, int height, int bpp) {
+ byte r,b;
+ int k;
+ for(int i=0; i<height; ++i) {
+ for(int j=0; j<bWidth; j+=bpp) {
+ k=i*bWidth+j;
+ b=data[k+0];
+ r=data[k+2];
+ data[k+0]=r;
+ data[k+2]=b;
+ }
+ }
+ }
+
+ /** Returns the width of the image. */
+ public int getWidth() { return header.width(); }
+
+ /** Returns the height of the image. */
+ public int getHeight() { return header.height(); }
+
+ /** Returns the OpenGL format for this texture; e.g. GL.GL_BGR or GL.GL_BGRA. */
+ public int getGLFormat() { return format; }
+
+ /** Returns the bytes per pixel */
+ public int getBytesPerPixel() { return bpp; }
+
+ /** Returns the raw data for this texture in the correct
+ (bottom-to-top) order for calls to glTexImage2D. */
+ public ByteBuffer getData() { return data; }
+
+ /** Reads a Targa image from the specified file. */
+ public static TGAImage read(String filename) throws IOException {
+ return read(new FileInputStream(filename));
+ }
+
+ /** Reads a Targa image from the specified InputStream. */
+ public static TGAImage read(InputStream in) throws IOException {
+ LEDataInputStream dIn = new LEDataInputStream(new BufferedInputStream(in));
+
+ Header header = new Header(dIn);
+ TGAImage res = new TGAImage(header);
+ res.decodeImage(dIn);
+ return res;
+ }
+
+ /** Writes the image in Targa format to the specified file name. */
+ public void write(String filename) throws IOException {
+ write(new File(filename));
+ }
+
+ /** Writes the image in Targa format to the specified file. */
+ public void write(File file) throws IOException {
+ FileOutputStream stream = new FileOutputStream(file);
+ FileChannel chan = stream.getChannel();
+ ByteBuffer buf = ByteBuffer.allocate(header.size());
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ header.write(buf);
+ buf.rewind();
+ chan.write(buf);
+ chan.write(data);
+ data.rewind();
+ chan.force(true);
+ chan.close();
+ stream.close();
+ }
+
+ /** Creates a TGAImage from data supplied by the end user. Shares
+ data with the passed ByteBuffer. Assumes the data is already in
+ the correct byte order for writing to disk, i.e., BGR or
+ BGRA. */
+ public static TGAImage createFromData(int width,
+ int height,
+ boolean hasAlpha,
+ boolean topToBottom,
+ ByteBuffer data) {
+ Header header = new Header();
+ header.imageType = Header.UTRUECOLOR;
+ header.width = width;
+ header.height = height;
+ header.pixelDepth = (byte) (hasAlpha ? 32 : 24);
+ header.imageDescriptor = (byte) (topToBottom ? Header.ID_TOPTOBOTTOM : 0);
+ // Note ID not supported
+ TGAImage ret = new TGAImage(header);
+ ret.data = data;
+ return ret;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java
new file mode 100755
index 000000000..88018edbe
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureProvider.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi;
+
+import java.io.*;
+import java.net.*;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.opengl.util.texture.*;
+
+/** Plug-in interface to TextureIO to support reading OpenGL textures
+ from new file formats. For all methods, either internalFormat or
+ pixelFormat may be 0 in which case they must be inferred as
+ e.g. RGB or RGBA depending on the file contents.
+*/
+
+public interface TextureProvider {
+
+ /**
+ * Produces a TextureData object from a file, or returns null if the
+ * file format was not supported by this TextureProvider. Does not
+ * do any OpenGL-related work. The resulting TextureData can be
+ * converted into an OpenGL texture in a later step.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param file the file from which to read the texture data
+ *
+ * @param internalFormat the OpenGL internal format to be used for
+ * the texture, or 0 if it should be inferred
+ * from the file's contents
+ *
+ * @param pixelFormat the OpenGL pixel format to be used for
+ * the texture, or 0 if it should be inferred
+ * from the file's contents
+ *
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ *
+ * @param fileSuffix the file suffix to be used as a hint to the
+ * provider to more quickly decide whether it
+ * can handle the file, or null if the
+ * provider should infer the type from the
+ * file's contents
+ *
+ * @throws IOException if an error occurred while reading the file
+ */
+ public TextureData newTextureData(GLProfile glp, File file,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException;
+
+ /**
+ * Produces a TextureData object from a stream, or returns null if
+ * the file format was not supported by this TextureProvider. Does
+ * not do any OpenGL-related work. The resulting TextureData can be
+ * converted into an OpenGL texture in a later step.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param stream the stream from which to read the texture data
+ *
+ * @param internalFormat the OpenGL internal format to be used for
+ * the texture, or 0 if it should be inferred
+ * from the file's contents
+ *
+ * @param pixelFormat the OpenGL pixel format to be used for
+ * the texture, or 0 if it should be inferred
+ * from the file's contents
+ *
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ *
+ * @param fileSuffix the file suffix to be used as a hint to the
+ * provider to more quickly decide whether it
+ * can handle the file, or null if the
+ * provider should infer the type from the
+ * file's contents
+ *
+ * @throws IOException if an error occurred while reading the stream
+ */
+ public TextureData newTextureData(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException;
+
+ /**
+ * Produces a TextureData object from a URL, or returns null if the
+ * file format was not supported by this TextureProvider. Does not
+ * do any OpenGL-related work. The resulting TextureData can be
+ * converted into an OpenGL texture in a later step.
+ *
+ * @param glp the OpenGL Profile this texture data should be
+ * created for.
+ * @param url the URL from which to read the texture data
+ *
+ * @param internalFormat the OpenGL internal format to be used for
+ * the texture, or 0 if it should be inferred
+ * from the file's contents
+ *
+ * @param pixelFormat the OpenGL pixel format to be used for
+ * the texture, or 0 if it should be inferred
+ * from the file's contents
+ *
+ * @param mipmap whether mipmaps should be produced for this
+ * texture either by autogenerating them or
+ * reading them from the file. Some file formats
+ * support multiple mipmaps in a single file in
+ * which case those mipmaps will be used rather
+ * than generating them.
+ *
+ * @param fileSuffix the file suffix to be used as a hint to the
+ * provider to more quickly decide whether it
+ * can handle the file, or null if the
+ * provider should infer the type from the
+ * file's contents
+ *
+ * @throws IOException if an error occurred while reading the URL
+ */
+ public TextureData newTextureData(GLProfile glp, URL url,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureWriter.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureWriter.java
new file mode 100755
index 000000000..55527cef5
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TextureWriter.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi;
+
+import java.io.*;
+
+import com.jogamp.opengl.util.texture.*;
+
+/** Plug-in interface to TextureIO to support writing OpenGL textures
+ to new file formats. */
+
+public interface TextureWriter {
+ /** Writes the given TextureData to the passed file. Returns true if
+ this TextureWriter successfully handled the writing of the file,
+ otherwise false. May throw IOException if either this writer did
+ not support certain parameters of the TextureData or if an I/O
+ error occurred. */
+ public boolean write(File file,
+ TextureData data) throws IOException;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java
new file mode 100644
index 000000000..a45821d87
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureProvider.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi.awt;
+
+import java.awt.Graphics;
+import java.awt.image.*;
+import java.io.*;
+import java.net.*;
+import javax.imageio.*;
+import javax.media.opengl.GLProfile;
+
+import com.jogamp.opengl.impl.Debug;
+import com.jogamp.opengl.util.texture.*;
+import com.jogamp.opengl.util.texture.awt.*;
+import com.jogamp.opengl.util.texture.spi.*;
+
+public class IIOTextureProvider implements TextureProvider {
+ private static final boolean DEBUG = Debug.debug("TextureIO");
+
+ public TextureData newTextureData(GLProfile glp, File file,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ BufferedImage img = ImageIO.read(file);
+ if (img == null) {
+ return null;
+ }
+ if (DEBUG) {
+ System.out.println("TextureIO.newTextureData(): BufferedImage type for " + file + " = " +
+ img.getType());
+ }
+ return new AWTTextureData(glp, internalFormat, pixelFormat, mipmap, img);
+ }
+
+ public TextureData newTextureData(GLProfile glp, InputStream stream,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ BufferedImage img = ImageIO.read(stream);
+ if (img == null) {
+ return null;
+ }
+ if (DEBUG) {
+ System.out.println("TextureIO.newTextureData(): BufferedImage type for stream = " +
+ img.getType());
+ }
+ return new AWTTextureData(glp, internalFormat, pixelFormat, mipmap, img);
+ }
+
+ public TextureData newTextureData(GLProfile glp, URL url,
+ int internalFormat,
+ int pixelFormat,
+ boolean mipmap,
+ String fileSuffix) throws IOException {
+ InputStream stream = url.openStream();
+ try {
+ return newTextureData(glp, stream, internalFormat, pixelFormat, mipmap, fileSuffix);
+ } finally {
+ stream.close();
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureWriter.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureWriter.java
new file mode 100644
index 000000000..405211204
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/awt/IIOTextureWriter.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.util.texture.spi.awt;
+
+import java.awt.Graphics;
+import java.awt.image.*;
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+import javax.imageio.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.awt.*;
+import com.jogamp.opengl.util.texture.*;
+import com.jogamp.opengl.util.texture.spi.*;
+
+public class IIOTextureWriter implements TextureWriter {
+ public boolean write(File file,
+ TextureData data) throws IOException {
+ int pixelFormat = data.getPixelFormat();
+ int pixelType = data.getPixelType();
+ if ((pixelFormat == GL.GL_RGB ||
+ pixelFormat == GL.GL_RGBA) &&
+ (pixelType == GL.GL_BYTE ||
+ pixelType == GL.GL_UNSIGNED_BYTE)) {
+ // Convert TextureData to appropriate BufferedImage
+ // FIXME: almost certainly not obeying correct pixel order
+ BufferedImage image = new BufferedImage(data.getWidth(), data.getHeight(),
+ (pixelFormat == GL.GL_RGB) ?
+ BufferedImage.TYPE_3BYTE_BGR :
+ BufferedImage.TYPE_4BYTE_ABGR);
+ byte[] imageData = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
+ ByteBuffer buf = (ByteBuffer) data.getBuffer();
+ if (buf == null) {
+ buf = (ByteBuffer) data.getMipmapData()[0];
+ }
+ buf.rewind();
+ buf.get(imageData);
+ buf.rewind();
+
+ // Swizzle image components to be correct
+ if (pixelFormat == GL.GL_RGB) {
+ for (int i = 0; i < imageData.length; i += 3) {
+ byte red = imageData[i + 0];
+ byte blue = imageData[i + 2];
+ imageData[i + 0] = blue;
+ imageData[i + 2] = red;
+ }
+ } else {
+ for (int i = 0; i < imageData.length; i += 4) {
+ byte red = imageData[i + 0];
+ byte green = imageData[i + 1];
+ byte blue = imageData[i + 2];
+ byte alpha = imageData[i + 3];
+ imageData[i + 0] = alpha;
+ imageData[i + 1] = blue;
+ imageData[i + 2] = green;
+ imageData[i + 3] = red;
+ }
+ }
+
+ // Flip image vertically for the user's convenience
+ ImageUtil.flipImageVertically(image);
+
+ // Happened to notice that writing RGBA images to JPEGS is broken
+ if (TextureIO.JPG.equals(FileUtil.getFileSuffix(file)) &&
+ image.getType() == BufferedImage.TYPE_4BYTE_ABGR) {
+ BufferedImage tmpImage = new BufferedImage(image.getWidth(), image.getHeight(),
+ BufferedImage.TYPE_3BYTE_BGR);
+ Graphics g = tmpImage.getGraphics();
+ g.drawImage(image, 0, 0, null);
+ g.dispose();
+ image = tmpImage;
+ }
+
+ return ImageIO.write(image, FileUtil.getFileSuffix(file), file);
+ }
+
+ throw new IOException("ImageIO writer doesn't support this pixel format / type (only GL_RGB/A + bytes)");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/openmax/OMXEventListener.java b/src/jogl/classes/com/jogamp/openmax/OMXEventListener.java
new file mode 100644
index 000000000..08cfeccde
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/openmax/OMXEventListener.java
@@ -0,0 +1,14 @@
+
+package com.jogamp.openmax;
+
+public interface OMXEventListener {
+
+ static final int EVENT_CHANGE_SIZE = 1<<0;
+ static final int EVENT_CHANGE_FPS = 1<<1;
+ static final int EVENT_CHANGE_BPS = 1<<2;
+ static final int EVENT_CHANGE_LENGTH = 1<<3;
+
+ public void changedAttributes(OMXInstance omx, int event_mask);
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/openmax/OMXInstance.java b/src/jogl/classes/com/jogamp/openmax/OMXInstance.java
new file mode 100644
index 000000000..9f5b850ba
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/openmax/OMXInstance.java
@@ -0,0 +1,509 @@
+
+package com.jogamp.openmax;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.GLU;
+import com.jogamp.opengl.util.texture.*;
+
+import com.jogamp.opengl.impl.egl.EGL;
+import com.jogamp.opengl.impl.egl.EGLContext;
+import com.jogamp.opengl.impl.egl.EGLDrawable;
+import com.jogamp.opengl.impl.egl.EGLExt;
+
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.*;
+
+public class OMXInstance {
+ private long moviePtr = 0;
+
+ protected String path = null;
+ protected URL url = null;
+
+ // *** Texture impl
+ protected Texture texture = null; // holds the last fetched texture
+
+ protected float playSpeed = 1.0f;
+
+ /**
+ * The following data is set by the setStream function,
+ * and may be set by the native OMX implementation,
+ * in case the stream attributes changes (see attributesUpdated)
+ */
+ protected int width = 0;
+ protected int height = 0;
+ protected int fps = 0; // frames per seconds
+ protected long bps = 0; // bits per seconds
+ protected long totalFrames = 0; // duration in frames
+ protected String acodec = null;
+ protected String vcodec = null;
+
+ /**
+ * Old stream values, before the last attributesUpdated)
+ */
+ protected int o_width = 0;
+ protected int o_height = 0;
+ protected int o_fps = 0; // frames per seconds
+ protected long o_bps = 0; // bits per seconds
+ protected long o_totalFrames = 0; // duration in frames
+
+ static class EGLImageTexture {
+ public EGLImageTexture(com.jogamp.opengl.util.texture.Texture t, long i, long s) {
+ texture = t; image = i; sync = s;
+ }
+ public String toString() {
+ return "EGLImageTexture[" + texture + ", image " + image + ", sync "+sync+"]";
+ }
+ protected com.jogamp.opengl.util.texture.Texture texture;
+ protected long image;
+ protected long sync;
+ }
+ private EGLImageTexture[] eglImgTexs=null;
+ private HashMap eglImgTexsMap = new HashMap();
+ protected int textureNum;
+
+ private EGLExt eglExt = null;
+ private long eglSurface = 0;
+ private long eglDisplay = 0;
+ private long eglContext = 0;
+ private int sWidth=0, sHeight=0;
+
+ private GL initGLData(GL gl) {
+ if(null==gl) {
+ throw new RuntimeException("No current GL");
+ }
+ EGLContext eglCtx = (EGLContext) gl.getContext();
+ if(null==eglCtx) {
+ throw new RuntimeException("No current EGL context");
+ }
+ EGLDrawable eglDrawable = (EGLDrawable) eglCtx.getGLDrawable();
+ if(null==eglDrawable) {
+ throw new RuntimeException("No valid drawable");
+ }
+ eglContext = eglCtx.getContext();
+ eglDisplay = eglDrawable.getDisplay();
+ eglSurface = eglDrawable.getSurface();
+ eglExt = eglCtx.getEGLExt();
+ if(null==eglExt) {
+ throw new RuntimeException("No valid EGLExt");
+ }
+
+ int iTmp[] = new int[1];
+ EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, iTmp, 0);
+ sWidth=iTmp[0];
+ EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_HEIGHT, iTmp, 0);
+ sHeight=iTmp[0];
+ System.out.println("surface size: "+width+"x"+height);
+ System.out.println(eglDrawable);
+ System.out.println(eglCtx);
+ System.out.println("EGL Extensions : "+EGL.eglQueryString(eglDisplay, EGL.EGL_EXTENSIONS));
+ System.out.println("EGL CLIENT APIs: "+EGL.eglQueryString(eglDisplay, EGL.EGL_CLIENT_APIS));
+ return gl;
+ }
+
+ public OMXInstance() {
+ moviePtr = _createInstance();
+ if(0==moviePtr) {
+ throw new GLException("Couldn't create OMXInstance");
+ }
+ }
+ native long _createInstance();
+
+ public synchronized void setStream(int textureNum, URL u) {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ this.textureNum=textureNum;
+ url = u;
+ if (url == null) {
+ System.out.println("setURL (null)");
+ stop();
+ return;
+ }
+ path=null;
+ if (url.getProtocol() == null || "file".equals(url.getProtocol())) {
+ // CV only accepts absolute paths
+ try {
+ File file = new File(url.getPath());
+ if (!file.exists()) {
+ throw new RuntimeException(new FileNotFoundException(file.toString()));
+ }
+ path = file.getCanonicalPath();
+ System.out.println("setURL: path "+path);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+ path = replaceAll(path, "\\", "/").trim();
+ if(null==path) {
+ throw new RuntimeException("Couldn't parse stream URL: "+url);
+ }
+ System.out.println("setURL: clean path "+path);
+
+ System.out.println("setURL: p1 "+this);
+ _setStream(moviePtr, textureNum, path);
+ System.out.println("setURL: p2 "+this);
+ }
+ native void _setStream(long moviePtr, int textureNum, String path);
+
+ public synchronized void setStreamAllEGLImageTexture2D(GL gl) {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ if(null==vcodec) {
+ return;
+ }
+ gl = initGLData(gl);
+
+ if(null!=eglImgTexs) {
+ removeAllEGLImageTexture2D(gl);
+ } else {
+ eglImgTexs = new EGLImageTexture[textureNum];
+ }
+
+ int[] tmp = new int[1];
+ int tex, e;
+
+ errorCheckGL(gl, "i.1");
+ gl.glEnable(gl.GL_TEXTURE_2D);
+ errorCheckGL(gl, "i.2");
+
+ for(int i=0; i<textureNum; i++) {
+ String s0 = String.valueOf(i);
+ gl.glGenTextures(1, tmp, 0);
+ tex=tmp[0];
+ if( (e=gl.glGetError()) != GL.GL_NO_ERROR || 0>tex ) {
+ throw new RuntimeException("TextureName creation failed: "+e);
+ }
+ gl.glBindTexture(gl.GL_TEXTURE_2D, tex);
+
+ // create space for buffer with a texture
+ gl.glTexImage2D(
+ gl.GL_TEXTURE_2D, // target
+ 0, // level
+ gl.GL_RGBA, // internal format
+ width, // width
+ height, // height
+ 0, // border
+ gl.GL_RGBA, // format
+ gl.GL_UNSIGNED_BYTE, // type
+ null); // pixels -- will be provided later
+ gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST);
+ gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST);
+
+ long image=0, sync=0;
+
+ // create EGLImage from texture
+ tmp[0] = EGL.EGL_NONE;
+ image = eglExt.eglCreateImageKHR(
+ eglDisplay,
+ eglContext,
+ eglExt.EGL_GL_TEXTURE_2D_KHR,
+ tex,
+ tmp, 0);
+ if (0==image) {
+ throw new RuntimeException("EGLImage creation failed: "+EGL.eglGetError()+", dpy "+eglDisplay+", ctx "+eglContext+", tex "+tex);
+ }
+
+ // Create sync object so that we can be sure that gl has finished
+ // rendering the EGLImage texture before we tell OpenMAX to fill
+ // it with a new frame.
+ tmp[0] = EGL.EGL_NONE;
+ sync = eglExt.eglCreateFenceSyncKHR(
+ eglDisplay,
+ eglExt.EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR, tmp, 0);
+
+ _setStreamEGLImageTexture2D(moviePtr, i, tex, image, sync);
+
+ eglImgTexs[i] = new EGLImageTexture(
+ com.jogamp.opengl.util.texture.TextureIO.newTexture(tex,
+ javax.media.opengl.GL2.GL_TEXTURE_2D,
+ width,
+ height,
+ width,
+ height,
+ true),
+ image, sync);
+ eglImgTexsMap.put(new Integer(tex), eglImgTexs[i]);
+ }
+ gl.glDisable(gl.GL_TEXTURE_2D);
+ }
+ native void _setStreamEGLImageTexture2D(long moviePtr, int i, int tex, long image, long sync);
+
+ public synchronized void activateStream() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ _activateStream(moviePtr);
+ }
+ native void _activateStream(long moviePtr);
+
+ public synchronized void detachVideoRenderer() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ _detachVideoRenderer(moviePtr);
+ }
+ native void _detachVideoRenderer(long moviePtr); // stop before
+
+ public synchronized void attachVideoRenderer() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ _attachVideoRenderer(moviePtr);
+ }
+ native void _attachVideoRenderer(long moviePtr); // detach before
+
+ public synchronized void setPlaySpeed(float rate) {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ _setPlaySpeed(moviePtr, rate);
+ playSpeed = rate;
+ }
+ public synchronized float getPlaySpeed() {
+ return playSpeed;
+ }
+ native void _setPlaySpeed(long moviePtr, float rate);
+
+ /** @return time position after issuing the command */
+ public synchronized float play() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ return _play(moviePtr);
+ }
+ native float _play(long moviePtr);
+
+ /** @return time position after issuing the command */
+ public synchronized float pause() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ return _pause(moviePtr);
+ }
+ native float _pause(long moviePtr);
+
+ /** @return time position after issuing the command */
+ public synchronized float stop() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ return _stop(moviePtr);
+ }
+ native float _stop(long moviePtr);
+
+ /** @return time position after issuing the command */
+ public synchronized float seek(float pos) {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ return _seek(moviePtr, pos);
+ }
+ native float _seek(long moviePtr, float position);
+
+ public synchronized Texture getLastTextureID() {
+ return texture;
+ }
+ public synchronized Texture getNextTextureID() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ texture=null;
+ EGLImageTexture eglImgTex = (EGLImageTexture) eglImgTexsMap.get(new Integer(_getNextTextureID(moviePtr)));
+ if(null!=eglImgTex) {
+ texture = eglImgTex.texture;
+ }
+ return texture;
+ }
+ native int _getNextTextureID(long moviePtr);
+
+ public synchronized float getCurrentPosition() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ return _getCurrentPosition(moviePtr);
+ }
+ native float _getCurrentPosition(long moviePtr);
+
+ public synchronized void destroy(GL gl) {
+ removeAllEGLImageTexture2D(gl);
+ if (moviePtr != 0) {
+ long ptr = moviePtr;
+ moviePtr = 0;
+ _destroyInstance(ptr);
+
+ eglExt=null;
+ eglSurface=0;
+ eglDisplay=0;
+ eglContext=0;
+ }
+ }
+ protected synchronized void finalize() {
+ if (moviePtr != 0) {
+ destroy(null);
+ }
+ }
+ native void _destroyInstance(long moviePtr);
+
+ public synchronized boolean isValid() {
+ return (moviePtr != 0);
+ }
+ public synchronized String getPath() {
+ return path;
+ }
+ public synchronized URL getURL() {
+ return url;
+ }
+ public synchronized String getVideoCodec() {
+ return vcodec;
+ }
+ public synchronized String getAudioCodec() {
+ return acodec;
+ }
+ public synchronized long getTotalFrames() {
+ return totalFrames;
+ }
+ public synchronized long getBitrate() {
+ return bps;
+ }
+ public synchronized int getFramerate() {
+ return fps;
+ }
+ public synchronized int getWidth() {
+ return width;
+ }
+ public synchronized int getHeight() {
+ return height;
+ }
+ public synchronized String toString() {
+ return "OMXInstance [ stream [ video [ "+vcodec+", "+width+"x"+height+", "+fps+"fps, "+bps+"bsp, "+totalFrames+"f ] ] ]";
+ }
+
+ /**
+ * Java callback method issued by the native OMX backend
+ */
+ private void saveAttributes() {
+ o_width = width;
+ o_height = height;
+ o_fps = fps;
+ o_bps = bps;
+ o_totalFrames = totalFrames;
+ }
+
+ private void attributesUpdated() {
+ int event_mask = 0;
+ if( o_width != width || o_height != height ) {
+ event_mask |= OMXEventListener.EVENT_CHANGE_SIZE;
+ }
+ if( o_fps != fps ) {
+ event_mask |= OMXEventListener.EVENT_CHANGE_FPS;
+ }
+ if( o_bps != bps ) {
+ event_mask |= OMXEventListener.EVENT_CHANGE_BPS;
+ }
+ if( o_totalFrames != totalFrames ) {
+ event_mask |= OMXEventListener.EVENT_CHANGE_LENGTH;
+ }
+ if(0==event_mask) {
+ return;
+ }
+
+ ArrayList listeners = null;
+ synchronized(this) {
+ listeners = eventListeners;
+ }
+ for(Iterator i = listeners.iterator(); i.hasNext(); ) {
+ OMXEventListener l = (OMXEventListener) i.next();
+ l.changedAttributes(this, event_mask);
+ }
+ }
+
+ private String replaceAll(String orig, String search, String repl) {
+ String dest=null;
+ // In case replaceAll / java.util.regex.* is not supported (-> CVM)
+ int i=0,j;
+ dest = new String();
+ while((j=orig.indexOf(search, i))>=0) {
+ dest=dest.concat(orig.substring(i, j));
+ dest=dest.concat(repl);
+ i=j+1;
+ }
+ return dest.concat(orig.substring(i, orig.length()));
+ }
+
+ private void removeAllEGLImageTexture2D(GL gl) {
+ if (moviePtr != 0) {
+ if(null==eglExt) {
+ throw new RuntimeException("No valid EGLExt");
+ }
+
+ texture = null;
+ for(int i=0; i<textureNum; i++) {
+ if(null!=eglImgTexs[i]) {
+ if(0!=eglImgTexs[i].image) {
+ eglExt.eglDestroyImageKHR(
+ eglDisplay,
+ eglImgTexs[i].image);
+ }
+ if(0!=eglImgTexs[i].sync) {
+ eglExt.eglDestroySyncKHR(eglImgTexs[i].sync);
+ }
+ if(null!=gl) {
+ eglImgTexs[i].texture.destroy(gl);
+ }
+ eglImgTexs[i]=null;
+ }
+ }
+ eglImgTexsMap.clear();
+ }
+ }
+
+ private void errorCheckGL(GL gl, String s) {
+ int e;
+ if( (e=gl.glGetError()) != GL.GL_NO_ERROR ) {
+ System.out.println("GL Error: ("+s+"): "+e);
+ }
+ }
+
+ private void errorCheckEGL(String s) {
+ int e;
+ if( (e=EGL.eglGetError()) != EGL.EGL_SUCCESS ) {
+ System.out.println("EGL Error: ("+s+"): "+e);
+ }
+ }
+
+
+ //
+ // OMXEventListener Support
+ //
+
+ public synchronized void addEventListener(OMXEventListener l) {
+ if(l == null) {
+ return;
+ }
+ ArrayList newEventListeners = (ArrayList) eventListeners.clone();
+ newEventListeners.add(l);
+ eventListeners = newEventListeners;
+ }
+
+ public synchronized void removeEventListener(OMXEventListener l) {
+ if (l == null) {
+ return;
+ }
+ ArrayList newEventListeners = (ArrayList) eventListeners.clone();
+ newEventListeners.remove(l);
+ eventListeners = newEventListeners;
+ }
+
+ public synchronized OMXEventListener[] getEventListeners() {
+ return (OMXEventListener[]) eventListeners.toArray();
+ }
+
+ private ArrayList eventListeners = new ArrayList();
+
+}
+