summaryrefslogtreecommitdiffstats
path: root/src/classes
diff options
context:
space:
mode:
authorKevin Rushforth <[email protected]>2006-09-29 18:04:13 +0000
committerKevin Rushforth <[email protected]>2006-09-29 18:04:13 +0000
commit908d0fbb2ea26226165cd42f12abf0d27e4a3f53 (patch)
tree0258d2293efab8f4eafba39a528a3d2eedd0c3cb /src/classes
parent0661a22dd9278b20856b13b08ff22d248119cf6b (diff)
Merged dev-1_5 branch back to MAIN trunk
git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@701 ba19aa83-45c5-6ac9-afd3-db810772062c
Diffstat (limited to 'src/classes')
-rw-r--r--src/classes/J3dVersion2
-rw-r--r--src/classes/build.xml69
-rwxr-xr-xsrc/classes/jogl/javax/media/j3d/JoglCgShaderInfo.java32
-rwxr-xr-xsrc/classes/jogl/javax/media/j3d/JoglCgShaderParameter.java29
-rwxr-xr-xsrc/classes/jogl/javax/media/j3d/JoglCgShaderProgramInfo.java38
-rw-r--r--src/classes/jogl/javax/media/j3d/JoglContext.java231
-rwxr-xr-xsrc/classes/jogl/javax/media/j3d/JoglDrawable.java30
-rw-r--r--src/classes/jogl/javax/media/j3d/JoglDrawingSurfaceObject.java60
-rwxr-xr-xsrc/classes/jogl/javax/media/j3d/JoglGraphicsConfiguration.java103
-rw-r--r--src/classes/jogl/javax/media/j3d/JoglPipeline.java9279
-rwxr-xr-xsrc/classes/jogl/javax/media/j3d/JoglShaderObject.java25
-rw-r--r--src/classes/linux/javax/media/j3d/J3dGraphicsConfig.java44
-rw-r--r--src/classes/linux/javax/media/j3d/NativeConfigTemplate3D.java295
-rw-r--r--src/classes/linux/javax/media/j3d/NativeScreenInfo.java78
-rw-r--r--src/classes/linux/javax/media/j3d/NativeWSInfo.java64
-rw-r--r--src/classes/share/javax/media/j3d/AlternateAppearanceRetained.java6
-rw-r--r--src/classes/share/javax/media/j3d/AmbientLightRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/Appearance.java72
-rw-r--r--src/classes/share/javax/media/j3d/AppearanceRetained.java20
-rw-r--r--src/classes/share/javax/media/j3d/AttributeBin.java19
-rw-r--r--src/classes/share/javax/media/j3d/BHInternalNode.java3
-rw-r--r--src/classes/share/javax/media/j3d/BHNode.java3
-rw-r--r--src/classes/share/javax/media/j3d/BHTree.java6
-rw-r--r--src/classes/share/javax/media/j3d/Background.java44
-rw-r--r--src/classes/share/javax/media/j3d/BackgroundRetained.java161
-rw-r--r--src/classes/share/javax/media/j3d/BehaviorRetained.java9
-rw-r--r--src/classes/share/javax/media/j3d/BehaviorScheduler.java7
-rw-r--r--src/classes/share/javax/media/j3d/BehaviorStructure.java2
-rw-r--r--src/classes/share/javax/media/j3d/Billboard.java13
-rw-r--r--src/classes/share/javax/media/j3d/BoundingLeafRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/BoundingPolytope.java4
-rw-r--r--src/classes/share/javax/media/j3d/BranchGroupRetained.java8
-rw-r--r--src/classes/share/javax/media/j3d/Canvas3D.java1734
-rw-r--r--src/classes/share/javax/media/j3d/CanvasViewCache.java3
-rw-r--r--src/classes/share/javax/media/j3d/CgShaderProgramRetained.java409
-rw-r--r--src/classes/share/javax/media/j3d/ClipRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/ColoringAttributesRetained.java24
-rw-r--r--src/classes/share/javax/media/j3d/CompressedGeometryRenderMethod.java16
-rw-r--r--src/classes/share/javax/media/j3d/CompressedGeometryRetained.java9
-rw-r--r--src/classes/share/javax/media/j3d/Context.java22
-rw-r--r--src/classes/share/javax/media/j3d/DefaultRenderMethod.java16
-rw-r--r--src/classes/share/javax/media/j3d/DetailTextureImage.java219
-rw-r--r--src/classes/share/javax/media/j3d/DirectionalLightRetained.java14
-rw-r--r--src/classes/share/javax/media/j3d/DisplayListRenderMethod.java22
-rw-r--r--src/classes/share/javax/media/j3d/DistanceLOD.java5
-rw-r--r--src/classes/share/javax/media/j3d/Drawable.java22
-rw-r--r--src/classes/share/javax/media/j3d/DrawingSurfaceObjectAWT.java39
-rw-r--r--src/classes/share/javax/media/j3d/EnvironmentSet.java3
-rw-r--r--src/classes/share/javax/media/j3d/ExceptionStrings.properties64
-rw-r--r--src/classes/share/javax/media/j3d/ExponentialFogRetained.java10
-rw-r--r--src/classes/share/javax/media/j3d/FogRetained.java6
-rw-r--r--src/classes/share/javax/media/j3d/FreeListManager.java51
-rw-r--r--src/classes/share/javax/media/j3d/GLSLShaderProgramRetained.java418
-rw-r--r--src/classes/share/javax/media/j3d/GeometryArray.java63
-rw-r--r--src/classes/share/javax/media/j3d/GeometryArrayRetained.java992
-rw-r--r--src/classes/share/javax/media/j3d/GeometryAtom.java4
-rw-r--r--src/classes/share/javax/media/j3d/GeometryRetained.java20
-rw-r--r--src/classes/share/javax/media/j3d/GeometryStructure.java6
-rw-r--r--src/classes/share/javax/media/j3d/GraphicsConfigInfo.java33
-rw-r--r--src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java13
-rw-r--r--src/classes/share/javax/media/j3d/GraphicsContext3D.java867
-rw-r--r--src/classes/share/javax/media/j3d/GroupRetained.java28
-rw-r--r--src/classes/share/javax/media/j3d/IllegalRenderingStateException.java4
-rw-r--r--src/classes/share/javax/media/j3d/ImageComponent.java64
-rw-r--r--src/classes/share/javax/media/j3d/ImageComponent2D.java219
-rw-r--r--src/classes/share/javax/media/j3d/ImageComponent2DRetained.java1553
-rw-r--r--src/classes/share/javax/media/j3d/ImageComponent3D.java337
-rw-r--r--src/classes/share/javax/media/j3d/ImageComponent3DRetained.java298
-rw-r--r--src/classes/share/javax/media/j3d/ImageComponentRetained.java3984
-rw-r--r--src/classes/share/javax/media/j3d/IndexedGeometryArray.java133
-rw-r--r--src/classes/share/javax/media/j3d/IndexedGeometryArrayRetained.java362
-rw-r--r--src/classes/share/javax/media/j3d/InputDeviceBlockingThread.java36
-rw-r--r--src/classes/share/javax/media/j3d/J3DBuffer.java7
-rw-r--r--src/classes/share/javax/media/j3d/J3DGraphics2DImpl.java159
-rw-r--r--src/classes/share/javax/media/j3d/J3dClock.java20
-rw-r--r--src/classes/share/javax/media/j3d/J3dMessage.java3
-rw-r--r--src/classes/share/javax/media/j3d/J3dNotification.java2
-rw-r--r--src/classes/share/javax/media/j3d/J3dThread.java81
-rw-r--r--src/classes/share/javax/media/j3d/LightBin.java3
-rw-r--r--src/classes/share/javax/media/j3d/LightRetained.java10
-rw-r--r--src/classes/share/javax/media/j3d/LineAttributesRetained.java21
-rw-r--r--src/classes/share/javax/media/j3d/LinearFogRetained.java14
-rw-r--r--src/classes/share/javax/media/j3d/Locale.java36
-rw-r--r--src/classes/share/javax/media/j3d/MasterControl.java1021
-rw-r--r--src/classes/share/javax/media/j3d/MaterialRetained.java19
-rw-r--r--src/classes/share/javax/media/j3d/MediaContainerRetained.java6
-rw-r--r--src/classes/share/javax/media/j3d/ModelClipRetained.java17
-rw-r--r--src/classes/share/javax/media/j3d/MorphRetained.java20
-rw-r--r--src/classes/share/javax/media/j3d/NativeAPIInfo.java32
-rw-r--r--src/classes/share/javax/media/j3d/NativeContext.java31
-rw-r--r--src/classes/share/javax/media/j3d/NativeDrawable.java32
-rw-r--r--src/classes/share/javax/media/j3d/NativePipeline.java3325
-rw-r--r--src/classes/share/javax/media/j3d/NativeShaderObject.java31
-rw-r--r--src/classes/share/javax/media/j3d/NioImageBuffer.java379
-rw-r--r--src/classes/share/javax/media/j3d/NodeComponent.java25
-rw-r--r--src/classes/share/javax/media/j3d/NodeComponentRetained.java12
-rw-r--r--src/classes/share/javax/media/j3d/NodeRetained.java3
-rw-r--r--src/classes/share/javax/media/j3d/NoopDrawingSurfaceObject.java57
-rw-r--r--src/classes/share/javax/media/j3d/NoopPipeline.java1561
-rw-r--r--src/classes/share/javax/media/j3d/NotificationThread.java3
-rw-r--r--src/classes/share/javax/media/j3d/OrderedGroupRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/OrientedShape3DRenderMethod.java20
-rw-r--r--src/classes/share/javax/media/j3d/OrientedShape3DRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/Pipeline.java1403
-rw-r--r--src/classes/share/javax/media/j3d/PointAttributesRetained.java13
-rw-r--r--src/classes/share/javax/media/j3d/PointLightRetained.java20
-rw-r--r--src/classes/share/javax/media/j3d/PolygonAttributesRetained.java21
-rw-r--r--src/classes/share/javax/media/j3d/QuadArrayRetained.java21
-rw-r--r--src/classes/share/javax/media/j3d/Raster.java33
-rw-r--r--src/classes/share/javax/media/j3d/RasterRetained.java502
-rw-r--r--src/classes/share/javax/media/j3d/RenderBin.java417
-rw-r--r--src/classes/share/javax/media/j3d/RenderMethod.java2
-rw-r--r--src/classes/share/javax/media/j3d/RenderMolecule.java123
-rw-r--r--src/classes/share/javax/media/j3d/Renderer.java1049
-rw-r--r--src/classes/share/javax/media/j3d/RenderingAttributesRetained.java21
-rw-r--r--src/classes/share/javax/media/j3d/RenderingError.java253
-rw-r--r--src/classes/share/javax/media/j3d/RenderingErrorListener.java29
-rw-r--r--src/classes/share/javax/media/j3d/Screen3D.java14
-rw-r--r--src/classes/share/javax/media/j3d/SetLiveState.java5
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAppearanceRetained.java18
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttrLoc.java22
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeObjectRetained.java24
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeSetRetained.java24
-rw-r--r--src/classes/share/javax/media/j3d/ShaderBin.java2
-rw-r--r--src/classes/share/javax/media/j3d/ShaderId.java22
-rw-r--r--src/classes/share/javax/media/j3d/ShaderProgramId.java22
-rw-r--r--src/classes/share/javax/media/j3d/ShaderProgramRetained.java220
-rw-r--r--src/classes/share/javax/media/j3d/ShaderRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/Shape3DRetained.java26
-rw-r--r--src/classes/share/javax/media/j3d/SoundRetained.java4
-rw-r--r--src/classes/share/javax/media/j3d/SoundScheduler.java12
-rw-r--r--src/classes/share/javax/media/j3d/SoundscapeRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/SpotLightRetained.java60
-rw-r--r--src/classes/share/javax/media/j3d/SwitchRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/TexCoordGenerationRetained.java27
-rw-r--r--src/classes/share/javax/media/j3d/Text3DRenderMethod.java21
-rw-r--r--src/classes/share/javax/media/j3d/Text3DRetained.java19
-rw-r--r--src/classes/share/javax/media/j3d/Texture.java174
-rw-r--r--src/classes/share/javax/media/j3d/Texture2D.java130
-rw-r--r--src/classes/share/javax/media/j3d/Texture2DRetained.java188
-rw-r--r--src/classes/share/javax/media/j3d/Texture3D.java42
-rw-r--r--src/classes/share/javax/media/j3d/Texture3DRetained.java196
-rw-r--r--src/classes/share/javax/media/j3d/TextureAttributesRetained.java116
-rw-r--r--src/classes/share/javax/media/j3d/TextureBin.java158
-rw-r--r--src/classes/share/javax/media/j3d/TextureCubeMap.java27
-rw-r--r--src/classes/share/javax/media/j3d/TextureCubeMapRetained.java170
-rw-r--r--src/classes/share/javax/media/j3d/TextureRetained.java617
-rw-r--r--src/classes/share/javax/media/j3d/TextureUnitState.java42
-rw-r--r--src/classes/share/javax/media/j3d/TextureUnitStateRetained.java12
-rw-r--r--src/classes/share/javax/media/j3d/TimerThread.java38
-rw-r--r--src/classes/share/javax/media/j3d/Transform3D.java374
-rw-r--r--src/classes/share/javax/media/j3d/TransformGroup.java3
-rw-r--r--src/classes/share/javax/media/j3d/TransformGroupRetained.java8
-rw-r--r--src/classes/share/javax/media/j3d/TransformStructure.java2
-rw-r--r--src/classes/share/javax/media/j3d/TransparencyAttributesRetained.java19
-rw-r--r--src/classes/share/javax/media/j3d/TriangleArrayRetained.java18
-rw-r--r--src/classes/share/javax/media/j3d/TriangleFanArrayRetained.java18
-rw-r--r--src/classes/share/javax/media/j3d/TriangleStripArrayRetained.java19
-rw-r--r--src/classes/share/javax/media/j3d/VertexArrayRenderMethod.java22
-rw-r--r--src/classes/share/javax/media/j3d/View.java83
-rw-r--r--src/classes/share/javax/media/j3d/ViewPlatformRetained.java8
-rw-r--r--src/classes/share/javax/media/j3d/ViewSpecificGroupRetained.java16
-rw-r--r--src/classes/share/javax/media/j3d/VirtualUniverse.java177
-rw-r--r--src/classes/share/javax/media/j3d/WakeupCondition.java2
-rw-r--r--src/classes/solaris/javax/media/j3d/J3dGraphicsConfig.java40
-rw-r--r--src/classes/solaris/javax/media/j3d/NativeWSInfo.java58
-rw-r--r--src/classes/win32/javax/media/j3d/J3dGraphicsConfig.java41
-rw-r--r--src/classes/win32/javax/media/j3d/NativeConfigTemplate3D.java32
-rw-r--r--src/classes/win32/javax/media/j3d/NativeScreenInfo.java25
-rw-r--r--src/classes/win32/javax/media/j3d/NativeWSInfo.java69
-rw-r--r--src/classes/x11/javax/media/j3d/NativeConfigTemplate3D.java (renamed from src/classes/solaris/javax/media/j3d/NativeConfigTemplate3D.java)86
-rw-r--r--src/classes/x11/javax/media/j3d/NativeScreenInfo.java (renamed from src/classes/solaris/javax/media/j3d/NativeScreenInfo.java)36
172 files changed, 27235 insertions, 10124 deletions
diff --git a/src/classes/J3dVersion b/src/classes/J3dVersion
index cc882bb..c6c433a 100644
--- a/src/classes/J3dVersion
+++ b/src/classes/J3dVersion
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
Specification-Title: Java 3D API Specification
-Specification-Version: 1.4
+Specification-Version: 1.5
Specification-Vendor: Sun Microsystems, Inc.
Implementation-Title: Java 3D Core Runtime Environment
Implementation-Version: @VERSION_BASE@
diff --git a/src/classes/build.xml b/src/classes/build.xml
index 8a81c3c..df60201 100644
--- a/src/classes/build.xml
+++ b/src/classes/build.xml
@@ -15,7 +15,7 @@
-->
<!-- Ant file for building java classes and jar files -->
-<project name="Java 3D" default="jar-opt">
+<project name="Java 3D" default="jar-debug">
<path id="vecmath.debug.classpath">
<pathelement location="${vecmath_home}/build/debug/lib/ext/vecmath.jar"/>
@@ -53,12 +53,13 @@
</copy>
<!-- Compile the java code from ${src} into ${build}/${platform}/debug/classes -->
- <javac srcdir="${src}/classes/share:${src}/classes/${ostype}:${core_utils_src}/classes/share:${build-debug-gen}/classes"
+ <javac srcdir="${src}/classes/share:${src}/classes/${wstype}:${jogl.pipeline.srcdir}:${core_utils_src}/classes/share:${build-debug-gen}/classes"
destdir="${build}/${platform}/debug/classes"
- source="1.4"
- target="1.4"
+ source="1.5"
+ target="1.5"
debug="true"
- deprecation="off">
+ deprecation="off"
+ excludes="${javac.excludes}">
<classpath refid="vecmath.debug.classpath"/>
</javac>
@@ -97,12 +98,13 @@
</copy>
<!-- Compile the java code from ${src} into ${build}/${platform}/opt/classes -->
- <javac srcdir="${src}/classes/share:${src}/classes/${ostype}:${core_utils_src}/classes/share:${build-opt-gen}/classes" destdir="${build}/${platform}/opt/classes"
- source="1.4"
- target="1.4"
+ <javac srcdir="${src}/classes/share:${src}/classes/${wstype}:${jogl.pipeline.srcdir}:${core_utils_src}/classes/share:${build-opt-gen}/classes" destdir="${build}/${platform}/opt/classes"
+ source="1.5"
+ target="1.5"
debug="true"
debuglevel="lines,source"
- deprecation="off">
+ deprecation="off"
+ excludes="${javac.excludes}">
<classpath refid="vecmath.opt.classpath"/>
</javac>
@@ -113,7 +115,10 @@
</copy>
</target>
- <target name="jar-debug">
+
+ <target name="jar-debug" depends="jar-debug-impl,copy-default-debug"/>
+
+ <target name="jar-debug-impl">
<!-- Create the j3dcore and j3dutils jars directory -->
<mkdir dir="${build}/${platform}/debug/lib/ext"/>
@@ -153,7 +158,21 @@
</jar>
</target>
- <target name="jar-opt">
+ <target name="copy-default-debug" unless="build.concurrent">
+ <!-- Copy platform-specific jar and native files to "default" directory -->
+ <delete dir="${build}/default/debug" quiet="true"/>
+ <mkdir dir="${build}/default/debug/native"/>
+ <copy todir="${build}/default/debug" overwrite="true">
+ <fileset dir="${build}/${platform}/debug" includes="lib/ext/**/*.jar"/>
+ </copy>
+ <copy todir="${build}/default/debug/native" overwrite="true" includeemptydirs="false" flatten="true">
+ <fileset dir="${build}/${platform}/debug" includes="lib/** bin/**" excludes="**/*.jar"/>
+ </copy>
+ </target>
+
+ <target name="jar-opt" depends="jar-opt-impl,copy-default-opt"/>
+
+ <target name="jar-opt-impl">
<!-- Create the j3dcore and j3dutils jars directory -->
<mkdir dir="${build}/${platform}/opt/lib/ext"/>
@@ -188,11 +207,23 @@
<!-- Put everything in ${build}/${platform}/opt/classes/com into the j3dutils.jar file -->
<jar jarfile="${build}/${platform}/opt/lib/ext/j3dutils.jar"
manifest="${build-opt-gen}/ToolsVersion" update="no"
- compress="false">
- <fileset dir="${build}/${platform}/opt/classes" includes="com/**/*"/>
+ compress="false">
+ <fileset dir="${build}/${platform}/opt/classes" includes="com/**/*"/>
</jar>
</target>
+ <target name="copy-default-opt" unless="build.concurrent">
+ <!-- Copy platform-specific jar and native files to "default" directory -->
+ <delete dir="${build}/default/opt" quiet="true"/>
+ <mkdir dir="${build}/default/opt/native"/>
+ <copy todir="${build}/default/opt" overwrite="true">
+ <fileset dir="${build}/${platform}/opt" includes="lib/ext/**/*.jar"/>
+ </copy>
+ <copy todir="${build}/default/opt/native" overwrite="true" includeemptydirs="false" flatten="true">
+ <fileset dir="${build}/${platform}/opt" includes="lib/** bin/**" excludes="**/*.jar"/>
+ </copy>
+ </target>
+
<target name="setup-docs">
<property name="javadoc.bottom"
value="&lt;font size=&quot;-1&quot;&gt;Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. Use is subject to &lt;a href=&quot;{@docRoot}/LICENSE-SPEC.html&quot;&gt;license terms&lt;/a&gt;."/>
@@ -211,7 +242,7 @@
windowtitle="Java 3D ${version}">
<sourcepath>
<pathelement location="${src}/classes/share"/>
- <pathelement location="${src}/classes/${ostype}"/>
+ <pathelement location="${src}/classes/${wstype}"/>
<pathelement location="${core_utils_src}/classes/share"/>
<pathelement location="${vecmath_src}"/>
</sourcepath>
@@ -253,7 +284,7 @@
windowtitle="Java 3D ${version}">
<sourcepath>
<pathelement location="${src}/classes/share"/>
- <pathelement location="${src}/classes/${ostype}"/>
+ <pathelement location="${src}/classes/${wstype}"/>
<pathelement location="${build}/${platform}/opt/gen/classes"/>
<pathelement location="${core_utils_src}/classes/share"/>
<pathelement location="${vecmath_src}"/>
@@ -274,10 +305,12 @@
<!-- Compile the javadoc from ${src} into ${build}/javadocs -->
<javadoc packagenames="javax.media.j3d.*,
com.sun.j3d.audioengines.*,
+ com.sun.j3d.exp.*,
com.sun.j3d.loaders.*,
com.sun.j3d.utils.*,
javax.vecmath.*"
excludepackagenames="com.sun.j3d.utils.scenegraph.io.retained,
+ com.sun.j3d.exp.swing.impl,
com.sun.j3d.utils.scenegraph.io.state.*"
maxmemory="128m"
destdir="${build}/${platform}/javadocs/docs-public"
@@ -285,7 +318,7 @@
windowtitle="Java 3D ${version}">
<sourcepath>
<pathelement location="${src}/classes/share"/>
- <pathelement location="${src}/classes/${ostype}"/>
+ <pathelement location="${src}/classes/${wstype}"/>
<pathelement location="${core_utils_src}/classes/share"/>
<pathelement location="${vecmath_src}"/>
</sourcepath>
@@ -333,8 +366,8 @@
<fileset dir="${java.home}/lib/ext" includes="j3dcore.jar, j3dutils.jar, vecmath.jar"/>
</delete>
<delete>
- <fileset dir="${java.home}/${install.bin}" includes="libj3dcore*.so, libj3dutils.so"/>
- <fileset dir="${java.home}/${install.bin}" includes="j3dcore*.dll, j3dutils.dll"/>
+ <fileset dir="${java.home}/${install.bin}" includes="libj3dcore*.so"/>
+ <fileset dir="${java.home}/${install.bin}" includes="j3dcore*.dll"/>
</delete>
</target>
diff --git a/src/classes/jogl/javax/media/j3d/JoglCgShaderInfo.java b/src/classes/jogl/javax/media/j3d/JoglCgShaderInfo.java
new file mode 100755
index 0000000..c739027
--- /dev/null
+++ b/src/classes/jogl/javax/media/j3d/JoglCgShaderInfo.java
@@ -0,0 +1,32 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import com.sun.opengl.cg.*;
+
+class JoglCgShaderInfo extends JoglShaderObject {
+ private CGprogram cgShader;
+ private int j3dShaderType;
+ private int shaderProfile;
+
+ JoglCgShaderInfo() {
+ super(0);
+ }
+
+ public void setCgShader(CGprogram shader) { cgShader = shader; }
+ public CGprogram getCgShader() { return cgShader; }
+ public void setJ3DShaderType(int type) { j3dShaderType = type; }
+ public int getJ3DShaderType() { return j3dShaderType; }
+ public void setShaderProfile(int shaderProfile) { this.shaderProfile = shaderProfile; }
+ public int getShaderProfile() { return shaderProfile; }
+}
diff --git a/src/classes/jogl/javax/media/j3d/JoglCgShaderParameter.java b/src/classes/jogl/javax/media/j3d/JoglCgShaderParameter.java
new file mode 100755
index 0000000..f744f1d
--- /dev/null
+++ b/src/classes/jogl/javax/media/j3d/JoglCgShaderParameter.java
@@ -0,0 +1,29 @@
+/*
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import com.sun.opengl.cg.*;
+
+class JoglCgShaderParameter extends JoglShaderObject {
+ private CGparameter vParam;
+ private CGparameter fParam;
+
+ JoglCgShaderParameter(CGparameter vParam,
+ CGparameter fParam) {
+ super(0);
+ this.vParam = vParam;
+ this.fParam = fParam;
+ }
+
+ CGparameter vParam() {
+ return vParam;
+ }
+
+ CGparameter fParam() {
+ return fParam;
+ }
+}
diff --git a/src/classes/jogl/javax/media/j3d/JoglCgShaderProgramInfo.java b/src/classes/jogl/javax/media/j3d/JoglCgShaderProgramInfo.java
new file mode 100755
index 0000000..fe88cf1
--- /dev/null
+++ b/src/classes/jogl/javax/media/j3d/JoglCgShaderProgramInfo.java
@@ -0,0 +1,38 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import com.sun.opengl.cg.*;
+
+class JoglCgShaderProgramInfo extends JoglShaderObject {
+ private JoglCgShaderInfo vShader; // vertex shader
+ private JoglCgShaderInfo fShader; // fragment shader
+ // Array of parameters for (varying) vertex attributes
+ private CGparameter[] vtxAttrs;
+
+ JoglCgShaderProgramInfo() {
+ super(0);
+ }
+
+ public JoglCgShaderInfo getVertexShader() { return vShader; }
+ public void setVertexShader(JoglCgShaderInfo info) { vShader = info; }
+ public JoglCgShaderInfo getFragmentShader() { return fShader; }
+ public void setFragmentShader(JoglCgShaderInfo info) { fShader = info; }
+ public CGparameter[] getVertexAttributes() { return vtxAttrs; }
+ public void setVertexAttributes(CGparameter[] attrs) { vtxAttrs = attrs; }
+ public int getNumVertexAttributes() {
+ if (vtxAttrs == null)
+ return 0;
+ return vtxAttrs.length;
+ }
+}
diff --git a/src/classes/jogl/javax/media/j3d/JoglContext.java b/src/classes/jogl/javax/media/j3d/JoglContext.java
new file mode 100644
index 0000000..075c304
--- /dev/null
+++ b/src/classes/jogl/javax/media/j3d/JoglContext.java
@@ -0,0 +1,231 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.nio.*;
+import javax.media.opengl.*;
+import com.sun.opengl.cg.*;
+
+/**
+ * Graphics context objects for Jogl rendering pipeline.
+ */
+class JoglContext implements Context {
+ private GLContext context;
+
+ // Properties we need to keep track of for efficiency
+ private int maxTexCoordSets;
+ private float alphaClearValue;
+ private int currentTextureUnit;
+ private int currentCombinerUnit;
+ private boolean hasMultisample;
+
+ // Needed for vertex attribute implementation
+ private JoglShaderObject shaderProgram;
+
+ // Implementation of vertex attribute methods
+ static interface VertexAttributeImpl {
+ public void vertexAttrPointer(GL gl,
+ int index, int size, int type, int stride, Buffer pointer);
+ public void enableVertexAttrArray(GL gl, int index);
+ public void disableVertexAttrArray(GL gl, int index);
+ public void vertexAttr1fv(GL gl, int index, FloatBuffer buf);
+ public void vertexAttr2fv(GL gl, int index, FloatBuffer buf);
+ public void vertexAttr3fv(GL gl, int index, FloatBuffer buf);
+ public void vertexAttr4fv(GL gl, int index, FloatBuffer buf);
+ }
+ private VertexAttributeImpl vertexAttrImpl;
+
+ class CgVertexAttributeImpl implements VertexAttributeImpl {
+ public void vertexAttrPointer(GL gl,
+ int index, int size, int type, int stride, Buffer pointer) {
+ JoglCgShaderProgramInfo shaderProgramInfo = (JoglCgShaderProgramInfo) shaderProgram;
+ if (shaderProgramInfo != null && index < shaderProgramInfo.getNumVertexAttributes()) {
+ CgGL.cgGLSetParameterPointer(shaderProgramInfo.getVertexAttributes()[index],
+ size, type, stride, pointer);
+ } else {
+ if (shaderProgramInfo == null) {
+ System.err.println(" shaderProgramInfo is null");
+ } else {
+ System.err.println(" index (" + index + ") out of range: numVtxAttrs = " +
+ shaderProgramInfo.getNumVertexAttributes());
+ }
+ }
+ }
+
+ public void enableVertexAttrArray(GL gl, int index) {
+ JoglCgShaderProgramInfo shaderProgramInfo = (JoglCgShaderProgramInfo) shaderProgram;
+ if (shaderProgramInfo != null && index < shaderProgramInfo.getNumVertexAttributes()) {
+ CgGL.cgGLEnableClientState(shaderProgramInfo.getVertexAttributes()[index]);
+ } else {
+ if (shaderProgramInfo == null) {
+ System.err.println(" shaderProgramInfo is null");
+ } else {
+ System.err.println(" index (" + index + ") out of range: numVtxAttrs = " +
+ shaderProgramInfo.getNumVertexAttributes());
+ }
+ }
+ }
+
+ public void disableVertexAttrArray(GL gl, int index) {
+ JoglCgShaderProgramInfo shaderProgramInfo = (JoglCgShaderProgramInfo) shaderProgram;
+ if (shaderProgramInfo != null && index < shaderProgramInfo.getNumVertexAttributes()) {
+ CgGL.cgGLDisableClientState(shaderProgramInfo.getVertexAttributes()[index]);
+ } else {
+ if (shaderProgramInfo == null) {
+ System.err.println(" shaderProgramInfo is null");
+ } else {
+ System.err.println(" index (" + index + ") out of range: numVtxAttrs = " +
+ shaderProgramInfo.getNumVertexAttributes());
+ }
+ }
+ }
+
+ // NOTE: we should never get here. These functions are only called
+ // when building display lists for geometry arrays with vertex
+ // attributes, and such display lists are disabled in Cg mode.
+ public void vertexAttr1fv(GL gl, int index, FloatBuffer buf) {
+ throw new RuntimeException("Java 3D ERROR : Assertion failed: invalid call to cgVertexAttr1fv");
+ }
+
+ public void vertexAttr2fv(GL gl, int index, FloatBuffer buf) {
+ throw new RuntimeException("Java 3D ERROR : Assertion failed: invalid call to cgVertexAttr2fv");
+ }
+
+ public void vertexAttr3fv(GL gl, int index, FloatBuffer buf) {
+ throw new RuntimeException("Java 3D ERROR : Assertion failed: invalid call to cgVertexAttr3fv");
+ }
+
+ public void vertexAttr4fv(GL gl, int index, FloatBuffer buf) {
+ throw new RuntimeException("Java 3D ERROR : Assertion failed: invalid call to cgVertexAttr4fv");
+ }
+ }
+
+ class GLSLVertexAttributeImpl implements VertexAttributeImpl {
+ public void vertexAttrPointer(GL gl,
+ int index, int size, int type, int stride, Buffer pointer) {
+ gl.glVertexAttribPointerARB(index + glslVertexAttrOffset,
+ size, type, false, stride, pointer);
+ }
+
+ public void enableVertexAttrArray(GL gl, int index) {
+ gl.glEnableVertexAttribArrayARB(index + glslVertexAttrOffset);
+ }
+
+ public void disableVertexAttrArray(GL gl, int index) {
+ gl.glDisableVertexAttribArrayARB(index + glslVertexAttrOffset);
+ }
+
+ public void vertexAttr1fv(GL gl, int index, FloatBuffer buf) {
+ gl.glVertexAttrib1fvARB(index + glslVertexAttrOffset, buf);
+ }
+
+ public void vertexAttr2fv(GL gl, int index, FloatBuffer buf) {
+ gl.glVertexAttrib2fvARB(index + glslVertexAttrOffset, buf);
+ }
+
+ public void vertexAttr3fv(GL gl, int index, FloatBuffer buf) {
+ gl.glVertexAttrib3fvARB(index + glslVertexAttrOffset, buf);
+ }
+
+ public void vertexAttr4fv(GL gl, int index, FloatBuffer buf) {
+ gl.glVertexAttrib4fvARB(index + glslVertexAttrOffset, buf);
+ }
+ }
+
+ // Only used when GLSL shader library is active
+ private int glslVertexAttrOffset;
+
+ // Only used when Cg shader library is active
+ private CGcontext cgContext;
+ private int cgVertexProfile;
+ private int cgFragmentProfile;
+
+ JoglContext(GLContext context) {
+ this.context = context;
+ }
+
+ GLContext getGLContext() {
+ return context;
+ }
+
+ int getMaxTexCoordSets() { return maxTexCoordSets; }
+ void setMaxTexCoordSets(int val) { maxTexCoordSets = val; }
+ float getAlphaClearValue() { return alphaClearValue; }
+ void setAlphaClearValue(float val) { alphaClearValue = val; }
+ int getCurrentTextureUnit() { return currentTextureUnit; }
+ void setCurrentTextureUnit(int val) { currentTextureUnit = val; }
+ int getCurrentCombinerUnit() { return currentCombinerUnit; }
+ void setCurrentCombinerUnit(int val) { currentCombinerUnit = val; }
+ boolean getHasMultisample() { return hasMultisample; }
+ void setHasMultisample(boolean val){ hasMultisample = val; }
+
+ // Helpers for vertex attribute methods
+ void initCgVertexAttributeImpl() {
+ if (vertexAttrImpl != null) {
+ throw new RuntimeException("Should not initialize the vertex attribute implementation twice");
+ }
+ vertexAttrImpl = new CgVertexAttributeImpl();
+ }
+
+ void initGLSLVertexAttributeImpl() {
+ if (vertexAttrImpl != null) {
+ throw new RuntimeException("Should not initialize the vertex attribute implementation twice");
+ }
+ vertexAttrImpl = new GLSLVertexAttributeImpl();
+ }
+
+ void vertexAttrPointer(GL gl,
+ int index, int size, int type, int stride, Buffer pointer) {
+ vertexAttrImpl.vertexAttrPointer(gl, index, size, type, stride, pointer);
+ }
+
+ void enableVertexAttrArray(GL gl, int index) {
+ vertexAttrImpl.enableVertexAttrArray(gl, index);
+ }
+
+ void disableVertexAttrArray(GL gl, int index) {
+ vertexAttrImpl.disableVertexAttrArray(gl, index);
+ }
+
+ void vertexAttr1fv(GL gl, int index, FloatBuffer buf) {
+ vertexAttrImpl.vertexAttr1fv(gl, index, buf);
+ }
+
+ void vertexAttr2fv(GL gl, int index, FloatBuffer buf) {
+ vertexAttrImpl.vertexAttr2fv(gl, index, buf);
+ }
+
+ void vertexAttr3fv(GL gl, int index, FloatBuffer buf) {
+ vertexAttrImpl.vertexAttr3fv(gl, index, buf);
+ }
+
+ void vertexAttr4fv(GL gl, int index, FloatBuffer buf) {
+ vertexAttrImpl.vertexAttr4fv(gl, index, buf);
+ }
+
+ // Used in vertex attribute implementation
+ JoglShaderObject getShaderProgram() { return shaderProgram; }
+ void setShaderProgram(JoglShaderObject object) { shaderProgram = object; }
+
+ // Only used when GLSL shaders are in use
+ int getGLSLVertexAttrOffset() { return glslVertexAttrOffset; }
+ void setGLSLVertexAttrOffset(int offset) { glslVertexAttrOffset = offset; }
+
+ // Only used when Cg shaders are in use
+ CGcontext getCgContext() { return cgContext; }
+ void setCgContext(CGcontext c) { cgContext = c; }
+ int getCgVertexProfile() { return cgVertexProfile; }
+ void setCgVertexProfile(int p) { cgVertexProfile = p; }
+ int getCgFragmentProfile() { return cgFragmentProfile; }
+ void setCgFragmentProfile(int p) { cgFragmentProfile = p; }
+}
diff --git a/src/classes/jogl/javax/media/j3d/JoglDrawable.java b/src/classes/jogl/javax/media/j3d/JoglDrawable.java
new file mode 100755
index 0000000..3834a11
--- /dev/null
+++ b/src/classes/jogl/javax/media/j3d/JoglDrawable.java
@@ -0,0 +1,30 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.media.opengl.*;
+
+/**
+ * Drawable class for the Jogl rendering pipeline.
+ */
+class JoglDrawable implements Drawable {
+ private GLDrawable drawable;
+
+ JoglDrawable(GLDrawable drawable) {
+ this.drawable = drawable;
+ }
+
+ GLDrawable getGLDrawable() {
+ return drawable;
+ }
+}
diff --git a/src/classes/jogl/javax/media/j3d/JoglDrawingSurfaceObject.java b/src/classes/jogl/javax/media/j3d/JoglDrawingSurfaceObject.java
new file mode 100644
index 0000000..d20a3d0
--- /dev/null
+++ b/src/classes/jogl/javax/media/j3d/JoglDrawingSurfaceObject.java
@@ -0,0 +1,60 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * The DrawingSurfaceObject class is used to manage native drawing surface
+ */
+class JoglDrawingSurfaceObject extends DrawingSurfaceObject {
+
+ JoglDrawingSurfaceObject(Canvas3D cv) {
+ super(cv);
+
+ // System.err.println("JoglDrawingSurfaceObject constructed");
+ }
+
+ synchronized boolean renderLock() {
+ // System.err.println("JoglDrawingSurfaceObject.renderLock()");
+ gotDsiLock = true;
+ return true;
+ }
+
+ synchronized void unLock() {
+ // System.err.println("JoglDrawingSurfaceObject.unLock()");
+ gotDsiLock = false;
+ }
+
+ synchronized void getDrawingSurfaceObjectInfo() {
+ // FIXME: we don't have all of the information we need here to
+ // create a GLDrawable for the Canvas3D, so for now, do nothing
+
+ // FIXME: this mechanism is much too complicated
+
+ /*
+ System.err.println("JoglDrawingSurfaceObject.getDrawingSurfaceObjectInfo()");
+
+ if (canvas.drawable == null) {
+ System.err.println(
+ "JoglDrawingSurfaceObject.getDrawingSurfaceObjectInfo: window = "
+ + canvas.drawable);
+
+ // TODO: replace with a real JoglDrawable
+ canvas.drawable = new JoglDrawable();
+ }
+ */
+ }
+
+ synchronized void invalidate() {
+ System.err.println("JoglDrawingSurfaceObject.invalidate()");
+ }
+}
diff --git a/src/classes/jogl/javax/media/j3d/JoglGraphicsConfiguration.java b/src/classes/jogl/javax/media/j3d/JoglGraphicsConfiguration.java
new file mode 100755
index 0000000..d207069
--- /dev/null
+++ b/src/classes/jogl/javax/media/j3d/JoglGraphicsConfiguration.java
@@ -0,0 +1,103 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.*;
+import javax.media.opengl.*;
+
+/**
+ * Class implementing the GraphicsConfiguration API, but not a "real"
+ * GraphicsConfiguration object. Wraps a GLCapabilities object and
+ * supports either immediate or deferred pixel format / visual
+ * selection depending on which platform we are running.
+ */
+
+class JoglGraphicsConfiguration extends GraphicsConfiguration {
+ private GLCapabilities caps;
+ private int chosenIndex;
+ private GraphicsDevice device;
+ // Needed for Screen3D
+ private int width;
+ private int height;
+
+ JoglGraphicsConfiguration(GLCapabilities caps, int chosenIndex, GraphicsDevice device) {
+ super();
+ this.caps = caps;
+ this.chosenIndex = chosenIndex;
+ this.device = device;
+ DisplayMode m = device.getDisplayMode();
+ width = m.getWidth();
+ height = m.getHeight();
+ }
+
+ GLCapabilities getGLCapabilities() {
+ return caps;
+ }
+
+ int getChosenIndex() {
+ return chosenIndex;
+ }
+
+ public BufferedImage createCompatibleImage(int width, int height) {
+ throw new RuntimeException("Unimplemented");
+ }
+
+ public BufferedImage createCompatibleImage(int width, int height,
+ int transparency) {
+ throw new RuntimeException("Unimplemented");
+ }
+
+ public VolatileImage createCompatibleVolatileImage(int width, int height) {
+ throw new RuntimeException("Unimplemented");
+ }
+
+ public VolatileImage createCompatibleVolatileImage(int width, int height, int transparency) {
+ throw new RuntimeException("Unimplemented");
+ }
+
+ public VolatileImage createCompatibleVolatileImage(int width, int height,
+ ImageCapabilities caps) throws AWTException {
+ throw new RuntimeException("Unimplemented");
+ }
+
+ public VolatileImage createCompatibleVolatileImage(int width, int height,
+ ImageCapabilities caps, int transparency) throws AWTException {
+ throw new RuntimeException("Unimplemented");
+ }
+
+ public Rectangle getBounds() {
+ return new Rectangle(0, 0, width, height);
+ }
+
+ public ColorModel getColorModel() {
+ throw new RuntimeException("Unimplemented");
+ }
+
+ public ColorModel getColorModel(int transparency) {
+ throw new RuntimeException("Unimplemented");
+ }
+
+ public AffineTransform getDefaultTransform() {
+ throw new RuntimeException("Unimplemented");
+ }
+
+ public GraphicsDevice getDevice() {
+ return device;
+ }
+
+ public AffineTransform getNormalizingTransform() {
+ throw new RuntimeException("Unimplemented");
+ }
+}
diff --git a/src/classes/jogl/javax/media/j3d/JoglPipeline.java b/src/classes/jogl/javax/media/j3d/JoglPipeline.java
new file mode 100644
index 0000000..3557c32
--- /dev/null
+++ b/src/classes/jogl/javax/media/j3d/JoglPipeline.java
@@ -0,0 +1,9279 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.awt.*;
+import java.io.*;
+import java.lang.reflect.*;
+import java.nio.*;
+import java.security.*;
+import java.util.*;
+import java.util.regex.*;
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import com.sun.opengl.cg.*;
+import com.sun.opengl.util.*;
+
+/**
+ * Concrete implementation of Pipeline class for the JOGL rendering
+ * pipeline.
+ */
+class JoglPipeline extends Pipeline {
+
+ // Flags indicating whether the Cg or GLSL libraries are available.
+ private boolean cgLibraryAvailable = false;
+
+ // Currently prints for entry points not yet implemented
+ private static final boolean DEBUG = true;
+ // Currently prints for entry points already implemented
+ private static final boolean VERBOSE = false;
+ // Debugging output for graphics configuration selection
+ private static final boolean DEBUG_CONFIG = false;
+ // Prints extra debugging information
+ private static final boolean EXTRA_DEBUGGING = false;
+ // Number of milliseconds to wait for windows to pop up on screen
+ private static final int WAIT_TIME = 1000;
+ // Configurable constant just in case we want to change this later
+ private static final int MIN_FRAME_SIZE = 1;
+
+ /**
+ * Constructor for singleton JoglPipeline instance
+ */
+ protected JoglPipeline() {
+ }
+
+ /**
+ * Initialize the pipeline
+ */
+ void initialize(Pipeline.Type pipelineType) {
+ super.initialize(pipelineType);
+
+ assert pipelineType == Pipeline.Type.JOGL;
+
+ // Java3D maintains strict control over which threads perform OpenGL work
+ Threading.disableSingleThreading();
+
+ // TODO: finish this with any other needed initialization
+ }
+
+ /**
+ * Load all of the required libraries
+ */
+ void loadLibraries(int globalShadingLanguage) {
+ if (globalShadingLanguage == Shader.SHADING_LANGUAGE_CG) {
+ // Try to load the jogl_cg library and set the
+ // cgLibraryAvailable flag to true if loads successfully; note
+ // that successfully performing initialization of this class
+ // will cause the Cg native library to be loaded on our behalf
+ try {
+ Class.forName("com.sun.opengl.cg.CgGL");
+ cgLibraryAvailable = true;
+ } catch (Exception ex) {
+ System.err.println(ex);
+ } catch (Error ex) {
+ System.err.println(ex);
+ }
+ }
+ }
+
+ /**
+ * Returns true if the Cg library is loaded and available. Note that this
+ * does not necessarily mean that Cg is supported by the graphics card.
+ */
+ boolean isCgLibraryAvailable() {
+ return cgLibraryAvailable;
+ }
+
+ /**
+ * Returns true if the GLSL library is loaded and available. Note that this
+ * does not necessarily mean that GLSL is supported by the graphics card.
+ */
+ boolean isGLSLLibraryAvailable() {
+ return true;
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GeometryArrayRetained methods
+ //
+
+ // Used by D3D to free vertex buffer
+ void freeD3DArray(GeometryArrayRetained geo, boolean deleteVB) {
+ // Nothing to do
+ }
+
+ // used for GeometryArrays by Copy or interleaved
+ void execute(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texUnitOffset,
+ int numActiveTexUnitState,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[] varray, float[] carray, int cDirty) {
+ if (VERBOSE) System.err.println("JoglPipeline.execute()");
+
+ executeGeometryArray(ctx, geo, geo_type, isNonUniformScale, useAlpha,
+ ignoreVertexColors, startVIndex, vcount, vformat,
+ texCoordSetCount, texCoordSetMap, texCoordSetMapLen,
+ texUnitOffset, numActiveTexUnitState,
+ vertexAttrCount, vertexAttrSizes,
+ varray, null, carray, cDirty);
+ }
+
+ // used by GeometryArray by Reference with java arrays
+ void executeVA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int initialCoordIndex, float[] vfcoords, double[] vdcoords,
+ int initialColorIndex, float[] cfdata, byte[] cbdata,
+ int initialNormalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndices, float[][] vertexAttrData,
+ int texCoordMapLength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty) {
+ if (VERBOSE) System.err.println("JoglPipeline.executeVA()");
+
+ boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
+ boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
+ boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
+ boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
+ boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
+ boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
+ boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
+
+ FloatBuffer fverts = null;
+ DoubleBuffer dverts = null;
+ FloatBuffer fclrs = null;
+ ByteBuffer bclrs = null;
+ FloatBuffer[] texCoordBufs = null;
+ FloatBuffer norms = null;
+ FloatBuffer[] vertexAttrBufs = null;
+
+ // Get vertex attribute arrays
+ if (vattrDefined) {
+ vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData);
+ }
+
+ // get texture arrays
+ if (textureDefined) {
+ texCoordBufs = getTexCoordSetBuffer(texCoords);
+ }
+
+ // get coordinate array
+ if (floatCoordDefined) {
+ fverts = getVertexArrayBuffer(vfcoords);
+ } else if (doubleCoordDefined) {
+ dverts = getVertexArrayBuffer(vdcoords);
+ }
+
+ // get color array
+ if (floatColorsDefined) {
+ fclrs = getColorArrayBuffer(cfdata);
+ } else if (byteColorsDefined) {
+ bclrs = getColorArrayBuffer(cbdata);
+ }
+
+ // get normal array
+ if (normalsDefined) {
+ norms = getNormalArrayBuffer(ndata);
+ }
+
+ int[] sarray = null;
+ int[] start_array = null;
+ int strip_len = 0;
+ if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
+ sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts;
+ strip_len = sarray.length;
+ start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices;
+ }
+
+ executeGeometryArrayVA(ctx, geo, geo_type,
+ isNonUniformScale, ignoreVertexColors,
+ vcount, vformat, vdefined,
+ initialCoordIndex, fverts, dverts,
+ initialColorIndex, fclrs, bclrs,
+ initialNormalIndex, norms,
+ vertexAttrCount, vertexAttrSizes,
+ vertexAttrIndices, vertexAttrBufs,
+ texCoordMapLength,
+ texcoordoffset, numActiveTexUnitState,
+ texIndex, texstride, texCoordBufs, cdirty,
+ sarray, strip_len, start_array);
+ }
+
+ // used by GeometryArray by Reference with NIO buffer
+ void executeVABuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int initialCoordIndex,
+ Object vcoords,
+ int initialColorIndex,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ int initialNormalIndex, Object ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndices, Object[] vertexAttrData,
+ int texCoordMapLength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty) {
+ if (VERBOSE) System.err.println("JoglPipeline.executeVABuffer()");
+
+ boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
+ boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
+ boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
+ boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
+ boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
+ boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
+ boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
+
+ FloatBuffer fverts = null;
+ DoubleBuffer dverts = null;
+ FloatBuffer fclrs = null;
+ ByteBuffer bclrs = null;
+ FloatBuffer[] texCoordBufs = null;
+ FloatBuffer norms = null;
+ FloatBuffer[] vertexAttrBufs = null;
+
+ // Get vertex attribute arrays
+ if (vattrDefined) {
+ vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData);
+ }
+
+ // get texture arrays
+ if (textureDefined) {
+ texCoordBufs = new FloatBuffer[texCoords.length];
+ for (int i = 0; i < texCoords.length; i++) {
+ texCoordBufs[i] = (FloatBuffer) texCoords[i];
+ }
+ }
+
+ // get coordinate array
+ if (floatCoordDefined) {
+ fverts = (FloatBuffer) vcoords;
+ } else if (doubleCoordDefined) {
+ dverts = (DoubleBuffer) vcoords;
+ }
+
+ if (fverts == null && dverts == null) {
+ return;
+ }
+
+ // get color array
+ if (floatColorsDefined) {
+ if (cfdata != null)
+ fclrs = getColorArrayBuffer(cfdata);
+ else
+ fclrs = (FloatBuffer) cdataBuffer;
+ } else if (byteColorsDefined) {
+ if (cbdata != null)
+ bclrs = getColorArrayBuffer(cbdata);
+ else
+ bclrs = (ByteBuffer) cdataBuffer;
+ }
+
+ // get normal array
+ if (normalsDefined) {
+ norms = (FloatBuffer) ndata;
+ }
+
+ int[] sarray = null;
+ int[] start_array = null;
+ int strip_len = 0;
+ if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
+ sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts;
+ strip_len = sarray.length;
+ start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices;
+ }
+
+ executeGeometryArrayVA(ctx, geo, geo_type,
+ isNonUniformScale, ignoreVertexColors,
+ vcount, vformat, vdefined,
+ initialCoordIndex, fverts, dverts,
+ initialColorIndex, fclrs, bclrs,
+ initialNormalIndex, norms,
+ vertexAttrCount, vertexAttrSizes,
+ vertexAttrIndices, vertexAttrBufs,
+ texCoordMapLength,
+ texcoordoffset, numActiveTexUnitState,
+ texIndex, texstride, texCoordBufs, cdirty,
+ sarray, strip_len, start_array);
+ }
+
+ // used by GeometryArray by Reference in interleaved format with NIO buffer
+ void executeInterleavedBuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texUnitOffset,
+ int numActiveTexUnit,
+ Object varray, float[] cdata, int cdirty) {
+ if (VERBOSE) System.err.println("JoglPipeline.executeInterleavedBuffer()");
+
+ executeGeometryArray(ctx, geo, geo_type,
+ isNonUniformScale, useAlpha, ignoreVertexColors,
+ startVIndex, vcount, vformat,
+ texCoordSetCount, texCoordSetMap, texCoordSetMapLen,
+ texUnitOffset, numActiveTexUnit, 0, null,
+ null, (Buffer) varray, cdata, cdirty);
+ }
+
+ void setVertexFormat(Context ctx, GeometryArrayRetained geo,
+ int vformat, boolean useAlpha, boolean ignoreVertexColors) {
+ if (VERBOSE) System.err.println("JoglPipeline.setVertexFormat()");
+
+ GL gl = context(ctx).getGL();
+
+ // Enable and disable the appropriate pointers
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
+ } else {
+ gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
+ }
+ if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) {
+ gl.glEnableClientState(GL.GL_COLOR_ARRAY);
+ } else {
+ gl.glDisableClientState(GL.GL_COLOR_ARRAY);
+ }
+
+ if (gl.isExtensionAvailable("GL_SUN_global_alpha")) {
+ if (useAlpha) {
+ gl.glEnable(GL.GL_GLOBAL_ALPHA_SUN);
+ } else {
+ gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN);
+ }
+ }
+
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
+ } else {
+ gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
+ }
+ }
+
+ void disableGlobalAlpha(Context ctx, GeometryArrayRetained geo, int vformat,
+ boolean useAlpha, boolean ignoreVertexColors) {
+ if (VERBOSE) System.err.println("JoglPipeline.disableGlobalAlpha()");
+
+ GL gl = context(ctx).getGL();
+
+ if (gl.isExtensionAvailable("GL_SUN_global_alpha")) {
+ if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) {
+ if (useAlpha) {
+ gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN);
+ }
+ }
+ }
+ }
+
+ // used for GeometryArrays
+ void buildGA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int startVIndex,
+ int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen, int[] texCoordSetMapOffset,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ double[] xform, double[] nxform,
+ float[] varray) {
+ if (VERBOSE) System.err.println("JoglPipeline.buildGA()");
+ JoglContext jctx = (JoglContext) ctx;
+ GL gl = context(ctx).getGL();
+ FloatBuffer verts = null;
+ int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0;
+ int texStride = 0;
+ int vAttrOff = 0;
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ stride += 3;
+ }
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ stride += 3;
+ coordoff += 3;
+ }
+
+ if ((vformat & GeometryArray.COLOR) != 0) {
+ if ((vformat & GeometryArray.BY_REFERENCE) != 0) {
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ } else {
+ stride += 3;
+ normoff += 3;
+ coordoff += 3;
+ }
+ } else {
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ }
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
+ texStride = 2 * texCoordSetCount;
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
+ texStride = 3 * texCoordSetCount;
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) {
+ texStride = 4 * texCoordSetCount;
+ }
+ stride += texStride;
+ normoff += texStride;
+ coloroff += texStride;
+ coordoff += texStride;
+ }
+
+ int vAttrStride = 0;
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ vAttrStride += vertexAttrSizes[i];
+ }
+ stride += vAttrStride;
+ normoff += vAttrStride;
+ coloroff += vAttrStride;
+ coordoff += vAttrStride;
+ texCoordoff += vAttrStride;
+ }
+
+ int bstride = stride * BufferUtil.SIZEOF_FLOAT;
+ // Start sending down from the startVIndex
+ int initialOffset = startVIndex * stride;
+ normoff += initialOffset;
+ coloroff += initialOffset;
+ coordoff += initialOffset;
+ texCoordoff += initialOffset;
+ vAttrOff += initialOffset;
+
+ // process alpha for geometryArray without alpha
+ boolean useAlpha = false;
+ if (updateAlpha && !ignoreVertexColors) {
+ useAlpha = true;
+ }
+
+ if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
+ int[] sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts;
+
+ int primType = 0;
+ switch (geo_type) {
+ case GeometryRetained.GEO_TYPE_TRI_STRIP_SET :
+ primType = GL.GL_TRIANGLE_STRIP;
+ break;
+ case GeometryRetained.GEO_TYPE_TRI_FAN_SET :
+ primType = GL.GL_TRIANGLE_FAN;
+ break;
+ case GeometryRetained.GEO_TYPE_LINE_STRIP_SET :
+ primType = GL.GL_LINE_STRIP;
+ break;
+ }
+
+ if (ignoreVertexColors) {
+ vformat &= ~GeometryArray.COLOR;
+ }
+
+ for (int i = 0; i < sarray.length; i++) {
+ gl.glBegin(primType);
+ for (int j = 0; j < sarray[i]; j++) {
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ if (nxform != null) {
+ float nx = (float) (nxform[0] * varray[normoff] +
+ nxform[1] * varray[normoff+1] +
+ nxform[2] * varray[normoff+2]);
+ float ny = (float) (nxform[4] * varray[normoff] +
+ nxform[5] * varray[normoff+1] +
+ nxform[6] * varray[normoff+2]);
+ float nz = (float) (nxform[8] * varray[normoff] +
+ nxform[9] * varray[normoff+1] +
+ nxform[10] * varray[normoff+2]);
+ gl.glNormal3f(nx, ny, nz);
+ } else {
+ gl.glNormal3f(varray[normoff], varray[normoff+1], varray[normoff+2]);
+ }
+ }
+ if ((vformat & GeometryArray.COLOR) != 0) {
+ if (useAlpha) {
+ gl.glColor4f(varray[coloroff],
+ varray[coloroff+1],
+ varray[coloroff+2],
+ varray[coloroff+3] * alpha);
+ } else {
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) { // alpha is present
+ gl.glColor4f(varray[coloroff],
+ varray[coloroff+1],
+ varray[coloroff+2],
+ varray[coloroff+3]);
+ } else {
+ gl.glColor3f(varray[coloroff],
+ varray[coloroff+1],
+ varray[coloroff+2]);
+ }
+ }
+ }
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ int vaOff = vAttrOff;
+ if (verts == null) {
+ verts = FloatBuffer.wrap(varray);
+ }
+ for (int vaIdx = 0; vaIdx < vertexAttrCount; vaIdx++) {
+ switch (vertexAttrSizes[vaIdx]) {
+ case 1:
+ verts.position(vaOff);
+ jctx.vertexAttr1fv(gl, vaIdx, verts);
+ break;
+ case 2:
+ verts.position(vaOff);
+ jctx.vertexAttr2fv(gl, vaIdx, verts);
+ break;
+ case 3:
+ verts.position(vaOff);
+ jctx.vertexAttr3fv(gl, vaIdx, verts);
+ break;
+ case 4:
+ verts.position(vaOff);
+ jctx.vertexAttr4fv(gl, vaIdx, verts);
+ break;
+ }
+
+ vaOff += vertexAttrSizes[vaIdx];
+ }
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ if (texCoordSetMapLen > 0) {
+ if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
+ for (int k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ int off = texCoordoff + texCoordSetMapOffset[k];
+ gl.glMultiTexCoord2f(GL.GL_TEXTURE0 + k,
+ varray[off],
+ varray[off + 1]);
+ }
+ }
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
+ for (int k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ int off = texCoordoff + texCoordSetMapOffset[k];
+ gl.glMultiTexCoord3f(GL.GL_TEXTURE0 + k,
+ varray[off],
+ varray[off + 1],
+ varray[off + 2]);
+ }
+ }
+ } else {
+ for (int k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ int off = texCoordoff + texCoordSetMapOffset[k];
+ gl.glMultiTexCoord4f(GL.GL_TEXTURE0 + k,
+ varray[off],
+ varray[off + 1],
+ varray[off + 2],
+ varray[off + 3]);
+ }
+ }
+ }
+ } else { // no multitexture
+ if (texCoordSetMapOffset[0] != -1) {
+ int off = texCoordoff + texCoordSetMapOffset[0];
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
+ gl.glTexCoord2f(varray[off], varray[off + 1]);
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
+ gl.glTexCoord3f(varray[off], varray[off + 1], varray[off + 2]);
+ } else {
+ gl.glTexCoord4f(varray[off], varray[off + 1], varray[off + 2], varray[off + 3]);
+ }
+ }
+ } // no multitexture
+ }
+ // texCoordSetMapLen can't be 0 if texture coordinates
+ // is to be specified
+ }
+
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ if (xform != null) {
+ // transform the vertex data with the static transform
+ float w = (float) (xform[12] * varray[coordoff] +
+ xform[13] * varray[coordoff+1] +
+ xform[14] * varray[coordoff+2] +
+ xform[15]);
+ float winv = 1.0f/w;
+ float vx = (float) (xform[0] * varray[coordoff] +
+ xform[1] * varray[coordoff+1] +
+ xform[2] * varray[coordoff+2] +
+ xform[3]) * winv;
+ float vy = (float) (xform[4] * varray[coordoff] +
+ xform[5] * varray[coordoff+1] +
+ xform[6] * varray[coordoff+2] +
+ xform[7]) * winv;
+ float vz = (float) (xform[8] * varray[coordoff] +
+ xform[9] * varray[coordoff+1] +
+ xform[10] * varray[coordoff+2] +
+ xform[11]) * winv;
+ gl.glVertex3f(vx, vy, vz);
+ } else {
+ gl.glVertex3f(varray[coordoff], varray[coordoff + 1], varray[coordoff + 2]);
+ }
+ }
+ normoff += stride;
+ coloroff += stride;
+ coordoff += stride;
+ texCoordoff += stride;
+ vAttrOff += stride;
+ }
+ gl.glEnd();
+ }
+ } else if ((geo_type == GeometryRetained.GEO_TYPE_QUAD_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_TRI_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_POINT_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_LINE_SET)) {
+ int primType = 0;
+ switch (geo_type) {
+ case GeometryRetained.GEO_TYPE_QUAD_SET :
+ primType = GL.GL_QUADS;
+ break;
+ case GeometryRetained.GEO_TYPE_TRI_SET :
+ primType = GL.GL_TRIANGLES;
+ break;
+ case GeometryRetained.GEO_TYPE_POINT_SET :
+ primType = GL.GL_POINTS;
+ break;
+ case GeometryRetained.GEO_TYPE_LINE_SET :
+ primType = GL.GL_LINES;
+ break;
+ }
+
+ if (ignoreVertexColors) {
+ vformat &= ~GeometryArray.COLOR;
+ }
+
+ gl.glBegin(primType);
+ for (int j = 0; j < vcount; j++) {
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ if (nxform != null) {
+ float nx = (float) (nxform[0] * varray[normoff] +
+ nxform[1] * varray[normoff+1] +
+ nxform[2] * varray[normoff+2]);
+ float ny = (float) (nxform[4] * varray[normoff] +
+ nxform[5] * varray[normoff+1] +
+ nxform[6] * varray[normoff+2]);
+ float nz = (float) (nxform[8] * varray[normoff] +
+ nxform[9] * varray[normoff+1] +
+ nxform[10] * varray[normoff+2]);
+ gl.glNormal3f(nx, ny, nz);
+ } else {
+ gl.glNormal3f(varray[normoff], varray[normoff + 1], varray[normoff + 2]);
+ }
+ }
+ if ((vformat & GeometryArray.COLOR) != 0) {
+ if (useAlpha) {
+ float cr, cg, cb, ca;
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
+ cr = varray[coloroff];
+ cg = varray[coloroff + 1];
+ cb = varray[coloroff + 2];
+ ca = varray[coloroff + 3] * alpha;
+ } else {
+ cr = varray[coloroff];
+ cg = varray[coloroff + 1];
+ cb = varray[coloroff + 2];
+ ca = alpha;
+ }
+ gl.glColor4f(cr, cg, cb, ca);
+ } else {
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) { // alpha is present
+ gl.glColor4f(varray[coloroff],
+ varray[coloroff + 1],
+ varray[coloroff + 2],
+ varray[coloroff + 3]);
+ } else {
+ gl.glColor3f(varray[coloroff],
+ varray[coloroff + 1],
+ varray[coloroff + 2]);
+ }
+ }
+ }
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ int vaOff = vAttrOff;
+ if (verts == null) {
+ verts = FloatBuffer.wrap(varray);
+ }
+ for (int vaIdx = 0; vaIdx < vertexAttrCount; vaIdx++) {
+ switch (vertexAttrSizes[vaIdx]) {
+ case 1:
+ verts.position(vaOff);
+ jctx.vertexAttr1fv(gl, vaIdx, verts);
+ break;
+ case 2:
+ verts.position(vaOff);
+ jctx.vertexAttr2fv(gl, vaIdx, verts);
+ break;
+ case 3:
+ verts.position(vaOff);
+ jctx.vertexAttr3fv(gl, vaIdx, verts);
+ break;
+ case 4:
+ verts.position(vaOff);
+ jctx.vertexAttr4fv(gl, vaIdx, verts);
+ break;
+ }
+
+ vaOff += vertexAttrSizes[vaIdx];
+ }
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ if (texCoordSetMapLen > 0) {
+ if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
+ for (int k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ int off = texCoordoff + texCoordSetMapOffset[k];
+ gl.glMultiTexCoord2f(GL.GL_TEXTURE0 + k,
+ varray[off],
+ varray[off + 1]);
+ }
+ }
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
+ for (int k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ int off = texCoordoff + texCoordSetMapOffset[k];
+ gl.glMultiTexCoord3f(GL.GL_TEXTURE0 + k,
+ varray[off],
+ varray[off + 1],
+ varray[off + 2]);
+ }
+ }
+ } else {
+ for (int k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ int off = texCoordoff + texCoordSetMapOffset[k];
+ gl.glMultiTexCoord4f(GL.GL_TEXTURE0 + k,
+ varray[off],
+ varray[off + 1],
+ varray[off + 2],
+ varray[off + 3]);
+ }
+ }
+ }
+ } else { // no multitexture
+ if (texCoordSetMapOffset[0] != -1) {
+ int off = texCoordoff + texCoordSetMapOffset[0];
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
+ gl.glTexCoord2f(varray[off], varray[off + 1]);
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
+ gl.glTexCoord3f(varray[off], varray[off + 1], varray[off + 2]);
+ } else {
+ gl.glTexCoord4f(varray[off], varray[off + 1], varray[off + 2], varray[off + 3]);
+ }
+ }
+ } // no multitexture
+ }
+ // texCoordSetMapLen can't be 0 if texture coordinates is
+ // to be specified
+ }
+
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ if (xform != null) {
+ // transform the vertex data with the static transform
+ float w = (float) (xform[12] * varray[coordoff] +
+ xform[13] * varray[coordoff+1] +
+ xform[14] * varray[coordoff+2] +
+ xform[15]);
+ float winv = 1.0f/w;
+ float vx = (float) (xform[0] * varray[coordoff] +
+ xform[1] * varray[coordoff+1] +
+ xform[2] * varray[coordoff+2] +
+ xform[3]) * winv;
+ float vy = (float) (xform[4] * varray[coordoff] +
+ xform[5] * varray[coordoff+1] +
+ xform[6] * varray[coordoff+2] +
+ xform[7]) * winv;
+ float vz = (float) (xform[8] * varray[coordoff] +
+ xform[9] * varray[coordoff+1] +
+ xform[10] * varray[coordoff+2] +
+ xform[11]) * winv;
+ gl.glVertex3f(vx, vy, vz);
+ } else {
+ gl.glVertex3f(varray[coordoff], varray[coordoff + 1], varray[coordoff + 2]);
+ }
+ }
+ normoff += stride;
+ coloroff += stride;
+ coordoff += stride;
+ texCoordoff += stride;
+ vAttrOff += stride;
+ }
+ gl.glEnd();
+ }
+ }
+
+ // used to Build Dlist GeometryArray by Reference with java arrays
+ void buildGAForByRef(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int initialCoordIndex, float[] vfcoords, double[] vdcoords,
+ int initialColorIndex, float[] cfdata, byte[] cbdata,
+ int initialNormalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndices, float[][] vertexAttrData,
+ int texCoordMapLength,
+ int[] tcoordsetmap,
+ int[] texIndices, int texStride, Object[] texCoords,
+ double[] xform, double[] nxform) {
+ if (VERBOSE) System.err.println("JoglPipeline.buildGAForByRef()");
+
+ GL gl = context(ctx).getGL();
+
+ boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
+ boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
+ boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
+ boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
+ boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
+ boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
+ boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
+
+ FloatBuffer fverts = null;
+ DoubleBuffer dverts = null;
+ FloatBuffer fclrs = null;
+ ByteBuffer bclrs = null;
+ FloatBuffer[] texCoordBufs = null;
+ FloatBuffer norms = null;
+ FloatBuffer[] vertexAttrBufs = null;
+
+ // Get vertex attribute arrays
+ if (vattrDefined) {
+ vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData);
+ }
+
+ // get texture arrays
+ if (textureDefined) {
+ texCoordBufs = getTexCoordSetBuffer(texCoords);
+ }
+
+ // process alpha for geometryArray without alpha
+ boolean useAlpha = false;
+ if (updateAlpha && !ignoreVertexColors) {
+ useAlpha = true;
+ }
+
+ int[] sarray = null;
+ int[] start_array = null;
+ int strip_len = 0;
+ if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
+ sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts;
+ strip_len = sarray.length;
+ start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices;
+ }
+
+ if (ignoreVertexColors) {
+ vformat &= ~GeometryArray.COLOR;
+ floatColorsDefined = false;
+ byteColorsDefined = false;
+ }
+
+ // get coordinate array
+ if (floatCoordDefined) {
+ gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
+ fverts = getVertexArrayBuffer(vfcoords, (xform == null));
+ if (xform != null) {
+ // Must copy in and transform data
+ for (int i = initialCoordIndex; i < vcount * 3; i += 3) {
+ fverts.put(i , (float) (xform[0] * vfcoords[i] +
+ xform[1] * vfcoords[i+1] +
+ xform[2] * vfcoords[i+2]));
+ fverts.put(i+1, (float) (xform[4] * vfcoords[i] +
+ xform[5] * vfcoords[i+1] +
+ xform[6] * vfcoords[i+2]));
+ fverts.put(i+2, (float) (xform[8] * vfcoords[i] +
+ xform[9] * vfcoords[i+1] +
+ xform[10] * vfcoords[i+2]));
+ }
+ }
+ } else if (doubleCoordDefined) {
+ gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
+ dverts = getVertexArrayBuffer(vdcoords, (xform == null));
+ if (xform != null) {
+ // Must copy in and transform data
+ for (int i = initialCoordIndex; i < vcount * 3; i += 3) {
+ dverts.put(i , (xform[0] * vdcoords[i] +
+ xform[1] * vdcoords[i+1] +
+ xform[2] * vdcoords[i+2]));
+ dverts.put(i+1, (xform[4] * vdcoords[i] +
+ xform[5] * vdcoords[i+1] +
+ xform[6] * vdcoords[i+2]));
+ dverts.put(i+2, (xform[8] * vdcoords[i] +
+ xform[9] * vdcoords[i+1] +
+ xform[10] * vdcoords[i+2]));
+ }
+ }
+ } else {
+ gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
+ }
+
+ // get color array
+ if (floatColorsDefined) {
+ gl.glEnableClientState(GL.GL_COLOR_ARRAY);
+ fclrs = getColorArrayBuffer(cfdata, !useAlpha);
+ if (useAlpha) {
+ // Must copy in and modify color data
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
+ for (int i = initialColorIndex; i < vcount * 4; i += 4) {
+ fclrs.put(i , cfdata[i]);
+ fclrs.put(i+1, cfdata[i+1]);
+ fclrs.put(i+2, cfdata[i+2]);
+ fclrs.put(i+3, alpha * cfdata[i+3]);
+ }
+ } else {
+ int k = 0;
+ for (int i = initialColorIndex; i < vcount * 4; i += 4) {
+ fclrs.put(i , cfdata[k++]);
+ fclrs.put(i+1, cfdata[k++]);
+ fclrs.put(i+2, cfdata[k++]);
+ fclrs.put(i+3, alpha);
+ }
+ }
+ vformat |= GeometryArray.WITH_ALPHA;
+ }
+ } else if (byteColorsDefined) {
+ gl.glEnableClientState(GL.GL_COLOR_ARRAY);
+ bclrs = getColorArrayBuffer(cbdata, !useAlpha);
+ if (useAlpha) {
+ // Must copy in and modify color data
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
+ for (int i = initialColorIndex; i < vcount * 4; i += 4) {
+ bclrs.put(i , cbdata[i]);
+ bclrs.put(i+1, cbdata[i+1]);
+ bclrs.put(i+2, cbdata[i+2]);
+ bclrs.put(i+3, (byte) (alpha * (int) (cbdata[i+3] & 0xFF)));
+ }
+ } else {
+ int k = 0;
+ for (int i = initialColorIndex; i < vcount * 4; i += 4) {
+ bclrs.put(i , cbdata[k++]);
+ bclrs.put(i+1, cbdata[k++]);
+ bclrs.put(i+2, cbdata[k++]);
+ bclrs.put(i+3, (byte) (alpha * 255.0f));
+ }
+ }
+ vformat |= GeometryArray.WITH_ALPHA;
+ }
+ } else {
+ gl.glDisableClientState(GL.GL_COLOR_ARRAY);
+ }
+
+ // get normal array
+ if (normalsDefined) {
+ gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
+ norms = getNormalArrayBuffer(ndata, (nxform == null));
+ if (nxform != null) {
+ // Must copy in and transform data
+ for (int i = initialNormalIndex; i < vcount * 3; i += 3) {
+ norms.put(i , (float) (nxform[0] * ndata[i] +
+ nxform[1] * ndata[i+1] +
+ nxform[2] * ndata[i+2]));
+ norms.put(i+1, (float) (nxform[4] * ndata[i] +
+ nxform[5] * ndata[i+1] +
+ nxform[6] * ndata[i+2]));
+ norms.put(i+2, (float) (nxform[8] * ndata[i] +
+ nxform[9] * ndata[i+1] +
+ nxform[10] * ndata[i+2]));
+ }
+ }
+ } else {
+ gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
+ }
+
+ executeGeometryArrayVA(ctx, geo, geo_type,
+ isNonUniformScale, ignoreVertexColors,
+ vcount, vformat, vdefined,
+ initialCoordIndex, fverts, dverts,
+ initialColorIndex, fclrs, bclrs,
+ initialNormalIndex, norms,
+ vertexAttrCount, vertexAttrSizes,
+ vertexAttrIndices, vertexAttrBufs,
+ texCoordMapLength,
+ tcoordsetmap, texCoordMapLength,
+ texIndices, texStride, texCoordBufs, 0,
+ sarray, strip_len, start_array);
+ }
+
+ //----------------------------------------------------------------------
+ // Private helper methods for GeometryArrayRetained
+ //
+
+ private void
+ testForInterleavedArrays(int vformat,
+ boolean[] useInterleavedArrays,
+ int[] iaFormat) {
+ if (VERBOSE) System.err.println("JoglPipeline.testForInterleavedArrays()");
+ useInterleavedArrays[0] = true;
+ switch (vformat) {
+ case GeometryArray.COORDINATES :
+ iaFormat[0] = GL.GL_V3F; break;
+ case (GeometryArray.COORDINATES | GeometryArray.NORMALS) :
+ iaFormat[0] = GL.GL_N3F_V3F; break;
+ case (GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2) :
+ iaFormat[0] = GL.GL_T2F_V3F; break;
+ case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR) :
+ case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR | GeometryArray.WITH_ALPHA) :
+ iaFormat[0] = GL.GL_C4F_N3F_V3F; break;
+ case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.TEXTURE_COORDINATE_2) :
+ iaFormat[0] = GL.GL_T2F_N3F_V3F; break;
+ case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR | GeometryArray.TEXTURE_COORDINATE_2):
+ case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR | GeometryArray.WITH_ALPHA | GeometryArray.TEXTURE_COORDINATE_2):
+ iaFormat[0] = GL.GL_T2F_C4F_N3F_V3F; break;
+ default:
+ useInterleavedArrays[0] = false; break;
+ }
+ }
+
+ private void
+ enableTexCoordPointer(GL gl,
+ int texUnit,
+ int texSize,
+ int texDataType,
+ int stride,
+ Buffer pointer) {
+ if (VERBOSE) System.err.println("JoglPipeline.enableTexCoordPointer()");
+ clientActiveTextureUnit(gl, texUnit);
+ gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+ gl.glTexCoordPointer(texSize, texDataType, stride, pointer);
+ }
+
+ private void
+ disableTexCoordPointer(GL gl,
+ int texUnit) {
+ if (VERBOSE) System.err.println("JoglPipeline.disableTexCoordPointer()");
+ clientActiveTextureUnit(gl, texUnit);
+ gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+ }
+
+ private void
+ clientActiveTextureUnit(GL gl,
+ int texUnit) {
+ if (VERBOSE) System.err.println("JoglPipeline.clientActiveTextureUnit()");
+ if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ gl.glClientActiveTexture(texUnit + GL.GL_TEXTURE0);
+ }
+ }
+
+
+ private void
+ executeTexture(int texCoordSetMapLen,
+ int texSize, int bstride, int texCoordoff,
+ int[] texCoordSetMapOffset,
+ int numActiveTexUnit,
+ FloatBuffer verts, GL gl) {
+ if (VERBOSE) System.err.println("JoglPipeline.executeTexture()");
+ int tus = 0; /* texture unit state index */
+
+ for (int i = 0; i < numActiveTexUnit; i++) {
+
+ tus = i;
+
+ /*
+ * it's possible thattexture unit state index (tus)
+ * is greater than the texCoordSetMapOffsetLen, in this
+ * case, just disable TexCoordPointer.
+ */
+ if ((tus < texCoordSetMapLen) &&
+ (texCoordSetMapOffset[tus] != -1)) {
+ if (EXTRA_DEBUGGING) {
+ System.err.println(" texCoord position " + i + ": " + (texCoordoff + texCoordSetMapOffset[tus]));
+ }
+ verts.position(texCoordoff + texCoordSetMapOffset[tus]);
+ enableTexCoordPointer(gl, i,
+ texSize, GL.GL_FLOAT, bstride,
+ verts);
+ } else {
+ disableTexCoordPointer(gl, i);
+ }
+ }
+ }
+
+ private void
+ resetTexture(GL gl, JoglContext ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.resetTexture()");
+ /* Disable texture coordinate arrays for all texture units */
+ for (int i = 0; i < ctx.getMaxTexCoordSets(); i++) {
+ disableTexCoordPointer(gl, i);
+ }
+ /* Reset client active texture unit to 0 */
+ clientActiveTextureUnit(gl, 0);
+ }
+
+ private void
+ executeGeometryArray(Context absCtx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetMapOffset,
+ int numActiveTexUnitState,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[] varray, Buffer varrayBuffer,
+ float[] carray, int cDirty) {
+ if (VERBOSE) System.err.println("JoglPipeline.executeGeometryArray()");
+ JoglContext ctx = (JoglContext) absCtx;
+ GLContext context = context(ctx);
+ GL gl = context.getGL();
+
+ boolean useInterleavedArrays;
+ int iaFormat = 0;
+ int primType = 0;
+ int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0;
+ int texSize = 0, texStride = 0;
+ int vAttrOff = 0;
+ int vAttrStride = 0;
+ int bstride = 0, cbstride = 0;
+ FloatBuffer verts = null;
+ FloatBuffer clrs = null;
+ int[] sarray = null;
+ int[] start_array = null;
+
+ if (EXTRA_DEBUGGING) {
+ System.err.println("Vertex format: " + getVertexDescription(vformat));
+ System.err.println("Geometry type: " + getGeometryDescription(geo_type));
+ if (carray != null) {
+ System.err.println(" Separate color array");
+ } else {
+ System.err.println(" Colors (if any) interleaved");
+ }
+ }
+
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ stride += 3;
+ }
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ stride += 3;
+ coordoff += 3;
+ }
+ if ((vformat & GeometryArray.COLOR) != 0) {
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0 ) {
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ } else { /* Handle the case of executeInterleaved 3f */
+ stride += 3;
+ normoff += 3;
+ coordoff += 3;
+ }
+ }
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ if (EXTRA_DEBUGGING) {
+ System.err.println(" Number of tex coord sets: " + texCoordSetCount);
+ }
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
+ texSize = 2;
+ texStride = 2 * texCoordSetCount;
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
+ texSize = 3;
+ texStride = 3 * texCoordSetCount;
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) {
+ texSize = 4;
+ texStride = 4 * texCoordSetCount;
+ }
+ stride += texStride;
+ normoff += texStride;
+ coloroff += texStride;
+ coordoff += texStride;
+ }
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ vAttrStride += vertexAttrSizes[i];
+ }
+ stride += vAttrStride;
+ normoff += vAttrStride;
+ coloroff += vAttrStride;
+ coordoff += vAttrStride;
+ texCoordoff += vAttrStride;
+ }
+
+ bstride = stride * BufferUtil.SIZEOF_FLOAT;
+
+ if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
+ sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts;
+ start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices;
+ }
+
+ // We have to copy if the data isn't specified using NIO
+ if (varray != null) {
+ verts = getVertexArrayBuffer(varray);
+ } else if (varrayBuffer != null) {
+ verts = (FloatBuffer) varrayBuffer;
+ } else {
+ // This should never happen
+ throw new AssertionError("Unable to get vertex pointer");
+ }
+
+ // using byRef interleaved array and has a separate pointer, then ..
+ int cstride = stride;
+ if (carray != null) {
+ clrs = getColorArrayBuffer(carray);
+ cstride = 4;
+ } else {
+ // FIXME: need to "auto-slice" this buffer later
+ clrs = verts;
+ }
+
+ cbstride = cstride * BufferUtil.SIZEOF_FLOAT;
+
+ // Enable normalize for non-uniform scale (which rescale can't handle)
+ if (isNonUniformScale) {
+ gl.glEnable(GL.GL_NORMALIZE);
+ }
+
+ int startVertex = stride * startVIndex;
+ int startClrs = cstride * startVIndex;
+ if (clrs == verts) {
+ startClrs += coloroff;
+ }
+
+ /*** Handle non-indexed strip GeometryArray first *******/
+ if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
+ if (ignoreVertexColors || (carray != null) ||
+ ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = false;
+ } else {
+ boolean[] tmp = new boolean[1];
+ int[] tmp2 = new int[1];
+ testForInterleavedArrays(vformat, tmp, tmp2);
+ useInterleavedArrays = tmp[0];
+ iaFormat = tmp2[0];
+ }
+ if (useInterleavedArrays) {
+ verts.position(startVertex);
+ gl.glInterleavedArrays(iaFormat, bstride, verts);
+ } else {
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ verts.position(startVertex + normoff);
+ gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
+ }
+ if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) {
+ if (EXTRA_DEBUGGING) {
+ System.err.println(" Doing colors");
+ }
+ clrs.position(startClrs);
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) {
+ gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs);
+ } else {
+ gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs);
+ }
+ }
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ verts.position(startVertex + coordoff);
+ gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ executeTexture(texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetMapOffset,
+ numActiveTexUnitState,
+ verts, gl);
+ }
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ int vAttrOffset = startVertex + vAttrOff;
+ for (int i = 0; i < vertexAttrCount; i++) {
+ ctx.enableVertexAttrArray(gl, i);
+ verts.position(vAttrOffset);
+ ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i],
+ GL.GL_FLOAT, bstride, verts);
+ vAttrOffset += vertexAttrSizes[i];
+ }
+ }
+ }
+
+ switch (geo_type) {
+ case GeometryRetained.GEO_TYPE_TRI_STRIP_SET:
+ primType = GL.GL_TRIANGLE_STRIP;
+ break;
+ case GeometryRetained.GEO_TYPE_TRI_FAN_SET:
+ primType = GL.GL_TRIANGLE_FAN;
+ break;
+ case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
+ primType = GL.GL_LINE_STRIP;
+ break;
+ }
+
+ if (gl.isExtensionAvailable("GL_EXT_multi_draw_arrays")) {
+ gl.glMultiDrawArraysEXT(primType, start_array, 0, sarray, 0, sarray.length);
+ } else {
+ for (int i = 0; i < sarray.length; i++) {
+ gl.glDrawArrays(primType, start_array[i], sarray[i]);
+ }
+ }
+ } else if ((geo_type == GeometryRetained.GEO_TYPE_QUAD_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_TRI_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_POINT_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_LINE_SET)) {
+ /******* Handle non-indexed non-striped GeometryArray now *****/
+ if (ignoreVertexColors || (carray != null) ||
+ ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = false;
+ } else {
+ boolean[] tmp = new boolean[1];
+ int[] tmp2 = new int[1];
+ testForInterleavedArrays(vformat, tmp, tmp2);
+ useInterleavedArrays = tmp[0];
+ iaFormat = tmp2[0];
+ }
+
+ if (useInterleavedArrays) {
+ verts.position(startVertex);
+ gl.glInterleavedArrays(iaFormat, bstride, verts);
+ } else {
+ if (EXTRA_DEBUGGING) {
+ System.err.println(" startVertex: " + startVertex);
+ System.err.println(" stride: " + stride);
+ System.err.println(" bstride: " + bstride);
+ System.err.println(" normoff: " + normoff);
+ System.err.println(" coloroff: " + coloroff);
+ System.err.println(" coordoff: " + coordoff);
+ System.err.println(" texCoordoff: " + texCoordoff);
+ }
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ verts.position(startVertex + normoff);
+ gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
+ }
+ if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) {
+ clrs.position(startClrs);
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) {
+ gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs);
+ } else {
+ gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs);
+ }
+ }
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ verts.position(startVertex + coordoff);
+ gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ executeTexture(texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetMapOffset,
+ numActiveTexUnitState,
+ verts, gl);
+ }
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ int vAttrOffset = startVertex + vAttrOff;
+ for (int i = 0; i < vertexAttrCount; i++) {
+ ctx.enableVertexAttrArray(gl, i);
+ verts.position(vAttrOffset);
+ ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i],
+ GL.GL_FLOAT, bstride, verts);
+ vAttrOffset += vertexAttrSizes[i];
+ }
+ }
+ }
+ switch (geo_type){
+ case GeometryRetained.GEO_TYPE_QUAD_SET : gl.glDrawArrays(GL.GL_QUADS, 0, vcount); break;
+ case GeometryRetained.GEO_TYPE_TRI_SET : gl.glDrawArrays(GL.GL_TRIANGLES, 0, vcount); break;
+ case GeometryRetained.GEO_TYPE_POINT_SET: gl.glDrawArrays(GL.GL_POINTS, 0, vcount); break;
+ case GeometryRetained.GEO_TYPE_LINE_SET : gl.glDrawArrays(GL.GL_LINES, 0, vcount); break;
+ }
+ }
+
+ /* clean up if we turned on normalize */
+ if (isNonUniformScale) {
+ gl.glDisable(GL.GL_NORMALIZE);
+ }
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ resetVertexAttrs(gl, ctx, vertexAttrCount);
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ resetTexture(gl, ctx);
+ }
+ }
+
+
+ // glLockArrays() is invoked only for indexed geometry, and the
+ // vertexCount is guarenteed to be >= 0.
+ private void lockArray(GL gl, int vertexCount) {
+ if (gl.isExtensionAvailable("GL_EXT_compiled_vertex_array")) {
+ gl.glLockArraysEXT(0, vertexCount);
+ }
+ }
+
+ private void unlockArray(GL gl) {
+ if (gl.isExtensionAvailable("GL_EXT_compiled_vertex_array")) {
+ gl.glUnlockArraysEXT();
+ }
+ }
+
+ private void
+ executeGeometryArrayVA(Context absCtx,
+ GeometryArrayRetained geo,
+ int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int initialCoordIndex, FloatBuffer fverts, DoubleBuffer dverts,
+ int initialColorIndex, FloatBuffer fclrs, ByteBuffer bclrs,
+ int initialNormalIndex, FloatBuffer norms,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndices, FloatBuffer[] vertexAttrData,
+ int texCoordMapLength,
+ int[] texCoordSetMap,
+ int numActiveTexUnit,
+ int[] texindices, int texStride, FloatBuffer[] texCoords,
+ int cdirty,
+ int[] sarray,
+ int strip_len,
+ int[] start_array) {
+ JoglContext ctx = (JoglContext) absCtx;
+ GLContext context = context(ctx);
+ GL gl = context.getGL();
+
+ boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
+ boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
+ boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
+ boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
+ boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
+ boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
+ boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
+
+ // Enable normalize for non-uniform scale (which rescale can't handle)
+ if (isNonUniformScale) {
+ gl.glEnable(GL.GL_NORMALIZE);
+ }
+
+ int coordoff = 3 * initialCoordIndex;
+ // Define the data pointers
+ if (floatCoordDefined) {
+ fverts.position(coordoff);
+ gl.glVertexPointer(3, GL.GL_FLOAT, 0, fverts);
+ } else if (doubleCoordDefined){
+ dverts.position(coordoff);
+ gl.glVertexPointer(3, GL.GL_DOUBLE, 0, dverts);
+ }
+
+ if (floatColorsDefined) {
+ int coloroff;
+ int sz;
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
+ coloroff = 4 * initialColorIndex;
+ sz = 4;
+ } else {
+ coloroff = 3 * initialColorIndex;
+ sz = 3;
+ }
+ fclrs.position(coloroff);
+ gl.glColorPointer(sz, GL.GL_FLOAT, 0, fclrs);
+ } else if (byteColorsDefined) {
+ int coloroff;
+ int sz;
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
+ coloroff = 4 * initialColorIndex;
+ sz = 4;
+ } else {
+ coloroff = 3 * initialColorIndex;
+ sz = 3;
+ }
+ bclrs.position(coloroff);
+ gl.glColorPointer(sz, GL.GL_UNSIGNED_BYTE, 0, bclrs);
+ }
+ if (normalsDefined) {
+ int normoff = 3 * initialNormalIndex;
+ norms.position(normoff);
+ gl.glNormalPointer(GL.GL_FLOAT, 0, norms);
+ }
+
+ if (vattrDefined) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ FloatBuffer vertexAttrs = vertexAttrData[i];
+ int sz = vertexAttrSizes[i];
+ int initIdx = vertexAttrIndices[i];
+ ctx.enableVertexAttrArray(gl, i);
+ vertexAttrs.position(initIdx * sz);
+ ctx.vertexAttrPointer(gl, i, sz, GL.GL_FLOAT, 0, vertexAttrs);
+ }
+ }
+
+ if (textureDefined) {
+ int texSet = 0;
+ for (int i = 0; i < numActiveTexUnit; i++) {
+ if (( i < texCoordMapLength) &&
+ ((texSet = texCoordSetMap[i]) != -1)) {
+ FloatBuffer buf = texCoords[texSet];
+ buf.position(texStride * texindices[texSet]);
+ enableTexCoordPointer(gl, i, texStride,
+ GL.GL_FLOAT, 0, buf);
+ } else {
+ disableTexCoordPointer(gl, i);
+ }
+ }
+
+ // Reset client active texture unit to 0
+ clientActiveTextureUnit(gl, 0);
+ }
+
+ if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) {
+ int primType = 0;
+ switch (geo_type) {
+ case GeometryRetained.GEO_TYPE_TRI_STRIP_SET:
+ primType = GL.GL_TRIANGLE_STRIP;
+ break;
+ case GeometryRetained.GEO_TYPE_TRI_FAN_SET:
+ primType = GL.GL_TRIANGLE_FAN;
+ break;
+ case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
+ primType = GL.GL_LINE_STRIP;
+ break;
+ }
+ if (gl.isExtensionAvailable("GL_EXT_multi_draw_arrays")) {
+ gl.glMultiDrawArraysEXT(primType, start_array, 0, sarray, 0, strip_len);
+ } else if (gl.isExtensionAvailable("GL_VERSION_1_4")) {
+ gl.glMultiDrawArrays(primType, start_array, 0, sarray, 0, strip_len);
+ } else {
+ for (int i = 0; i < strip_len; i++) {
+ gl.glDrawArrays(primType, start_array[i], sarray[i]);
+ }
+ }
+ } else {
+ switch (geo_type){
+ case GeometryRetained.GEO_TYPE_QUAD_SET : gl.glDrawArrays(GL.GL_QUADS, 0, vcount); break;
+ case GeometryRetained.GEO_TYPE_TRI_SET : gl.glDrawArrays(GL.GL_TRIANGLES, 0, vcount); break;
+ case GeometryRetained.GEO_TYPE_POINT_SET : gl.glDrawArrays(GL.GL_POINTS, 0, vcount); break;
+ case GeometryRetained.GEO_TYPE_LINE_SET : gl.glDrawArrays(GL.GL_LINES, 0, vcount); break;
+ }
+ }
+
+ // clean up if we turned on normalize
+ if (isNonUniformScale) {
+ gl.glDisable(GL.GL_NORMALIZE);
+ }
+
+ if (vattrDefined) {
+ resetVertexAttrs(gl, ctx, vertexAttrCount);
+ }
+
+ if (textureDefined) {
+ resetTexture(gl, ctx);
+ }
+ }
+
+ private String getVertexDescription(int vformat) {
+ String res = "";
+ if ((vformat & GeometryArray.COORDINATES) != 0) res += "COORDINATES ";
+ if ((vformat & GeometryArray.NORMALS) != 0) res += "NORMALS ";
+ if ((vformat & GeometryArray.COLOR) != 0) res += "COLOR ";
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) res += "(WITH_ALPHA) ";
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) res += "TEXTURE_COORDINATE ";
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) res += "(2) ";
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) res += "(3) ";
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) res += "(4) ";
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) res += "VERTEX_ATTRIBUTES ";
+ return res;
+ }
+
+ private String getGeometryDescription(int geo_type) {
+ switch (geo_type) {
+ case GeometryRetained.GEO_TYPE_TRI_STRIP_SET : return "GEO_TYPE_TRI_STRIP_SET";
+ case GeometryRetained.GEO_TYPE_TRI_FAN_SET : return "GEO_TYPE_TRI_FAN_SET";
+ case GeometryRetained.GEO_TYPE_LINE_STRIP_SET: return "GEO_TYPE_LINE_STRIP_SET";
+ case GeometryRetained.GEO_TYPE_QUAD_SET : return "GEO_TYPE_QUAD_SET";
+ case GeometryRetained.GEO_TYPE_TRI_SET : return "GEO_TYPE_TRI_SET";
+ case GeometryRetained.GEO_TYPE_POINT_SET : return "GEO_TYPE_POINT_SET";
+ case GeometryRetained.GEO_TYPE_LINE_SET : return "GEO_TYPE_LINE_SET";
+ default: return "(unknown " + geo_type + ")";
+ }
+ }
+
+ private void resetVertexAttrs(GL gl, JoglContext ctx, int vertexAttrCount) {
+ // Disable specified vertex attr arrays
+ for (int i = 0; i < vertexAttrCount; i++) {
+ ctx.disableVertexAttrArray(gl, i);
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // IndexedGeometryArrayRetained methods
+ //
+
+ // by-copy or interleaved, by reference, Java arrays
+ void executeIndexedGeometry(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ float[] varray, float[] carray,
+ int cdirty,
+ int[] indexCoord) {
+ if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometry()");
+
+ executeIndexedGeometryArray(ctx, geo, geo_type,
+ isNonUniformScale, useAlpha, ignoreVertexColors,
+ initialIndexIndex, indexCount,
+ vertexCount, vformat,
+ vertexAttrCount, vertexAttrSizes,
+ texCoordSetCount, texCoordSetMap, texCoordSetMapLen,
+ texCoordSetOffset,
+ numActiveTexUnitState,
+ varray, null, carray,
+ cdirty, indexCoord);
+ }
+
+ // interleaved, by reference, nio buffer
+ void executeIndexedGeometryBuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ Object vdata, float[] carray,
+ int cDirty,
+ int[] indexCoord) {
+ if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometryBuffer()");
+
+ executeIndexedGeometryArray(ctx, geo, geo_type,
+ isNonUniformScale, useAlpha, ignoreVertexColors,
+ initialIndexIndex, indexCount, vertexCount, vformat,
+ 0, null,
+ texCoordSetCount, texCoordSetMap, texCoordSetMapLen, texCoordSetOffset,
+ numActiveTexUnitState,
+ null, (FloatBuffer) vdata, carray,
+ cDirty, indexCoord);
+ }
+
+ // non interleaved, by reference, Java arrays
+ void executeIndexedGeometryVA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ float[] vfcoords, double[] vdcoords,
+ float[] cfdata, byte[] cbdata,
+ float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[][] vertexAttrData,
+ int texCoordMapLength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int texStride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord) {
+ if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometryVA()");
+
+ boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
+ boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
+ boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
+ boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
+ boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
+ boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
+ boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
+
+ FloatBuffer fverts = null;
+ DoubleBuffer dverts = null;
+ FloatBuffer fclrs = null;
+ ByteBuffer bclrs = null;
+ FloatBuffer[] texCoordBufs = null;
+ FloatBuffer norms = null;
+ FloatBuffer[] vertexAttrBufs = null;
+
+ // Get vertex attribute arrays
+ if (vattrDefined) {
+ vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData);
+ }
+
+ // get texture arrays
+ if (textureDefined) {
+ texCoordBufs = getTexCoordSetBuffer(texCoords);
+ }
+
+ int[] sarray = null;
+ int strip_len = 0;
+ if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+ sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts;
+ strip_len = sarray.length;
+ }
+
+ // get coordinate array
+ if (floatCoordDefined) {
+ fverts = getVertexArrayBuffer(vfcoords);
+ } else if (doubleCoordDefined) {
+ dverts = getVertexArrayBuffer(vdcoords);
+ }
+
+ // get color array
+ if (floatColorsDefined) {
+ fclrs = getColorArrayBuffer(cfdata);
+ } else if (byteColorsDefined) {
+ bclrs = getColorArrayBuffer(cbdata);
+ }
+
+ // get normal array
+ if (normalsDefined) {
+ norms = getNormalArrayBuffer(ndata);
+ }
+
+ executeIndexedGeometryArrayVA(ctx, geo, geo_type,
+ isNonUniformScale, ignoreVertexColors,
+ initialIndexIndex, validIndexCount, vertexCount,
+ vformat, vdefined,
+ fverts, dverts,
+ fclrs, bclrs,
+ norms,
+ vertexAttrCount, vertexAttrSizes, vertexAttrBufs,
+ texCoordMapLength, texcoordoffset,
+ numActiveTexUnitState,
+ texStride, texCoordBufs,
+ cdirty, indexCoord,
+ sarray, strip_len);
+ }
+
+ // non interleaved, by reference, nio buffer
+ void executeIndexedGeometryVABuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ Object vcoords,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ Object ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ Object[] vertexAttrData,
+ int texCoordMapLength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int texStride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord) {
+ if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometryVABuffer()");
+
+ boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
+ boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
+ boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
+ boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
+ boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
+ boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
+ boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
+
+ FloatBuffer fverts = null;
+ DoubleBuffer dverts = null;
+ FloatBuffer fclrs = null;
+ ByteBuffer bclrs = null;
+ FloatBuffer[] texCoordBufs = null;
+ FloatBuffer norms = null;
+ FloatBuffer[] vertexAttrBufs = null;
+
+ // Get vertex attribute arrays
+ if (vattrDefined) {
+ vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData);
+ }
+
+ // get texture arrays
+ if (textureDefined) {
+ texCoordBufs = new FloatBuffer[texCoords.length];
+ for (int i = 0; i < texCoords.length; i++) {
+ texCoordBufs[i] = (FloatBuffer) texCoords[i];
+ }
+ }
+
+ // get coordinate array
+ if (floatCoordDefined) {
+ fverts = (FloatBuffer) vcoords;
+ } else if (doubleCoordDefined) {
+ dverts = (DoubleBuffer) vcoords;
+ }
+
+ if (fverts == null && dverts == null) {
+ return;
+ }
+
+ int[] sarray = null;
+ int strip_len = 0;
+ if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+ sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts;
+ strip_len = sarray.length;
+ }
+
+ // get color array
+ if (floatColorsDefined) {
+ if (cfdata != null)
+ fclrs = getColorArrayBuffer(cfdata);
+ else
+ fclrs = (FloatBuffer) cdataBuffer;
+ } else if (byteColorsDefined) {
+ if (cbdata != null)
+ bclrs = getColorArrayBuffer(cbdata);
+ else
+ bclrs = (ByteBuffer) cdataBuffer;
+ }
+
+ // get normal array
+ if (normalsDefined) {
+ norms = (FloatBuffer) ndata;
+ }
+
+ executeIndexedGeometryArrayVA(ctx, geo, geo_type,
+ isNonUniformScale, ignoreVertexColors,
+ initialIndexIndex, validIndexCount, vertexCount,
+ vformat, vdefined,
+ fverts, dverts,
+ fclrs, bclrs,
+ norms,
+ vertexAttrCount, vertexAttrSizes, vertexAttrBufs,
+ texCoordMapLength, texcoordoffset,
+ numActiveTexUnitState,
+ texStride, texCoordBufs,
+ cdirty, indexCoord,
+ sarray, strip_len);
+ }
+
+ // by-copy geometry
+ void buildIndexedGeometry(Context absCtx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetMapOffset,
+ double[] xform, double[] nxform,
+ float[] varray, int[] indexCoord) {
+ if (VERBOSE) System.err.println("JoglPipeline.buildIndexedGeometry()");
+
+ JoglContext ctx = (JoglContext) absCtx;
+ GL gl = context(ctx).getGL();
+
+ boolean useInterleavedArrays;
+ int iaFormat = 0;
+ int primType = 0;
+ int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0;
+ int texSize = 0, texStride = 0;
+ int vAttrOff = 0;
+ int vAttrStride = 0;
+ int bstride = 0, cbstride = 0;
+ FloatBuffer verts = null;
+ FloatBuffer clrs = null;
+ int[] sarray = null;
+ int strip_len = 0;
+ boolean useAlpha = false;
+
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
+ stride += 3;
+ } else {
+ gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
+ }
+
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
+ stride += 3;
+ coordoff += 3;
+ } else {
+ gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
+ }
+
+ if ((vformat & GeometryArray.COLOR) != 0) {
+ gl.glEnableClientState(GL.GL_COLOR_ARRAY);
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ } else {
+ gl.glDisableClientState(GL.GL_COLOR_ARRAY);
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
+ texSize = 2;
+ texStride = 2 * texCoordSetCount;
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
+ texSize = 3;
+ texStride = 3 * texCoordSetCount;
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) {
+ texSize = 4;
+ texStride = 4 * texCoordSetCount;
+ }
+ stride += texStride;
+ normoff += texStride;
+ coloroff += texStride;
+ coordoff += texStride;
+ }
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ vAttrStride += vertexAttrSizes[i];
+ }
+ stride += vAttrStride;
+ normoff += vAttrStride;
+ coloroff += vAttrStride;
+ coordoff += vAttrStride;
+ texCoordoff += vAttrStride;
+ }
+
+ bstride = stride * BufferUtil.SIZEOF_FLOAT;
+
+ // process alpha for geometryArray without alpha
+ if (updateAlpha && !ignoreVertexColors) {
+ useAlpha = true;
+ }
+
+ if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+ sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts;
+ strip_len = sarray.length;
+ }
+
+ // Copy data into NIO array
+ verts = getVertexArrayBuffer(varray);
+
+ // Apply normal transform if necessary
+ if ((vformat & GeometryArray.NORMALS) != 0 && nxform != null) {
+ int off = normoff;
+ for (int i = 0; i < vertexCount * 3; i+=3) {
+ verts.put(off , (float) (nxform[0] * varray[off] +
+ nxform[1] * varray[off+1] +
+ nxform[2] * varray[off+2]));
+ verts.put(off+1, (float) (nxform[4] * varray[off] +
+ nxform[5] * varray[off+1] +
+ nxform[6] * varray[off+2]));
+ verts.put(off+2, (float) (nxform[8] * varray[off] +
+ nxform[9] * varray[off+1] +
+ nxform[10] * varray[off+2]));
+ off += stride;
+ }
+ }
+
+ // Apply coordinate transform if necessary
+ if ((vformat & GeometryArray.COORDINATES) != 0 && xform != null) {
+ int off = coordoff;
+ for (int i = 0; i < vertexCount * 3; i+=3) {
+ verts.put(off , (float) (xform[0] * varray[off] +
+ xform[1] * varray[off+1] +
+ xform[2] * varray[off+2]));
+ verts.put(off+1, (float) (xform[4] * varray[off] +
+ xform[5] * varray[off+1] +
+ xform[6] * varray[off+2]));
+ verts.put(off+2, (float) (xform[8] * varray[off] +
+ xform[9] * varray[off+1] +
+ xform[10] * varray[off+2]));
+ off += stride;
+ }
+ }
+
+ if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+ // Note we can use interleaved arrays even if we have a
+ // non-null xform since we use the same data layout unlike the
+ // C code
+ if (ignoreVertexColors ||
+ (((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = false;
+ } else {
+ boolean[] tmp = new boolean[1];
+ int[] tmp2 = new int[1];
+ testForInterleavedArrays(vformat, tmp, tmp2);
+ useInterleavedArrays = tmp[0];
+ iaFormat = tmp2[0];
+ }
+
+ if (useInterleavedArrays) {
+ verts.position(0);
+ gl.glInterleavedArrays(iaFormat, bstride, verts);
+ } else {
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ verts.position(normoff);
+ gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
+ }
+ if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) {
+ verts.position(coloroff);
+ if (((vformat & GeometryArray.WITH_ALPHA) != 0) || useAlpha) {
+ gl.glColorPointer(4, GL.GL_FLOAT, bstride, verts);
+ } else {
+ gl.glColorPointer(3, GL.GL_FLOAT, bstride, verts);
+ }
+ }
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ verts.position(coordoff);
+ gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
+ }
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ executeTexture(texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetMapOffset,
+ texCoordSetMapLen,
+ verts, gl);
+ }
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ int vAttrOffset = vAttrOff;
+ for (int i = 0; i < vertexAttrCount; i++) {
+ ctx.enableVertexAttrArray(gl, i);
+ verts.position(vAttrOffset);
+ ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i],
+ GL.GL_FLOAT, bstride, verts);
+ vAttrOffset += vertexAttrSizes[i];
+ }
+ }
+ }
+
+ switch (geo_type) {
+ case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET:
+ primType = GL.GL_TRIANGLE_STRIP;
+ break;
+ case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET:
+ primType = GL.GL_TRIANGLE_FAN;
+ break;
+ case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
+ primType = GL.GL_LINE_STRIP;
+ break;
+ }
+
+ lockArray(gl, vertexCount);
+
+ // Note: using MultiDrawElements is probably more expensive than
+ // not in this case due to the need to allocate more temporary
+ // direct buffers and slice up the incoming indices array
+ int offset = initialIndexIndex;
+ IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord);
+ for (int i = 0; i < strip_len; i++) {
+ indicesBuffer.position(offset);
+ int count = sarray[i];
+ gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT, indicesBuffer);
+ offset += count;
+ }
+ } else if ((geo_type == GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_INDEXED_POINT_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_SET)) {
+ // Note we can use interleaved arrays even if we have a
+ // non-null xform since we use the same data layout unlike the
+ // C code
+ if (ignoreVertexColors ||
+ (((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = false;
+ } else {
+ boolean[] tmp = new boolean[1];
+ int[] tmp2 = new int[1];
+ testForInterleavedArrays(vformat, tmp, tmp2);
+ useInterleavedArrays = tmp[0];
+ iaFormat = tmp2[0];
+ }
+
+ if (useInterleavedArrays) {
+ verts.position(0);
+ gl.glInterleavedArrays(iaFormat, bstride, verts);
+ } else {
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ verts.position(normoff);
+ gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
+ }
+
+ if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) {
+ verts.position(coloroff);
+ if (((vformat & GeometryArray.WITH_ALPHA) != 0) || useAlpha) {
+ gl.glColorPointer(4, GL.GL_FLOAT, bstride, verts);
+ } else {
+ gl.glColorPointer(3, GL.GL_FLOAT, bstride, verts);
+ }
+ }
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ verts.position(coordoff);
+ gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
+ }
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ executeTexture(texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetMapOffset,
+ texCoordSetMapLen,
+ verts, gl);
+ }
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ int vAttrOffset = vAttrOff;
+ for (int i = 0; i < vertexAttrCount; i++) {
+ ctx.enableVertexAttrArray(gl, i);
+ verts.position(vAttrOffset);
+ ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i],
+ GL.GL_FLOAT, bstride, verts);
+ vAttrOffset += vertexAttrSizes[i];
+ }
+ }
+
+ switch (geo_type) {
+ case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET :
+ primType = GL.GL_QUADS;
+ break;
+ case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET :
+ primType = GL.GL_TRIANGLES;
+ break;
+ case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET :
+ primType = GL.GL_POINTS;
+ break;
+ case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET :
+ primType = GL.GL_LINES;
+ break;
+ }
+
+ lockArray(gl, vertexCount);
+
+ IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord);
+ indicesBuffer.position(initialIndexIndex);
+ gl.glDrawElements(primType, validIndexCount, GL.GL_UNSIGNED_INT, indicesBuffer);
+ }
+ }
+
+ unlockArray(gl);
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ resetVertexAttrs(gl, ctx, vertexAttrCount);
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ resetTexture(gl, ctx);
+ }
+ }
+
+
+ //----------------------------------------------------------------------
+ //
+ // Helper routines for IndexedGeometryArrayRetained
+ //
+
+ private void executeIndexedGeometryArray(Context absCtx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ float[] varray, FloatBuffer vdata, float[] carray,
+ int cDirty,
+ int[] indexCoord) {
+ JoglContext ctx = (JoglContext) absCtx;
+ GL gl = context(ctx).getGL();
+
+ boolean useInterleavedArrays;
+ int iaFormat = 0;
+ int primType = 0;
+ int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0;
+ int texSize = 0, texStride = 0;
+ int vAttrOff = 0;
+ int vAttrStride = 0;
+ int bstride = 0, cbstride = 0;
+ FloatBuffer verts = null;
+ FloatBuffer clrs = null;
+ int[] sarray = null;
+ int strip_len = 0;
+
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ stride += 3;
+ }
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ stride += 3;
+ coordoff += 3;
+ }
+
+ if ((vformat & GeometryArray.COLOR) != 0) {
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ } else { // Handle the case of executeInterleaved 3f
+ stride += 3;
+ normoff += 3;
+ coordoff += 3;
+ }
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
+ texSize = 2;
+ texStride = 2 * texCoordSetCount;
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
+ texSize = 3;
+ texStride = 3 * texCoordSetCount;
+ } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) {
+ texSize = 4;
+ texStride = 4 * texCoordSetCount;
+ }
+ stride += texStride;
+ normoff += texStride;
+ coloroff += texStride;
+ coordoff += texStride;
+ }
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ vAttrStride += vertexAttrSizes[i];
+ }
+ stride += vAttrStride;
+ normoff += vAttrStride;
+ coloroff += vAttrStride;
+ coordoff += vAttrStride;
+ texCoordoff += vAttrStride;
+ }
+
+ bstride = stride * BufferUtil.SIZEOF_FLOAT;
+
+ if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+ sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts;
+ strip_len = sarray.length;
+ }
+
+ // We have to copy if the data isn't specified using NIO
+ if (varray != null) {
+ verts = getVertexArrayBuffer(varray);
+ } else if (vdata != null) {
+ verts = vdata;
+ } else {
+ // This should never happen
+ throw new AssertionError("Unable to get vertex pointer");
+ }
+
+ // using byRef interleaved array and has a separate pointer, then ..
+ int cstride = stride;
+ if (carray != null) {
+ clrs = getColorArrayBuffer(carray);
+ cstride = 4;
+ } else {
+ // FIXME: need to "auto-slice" this buffer later
+ clrs = verts;
+ }
+
+ cbstride = cstride * BufferUtil.SIZEOF_FLOAT;
+
+ // Enable normalize for non-uniform scale (which rescale can't handle)
+ if (isNonUniformScale) {
+ gl.glEnable(GL.GL_NORMALIZE);
+ }
+
+ /*** Handle non-indexed strip GeometryArray first *******/
+ if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+ if (ignoreVertexColors || (carray != null) ||
+ ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = false;
+ } else {
+ boolean[] tmp = new boolean[1];
+ int[] tmp2 = new int[1];
+ testForInterleavedArrays(vformat, tmp, tmp2);
+ useInterleavedArrays = tmp[0];
+ iaFormat = tmp2[0];
+ }
+ if (useInterleavedArrays) {
+ verts.position(0);
+ gl.glInterleavedArrays(iaFormat, bstride, verts);
+ } else {
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ verts.position(normoff);
+ gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
+ }
+ if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) {
+ if (clrs == verts) {
+ clrs.position(coloroff);
+ }
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) {
+ gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs);
+ } else {
+ gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs);
+ }
+ }
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ verts.position(coordoff);
+ gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ /* XXXX: texCoordoff == 0 ???*/
+ executeTexture(texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetOffset,
+ numActiveTexUnitState,
+ verts, gl);
+ }
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ int vAttrOffset = vAttrOff;
+ for (int i = 0; i < vertexAttrCount; i++) {
+ ctx.enableVertexAttrArray(gl, i);
+ verts.position(vAttrOffset);
+ ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i],
+ GL.GL_FLOAT, bstride, verts);
+ vAttrOffset += vertexAttrSizes[i];
+ }
+ }
+ }
+
+ switch (geo_type) {
+ case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET:
+ primType = GL.GL_TRIANGLE_STRIP;
+ break;
+ case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET:
+ primType = GL.GL_TRIANGLE_FAN;
+ break;
+ case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
+ primType = GL.GL_LINE_STRIP;
+ break;
+ }
+
+ lockArray(gl, vertexCount);
+
+ // Note: using MultiDrawElements is probably more expensive than
+ // not in this case due to the need to allocate more temporary
+ // direct buffers and slice up the incoming indices array
+ int offset = initialIndexIndex;
+ IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord);
+ for (int i = 0; i < strip_len; i++) {
+ indicesBuffer.position(offset);
+ int count = sarray[i];
+ gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT, indicesBuffer);
+ offset += count;
+ }
+ } else if ((geo_type == GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_INDEXED_POINT_SET) ||
+ (geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_SET)) {
+ /******* Handle non-indexed non-striped GeometryArray now *****/
+ if (ignoreVertexColors || (carray != null) ||
+ ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = false;
+ } else {
+ boolean[] tmp = new boolean[1];
+ int[] tmp2 = new int[1];
+ testForInterleavedArrays(vformat, tmp, tmp2);
+ useInterleavedArrays = tmp[0];
+ iaFormat = tmp2[0];
+ }
+
+ if (useInterleavedArrays) {
+ verts.position(0);
+ gl.glInterleavedArrays(iaFormat, bstride, verts);
+ } else {
+ if ((vformat & GeometryArray.NORMALS) != 0) {
+ verts.position(normoff);
+ gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
+ }
+
+ if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) {
+ if (clrs == verts) {
+ clrs.position(coloroff);
+ }
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) {
+ gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs);
+ } else {
+ gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs);
+ }
+ }
+ if ((vformat & GeometryArray.COORDINATES) != 0) {
+ verts.position(coordoff);
+ gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ /* XXXX: texCoordoff == 0 ???*/
+ executeTexture(texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetOffset,
+ numActiveTexUnitState,
+ verts, gl);
+ }
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ int vAttrOffset = vAttrOff;
+ for (int i = 0; i < vertexAttrCount; i++) {
+ ctx.enableVertexAttrArray(gl, i);
+ verts.position(vAttrOffset);
+ ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i],
+ GL.GL_FLOAT, bstride, verts);
+ vAttrOffset += vertexAttrSizes[i];
+ }
+ }
+ }
+
+ lockArray(gl, vertexCount);
+ IntBuffer buf = IntBuffer.wrap(indexCoord);
+ buf.position(initialIndexIndex);
+ switch (geo_type){
+ case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET : gl.glDrawElements(GL.GL_QUADS, indexCount, GL.GL_UNSIGNED_INT, buf); break;
+ case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET : gl.glDrawElements(GL.GL_TRIANGLES, indexCount, GL.GL_UNSIGNED_INT, buf); break;
+ case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET: gl.glDrawElements(GL.GL_POINTS, indexCount, GL.GL_UNSIGNED_INT, buf); break;
+ case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET : gl.glDrawElements(GL.GL_LINES, indexCount, GL.GL_UNSIGNED_INT, buf); break;
+ }
+ }
+
+ unlockArray(gl);
+
+ if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ resetVertexAttrs(gl, ctx, vertexAttrCount);
+ }
+
+ if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ resetTexture(gl, ctx);
+ }
+
+ // clean up if we turned on normalize
+ if (isNonUniformScale) {
+ gl.glDisable(GL.GL_NORMALIZE);
+ }
+ }
+
+
+ private void executeIndexedGeometryArrayVA(Context absCtx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount, int vformat, int vdefined,
+ FloatBuffer fverts, DoubleBuffer dverts,
+ FloatBuffer fclrs, ByteBuffer bclrs,
+ FloatBuffer norms,
+ int vertexAttrCount, int[] vertexAttrSizes, FloatBuffer[] vertexAttrBufs,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int numActiveTexUnitState,
+ int texStride,
+ FloatBuffer[] texCoords,
+ int cDirty, int[] indexCoord, int[] sarray, int strip_len) {
+ JoglContext ctx = (JoglContext) absCtx;
+ GL gl = context(ctx).getGL();
+
+ boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0);
+ boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0);
+ boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0);
+ boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0);
+ boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0);
+ boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0);
+ boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0);
+
+ // Enable normalize for non-uniform scale (which rescale can't handle)
+ if (isNonUniformScale) {
+ gl.glEnable(GL.GL_NORMALIZE);
+ }
+
+ // Define the data pointers
+ if (floatCoordDefined) {
+ fverts.position(0);
+ gl.glVertexPointer(3, GL.GL_FLOAT, 0, fverts);
+ } else if (doubleCoordDefined){
+ dverts.position(0);
+ gl.glVertexPointer(3, GL.GL_DOUBLE, 0, dverts);
+ }
+ if (floatColorsDefined) {
+ fclrs.position(0);
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
+ gl.glColorPointer(4, GL.GL_FLOAT, 0, fclrs);
+ } else {
+ gl.glColorPointer(3, GL.GL_FLOAT, 0, fclrs);
+ }
+ } else if (byteColorsDefined) {
+ bclrs.position(0);
+ if ((vformat & GeometryArray.WITH_ALPHA) != 0) {
+ gl.glColorPointer(4, GL.GL_UNSIGNED_BYTE, 0, bclrs);
+ } else {
+ gl.glColorPointer(3, GL.GL_UNSIGNED_BYTE, 0, bclrs);
+ }
+ }
+ if (normalsDefined) {
+ norms.position(0);
+ gl.glNormalPointer(GL.GL_FLOAT, 0, norms);
+ }
+
+ if (vattrDefined) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ FloatBuffer vertexAttrs = vertexAttrBufs[i];
+ int sz = vertexAttrSizes[i];
+ ctx.enableVertexAttrArray(gl, i);
+ vertexAttrs.position(0);
+ ctx.vertexAttrPointer(gl, i, sz, GL.GL_FLOAT, 0, vertexAttrs);
+ }
+ }
+
+ if (textureDefined) {
+ int texSet = 0;
+ for (int i = 0; i < numActiveTexUnitState; i++) {
+ if ((i < texCoordSetCount) &&
+ ((texSet = texCoordSetMap[i]) != -1)) {
+ FloatBuffer buf = texCoords[texSet];
+ buf.position(0);
+ enableTexCoordPointer(gl, i, texStride,
+ GL.GL_FLOAT, 0, buf);
+ } else {
+ disableTexCoordPointer(gl, i);
+ }
+ }
+
+ // Reset client active texture unit to 0
+ clientActiveTextureUnit(gl, 0);
+ }
+
+ lockArray(gl, vertexCount);
+
+ if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+ int primType = 0;
+ switch (geo_type) {
+ case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET:
+ primType = GL.GL_TRIANGLE_STRIP;
+ break;
+ case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET:
+ primType = GL.GL_TRIANGLE_FAN;
+ break;
+ case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
+ primType = GL.GL_LINE_STRIP;
+ break;
+ }
+
+ // Note: using MultiDrawElements is probably more expensive than
+ // not in this case due to the need to allocate more temporary
+ // direct buffers and slice up the incoming indices array
+ int offset = initialIndexIndex;
+ IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord);
+ for (int i = 0; i < strip_len; i++) {
+ indicesBuffer.position(offset);
+ int count = sarray[i];
+ gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT, indicesBuffer);
+ offset += count;
+ }
+ } else {
+ IntBuffer buf = IntBuffer.wrap(indexCoord);
+ buf.position(initialIndexIndex);
+ switch (geo_type){
+ case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET : gl.glDrawElements(GL.GL_QUADS, validIndexCount, GL.GL_UNSIGNED_INT, buf); break;
+ case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET : gl.glDrawElements(GL.GL_TRIANGLES, validIndexCount, GL.GL_UNSIGNED_INT, buf); break;
+ case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET: gl.glDrawElements(GL.GL_POINTS, validIndexCount, GL.GL_UNSIGNED_INT, buf); break;
+ case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET : gl.glDrawElements(GL.GL_LINES, validIndexCount, GL.GL_UNSIGNED_INT, buf); break;
+ }
+ }
+
+ unlockArray(gl);
+
+ // clean up if we turned on normalize
+ if (isNonUniformScale) {
+ gl.glDisable(GL.GL_NORMALIZE);
+ }
+
+ if (vattrDefined) {
+ resetVertexAttrs(gl, ctx, vertexAttrCount);
+ }
+
+ if (textureDefined) {
+ resetTexture(gl, ctx);
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GraphicsContext3D methods
+ //
+
+ // Native method for readRaster
+ void readRaster(Context ctx,
+ int type, int xSrcOffset, int ySrcOffset,
+ int width, int height, int hCanvas,
+ int imageDataType,
+ int imageFormat,
+ Object imageBuffer,
+ int depthFormat,
+ Object depthBuffer) {
+
+ GL gl = context(ctx).getGL();
+ gl.glPixelStorei(GL.GL_PACK_ROW_LENGTH, width);
+ gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
+ int yAdjusted = hCanvas - height - ySrcOffset;
+
+ if ((type & Raster.RASTER_COLOR) != 0) {
+ int oglFormat = 0;
+ if(imageDataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) {
+
+ switch (imageFormat) {
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ oglFormat = GL.GL_BGR;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ oglFormat = GL.GL_RGB;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here!
+ oglFormat = GL.GL_ABGR_EXT;
+ } else {
+ assert false;
+ return;
+ }
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ // all RGB types are stored as RGBA
+ oglFormat = GL.GL_RGBA;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ // all LA types are stored as LA8
+ oglFormat = GL.GL_LUMINANCE_ALPHA;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_INT_BGR:
+ case ImageComponentRetained.TYPE_INT_RGB:
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ default:
+ assert false;
+ return;
+ }
+
+ gl.glReadPixels(xSrcOffset, yAdjusted, width, height,
+ oglFormat, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[]) imageBuffer));
+
+
+ } else if(imageDataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) {
+ int intType = GL.GL_UNSIGNED_INT_8_8_8_8;
+ boolean forceAlphaToOne = false;
+
+ switch (imageFormat) {
+ /* GL_BGR */
+ case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
+ oglFormat = GL.GL_RGBA;
+ intType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ forceAlphaToOne = true;
+ break;
+ case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
+ forceAlphaToOne = true;
+ /* Fall through to next case */
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ oglFormat = GL.GL_BGRA;
+ intType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ /* This method only supports 3 and 4 components formats and INT types. */
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ default:
+ assert false;
+ return;
+ }
+
+ /* Force Alpha to 1.0 if needed */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
+ }
+
+ gl.glReadPixels(xSrcOffset, yAdjusted, width, height,
+ oglFormat, intType, IntBuffer.wrap((int[]) imageBuffer));
+
+ /* Restore Alpha scale and bias */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
+ }
+
+ } else {
+ assert false;
+ }
+ }
+
+ if ((type & Raster.RASTER_DEPTH) != 0) {
+
+ if (depthFormat == DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT) {
+ // yOffset is adjusted for OpenGL - Y upward
+ gl.glReadPixels(xSrcOffset, yAdjusted, width, height,
+ GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT, IntBuffer.wrap((int[]) depthBuffer));
+ } else {
+ // DEPTH_COMPONENT_TYPE_FLOAT
+ // yOffset is adjusted for OpenGL - Y upward
+ gl.glReadPixels(xSrcOffset, yAdjusted, width, height,
+ GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, FloatBuffer.wrap((float[]) depthBuffer));
+ }
+ }
+
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // CgShaderProgramRetained methods
+ //
+
+ // ShaderAttributeValue methods
+
+ ShaderError setCgUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform1i()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgSetParameter1i(param.vParam(), value);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgSetParameter1i(param.fParam(), value);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform1f()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgSetParameter1f(param.vParam(), value);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgSetParameter1f(param.fParam(), value);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform2i()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgSetParameter2i(param.vParam(), value[0], value[1]);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgSetParameter2i(param.fParam(), value[0], value[1]);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform2f()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgSetParameter2f(param.vParam(), value[0], value[1]);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgSetParameter2f(param.fParam(), value[0], value[1]);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform3i()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgSetParameter3i(param.vParam(), value[0], value[1], value[2]);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgSetParameter3i(param.fParam(), value[0], value[1], value[2]);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform3f()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgSetParameter3f(param.vParam(), value[0], value[1], value[2]);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgSetParameter3f(param.fParam(), value[0], value[1], value[2]);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform4i()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgSetParameter4i(param.vParam(), value[0], value[1], value[2], value[3]);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgSetParameter4i(param.fParam(), value[0], value[1], value[2], value[3]);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform4f()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgSetParameter4f(param.vParam(), value[0], value[1], value[2], value[3]);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgSetParameter4f(param.fParam(), value[0], value[1], value[2], value[3]);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniformMatrix3f()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetMatrixParameterfr(param.vParam(), value, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetMatrixParameterfr(param.fParam(), value, 0);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniformMatrix4f()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetMatrixParameterfr(param.vParam(), value, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetMatrixParameterfr(param.fParam(), value, 0);
+ }
+
+ return null;
+ }
+
+ // ShaderAttributeArray methods
+
+ ShaderError setCgUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform1iArray()");
+
+ float[] fval = new float[value.length];
+ for (int i = 0; i < value.length; i++) {
+ fval[i] = value[i];
+ }
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetParameterArray1f(param.vParam(), 0, numElements, fval, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetParameterArray1f(param.fParam(), 0, numElements, fval, 0);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform1fArray()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetParameterArray1f(param.vParam(), 0, numElements, value, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetParameterArray1f(param.fParam(), 0, numElements, value, 0);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform2iArray()");
+
+ float[] fval = new float[value.length];
+ for (int i = 0; i < value.length; i++) {
+ fval[i] = value[i];
+ }
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetParameterArray2f(param.vParam(), 0, numElements, fval, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetParameterArray2f(param.fParam(), 0, numElements, fval, 0);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform2fArray()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetParameterArray2f(param.vParam(), 0, numElements, value, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetParameterArray2f(param.fParam(), 0, numElements, value, 0);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform3iArray()");
+
+ float[] fval = new float[value.length];
+ for (int i = 0; i < value.length; i++) {
+ fval[i] = value[i];
+ }
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetParameterArray3f(param.vParam(), 0, numElements, fval, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetParameterArray3f(param.fParam(), 0, numElements, fval, 0);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform3fArray()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetParameterArray2f(param.vParam(), 0, numElements, value, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetParameterArray2f(param.fParam(), 0, numElements, value, 0);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform4iArray()");
+
+ float[] fval = new float[value.length];
+ for (int i = 0; i < value.length; i++) {
+ fval[i] = value[i];
+ }
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetParameterArray4f(param.vParam(), 0, numElements, fval, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetParameterArray4f(param.fParam(), 0, numElements, fval, 0);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniform4fArray()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetParameterArray2f(param.vParam(), 0, numElements, value, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetParameterArray2f(param.fParam(), 0, numElements, value, 0);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniformMatrix3fArray()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetMatrixParameterArrayfr(param.vParam(), 0, numElements, value, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetMatrixParameterArrayfr(param.fParam(), 0, numElements, value, 0);
+ }
+
+ return null;
+ }
+
+ ShaderError setCgUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setCgUniformMatrix4fArray()");
+
+ JoglCgShaderParameter param = (JoglCgShaderParameter) uniformLocation;
+ if (param.vParam() != null) {
+ CgGL.cgGLSetMatrixParameterArrayfr(param.vParam(), 0, numElements, value, 0);
+ }
+
+ if (param.fParam() != null) {
+ CgGL.cgGLSetMatrixParameterArrayfr(param.fParam(), 0, numElements, value, 0);
+ }
+
+ return null;
+ }
+
+ // interfaces for shader compilation, etc.
+ ShaderError createCgShader(Context ctx, int shaderType, ShaderId[] shaderId) {
+ if (VERBOSE) System.err.println("JoglPipeline.createCgShader()");
+
+ JoglContext jctx = (JoglContext) ctx;
+ JoglCgShaderInfo info = new JoglCgShaderInfo();
+ info.setJ3DShaderType(shaderType);
+ if (shaderType == Shader.SHADER_TYPE_VERTEX) {
+ info.setShaderProfile(jctx.getCgVertexProfile());
+ } else if (shaderType == Shader.SHADER_TYPE_FRAGMENT) {
+ info.setShaderProfile(jctx.getCgFragmentProfile());
+ } else {
+ throw new AssertionError("unrecognized shaderType " + shaderType);
+ }
+ shaderId[0] = info;
+ return null;
+ }
+ ShaderError destroyCgShader(Context ctx, ShaderId shaderId) {
+ if (VERBOSE) System.err.println("JoglPipeline.destroyCgShader()");
+
+ JoglCgShaderInfo info = (JoglCgShaderInfo) shaderId;
+ CGprogram program = info.getCgShader();
+ if (program != null) {
+ CgGL.cgDestroyProgram(program);
+ }
+ return null;
+ }
+ ShaderError compileCgShader(Context ctx, ShaderId shaderId, String programString) {
+ if (VERBOSE) System.err.println("JoglPipeline.compileCgShader()");
+
+ if (programString == null)
+ throw new AssertionError("shader program string is null");
+ JoglCgShaderInfo info = (JoglCgShaderInfo) shaderId;
+ JoglContext jctx = (JoglContext) ctx;
+ CGprogram program = CgGL.cgCreateProgram(jctx.getCgContext(),
+ CgGL.CG_SOURCE,
+ programString,
+ info.getShaderProfile(),
+ null,
+ null);
+ int lastError = 0;
+ if ((lastError = CgGL.cgGetError()) != 0) {
+ ShaderError err = new ShaderError(ShaderError.COMPILE_ERROR,
+ "Cg shader compile error");
+ err.setDetailMessage(getCgErrorLog(jctx, lastError));
+ return err;
+ }
+ info.setCgShader(program);
+ return null;
+ }
+
+ ShaderError createCgShaderProgram(Context ctx, ShaderProgramId[] shaderProgramId) {
+ if (VERBOSE) System.err.println("JoglPipeline.createCgShaderProgram()");
+
+ JoglCgShaderProgramInfo info = new JoglCgShaderProgramInfo();
+ shaderProgramId[0] = info;
+ return null;
+ }
+ ShaderError destroyCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ if (VERBOSE) System.err.println("JoglPipeline.destroyCgShaderProgram()");
+ // Nothing to do in pure Java port
+ return null;
+ }
+ ShaderError linkCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId,
+ ShaderId[] shaderIds) {
+ if (VERBOSE) System.err.println("JoglPipeline.linkCgShaderProgram()");
+
+ JoglCgShaderProgramInfo shaderProgramInfo = (JoglCgShaderProgramInfo) shaderProgramId;
+ // NOTE: we assume that the caller has already verified that there
+ // is at most one vertex program and one fragment program
+ shaderProgramInfo.setVertexShader(null);
+ shaderProgramInfo.setFragmentShader(null);
+ for (int i = 0; i < shaderIds.length; i++) {
+ JoglCgShaderInfo shader = (JoglCgShaderInfo) shaderIds[i];
+ if (shader.getJ3DShaderType() == Shader.SHADER_TYPE_VERTEX) {
+ shaderProgramInfo.setVertexShader(shader);
+ } else {
+ shaderProgramInfo.setFragmentShader(shader);
+ }
+
+ CgGL.cgGLLoadProgram(shader.getCgShader());
+ int lastError = 0;
+ if ((lastError = CgGL.cgGetError()) != 0) {
+ ShaderError err = new ShaderError(ShaderError.LINK_ERROR,
+ "Cg shader link/load error");
+ err.setDetailMessage(getCgErrorLog((JoglContext) ctx,
+ lastError));
+ return err;
+ }
+
+ CgGL.cgGLBindProgram(shader.getCgShader());
+ if ((lastError = CgGL.cgGetError()) != 0) {
+ ShaderError err = new ShaderError(ShaderError.LINK_ERROR,
+ "Cg shader link/bind error");
+ err.setDetailMessage(getCgErrorLog((JoglContext) ctx,
+ lastError));
+ return err;
+ }
+ }
+
+ return null;
+ }
+ void lookupCgVertexAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, boolean[] errArr) {
+ if (VERBOSE) System.err.println("JoglPipeline.lookupCgVertexAttrNames()");
+
+ JoglCgShaderProgramInfo shaderProgramInfo = (JoglCgShaderProgramInfo) shaderProgramId;
+ if (shaderProgramInfo.getVertexShader() == null) {
+ // If there if no vertex shader, no attributes can be looked up, so all fail
+ for (int i = 0; i < errArr.length; i++) {
+ errArr[i] = false;
+ }
+ return;
+ }
+
+ shaderProgramInfo.setVertexAttributes(new CGparameter[numAttrNames]);
+ for (int i = 0; i < numAttrNames; i++) {
+ String attrName = attrNames[i];
+ shaderProgramInfo.getVertexAttributes()[i] =
+ CgGL.cgGetNamedParameter(shaderProgramInfo.getVertexShader().getCgShader(),
+ attrName);
+ if (shaderProgramInfo.getVertexAttributes()[i] == null) {
+ errArr[i] = true;
+ }
+ }
+ }
+ void lookupCgShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, ShaderAttrLoc[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr) {
+ if (VERBOSE) System.err.println("JoglPipeline.lookupCgShaderAttrNames()");
+
+ JoglCgShaderProgramInfo shaderProgramInfo =
+ (JoglCgShaderProgramInfo) shaderProgramId;
+
+ // Set the loc, type, and size arrays to out-of-bounds values
+ for (int i = 0; i < numAttrNames; i++) {
+ locArr[i] = null;
+ typeArr[i] = -1;
+ sizeArr[i] = -1;
+ }
+
+ int[] vType = new int[1];
+ int[] vSize = new int[1];
+ boolean[] vIsArray = new boolean[1];
+ int[] fType = new int[1];
+ int[] fSize = new int[1];
+ boolean[] fIsArray = new boolean[1];
+
+ boolean err = false;
+
+ // Now lookup the location of each name in the attrNames array
+ for (int i = 0; i < numAttrNames; i++) {
+ String attrName = attrNames[i];
+ // Get uniform attribute location -- note that we need to
+ // lookup the name in both the vertex and fragment shader
+ // (although we will generalize it to look at the list of "N"
+ // shaders). If all parameter locations are NULL, then no
+ // struct will be allocated and -1 will be stored for this
+ // attribute. If there is more than one non-NULL parameter,
+ // then all must be of the same type and dimensionality,
+ // otherwise an error will be generated and -1 will be stored
+ // for this attribute. If all non-NULL parameters are of the
+ // same type and dimensionality, then a struct is allocated
+ // containing the list of parameters.
+ //
+ // When any of the setCgUniform methods are called, the
+ // attribute will be set for each parameter in the list.
+ CGparameter vLoc = null;
+ if (shaderProgramInfo.getVertexShader() != null) {
+ vLoc = lookupCgParams(shaderProgramInfo.getVertexShader(),
+ attrName,
+ vType, vSize, vIsArray);
+ if (vLoc != null) {
+ sizeArr[i] = vSize[0];
+ isArrayArr[i] = vIsArray[0];
+ typeArr[i] = cgToJ3dType(vType[0]);
+ }
+ }
+
+ CGparameter fLoc = null;
+ if (shaderProgramInfo.getVertexShader() != null) {
+ fLoc = lookupCgParams(shaderProgramInfo.getFragmentShader(),
+ attrName,
+ fType, fSize, fIsArray);
+ if (fLoc != null) {
+ sizeArr[i] = fSize[0];
+ isArrayArr[i] = fIsArray[0];
+ typeArr[i] = cgToJ3dType(fType[0]);
+ }
+ }
+
+ // If the name lookup found an entry in both vertex and
+ // fragment program, verify that the type and size are the
+ // same.
+ if (vLoc != null && fLoc != null) {
+ if (vType != fType || vSize != fSize || vIsArray != fIsArray) {
+ // TODO: the following needs to be propagated to ShaderError
+ System.err.println("JAVA 3D : error shader attribute type mismatch: " + attrName);
+ System.err.println(" 1 : type = " + vType[0] + ", size = " + vSize[0] + ", isArray = " + vIsArray[0]);
+ System.err.println(" 0 : type = " + fType[0] + ", size = " + fSize[0] + ", isArray = " + fIsArray[0]);
+ err = true;
+ }
+ }
+
+ // Report an error if we got a mismatch or if the attribute
+ // was not found in either the vertex or the fragment program
+ if (err || (vLoc == null && fLoc == null)) {
+ // TODO: distinguish between (err) and (vParam and fParam both NULL)
+ // so we can report a more helpful error message
+ // locPtr[i] = (jlong)-1;
+ } else {
+ // TODO: need to store the cgParamInfo pointers in the
+ // shader program so we can free them later.
+ //
+ // NOTE: WE CURRENTLY HAVE A MEMORY LEAK.
+ locArr[i] = new JoglCgShaderParameter(vLoc, fLoc);
+ }
+ }
+ }
+
+ ShaderError useCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ if (VERBOSE) System.err.println("JoglPipeline.useCgShaderProgram()");
+
+ JoglCgShaderProgramInfo shaderProgramInfo =
+ (JoglCgShaderProgramInfo) shaderProgramId;
+ JoglContext jctx = (JoglContext) ctx;
+
+ // Disable shader profiles
+ CgGL.cgGLDisableProfile(jctx.getCgVertexProfile());
+ CgGL.cgGLDisableProfile(jctx.getCgFragmentProfile());
+ if (shaderProgramInfo != null) {
+ if (shaderProgramInfo.getVertexShader() != null) {
+ CgGL.cgGLBindProgram(shaderProgramInfo.getVertexShader().getCgShader());
+ CgGL.cgGLEnableProfile(shaderProgramInfo.getVertexShader().getShaderProfile());
+ } else {
+ CgGL.cgGLUnbindProgram(jctx.getCgVertexProfile());
+ }
+
+ if (shaderProgramInfo.getFragmentShader() != null) {
+ CgGL.cgGLBindProgram(shaderProgramInfo.getFragmentShader().getCgShader());
+ CgGL.cgGLEnableProfile(shaderProgramInfo.getFragmentShader().getShaderProfile());
+ } else {
+ CgGL.cgGLUnbindProgram(jctx.getCgFragmentProfile());
+ }
+ } else {
+ CgGL.cgGLUnbindProgram(jctx.getCgVertexProfile());
+ CgGL.cgGLUnbindProgram(jctx.getCgFragmentProfile());
+ }
+
+ jctx.setShaderProgram(shaderProgramInfo);
+ return null;
+ }
+
+ //
+ // Helper methods for above
+ //
+ private String getCgErrorLog(JoglContext ctx, int lastError) {
+ if (lastError == 0)
+ throw new AssertionError("lastError == 0");
+ String errString = CgGL.cgGetErrorString(lastError);
+ String listing = CgGL.cgGetLastListing(ctx.getCgContext());
+ return (errString + System.getProperty("line.separator") + listing);
+ }
+
+ private int cgToJ3dType(int type) {
+ switch (type) {
+ case CgGL.CG_BOOL:
+ case CgGL.CG_BOOL1:
+ case CgGL.CG_FIXED:
+ case CgGL.CG_FIXED1:
+ case CgGL.CG_HALF:
+ case CgGL.CG_HALF1:
+ case CgGL.CG_INT:
+ case CgGL.CG_INT1:
+ return ShaderAttributeObjectRetained.TYPE_INTEGER;
+
+ // XXXX: add ShaderAttribute support for setting samplers. In the
+ // mean time, the binding between sampler and texture unit will
+ // need to be specified in the shader itself (which it already is
+ // in most example shaders).
+ //
+ // case CgGL.CG_SAMPLER2D:
+ // case CgGL.CG_SAMPLER3D:
+ // case CgGL.CG_SAMPLERCUBE:
+
+ case CgGL.CG_BOOL2:
+ case CgGL.CG_FIXED2:
+ case CgGL.CG_HALF2:
+ case CgGL.CG_INT2:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE2I;
+
+ case CgGL.CG_BOOL3:
+ case CgGL.CG_FIXED3:
+ case CgGL.CG_HALF3:
+ case CgGL.CG_INT3:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE3I;
+
+ case CgGL.CG_BOOL4:
+ case CgGL.CG_FIXED4:
+ case CgGL.CG_HALF4:
+ case CgGL.CG_INT4:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE4I;
+
+ case CgGL.CG_FLOAT:
+ case CgGL.CG_FLOAT1:
+ return ShaderAttributeObjectRetained.TYPE_FLOAT;
+
+ case CgGL.CG_FLOAT2:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE2F;
+
+ case CgGL.CG_FLOAT3:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE3F;
+
+ case CgGL.CG_FLOAT4:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE4F;
+
+ case CgGL.CG_FLOAT3x3:
+ return ShaderAttributeObjectRetained.TYPE_MATRIX3F;
+
+ case CgGL.CG_FLOAT4x4:
+ return ShaderAttributeObjectRetained.TYPE_MATRIX4F;
+
+ // Java 3D does not support the following sampler types:
+ //
+ // case CgGL.CG_SAMPLER1D:
+ // case CgGL.CG_SAMPLERRECT:
+ }
+
+ return -1;
+ }
+
+ private CGparameter lookupCgParams(JoglCgShaderInfo shader,
+ String attrNameString,
+ int[] type,
+ int[] size,
+ boolean[] isArray) {
+ CGparameter loc = CgGL.cgGetNamedParameter(shader.getCgShader(), attrNameString);
+ if (loc != null) {
+ type[0] = CgGL.cgGetParameterType(loc);
+ if (type[0] == CgGL.CG_ARRAY) {
+ isArray[0] = true;
+ size[0] = CgGL.cgGetArraySize(loc, 0);
+ CGparameter firstElem = CgGL.cgGetArrayParameter(loc, 0);
+ type[0] = CgGL.cgGetParameterType(firstElem);
+ } else {
+ isArray[0] = false;
+ size[0] = 1;
+ }
+ }
+ return loc;
+ }
+
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GLSLShaderProgramRetained methods
+ //
+
+ // ShaderAttributeValue methods
+
+ ShaderError setGLSLUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1i()");
+
+ context(ctx).getGL().glUniform1iARB(unbox(uniformLocation), value);
+ return null;
+ }
+
+ ShaderError setGLSLUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1f()");
+
+ context(ctx).getGL().glUniform1fARB(unbox(uniformLocation), value);
+ return null;
+ }
+
+ ShaderError setGLSLUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2i()");
+
+ context(ctx).getGL().glUniform2iARB(unbox(uniformLocation), value[0], value[1]);
+ return null;
+ }
+
+ ShaderError setGLSLUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2f()");
+
+ context(ctx).getGL().glUniform2fARB(unbox(uniformLocation), value[0], value[1]);
+ return null;
+ }
+
+ ShaderError setGLSLUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3i()");
+
+ context(ctx).getGL().glUniform3iARB(unbox(uniformLocation), value[0], value[1], value[2]);
+ return null;
+ }
+
+ ShaderError setGLSLUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3f()");
+
+ context(ctx).getGL().glUniform3fARB(unbox(uniformLocation), value[0], value[1], value[2]);
+ return null;
+ }
+
+ ShaderError setGLSLUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4i()");
+
+ context(ctx).getGL().glUniform4iARB(unbox(uniformLocation), value[0], value[1], value[2], value[3]);
+ return null;
+ }
+
+ ShaderError setGLSLUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4f()");
+
+ context(ctx).getGL().glUniform4fARB(unbox(uniformLocation), value[0], value[1], value[2], value[3]);
+ return null;
+ }
+
+ ShaderError setGLSLUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix3f()");
+
+ // Load attribute
+ // transpose is true : each matrix is supplied in row major order
+ context(ctx).getGL().glUniformMatrix3fvARB(unbox(uniformLocation), 1, true, value, 0);
+ return null;
+ }
+
+ ShaderError setGLSLUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix4f()");
+
+ // Load attribute
+ // transpose is true : each matrix is supplied in row major order
+ context(ctx).getGL().glUniformMatrix4fvARB(unbox(uniformLocation), 1, true, value, 0);
+ return null;
+ }
+
+ // ShaderAttributeArray methods
+
+ ShaderError setGLSLUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1iArray()");
+
+ context(ctx).getGL().glUniform1ivARB(unbox(uniformLocation), numElements, value, 0);
+ return null;
+ }
+
+ ShaderError setGLSLUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1fArray()");
+
+ context(ctx).getGL().glUniform1fvARB(unbox(uniformLocation), numElements, value, 0);
+ return null;
+ }
+
+ ShaderError setGLSLUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2iArray()");
+
+ context(ctx).getGL().glUniform2ivARB(unbox(uniformLocation), numElements, value, 0);
+ return null;
+ }
+
+ ShaderError setGLSLUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2fArray()");
+
+ context(ctx).getGL().glUniform2fvARB(unbox(uniformLocation), numElements, value, 0);
+ return null;
+ }
+
+ ShaderError setGLSLUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3iArray()");
+
+ context(ctx).getGL().glUniform3ivARB(unbox(uniformLocation), numElements, value, 0);
+ return null;
+ }
+
+ ShaderError setGLSLUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3fArray()");
+
+ context(ctx).getGL().glUniform3fvARB(unbox(uniformLocation), numElements, value, 0);
+ return null;
+ }
+
+ ShaderError setGLSLUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4iArray()");
+
+ context(ctx).getGL().glUniform4ivARB(unbox(uniformLocation), numElements, value, 0);
+ return null;
+ }
+
+ ShaderError setGLSLUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4fArray()");
+
+ context(ctx).getGL().glUniform4fvARB(unbox(uniformLocation), numElements, value, 0);
+ return null;
+ }
+
+ ShaderError setGLSLUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix3fArray()");
+
+ // Load attribute
+ // transpose is true : each matrix is supplied in row major order
+ context(ctx).getGL().glUniformMatrix3fvARB(unbox(uniformLocation), numElements, true, value, 0);
+ return null;
+ }
+
+ ShaderError setGLSLUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix4fArray()");
+
+ // Load attribute
+ // transpose is true : each matrix is supplied in row major order
+ context(ctx).getGL().glUniformMatrix4fvARB(unbox(uniformLocation), numElements, true, value, 0);
+ return null;
+ }
+
+ // interfaces for shader compilation, etc.
+ ShaderError createGLSLShader(Context ctx, int shaderType, ShaderId[] shaderId) {
+ if (VERBOSE) System.err.println("JoglPipeline.createGLSLShader()");
+
+ GL gl = context(ctx).getGL();
+
+ int shaderHandle = 0;
+ if (shaderType == Shader.SHADER_TYPE_VERTEX) {
+ shaderHandle = gl.glCreateShaderObjectARB(GL.GL_VERTEX_SHADER_ARB);
+ } else if (shaderType == Shader.SHADER_TYPE_FRAGMENT) {
+ shaderHandle = gl.glCreateShaderObjectARB(GL.GL_FRAGMENT_SHADER_ARB);
+ }
+
+ if (shaderHandle == 0) {
+ return new ShaderError(ShaderError.COMPILE_ERROR,
+ "Unable to create native shader object");
+ }
+
+ shaderId[0] = new JoglShaderObject(shaderHandle);
+ return null;
+ }
+ ShaderError destroyGLSLShader(Context ctx, ShaderId shaderId) {
+ if (VERBOSE) System.err.println("JoglPipeline.destroyGLSLShader()");
+
+ GL gl = context(ctx).getGL();
+ gl.glDeleteObjectARB(unbox(shaderId));
+ return null;
+ }
+ ShaderError compileGLSLShader(Context ctx, ShaderId shaderId, String program) {
+ if (VERBOSE) System.err.println("JoglPipeline.compileGLSLShader()");
+
+ int id = unbox(shaderId);
+ if (id == 0) {
+ throw new AssertionError("shaderId == 0");
+ }
+
+ if (program == null) {
+ throw new AssertionError("shader program string is null");
+ }
+
+ GL gl = context(ctx).getGL();
+ gl.glShaderSourceARB(id, 1, new String[] { program }, null, 0);
+ gl.glCompileShaderARB(id);
+ int[] status = new int[1];
+ gl.glGetObjectParameterivARB(id, GL.GL_OBJECT_COMPILE_STATUS_ARB, status, 0);
+ if (status[0] == 0) {
+ String detailMsg = getInfoLog(gl, id);
+ ShaderError res = new ShaderError(ShaderError.COMPILE_ERROR,
+ "GLSL shader compile error");
+ res.setDetailMessage(detailMsg);
+ return res;
+ }
+ return null;
+ }
+
+ ShaderError createGLSLShaderProgram(Context ctx, ShaderProgramId[] shaderProgramId) {
+ if (VERBOSE) System.err.println("JoglPipeline.createGLSLShaderProgram()");
+
+ GL gl = context(ctx).getGL();
+
+ int shaderProgramHandle = gl.glCreateProgramObjectARB();
+ if (shaderProgramHandle == 0) {
+ return new ShaderError(ShaderError.LINK_ERROR,
+ "Unable to create native shader program object");
+ }
+ shaderProgramId[0] = new JoglShaderObject(shaderProgramHandle);
+ return null;
+ }
+ ShaderError destroyGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ if (VERBOSE) System.err.println("JoglPipeline.destroyGLSLShaderProgram()");
+ context(ctx).getGL().glDeleteObjectARB(unbox(shaderProgramId));
+ return null;
+ }
+ ShaderError linkGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId,
+ ShaderId[] shaderIds) {
+ if (VERBOSE) System.err.println("JoglPipeline.linkGLSLShaderProgram()");
+
+ GL gl = context(ctx).getGL();
+ int id = unbox(shaderProgramId);
+ for (int i = 0; i < shaderIds.length; i++) {
+ gl.glAttachObjectARB(id, unbox(shaderIds[i]));
+ }
+ gl.glLinkProgramARB(id);
+ int[] status = new int[1];
+ gl.glGetObjectParameterivARB(id, GL.GL_OBJECT_LINK_STATUS_ARB, status, 0);
+ if (status[0] == 0) {
+ String detailMsg = getInfoLog(gl, id);
+ ShaderError res = new ShaderError(ShaderError.LINK_ERROR,
+ "GLSL shader program link error");
+ res.setDetailMessage(detailMsg);
+ return res;
+ }
+ return null;
+ }
+ ShaderError bindGLSLVertexAttrName(Context ctx, ShaderProgramId shaderProgramId,
+ String attrName, int attrIndex) {
+ if (VERBOSE) System.err.println("JoglPipeline.bindGLSLVertexAttrName()");
+
+ JoglContext jctx = (JoglContext) ctx;
+ context(ctx).getGL().glBindAttribLocationARB(unbox(shaderProgramId),
+ attrIndex + VirtualUniverse.mc.glslVertexAttrOffset,
+ attrName);
+ return null;
+ }
+ void lookupGLSLShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, ShaderAttrLoc[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr) {
+ if (VERBOSE) System.err.println("JoglPipeline.lookupGLSLShaderAttrNames()");
+
+ // set the loc, type, and size arrays to out-of-bound values
+ for (int i = 0; i < attrNames.length; i++) {
+ locArr[i] = null;
+ typeArr[i] = -1;
+ sizeArr[i] = -1;
+ }
+
+ // Loop through the list of active uniform variables, one at a
+ // time, searching for a match in the attrNames array.
+ //
+ // NOTE: Since attrNames isn't sorted, and we don't have a
+ // hashtable of names to index locations, we will do a
+ // brute-force, linear search of the array. This leads to an
+ // O(n^2) algorithm (actually O(n*m) where n is attrNames.length
+ // and m is the number of uniform variables), but since we expect
+ // N to be small, we will not optimize this at this time.
+ int id = unbox(shaderProgramId);
+ int[] tmp = new int[1];
+ int[] tmp2 = new int[1];
+ int[] tmp3 = new int[1];
+ GL gl = context(ctx).getGL();
+ gl.glGetObjectParameterivARB(id,
+ GL.GL_OBJECT_ACTIVE_UNIFORMS_ARB,
+ tmp, 0);
+ int numActiveUniforms = tmp[0];
+ gl.glGetObjectParameterivARB(id,
+ GL.GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB,
+ tmp, 0);
+ int maxStrLen = tmp[0];
+ byte[] nameBuf = new byte[maxStrLen];
+
+ for (int i = 0; i < numActiveUniforms; i++) {
+ gl.glGetActiveUniformARB(id, i, maxStrLen, tmp3, 0,
+ tmp, 0,
+ tmp2, 0,
+ nameBuf, 0);
+ int size = tmp[0];
+ int type = tmp2[0];
+ String name = null;
+ try {
+ // TODO KCR : Shouldn't this use the default locale?
+ name = new String(nameBuf, 0, tmp3[0], "US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ // Issue 247 - we need to workaround an ATI bug where they erroneously
+ // report individual elements of arrays rather than the array itself
+ if (name.length() >= 3 && name.endsWith("]")) {
+ if (name.endsWith("[0]")) {
+ name = name.substring(0, name.length() - 3);
+ } else {
+ // Ignore this name
+ continue;
+ }
+ }
+
+ // Now try to find the name
+ for (int j = 0; j < numAttrNames; j++) {
+ if (name.equals(attrNames[j])) {
+ sizeArr[j] = size;
+ isArrayArr[j] = (size > 1);
+ typeArr[j] = glslToJ3dType(type);
+ break;
+ }
+ }
+ }
+
+ // Now lookup the location of each name in the attrNames array
+ for (int i = 0; i < numAttrNames; i++) {
+ // Get uniform attribute location
+ int loc = gl.glGetUniformLocationARB(id, attrNames[i]);
+ locArr[i] = new JoglShaderObject(loc);
+ }
+ }
+
+ ShaderError useGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ if (VERBOSE) System.err.println("JoglPipeline.useGLSLShaderProgram()");
+
+ context(ctx).getGL().glUseProgramObjectARB(unbox(shaderProgramId));
+ ((JoglContext) ctx).setShaderProgram((JoglShaderObject) shaderProgramId);
+ return null;
+ }
+
+ //----------------------------------------------------------------------
+ // Helper methods for above shader routines
+ //
+ private int unbox(ShaderAttrLoc loc) {
+ if (loc == null)
+ return 0;
+ return ((JoglShaderObject) loc).getValue();
+ }
+
+ private int unbox(ShaderProgramId id) {
+ if (id == null)
+ return 0;
+ return ((JoglShaderObject) id).getValue();
+ }
+
+ private int unbox(ShaderId id) {
+ if (id == null)
+ return 0;
+ return ((JoglShaderObject) id).getValue();
+ }
+
+ private String getInfoLog(GL gl, int id) {
+ int[] infoLogLength = new int[1];
+ gl.glGetObjectParameterivARB(id, GL.GL_OBJECT_INFO_LOG_LENGTH_ARB, infoLogLength, 0);
+ if (infoLogLength[0] > 0) {
+ byte[] storage = new byte[infoLogLength[0]];
+ int[] len = new int[1];
+ gl.glGetInfoLogARB(id, infoLogLength[0], len, 0, storage, 0);
+ try {
+ // TODO KCR : Shouldn't this use the default locale?
+ return new String(storage, 0, len[0], "US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return null;
+ }
+
+ private int glslToJ3dType(int type) {
+ switch (type) {
+ case GL.GL_BOOL_ARB:
+ case GL.GL_INT:
+ case GL.GL_SAMPLER_2D_ARB:
+ case GL.GL_SAMPLER_3D_ARB:
+ case GL.GL_SAMPLER_CUBE_ARB:
+ return ShaderAttributeObjectRetained.TYPE_INTEGER;
+
+ case GL.GL_FLOAT:
+ return ShaderAttributeObjectRetained.TYPE_FLOAT;
+
+ case GL.GL_INT_VEC2_ARB:
+ case GL.GL_BOOL_VEC2_ARB:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE2I;
+
+ case GL.GL_FLOAT_VEC2_ARB:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE2F;
+
+ case GL.GL_INT_VEC3_ARB:
+ case GL.GL_BOOL_VEC3_ARB:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE3I;
+
+ case GL.GL_FLOAT_VEC3_ARB:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE3F;
+
+ case GL.GL_INT_VEC4_ARB:
+ case GL.GL_BOOL_VEC4_ARB:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE4I;
+
+ case GL.GL_FLOAT_VEC4_ARB:
+ return ShaderAttributeObjectRetained.TYPE_TUPLE4F;
+
+ // case GL.GL_FLOAT_MAT2_ARB:
+
+ case GL.GL_FLOAT_MAT3_ARB:
+ return ShaderAttributeObjectRetained.TYPE_MATRIX3F;
+
+ case GL.GL_FLOAT_MAT4_ARB:
+ return ShaderAttributeObjectRetained.TYPE_MATRIX4F;
+
+ // Java 3D does not support the following sampler types:
+ //
+ // case GL.GL_SAMPLER_1D_ARB:
+ // case GL.GL_SAMPLER_1D_SHADOW_ARB:
+ // case GL.GL_SAMPLER_2D_SHADOW_ARB:
+ // case GL.GL_SAMPLER_2D_RECT_ARB:
+ // case GL.GL_SAMPLER_2D_RECT_SHADOW_ARB:
+ }
+
+ return -1;
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ImageComponent2DRetained methods
+ //
+
+ // free d3d surface referred to by id
+ void freeD3DSurface(ImageComponent2DRetained image, int hashId) {
+ // Nothing to do
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Renderer methods
+ //
+
+ void cleanupRenderer() {
+ // Nothing to do
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ColoringAttributesRetained methods
+ //
+
+ void updateColoringAttributes(Context ctx,
+ float dRed, float dGreen, float dBlue,
+ float red, float green, float blue,
+ float alpha,
+ boolean lightEnable,
+ int shadeModel) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateColoringAttributes()");
+
+ GL gl = context(ctx).getGL();
+
+ float cr, cg, cb;
+
+ if (lightEnable) {
+ cr = dRed; cg = dGreen; cb = dBlue;
+ } else {
+ cr = red; cg = green; cb = blue;
+ }
+ gl.glColor4f(cr, cg, cb, alpha);
+ if (shadeModel == ColoringAttributes.SHADE_FLAT) {
+ gl.glShadeModel(GL.GL_FLAT);
+ } else {
+ gl.glShadeModel(GL.GL_SMOOTH);
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // DirectionalLightRetained methods
+ //
+
+ private static final float[] black = new float[4];
+ void updateDirectionalLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float dirx, float diry, float dirz) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateDirectionalLight()");
+
+ GL gl = context(ctx).getGL();
+
+ int lightNum = GL.GL_LIGHT0 + lightSlot;
+ float[] values = new float[4];
+
+ values[0] = red;
+ values[1] = green;
+ values[2] = blue;
+ values[3] = 1.0f;
+ gl.glLightfv(lightNum, GL.GL_DIFFUSE, values, 0);
+ gl.glLightfv(lightNum, GL.GL_SPECULAR, values, 0);
+ values[0] = -dirx;
+ values[1] = -diry;
+ values[2] = -dirz;
+ values[3] = 0.0f;
+ gl.glLightfv(lightNum, GL.GL_POSITION, values, 0);
+ gl.glLightfv(lightNum, GL.GL_AMBIENT, black, 0);
+ gl.glLightf(lightNum, GL.GL_CONSTANT_ATTENUATION, 1.0f);
+ gl.glLightf(lightNum, GL.GL_LINEAR_ATTENUATION, 0.0f);
+ gl.glLightf(lightNum, GL.GL_QUADRATIC_ATTENUATION, 0.0f);
+ gl.glLightf(lightNum, GL.GL_SPOT_EXPONENT, 0.0f);
+ gl.glLightf(lightNum, GL.GL_SPOT_CUTOFF, 180.0f);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PointLightRetained methods
+ //
+
+ void updatePointLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float attenx, float atteny, float attenz,
+ float posx, float posy, float posz) {
+ if (VERBOSE) System.err.println("JoglPipeline.updatePointLight()");
+
+ GL gl = context(ctx).getGL();
+
+ int lightNum = GL.GL_LIGHT0 + lightSlot;
+ float[] values = new float[4];
+
+ values[0] = red;
+ values[1] = green;
+ values[2] = blue;
+ values[3] = 1.0f;
+ gl.glLightfv(lightNum, GL.GL_DIFFUSE, values, 0);
+ gl.glLightfv(lightNum, GL.GL_SPECULAR, values, 0);
+ gl.glLightfv(lightNum, GL.GL_AMBIENT, black, 0);
+ values[0] = posx;
+ values[1] = posy;
+ values[2] = posz;
+ gl.glLightfv(lightNum, GL.GL_POSITION, values, 0);
+ gl.glLightf(lightNum, GL.GL_CONSTANT_ATTENUATION, attenx);
+ gl.glLightf(lightNum, GL.GL_LINEAR_ATTENUATION, atteny);
+ gl.glLightf(lightNum, GL.GL_QUADRATIC_ATTENUATION, attenz);
+ gl.glLightf(lightNum, GL.GL_SPOT_EXPONENT, 0.0f);
+ gl.glLightf(lightNum, GL.GL_SPOT_CUTOFF, 180.0f);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // SpotLightRetained methods
+ //
+
+ void updateSpotLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float attenx, float atteny, float attenz,
+ float posx, float posy, float posz, float spreadAngle,
+ float concentration, float dirx, float diry,
+ float dirz) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateSpotLight()");
+
+ GL gl = context(ctx).getGL();
+
+ int lightNum = GL.GL_LIGHT0 + lightSlot;
+ float[] values = new float[4];
+
+ values[0] = red;
+ values[1] = green;
+ values[2] = blue;
+ values[3] = 1.0f;
+ gl.glLightfv(lightNum, GL.GL_DIFFUSE, values, 0);
+ gl.glLightfv(lightNum, GL.GL_SPECULAR, values, 0);
+ gl.glLightfv(lightNum, GL.GL_AMBIENT, black, 0);
+ values[0] = posx;
+ values[1] = posy;
+ values[2] = posz;
+ gl.glLightfv(lightNum, GL.GL_POSITION, values, 0);
+ gl.glLightf(lightNum, GL.GL_CONSTANT_ATTENUATION, attenx);
+ gl.glLightf(lightNum, GL.GL_LINEAR_ATTENUATION, atteny);
+ gl.glLightf(lightNum, GL.GL_QUADRATIC_ATTENUATION, attenz);
+ values[0] = dirx;
+ values[1] = diry;
+ values[2] = dirz;
+ gl.glLightfv(lightNum, GL.GL_SPOT_DIRECTION, values, 0);
+ gl.glLightf(lightNum, GL.GL_SPOT_EXPONENT, concentration);
+ gl.glLightf(lightNum, GL.GL_SPOT_CUTOFF, (float) (spreadAngle * 180.0f / Math.PI));
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ExponentialFogRetained methods
+ //
+
+ void updateExponentialFog(Context ctx,
+ float red, float green, float blue,
+ float density) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateExponentialFog()");
+
+ GL gl = context(ctx).getGL();
+
+ float[] color = new float[3];
+ color[0] = red;
+ color[1] = green;
+ color[2] = blue;
+ gl.glFogi(GL.GL_FOG_MODE, GL.GL_EXP);
+ gl.glFogfv(GL.GL_FOG_COLOR, color, 0);
+ gl.glFogf(GL.GL_FOG_DENSITY, density);
+ gl.glEnable(GL.GL_FOG);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // LinearFogRetained methods
+ //
+
+ void updateLinearFog(Context ctx,
+ float red, float green, float blue,
+ double fdist, double bdist) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateLinearFog()");
+
+ GL gl = context(ctx).getGL();
+
+ float[] color = new float[3];
+ color[0] = red;
+ color[1] = green;
+ color[2] = blue;
+ gl.glFogi(GL.GL_FOG_MODE, GL.GL_LINEAR);
+ gl.glFogfv(GL.GL_FOG_COLOR, color, 0);
+ gl.glFogf(GL.GL_FOG_START, (float) fdist);
+ gl.glFogf(GL.GL_FOG_END, (float) bdist);
+ gl.glEnable(GL.GL_FOG);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // LineAttributesRetained methods
+ //
+
+ void updateLineAttributes(Context ctx,
+ float lineWidth, int linePattern,
+ int linePatternMask,
+ int linePatternScaleFactor,
+ boolean lineAntialiasing) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateLineAttributes()");
+
+ GL gl = context(ctx).getGL();
+ gl.glLineWidth(lineWidth);
+
+ if (linePattern == LineAttributes.PATTERN_SOLID) {
+ gl.glDisable(GL.GL_LINE_STIPPLE);
+ } else {
+ if (linePattern == LineAttributes.PATTERN_DASH) { // dashed lines
+ gl.glLineStipple(1, (short) 0x00ff);
+ } else if (linePattern == LineAttributes.PATTERN_DOT) { // dotted lines
+ gl.glLineStipple(1, (short) 0x0101);
+ } else if (linePattern == LineAttributes.PATTERN_DASH_DOT) { // dash-dotted lines
+ gl.glLineStipple(1, (short) 0x087f);
+ } else if (linePattern == LineAttributes.PATTERN_USER_DEFINED) { // user-defined mask
+ gl.glLineStipple(linePatternScaleFactor, (short) linePatternMask);
+ }
+ gl.glEnable(GL.GL_LINE_STIPPLE);
+ }
+
+ /* XXXX: Polygon Mode check, blend enable */
+ if (lineAntialiasing) {
+ gl.glEnable(GL.GL_LINE_SMOOTH);
+ } else {
+ gl.glDisable(GL.GL_LINE_SMOOTH);
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // MaterialRetained methods
+ //
+
+ void updateMaterial(Context ctx,
+ float red, float green, float blue, float alpha,
+ float aRed, float aGreen, float aBlue,
+ float eRed, float eGreen, float eBlue,
+ float dRed, float dGreen, float dBlue,
+ float sRed, float sGreen, float sBlue,
+ float shininess, int colorTarget, boolean lightEnable) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateMaterial()");
+
+ float[] color = new float[4];
+
+ GL gl = context(ctx).getGL();
+
+ gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, shininess);
+ switch (colorTarget) {
+ case Material.DIFFUSE:
+ gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE);
+ break;
+ case Material.AMBIENT:
+ gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT);
+ break;
+ case Material.EMISSIVE:
+ gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_EMISSION);
+ break;
+ case Material.SPECULAR:
+ gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR);
+ break;
+ case Material.AMBIENT_AND_DIFFUSE:
+ gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE);
+ break;
+ }
+
+ color[0] = eRed; color[1] = eGreen; color[2] = eBlue;
+ gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_EMISSION, color, 0);
+
+ color[0] = aRed; color[1] = aGreen; color[2] = aBlue;
+ gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, color, 0);
+
+ color[0] = sRed; color[1] = sGreen; color[2] = sBlue;
+ gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, color, 0);
+
+ float cr, cg, cb;
+
+ if (lightEnable) {
+ color[0] = dRed; color[1] = dGreen; color[2] = dBlue;
+ } else {
+ color[0] = red; color[1] = green; color[2] = blue;
+ }
+ color[3] = alpha;
+ gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, color, 0);
+ gl.glColor4f(color[0], color[1], color[2], color[3]);
+
+ if (lightEnable) {
+ gl.glEnable(GL.GL_LIGHTING);
+ } else {
+ gl.glDisable(GL.GL_LIGHTING);
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ModelClipRetained methods
+ //
+
+ void updateModelClip(Context ctx, int planeNum, boolean enableFlag,
+ double A, double B, double C, double D) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateModelClip()");
+
+ GL gl = context(ctx).getGL();
+
+ double[] equation = new double[4];
+ int pl = GL.GL_CLIP_PLANE0 + planeNum;
+
+ // OpenGL clip planes are opposite to J3d clip planes
+ if (enableFlag) {
+ equation[0] = -A;
+ equation[1] = -B;
+ equation[2] = -C;
+ equation[3] = -D;
+ gl.glClipPlane(pl, DoubleBuffer.wrap(equation));
+ gl.glEnable(pl);
+ } else {
+ gl.glDisable(pl);
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PointAttributesRetained methods
+ //
+
+ void updatePointAttributes(Context ctx, float pointSize, boolean pointAntialiasing) {
+ if (VERBOSE) System.err.println("JoglPipeline.updatePointAttributes()");
+
+ GL gl = context(ctx).getGL();
+ gl.glPointSize(pointSize);
+
+ // XXXX: Polygon Mode check, blend enable
+ if (pointAntialiasing) {
+ gl.glEnable(GL.GL_POINT_SMOOTH);
+ } else {
+ gl.glDisable(GL.GL_POINT_SMOOTH);
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PolygonAttributesRetained methods
+ //
+
+ void updatePolygonAttributes(Context ctx,
+ int polygonMode, int cullFace,
+ boolean backFaceNormalFlip,
+ float polygonOffset,
+ float polygonOffsetFactor) {
+ if (VERBOSE) System.err.println("JoglPipeline.updatePolygonAttributes()");
+
+ GL gl = context(ctx).getGL();
+
+ if (cullFace == PolygonAttributes.CULL_NONE) {
+ gl.glDisable(GL.GL_CULL_FACE);
+ } else {
+ if (cullFace == PolygonAttributes.CULL_BACK) {
+ gl.glCullFace(GL.GL_BACK);
+ } else {
+ gl.glCullFace(GL.GL_FRONT);
+ }
+ gl.glEnable(GL.GL_CULL_FACE);
+ }
+
+ if (backFaceNormalFlip && (cullFace != PolygonAttributes.CULL_BACK)) {
+ gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_TRUE);
+ } else {
+ gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_FALSE);
+ }
+
+ if (polygonMode == PolygonAttributes.POLYGON_POINT) {
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_POINT);
+ } else if (polygonMode == PolygonAttributes.POLYGON_LINE) {
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
+ } else {
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
+ }
+
+ gl.glPolygonOffset(polygonOffsetFactor, polygonOffset);
+
+ if ((polygonOffsetFactor != 0.0) || (polygonOffset != 0.0)) {
+ switch (polygonMode) {
+ case PolygonAttributes.POLYGON_POINT:
+ gl.glEnable(GL.GL_POLYGON_OFFSET_POINT);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_LINE);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
+ break;
+ case PolygonAttributes.POLYGON_LINE:
+ gl.glEnable(GL.GL_POLYGON_OFFSET_LINE);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_POINT);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
+ break;
+ case PolygonAttributes.POLYGON_FILL:
+ gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_POINT);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_LINE);
+ break;
+ }
+ } else {
+ gl.glDisable(GL.GL_POLYGON_OFFSET_POINT);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_LINE);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // RenderingAttributesRetained methods
+ //
+
+ void updateRenderingAttributes(Context ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride,
+ boolean depthBufferEnable,
+ boolean depthBufferWriteEnable,
+ int depthTestFunction,
+ float alphaTestValue, int alphaTestFunction,
+ boolean ignoreVertexColors,
+ boolean rasterOpEnable, int rasterOp,
+ boolean userStencilAvailable, boolean stencilEnable,
+ int stencilFailOp, int stencilZFailOp, int stencilZPassOp,
+ int stencilFunction, int stencilReferenceValue,
+ int stencilCompareMask, int stencilWriteMask ) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateRenderingAttributes()");
+
+ GL gl = context(ctx).getGL();
+
+ if (!depthBufferEnableOverride) {
+ if (depthBufferEnable) {
+ gl.glEnable(GL.GL_DEPTH_TEST);
+ gl.glDepthFunc(getFunctionValue(depthTestFunction));
+ } else {
+ gl.glDisable(GL.GL_DEPTH_TEST);
+ }
+ }
+
+ if (!depthBufferWriteEnableOverride) {
+ if (depthBufferWriteEnable) {
+ gl.glDepthMask(true);
+ } else {
+ gl.glDepthMask(false);
+ }
+ }
+
+ if (alphaTestFunction == RenderingAttributes.ALWAYS) {
+ gl.glDisable(GL.GL_ALPHA_TEST);
+ } else {
+ gl.glEnable(GL.GL_ALPHA_TEST);
+ gl.glAlphaFunc(getFunctionValue(alphaTestFunction), alphaTestValue);
+ }
+
+ if (ignoreVertexColors) {
+ gl.glDisable(GL.GL_COLOR_MATERIAL);
+ } else {
+ gl.glEnable(GL.GL_COLOR_MATERIAL);
+ }
+
+ if (rasterOpEnable) {
+ gl.glEnable(GL.GL_COLOR_LOGIC_OP);
+ switch (rasterOp) {
+ case RenderingAttributes.ROP_CLEAR:
+ gl.glLogicOp(GL.GL_CLEAR);
+ break;
+ case RenderingAttributes.ROP_AND:
+ gl.glLogicOp(GL.GL_AND);
+ break;
+ case RenderingAttributes.ROP_AND_REVERSE:
+ gl.glLogicOp(GL.GL_AND_REVERSE);
+ break;
+ case RenderingAttributes.ROP_COPY:
+ gl.glLogicOp(GL.GL_COPY);
+ break;
+ case RenderingAttributes.ROP_AND_INVERTED:
+ gl.glLogicOp(GL.GL_AND_INVERTED);
+ break;
+ case RenderingAttributes.ROP_NOOP:
+ gl.glLogicOp(GL.GL_NOOP);
+ break;
+ case RenderingAttributes.ROP_XOR:
+ gl.glLogicOp(GL.GL_XOR);
+ break;
+ case RenderingAttributes.ROP_OR:
+ gl.glLogicOp(GL.GL_OR);
+ break;
+ case RenderingAttributes.ROP_NOR:
+ gl.glLogicOp(GL.GL_NOR);
+ break;
+ case RenderingAttributes.ROP_EQUIV:
+ gl.glLogicOp(GL.GL_EQUIV);
+ break;
+ case RenderingAttributes.ROP_INVERT:
+ gl.glLogicOp(GL.GL_INVERT);
+ break;
+ case RenderingAttributes.ROP_OR_REVERSE:
+ gl.glLogicOp(GL.GL_OR_REVERSE);
+ break;
+ case RenderingAttributes.ROP_COPY_INVERTED:
+ gl.glLogicOp(GL.GL_COPY_INVERTED);
+ break;
+ case RenderingAttributes.ROP_OR_INVERTED:
+ gl.glLogicOp(GL.GL_OR_INVERTED);
+ break;
+ case RenderingAttributes.ROP_NAND:
+ gl.glLogicOp(GL.GL_NAND);
+ break;
+ case RenderingAttributes.ROP_SET:
+ gl.glLogicOp(GL.GL_SET);
+ break;
+ }
+ } else {
+ gl.glDisable(GL.GL_COLOR_LOGIC_OP);
+ }
+
+ if (userStencilAvailable) {
+ if (stencilEnable) {
+ gl.glEnable(GL.GL_STENCIL_TEST);
+
+ gl.glStencilOp(getStencilOpValue(stencilFailOp),
+ getStencilOpValue(stencilZFailOp),
+ getStencilOpValue(stencilZPassOp));
+
+ gl.glStencilFunc(getFunctionValue(stencilFunction),
+ stencilReferenceValue, stencilCompareMask);
+
+ gl.glStencilMask(stencilWriteMask);
+
+ } else {
+ gl.glDisable(GL.GL_STENCIL_TEST);
+ }
+ }
+ }
+
+ private int getFunctionValue(int func) {
+ switch (func) {
+ case RenderingAttributes.ALWAYS:
+ func = GL.GL_ALWAYS;
+ break;
+ case RenderingAttributes.NEVER:
+ func = GL.GL_NEVER;
+ break;
+ case RenderingAttributes.EQUAL:
+ func = GL.GL_EQUAL;
+ break;
+ case RenderingAttributes.NOT_EQUAL:
+ func = GL.GL_NOTEQUAL;
+ break;
+ case RenderingAttributes.LESS:
+ func = GL.GL_LESS;
+ break;
+ case RenderingAttributes.LESS_OR_EQUAL:
+ func = GL.GL_LEQUAL;
+ break;
+ case RenderingAttributes.GREATER:
+ func = GL.GL_GREATER;
+ break;
+ case RenderingAttributes.GREATER_OR_EQUAL:
+ func = GL.GL_GEQUAL;
+ break;
+ }
+
+ return func;
+ }
+
+ private int getStencilOpValue(int op) {
+ switch (op) {
+ case RenderingAttributes.STENCIL_KEEP:
+ op = GL.GL_KEEP;
+ break;
+ case RenderingAttributes.STENCIL_ZERO:
+ op = GL.GL_ZERO;
+ break;
+ case RenderingAttributes.STENCIL_REPLACE:
+ op = GL.GL_REPLACE;
+ break;
+ case RenderingAttributes.STENCIL_INCR:
+ op = GL.GL_INCR;
+ break;
+ case RenderingAttributes.STENCIL_DECR:
+ op = GL.GL_DECR;
+ break;
+ case RenderingAttributes.STENCIL_INVERT:
+ op = GL.GL_INVERT;
+ break;
+ }
+
+ return op;
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TexCoordGenerationRetained methods
+ //
+
+ /**
+ * This method updates the native context:
+ * trans contains eyeTovworld transform in d3d
+ * trans contains vworldToEye transform in ogl
+ */
+ void updateTexCoordGeneration(Context ctx,
+ boolean enable, int genMode, int format,
+ float planeSx, float planeSy, float planeSz, float planeSw,
+ float planeTx, float planeTy, float planeTz, float planeTw,
+ float planeRx, float planeRy, float planeRz, float planeRw,
+ float planeQx, float planeQy, float planeQz, float planeQw,
+ double[] vworldToEc) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexCoordGeneration()");
+
+ GL gl = context(ctx).getGL();
+
+ float[] planeS = new float[4];
+ float[] planeT = new float[4];
+ float[] planeR = new float[4];
+ float[] planeQ = new float[4];
+
+ if (enable) {
+ gl.glEnable(GL.GL_TEXTURE_GEN_S);
+ gl.glEnable(GL.GL_TEXTURE_GEN_T);
+ if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
+ gl.glEnable(GL.GL_TEXTURE_GEN_R);
+ gl.glDisable(GL.GL_TEXTURE_GEN_Q);
+ } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
+ gl.glEnable(GL.GL_TEXTURE_GEN_R);
+ gl.glEnable(GL.GL_TEXTURE_GEN_Q);
+ } else {
+ gl.glDisable(GL.GL_TEXTURE_GEN_R);
+ gl.glDisable(GL.GL_TEXTURE_GEN_Q);
+ }
+
+ if (genMode != TexCoordGeneration.SPHERE_MAP) {
+ planeS[0] = planeSx; planeS[1] = planeSy;
+ planeS[2] = planeSz; planeS[3] = planeSw;
+ planeT[0] = planeTx; planeT[1] = planeTy;
+ planeT[2] = planeTz; planeT[3] = planeTw;
+ if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
+ planeR[0] = planeRx; planeR[1] = planeRy;
+ planeR[2] = planeRz; planeR[3] = planeRw;
+ } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
+ planeR[0] = planeRx; planeR[1] = planeRy;
+ planeR[2] = planeRz; planeR[3] = planeRw;
+ planeQ[0] = planeQx; planeQ[1] = planeQy;
+ planeQ[2] = planeQz; planeQ[3] = planeQw;
+ }
+ }
+
+ switch (genMode) {
+ case TexCoordGeneration.OBJECT_LINEAR:
+ gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
+ gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
+ gl.glTexGenfv(GL.GL_S, GL.GL_OBJECT_PLANE, planeS, 0);
+ gl.glTexGenfv(GL.GL_T, GL.GL_OBJECT_PLANE, planeT, 0);
+
+ if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
+ gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
+ gl.glTexGenfv(GL.GL_R, GL.GL_OBJECT_PLANE, planeR, 0);
+ } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
+ gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
+ gl.glTexGenfv(GL.GL_R, GL.GL_OBJECT_PLANE, planeR, 0);
+ gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
+ gl.glTexGenfv(GL.GL_Q, GL.GL_OBJECT_PLANE, planeQ, 0);
+ }
+ break;
+ case TexCoordGeneration.EYE_LINEAR:
+
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glPushMatrix();
+
+ if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ gl.glLoadTransposeMatrixd(vworldToEc, 0);
+ } else {
+ double[] v = new double[16];
+ copyTranspose(vworldToEc, v);
+ gl.glLoadMatrixd(v, 0);
+ }
+
+ gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
+ gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
+ gl.glTexGenfv(GL.GL_S, GL.GL_EYE_PLANE, planeS, 0);
+ gl.glTexGenfv(GL.GL_T, GL.GL_EYE_PLANE, planeT, 0);
+
+ if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
+ gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
+ gl.glTexGenfv(GL.GL_R, GL.GL_EYE_PLANE, planeR, 0);
+ } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
+ gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
+ gl.glTexGenfv(GL.GL_R, GL.GL_EYE_PLANE, planeR, 0);
+ gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
+ gl.glTexGenfv(GL.GL_Q, GL.GL_EYE_PLANE, planeQ, 0);
+ }
+ gl.glPopMatrix();
+ break;
+ case TexCoordGeneration.SPHERE_MAP:
+ gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_SPHERE_MAP);
+ gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_SPHERE_MAP);
+ if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
+ gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_SPHERE_MAP);
+ } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
+ gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_SPHERE_MAP);
+ gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE, GL.GL_SPHERE_MAP);
+ }
+
+ break;
+ case TexCoordGeneration.NORMAL_MAP:
+ gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP);
+ gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP);
+ if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
+ gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP);
+ } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
+ gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP);
+ gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP);
+ }
+ break;
+ case TexCoordGeneration.REFLECTION_MAP:
+ gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);
+ gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);
+ if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) {
+ gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);
+ } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) {
+ gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);
+ gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);
+ }
+ break;
+ }
+ } else {
+ gl.glDisable(GL.GL_TEXTURE_GEN_S);
+ gl.glDisable(GL.GL_TEXTURE_GEN_T);
+ gl.glDisable(GL.GL_TEXTURE_GEN_R);
+ gl.glDisable(GL.GL_TEXTURE_GEN_Q);
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TransparencyAttributesRetained methods
+ //
+
+ private static final int screen_door[][] = {
+ /* 0 / 16 */
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ },
+ /* 1 / 16 */
+ {
+ 0x00000000, 0x22222222, 0x00000000, 0x00000000,
+ 0x00000000, 0x22222222, 0x00000000, 0x00000000,
+ 0x00000000, 0x22222222, 0x00000000, 0x00000000,
+ 0x00000000, 0x22222222, 0x00000000, 0x00000000,
+ 0x00000000, 0x22222222, 0x00000000, 0x00000000,
+ 0x00000000, 0x22222222, 0x00000000, 0x00000000,
+ 0x00000000, 0x22222222, 0x00000000, 0x00000000,
+ 0x00000000, 0x22222222, 0x00000000, 0x00000000,
+ },
+ /* 2 / 16 */
+ {
+ 0x00000000, 0x22222222, 0x00000000, 0x88888888,
+ 0x00000000, 0x22222222, 0x00000000, 0x88888888,
+ 0x00000000, 0x22222222, 0x00000000, 0x88888888,
+ 0x00000000, 0x22222222, 0x00000000, 0x88888888,
+ 0x00000000, 0x22222222, 0x00000000, 0x88888888,
+ 0x00000000, 0x22222222, 0x00000000, 0x88888888,
+ 0x00000000, 0x22222222, 0x00000000, 0x88888888,
+ 0x00000000, 0x22222222, 0x00000000, 0x88888888,
+ },
+ /* 3 / 16 */
+ {
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888,
+ },
+ /* 4 / 16 */
+ {
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ },
+ /* 5 / 16 */
+ {
+ 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa,
+ },
+ /* 6 / 16 */
+ {
+ 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ },
+ /* 7 / 16 */
+ {
+ 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa,
+ },
+ /* 8 / 16 */
+ {
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ },
+ /* 9 / 16 */
+ {
+ 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ },
+ /* 10 / 16 */
+ {
+ 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ },
+ /* 11 / 16 */
+ {
+ 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa,
+ },
+ /* 12 / 16 */
+ {
+ 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa,
+ },
+ /* 13 / 16 */
+ {
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa,
+ },
+ /* 14 / 16 */
+ {
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee,
+ },
+ /* 15 / 16 */
+ {
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee,
+ },
+ /* 16 / 16 */
+ {
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ },
+ };
+ private static final ByteBuffer[] screen_door_table = new ByteBuffer[screen_door.length];
+ static {
+ int eachLen = screen_door[0].length;
+ ByteBuffer buf = BufferUtil.newByteBuffer(screen_door.length * eachLen * BufferUtil.SIZEOF_INT);
+ IntBuffer intBuf = buf.asIntBuffer();
+ for (int i = 0; i < screen_door.length; i++) {
+ intBuf.put(screen_door[i]);
+ }
+ buf.rewind();
+ for (int i = 0; i < screen_door.length; i++) {
+ buf.position(i * eachLen);
+ buf.limit((i+1) * eachLen);
+ screen_door_table[i] = buf.slice();
+ }
+ }
+
+ private static final int[] blendFunctionTable = new int[TransparencyAttributes.MAX_BLEND_FUNC_TABLE_SIZE];
+ static {
+ blendFunctionTable[TransparencyAttributes.BLEND_ZERO] = GL.GL_ZERO;
+ blendFunctionTable[TransparencyAttributes.BLEND_ONE] = GL.GL_ONE;
+ blendFunctionTable[TransparencyAttributes.BLEND_SRC_ALPHA] = GL.GL_SRC_ALPHA;
+ blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_SRC_ALPHA] = GL.GL_ONE_MINUS_SRC_ALPHA;
+ blendFunctionTable[TransparencyAttributes.BLEND_DST_COLOR] = GL.GL_DST_COLOR;
+ blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_DST_COLOR] = GL.GL_ONE_MINUS_DST_COLOR;
+ blendFunctionTable[TransparencyAttributes.BLEND_SRC_COLOR] = GL.GL_SRC_COLOR;
+ blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_SRC_COLOR] = GL.GL_ONE_MINUS_SRC_COLOR;
+ blendFunctionTable[TransparencyAttributes.BLEND_CONSTANT_COLOR] = GL.GL_CONSTANT_COLOR;
+ }
+
+ void updateTransparencyAttributes(Context ctx,
+ float alpha, int geometryType,
+ int polygonMode,
+ boolean lineAA, boolean pointAA,
+ int transparencyMode,
+ int srcBlendFunction,
+ int dstBlendFunction) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTransparencyAttributes()");
+
+ GL gl = context(ctx).getGL();
+
+ if (transparencyMode != TransparencyAttributes.SCREEN_DOOR) {
+ gl.glDisable(GL.GL_POLYGON_STIPPLE);
+ } else {
+ gl.glEnable(GL.GL_POLYGON_STIPPLE);
+ gl.glPolygonStipple(screen_door_table[(int)(alpha * 16)]);
+ }
+
+ if ((transparencyMode < TransparencyAttributes.SCREEN_DOOR) ||
+ ((((geometryType & RenderMolecule.LINE) != 0) ||
+ (polygonMode == PolygonAttributes.POLYGON_LINE))
+ && lineAA) ||
+ ((((geometryType & RenderMolecule.POINT) != 0) ||
+ (polygonMode == PolygonAttributes.POLYGON_POINT))
+ && pointAA)) {
+ gl.glEnable(GL.GL_BLEND);
+ // valid range of blendFunction 0..3 is already verified in shared code.
+ gl.glBlendFunc(blendFunctionTable[srcBlendFunction], blendFunctionTable[dstBlendFunction]);
+ } else {
+ gl.glDisable(GL.GL_BLEND);
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureAttributesRetained methods
+ //
+
+ void updateTextureAttributes(Context ctx,
+ double[] transform, boolean isIdentity, int textureMode,
+ int perspCorrectionMode,
+ float textureBlendColorRed,
+ float textureBlendColorGreen,
+ float textureBlendColorBlue,
+ float textureBlendColorAlpha,
+ int textureFormat) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureAttributes()");
+
+ GL gl = context(ctx).getGL();
+ gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT,
+ (perspCorrectionMode == TextureAttributes.NICEST) ? GL.GL_NICEST : GL.GL_FASTEST);
+
+ // set OGL texture matrix
+ gl.glPushAttrib(GL.GL_TRANSFORM_BIT);
+ gl.glMatrixMode(GL.GL_TEXTURE);
+
+ if (isIdentity) {
+ gl.glLoadIdentity();
+ } else if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ gl.glLoadTransposeMatrixd(transform, 0);
+ } else {
+ double[] mx = new double[16];
+ copyTranspose(transform, mx);
+ gl.glLoadMatrixd(mx, 0);
+ }
+
+ gl.glPopAttrib();
+
+ // set texture color
+ float[] color = new float[4];
+ color[0] = textureBlendColorRed;
+ color[1] = textureBlendColorGreen;
+ color[2] = textureBlendColorBlue;
+ color[3] = textureBlendColorAlpha;
+ gl.glTexEnvfv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_COLOR, color, 0);
+
+ // set texture environment mode
+
+ switch (textureMode) {
+ case TextureAttributes.MODULATE:
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
+ break;
+ case TextureAttributes.DECAL:
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_DECAL);
+ break;
+ case TextureAttributes.BLEND:
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_BLEND);
+ break;
+ case TextureAttributes.REPLACE:
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
+ break;
+ case TextureAttributes.COMBINE:
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_COMBINE);
+ break;
+ }
+
+ if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) {
+ gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI);
+ }
+ }
+
+ void updateRegisterCombiners(Context absCtx,
+ double[] transform, boolean isIdentity, int textureMode,
+ int perspCorrectionMode,
+ float textureBlendColorRed,
+ float textureBlendColorGreen,
+ float textureBlendColorBlue,
+ float textureBlendColorAlpha,
+ int textureFormat,
+ int combineRgbMode, int combineAlphaMode,
+ int[] combineRgbSrc, int[] combineAlphaSrc,
+ int[] combineRgbFcn, int[] combineAlphaFcn,
+ int combineRgbScale, int combineAlphaScale) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateRegisterCombiners()");
+
+ JoglContext ctx = (JoglContext) absCtx;
+ GL gl = context(ctx).getGL();
+
+ if (perspCorrectionMode == TextureAttributes.NICEST) {
+ gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
+ } else {
+ gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_FASTEST);
+ }
+
+ // set OGL texture matrix
+ gl.glPushAttrib(GL.GL_TRANSFORM_BIT);
+ gl.glMatrixMode(GL.GL_TEXTURE);
+
+ if (isIdentity) {
+ gl.glLoadIdentity();
+ } else if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ gl.glLoadTransposeMatrixd(transform, 0);
+ } else {
+ double[] mx = new double[16];
+ copyTranspose(transform, mx);
+ gl.glLoadMatrixd(mx, 0);
+ }
+
+ gl.glPopAttrib();
+
+ // set texture color
+ float[] color = new float[4];
+ color[0] = textureBlendColorRed;
+ color[1] = textureBlendColorGreen;
+ color[2] = textureBlendColorBlue;
+ color[3] = textureBlendColorAlpha;
+ gl.glTexEnvfv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_COLOR, color, 0);
+
+ // set texture environment mode
+ gl.glEnable(GL.GL_REGISTER_COMBINERS_NV);
+ int textureUnit = ctx.getCurrentTextureUnit();
+ int combinerUnit = ctx.getCurrentCombinerUnit();
+ int fragment;
+ if (combinerUnit == GL.GL_COMBINER0_NV) {
+ fragment = GL.GL_PRIMARY_COLOR_NV;
+ } else {
+ fragment = GL.GL_SPARE0_NV;
+ }
+
+ switch (textureMode) {
+ case TextureAttributes.MODULATE:
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_A_NV, fragment,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_B_NV, textureUnit,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_VARIABLE_A_NV, fragment,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_VARIABLE_B_NV, textureUnit,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
+
+ gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV,
+ GL.GL_NONE, GL.GL_NONE, false, false, false);
+ gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV,
+ GL.GL_NONE, GL.GL_NONE, false, false, false);
+ break;
+
+ case TextureAttributes.DECAL:
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_A_NV, fragment,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_B_NV, textureUnit,
+ GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_C_NV, textureUnit,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_D_NV, textureUnit,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
+
+ gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_VARIABLE_A_NV, fragment,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_VARIABLE_B_NV, GL.GL_ZERO,
+ GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA);
+
+ gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, GL.GL_SPARE0_NV,
+ GL.GL_NONE, GL.GL_NONE, false, false, false);
+ gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV,
+ GL.GL_NONE, GL.GL_NONE, false, false, false);
+ break;
+
+ case TextureAttributes.BLEND:
+ gl.glCombinerParameterfvNV(GL.GL_CONSTANT_COLOR0_NV, color, 0);
+
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_A_NV, fragment,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_B_NV, textureUnit,
+ GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_C_NV, GL.GL_CONSTANT_COLOR0_NV,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_D_NV, textureUnit,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+
+ gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_VARIABLE_A_NV, fragment,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_VARIABLE_B_NV, textureUnit,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
+
+ gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, GL.GL_SPARE0_NV,
+ GL.GL_NONE, GL.GL_NONE, false, false, false);
+ gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV,
+ GL.GL_NONE, GL.GL_NONE, false, false, false);
+ break;
+
+ case TextureAttributes.REPLACE:
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_A_NV, textureUnit,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_B_NV, GL.GL_ZERO,
+ GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_VARIABLE_A_NV, textureUnit,
+ GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_VARIABLE_B_NV, GL.GL_ZERO,
+ GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA);
+
+ gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV,
+ GL.GL_NONE, GL.GL_NONE, false, false, false);
+ gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV,
+ GL.GL_NONE, GL.GL_NONE, false, false, false);
+ break;
+
+ case TextureAttributes.COMBINE:
+ if (combineRgbMode == TextureAttributes.COMBINE_DOT3) {
+ int color1 = getCombinerArg(gl, combineRgbSrc[0], textureUnit, combinerUnit);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_A_NV, color1,
+ GL.GL_EXPAND_NORMAL_NV, GL.GL_RGB);
+ int color2 = getCombinerArg(gl, combineRgbSrc[1], textureUnit, combinerUnit);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_VARIABLE_B_NV, color2,
+ GL.GL_EXPAND_NORMAL_NV, GL.GL_RGB);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_VARIABLE_A_NV, GL.GL_ZERO,
+ GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA);
+ gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_VARIABLE_B_NV, GL.GL_ZERO,
+ GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA);
+
+ gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB,
+ GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV,
+ GL.GL_NONE/*SCALE_BY_FOUR_NV*/, GL.GL_NONE, true,
+ false, false);
+ gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA,
+ GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV,
+ GL.GL_NONE, GL.GL_NONE, false,
+ false, false);
+ }
+ break;
+ }
+
+ gl.glFinalCombinerInputNV(GL.GL_VARIABLE_A_NV,
+ GL.GL_SPARE0_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glFinalCombinerInputNV(GL.GL_VARIABLE_B_NV,
+ GL.GL_ZERO, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB);
+ gl.glFinalCombinerInputNV(GL.GL_VARIABLE_C_NV,
+ GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glFinalCombinerInputNV(GL.GL_VARIABLE_D_NV,
+ GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glFinalCombinerInputNV(GL.GL_VARIABLE_E_NV,
+ GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glFinalCombinerInputNV(GL.GL_VARIABLE_F_NV,
+ GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
+ gl.glFinalCombinerInputNV(GL.GL_VARIABLE_G_NV,
+ GL.GL_SPARE0_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA);
+
+ if (gl.isExtensionAvailable("GL_SGI_texture_color_table"))
+ gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI);
+ // GL_SGI_texture_color_table
+ }
+
+ void updateTextureColorTable(Context ctx, int numComponents,
+ int colorTableSize,
+ int[] textureColorTable) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureColorTable()");
+
+ GL gl = context(ctx).getGL();
+ if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) {
+ if (numComponents == 3) {
+ gl.glColorTable(GL.GL_TEXTURE_COLOR_TABLE_SGI, GL.GL_RGB,
+ colorTableSize, GL.GL_RGB, GL.GL_INT, IntBuffer.wrap(textureColorTable));
+ } else {
+ gl.glColorTable(GL.GL_TEXTURE_COLOR_TABLE_SGI, GL.GL_RGBA,
+ colorTableSize, GL.GL_RGBA, GL.GL_INT, IntBuffer.wrap(textureColorTable));
+ }
+ gl.glEnable(GL.GL_TEXTURE_COLOR_TABLE_SGI);
+ }
+ }
+
+ void updateCombiner(Context ctx,
+ int combineRgbMode, int combineAlphaMode,
+ int[] combineRgbSrc, int[] combineAlphaSrc,
+ int[] combineRgbFcn, int[] combineAlphaFcn,
+ int combineRgbScale, int combineAlphaScale) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateCombiner()");
+
+ GL gl = context(ctx).getGL();
+ int[] GLrgbMode = new int[1];
+ int[] GLalphaMode = new int[1];
+ getGLCombineMode(gl, combineRgbMode, combineAlphaMode,
+ GLrgbMode, GLalphaMode);
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, GLrgbMode[0]);
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_ALPHA, GLalphaMode[0]);
+
+ int nargs;
+ if (combineRgbMode == TextureAttributes.COMBINE_REPLACE) {
+ nargs = 1;
+ } else if (combineRgbMode == TextureAttributes.COMBINE_INTERPOLATE) {
+ nargs = 3;
+ } else {
+ nargs = 2;
+ }
+
+ for (int i = 0; i < nargs; i++) {
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, _gl_combineRgbSrcIndex[i],
+ _gl_combineSrc[combineRgbSrc[i]]);
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, _gl_combineRgbOpIndex[i],
+ _gl_combineFcn[combineRgbFcn[i]]);
+ }
+
+ if (combineAlphaMode == TextureAttributes.COMBINE_REPLACE) {
+ nargs = 1;
+ } else if (combineAlphaMode == TextureAttributes.COMBINE_INTERPOLATE) {
+ nargs = 3;
+ } else {
+ nargs = 2;
+ }
+
+ for (int i = 0; i < nargs; i++) {
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, _gl_combineAlphaSrcIndex[i],
+ _gl_combineSrc[combineAlphaSrc[i]]);
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, _gl_combineAlphaOpIndex[i],
+ _gl_combineFcn[combineAlphaFcn[i]]);
+ }
+
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_RGB_SCALE, combineRgbScale);
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_ALPHA_SCALE, combineAlphaScale);
+ }
+
+ // Helper routines for above
+
+ private void getGLCombineMode(GL gl, int combineRgbMode, int combineAlphaMode,
+ int[] GLrgbMode, int[] GLalphaMode) {
+ switch (combineRgbMode) {
+ case TextureAttributes.COMBINE_REPLACE:
+ GLrgbMode[0] = GL.GL_REPLACE;
+ break;
+ case TextureAttributes.COMBINE_MODULATE:
+ GLrgbMode[0] = GL.GL_MODULATE;
+ break;
+ case TextureAttributes.COMBINE_ADD:
+ GLrgbMode[0] = GL.GL_ADD;
+ break;
+ case TextureAttributes.COMBINE_ADD_SIGNED:
+ GLrgbMode[0] = GL.GL_ADD_SIGNED;
+ break;
+ case TextureAttributes.COMBINE_SUBTRACT:
+ GLrgbMode[0] = GL.GL_SUBTRACT;
+ break;
+ case TextureAttributes.COMBINE_INTERPOLATE:
+ GLrgbMode[0] = GL.GL_INTERPOLATE;
+ break;
+ case TextureAttributes.COMBINE_DOT3:
+ GLrgbMode[0] = GL.GL_DOT3_RGB;
+ break;
+ default:
+ break;
+ }
+
+ switch (combineAlphaMode) {
+ case TextureAttributes.COMBINE_REPLACE:
+ GLalphaMode[0] = GL.GL_REPLACE;
+ break;
+ case TextureAttributes.COMBINE_MODULATE:
+ GLalphaMode[0] = GL.GL_MODULATE;
+ break;
+ case TextureAttributes.COMBINE_ADD:
+ GLalphaMode[0] = GL.GL_ADD;
+ break;
+ case TextureAttributes.COMBINE_ADD_SIGNED:
+ GLalphaMode[0] = GL.GL_ADD_SIGNED;
+ break;
+ case TextureAttributes.COMBINE_SUBTRACT:
+ GLalphaMode[0] = GL.GL_SUBTRACT;
+ break;
+ case TextureAttributes.COMBINE_INTERPOLATE:
+ GLalphaMode[0] = GL.GL_INTERPOLATE;
+ break;
+ case TextureAttributes.COMBINE_DOT3:
+ // dot3 will only make sense for alpha if rgb is also
+ // doing dot3. So if rgb is not doing dot3, fallback to replace
+ if (combineRgbMode == TextureAttributes.COMBINE_DOT3) {
+ GLrgbMode[0] = GL.GL_DOT3_RGBA;
+ } else {
+ GLalphaMode[0] = GL.GL_REPLACE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ // mapping from java enum to gl enum
+ private static final int[] _gl_combineRgbSrcIndex = {
+ GL.GL_SOURCE0_RGB,
+ GL.GL_SOURCE1_RGB,
+ GL.GL_SOURCE2_RGB,
+ };
+
+ private static final int[] _gl_combineAlphaSrcIndex = {
+ GL.GL_SOURCE0_ALPHA,
+ GL.GL_SOURCE1_ALPHA,
+ GL.GL_SOURCE2_ALPHA,
+ };
+
+ private static final int[] _gl_combineRgbOpIndex = {
+ GL.GL_OPERAND0_RGB,
+ GL.GL_OPERAND1_RGB,
+ GL.GL_OPERAND2_RGB,
+ };
+
+ private static final int[] _gl_combineAlphaOpIndex = {
+ GL.GL_OPERAND0_ALPHA,
+ GL.GL_OPERAND1_ALPHA,
+ GL.GL_OPERAND2_ALPHA,
+ };
+
+ private static final int[] _gl_combineSrc = {
+ GL.GL_PRIMARY_COLOR, // TextureAttributes.COMBINE_OBJECT_COLOR
+ GL.GL_TEXTURE, // TextureAttributes.COMBINE_TEXTURE
+ GL.GL_CONSTANT, // TextureAttributes.COMBINE_CONSTANT_COLOR
+ GL.GL_PREVIOUS, // TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE
+ };
+
+ private static final int[] _gl_combineFcn = {
+ GL.GL_SRC_COLOR, // TextureAttributes.COMBINE_SRC_COLOR
+ GL.GL_ONE_MINUS_SRC_COLOR, // TextureAttributes.COMBINE_ONE_MINUS_SRC_COLOR
+ GL.GL_SRC_ALPHA, // TextureAttributes.COMBINE_SRC_ALPHA
+ GL.GL_ONE_MINUS_SRC_ALPHA, // TextureAttributes.COMBINE_ONE_MINUS_SRC_ALPHA
+ };
+
+ private int getCombinerArg(GL gl, int arg, int textureUnit, int combUnit) {
+ int comb = 0;
+
+ switch (arg) {
+ case TextureAttributes.COMBINE_OBJECT_COLOR:
+ if (combUnit == GL.GL_COMBINER0_NV) {
+ comb = GL.GL_PRIMARY_COLOR_NV;
+ } else {
+ comb = GL.GL_SPARE0_NV;
+ }
+ break;
+ case TextureAttributes.COMBINE_TEXTURE_COLOR:
+ comb = textureUnit;
+ break;
+ case TextureAttributes.COMBINE_CONSTANT_COLOR:
+ comb = GL.GL_CONSTANT_COLOR0_NV;
+ break;
+ case TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE:
+ comb = textureUnit -1;
+ break;
+ }
+
+ return comb;
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureUnitStateRetained methods
+ //
+
+ void updateTextureUnitState(Context ctx, int index, boolean enable) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureUnitState()");
+
+ GL gl = context(ctx).getGL();
+ JoglContext jctx = (JoglContext) ctx;
+
+ if (index >= 0 && gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ gl.glActiveTexture(index + GL.GL_TEXTURE0);
+ gl.glClientActiveTexture(GL.GL_TEXTURE0 + index);
+ if (gl.isExtensionAvailable("GL_NV_register_combiners")) {
+ jctx.setCurrentTextureUnit(index + GL.GL_TEXTURE0);
+ jctx.setCurrentCombinerUnit(index + GL.GL_COMBINER0_NV);
+ gl.glCombinerParameteriNV(GL.GL_NUM_GENERAL_COMBINERS_NV, index + 1);
+ }
+ }
+
+ if (!enable) {
+ // if not enabled, then don't enable any tex mapping
+ gl.glDisable(GL.GL_TEXTURE_1D);
+ gl.glDisable(GL.GL_TEXTURE_2D);
+ gl.glDisable(GL.GL_TEXTURE_3D);
+ gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
+ }
+
+ // if it is enabled, the enable flag will be taken care of
+ // in the bindTexture call
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureRetained methods
+ // Texture2DRetained methods
+ //
+
+ void bindTexture2D(Context ctx, int objectId, boolean enable) {
+ if (VERBOSE) System.err.println("JoglPipeline.bindTexture2D(objectId=" + objectId + ",enable=" + enable + ")");
+
+ GL gl = context(ctx).getGL();
+ gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
+ gl.glDisable(GL.GL_TEXTURE_3D);
+
+ if (!enable) {
+ gl.glDisable(GL.GL_TEXTURE_2D);
+ } else {
+ gl.glBindTexture(GL.GL_TEXTURE_2D, objectId);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ }
+ }
+
+ void updateTexture2DImage(Context ctx,
+ int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int dataType, Object data) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DImage(width=" + width + ",height=" + height + ",level=" + level + ")");
+
+ updateTexture2DImage(ctx, GL.GL_TEXTURE_2D,
+ numLevels, level, textureFormat, imageFormat,
+ width, height, boundaryWidth, dataType, data);
+ }
+
+ void updateTexture2DSubImage(Context ctx,
+ int level, int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int dataType, Object data) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DSubImage()");
+
+ updateTexture2DSubImage(ctx, GL.GL_TEXTURE_2D,
+ level, xoffset, yoffset,
+ textureFormat, imageFormat,
+ imgXOffset, imgYOffset, tilew, width, height,
+ dataType, data);
+ }
+
+ void updateTexture2DLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLOD, float maximumLOD) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DLodRange()");
+
+ updateTextureLodRange(ctx, GL.GL_TEXTURE_2D,
+ baseLevel, maximumLevel,
+ minimumLOD, maximumLOD);
+ }
+
+ void updateTexture2DLodOffset(Context ctx,
+ float lodOffsetS, float lodOffsetT,
+ float lodOffsetR) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DLodOffset()");
+
+ updateTextureLodOffset(ctx, GL.GL_TEXTURE_2D,
+ lodOffsetS, lodOffsetT, lodOffsetR);
+ }
+
+ void updateTexture2DBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DBoundary()");
+
+ updateTextureBoundary(ctx, GL.GL_TEXTURE_2D,
+ boundaryModeS, boundaryModeT, -1,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+ }
+
+ void updateTexture2DFilterModes(Context ctx,
+ int minFilter, int magFilter) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DFilterModes()");
+
+ updateTextureFilterModes(ctx, GL.GL_TEXTURE_2D, minFilter, magFilter);
+ }
+
+ void updateTexture2DSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DSharpenFunc()");
+
+ updateTextureSharpenFunc(ctx, GL.GL_TEXTURE_2D,
+ numSharpenTextureFuncPts, sharpenTextureFuncPts);
+ }
+
+ void updateTexture2DFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DFilter4Func()");
+
+ updateTextureFilter4Func(ctx, GL.GL_TEXTURE_2D,
+ numFilter4FuncPts, filter4FuncPts);
+ }
+
+ void updateTexture2DAnisotropicFilter(Context ctx, float degree) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DAnisotropicFilter()");
+
+ updateTextureAnisotropicFilter(ctx, GL.GL_TEXTURE_2D, degree);
+ }
+
+ private void updateTextureLodRange(Context ctx,
+ int target,
+ int baseLevel, int maximumLevel,
+ float minimumLOD, float maximumLOD) {
+ GL gl = context(ctx).getGL();
+ // checking of the availability of the extension is already done
+ // in the shared code
+ gl.glTexParameteri(target, GL.GL_TEXTURE_BASE_LEVEL, baseLevel);
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAX_LEVEL, maximumLevel);
+ gl.glTexParameterf(target, GL.GL_TEXTURE_MIN_LOD, minimumLOD);
+ gl.glTexParameterf(target, GL.GL_TEXTURE_MAX_LOD, maximumLOD);
+ }
+
+ private void updateTextureLodOffset(Context ctx,
+ int target,
+ float lodOffsetS, float lodOffsetT,
+ float lodOffsetR) {
+ GL gl = context(ctx).getGL();
+ // checking of the availability of the extension is already done
+ // in the shared code
+ gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_S_SGIX, lodOffsetS);
+ gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_T_SGIX, lodOffsetT);
+ gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_R_SGIX, lodOffsetR);
+ }
+
+ private void updateTextureAnisotropicFilter(Context ctx, int target, float degree) {
+ GL gl = context(ctx).getGL();
+ // checking of the availability of anisotropic filter functionality
+ // is already done in the shared code
+ gl.glTexParameterf(target,
+ GL.GL_TEXTURE_MAX_ANISOTROPY_EXT,
+ degree);
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Texture3DRetained methods
+ //
+
+ void bindTexture3D(Context ctx, int objectId, boolean enable) {
+ if (VERBOSE) System.err.println("JoglPipeline.bindTexture3D()");
+
+ GL gl = context(ctx).getGL();
+ // textureCubeMap will take precedure over 3D Texture
+ gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
+
+ if (!enable) {
+ gl.glDisable(GL.GL_TEXTURE_3D);
+ } else {
+ gl.glBindTexture(GL.GL_TEXTURE_3D, objectId);
+ gl.glEnable(GL.GL_TEXTURE_3D);
+ }
+ }
+
+ void updateTexture3DImage(Context ctx,
+ int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height, int depth,
+ int boundaryWidth,
+ int dataType, Object data) {
+
+ /* TODO Chien : Need to support INT, and NIO buffers */
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DImage()");
+
+ GL gl = context(ctx).getGL();
+
+ int format = 0;
+ int internalFormat = 0;
+ int type = GL.GL_UNSIGNED_INT_8_8_8_8;
+ boolean forceAlphaToOne = false;
+
+ // check if we are trying to draw NPOT on a system that doesn't support it
+ boolean textureNonPowerOfTwoAvailable =
+ gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two") ||
+ gl.isExtensionAvailable("GL_VERSION_2_0");
+
+ if (!textureNonPowerOfTwoAvailable &&
+ (!isPowerOfTwo(width) || !isPowerOfTwo(height) || !isPowerOfTwo(depth))) {
+ // disable texture by setting width, height and depth to 0
+ width = height = depth = 0;
+ }
+
+ switch (textureFormat) {
+ case Texture.INTENSITY:
+ internalFormat = GL.GL_INTENSITY;
+ break;
+ case Texture.LUMINANCE:
+ internalFormat = GL.GL_LUMINANCE;
+ break;
+ case Texture.ALPHA:
+ internalFormat = GL.GL_ALPHA;
+ break;
+ case Texture.LUMINANCE_ALPHA:
+ internalFormat = GL.GL_LUMINANCE_ALPHA;
+ break;
+ case Texture.RGB:
+ internalFormat = GL.GL_RGB;
+ break;
+ case Texture.RGBA:
+ internalFormat = GL.GL_RGBA;
+ break;
+ default:
+ assert false;
+ return;
+ }
+
+ if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) ||
+ (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) {
+
+ switch (imageFormat) {
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ format = GL.GL_BGR;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ format = GL.GL_RGB;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here!
+ format = GL.GL_ABGR_EXT;
+ } else {
+ assert false;
+ return;
+ }
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ // all RGB types are stored as RGBA
+ format = GL.GL_RGBA;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ // all LA types are stored as LA8
+ format = GL.GL_LUMINANCE_ALPHA;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ if (internalFormat == GL.GL_ALPHA) {
+ format = GL.GL_ALPHA;
+ } else {
+ format = GL.GL_LUMINANCE;
+ }
+ break;
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_INT_BGR:
+ case ImageComponentRetained.TYPE_INT_RGB:
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ default:
+ assert false;
+ return;
+ }
+
+ gl.glTexImage3D(GL.GL_TEXTURE_3D,
+ level, internalFormat,
+ width, height, depth, boundaryWidth,
+ format, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[]) data));
+
+ } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) ||
+ (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) {
+
+ switch (imageFormat) {
+ /* GL_BGR */
+ case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
+ format = GL.GL_RGBA;
+ type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ forceAlphaToOne = true;
+ break;
+ case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
+ forceAlphaToOne = true;
+ /* Fall through to next case */
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ format = GL.GL_BGRA;
+ type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ /* This method only supports 3 and 4 components formats and INT types. */
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ default:
+ assert false;
+ return;
+ }
+
+ /* Force Alpha to 1.0 if needed */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
+ }
+
+ gl.glTexImage3D(GL.GL_TEXTURE_3D,
+ level, internalFormat,
+ width, height, depth, boundaryWidth,
+ format, type, IntBuffer.wrap((int[]) data));
+
+ /* Restore Alpha scale and bias */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
+ }
+ } else {
+ assert false;
+ }
+ }
+
+ void updateTexture3DSubImage(Context ctx,
+ int level,
+ int xoffset, int yoffset, int zoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset, int imgZOffset,
+ int tilew, int tileh,
+ int width, int height, int depth,
+ int dataType, Object data) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DSubImage()");
+
+ /* TODO Chien : Need to support INT, and NIO buffers */
+ GL gl = context(ctx).getGL();
+
+ int format = 0;
+ int internalFormat = 0;
+ int type = GL.GL_UNSIGNED_INT_8_8_8_8;
+ int numBytes = 0;
+ boolean forceAlphaToOne = false;
+ boolean pixelStore = false;
+
+ if (imgXOffset > 0 || (width < tilew)) {
+ pixelStore = true;
+ gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, tilew);
+ }
+
+ // if NPOT textures are not supported, check if h=w=0, if so we have been
+ // disabled due to a NPOT texture being sent to a context that doesn't
+ // support it: disable the glTexSubImage as well
+ boolean textureNonPowerOfTwoAvailable =
+ gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two") ||
+ gl.isExtensionAvailable("GL_VERSION_2_0");
+
+ if (!textureNonPowerOfTwoAvailable) {
+ int[] tmp = new int[1];
+ int texWidth, texHeight, texDepth;
+ gl.glGetTexLevelParameteriv(GL.GL_TEXTURE_2D, 0, GL.GL_TEXTURE_WIDTH, tmp, 0);
+ texWidth = tmp[0];
+ gl.glGetTexLevelParameteriv(GL.GL_TEXTURE_2D, 0, GL.GL_TEXTURE_HEIGHT, tmp, 0);
+ texHeight = tmp[0];
+ gl.glGetTexLevelParameteriv(GL.GL_TEXTURE_2D, 0, GL.GL_TEXTURE_DEPTH, tmp, 0);
+ texDepth = tmp[0];
+ if ((texWidth == 0) && (texHeight == 0) && (texDepth == 0)) {
+ // disable the sub-image by setting it's width, height and depth to 0
+ width = height = depth = 0;
+ }
+ }
+
+ switch (textureFormat) {
+ case Texture.INTENSITY:
+ internalFormat = GL.GL_INTENSITY;
+ break;
+ case Texture.LUMINANCE:
+ internalFormat = GL.GL_LUMINANCE;
+ break;
+ case Texture.ALPHA:
+ internalFormat = GL.GL_ALPHA;
+ break;
+ case Texture.LUMINANCE_ALPHA:
+ internalFormat = GL.GL_LUMINANCE_ALPHA;
+ break;
+ case Texture.RGB:
+ internalFormat = GL.GL_RGB;
+ break;
+ case Texture.RGBA:
+ internalFormat = GL.GL_RGBA;
+ break;
+ default:
+ assert false;
+ }
+
+ if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) ||
+ (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) {
+
+ switch (imageFormat) {
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ format = GL.GL_BGR;
+ numBytes = 3;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ format = GL.GL_RGB;
+ numBytes = 3;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here!
+ format = GL.GL_ABGR_EXT;
+ numBytes = 4;
+ } else {
+ assert false;
+ return;
+ }
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ // all RGB types are stored as RGBA
+ format = GL.GL_RGBA;
+ numBytes = 4;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ // all LA types are stored as LA8
+ format = GL.GL_LUMINANCE_ALPHA;
+ numBytes = 2;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ if (internalFormat == GL.GL_ALPHA) {
+ format = GL.GL_ALPHA;
+ numBytes = 1;
+ } else {
+ format = GL.GL_LUMINANCE;
+ numBytes = 1;
+ }
+ break;
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_INT_BGR:
+ case ImageComponentRetained.TYPE_INT_RGB:
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ default:
+ assert false;
+ return;
+ }
+
+ ByteBuffer buf = ByteBuffer.wrap((byte[]) data);
+ int offset = (tilew * tileh * imgZOffset +
+ tilew * imgYOffset + imgXOffset) * numBytes;
+ buf.position(offset);
+ gl.glTexSubImage3D(GL.GL_TEXTURE_3D,
+ level, xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, GL.GL_UNSIGNED_BYTE,
+ buf);
+
+ } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) ||
+ (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) {
+
+ switch (imageFormat) {
+ /* GL_BGR */
+ case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
+ format = GL.GL_RGBA;
+ type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ forceAlphaToOne = true;
+ break;
+ case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
+ forceAlphaToOne = true;
+ /* Fall through to next case */
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ format = GL.GL_BGRA;
+ type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ /* This method only supports 3 and 4 components formats and INT types. */
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ default:
+ assert false;
+ return;
+ }
+
+ /* Force Alpha to 1.0 if needed */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
+ }
+
+ IntBuffer buf = IntBuffer.wrap((int[]) data);
+ int offset = tilew * tileh * imgZOffset +
+ tilew * imgYOffset + imgXOffset;
+ buf.position(offset);
+ gl.glTexSubImage3D(GL.GL_TEXTURE_3D,
+ level, xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type,
+ buf);
+
+ /* Restore Alpha scale and bias */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
+ }
+ } else {
+ assert false;
+ return;
+ }
+
+ if (pixelStore) {
+ gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
+ }
+
+ }
+
+
+ void updateTexture3DLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DLodRange()");
+
+ updateTextureLodRange(ctx, GL.GL_TEXTURE_3D,
+ baseLevel, maximumLevel,
+ minimumLod, maximumLod);
+ }
+
+ void updateTexture3DLodOffset(Context ctx,
+ float lodOffsetS, float lodOffsetT,
+ float lodOffsetR) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DLodOffset()");
+
+ updateTextureLodOffset(ctx, GL.GL_TEXTURE_3D,
+ lodOffsetS, lodOffsetT, lodOffsetR);
+ }
+
+ void updateTexture3DBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ int boundaryModeR, float boundaryRed,
+ float boundaryGreen, float boundaryBlue,
+ float boundaryAlpha) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DBoundary()");
+
+ updateTextureBoundary(ctx, GL.GL_TEXTURE_2D,
+ boundaryModeS, boundaryModeT, boundaryModeR,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+ }
+
+ void updateTexture3DFilterModes(Context ctx,
+ int minFilter, int magFilter) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DFilterModes()");
+
+ updateTextureFilterModes(ctx, GL.GL_TEXTURE_3D,
+ minFilter, magFilter);
+ }
+
+ void updateTexture3DSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DSharpenFunc()");
+
+ updateTextureSharpenFunc(ctx, GL.GL_TEXTURE_3D,
+ numSharpenTextureFuncPts, sharpenTextureFuncPts);
+ }
+
+ void updateTexture3DFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DFilter4Func()");
+
+ updateTextureFilter4Func(ctx, GL.GL_TEXTURE_3D,
+ numFilter4FuncPts, filter4FuncPts);
+ }
+
+ void updateTexture3DAnisotropicFilter(Context ctx, float degree) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DAnisotropicFilter()");
+
+ updateTextureAnisotropicFilter(ctx, GL.GL_TEXTURE_3D, degree);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureCubeMapRetained methods
+ //
+
+ void bindTextureCubeMap(Context ctx, int objectId, boolean enable) {
+ if (VERBOSE) System.err.println("JoglPipeline.bindTextureCubeMap()");
+
+ GL gl = context(ctx).getGL();
+ // TextureCubeMap will take precedure over 3D Texture so
+ // there is no need to disable 3D Texture here.
+ if (!enable) {
+ gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
+ } else {
+ gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, objectId);
+ gl.glEnable(GL.GL_TEXTURE_CUBE_MAP);
+ }
+ }
+
+ void updateTextureCubeMapImage(Context ctx,
+ int face, int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int dataType, Object data) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapImage()");
+
+ updateTexture2DImage(ctx, _gl_textureCubeMapFace[face],
+ numLevels, level, textureFormat, imageFormat,
+ width, height, boundaryWidth, dataType, data);
+ }
+
+ void updateTextureCubeMapSubImage(Context ctx,
+ int face, int level, int xoffset, int yoffset,
+ int textureFormat,int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int dataType, Object data) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapSubImage()");
+
+ updateTexture2DSubImage(ctx, _gl_textureCubeMapFace[face],
+ level, xoffset, yoffset, textureFormat,
+ imageFormat, imgXOffset, imgYOffset, tilew,
+ width, height, dataType, data);
+ }
+
+ void updateTextureCubeMapLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapLodRange()");
+
+ updateTextureLodRange(ctx,
+ GL.GL_TEXTURE_CUBE_MAP,
+ baseLevel, maximumLevel,
+ minimumLod, maximumLod);
+ }
+
+ void updateTextureCubeMapLodOffset(Context ctx,
+ float lodOffsetS, float lodOffsetT,
+ float lodOffsetR) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapLodOffset()");
+
+ updateTextureLodOffset(ctx,
+ GL.GL_TEXTURE_CUBE_MAP,
+ lodOffsetS, lodOffsetT, lodOffsetR);
+ }
+
+ void updateTextureCubeMapBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapBoundary()");
+
+ updateTextureBoundary(ctx,
+ GL.GL_TEXTURE_CUBE_MAP,
+ boundaryModeS, boundaryModeT, -1,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+ }
+
+ void updateTextureCubeMapFilterModes(Context ctx,
+ int minFilter, int magFilter) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapFilterModes()");
+
+ updateTextureFilterModes(ctx,
+ GL.GL_TEXTURE_CUBE_MAP,
+ minFilter, magFilter);
+ }
+
+ void updateTextureCubeMapSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapSharpenFunc()");
+
+ updateTextureSharpenFunc(ctx,
+ GL.GL_TEXTURE_CUBE_MAP,
+ numSharpenTextureFuncPts, sharpenTextureFuncPts);
+ }
+
+ void updateTextureCubeMapFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapFilter4Func()");
+
+ updateTextureFilter4Func(ctx,
+ GL.GL_TEXTURE_CUBE_MAP,
+ numFilter4FuncPts, filter4FuncPts);
+ }
+
+ void updateTextureCubeMapAnisotropicFilter(Context ctx, float degree) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapAnisotropicFilter()");
+
+ updateTextureAnisotropicFilter(ctx,
+ GL.GL_TEXTURE_CUBE_MAP,
+ degree);
+ }
+
+ //----------------------------------------------------------------------
+ //
+ // Helper routines for above texture methods
+ //
+
+ private void updateTexture2DImage(Context ctx,
+ int target,
+ int numLevels,
+ int level,
+ int textureFormat,
+ int imageFormat,
+ int width,
+ int height,
+ int boundaryWidth,
+ int dataType,
+ Object data) {
+ GL gl = context(ctx).getGL();
+
+ int format = 0, internalFormat = 0;
+ int type = GL.GL_UNSIGNED_INT_8_8_8_8;
+ boolean forceAlphaToOne = false;
+
+ // check if we are trying to draw NPOT on a system that doesn't support it
+ boolean textureNonPowerOfTwoAvailable =
+ gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two") ||
+ gl.isExtensionAvailable("GL_VERSION_2_0");
+
+ if (!textureNonPowerOfTwoAvailable &&
+ (!isPowerOfTwo(width) || !isPowerOfTwo(height))) {
+ // disable texture by setting width and height to 0
+ width = height = 0;
+ }
+
+ switch (textureFormat) {
+ case Texture.INTENSITY:
+ internalFormat = GL.GL_INTENSITY;
+ break;
+ case Texture.LUMINANCE:
+ internalFormat = GL.GL_LUMINANCE;
+ break;
+ case Texture.ALPHA:
+ internalFormat = GL.GL_ALPHA;
+ break;
+ case Texture.LUMINANCE_ALPHA:
+ internalFormat = GL.GL_LUMINANCE_ALPHA;
+ break;
+ case Texture.RGB:
+ internalFormat = GL.GL_RGB;
+ break;
+ case Texture.RGBA:
+ internalFormat = GL.GL_RGBA;
+ break;
+ default:
+ assert false;
+ }
+
+ if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) ||
+ (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) {
+
+ switch (imageFormat) {
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ format = GL.GL_BGR;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ format = GL.GL_RGB;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here!
+ format = GL.GL_ABGR_EXT;
+ } else {
+ assert false;
+ return;
+ }
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ // all RGB types are stored as RGBA
+ format = GL.GL_RGBA;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ // all LA types are stored as LA8
+ format = GL.GL_LUMINANCE_ALPHA;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ if (internalFormat == GL.GL_ALPHA) {
+ format = GL.GL_ALPHA;
+ } else {
+ format = GL.GL_LUMINANCE;
+ }
+ break;
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_INT_BGR:
+ case ImageComponentRetained.TYPE_INT_RGB:
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ default:
+ assert false;
+ return;
+ }
+
+ gl.glTexImage2D(target, level, internalFormat,
+ width, height, boundaryWidth,
+ format, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[]) data));
+
+ } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) ||
+ (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) {
+
+ switch (imageFormat) {
+ /* GL_BGR */
+ case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
+ format = GL.GL_RGBA;
+ type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ forceAlphaToOne = true;
+ break;
+ case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
+ forceAlphaToOne = true;
+ /* Fall through to next case */
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ format = GL.GL_BGRA;
+ type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ /* This method only supports 3 and 4 components formats and INT types. */
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ default:
+ assert false;
+ return;
+ }
+
+ /* Force Alpha to 1.0 if needed */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
+ }
+
+ gl.glTexImage2D(target, level, internalFormat,
+ width, height, boundaryWidth,
+ format, type, IntBuffer.wrap((int[]) data));
+
+ /* Restore Alpha scale and bias */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
+ }
+ } else {
+ assert false;
+ }
+ }
+
+ private void updateTexture2DSubImage(Context ctx,
+ int target,
+ int level, int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int dataType, Object data) {
+ GL gl = context(ctx).getGL();
+
+ int format = 0, internalFormat=0;
+ int numBytes = 0;
+ int type = GL.GL_UNSIGNED_INT_8_8_8_8;
+ boolean forceAlphaToOne = false;
+ boolean pixelStore = false;
+
+ if (imgXOffset > 0 || (width < tilew)) {
+ pixelStore = true;
+ gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, tilew);
+ }
+
+ // if NPOT textures are not supported, check if h=w=0, if so we have been
+ // disabled due to a NPOT texture being sent to a context that doesn't
+ // support it: disable the glTexSubImage as well
+ boolean textureNonPowerOfTwoAvailable =
+ gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two") ||
+ gl.isExtensionAvailable("GL_VERSION_2_0");
+
+ if (!textureNonPowerOfTwoAvailable) {
+ int[] tmp = new int[1];
+ int texWidth, texHeight;
+ gl.glGetTexLevelParameteriv(GL.GL_TEXTURE_2D, 0, GL.GL_TEXTURE_WIDTH, tmp, 0);
+ texWidth = tmp[0];
+ gl.glGetTexLevelParameteriv(GL.GL_TEXTURE_2D, 0, GL.GL_TEXTURE_HEIGHT, tmp, 0);
+ texHeight = tmp[0];
+ if ((texWidth == 0) && (texHeight == 0)) {
+ // disable the sub-image by setting it's width and height to 0
+ width = height = 0;
+ }
+ }
+
+ switch (textureFormat) {
+ case Texture.INTENSITY:
+ internalFormat = GL.GL_INTENSITY;
+ break;
+ case Texture.LUMINANCE:
+ internalFormat = GL.GL_LUMINANCE;
+ break;
+ case Texture.ALPHA:
+ internalFormat = GL.GL_ALPHA;
+ break;
+ case Texture.LUMINANCE_ALPHA:
+ internalFormat = GL.GL_LUMINANCE_ALPHA;
+ break;
+ case Texture.RGB:
+ internalFormat = GL.GL_RGB;
+ break;
+ case Texture.RGBA:
+ internalFormat = GL.GL_RGBA;
+ break;
+ default:
+ assert false;
+ }
+
+ if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) ||
+ (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) {
+
+ switch (imageFormat) {
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ format = GL.GL_BGR;
+ numBytes = 3;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ format = GL.GL_RGB;
+ numBytes = 3;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here!
+ format = GL.GL_ABGR_EXT;
+ numBytes = 4;
+ } else {
+ assert false;
+ return;
+ }
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ // all RGB types are stored as RGBA
+ format = GL.GL_RGBA;
+ numBytes = 4;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ // all LA types are stored as LA8
+ format = GL.GL_LUMINANCE_ALPHA;
+ numBytes = 2;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ if (internalFormat == GL.GL_ALPHA) {
+ format = GL.GL_ALPHA;
+ numBytes = 1;
+ } else {
+ format = GL.GL_LUMINANCE;
+ numBytes = 1;
+ }
+ break;
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_INT_BGR:
+ case ImageComponentRetained.TYPE_INT_RGB:
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ default:
+ assert false;
+ return;
+ }
+
+ ByteBuffer buf = ByteBuffer.wrap((byte[]) data);
+
+ // offset by the imageOffset
+ buf.position((tilew * imgYOffset + imgXOffset) * numBytes);
+ gl.glTexSubImage2D(target, level, xoffset, yoffset, width, height,
+ format, GL.GL_UNSIGNED_BYTE, buf);
+
+ } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) ||
+ (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) {
+
+ switch (imageFormat) {
+ /* GL_BGR */
+ case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
+ format = GL.GL_RGBA;
+ type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ forceAlphaToOne = true;
+ break;
+ case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
+ forceAlphaToOne = true;
+ /* Fall through to next case */
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ format = GL.GL_BGRA;
+ type = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ /* This method only supports 3 and 4 components formats and INT types. */
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ default:
+ assert false;
+ return;
+ }
+ /* Force Alpha to 1.0 if needed */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
+ }
+
+ IntBuffer buf = IntBuffer.wrap((int[]) data);
+
+ // offset by the imageOffset
+ buf.position(tilew * imgYOffset + imgXOffset);
+ gl.glTexSubImage2D(target, level, xoffset, yoffset, width, height,
+ format, type, buf);
+
+ /* Restore Alpha scale and bias */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
+ }
+ } else {
+ assert false;
+ return;
+ }
+
+ if (pixelStore) {
+ gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
+ }
+
+ }
+
+
+ private static boolean isPowerOfTwo(int val) {
+ return ((val & (val - 1)) == 0);
+ }
+
+ void updateTextureFilterModes(Context ctx,
+ int target,
+ int minFilter,
+ int magFilter) {
+ GL gl = context(ctx).getGL();
+
+ if (EXTRA_DEBUGGING) {
+ System.err.println("minFilter: " + getFilterName(minFilter) +
+ " magFilter: " + getFilterName(magFilter));
+ }
+
+ // FIXME: unclear whether we really need to set up the enum values
+ // in the JoglContext as is done in the native code depending on
+ // extension availability; maybe this is the defined fallback
+ // behavior of the various Java3D modes
+
+ // set texture min filter
+ switch (minFilter) {
+ case Texture.FASTEST:
+ case Texture.BASE_LEVEL_POINT:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ break;
+ case Texture.BASE_LEVEL_LINEAR:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
+ break;
+ case Texture.MULTI_LEVEL_POINT:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER,
+ GL.GL_NEAREST_MIPMAP_NEAREST);
+ break;
+ case Texture.NICEST:
+ case Texture.MULTI_LEVEL_LINEAR:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER,
+ GL.GL_LINEAR_MIPMAP_LINEAR);
+ break;
+ case Texture.FILTER4:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER,
+ GL.GL_FILTER4_SGIS);
+ break;
+ }
+
+ // set texture mag filter
+ switch (magFilter) {
+ case Texture.FASTEST:
+ case Texture.BASE_LEVEL_POINT:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ break;
+ case Texture.NICEST:
+ case Texture.BASE_LEVEL_LINEAR:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
+ break;
+ case Texture.LINEAR_SHARPEN:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
+ GL.GL_LINEAR_SHARPEN_SGIS);
+ break;
+ case Texture.LINEAR_SHARPEN_RGB:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
+ GL.GL_LINEAR_SHARPEN_COLOR_SGIS);
+ break;
+ case Texture.LINEAR_SHARPEN_ALPHA:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
+ GL.GL_LINEAR_SHARPEN_ALPHA_SGIS);
+ break;
+ case Texture2D.LINEAR_DETAIL:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
+ GL.GL_LINEAR_DETAIL_SGIS);
+ break;
+ case Texture2D.LINEAR_DETAIL_RGB:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
+ GL.GL_LINEAR_DETAIL_COLOR_SGIS);
+ break;
+ case Texture2D.LINEAR_DETAIL_ALPHA:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
+ GL.GL_LINEAR_DETAIL_ALPHA_SGIS);
+ break;
+ case Texture.FILTER4:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER,
+ GL.GL_FILTER4_SGIS);
+ break;
+ }
+ }
+
+ void updateTextureBoundary(Context ctx,
+ int target,
+ int boundaryModeS,
+ int boundaryModeT,
+ int boundaryModeR,
+ float boundaryRed,
+ float boundaryGreen,
+ float boundaryBlue,
+ float boundaryAlpha) {
+ GL gl = context(ctx).getGL();
+
+ // set texture wrap parameter
+ switch (boundaryModeS) {
+ case Texture.WRAP:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
+ break;
+ case Texture.CLAMP:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
+ break;
+ case Texture.CLAMP_TO_EDGE:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S,
+ GL.GL_CLAMP_TO_EDGE);
+ break;
+ case Texture.CLAMP_TO_BOUNDARY:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S,
+ GL.GL_CLAMP_TO_BORDER);
+ break;
+ }
+
+ switch (boundaryModeT) {
+ case Texture.WRAP:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
+ break;
+ case Texture.CLAMP:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
+ break;
+ case Texture.CLAMP_TO_EDGE:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T,
+ GL.GL_CLAMP_TO_EDGE);
+ break;
+ case Texture.CLAMP_TO_BOUNDARY:
+ gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T,
+ GL.GL_CLAMP_TO_BORDER);
+ break;
+ }
+
+ // applies to Texture3D only
+ if (boundaryModeR != -1) {
+ switch (boundaryModeR) {
+ case Texture.WRAP:
+ gl.glTexParameteri(target,
+ GL.GL_TEXTURE_WRAP_R, GL.GL_REPEAT);
+ break;
+
+ case Texture.CLAMP:
+ gl.glTexParameteri(target,
+ GL.GL_TEXTURE_WRAP_R, GL.GL_CLAMP);
+ break;
+ case Texture.CLAMP_TO_EDGE:
+ gl.glTexParameteri(target,
+ GL.GL_TEXTURE_WRAP_R,
+ GL.GL_CLAMP_TO_EDGE);
+ break;
+ case Texture.CLAMP_TO_BOUNDARY:
+ gl.glTexParameteri(target,
+ GL.GL_TEXTURE_WRAP_R,
+ GL.GL_CLAMP_TO_BORDER);
+ break;
+ }
+ }
+
+ if (boundaryModeS == Texture.CLAMP ||
+ boundaryModeT == Texture.CLAMP ||
+ boundaryModeR == Texture.CLAMP) {
+ // set texture border color
+ float[] color = new float[4];
+ color[0] = boundaryRed;
+ color[1] = boundaryGreen;
+ color[2] = boundaryBlue;
+ color[3] = boundaryAlpha;
+ gl.glTexParameterfv(target, GL.GL_TEXTURE_BORDER_COLOR, color, 0);
+ }
+ }
+
+ private static final String getFilterName(int filter) {
+ switch (filter) {
+ case Texture.FASTEST:
+ return "Texture.FASTEST";
+ case Texture.NICEST:
+ return "Texture.NICEST";
+ case Texture.BASE_LEVEL_POINT:
+ return "Texture.BASE_LEVEL_POINT";
+ case Texture.BASE_LEVEL_LINEAR:
+ return "Texture.BASE_LEVEL_LINEAR";
+ case Texture.MULTI_LEVEL_POINT:
+ return "Texture.MULTI_LEVEL_POINT";
+ case Texture.MULTI_LEVEL_LINEAR:
+ return "Texture.MULTI_LEVEL_LINEAR";
+ case Texture.FILTER4:
+ return "Texture.FILTER4";
+ case Texture.LINEAR_SHARPEN:
+ return "Texture.LINEAR_SHARPEN";
+ case Texture.LINEAR_SHARPEN_RGB:
+ return "Texture.LINEAR_SHARPEN_RGB";
+ case Texture.LINEAR_SHARPEN_ALPHA:
+ return "Texture.LINEAR_SHARPEN_ALPHA";
+ case Texture2D.LINEAR_DETAIL:
+ return "Texture.LINEAR_DETAIL";
+ case Texture2D.LINEAR_DETAIL_RGB:
+ return "Texture.LINEAR_DETAIL_RGB";
+ case Texture2D.LINEAR_DETAIL_ALPHA:
+ return "Texture.LINEAR_DETAIL_ALPHA";
+ default:
+ return "(unknown)";
+ }
+ }
+
+ private void updateTextureSharpenFunc(Context ctx,
+ int target,
+ int numPts,
+ float[] pts) {
+ // checking of the availability of sharpen texture functionality
+ // is already done in shared code
+ GL gl = context(ctx).getGL();
+ gl.glSharpenTexFuncSGIS(target, numPts, pts, 0);
+ }
+
+ private void updateTextureFilter4Func(Context ctx,
+ int target,
+ int numPts,
+ float[] pts) {
+ // checking of the availability of filter4 functionality
+ // is already done in shared code
+ GL gl = context(ctx).getGL();
+ gl.glTexFilterFuncSGIS(target, GL.GL_FILTER4_SGIS,
+ numPts, pts, 0);
+ }
+
+ // mapping from java enum to gl enum
+ private static final int[] _gl_textureCubeMapFace = {
+ GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+ GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+ GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+ GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+ GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
+ };
+
+ // ---------------------------------------------------------------------
+
+ //
+ // MasterControl methods
+ //
+
+ // Method to return the AWT object
+ long getAWT() {
+ if (VERBOSE) System.err.println("JoglPipeline.getAWT()");
+
+ // FIXME: probably completely unneeded in this implementation,
+ // but should probably remove this dependence in the shared code
+ return 0;
+ }
+
+ // Method to initialize the native J3D library
+ boolean initializeJ3D(boolean disableXinerama) {
+ // Dummy method in JOGL pipeline
+ return true;
+ }
+
+ // Maximum lights supported by the native API
+ int getMaximumLights() {
+ if (VERBOSE) System.err.println("JoglPipeline.getMaximumLights()");
+
+ // FIXME: this isn't quite what the NativePipeline returns but
+ // is probably close enough
+ return 8;
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Canvas3D methods - native wrappers
+ //
+
+ // This is the native method for creating the underlying graphics context.
+ Context createNewContext(Canvas3D cv, long display, Drawable drawable,
+ long fbConfig, Context shareCtx, boolean isSharedCtx,
+ boolean offScreen,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable) {
+ if (VERBOSE) System.err.println("JoglPipeline.createNewContext()");
+ GLDrawable draw = null;
+ GLCapabilitiesChooser indexChooser = null;
+ JoglGraphicsConfiguration config = (JoglGraphicsConfiguration) cv.graphicsConfiguration;
+ if (config.getChosenIndex() >= 0) {
+ indexChooser = new IndexCapabilitiesChooser(config.getChosenIndex());
+ }
+ if (cv.drawable == null) {
+ draw =
+ GLDrawableFactory.getFactory().getGLDrawable(cv,
+ config.getGLCapabilities(),
+ indexChooser);
+ cv.drawable = new JoglDrawable(draw);
+ } else {
+ draw = drawable(cv.drawable);
+ }
+
+ // FIXME: assuming that this only gets called after addNotify has been called
+ draw.setRealized(true);
+ GLContext context = draw.createContext(context(shareCtx));
+
+ // Apparently we are supposed to make the context current at
+ // this point and set up a bunch of properties
+ if (context.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) {
+ throw new IllegalRenderingStateException("Unable to make new context current");
+ }
+
+ GL gl = context.getGL();
+ JoglContext ctx = new JoglContext(context);
+
+ try {
+ if (!getPropertiesFromCurrentContext(ctx)) {
+ throw new IllegalRenderingStateException("Unable to fetch properties from current OpenGL context");
+ }
+
+ if(!isSharedCtx){
+ // Set up fields in Canvas3D
+ setupCanvasProperties(cv, ctx, gl, glslLibraryAvailable, cgLibraryAvailable);
+ }
+
+ // Enable rescale normal
+ gl.glEnable(GL.GL_RESCALE_NORMAL);
+
+ gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE);
+ gl.glDepthFunc(GL.GL_LEQUAL);
+ gl.glEnable(GL.GL_COLOR_MATERIAL);
+ gl.glReadBuffer(GL.GL_FRONT);
+ } finally {
+ context.release();
+ }
+
+ return ctx;
+ }
+
+ void createQueryContext(Canvas3D cv, long display, Drawable drawable,
+ long fbConfig, boolean offScreen, int width, int height,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable) {
+ if (VERBOSE) System.err.println("JoglPipeline.createQueryContext()");
+
+ // FIXME: for now, ignoring the "offscreen" flag -- unclear how
+ // to create an offscreen buffer at this point -- very likely
+ // need Canvas3D.offScreenBufferInfo promoted to an Object --
+ // this logic will need to be revisited to make sure we capture
+ // all of the functionality of the NativePipeline
+
+ Frame f = new Frame();
+ f.setUndecorated(true);
+ f.setLayout(new BorderLayout());
+ GLCapabilities caps = new GLCapabilities();
+ ContextQuerier querier = new ContextQuerier(cv,
+ glslLibraryAvailable,
+ cgLibraryAvailable);
+ // FIXME: should know what GraphicsDevice on which to create
+ // this Canvas / Frame, and this should probably be known from
+ // the incoming "display" parameter
+ QueryCanvas canvas = new QueryCanvas(caps, querier, null);
+ f.add(canvas, BorderLayout.CENTER);
+ f.setSize(MIN_FRAME_SIZE, MIN_FRAME_SIZE);
+ f.setVisible(true);
+ canvas.doQuery();
+ // Attempt to wait for the frame to become visible, but don't block the EDT
+ if (!EventQueue.isDispatchThread()) {
+ synchronized(querier) {
+ if (!querier.done()) {
+ try {
+ querier.wait(WAIT_TIME);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+
+ disposeOnEDT(f);
+ }
+
+ // This is the native for creating an offscreen buffer
+ Drawable createOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, int width, int height) {
+ if (VERBOSE) System.err.println("JoglPipeline.createOffScreenBuffer()");
+
+ // Note 1: when this is called, the incoming Context argument is
+ // null because (obviously) no drawable or context has been
+ // created for the Canvas3D yet.
+
+ // Note 2: we ignore the global j3d.usePbuffer flag; JOGL
+ // doesn't expose pixmap/bitmap surfaces in its public API.
+
+ // First pick up the JoglGraphicsConfiguration and from there
+ // the GLCapabilities from the Canvas3D
+ JoglGraphicsConfiguration jcfg = (JoglGraphicsConfiguration) cv.graphicsConfiguration;
+ // Note that we ignore any chosen index from a prior call to getBestConfiguration();
+ // those only enumerate the on-screen visuals, and we need to find one which is
+ // pbuffer capable
+ GLCapabilities caps = jcfg.getGLCapabilities();
+ if (!GLDrawableFactory.getFactory().canCreateGLPbuffer()) {
+ // FIXME: do anything else here? Throw exception?
+ return null;
+ }
+
+ GLPbuffer pbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, null,
+ width, height, null);
+ return new JoglDrawable(pbuffer);
+ }
+
+ void destroyOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, Drawable drawable) {
+ if (VERBOSE) System.err.println("JoglPipeline.destroyOffScreenBuffer()");
+
+ JoglDrawable jdraw = (JoglDrawable) drawable;
+ GLPbuffer pbuffer = (GLPbuffer) jdraw.getGLDrawable();
+ pbuffer.destroy();
+ }
+
+ // This is the native for reading the image from the offscreen buffer
+ void readOffScreenBuffer(Canvas3D cv, Context ctx, int format, int dataType, Object data, int width, int height) {
+ if (VERBOSE) System.err.println("JoglPipeline.readOffScreenBuffer()");
+
+ GL gl = context(ctx).getGL();
+ gl.glPixelStorei(GL.GL_PACK_ROW_LENGTH, width);
+ gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
+
+ int type = 0;
+ if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) ||
+ (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) {
+
+ switch (format) {
+ // GL_BGR
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ type = GL.GL_BGR;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ type = GL.GL_RGB;
+ break;
+ // GL_ABGR_EXT
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If false, should never come here!
+ type = GL.GL_ABGR_EXT;
+ } else {
+ assert false;
+ return;
+ }
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ type = GL.GL_RGBA;
+ break;
+
+ /* This method only supports 3 and 4 components formats and BYTE types. */
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_INT_BGR:
+ case ImageComponentRetained.TYPE_INT_RGB:
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ default:
+ throw new AssertionError("illegal format " + format);
+ }
+
+ gl.glReadPixels(0, 0, width, height, type, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[]) data));
+
+ } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) ||
+ (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) {
+
+ int intType = GL.GL_UNSIGNED_INT_8_8_8_8;
+ boolean forceAlphaToOne = false;
+
+ switch (format) {
+ /* GL_BGR */
+ case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */
+ type = GL.GL_RGBA;
+ intType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ forceAlphaToOne = true;
+ break;
+ case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */
+ forceAlphaToOne = true;
+ /* Fall through to next case */
+ case ImageComponentRetained.TYPE_INT_ARGB:
+ type = GL.GL_BGRA;
+ intType = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ /* This method only supports 3 and 4 components formats and BYTE types. */
+ case ImageComponentRetained.TYPE_BYTE_LA:
+ case ImageComponentRetained.TYPE_BYTE_GRAY:
+ case ImageComponentRetained.TYPE_USHORT_GRAY:
+ case ImageComponentRetained.TYPE_BYTE_BGR:
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ case ImageComponentRetained.TYPE_BYTE_ABGR:
+ default:
+ throw new AssertionError("illegal format " + format);
+ }
+
+ /* Force Alpha to 1.0 if needed */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 0.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 1.0f);
+ }
+
+ gl.glReadPixels(0, 0, width, height, type, intType, IntBuffer.wrap((int[]) data));
+
+ /* Restore Alpha scale and bias */
+ if(forceAlphaToOne) {
+ gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1.0f);
+ gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0.0f);
+ }
+
+ } else {
+ throw new AssertionError("illegal image data type " + dataType);
+
+ }
+ }
+
+ // The native method for swapBuffers
+ int swapBuffers(Canvas3D cv, Context ctx, long dpy, Drawable drawable) {
+ if (VERBOSE) System.err.println("JoglPipeline.swapBuffers()");
+ GLDrawable draw = drawable(drawable);
+ draw.swapBuffers();
+ return 0;
+ }
+
+ // notify D3D that Canvas is resize
+ int resizeD3DCanvas(Canvas3D cv, Context ctx) {
+ // Dummy method in JOGL pipeline
+ return 0;
+ }
+
+ // notify D3D to toggle between FullScreen and window mode
+ int toggleFullScreenMode(Canvas3D cv, Context ctx) {
+ // Dummy method in JOGL pipeline
+ return 0;
+ }
+
+ // native method for setting Material when no material is present
+ void updateMaterialColor(Context ctx, float r, float g, float b, float a) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateMaterialColor()");
+
+ GL gl = context(ctx).getGL();
+ gl.glColor4f(r, g, b, a);
+ gl.glDisable(GL.GL_LIGHTING);
+ }
+
+ void destroyContext(long display, Drawable drawable, Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.destroyContext()");
+ GLDrawable draw = drawable(drawable);
+ GLContext context = context(ctx);
+ if (GLContext.getCurrent() == context) {
+ context.release();
+ }
+ context.destroy();
+ // FIXME: assuming this is the right point at which to make this call
+ draw.setRealized(false);
+ }
+
+ // This is the native method for doing accumulation.
+ void accum(Context ctx, float value) {
+ if (VERBOSE) System.err.println("JoglPipeline.accum()");
+
+ GL gl = context(ctx).getGL();
+ gl.glReadBuffer(GL.GL_BACK);
+ gl.glAccum(GL.GL_ACCUM, value);
+ gl.glReadBuffer(GL.GL_FRONT);
+ }
+
+ // This is the native method for doing accumulation return.
+ void accumReturn(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.accumReturn()");
+
+ GL gl = context(ctx).getGL();
+ gl.glAccum(GL.GL_RETURN, 1.0f);
+ }
+
+ // This is the native method for clearing the accumulation buffer.
+ void clearAccum(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.clearAccum()");
+
+ GL gl = context(ctx).getGL();
+ gl.glClear(GL.GL_ACCUM_BUFFER_BIT);
+ }
+
+ // This is the native method for getting the number of lights the underlying
+ // native library can support.
+ int getNumCtxLights(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.getNumCtxLights()");
+
+ GL gl = context(ctx).getGL();
+ int[] res = new int[1];
+ gl.glGetIntegerv(GL.GL_MAX_LIGHTS, res, 0);
+ return res[0];
+ }
+
+ // Native method for decal 1st child setup
+ boolean decal1stChildSetup(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.decal1stChildSetup()");
+
+ GL gl = context(ctx).getGL();
+ gl.glEnable(GL.GL_STENCIL_TEST);
+ gl.glClearStencil(0x0);
+ gl.glClear(GL.GL_STENCIL_BUFFER_BIT);
+ gl.glStencilFunc(GL.GL_ALWAYS, 0x1, 0x1);
+ gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_REPLACE);
+ if (gl.glIsEnabled(GL.GL_DEPTH_TEST))
+ return true;
+ else
+ return false;
+ }
+
+ // Native method for decal nth child setup
+ void decalNthChildSetup(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.decalNthChildSetup()");
+
+ GL gl = context(ctx).getGL();
+ gl.glDisable(GL.GL_DEPTH_TEST);
+ gl.glStencilFunc(GL.GL_EQUAL, 0x1, 0x1);
+ gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP);
+ }
+
+ // Native method for decal reset
+ void decalReset(Context ctx, boolean depthBufferEnable) {
+ if (VERBOSE) System.err.println("JoglPipeline.decalReset()");
+
+ GL gl = context(ctx).getGL();
+ gl.glDisable(GL.GL_STENCIL_TEST);
+ if (depthBufferEnable)
+ gl.glEnable(GL.GL_DEPTH_TEST);
+ }
+
+ // Native method for eye lighting
+ void ctxUpdateEyeLightingEnable(Context ctx, boolean localEyeLightingEnable) {
+ if (VERBOSE) System.err.println("JoglPipeline.ctxUpdateEyeLightingEnable()");
+
+ GL gl = context(ctx).getGL();
+
+ if (localEyeLightingEnable) {
+ gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, GL.GL_TRUE);
+ } else {
+ gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, GL.GL_FALSE);
+ }
+ }
+
+ // The following three methods are used in multi-pass case
+
+ // native method for setting blend color
+ void setBlendColor(Context ctx, float red, float green,
+ float blue, float alpha) {
+ if (VERBOSE) System.err.println("JoglPipeline.setBlendColor()");
+
+ GL gl = context(ctx).getGL();
+ if (gl.isExtensionAvailable("GL_ARB_imaging")) {
+ gl.glBlendColor(red, green, blue, alpha);
+ }
+ }
+
+ // native method for setting blend func
+ void setBlendFunc(Context ctx, int srcBlendFunction, int dstBlendFunction) {
+ if (VERBOSE) System.err.println("JoglPipeline.setBlendFunc()");
+
+ GL gl = context(ctx).getGL();
+ gl.glEnable(GL.GL_BLEND);
+ gl.glBlendFunc(blendFunctionTable[srcBlendFunction],
+ blendFunctionTable[dstBlendFunction]);
+ }
+
+ // native method for setting fog enable flag
+ void setFogEnableFlag(Context ctx, boolean enable) {
+ if (VERBOSE) System.err.println("JoglPipeline.setFogEnableFlag()");
+
+ GL gl = context(ctx).getGL();
+
+ if (enable)
+ gl.glEnable(GL.GL_FOG);
+ else
+ gl.glDisable(GL.GL_FOG);
+ }
+
+ // Setup the full scene antialising in D3D and ogl when GL_ARB_multisamle supported
+ void setFullSceneAntialiasing(Context absCtx, boolean enable) {
+ if (VERBOSE) System.err.println("JoglPipeline.setFullSceneAntialiasing()");
+
+ JoglContext ctx = (JoglContext) absCtx;
+ GL gl = context(ctx).getGL();
+ if (ctx.getHasMultisample() && !VirtualUniverse.mc.implicitAntialiasing) {
+ if (enable) {
+ gl.glEnable(GL.GL_MULTISAMPLE);
+ } else {
+ gl.glDisable(GL.GL_MULTISAMPLE);
+ }
+ }
+ }
+
+ void setGlobalAlpha(Context ctx, float alpha) {
+ if (VERBOSE) System.err.println("JoglPipeline.setGlobalAlpha()");
+
+ GL gl = context(ctx).getGL();
+ if (gl.isExtensionAvailable("GL_SUN_global_alpha")) {
+ gl.glEnable(GL.GL_GLOBAL_ALPHA_SUN);
+ gl.glGlobalAlphaFactorfSUN(alpha);
+ }
+ }
+
+ // Native method to update separate specular color control
+ void updateSeparateSpecularColorEnable(Context ctx, boolean enable) {
+ if (VERBOSE) System.err.println("JoglPipeline.updateSeparateSpecularColorEnable()");
+
+ GL gl = context(ctx).getGL();
+
+ if (enable) {
+ gl.glLightModeli(GL.GL_LIGHT_MODEL_COLOR_CONTROL, GL.GL_SEPARATE_SPECULAR_COLOR);
+ } else {
+ gl.glLightModeli(GL.GL_LIGHT_MODEL_COLOR_CONTROL, GL.GL_SINGLE_COLOR);
+ }
+ }
+
+ // Initialization for D3D when scene begins and ends
+ void beginScene(Context ctx) {
+ }
+ void endScene(Context ctx) {
+ }
+
+ // True under Solaris,
+ // False under windows when display mode <= 8 bit
+ boolean validGraphicsMode() {
+ if (VERBOSE) System.err.println("JoglPipeline.validGraphicsMode()");
+
+ // FIXME: believe this should do exactly what the native code
+ // used to, but not 100% sure (also in theory should only run
+ // this code on the Windows platform? What about Mac OS X?)
+ DisplayMode currentMode =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode();
+ // Note: on X11 platforms, a bit depth < 0 simply indicates that
+ // multiple visuals are supported on the current display mode
+
+ if (VERBOSE) System.err.println(" Returning " + (currentMode.getBitDepth() < 0 ||
+ currentMode.getBitDepth() > 8));
+
+ return (currentMode.getBitDepth() < 0 ||
+ currentMode.getBitDepth() > 8);
+ }
+
+ // native method for setting light enables
+ void setLightEnables(Context ctx, long enableMask, int maxLights) {
+ if (VERBOSE) System.err.println("JoglPipeline.setLightEnables()");
+
+ GL gl = context(ctx).getGL();
+
+ for (int i = 0; i < maxLights; i++) {
+ if ((enableMask & (1 << i)) != 0) {
+ gl.glEnable(GL.GL_LIGHT0 + i);
+ } else {
+ gl.glDisable(GL.GL_LIGHT0 + i);
+ }
+ }
+ }
+
+ // native method for setting scene ambient
+ void setSceneAmbient(Context ctx, float red, float green, float blue) {
+ if (VERBOSE) System.err.println("JoglPipeline.setSceneAmbient()");
+
+ GL gl = context(ctx).getGL();
+
+ float[] color = new float[4];
+ color[0] = red;
+ color[1] = green;
+ color[2] = blue;
+ color[3] = 1.0f;
+ gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, color, 0);
+ }
+
+ // native method for disabling fog
+ void disableFog(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.disableFog()");
+
+ GL gl = context(ctx).getGL();
+ gl.glDisable(GL.GL_FOG);
+ }
+
+ // native method for disabling modelClip
+ void disableModelClip(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.disableModelClip()");
+
+ GL gl = context(ctx).getGL();
+
+ gl.glDisable(GL.GL_CLIP_PLANE0);
+ gl.glDisable(GL.GL_CLIP_PLANE1);
+ gl.glDisable(GL.GL_CLIP_PLANE2);
+ gl.glDisable(GL.GL_CLIP_PLANE3);
+ gl.glDisable(GL.GL_CLIP_PLANE4);
+ gl.glDisable(GL.GL_CLIP_PLANE5);
+ }
+
+ // native method for setting default RenderingAttributes
+ void resetRenderingAttributes(Context ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride) {
+ if (VERBOSE) System.err.println("JoglPipeline.resetRenderingAttributes()");
+
+ GL gl = context(ctx).getGL();
+
+ if (!depthBufferWriteEnableOverride) {
+ gl.glDepthMask(true);
+ }
+ if (!depthBufferEnableOverride) {
+ gl.glEnable(GL.GL_DEPTH_TEST);
+ }
+ gl.glAlphaFunc(GL.GL_ALWAYS, 0.0f);
+ gl.glDepthFunc(GL.GL_LEQUAL);
+ gl.glEnable(GL.GL_COLOR_MATERIAL);
+ gl.glDisable(GL.GL_COLOR_LOGIC_OP);
+ }
+
+ // native method for setting default texture
+ void resetTextureNative(Context ctx, int texUnitIndex) {
+ if (VERBOSE) System.err.println("JoglPipeline.resetTextureNative()");
+
+ GL gl = context(ctx).getGL();
+ if (texUnitIndex >= 0 &&
+ gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ gl.glActiveTexture(texUnitIndex + GL.GL_TEXTURE0);
+ gl.glClientActiveTexture(texUnitIndex + GL.GL_TEXTURE0);
+ }
+
+ gl.glDisable(GL.GL_TEXTURE_1D);
+ gl.glDisable(GL.GL_TEXTURE_2D);
+ gl.glDisable(GL.GL_TEXTURE_3D);
+ gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
+ }
+
+ // native method for activating a particular texture unit
+ void activeTextureUnit(Context ctx, int texUnitIndex) {
+ if (VERBOSE) System.err.println("JoglPipeline.activeTextureUnit()");
+
+ GL gl = context(ctx).getGL();
+ if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ gl.glActiveTexture(texUnitIndex + GL.GL_TEXTURE0);
+ gl.glClientActiveTexture(texUnitIndex + GL.GL_TEXTURE0);
+ }
+ }
+
+ // native method for setting default TexCoordGeneration
+ void resetTexCoordGeneration(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.resetTexCoordGeneration()");
+
+ GL gl = context(ctx).getGL();
+ gl.glDisable(GL.GL_TEXTURE_GEN_S);
+ gl.glDisable(GL.GL_TEXTURE_GEN_T);
+ gl.glDisable(GL.GL_TEXTURE_GEN_R);
+ gl.glDisable(GL.GL_TEXTURE_GEN_Q);
+ }
+
+ // native method for setting default TextureAttributes
+ void resetTextureAttributes(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.resetTextureAttributes()");
+
+ GL gl = context(ctx).getGL();
+
+ float[] color = new float[4];
+
+ gl.glPushAttrib(GL.GL_TRANSFORM_BIT);
+ gl.glMatrixMode(GL.GL_TEXTURE);
+ gl.glLoadIdentity();
+ gl.glPopAttrib();
+ gl.glTexEnvfv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_COLOR, color, 0);
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
+ gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
+
+ if (gl.isExtensionAvailable("GL_NV_register_combiners")) {
+ gl.glDisable(GL.GL_REGISTER_COMBINERS_NV);
+ }
+
+ if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) {
+ gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI);
+ }
+ }
+
+ // native method for setting default PolygonAttributes
+ void resetPolygonAttributes(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.resetPolygonAttributes()");
+
+ GL gl = context(ctx).getGL();
+
+ gl.glCullFace(GL.GL_BACK);
+ gl.glEnable(GL.GL_CULL_FACE);
+
+ gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_FALSE);
+
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
+
+ gl.glPolygonOffset(0.0f, 0.0f);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_POINT);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_LINE);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
+ }
+
+ // native method for setting default LineAttributes
+ void resetLineAttributes(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.resetLineAttributes()");
+
+ GL gl = context(ctx).getGL();
+ gl.glLineWidth(1.0f);
+ gl.glDisable(GL.GL_LINE_STIPPLE);
+
+ // XXXX: Polygon Mode check, blend enable
+ gl.glDisable(GL.GL_LINE_SMOOTH);
+ }
+
+ // native method for setting default PointAttributes
+ void resetPointAttributes(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.resetPointAttributes()");
+
+ GL gl = context(ctx).getGL();
+ gl.glPointSize(1.0f);
+
+ // XXXX: Polygon Mode check, blend enable
+ gl.glDisable(GL.GL_POINT_SMOOTH);
+ }
+
+ // native method for setting default TransparencyAttributes
+ void resetTransparency(Context ctx, int geometryType,
+ int polygonMode, boolean lineAA,
+ boolean pointAA) {
+ if (VERBOSE) System.err.println("JoglPipeline.resetTransparency()");
+
+ GL gl = context(ctx).getGL();
+
+ if (((((geometryType & RenderMolecule.LINE) != 0) ||
+ (polygonMode == PolygonAttributes.POLYGON_LINE))
+ && lineAA) ||
+ ((((geometryType & RenderMolecule.POINT) != 0) ||
+ (polygonMode == PolygonAttributes.POLYGON_POINT))
+ && pointAA)) {
+ gl.glEnable(GL.GL_BLEND);
+ gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
+ } else {
+ gl.glDisable(GL.GL_BLEND);
+ }
+ gl.glDisable(GL.GL_POLYGON_STIPPLE);
+ }
+
+ // native method for setting default ColoringAttributes
+ void resetColoringAttributes(Context ctx,
+ float r, float g,
+ float b, float a,
+ boolean enableLight) {
+ if (VERBOSE) System.err.println("JoglPipeline.resetColoringAttributes()");
+
+ GL gl = context(ctx).getGL();
+
+ if (!enableLight) {
+ gl.glColor4f(r, g, b, a);
+ }
+ gl.glShadeModel(GL.GL_SMOOTH);
+ }
+
+ /**
+ * This native method makes sure that the rendering for this canvas
+ * gets done now.
+ */
+ void syncRender(Context ctx, boolean wait) {
+ if (VERBOSE) System.err.println("JoglPipeline.syncRender()");
+
+ GL gl = context(ctx).getGL();
+
+ if (wait)
+ gl.glFinish();
+ else
+ gl.glFlush();
+ }
+
+ // The native method that sets this ctx to be the current one
+ boolean useCtx(Context ctx, long display, Drawable drawable) {
+ if (VERBOSE) System.err.println("JoglPipeline.useCtx()");
+ GLContext context = context(ctx);
+ int res = context.makeCurrent();
+ return (res != GLContext.CONTEXT_NOT_CURRENT);
+ }
+
+ // Optionally release the context. Returns true if the context was released.
+ boolean releaseCtx(Context ctx, long dpy) {
+ if (VERBOSE) System.err.println("JoglPipeline.releaseCtx()");
+ GLContext context = context(ctx);
+ context.release();
+ return true;
+ }
+
+ void clear(Context ctx, float r, float g, float b) {
+ if (VERBOSE) System.err.println("JoglPipeline.clear()");
+
+ JoglContext jctx = (JoglContext) ctx;
+ GLContext context = context(ctx);
+ GL gl = context.getGL();
+ gl.glClearColor(r, g, b, jctx.getAlphaClearValue());
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT);
+
+ // Java 3D always clears the Z-buffer
+ gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT);
+ gl.glDepthMask(true);
+ gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
+ gl.glPopAttrib();
+
+ }
+
+ void textureFillBackground(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY) {
+ if (VERBOSE) System.err.println("JoglPipeline.textureFillBackground()");
+
+ GLContext context = context(ctx);
+ GL gl = context.getGL();
+
+ // Temporarily disable fragment and most 3D operations
+ gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_TEXTURE_BIT | GL.GL_POLYGON_BIT);
+
+ disableAttribFor2D(gl);
+ gl.glDepthMask(false);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+
+ // reset the polygon mode
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
+
+ gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
+
+ // load identity modelview and projection matrix
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glMatrixMode(GL.GL_TEXTURE);
+ gl.glPushMatrix();
+ gl.glLoadIdentity();
+
+ gl.glBegin(GL.GL_QUADS);
+ gl.glTexCoord2f(texMinU, texMinV); gl.glVertex2f(mapMinX,mapMinY);
+ gl.glTexCoord2f(texMaxU, texMinV); gl.glVertex2f(mapMaxX,mapMinY);
+ gl.glTexCoord2f(texMaxU, texMaxV); gl.glVertex2f(mapMaxX,mapMaxY);
+ gl.glTexCoord2f(texMinU, texMaxV); gl.glVertex2f(mapMinX,mapMaxY);
+ gl.glEnd();
+
+ // Restore texture Matrix transform
+ gl.glPopMatrix();
+
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ // Restore attributes
+ gl.glPopAttrib();
+
+ }
+
+ void textureFillRaster(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, float mapZ, float alpha) {
+ if (VERBOSE) System.err.println("JoglPipeline.textureFillRaster()");
+
+ GLContext context = context(ctx);
+ GL gl = context.getGL();
+
+ // Temporarily disable fragment and most 3D operations
+ gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_TEXTURE_BIT | GL.GL_POLYGON_BIT |
+ GL.GL_CURRENT_BIT );
+
+ disableAttribForRaster(gl);
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
+ gl.glColor4f(1.0f, 1.0f, 1.0f, alpha);
+
+ // reset the polygon mode
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
+
+ gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
+
+ // load identity modelview and projection matrix
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glPushMatrix();
+ gl.glLoadIdentity();
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ gl.glPushMatrix();
+ gl.glLoadIdentity();
+ gl.glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
+
+ gl.glBegin(GL.GL_QUADS);
+ gl.glTexCoord2f(texMinU, texMinV); gl.glVertex3f(mapMinX,mapMinY, mapZ);
+ gl.glTexCoord2f(texMaxU, texMinV); gl.glVertex3f(mapMaxX,mapMinY, mapZ);
+ gl.glTexCoord2f(texMaxU, texMaxV); gl.glVertex3f(mapMaxX,mapMaxY, mapZ);
+ gl.glTexCoord2f(texMinU, texMaxV); gl.glVertex3f(mapMinX,mapMaxY, mapZ);
+ gl.glEnd();
+
+ // Restore matrices
+ gl.glPopMatrix();
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glPopMatrix();
+ // Restore attributes
+ gl.glPopAttrib();
+
+ }
+
+ void executeRasterDepth(Context ctx, float posX, float posY, float posZ,
+ int srcOffsetX, int srcOffsetY, int rasterWidth, int rasterHeight,
+ int depthWidth, int depthHeight, int depthFormat, Object depthData) {
+ if (VERBOSE) System.err.println("JoglPipeline.executeRasterDepth()");
+ GLContext context = context(ctx);
+ GL gl = context.getGL();
+
+
+ gl.glRasterPos3f(posX, posY, posZ);
+
+ int[] drawBuf = new int[1];
+ gl.glGetIntegerv(GL.GL_DRAW_BUFFER, drawBuf, 0);
+ /* disable draw buffer */
+ gl.glDrawBuffer(GL.GL_NONE);
+
+ /*
+ * raster position is upper left corner, default for Java3D
+ * ImageComponent currently has the data reverse in Y
+ */
+ gl.glPixelZoom(1.0f, -1.0f);
+ gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, depthWidth);
+ if (srcOffsetX >= 0) {
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, srcOffsetX);
+ if (srcOffsetX + rasterWidth > depthWidth) {
+ rasterWidth = depthWidth - srcOffsetX;
+ }
+ } else {
+ rasterWidth += srcOffsetX;
+ if (rasterWidth > depthWidth) {
+ rasterWidth = depthWidth;
+ }
+ }
+ if (srcOffsetY >= 0) {
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, srcOffsetY);
+ if (srcOffsetY + rasterHeight > rasterHeight) {
+ rasterHeight = rasterHeight - srcOffsetY;
+ }
+ } else {
+ rasterHeight += srcOffsetY;
+ if (rasterHeight > rasterHeight) {
+ rasterHeight = rasterHeight;
+ }
+ }
+
+
+ if (depthFormat == DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT) {
+ gl.glDrawPixels(rasterWidth, rasterHeight, GL.GL_DEPTH_COMPONENT,
+ GL.GL_UNSIGNED_INT, IntBuffer.wrap((int[]) depthData));
+ } else { /* DepthComponentRetained.DEPTH_COMPONENT_TYPE_FLOAT */
+ gl.glDrawPixels(rasterWidth, rasterHeight, GL.GL_DEPTH_COMPONENT,
+ GL.GL_FLOAT, FloatBuffer.wrap((float[]) depthData));
+ }
+
+ /* re-enable draw buffer */
+ gl.glDrawBuffer(drawBuf[0]);
+
+ gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, 0);
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, 0);
+
+ }
+
+ // The native method for setting the ModelView matrix.
+ void setModelViewMatrix(Context ctx, double[] viewMatrix, double[] modelMatrix) {
+ if (VERBOSE) System.err.println("JoglPipeline.setModelViewMatrix()");
+ GLContext context = context(ctx);
+ GL gl = context.getGL();
+
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+
+ if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ gl.glLoadTransposeMatrixd(viewMatrix, 0);
+ gl.glMultTransposeMatrixd(modelMatrix, 0);
+ } else {
+ double[] v = new double[16];
+ double[] m = new double[16];
+ copyTranspose(viewMatrix, v);
+ copyTranspose(modelMatrix, m);
+ gl.glLoadMatrixd(v, 0);
+ gl.glMultMatrixd(m, 0);
+ }
+ }
+
+ // The native method for setting the Projection matrix.
+ void setProjectionMatrix(Context ctx, double[] projMatrix) {
+ if (VERBOSE) System.err.println("JoglPipeline.setProjectionMatrix()");
+ GLContext context = context(ctx);
+ GL gl = context.getGL();
+
+ gl.glMatrixMode(GL.GL_PROJECTION);
+
+ if (gl.isExtensionAvailable("GL_VERSION_1_3")) {
+ // Invert the Z value in clipping coordinates because OpenGL uses
+ // left-handed clipping coordinates, while Java3D defines right-handed
+ // coordinates everywhere.
+ projMatrix[8] *= -1.0;
+ projMatrix[9] *= -1.0;
+ projMatrix[10] *= -1.0;
+ projMatrix[11] *= -1.0;
+ gl.glLoadTransposeMatrixd(projMatrix, 0);
+ projMatrix[8] *= -1.0;
+ projMatrix[9] *= -1.0;
+ projMatrix[10] *= -1.0;
+ projMatrix[11] *= -1.0;
+ } else {
+ double[] p = new double[16];
+ copyTranspose(projMatrix, p);
+ // Invert the Z value in clipping coordinates because OpenGL uses
+ // left-handed clipping coordinates, while Java3D defines right-handed
+ // coordinates everywhere.
+ p[2] *= -1.0;
+ p[6] *= -1.0;
+ p[10] *= -1.0;
+ p[14] *= -1.0;
+ gl.glLoadMatrixd(p, 0);
+ }
+ }
+
+ // The native method for setting the Viewport.
+ void setViewport(Context ctx, int x, int y, int width, int height) {
+ if (VERBOSE) System.err.println("JoglPipeline.setViewport()");
+ GL gl = context(ctx).getGL();
+ gl.glViewport(x, y, width, height);
+ }
+
+ // used for display Lists
+ void newDisplayList(Context ctx, int displayListId) {
+ if (VERBOSE) System.err.println("JoglPipeline.newDisplayList()");
+ if (displayListId <= 0) {
+ System.err.println("JAVA 3D ERROR : glNewList(" + displayListId + ") -- IGNORED");
+ }
+
+ GL gl = context(ctx).getGL();
+ gl.glNewList(displayListId, GL.GL_COMPILE);
+ }
+
+ void endDisplayList(Context ctx) {
+ if (VERBOSE) System.err.println("JoglPipeline.endDisplayList()");
+ GL gl = context(ctx).getGL();
+ gl.glEndList();
+ }
+
+ int numInvalidLists = 0;
+ void callDisplayList(Context ctx, int id, boolean isNonUniformScale) {
+ if (VERBOSE) System.err.println("JoglPipeline.callDisplayList()");
+ if (id <= 0) {
+ if (numInvalidLists < 3) {
+ ++numInvalidLists;
+ System.err.println("JAVA 3D ERROR : glCallList(" + id + ") -- IGNORED");
+ } else if (numInvalidLists == 3) {
+ ++numInvalidLists;
+ System.err.println("JAVA 3D : further glCallList error messages discarded");
+ }
+ return;
+ }
+
+ GL gl = context(ctx).getGL();
+ // Set normalization if non-uniform scale
+ if (isNonUniformScale) {
+ gl.glEnable(GL.GL_NORMALIZE);
+ }
+
+ gl.glCallList(id);
+
+ // Turn normalization back off
+ if (isNonUniformScale) {
+ gl.glDisable(GL.GL_NORMALIZE);
+ }
+ }
+
+ void freeDisplayList(Context ctx, int id) {
+ if (VERBOSE) System.err.println("JoglPipeline.freeDisplayList()");
+ if (id <= 0) {
+ System.err.println("JAVA 3D ERROR : glDeleteLists(" + id + ",1) -- IGNORED");
+ }
+
+ GL gl = context(ctx).getGL();
+ gl.glDeleteLists(id, 1);
+ }
+ void freeTexture(Context ctx, int id) {
+ if (VERBOSE) System.err.println("JoglPipeline.freeTexture()");
+
+ GL gl = context(ctx).getGL();
+
+ if (id > 0) {
+ int[] tmp = new int[1];
+ tmp[0] = id;
+ gl.glDeleteTextures(1, tmp, 0);
+ } else {
+ System.err.println("tried to delete tex with texid <= 0");
+ }
+ }
+
+
+ void texturemapping(Context ctx,
+ int px, int py,
+ int minX, int minY, int maxX, int maxY,
+ int texWidth, int texHeight,
+ int rasWidth,
+ int format, int objectId,
+ byte[] imageYdown,
+ int winWidth, int winHeight) {
+ if (VERBOSE) System.err.println("JoglPipeline.texturemapping()");
+
+ GL gl = context(ctx).getGL();
+
+ int glType = GL.GL_RGBA;
+
+ // Temporarily disable fragment and most 3D operations
+ gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_TEXTURE_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_POLYGON_BIT);
+ disableAttribFor2D(gl);
+
+ // Reset the polygon mode
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
+
+ gl.glDepthMask(false);
+ gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, objectId);
+ // set up texture parameter
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
+
+ gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
+ gl.glEnable(GL.GL_BLEND);
+ gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
+
+ gl.glEnable(GL.GL_TEXTURE_2D);
+
+ // loaded identity modelview and projection matrix
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ gl.glLoadIdentity();
+
+ gl.glOrtho(0.0, winWidth, 0.0, winHeight, 0.0, 0.0);
+
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glLoadIdentity();
+
+ if (gl.isExtensionAvailable("GL_EXT_abgr")) {
+ glType = GL.GL_ABGR_EXT;
+ } else {
+ switch (format) {
+ case ImageComponentRetained.TYPE_BYTE_RGBA:
+ glType = GL.GL_RGBA;
+ break;
+ case ImageComponentRetained.TYPE_BYTE_RGB:
+ glType = GL.GL_RGB;
+ break;
+ }
+ }
+ gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, rasWidth);
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, minX);
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, minY);
+ gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, minX, minY,
+ maxX - minX, maxY - minY,
+ glType, GL.GL_UNSIGNED_BYTE,
+ ByteBuffer.wrap(imageYdown));
+ gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, 0);
+ gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, 0);
+
+ float texMinU = (float) minX/ (float) texWidth;
+ float texMinV = (float) minY/ (float) texHeight;
+ float texMaxU = (float) maxX/ (float) texWidth;
+ float texMaxV = (float) maxY/ (float) texHeight;
+ float halfWidth = (float)winWidth/2.0f;
+ float halfHeight = (float)winHeight/2.0f;
+
+ float mapMinX = (float) (((px + minX)- halfWidth)/halfWidth);
+ float mapMinY = (float) ((halfHeight - (py + maxY))/halfHeight);
+ float mapMaxX = (float) ((px + maxX - halfWidth)/halfWidth);
+ float mapMaxY = (float) ((halfHeight - (py + minY))/halfHeight);
+
+ gl.glBegin(GL.GL_QUADS);
+
+ gl.glTexCoord2f(texMinU, texMaxV); gl.glVertex2f(mapMinX,mapMinY);
+ gl.glTexCoord2f(texMaxU, texMaxV); gl.glVertex2f(mapMaxX,mapMinY);
+ gl.glTexCoord2f(texMaxU, texMinV); gl.glVertex2f(mapMaxX,mapMaxY);
+ gl.glTexCoord2f(texMinU, texMinV); gl.glVertex2f(mapMinX,mapMaxY);
+ gl.glEnd();
+
+ // Java 3D always clears the Z-buffer
+ gl.glDepthMask(true);
+ gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
+ gl.glPopAttrib();
+ }
+
+ boolean initTexturemapping(Context ctx, int texWidth,
+ int texHeight, int objectId) {
+ if (VERBOSE) System.err.println("JoglPipeline.initTexturemapping()");
+
+ GL gl = context(ctx).getGL();
+
+ int glType = (gl.isExtensionAvailable("GL_EXT_abgr") ? GL.GL_ABGR_EXT : GL.GL_RGBA);
+
+ gl.glBindTexture(GL.GL_TEXTURE_2D, objectId);
+
+ gl.glTexImage2D(GL.GL_PROXY_TEXTURE_2D, 0, GL.GL_RGBA, texWidth,
+ texHeight, 0, glType, GL.GL_UNSIGNED_BYTE, null);
+
+ int[] width = new int[1];
+ gl.glGetTexLevelParameteriv(GL.GL_PROXY_TEXTURE_2D, 0,
+ GL.GL_TEXTURE_WIDTH, width, 0);
+
+ if (width[0] <= 0) {
+ return false;
+ }
+
+ // init texture size only without filling the pixels
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, texWidth,
+ texHeight, 0, glType, GL.GL_UNSIGNED_BYTE, null);
+
+ return true;
+ }
+
+
+ // Set internal render mode to one of FIELD_ALL, FIELD_LEFT or
+ // FIELD_RIGHT. Note that it is up to the caller to ensure that
+ // stereo is available before setting the mode to FIELD_LEFT or
+ // FIELD_RIGHT. The boolean isTRUE for double buffered mode, FALSE
+ // foe single buffering.
+ void setRenderMode(Context ctx, int mode, boolean doubleBuffer) {
+ if (VERBOSE) System.err.println("JoglPipeline.setRenderMode()");
+
+ GL gl = context(ctx).getGL();
+ int drawBuf = 0;
+ if (doubleBuffer) {
+ drawBuf = GL.GL_BACK;
+ switch (mode) {
+ case Canvas3D.FIELD_LEFT:
+ drawBuf = GL.GL_BACK_LEFT;
+ break;
+ case Canvas3D.FIELD_RIGHT:
+ drawBuf = GL.GL_BACK_RIGHT;
+ break;
+ case Canvas3D.FIELD_ALL:
+ drawBuf = GL.GL_BACK;
+ break;
+ }
+ } else {
+ drawBuf = GL.GL_FRONT;
+ switch (mode) {
+ case Canvas3D.FIELD_LEFT:
+ drawBuf = GL.GL_FRONT_LEFT;
+ break;
+ case Canvas3D.FIELD_RIGHT:
+ drawBuf = GL.GL_FRONT_RIGHT;
+ break;
+ case Canvas3D.FIELD_ALL:
+ drawBuf = GL.GL_FRONT;
+ break;
+ }
+ }
+
+ gl.glDrawBuffer(drawBuf);
+ }
+
+ // Set glDepthMask.
+ void setDepthBufferWriteEnable(Context ctx, boolean mode) {
+ if (VERBOSE) System.err.println("JoglPipeline.setDepthBufferWriteEnable()");
+
+ GL gl = context(ctx).getGL();
+ if (mode) {
+ gl.glDepthMask(true);
+ } else {
+ gl.glDepthMask(false);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Helper private functions for Canvas3D
+ //
+
+ private boolean getPropertiesFromCurrentContext(JoglContext ctx) {
+ GL gl = GLU.getCurrentGL();
+ // FIXME: this is a heavily abridged set of the stuff in Canvas3D.c;
+ // probably need to pull much more in
+ int[] tmp = new int[1];
+ gl.glGetIntegerv(GL.GL_MAX_TEXTURE_UNITS, tmp, 0);
+ ctx.setMaxTexCoordSets(tmp[0]);
+ if (VirtualUniverse.mc.transparentOffScreen) {
+ ctx.setAlphaClearValue(0.0f);
+ } else {
+ ctx.setAlphaClearValue(1.0f);
+ }
+ if (gl.isExtensionAvailable("GL_ARB_vertex_shader")) {
+ gl.glGetIntegerv(GL.GL_MAX_TEXTURE_COORDS_ARB, tmp, 0);
+ ctx.setMaxTexCoordSets(tmp[0]);
+ }
+ return true;
+ }
+
+ private int[] extractVersionInfo(String versionString) {
+ StringTokenizer tok = new StringTokenizer(versionString, ". ");
+ int major = Integer.valueOf(tok.nextToken()).intValue();
+ int minor = Integer.valueOf(tok.nextToken()).intValue();
+
+ // See if there's vendor-specific information which might
+ // imply a more recent OpenGL version
+ tok = new StringTokenizer(versionString, " ");
+ if (tok.hasMoreTokens()) {
+ tok.nextToken();
+ if (tok.hasMoreTokens()) {
+ Pattern p = Pattern.compile("\\D*(\\d+)\\.(\\d+)\\.?(\\d*).*");
+ Matcher m = p.matcher(tok.nextToken());
+ if (m.matches()) {
+ int altMajor = Integer.valueOf(m.group(1)).intValue();
+ int altMinor = Integer.valueOf(m.group(2)).intValue();
+ // Avoid possibly confusing situations by requiring
+ // major version to match
+ if (altMajor == major &&
+ altMinor > minor) {
+ minor = altMinor;
+ }
+ }
+ }
+ }
+ return new int[] { major, minor };
+ }
+
+ private int getTextureColorTableSize(GL gl) {
+ if (!gl.isExtensionAvailable("GL_ARB_imaging")) {
+ return 0;
+ }
+
+ gl.glColorTable(GL.GL_PROXY_TEXTURE_COLOR_TABLE_SGI, GL.GL_RGBA, 256, GL.GL_RGB,
+ GL.GL_INT, null);
+ int[] tmp = new int[1];
+ gl.glGetColorTableParameteriv(GL.GL_PROXY_TEXTURE_COLOR_TABLE_SGI,
+ GL.GL_COLOR_TABLE_WIDTH, tmp, 0);
+ return tmp[0];
+ }
+
+
+ private void checkTextureExtensions(Canvas3D cv,
+ JoglContext ctx,
+ GL gl,
+ boolean gl13) {
+ if (gl13) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_MULTI_TEXTURE;
+ cv.multiTexAccelerated = true;
+ int[] tmp = new int[1];
+ gl.glGetIntegerv(GL.GL_MAX_TEXTURE_UNITS, tmp, 0);
+ cv.maxTextureUnits = tmp[0];
+ cv.maxTexCoordSets = cv.maxTextureUnits;
+ if (gl.isExtensionAvailable("GL_ARB_vertex_shader")) {
+ gl.glGetIntegerv(GL.GL_MAX_TEXTURE_COORDS_ARB, tmp, 0);
+ cv.maxTexCoordSets = tmp[0];
+ }
+ }
+
+ if (gl.isExtensionAvailable("GL_SGI_texture_color_table") ||
+ gl.isExtensionAvailable("GL_ARB_imaging")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COLOR_TABLE;
+
+ // get texture color table size
+ // need to check later
+ cv.textureColorTableSize = getTextureColorTableSize(gl);
+ if (cv.textureColorTableSize <= 0) {
+ cv.textureExtendedFeatures &= ~Canvas3D.TEXTURE_COLOR_TABLE;
+ }
+ if (cv.textureColorTableSize > 256) {
+ cv.textureColorTableSize = 256;
+ }
+ }
+
+ if (gl.isExtensionAvailable("GL_ARB_texture_env_combine")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE;
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE_SUBTRACT;
+ } else if (gl.isExtensionAvailable("GL_EXT_texture_env_combine")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE;
+ }
+
+ if (gl.isExtensionAvailable("GL_NV_register_combiners")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_REGISTER_COMBINERS;
+ }
+
+ if (gl.isExtensionAvailable("GL_ARB_texture_env_dot3") ||
+ gl.isExtensionAvailable("GL_EXT_texture_env_dot3")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE_DOT3;
+ }
+
+ if (gl13) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_CUBE_MAP;
+ }
+
+ if (gl.isExtensionAvailable("GL_SGIS_sharpen_texture")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_SHARPEN;
+ }
+
+ if (gl.isExtensionAvailable("GL_SGIS_detail_texture")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_DETAIL;
+ }
+
+ if (gl.isExtensionAvailable("GL_SGIS_texture_filter4")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_FILTER4;
+ }
+
+ if (gl.isExtensionAvailable("GL_EXT_texture_filter_anisotropic")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_ANISOTROPIC_FILTER;
+ float[] tmp = new float[1];
+ gl.glGetFloatv(GL. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, tmp, 0);
+ cv.anisotropicDegreeMax = tmp[0];
+ }
+
+ if (gl.isExtensionAvailable("GL_SGIX_texture_lod_bias")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_LOD_OFFSET;
+ }
+
+ if (gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two")) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_NON_POWER_OF_TWO;
+ }
+ }
+
+
+ private void checkGLSLShaderExtensions(Canvas3D cv,
+ JoglContext ctx,
+ GL gl,
+ boolean glslLibraryAvailable) {
+ if (glslLibraryAvailable &&
+ gl.isExtensionAvailable("GL_ARB_shader_objects") &&
+ gl.isExtensionAvailable("GL_ARB_shading_language_100")) {
+ // Initialize shader vertex attribute function pointers
+ ctx.initGLSLVertexAttributeImpl();
+
+ // FIXME: this isn't complete and would need to set up the
+ // JoglContext for dispatch of various routines such as those
+ // related to vertex attributes
+ int[] tmp = new int[1];
+ gl.glGetIntegerv(GL. GL_MAX_TEXTURE_IMAGE_UNITS_ARB, tmp, 0);
+ cv.maxTextureImageUnits = tmp[0];
+ gl.glGetIntegerv(GL. GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, tmp, 0);
+ cv.maxVertexTextureImageUnits = tmp[0];
+ gl.glGetIntegerv(GL. GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, tmp, 0);
+ cv.maxCombinedTextureImageUnits = tmp[0];
+ int vertexAttrOffset = VirtualUniverse.mc.glslVertexAttrOffset;
+ ctx.setGLSLVertexAttrOffset(vertexAttrOffset);
+ gl.glGetIntegerv(GL. GL_MAX_VERTEX_ATTRIBS_ARB, tmp, 0);
+ cv.maxVertexAttrs = tmp[0];
+ // decr count to allow for reserved vertex attrs
+ cv.maxVertexAttrs -= vertexAttrOffset;
+ if (cv.maxVertexAttrs < 0) {
+ cv.maxVertexAttrs = 0;
+ }
+ cv.shadingLanguageGLSL = true;
+ }
+ }
+
+ private boolean createCgContext(JoglContext ctx) {
+ CGcontext cgContext = CgGL.cgCreateContext();
+
+ int err = CgGL.cgGetError();
+ if (err != 0) {
+ String detail = CgGL.cgGetErrorString(err);
+ System.err.println("JAVA 3D ERROR : Fatal error in creating Cg context: \"" +
+ detail + "\"");
+ return false;
+ }
+
+ if (cgContext == null) {
+ System.err.println("JAVA 3D ERROR : Invalid null Cg context");
+ return false;
+ }
+
+ ctx.setCgContext(cgContext);
+
+ // Use GL_ARB_vertex_program extension if supported by video card
+ if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_ARBVP1)) {
+ ctx.setCgVertexProfile(CgGL.CG_PROFILE_ARBVP1);
+ } else if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_VP20)) {
+ ctx.setCgVertexProfile(CgGL.CG_PROFILE_VP20);
+ } else {
+ System.err.println("JAVA 3D ERROR : No CG vertex program profile is supported");
+ ctx.setCgContext(null);
+ return false;
+ }
+
+ // Use GL_ARB_fragment_program extension if supported by video card
+ if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_ARBFP1)) {
+ ctx.setCgFragmentProfile(CgGL.CG_PROFILE_ARBFP1);
+ } else if (CgGL.cgGLIsProfileSupported(CgGL.CG_PROFILE_FP20)) {
+ ctx.setCgFragmentProfile(CgGL.CG_PROFILE_FP20);
+ } else {
+ System.err.println("JAVA 3D ERROR : No CG fragment program profile is supported");
+ ctx.setCgContext(null);
+ return false;
+ }
+
+ return true;
+ }
+
+ private void checkCgShaderExtensions(Canvas3D cv,
+ JoglContext ctx,
+ GL gl,
+ boolean cgLibraryAvailable) {
+ if (cgLibraryAvailable) {
+ if (!createCgContext(ctx)) {
+ return;
+ }
+ cv.shadingLanguageCg = true;
+ // TODO: Query Cg texture sampler limits
+ cv.maxTextureImageUnits = cv.maxTextureUnits;
+ cv.maxVertexTextureImageUnits = 0;
+ cv.maxCombinedTextureImageUnits = cv.maxTextureUnits;
+ // TODO: Query max vertex attrs
+ cv.maxVertexAttrs = 7;
+ // Initialize shader vertex attribute function pointers
+ ctx.initCgVertexAttributeImpl();
+ }
+ }
+
+ private void setupCanvasProperties(Canvas3D cv,
+ JoglContext ctx,
+ GL gl,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable) {
+ // Note: this includes relevant portions from both the
+ // NativePipeline's getPropertiesFromCurrentContext and setupCanvasProperties
+
+ // Reset all fields
+ cv.multiTexAccelerated = false;
+ cv.maxTextureUnits = 0;
+ cv.maxTexCoordSets = 0;
+ cv.maxTextureImageUnits = 0;
+ cv.maxVertexTextureImageUnits = 0;
+ cv.maxCombinedTextureImageUnits = 0;
+ cv.maxVertexAttrs = 0;
+ cv.extensionsSupported = 0;
+ cv.textureExtendedFeatures = 0;
+ cv.textureColorTableSize = 0;
+ cv.anisotropicDegreeMax = 0;
+ cv.textureBoundaryWidthMax = 0;
+ cv.textureWidthMax = 0;
+ cv.textureHeightMax = 0;
+ cv.texture3DWidthMax = 0;
+ cv.texture3DHeightMax = 0;
+ cv.texture3DDepthMax = 0;
+ cv.shadingLanguageGLSL = false;
+ cv.shadingLanguageCg = false;
+
+ // Now make queries and set up these fields
+ String glVersion = gl.glGetString(GL.GL_VERSION);
+ String glVendor = gl.glGetString(GL.GL_VENDOR);
+ String glRenderer = gl.glGetString(GL.GL_RENDERER);
+ cv.nativeGraphicsVersion = glVersion;
+ cv.nativeGraphicsVendor = glVendor;
+ cv.nativeGraphicsRenderer = glRenderer;
+
+ // find out the version, major and minor version number
+ int[] versionNumbers = extractVersionInfo(glVersion);
+ int major = versionNumbers[0];
+ int minor = versionNumbers[1];
+
+ ///////////////////////////////////////////
+ // setup the graphics context properties //
+
+ // NOTE: Java 3D now requires OpenGL 1.3 for full functionality.
+ // For backwards compatibility with certain older graphics cards and
+ // drivers (e.g., the Linux DRI driver for older ATI cards),
+ // we will try to run on OpenGL 1.2 in an unsupported manner. However,
+ // we will not attempt to use OpenGL extensions for any features that
+ // are available in OpenGL 1.3, specifically multitexture, multisample,
+ // and cube map textures.
+
+ if (major < 1 || (major == 1 && minor < 2)) {
+ throw new IllegalRenderingStateException(
+ "Java 3D ERROR : OpenGL 1.2 or better is required (GL_VERSION=" +
+ major + "." + minor + ")");
+ }
+
+ boolean gl20 = false;
+ boolean gl13 = false;
+ if (major > 1) {
+ // OpenGL 2.x -- set flags for 1.3 and 2.0 or greater
+ gl20 = true;
+ gl13 = true;
+ } else {
+ if (minor == 2) {
+ System.err.println("*********************************************************");
+ System.err.println("*** JAVA 3D: WARNING OpenGL 1.2 is no longer supported.");
+ System.err.println("*** Will attempt to run with reduced functionality.");
+ System.err.println("*********************************************************");
+ } else {
+ gl13 = true;
+ }
+ }
+
+ if (gl20) {
+ assert gl13;
+ assert gl.isExtensionAvailable("GL_VERSION_2_0");
+ }
+ if (gl13) {
+ assert gl.isExtensionAvailable("GL_VERSION_1_3");
+ }
+
+ // Set up properties for OpenGL 1.3
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_3D;
+
+ // Note that we don't query for GL_ARB_imaging here
+
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_LOD_RANGE;
+
+ // look for OpenGL 2.0 features
+ if (gl20) {
+ cv.textureExtendedFeatures |= Canvas3D.TEXTURE_NON_POWER_OF_TWO;
+ }
+
+ // Setup GL_EXT_abgr
+ if (gl.isExtensionAvailable("GL_EXT_abgr")) {
+ cv.extensionsSupported |= Canvas3D.EXT_ABGR;
+ }
+
+ // GL_BGR is always supported
+ cv.extensionsSupported |= Canvas3D.EXT_BGR;
+
+ // Setup multisample
+ // FIXME: this is not correct for the Windows platform yet
+ if (gl13) {
+ cv.extensionsSupported |= Canvas3D.MULTISAMPLE;
+ }
+
+ if ((cv.extensionsSupported & Canvas3D.MULTISAMPLE) != 0 &&
+ !VirtualUniverse.mc.implicitAntialiasing) {
+ gl.glDisable(GL.GL_MULTISAMPLE);
+ }
+
+ // Check texture extensions
+ checkTextureExtensions(cv, ctx, gl, gl13);
+
+ // Check shader extensions
+ if (gl13) {
+ checkGLSLShaderExtensions(cv, ctx, gl, glslLibraryAvailable);
+ checkCgShaderExtensions(cv, ctx, gl, cgLibraryAvailable);
+ } else {
+ // Force shaders to be disabled, since no multitexture support
+ checkGLSLShaderExtensions(cv, ctx, gl, false);
+ checkCgShaderExtensions(cv, ctx, gl, false);
+ }
+
+ // Setup GL_SUN_gloabl_alpha
+ if (gl.isExtensionAvailable("GL_SUN_gloabl_alpha")) {
+ cv.extensionsSupported |= Canvas3D.SUN_GLOBAL_ALPHA;
+ }
+
+ cv.textureBoundaryWidthMax = 1;
+ {
+ int[] tmp = new int[1];
+ gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, tmp, 0);
+ cv.textureWidthMax = tmp[0];
+ cv.textureHeightMax = tmp[0];
+
+ tmp[0] = -1;
+ gl.glGetIntegerv(GL.GL_MAX_3D_TEXTURE_SIZE, tmp, 0);
+ cv.texture3DWidthMax = tmp[0];
+ cv.texture3DHeightMax = tmp[0];
+ cv.texture3DDepthMax = tmp[0];
+ }
+ }
+
+ /*
+ * Function to disable most rendering attributes when doing a 2D
+ * clear, image copy, or image composite operation. Note that the
+ * caller must save/restore the attributes with
+ * pushAttrib(GL_ENABLE_BIT|...) and popAttrib()
+ */
+ private void disableAttribFor2D(GL gl) {
+ gl.glDisable(GL.GL_ALPHA_TEST);
+ gl.glDisable(GL.GL_BLEND);
+ gl.glDisable(GL.GL_COLOR_LOGIC_OP);
+ gl.glDisable(GL.GL_COLOR_MATERIAL);
+ gl.glDisable(GL.GL_CULL_FACE);
+ gl.glDisable(GL.GL_DEPTH_TEST);
+ gl.glDisable(GL.GL_FOG);
+ gl.glDisable(GL.GL_LIGHTING);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
+ gl.glDisable(GL.GL_POLYGON_STIPPLE);
+ gl.glDisable(GL.GL_STENCIL_TEST);
+ gl.glDisable(GL.GL_TEXTURE_2D);
+ gl.glDisable(GL.GL_TEXTURE_GEN_Q);
+ gl.glDisable(GL.GL_TEXTURE_GEN_R);
+ gl.glDisable(GL.GL_TEXTURE_GEN_S);
+ gl.glDisable(GL.GL_TEXTURE_GEN_T);
+
+
+ for (int i = 0; i < 6; i++) {
+ gl.glDisable(GL.GL_CLIP_PLANE0 + i);
+ }
+
+ gl.glDisable(GL.GL_TEXTURE_3D);
+ gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
+
+ if (gl.isExtensionAvailable("GL_NV_register_combiners")) {
+ gl.glDisable(GL.GL_REGISTER_COMBINERS_NV);
+ }
+
+ if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) {
+ gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI);
+ }
+
+ if (gl.isExtensionAvailable("GL_SUN_global_alpha")) {
+ gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN);
+ }
+
+ }
+
+ private void disableAttribForRaster(GL gl) {
+
+ gl.glDisable(GL.GL_COLOR_MATERIAL);
+ gl.glDisable(GL.GL_CULL_FACE);
+ gl.glDisable(GL.GL_LIGHTING);
+ gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
+ gl.glDisable(GL.GL_POLYGON_STIPPLE);
+
+ // TODO: Disable if Raster.CLIP_POSITION is true
+// for (int i = 0; i < 6; i++) {
+// gl.glDisable(GL.GL_CLIP_PLANE0 + i);
+// }
+
+ if (gl.isExtensionAvailable("GL_SUN_global_alpha")) {
+ gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN);
+ }
+ }
+
+ private void copyTranspose(double[] src, double[] dst) {
+ dst[0] = src[0];
+ dst[1] = src[4];
+ dst[2] = src[8];
+ dst[3] = src[12];
+ dst[4] = src[1];
+ dst[5] = src[5];
+ dst[6] = src[9];
+ dst[7] = src[13];
+ dst[8] = src[2];
+ dst[9] = src[6];
+ dst[10] = src[10];
+ dst[11] = src[14];
+ dst[12] = src[3];
+ dst[13] = src[7];
+ dst[14] = src[11];
+ dst[15] = src[15];
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Canvas3D / GraphicsConfigTemplate3D methods - logic dealing with
+ // native graphics configuration or drawing surface
+ //
+
+ // Return a graphics config based on the one passed in. Note that we can
+ // assert that the input config is non-null and was created from a
+ // GraphicsConfigTemplate3D.
+ // This method must return a valid GraphicsConfig, or else it must throw
+ // an exception if one cannot be returned.
+ GraphicsConfiguration getGraphicsConfig(GraphicsConfiguration gconfig) {
+ if (VERBOSE) System.err.println("JoglPipeline.getGraphicsConfig()");
+ JoglGraphicsConfiguration config = (JoglGraphicsConfiguration) gconfig;
+ GLCapabilitiesChooser indexChooser = null;
+ if (config.getChosenIndex() >= 0) {
+ indexChooser = new IndexCapabilitiesChooser(config.getChosenIndex());
+ }
+
+ AbstractGraphicsConfiguration absConfig =
+ GLDrawableFactory.getFactory().chooseGraphicsConfiguration(config.getGLCapabilities(),
+ indexChooser,
+ new AWTGraphicsDevice(config.getDevice()));
+ if (absConfig == null) {
+ return null;
+ }
+ return ((AWTGraphicsConfiguration) absConfig).getGraphicsConfiguration();
+
+ /*
+
+ System.err.println("JoglPipeline.getGraphicsConfig()");
+ // Just return the input graphics config for now. eventually, we will
+ // use the input graphics config to get the GraphicsConfigTemplate3D
+ // parameters, which we will use to create a new graphics config with JOGL.
+ return gconfig;
+ */
+ }
+
+ // Get the native FBconfig pointer
+ long getFbConfig(GraphicsConfigInfo gcInfo) {
+ if (VERBOSE) System.err.println("JoglPipeline.getFbConfig()");
+ return 0L; // Dummy method in JOGL
+ }
+
+
+ private static final int DISABLE_STEREO = 1;
+ private static final int DISABLE_AA = 2;
+ private static final int DISABLE_DOUBLE_BUFFER = 3;
+
+ // Get best graphics config from pipeline
+ GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate3D gct,
+ GraphicsConfiguration[] gc) {
+ if (VERBOSE) System.err.println("JoglPipeline.getBestConfiguration()");
+ /*
+ System.err.println("gct.getDoubleBuffer(): " + gct.getDoubleBuffer());
+ System.err.println("gct.getStereo(): " + gct.getStereo());
+ System.err.println("gct.getDepthBits(): " + gct.getDepthSize());
+ System.err.println("gct.getRedSize(): " + gct.getRedSize());
+ System.err.println("gct.getGreenSize(): " + gct.getGreenSize());
+ System.err.println("gct.getBlueSize(): " + gct.getBlueSize());
+ System.err.println("gct.getSceneAntialiasing(): " + gct.getSceneAntialiasing());
+ */
+
+ // Create a GLCapabilities based on the GraphicsConfigTemplate3D
+ GLCapabilities caps = new GLCapabilities();
+ caps.setDoubleBuffered(gct.getDoubleBuffer() <= GraphicsConfigTemplate.PREFERRED);
+ caps.setStereo (gct.getStereo() <= GraphicsConfigTemplate.PREFERRED);
+ caps.setDepthBits (gct.getDepthSize());
+ caps.setStencilBits (gct.getStencilSize());
+ caps.setRedBits (Math.max(5, gct.getRedSize()));
+ caps.setGreenBits (Math.max(5, gct.getGreenSize()));
+ caps.setBlueBits (Math.max(5, gct.getBlueSize()));
+ caps.setSampleBuffers(gct.getSceneAntialiasing() <= GraphicsConfigTemplate.PREFERRED);
+ // FIXME: should be smarter about choosing the number of samples
+ // (Java3D's native code has a loop trying 8, 6, 4, 3, and 2 samples)
+ caps.setNumSamples(4);
+
+ java.util.List<Integer> capsToDisable = new ArrayList<Integer>();
+ // Add PREFERRED capabilities in order we will try disabling them
+ if (gct.getStereo() == GraphicsConfigTemplate.PREFERRED) {
+ capsToDisable.add(new Integer(DISABLE_STEREO));
+ }
+ if (gct.getSceneAntialiasing() == GraphicsConfigTemplate.PREFERRED) {
+ capsToDisable.add(new Integer(DISABLE_AA));
+ }
+ if (gct.getDoubleBuffer() == GraphicsConfigTemplate.PREFERRED) {
+ capsToDisable.add(new Integer(DISABLE_DOUBLE_BUFFER));
+ }
+
+ // Pick the GraphicsDevice from a random configuration
+ GraphicsDevice dev = gc[0].getDevice();
+
+ // Create a Frame and dummy GLCanvas to perform eager pixel format selection
+
+ // Note that we loop in similar fashion to the NativePipeline's
+ // native code in the situation where we need to disable certain
+ // capabilities which aren't required
+ boolean tryAgain = true;
+ CapabilitiesCapturer capturer = null;
+ while (tryAgain) {
+ Frame f = new Frame(dev.getDefaultConfiguration());
+ f.setUndecorated(true);
+ f.setLayout(new BorderLayout());
+ capturer = new CapabilitiesCapturer();
+ try {
+ QueryCanvas canvas = new QueryCanvas(caps, capturer, dev);
+ f.add(canvas, BorderLayout.CENTER);
+ f.setSize(MIN_FRAME_SIZE, MIN_FRAME_SIZE);
+ f.setVisible(true);
+ canvas.doQuery();
+ if (DEBUG_CONFIG) {
+ System.err.println("Waiting for CapabilitiesCapturer");
+ }
+ // Try to wait for result without blocking EDT
+ if (!EventQueue.isDispatchThread()) {
+ synchronized(capturer) {
+ if (!capturer.done()) {
+ try {
+ capturer.wait(WAIT_TIME);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+ disposeOnEDT(f);
+ tryAgain = false;
+ } catch (GLException e) {
+ // Failure to select a pixel format; try switching off one
+ // of the only-preferred capabilities
+ if (capsToDisable.size() == 0) {
+ tryAgain = false;
+ } else {
+ int whichToDisable = capsToDisable.remove(0).intValue();
+ switch (whichToDisable) {
+ case DISABLE_STEREO:
+ caps.setStereo(false);
+ break;
+
+ case DISABLE_AA:
+ caps.setSampleBuffers(false);
+ break;
+
+ case DISABLE_DOUBLE_BUFFER:
+ caps.setDoubleBuffered(false);
+ break;
+
+ default:
+ throw new AssertionError("missing case statement");
+ }
+ }
+ }
+ }
+ int chosenIndex = capturer.getChosenIndex();
+ GLCapabilities chosenCaps = null;
+ if (chosenIndex < 0) {
+ if (DEBUG_CONFIG) {
+ System.err.println("CapabilitiesCapturer returned invalid index");
+ }
+ // It's possible some platforms or implementations might not
+ // support the GLCapabilitiesChooser mechanism; feed in the
+ // same GLCapabilities later which we gave to the selector
+ chosenCaps = caps;
+ } else {
+ if (DEBUG_CONFIG) {
+ System.err.println("CapabilitiesCapturer returned index=" + chosenIndex);
+ }
+ chosenCaps = capturer.getCapabilities();
+ }
+
+ JoglGraphicsConfiguration config = new JoglGraphicsConfiguration(chosenCaps, chosenIndex, dev);
+
+ // FIXME: because of the fact that JoglGraphicsConfiguration
+ // doesn't override hashCode() or equals(), we will basically be
+ // creating a new one each time getBestConfiguration() is
+ // called; in theory, we should probably map the same
+ // GLCapabilities on the same GraphicsDevice to the same
+ // JoglGraphicsConfiguration object
+
+ // Cache the GraphicsTemplate3D
+ synchronized (Canvas3D.graphicsConfigTable) {
+ GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(gct);
+ // We don't need this
+ // gcInfo.setPrivateData(privateData);
+ Canvas3D.graphicsConfigTable.put(config, gcInfo);
+ }
+
+ return config;
+
+ /*
+
+ // TODO: implement this
+
+ // TODO: construct a unique GraphicsConfiguration object that will be
+ // used the key in the hashmap so we can lookup the GraphicsTemplate3D
+ GraphicsConfiguration gc1 = GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration();
+
+ // Cache the GraphicsTemplate3D
+ synchronized (Canvas3D.graphicsConfigTable) {
+ if (Canvas3D.graphicsConfigTable.get(gc1) == null) {
+ GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(gct);
+ // gcInfo.setPrivateData(privateData);
+ Canvas3D.graphicsConfigTable.put(gc1, gcInfo);
+ }
+ }
+ return gc1;
+
+ */
+ }
+
+ // Determine whether specified graphics config is supported by pipeline
+ boolean isGraphicsConfigSupported(GraphicsConfigTemplate3D gct,
+ GraphicsConfiguration gc) {
+ if (VERBOSE) System.err.println("JoglPipeline.isGraphicsConfigSupported()");
+
+ // FIXME: it looks like this method is implemented incorrectly
+ // in the existing NativePipeline in both the Windows and X11
+ // ports. According to the semantics of the javadoc, it looks
+ // like this method is supposed to figure out the OpenGL
+ // capabilities which would be requested by the passed
+ // GraphicsConfiguration object were it to be used, and see
+ // whether it is possible to create a context with them.
+ // Instead, on both platforms, the implementations basically set
+ // up a query based on the contents of the
+ // GraphicsConfigTemplate3D object, using the
+ // GraphicsConfiguration object only to figure out on which
+ // GraphicsDevice and screen we're making the request, and see
+ // whether it's possible to choose an OpenGL pixel format based
+ // on that information. This makes this method less useful and
+ // we can probably just safely return true here uniformly
+ // without breaking anything.
+ return true;
+ }
+
+ // Methods to get actual capabilities from Canvas3D
+ boolean hasDoubleBuffer(Canvas3D cv) {
+ if (VERBOSE) System.err.println("JoglPipeline.hasDoubleBuffer()");
+ if (VERBOSE) System.err.println(" Returning " + caps(cv).getDoubleBuffered());
+ return caps(cv).getDoubleBuffered();
+ }
+
+ boolean hasStereo(Canvas3D cv) {
+ if (VERBOSE) System.err.println("JoglPipeline.hasStereo()");
+ if (VERBOSE) System.err.println(" Returning " + caps(cv).getStereo());
+ return caps(cv).getStereo();
+ }
+
+ int getStencilSize(Canvas3D cv) {
+ if (VERBOSE) System.err.println("JoglPipeline.getStencilSize()");
+ if (VERBOSE) System.err.println(" Returning " + caps(cv).getStencilBits());
+ return caps(cv).getStencilBits();
+ }
+
+ boolean hasSceneAntialiasingMultisample(Canvas3D cv) {
+ if (VERBOSE) System.err.println("JoglPipeline.hasSceneAntialiasingMultisample()");
+ if (VERBOSE) System.err.println(" Returning " + caps(cv).getSampleBuffers());
+
+ return caps(cv).getSampleBuffers();
+ }
+
+ boolean hasSceneAntialiasingAccum(Canvas3D cv) {
+ if (VERBOSE) System.err.println("JoglPipeline.hasSceneAntialiasingAccum()");
+ GLCapabilities caps = caps(cv);
+ if (VERBOSE) System.err.println(" Returning " + (caps.getAccumRedBits() > 0 &&
+ caps.getAccumGreenBits() > 0 &&
+ caps.getAccumBlueBits() > 0));
+ return (caps.getAccumRedBits() > 0 &&
+ caps.getAccumGreenBits() > 0 &&
+ caps.getAccumBlueBits() > 0);
+ }
+
+ // Methods to get native WS display and screen
+ long getDisplay() {
+ if (VERBOSE) System.err.println("JoglPipeline.getDisplay()");
+ return 0L; // Dummy method in JOGL
+ }
+
+ private boolean checkedForGetScreenMethod = false;
+ private Method getScreenMethod = null;
+ int getScreen(final GraphicsDevice graphicsDevice) {
+ if (VERBOSE) System.err.println("JoglPipeline.getScreen()");
+
+ if (!checkedForGetScreenMethod) {
+ // All of the Sun GraphicsDevice implementations have a method
+ // int getScreen();
+ // which we want to call reflectively if it's available.
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ getScreenMethod = graphicsDevice.getClass().getDeclaredMethod("getScreen", new Class[] {});
+ getScreenMethod.setAccessible(true);
+ } catch (Exception e) {
+ }
+ checkedForGetScreenMethod = true;
+ return null;
+ }
+ });
+ }
+
+ if (getScreenMethod != null) {
+ try {
+ return ((Integer) getScreenMethod.invoke(graphicsDevice, (Object[]) null)).intValue();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ return 0;
+ }
+
+ //----------------------------------------------------------------------
+ // Helper classes and methods to support query context functionality
+ // and pixel format selection
+
+ interface ExtendedCapabilitiesChooser extends GLCapabilitiesChooser {
+ public void init(GLContext context);
+ }
+
+ // Canvas subclass to help with various query operations such as the
+ // "query context" mechanism and pixel format selection.
+ // Must defeat and simplify the single-threading behavior of JOGL's
+ // GLCanvas in order to be able to set up a temporary pixel format
+ // and OpenGL context. Apparently simply turning off the
+ // single-threaded mode isn't enough to do this.
+ class QueryCanvas extends Canvas {
+ private GLDrawable drawable;
+ private ExtendedCapabilitiesChooser chooser;
+ private boolean alreadyRan;
+
+ public QueryCanvas(GLCapabilities capabilities,
+ ExtendedCapabilitiesChooser chooser,
+ GraphicsDevice device) {
+ // The platform-specific GLDrawableFactory will only provide a
+ // non-null GraphicsConfiguration on platforms where this is
+ // necessary (currently only X11, as Windows allows the pixel
+ // format of the window to be set later and Mac OS X seems to
+ // handle this very differently than all other platforms). On
+ // other platforms this method returns null; it is the case (at
+ // least in the Sun AWT implementation) that this will result in
+ // equivalent behavior to calling the no-arg super() constructor
+ // for Canvas.
+ super(unwrap((AWTGraphicsConfiguration)
+ GLDrawableFactory.getFactory().chooseGraphicsConfiguration(capabilities,
+ chooser,
+ new AWTGraphicsDevice(device))));
+ drawable = GLDrawableFactory.getFactory().getGLDrawable(this, capabilities, chooser);
+ this.chooser = chooser;
+ }
+
+ public void addNotify() {
+ super.addNotify();
+ drawable.setRealized(true);
+ }
+
+ // It seems that at least on Mac OS X we need to do the OpenGL
+ // context-related work outside of the addNotify call because the
+ // Canvas hasn't been resized to a non-zero size by that point
+ public void doQuery() {
+ if (alreadyRan)
+ return;
+ GLContext context = drawable.createContext(null);
+ int res = context.makeCurrent();
+ if (res != GLContext.CONTEXT_NOT_CURRENT) {
+ try {
+ chooser.init(context);
+ } finally {
+ context.release();
+ }
+ }
+ context.destroy();
+ alreadyRan = true;
+ }
+ }
+
+ private static GraphicsConfiguration unwrap(AWTGraphicsConfiguration config) {
+ if (config == null) {
+ return null;
+ }
+ return config.getGraphicsConfiguration();
+ }
+
+ // Used in conjunction with IndexCapabilitiesChooser in pixel format
+ // selection -- see getBestConfiguration
+ class CapabilitiesCapturer extends DefaultGLCapabilitiesChooser implements ExtendedCapabilitiesChooser {
+ private boolean done;
+ private GLCapabilities capabilities;
+ private int chosenIndex = -1;
+
+ public boolean done() {
+ return done;
+ }
+
+ public GLCapabilities getCapabilities() {
+ return capabilities;
+ }
+
+ public int getChosenIndex() {
+ return chosenIndex;
+ }
+
+ public int chooseCapabilities(GLCapabilities desired,
+ GLCapabilities[] available,
+ int windowSystemRecommendedChoice) {
+ int res = super.chooseCapabilities(desired, available, windowSystemRecommendedChoice);
+ capabilities = available[res];
+ chosenIndex = res;
+ markDone();
+ return res;
+ }
+
+ public void init(GLContext context) {
+ // Avoid hanging things up for several seconds
+ kick();
+ }
+
+ private void markDone() {
+ synchronized (this) {
+ done = true;
+ notifyAll();
+ }
+ }
+
+ private void kick() {
+ synchronized (this) {
+ notifyAll();
+ }
+ }
+ }
+
+ // Used to support the query context mechanism -- needs to be more
+ // than just a GLCapabilitiesChooser
+ class ContextQuerier extends DefaultGLCapabilitiesChooser implements ExtendedCapabilitiesChooser {
+ private Canvas3D canvas;
+ private boolean glslLibraryAvailable;
+ private boolean cgLibraryAvailable;
+ private boolean done;
+
+ public ContextQuerier(Canvas3D canvas,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable) {
+ this.canvas = canvas;
+ this.glslLibraryAvailable = glslLibraryAvailable;
+ this.cgLibraryAvailable = cgLibraryAvailable;
+ }
+
+ public boolean done() {
+ return done;
+ }
+
+ public void init(GLContext context) {
+ // This is basically a temporary
+ JoglContext jctx = new JoglContext(context);
+ // Set up various properties
+ if (getPropertiesFromCurrentContext(jctx)) {
+ setupCanvasProperties(canvas, jctx, context.getGL(),
+ glslLibraryAvailable,
+ cgLibraryAvailable);
+ }
+ markDone();
+ }
+
+ private void markDone() {
+ synchronized (this) {
+ done = true;
+ notifyAll();
+ }
+ }
+ }
+
+ // Used in two phases of pixel format selection: transforming the
+ // JoglGraphicsConfiguration to a real AWT GraphicsConfiguration and
+ // during context creation to select exactly the same graphics
+ // configuration as was done during getBestConfiguration.
+ class IndexCapabilitiesChooser implements GLCapabilitiesChooser {
+ private int indexToChoose;
+
+ IndexCapabilitiesChooser(int indexToChoose) {
+ this.indexToChoose = indexToChoose;
+ }
+
+ public int chooseCapabilities(GLCapabilities desired,
+ GLCapabilities[] available,
+ int windowSystemRecommendedChoice) {
+ if (DEBUG_CONFIG) {
+ System.err.println("IndexCapabilitiesChooser returning index=" + indexToChoose);
+ }
+ return indexToChoose;
+ }
+ }
+
+ private void disposeOnEDT(final Frame f) {
+ Runnable r = new Runnable() {
+ public void run() {
+ f.setVisible(false);
+ f.dispose();
+ }
+ };
+ if (!EventQueue.isDispatchThread()) {
+ EventQueue.invokeLater(r);
+ } else {
+ r.run();
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // DrawingSurfaceObject methods
+ //
+
+ // Method to construct a new DrawingSurfaceObject
+ DrawingSurfaceObject createDrawingSurfaceObject(Canvas3D cv) {
+ if (VERBOSE) System.err.println("JoglPipeline.createDrawingSurfaceObject()");
+ return new JoglDrawingSurfaceObject(cv);
+ }
+
+ // Method to free the drawing surface object
+ void freeDrawingSurface(Canvas3D cv, DrawingSurfaceObject drawingSurfaceObject) {
+ if (VERBOSE) System.err.println("JoglPipeline.freeDrawingSurface()");
+ // This method is a no-op
+ }
+
+ // Method to free the native drawing surface object
+ void freeDrawingSurfaceNative(Object o) {
+ if (VERBOSE) System.err.println("JoglPipeline.freeDrawingSurfaceNative()");
+ // This method is a no-op
+ }
+
+ //----------------------------------------------------------------------
+ // Context-related routines
+ //
+
+ // Helper used everywhere
+ GLContext context(Context ctx) {
+ if (ctx == null)
+ return null;
+ return ((JoglContext) ctx).getGLContext();
+ }
+
+ // Helper used everywhere
+ GLDrawable drawable(Drawable drawable) {
+ if (drawable == null)
+ return null;
+ return ((JoglDrawable) drawable).getGLDrawable();
+ }
+
+ GLCapabilities caps(Canvas3D ctx) {
+ return ((JoglGraphicsConfiguration) ctx.graphicsConfiguration).getGLCapabilities();
+ }
+
+ //----------------------------------------------------------------------
+ // General helper routines
+ //
+
+ private static ThreadLocal nioVertexTemp = new ThreadLocal();
+ private static ThreadLocal nioVertexDoubleTemp = new ThreadLocal();
+ private static ThreadLocal nioColorTemp = new ThreadLocal();
+ private static ThreadLocal nioColorByteTemp = new ThreadLocal();
+ private static ThreadLocal nioNormalTemp = new ThreadLocal();
+ private static ThreadLocal nioTexCoordSetTemp = new ThreadLocal();
+ private static ThreadLocal nioVertexAttrSetTemp = new ThreadLocal();
+
+ private static FloatBuffer getVertexArrayBuffer(float[] vertexArray) {
+ return getVertexArrayBuffer(vertexArray, true);
+ }
+
+ private static FloatBuffer getVertexArrayBuffer(float[] vertexArray, boolean copyData) {
+ return getNIOBuffer(vertexArray, nioVertexTemp, copyData);
+ }
+
+ private static DoubleBuffer getVertexArrayBuffer(double[] vertexArray) {
+ return getVertexArrayBuffer(vertexArray, true);
+ }
+
+ private static DoubleBuffer getVertexArrayBuffer(double[] vertexArray, boolean copyData) {
+ return getNIOBuffer(vertexArray, nioVertexDoubleTemp, true);
+ }
+
+ private static FloatBuffer getColorArrayBuffer(float[] colorArray) {
+ return getColorArrayBuffer(colorArray, true);
+ }
+
+ private static FloatBuffer getColorArrayBuffer(float[] colorArray, boolean copyData) {
+ return getNIOBuffer(colorArray, nioColorTemp, true);
+ }
+
+ private static ByteBuffer getColorArrayBuffer(byte[] colorArray) {
+ return getColorArrayBuffer(colorArray, true);
+ }
+
+ private static ByteBuffer getColorArrayBuffer(byte[] colorArray, boolean copyData) {
+ return getNIOBuffer(colorArray, nioColorByteTemp, true);
+ }
+
+ private static FloatBuffer getNormalArrayBuffer(float[] normalArray) {
+ return getNormalArrayBuffer(normalArray, true);
+ }
+
+ private static FloatBuffer getNormalArrayBuffer(float[] normalArray, boolean copyData) {
+ return getNIOBuffer(normalArray, nioNormalTemp, true);
+ }
+
+ private static FloatBuffer[] getTexCoordSetBuffer(Object[] texCoordSet) {
+ return getNIOBuffer(texCoordSet, nioTexCoordSetTemp);
+ }
+
+ private static FloatBuffer[] getVertexAttrSetBuffer(Object[] vertexAttrSet) {
+ return getNIOBuffer(vertexAttrSet, nioVertexAttrSetTemp);
+ }
+
+ private static FloatBuffer getNIOBuffer(float[] array, ThreadLocal threadLocal, boolean copyData) {
+ if (array == null) {
+ return null;
+ }
+ FloatBuffer buf = (FloatBuffer) threadLocal.get();
+ if (buf == null) {
+ buf = BufferUtil.newFloatBuffer(array.length);
+ threadLocal.set(buf);
+ } else {
+ buf.rewind();
+ if (buf.remaining() < array.length) {
+ int newSize = Math.max(2 * buf.remaining(), array.length);
+ buf = BufferUtil.newFloatBuffer(newSize);
+ threadLocal.set(buf);
+ }
+ }
+ if (copyData) {
+ buf.put(array);
+ buf.rewind();
+ }
+ return buf;
+ }
+
+ private static DoubleBuffer getNIOBuffer(double[] array, ThreadLocal threadLocal, boolean copyData) {
+ if (array == null) {
+ return null;
+ }
+ DoubleBuffer buf = (DoubleBuffer) threadLocal.get();
+ if (buf == null) {
+ buf = BufferUtil.newDoubleBuffer(array.length);
+ threadLocal.set(buf);
+ } else {
+ buf.rewind();
+ if (buf.remaining() < array.length) {
+ int newSize = Math.max(2 * buf.remaining(), array.length);
+ buf = BufferUtil.newDoubleBuffer(newSize);
+ threadLocal.set(buf);
+ }
+ }
+ if (copyData) {
+ buf.put(array);
+ buf.rewind();
+ }
+ return buf;
+ }
+
+ private static ByteBuffer getNIOBuffer(byte[] array, ThreadLocal threadLocal, boolean copyData) {
+ if (array == null) {
+ return null;
+ }
+ ByteBuffer buf = (ByteBuffer) threadLocal.get();
+ if (buf == null) {
+ buf = BufferUtil.newByteBuffer(array.length);
+ threadLocal.set(buf);
+ } else {
+ buf.rewind();
+ if (buf.remaining() < array.length) {
+ int newSize = Math.max(2 * buf.remaining(), array.length);
+ buf = BufferUtil.newByteBuffer(newSize);
+ threadLocal.set(buf);
+ }
+ }
+ if (copyData) {
+ buf.put(array);
+ buf.rewind();
+ }
+ return buf;
+ }
+
+ private static FloatBuffer[] getNIOBuffer(Object[] array, ThreadLocal threadLocal) {
+ if (array == null) {
+ return null;
+ }
+ FloatBuffer[] bufs = (FloatBuffer[]) threadLocal.get();
+
+ // First resize array of FloatBuffers
+ if (bufs == null) {
+ bufs = new FloatBuffer[array.length];
+ threadLocal.set(bufs);
+ } else if (bufs.length < array.length) {
+ FloatBuffer[] newBufs = new FloatBuffer[array.length];
+ System.arraycopy(bufs, 0, newBufs, 0, bufs.length);
+ bufs = newBufs;
+ threadLocal.set(bufs);
+ }
+
+ // Now go down array of arrays, converting each into a direct FloatBuffer
+ for (int i = 0; i < array.length; i++) {
+ float[] cur = (float[]) array[i];
+ FloatBuffer buf = bufs[i];
+ if (buf == null) {
+ buf = BufferUtil.newFloatBuffer(cur.length);
+ bufs[i] = buf;
+ } else {
+ buf.rewind();
+ if (buf.remaining() < cur.length) {
+ int newSize = Math.max(2 * buf.remaining(), cur.length);
+ buf = BufferUtil.newFloatBuffer(newSize);
+ bufs[i] = buf;
+ }
+ }
+ buf.put(cur);
+ buf.rewind();
+ }
+
+ return bufs;
+ }
+}
diff --git a/src/classes/jogl/javax/media/j3d/JoglShaderObject.java b/src/classes/jogl/javax/media/j3d/JoglShaderObject.java
new file mode 100755
index 0000000..d610857
--- /dev/null
+++ b/src/classes/jogl/javax/media/j3d/JoglShaderObject.java
@@ -0,0 +1,25 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+class JoglShaderObject implements ShaderProgramId, ShaderId, ShaderAttrLoc {
+ private int val;
+
+ JoglShaderObject(int val) {
+ this.val = val;
+ }
+
+ int getValue() {
+ return val;
+ }
+}
diff --git a/src/classes/linux/javax/media/j3d/J3dGraphicsConfig.java b/src/classes/linux/javax/media/j3d/J3dGraphicsConfig.java
deleted file mode 100644
index 41673f2..0000000
--- a/src/classes/linux/javax/media/j3d/J3dGraphicsConfig.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-/*
- * Portions of this code were derived from work done by the Blackdown
- * group (www.blackdown.org), who did the initial Linux implementation
- * of the Java 3D API.
- */
-
-package javax.media.j3d;
-
-import sun.awt.*;
-import java.awt.*;
-
-class J3dGraphicsConfig {
-
- static native boolean isValidVisualID(long display, int vid);
-
- J3dGraphicsConfig(GraphicsDevice gd, int pixelFormat) {
- // a dummy class which this constructor should
- // never invoke under Linux
- }
-
- static boolean isValidPixelFormat(GraphicsConfiguration gc) {
- return isValidVisualID(NativeScreenInfo.getStaticDisplay(),
- ((X11GraphicsConfig) gc).getVisual());
- }
-
- static boolean isValidConfig(GraphicsConfiguration gc) {
- // Check to see if a valid FBConfig pointer has been cached.
- Object fbConfigObject = Canvas3D.fbConfigTable.get(gc);
- return ((fbConfigObject != null) &&
- (fbConfigObject instanceof GraphicsConfigInfo));
- }
-}
diff --git a/src/classes/linux/javax/media/j3d/NativeConfigTemplate3D.java b/src/classes/linux/javax/media/j3d/NativeConfigTemplate3D.java
deleted file mode 100644
index 9f1059c..0000000
--- a/src/classes/linux/javax/media/j3d/NativeConfigTemplate3D.java
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-/*
- * Portions of this code were derived from work done by the Blackdown
- * group (www.blackdown.org), who did the initial Linux implementation
- * of the Java 3D API.
- */
-
-package javax.media.j3d;
-
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsConfigTemplate;
-import java.awt.Rectangle;
-import sun.awt.X11GraphicsDevice;
-import sun.awt.X11GraphicsConfig;
-
-class NativeConfigTemplate3D {
- private final static boolean debug = false;
-
- NativeConfigTemplate3D() {
- }
-
- /*
- * This definition should match those in win32 NativeConfigTemplate3D.java
- */
- final static int RED_SIZE = 0;
- final static int GREEN_SIZE = 1;
- final static int BLUE_SIZE = 2;
- final static int ALPHA_SIZE = 3;
- final static int ACCUM_BUFFER = 4;
- final static int DEPTH_SIZE = 5;
- final static int DOUBLEBUFFER = 6;
- final static int STEREO = 7;
- final static int ANTIALIASING = 8;
- final static int STENCIL_SIZE = 9;
- final static int NUM_ITEMS = 10;
-
- // Native method to get an OpenGL visual id and a pointer to the
- // GLXFBConfig structure list itself.
- native int chooseOglVisual(long display, int screen,
- int[] attrList, long[] fbConfig);
-
- // Native method to free an GLXFBConfig struct. This is static since it
- // may need to be called to clean up the Canvas3D fbConfigTable after the
- // NativeConfigTemplate3D has been disposed of.
- static native void freeFBConfig(long fbConfig);
-
- // Native methods to return whether a particular attribute is available
- native boolean isStereoAvailable(long display, int screen, int vid);
- native boolean isDoubleBufferAvailable(long display, int screen, int vid);
- native boolean isSceneAntialiasingAccumAvailable(long display, int screen, int vid);
- native boolean isSceneAntialiasingMultisampleAvailable(long display, int screen, int vid);
- native int getStencilSize(long display, int screen, int vid);
-
-
- /*
- * Chooses the best FBConfig for Java 3D apps.
- */
- GraphicsConfiguration
- getBestConfiguration(GraphicsConfigTemplate3D template,
- GraphicsConfiguration[] gc) {
-
- X11GraphicsDevice gd =
- (X11GraphicsDevice)((X11GraphicsConfig)gc[0]).getDevice();
-
- if (!NativeScreenInfo.isGLX13()) {
- return null;
- }
-
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
-
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
-
- if (debug) {
- System.out.println(" NativeConfigTemplate3D: using device " + gd);
- System.out.println(" display " + display + " screen " + screen);
- System.out.println(" configuration count: " + gc.length);
- for (int i = 0 ; i < gc.length ; i++) {
- System.out.println(" visual id at index " + i + ": " +
- ((X11GraphicsConfig)gc[i]).getVisual());
- }
- }
-
- Rectangle bounds = gc[0].getBounds();
- if ((bounds.x != 0 || bounds.y != 0) &&
- (! VirtualUniverse.mc.xineramaDisabled)) {
- // Xinerama is being used. The screen needs to be set to 0 since
- // glxChooseFBConfig will not return a valid visual otherwise.
- screen = 0;
- if (debug) {
- System.out.println(" Non-primary Xinerama screen:");
- System.out.println(" bounds = " + bounds);
- System.out.println(" using screen 0 visual");
- }
- }
-
- int[] attrList; // holds the list of attributes to be translated
- // for glxChooseFBConfig call
-
- attrList = new int[NUM_ITEMS];
-
- // assign template values to array
- attrList[RED_SIZE] = template.getRedSize();
- attrList[GREEN_SIZE] = template.getGreenSize();
- attrList[BLUE_SIZE] = template.getBlueSize();
-
- attrList[DEPTH_SIZE] = template.getDepthSize();
- attrList[DOUBLEBUFFER] = template.getDoubleBuffer();
- attrList[STEREO] = template.getStereo();
- attrList[ANTIALIASING] = template.getSceneAntialiasing();
- attrList[STENCIL_SIZE] = template.getStencilSize();
- // System.out.println("NativeConfigTemplate3D : getStencilSize " +
- // attrList[STENCIL_SIZE]);
-
- long[] fbConfig = new long[1];
- int visID = chooseOglVisual(display, screen, attrList, fbConfig);
- if (debug) {
- System.out.println(" chooseOglVisual() returns " + visID);
- System.out.println(" pointer to GLXFBConfig is " + fbConfig[0]);
- System.out.println();
- }
-
- if (visID == 0 || fbConfig[0] == 0) {
- return null; // no valid visual was found
- }
-
- // search list of graphics configurations for config
- // with matching visualId
- GraphicsConfiguration gc1 = null;
- for (int i = 0; i < gc.length; i++)
- if (((X11GraphicsConfig)gc[i]).getVisual() == visID) {
- gc1 = gc[i];
- break;
- }
-
- // TODO: This may or may not be needed for Linux
- // To support disabling Solaris OpenGL Xinerama mode, we need to cache
- // the pointer to the actual GLXFBConfig that glXChooseFBConfig()
- // returns, since this is not cached with X11GraphicsConfig and there
- // are no public constructors to allow us to extend it.
- synchronized (Canvas3D.fbConfigTable) {
- if (Canvas3D.fbConfigTable.get(gc1) == null) {
- GraphicsConfigInfo gcInfo = new GraphicsConfigInfo();
- gcInfo.setFBConfig(fbConfig[0]);
- gcInfo.setRequestedStencilSize(attrList[STENCIL_SIZE]);
- Canvas3D.fbConfigTable.put(gc1, gcInfo);
- } else {
- freeFBConfig(fbConfig[0]);
- }
- }
-
- return gc1;
- }
-
- /*
- * Determine if a given GraphicsConfiguration object can be used
- * by Java 3D.
- */
- boolean isGraphicsConfigSupported(GraphicsConfigTemplate3D template,
- GraphicsConfiguration gc) {
-
- X11GraphicsDevice gd =
- (X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
-
- if (!NativeScreenInfo.isGLX13()) {
- return false;
- }
-
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
-
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
-
- int[] attrList; // holds the list of attributes to be tramslated
- // for glxChooseVisual call
-
- attrList = new int[NUM_ITEMS];
-
- // assign template values to array
- attrList[RED_SIZE] = template.getRedSize();
- attrList[GREEN_SIZE] = template.getGreenSize();
- attrList[BLUE_SIZE] = template.getBlueSize();
-
- attrList[DEPTH_SIZE] = template.getDepthSize();
- attrList[DOUBLEBUFFER] = template.getDoubleBuffer();
- attrList[STEREO] = template.getStereo();
- attrList[ANTIALIASING] = template.getSceneAntialiasing();
- attrList[STENCIL_SIZE] = template.getStencilSize();
- // System.out.println("NativeConfigTemplate3D : getStencilSize " +
- // attrList[STENCIL_SIZE]);
-
- long[] fbConfig = new long[1];
- int visID = chooseOglVisual(display, screen, attrList, fbConfig);
-
- if (visID == 0 || fbConfig[0] == 0)
- return false; // no valid visual was found
- else
- return true;
- }
-
-
- // Return whether stereo is available.
- boolean hasStereo(Canvas3D c3d) {
- GraphicsConfiguration gc = c3d.graphicsConfiguration;
-
- X11GraphicsDevice gd =
- (X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
-
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
- int vid = ((X11GraphicsConfig)gc).getVisual();
-
- return isStereoAvailable(display, screen, vid);
- }
-
-
- // Return the stencil of this canvas.
- int getStencilSize(Canvas3D c3d) {
- GraphicsConfiguration gc = c3d.graphicsConfiguration;
-
- X11GraphicsDevice gd =
- (X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
-
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
- int vid = ((X11GraphicsConfig)gc).getVisual();
-
- return getStencilSize(display, screen, vid);
- }
-
- // Return whether a double buffer is available.
- boolean hasDoubleBuffer(Canvas3D c3d) {
- GraphicsConfiguration gc = c3d.graphicsConfiguration;
-
- X11GraphicsDevice gd =
- (X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
-
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
- int vid = ((X11GraphicsConfig)gc).getVisual();
-
- return isDoubleBufferAvailable(display, screen, vid);
- }
-
- // Return whether scene antialiasing is available.
- boolean hasSceneAntialiasingAccum(Canvas3D c3d) {
- GraphicsConfiguration gc = c3d.graphicsConfiguration;
-
- X11GraphicsDevice gd =
- (X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
-
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
- int vid = ((X11GraphicsConfig)gc).getVisual();
-
- return isSceneAntialiasingAccumAvailable(display, screen, vid);
- }
-
-
- // Return whether scene antialiasing is available.
- boolean hasSceneAntialiasingMultisample(Canvas3D c3d) {
- GraphicsConfiguration gc = c3d.graphicsConfiguration;
-
- X11GraphicsDevice gd =
- (X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
-
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
- int vid = ((X11GraphicsConfig)gc).getVisual();
-
- return isSceneAntialiasingMultisampleAvailable(display, screen, vid);
- }
-
- // Ensure that the native libraries are loaded
- static {
- VirtualUniverse.loadLibraries();
- }
-}
diff --git a/src/classes/linux/javax/media/j3d/NativeScreenInfo.java b/src/classes/linux/javax/media/j3d/NativeScreenInfo.java
deleted file mode 100644
index cbf44fe..0000000
--- a/src/classes/linux/javax/media/j3d/NativeScreenInfo.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-/*
- * Portions of this code were derived from work done by the Blackdown
- * group (www.blackdown.org), who did the initial Linux implementation
- * of the Java 3D API.
- */
-
-package javax.media.j3d;
-
-import java.awt.GraphicsDevice;
-import sun.awt.X11GraphicsDevice;
-
-class NativeScreenInfo {
- private int screen;
- private static long display = 0;
- private static boolean glxChecked = false;
- private static boolean isGLX13;
-
- private native static long openDisplay();
- private native static int getDefaultScreen(long display);
- private native static boolean queryGLX13(long display);
-
- // Fix for issue 20.
- // This method will return true if glx version is 1.3 or higher,
- // else return false.
- synchronized static boolean isGLX13() {
- if (!glxChecked) {
- // Open a new static display connection if one is not already opened.
- getStaticDisplay();
- // Query for glx1.3 support.
- isGLX13 = queryGLX13(display);
- glxChecked = true;
- }
-
- return isGLX13;
- }
-
-
- synchronized static long getStaticDisplay() {
- if (display == 0) {
- display = openDisplay();
- }
- return display;
- }
-
- NativeScreenInfo(GraphicsDevice graphicsDevice) {
- // Open a new static display connection if one is not already opened
- getStaticDisplay();
-
- // Get the screen number
- screen = ((X11GraphicsDevice)graphicsDevice).getScreen();
- }
-
- long getDisplay() {
- return display;
- }
-
- int getScreen() {
- return screen;
- }
-
-
- // Ensure that the native libraries are loaded
- static {
- VirtualUniverse.loadLibraries();
- }
-}
diff --git a/src/classes/linux/javax/media/j3d/NativeWSInfo.java b/src/classes/linux/javax/media/j3d/NativeWSInfo.java
deleted file mode 100644
index 894f2a8..0000000
--- a/src/classes/linux/javax/media/j3d/NativeWSInfo.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-/*
- * Portions of this code were derived from work done by the Blackdown
- * group (www.blackdown.org), who did the initial Linux implementation
- * of the Java 3D API.
- */
-
-package javax.media.j3d;
-
-import java.awt.*;
-import java.awt.event.*;
-import sun.awt.*;
-import java.lang.reflect.Method;
-
-class NativeWSInfo {
-
- //X11DrawingSurface xds;
- Object xds;
-
- void getCanvasWSParameters(Canvas3D canvas) {
- try {
- Class x11DSclass = Class.forName("sun.awt.X11DrawingSurface");
- Method getDrawable = x11DSclass.getDeclaredMethod("getDrawable", null );
- Method getVisualID = x11DSclass.getDeclaredMethod("getVisualID", null );
-
- //canvas.window = xds.getDrawable();
- //canvas.vid = xds.getVisualID();
-
- canvas.window = ((Integer)getDrawable.invoke( xds, null )).intValue();
- canvas.vid = ((Integer)getVisualID.invoke( xds, null )).intValue();
- } catch( Exception e ) {
- e.printStackTrace();
- }
- }
-
- void getWSDrawingSurface( Object dsi) {
- try {
- //xds = (X11DrawingSurface)dsi.getSurface();
- Class drawingSurfaceInfoClass = Class.forName("sun.awt.DrawingSurfaceInfo");
- Method getSurface = drawingSurfaceInfoClass.getDeclaredMethod( "getSurface", null);
-
- //xds = dsi.getSurface();
- xds = getSurface.invoke( dsi, null );
- } catch( Exception e ) {
- e.printStackTrace();
- }
- }
-
- int getCanvasVid(GraphicsConfiguration gcfg) {
- return (((X11GraphicsConfig)gcfg).getVisual());
- }
-}
-
diff --git a/src/classes/share/javax/media/j3d/AlternateAppearanceRetained.java b/src/classes/share/javax/media/j3d/AlternateAppearanceRetained.java
index 3e76132..d6f05b4 100644
--- a/src/classes/share/javax/media/j3d/AlternateAppearanceRetained.java
+++ b/src/classes/share/javax/media/j3d/AlternateAppearanceRetained.java
@@ -587,7 +587,7 @@ class AlternateAppearanceRetained extends LeafRetained {
// Initialize the mirror object, this needs to be done, when
// renderBin is not accessing any of the fields
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.ALTERNATEAPPEARANCE_CHANGED;
@@ -721,7 +721,7 @@ class AlternateAppearanceRetained extends LeafRetained {
if (scopes.size() > 0) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.ALTERNATEAPPEARANCE_CHANGED;
@@ -759,7 +759,7 @@ class AlternateAppearanceRetained extends LeafRetained {
}
final void sendMessage(int attrMask, Object attr) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.universe = universe;
createMessage.type = J3dMessage.ALTERNATEAPPEARANCE_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/AmbientLightRetained.java b/src/classes/share/javax/media/j3d/AmbientLightRetained.java
index 8aaa65c..6f19e5b 100644
--- a/src/classes/share/javax/media/j3d/AmbientLightRetained.java
+++ b/src/classes/share/javax/media/j3d/AmbientLightRetained.java
@@ -34,6 +34,6 @@ class AmbientLightRetained extends LightRetained {
VirtualUniverse.mc.processMessage(createMessage);
}
- void update(long ctx, int lightSlot, double scale) {
+ void update(Context ctx, int lightSlot, double scale) {
}
}
diff --git a/src/classes/share/javax/media/j3d/Appearance.java b/src/classes/share/javax/media/j3d/Appearance.java
index 5cfb429..ca60e41 100644
--- a/src/classes/share/javax/media/j3d/Appearance.java
+++ b/src/classes/share/javax/media/j3d/Appearance.java
@@ -535,12 +535,32 @@ public class Appearance extends NodeComponent {
* @exception IllegalStateException if the specified texture
* object is non-null and the texture unit state array in this
* appearance object is already non-null.
+ *
+ * @exception IllegalSharingException if this Appearance is live and
+ * the specified texture refers to an ImageComponent2D that is being used
+ * by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalSharingException if this Appearance is
+ * being used by an immediate mode context and
+ * the specified texture refers to an ImageComponent2D that is being used
+ * by a Canvas3D as an off-screen buffer.
*/
public void setTexture(Texture texture) {
if (isLiveOrCompiled())
if (!this.getCapability(ALLOW_TEXTURE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Appearance2"));
- ((AppearanceRetained)this.retained).setTexture(texture);
+
+ // Do illegal sharing check
+ if(texture != null) {
+ ImageComponent[] images = ((TextureRetained)(texture.retained)).getImages();
+ if(images != null) {
+ for(int i=0; i<images.length; i++) {
+ validateImageIllegalSharing(images[i]);
+ }
+ }
+ }
+
+ ((AppearanceRetained)this.retained).setTexture(texture);
}
/**
@@ -665,13 +685,35 @@ public class Appearance extends NodeComponent {
* object, or texCoordGeneration object in this appearance object
* is already non-null.
*
+ * @exception IllegalSharingException if this Appearance is live and
+ * any of the specified textures refers to an ImageComponent2D that is
+ * being used by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalSharingException if this Appearance is
+ * being used by an immediate mode context and
+ * any of the specified textures refers to an ImageComponent2D that is
+ * being used by a Canvas3D as an off-screen buffer.
+ *
* @since Java 3D 1.2
*/
public void setTextureUnitState(TextureUnitState[] stateArray) {
- if (isLiveOrCompiled())
- if (!this.getCapability(ALLOW_TEXTURE_UNIT_STATE_WRITE))
- throw new CapabilityNotSetException(J3dI18N.getString("Appearance20"));
-
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_TEXTURE_UNIT_STATE_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("Appearance20"));
+
+ // Do illegal sharing check
+ for(int j=0; j<stateArray.length; j++) {
+ TextureRetained texRetained = ((TextureUnitStateRetained)stateArray[j].retained).texture;
+ if(texRetained != null) {
+ ImageComponent[] images = texRetained.getImages();
+ if(images != null) {
+ for(int i=0; i<images.length; i++) {
+ validateImageIllegalSharing(images[i]);
+ }
+ }
+ }
+ }
+
((AppearanceRetained)this.retained).setTextureUnitState(stateArray);
}
@@ -693,6 +735,15 @@ public class Appearance extends NodeComponent {
* @exception ArrayIndexOutOfBoundsException if <code>index >=
* stateArray.length</code>.
*
+ * @exception IllegalSharingException if this Appearance is live and
+ * the specified texture refers to an ImageComponent2D that is being used
+ * by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalSharingException if this Appearance is
+ * being used by an immediate mode context and
+ * the specified texture refers to an ImageComponent2D that is being used
+ * by a Canvas3D as an off-screen buffer.
+ *
* @since Java 3D 1.2
*/
public void setTextureUnitState(int index, TextureUnitState state) {
@@ -700,6 +751,17 @@ public class Appearance extends NodeComponent {
if (!this.getCapability(ALLOW_TEXTURE_UNIT_STATE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Appearance20"));
+ // Do illegal sharing check
+ TextureRetained texRetained = ((TextureUnitStateRetained)state.retained).texture;
+ if(texRetained != null) {
+ ImageComponent[] images = texRetained.getImages();
+ if(images != null) {
+ for(int i=0; i<images.length; i++) {
+ validateImageIllegalSharing(images[i]);
+ }
+ }
+ }
+
((AppearanceRetained)this.retained).setTextureUnitState(index, state);
}
diff --git a/src/classes/share/javax/media/j3d/AppearanceRetained.java b/src/classes/share/javax/media/j3d/AppearanceRetained.java
index 8f919da..904fb50 100644
--- a/src/classes/share/javax/media/j3d/AppearanceRetained.java
+++ b/src/classes/share/javax/media/j3d/AppearanceRetained.java
@@ -131,15 +131,13 @@ class AppearanceRetained extends NodeComponentRetained {
Material getMaterial() {
return (material == null ? null : (Material)material.source);
}
-
+
/**
* Sets the texture object to the specified object.
* @param texture object that specifies the desired texture
* map and texture parameters
*/
void setTexture(Texture texture) {
-
-
synchronized(liveStateLock) {
if (source.isLive()) {
@@ -528,7 +526,7 @@ class AppearanceRetained extends NodeComponentRetained {
void setTextureUnitState(TextureUnitState[] stateArray) {
int i;
-
+
synchronized(liveStateLock) {
if (source.isLive()) {
@@ -604,8 +602,8 @@ class AppearanceRetained extends NodeComponentRetained {
}
void setTextureUnitState(int index, TextureUnitState state) {
-
- synchronized(liveStateLock) {
+
+ synchronized(liveStateLock) {
if (source.isLive()) {
// remove the existing texture unit states from this appearance
@@ -1038,7 +1036,8 @@ class AppearanceRetained extends NodeComponentRetained {
return flag;
}
- /*
+
+ // Issue 209 - enable this method (was previously commented out)
// Simply pass along to the NodeComponents
void compile(CompileState compState) {
setCompiled();
@@ -1090,7 +1089,6 @@ class AppearanceRetained extends NodeComponentRetained {
material.compile(compState);
}
}
- */
/**
* Returns the hashcode for this object.
@@ -1244,7 +1242,7 @@ class AppearanceRetained extends NodeComponentRetained {
ArrayList gaList = Shape3DRetained.getGeomAtomsList(mirror.users, univList);
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.APPEARANCE_CHANGED;
createMessage.universe = null;
@@ -1258,7 +1256,7 @@ class AppearanceRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.APPEARANCE_CHANGED;
@@ -1294,7 +1292,7 @@ class AppearanceRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_GEOMETRY;
createMessage.type = J3dMessage.RENDERINGATTRIBUTES_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/AttributeBin.java b/src/classes/share/javax/media/j3d/AttributeBin.java
index dcfa24d..25b64b8 100644
--- a/src/classes/share/javax/media/j3d/AttributeBin.java
+++ b/src/classes/share/javax/media/j3d/AttributeBin.java
@@ -88,15 +88,17 @@ class AttributeBin extends Object implements ObjectUpdate {
numEditingShaderBins = 0;
renderingAttrs = renderingAttributes;
- renderBin = rBin;
+ renderBin = rBin;
- if (app != null) {
- soleUser = ((app.changedFrequent & AppearanceRetained.RENDERING) != 0);
- }
- else {
- soleUser = false;
- }
- //System.out.println("soleUser = "+soleUser+" renderingAttributes ="+renderingAttributes);
+ // Issue 249 - check for sole user only if property is set
+ soleUser = false;
+ if (VirtualUniverse.mc.allowSoleUser) {
+ if (app != null) {
+ soleUser = ((app.changedFrequent & AppearanceRetained.RENDERING) != 0);
+ }
+ }
+
+ //System.out.println("soleUser = "+soleUser+" renderingAttributes ="+renderingAttributes);
// Set the appearance only for soleUser case
if (soleUser)
this.app = app;
@@ -272,7 +274,6 @@ class AttributeBin extends Object implements ObjectUpdate {
}
sb.clear();
- renderBin.shaderBinFreelist.add(sb);
if (shaderBinList == null && addShaderBins.size() == 0 ) {
// Note: Removal of this attributebin as a user of the rendering
diff --git a/src/classes/share/javax/media/j3d/BHInternalNode.java b/src/classes/share/javax/media/j3d/BHInternalNode.java
index 3a83a6e..0b59f33 100644
--- a/src/classes/share/javax/media/j3d/BHInternalNode.java
+++ b/src/classes/share/javax/media/j3d/BHInternalNode.java
@@ -188,9 +188,6 @@ class BHInternalNode extends BHNode {
rChild = null;
lChild = null;
-
- // add to free list ...
- FreeListManager.freeObject(FreeListManager.BHINTERNAL, this);
}
}
diff --git a/src/classes/share/javax/media/j3d/BHNode.java b/src/classes/share/javax/media/j3d/BHNode.java
index 14456e7..f5b3985 100644
--- a/src/classes/share/javax/media/j3d/BHNode.java
+++ b/src/classes/share/javax/media/j3d/BHNode.java
@@ -153,9 +153,6 @@ abstract class BHNode {
}
}
}
-
- // add to free list ...
- VirtualUniverse.mc.addBHNodeToFreelists(this);
}
// delete all leaf nodes marked with DELETE_UPDATE and update the
diff --git a/src/classes/share/javax/media/j3d/BHTree.java b/src/classes/share/javax/media/j3d/BHTree.java
index 6cb997e..3d53667 100644
--- a/src/classes/share/javax/media/j3d/BHTree.java
+++ b/src/classes/share/javax/media/j3d/BHTree.java
@@ -632,7 +632,7 @@ class BHTree {
}
*/
- root = VirtualUniverse.mc.getBHNode(BHNode.BH_TYPE_INTERNAL);
+ root = new BHInternalNode();
constructTree((BHInternalNode) root, bhArr, centerValues,
centerValuesIndex);
@@ -1045,7 +1045,7 @@ class BHTree {
}
if (rightSet.length != 1) {
- parent.rChild = VirtualUniverse.mc.getBHNode(BHNode.BH_TYPE_INTERNAL);
+ parent.rChild = new BHInternalNode();
parent.rChild.setParent(parent);
constructTree((BHInternalNode)(parent.rChild), rightSet, centerValues,
centerValuesIndexR);
@@ -1055,7 +1055,7 @@ class BHTree {
}
if (leftSet.length != 1) {
- parent.lChild = VirtualUniverse.mc.getBHNode(BHNode.BH_TYPE_INTERNAL);
+ parent.lChild = new BHInternalNode();
parent.lChild.setParent(parent);
constructTree((BHInternalNode)(parent.lChild), leftSet, centerValues,
centerValuesIndexL);
diff --git a/src/classes/share/javax/media/j3d/Background.java b/src/classes/share/javax/media/j3d/Background.java
index 7a86d7e..335cbec 100644
--- a/src/classes/share/javax/media/j3d/Background.java
+++ b/src/classes/share/javax/media/j3d/Background.java
@@ -289,10 +289,18 @@ public class Background extends Leaf {
* filled with the background color.
*
* @param image pixel array object used as the background image
+ *
+ * @exception IllegalArgumentException if the image class of the specified
+ * ImageComponent2D is ImageClass.NIO_IMAGE_BUFFER.
*/
public Background(ImageComponent2D image) {
// set default read capabilities
setDefaultReadCapabilities(readCapabilities);
+
+ if((image != null) &&
+ (image.getImageClass() == ImageComponent.ImageClass.NIO_IMAGE_BUFFER)) {
+ throw new IllegalArgumentException(J3dI18N.getString("Background14"));
+ }
((BackgroundRetained)this.retained).setImage(image);
}
@@ -379,19 +387,51 @@ public class Background extends Leaf {
* than the window,
* then that portion of the window not covered by the image is
* filled with the background color.
+ *
* @param image new pixel array object used as the background image
+ *
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalSharingException if this Background is live and
+ * the specified image is being used by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalSharingException if this Background is
+ * being used by an immediate mode context and
+ * the specified image is being used by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalArgumentException if the image class of the specified
+ * ImageComponent2D is ImageClass.NIO_IMAGE_BUFFER.
*/
public void setImage(ImageComponent2D image) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_IMAGE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Background3"));
+ BackgroundRetained bgRetained = (BackgroundRetained)this.retained;
+
+ if((image != null) &&
+ (image.getImageClass() == ImageComponent.ImageClass.NIO_IMAGE_BUFFER)) {
+ throw new IllegalArgumentException(J3dI18N.getString("Background14"));
+ }
+
+ // Do illegal sharing check
+ if(image != null) {
+ ImageComponent2DRetained imageRetained = (ImageComponent2DRetained) image.retained;
+ if(imageRetained.getUsedByOffScreen()) {
+ if(isLive()) {
+ throw new IllegalSharingException(J3dI18N.getString("Background12"));
+ }
+ if(bgRetained.getInImmCtx()) {
+ throw new IllegalSharingException(J3dI18N.getString("Background13"));
+ }
+ }
+ }
+
if (isLive())
- ((BackgroundRetained)this.retained).setImage(image);
+ bgRetained.setImage(image);
else
- ((BackgroundRetained)this.retained).initImage(image);
+ bgRetained.initImage(image);
}
/**
diff --git a/src/classes/share/javax/media/j3d/BackgroundRetained.java b/src/classes/share/javax/media/j3d/BackgroundRetained.java
index 92e01f3..d61a231 100644
--- a/src/classes/share/javax/media/j3d/BackgroundRetained.java
+++ b/src/classes/share/javax/media/j3d/BackgroundRetained.java
@@ -37,10 +37,11 @@ class BackgroundRetained extends LeafRetained {
// color.
Color3f color = new Color3f(0.0f, 0.0f, 0.0f);
ImageComponent2DRetained image = null;
-
+ Texture2DRetained texture = null;
+
// the image scale mode if image is used.
int imageScaleMode = Background.SCALE_NONE;
-
+
/**
* The Boundary object defining the lights's application region.
*/
@@ -101,12 +102,7 @@ class BackgroundRetained extends LeafRetained {
// Is true, if the background is viewScoped
boolean isViewScoped = false;
-
- // for texture mapping the background
- ImageComponent2DRetained texImage = null;
- int xmax = 0;
- int ymax = 0;
-
+
BackgroundRetained () {
this.nodeType = NodeRetained.BACKGROUND;
localBounds = new BoundingBox();
@@ -114,7 +110,6 @@ class BackgroundRetained extends LeafRetained {
((BoundingBox)localBounds).setUpper(-1.0,-1.0,-1.0);
}
-
/**
* Initializes the background color to the specified color.
* This color is used
@@ -202,81 +197,46 @@ class BackgroundRetained extends LeafRetained {
/**
* Initializes the background image to the specified image.
- * @param image new ImageCompoent3D object used as the background image
+ * @param image new ImageCompoent2D object used as the background image
*/
final void initImage(ImageComponent2D img) {
- if (img != null) {
- // scale to power of 2 for texture mapping
- ImageComponent2DRetained rimage = (ImageComponent2DRetained) img.retained;
-
- if (!VirtualUniverse.mc.isBackgroundTexture) {
- rimage.setRasterRef();
- }
- else {
-// rimage.setTextureRef();
-
- xmax = rimage.width;
- ymax = rimage.height;
- int width = getClosestPowerOf2(xmax);
- int height = getClosestPowerOf2(ymax);
- float xScale = (float)width/(float)xmax;
- float yScale = (float)height/(float)ymax;
-
- // scale if scales aren't 1.0
- if (!(xScale == 1.0f && yScale == 1.0f)) {
- BufferedImage origImg = (BufferedImage) rimage.getImage();
- AffineTransform at = AffineTransform.getScaleInstance(xScale,
- yScale);
- AffineTransformOp atop = new AffineTransformOp(at,
- AffineTransformOp.TYPE_BILINEAR);
- BufferedImage scaledImg = atop.filter(origImg, null);
- int format = rimage.getFormat();
- boolean yUp = rimage.isYUp();
- boolean byRef = rimage.isByReference();
- ImageComponent2D ic = new ImageComponent2D(format,
- scaledImg,
- byRef, yUp);
- texImage = (ImageComponent2DRetained)ic.retained;
- texImage.setTextureRef();
- //rimage.setTextureRef();
- //texImage.setRasterRef();
- }
- else {
- texImage = rimage;
- texImage.setTextureRef();
- //rimage.setTextureRef();
- //texImage.setRasterRef();
- }
- }
-
- this.image = rimage;
- } else {
- this.image = null;
- this.texImage = null;
- }
- }
+ int texFormat;
- private int getClosestPowerOf2(int value) {
-
- if (value < 1)
- return value;
-
- int powerValue = 1;
- for (;;) {
- powerValue *= 2;
- if (value < powerValue) {
- // Found max bound of power, determine which is closest
- int minBound = powerValue/2;
- if ((powerValue - value) >
- (value - minBound))
- return minBound;
- else
- return powerValue;
- }
- }
- }
+ if (img == null) {
+ image = null;
+ texture = null;
+ return;
+ }
+ if (img.retained != image ) {
+ image = (ImageComponent2DRetained) img.retained;
+ image.setEnforceNonPowerOfTwoSupport(true);
+ switch(image.getNumberOfComponents()) {
+ case 1:
+ texFormat = Texture.INTENSITY;
+ break;
+ case 2:
+ texFormat = Texture.LUMINANCE_ALPHA;
+ break;
+ case 3:
+ texFormat = Texture.RGB;
+ break;
+ case 4:
+ texFormat = Texture.RGBA;
+ break;
+ default:
+ assert false;
+ return;
+ }
+ Texture2D tex2D = new Texture2D(Texture.BASE_LEVEL, texFormat,
+ img.getWidth(), img.getHeight());
+ texture = (Texture2DRetained) tex2D.retained;
+ // Background is special case of Raster.
+ texture.setUseAsRaster(true);
+ texture.initImage(0,img);
+ }
+ }
/**
* Sets the background image to the specified image.
@@ -284,19 +244,22 @@ class BackgroundRetained extends LeafRetained {
*/
final void setImage(ImageComponent2D img) {
if (source.isLive()) {
- if (this.image != null) {
- this.image.clearLive(refCount);
+ if (texture != null) {
+ texture.clearLive(refCount);
+ texture.removeUser(this);
}
}
initImage(img);
- if (source.isLive()) {
- if (img != null) {
- ((ImageComponent2DRetained)
- img.retained).setLive(inBackgroundGroup, refCount);
- }
- sendMessage(IMAGE_CHANGED,
- (image != null ? image.clone() : null));
- }
+ if (source.isLive()) {
+ if (texture != null) {
+ texture.setLive(inBackgroundGroup, refCount);
+ texture.addUser(this);
+ }
+
+ sendMessage(IMAGE_CHANGED,
+ (texture != null ? texture.mirror : null));
+
+ }
}
/**
@@ -333,7 +296,7 @@ class BackgroundRetained extends LeafRetained {
numMessages+=2; // INSERT_NODES, ORDERED_GROUP_INSERTED
m = new J3dMessage[numMessages];
for (i=0; i<numMessages; i++) {
- m[i] = VirtualUniverse.mc.getMessage();
+ m[i] = new J3dMessage();
}
i = 0;
if (geometryBranch != null) {
@@ -408,7 +371,7 @@ class BackgroundRetained extends LeafRetained {
initApplicationBounds(region);
// Don't send the message if there is a valid boundingleaf
if (boundingLeaf == null) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads |
J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.type = J3dMessage.BACKGROUND_CHANGED;
@@ -456,7 +419,7 @@ class BackgroundRetained extends LeafRetained {
} else {
boundingLeaf = null;
}
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads |
J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.type = J3dMessage.BACKGROUND_CHANGED;
@@ -539,7 +502,6 @@ class BackgroundRetained extends LeafRetained {
}
-
/**
* This setLive routine first calls the superclass's method, then
* it adds itself to the list of lights
@@ -637,8 +599,8 @@ class BackgroundRetained extends LeafRetained {
s.notifyThreads |= J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER;
- if (image != null) {
- image.setLive(inBackgroundGroup, refCount);
+ if (texture != null) {
+ texture.setLive(inBackgroundGroup, refCount);
}
super.markAsLive();
@@ -680,17 +642,14 @@ class BackgroundRetained extends LeafRetained {
fogs.clear();
}
- if (image != null) {
- image.clearLive(refCount);
+ if (texture != null) {
+ texture.clearLive(refCount);
}
s.notifyThreads |= J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER;
}
-
-
-
// The update Object function.
synchronized void updateImmediateMirrorObject(Object[] objs) {
int component = ((Integer)objs[1]).intValue();
@@ -761,7 +720,7 @@ class BackgroundRetained extends LeafRetained {
final void sendMessage(int attrMask, Object attr) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.universe = universe;
createMessage.type = J3dMessage.BACKGROUND_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/BehaviorRetained.java b/src/classes/share/javax/media/j3d/BehaviorRetained.java
index d292ba9..7b17f0e 100644
--- a/src/classes/share/javax/media/j3d/BehaviorRetained.java
+++ b/src/classes/share/javax/media/j3d/BehaviorRetained.java
@@ -346,11 +346,14 @@ class BehaviorRetained extends LeafRetained {
((Behavior)this.source).initialize();
}
catch (RuntimeException e) {
- inCallback = inCallbackSaved;
- inInitCallback = inInitCallbackSaved;
System.err.println("Exception occurred during Behavior initialization:");
e.printStackTrace();
}
+ catch (Error e) {
+ // Issue 264 - catch Error
+ System.err.println("Error occurred during Behavior initialization:");
+ e.printStackTrace();
+ }
inCallback = inCallbackSaved;
inInitCallback = inInitCallbackSaved;
}
@@ -482,7 +485,7 @@ class BehaviorRetained extends LeafRetained {
void addWakeupCondition() {}
final void sendMessage(int mtype, Object arg) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_BEHAVIOR;
createMessage.type = mtype;
createMessage.universe = universe;
diff --git a/src/classes/share/javax/media/j3d/BehaviorScheduler.java b/src/classes/share/javax/media/j3d/BehaviorScheduler.java
index fa9cf09..d9f31f1 100644
--- a/src/classes/share/javax/media/j3d/BehaviorScheduler.java
+++ b/src/classes/share/javax/media/j3d/BehaviorScheduler.java
@@ -178,6 +178,13 @@ class BehaviorScheduler extends J3dThread {
System.err.println("Exception occurred during Behavior execution:");
e.printStackTrace();
}
+ catch (Error e) {
+ // Force behavior condition to be unset
+ // Fix for issue 264
+ behavret.conditionSet = false;
+ System.err.println("Error occurred during Behavior execution:");
+ e.printStackTrace();
+ }
univ.inBehavior = false;
behavret.inCallback = false;
}
diff --git a/src/classes/share/javax/media/j3d/BehaviorStructure.java b/src/classes/share/javax/media/j3d/BehaviorStructure.java
index 66a4780..a7db263 100644
--- a/src/classes/share/javax/media/j3d/BehaviorStructure.java
+++ b/src/classes/share/javax/media/j3d/BehaviorStructure.java
@@ -1530,7 +1530,7 @@ class BehaviorStructure extends J3dStructure {
scheduleList.remove(behav);
behav.active = false;
if (behav.universe != universe) {
- J3dMessage m = VirtualUniverse.mc.getMessage();
+ J3dMessage m = new J3dMessage();
m.threads = J3dThread.UPDATE_BEHAVIOR;
m.type = J3dMessage.BEHAVIOR_REEVALUATE;
m.universe = behav.universe;
diff --git a/src/classes/share/javax/media/j3d/Billboard.java b/src/classes/share/javax/media/j3d/Billboard.java
index b76ad13..272e2da 100644
--- a/src/classes/share/javax/media/j3d/Billboard.java
+++ b/src/classes/share/javax/media/j3d/Billboard.java
@@ -312,9 +312,9 @@ public class Billboard extends Behavior {
Canvas3D canvas = (Canvas3D)v.getCanvas3D(0);
boolean status;
- Transform3D xform = VirtualUniverse.mc.getTransform3D(null);
- Transform3D bbXform = VirtualUniverse.mc.getTransform3D(null);
- Transform3D prevTransform = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D xform = new Transform3D();
+ Transform3D bbXform = new Transform3D();
+ Transform3D prevTransform = new Transform3D();
((TransformGroupRetained) tg.retained).getTransform(prevTransform);
@@ -400,7 +400,7 @@ public class Billboard extends Behavior {
// Need to rotate Z axis to point to eye, and Y axis to be
// parallel to view platform Y axis, rotating around rotation pt
- Transform3D zRotate = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D zRotate = new Transform3D();
// get the eye point
canvas.getCenterEyeInImagePlate(viewPosition);
@@ -534,15 +534,10 @@ public class Billboard extends Behavior {
tg.setTransform(bbXform);
}
}
- VirtualUniverse.mc.addToTransformFreeList(zRotate);
}
// Insert wakeup condition into queue
wakeupOn(wakeupFrame);
-
- VirtualUniverse.mc.addToTransformFreeList(xform);
- VirtualUniverse.mc.addToTransformFreeList(bbXform);
- VirtualUniverse.mc.addToTransformFreeList(prevTransform);
}
private boolean projectToPlane(Vector3d projVec, Vector3d planeVec) {
diff --git a/src/classes/share/javax/media/j3d/BoundingLeafRetained.java b/src/classes/share/javax/media/j3d/BoundingLeafRetained.java
index 61555bd..584737c 100644
--- a/src/classes/share/javax/media/j3d/BoundingLeafRetained.java
+++ b/src/classes/share/javax/media/j3d/BoundingLeafRetained.java
@@ -78,7 +78,7 @@ class BoundingLeafRetained extends LeafRetained {
*/
void setRegion(Bounds region) {
initRegion(region);
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = mirrorBoundingLeaf.targetThreads;
createMessage.type = J3dMessage.BOUNDINGLEAF_CHANGED;
createMessage.universe = universe;
diff --git a/src/classes/share/javax/media/j3d/BoundingPolytope.java b/src/classes/share/javax/media/j3d/BoundingPolytope.java
index c3f3408..30fa36f 100644
--- a/src/classes/share/javax/media/j3d/BoundingPolytope.java
+++ b/src/classes/share/javax/media/j3d/BoundingPolytope.java
@@ -816,7 +816,7 @@ public class BoundingPolytope extends Bounds {
int i;
double invMag;
- Transform3D invTrans = VirtualUniverse.mc.getTransform3D(matrix);
+ Transform3D invTrans = new Transform3D(matrix);
invTrans.invert();
invTrans.transpose();
@@ -828,8 +828,6 @@ public class BoundingPolytope extends Bounds {
planes[i].w = planes[i].w * mag[i];
invTrans.transform( planes[i] );
}
-
- VirtualUniverse.mc.addToTransformFreeList(invTrans);
for(i=0;i<planes.length;i++) {
diff --git a/src/classes/share/javax/media/j3d/BranchGroupRetained.java b/src/classes/share/javax/media/j3d/BranchGroupRetained.java
index ab68682..933800d 100644
--- a/src/classes/share/javax/media/j3d/BranchGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/BranchGroupRetained.java
@@ -65,11 +65,13 @@ class BranchGroupRetained extends GroupRetained {
GroupRetained oldParent = (GroupRetained)parent;
do_detach();
universe.setLiveState.clear();
- if (isLive)
- if (oldParent==null)
+ if (isLive) {
+ if (oldParent==null) {
universe.notifyStructureChangeListeners(false,locale,(BranchGroup)this.source);
- else
+ } else {
universe.notifyStructureChangeListeners(false,oldParent.source, (BranchGroup)this.source);
+ }
+ }
}
universe.waitForMC();
} else { // Not live yet, just do it.
diff --git a/src/classes/share/javax/media/j3d/Canvas3D.java b/src/classes/share/javax/media/j3d/Canvas3D.java
index af9020b..1b85eed 100644
--- a/src/classes/share/javax/media/j3d/Canvas3D.java
+++ b/src/classes/share/javax/media/j3d/Canvas3D.java
@@ -14,12 +14,10 @@ package javax.media.j3d;
import javax.vecmath.*;
import java.awt.*;
-import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.*;
-
/**
* The Canvas3D class provides a drawing canvas for 3D rendering. It
* is used either for on-screen rendering or off-screen rendering.
@@ -322,16 +320,23 @@ public class Canvas3D extends Canvas {
//
boolean offScreen = false;
+ //
+ // Issue 131: Flag that indicates whether this Canvas3D is a manually
+ // rendered Canvas3D (versus an automatically rendered Canvas3D).
+ //
+ // NOTE: manualRendering only applies to off-screen Canvas3Ds at this time.
+ // We have no plans to ever change this, but if we do, it might be necessary
+ // to determine which, if any, of the uses of "manualRendering" should be
+ // changed to "manualRendering&&offScreen"
+ //
+ boolean manualRendering = false;
+
// user specified offScreen Canvas location
Point offScreenCanvasLoc;
// user specified offScreen Canvas dimension
Dimension offScreenCanvasSize;
- // clipped offscreen canvas
- Point offScreenCanvasClippedLoc;
- Dimension offScreenCanvasClippedSize;
-
//
// Flag that indicates whether off-screen rendering is in progress or not
//
@@ -348,9 +353,6 @@ public class Canvas3D extends Canvas {
//
ImageComponent2D offScreenBuffer = null;
- // read buffer for reading off screen buffer
- byte[] byteBuffer = new byte[1];
-
// flag that indicates whether this canvas will use shared context
boolean useSharedCtx = true;
@@ -430,13 +432,6 @@ public class Canvas3D extends Canvas {
//
int textureColorTableSize;
- // a mapping between underlying graphics library texture unit and
- // texture unit state in j3d
- //
- // TODO: This mapping is now required to be 1-to-1, and it should be
- // removed entirely in Java 3D 1.5
- int[] texUnitStateMap = null;
-
// number of active/enabled texture unit
int numActiveTexUnit = 0;
@@ -450,6 +445,9 @@ public class Canvas3D extends Canvas {
// Query properties
J3dQueryProps queryProps;
+ // Flag indicating a fatal rendering error of some sort
+ private boolean fatalError = false;
+
//
// The positions of the manual left and right eyes in image-plate
// coordinates.
@@ -581,14 +579,9 @@ public class Canvas3D extends Canvas {
// NOTE that this is *read-only*
Transform3D vpcToEc;
- // The window field when running Windows is the native HDC. With X11 it
- // is the handle to the native X11 drawable.
- int window = 0;
-
- // The vid field when running Windows is the pixel format. With X11 it is
- // the visual id.
- int vid = 0;
-
+ // Opaque object representing the underlying drawable (window). This
+ // is defined by the Pipeline.
+ Drawable drawable = null;
// fbConfig is a pointer to the fbConfig object that is associated with
// the GraphicsConfiguration object used to create this Canvas.
@@ -602,37 +595,35 @@ public class Canvas3D extends Canvas {
// For Windows : Fix for issue 76. This is use as a holder of the
// PixelFormat structure ( see also gldef.h ) to allow value such
// as offScreen's pixelformat, and ARB function pointers to be stored.
- long fbConfig = 0;
- GraphicsConfigInfo gcInfo = null;
-
+ long fbConfig = 0;
+
// offScreenBufferInfo is a pointer to additional information about the
// offScreenBuffer in this Canvas.
//
// For Windows : Fix for issue 76.
long offScreenBufferInfo = 0;
- // fbConfigTable is a static hashtable which allows getBestConfiguration()
+ // graphicsConfigTable is a static hashtable which allows getBestConfiguration()
// in NativeConfigTemplate3D to map a GraphicsConfiguration to the pointer
// to the actual GLXFBConfig that glXChooseFBConfig() returns. The Canvas3D
// doesn't exist at the time getBestConfiguration() is called, and
// X11GraphicsConfig neither maintains this pointer nor provides a public
// constructor to allow Java 3D to extend it.
- // static Hashtable fbConfigInfoTable = new Hashtable(); -- Chien
- static Hashtable fbConfigTable = new Hashtable();
+ static Hashtable<GraphicsConfiguration,GraphicsConfigInfo> graphicsConfigTable =
+ new Hashtable<GraphicsConfiguration,GraphicsConfigInfo>();
// The native graphics version, vendor, and renderer information
- private String nativeGraphicsVersion = "<UNKNOWN>";
- private String nativeGraphicsVendor = "<UNKNOWN>";
- private String nativeGraphicsRenderer = "<UNKNOWN>";
+ String nativeGraphicsVersion = "<UNKNOWN>";
+ String nativeGraphicsVendor = "<UNKNOWN>";
+ String nativeGraphicsRenderer = "<UNKNOWN>";
- NativeWSInfo nativeWSobj = new NativeWSInfo();
boolean firstPaintCalled = false;
// This reflects whether or not this canvas has seen an addNotify.
boolean added = false;
// This is the id for the underlying graphics context structure.
- long ctx = 0;
+ Context ctx = null;
// since the ctx id can be the same as the previous one,
// we need to keep a time stamp to differentiate the contexts with the
@@ -672,6 +663,7 @@ public class Canvas3D extends Canvas {
TransparencyAttributesRetained transparency = null;
ColoringAttributesRetained coloringAttributes = null;
Transform3D modelMatrix = null;
+ Transform3D projTrans = null;
TextureBin textureBin = null;
@@ -687,13 +679,6 @@ public class Canvas3D extends Canvas {
TextureUnitStateRetained[] texUnitState = null;
/**
- * cached View states for lazy native states update
- */
- // - DVR support.
- float cachedDvrFactor = 1.0f;
- boolean cachedDvrResizeCompensation = true;
-
- /**
* These cached values are only used in Pure Immediate and Mixed Mode rendering
*/
TextureRetained texture = null;
@@ -779,22 +764,18 @@ public class Canvas3D extends Canvas {
// Use by D3D to indicate using one pass Blend mode
// if Texture interpolation mode is support.
static final int TEXTURE_LERP = 0x4000;
+ static final int TEXTURE_NON_POWER_OF_TWO = 0x8000;
int textureExtendedFeatures = 0;
// Extensions supported by the underlying canvas
- static final int SUN_GLOBAL_ALPHA = 0x1;
- static final int EXT_ABGR = 0x2;
- static final int EXT_BGR = 0x4;
- static final int EXT_RESCALE_NORMAL = 0x8;
- static final int EXT_MULTI_DRAW_ARRAYS = 0x10;
- static final int SUN_MULTI_DRAW_ARRAYS = 0x20;
- static final int SUN_CONSTANT_DATA = 0x40;
- static final int EXT_SEPARATE_SPECULAR_COLOR = 0x80;
- static final int ARB_TRANSPOSE_MATRIX = 0x100;
- static final int ARB_MULTISAMPLE = 0x200;
- static final int EXT_COMPILED_VERTEX_ARRAYS = 0x400;
- static final int SUN_VIDEO_RESIZE = 0x800;
+ //
+ // NOTE: we should remove EXT_BGR and EXT_ABGR when the imaging code is
+ // rewritten
+ static final int SUN_GLOBAL_ALPHA = 0x1;
+ static final int EXT_ABGR = 0x2;
+ static final int EXT_BGR = 0x4;
+ static final int MULTISAMPLE = 0x8;
// The following 10 variables are set by the native
// createNewContext()/createQueryContext() methods
@@ -876,93 +857,6 @@ public class Canvas3D extends Canvas {
// specifies if each bin in this set is updated or not.
Object curStateToUpdate[] = new Object[7];
-
- // Native method for determining the texture color table size
- // in the underlying API for this Canvas3D.
- /* native int getTextureColorTableSize(long ctx); */
-
- // This is the native method for creating the underlying graphics context.
- private native long createNewContext(long display, int window, int vid,
- long fbConfig, long shareCtx, boolean isSharedCtx,
- boolean offScreen,
- boolean glslLibraryAvailable,
- boolean cgLibraryAvailable);
-
- private native void createQueryContext(long display, int window, int vid,
- long fbConfig, boolean offScreen, int width, int height,
- boolean glslLibraryAvailable,
- boolean cgLibraryAvailable);
-
- native static void destroyContext(long display, int window, long context);
-
- // This is the native for creating offscreen buffer
- native int createOffScreenBuffer(long ctx, long display, int vid, long fbConfig, int width, int height);
-
- native void destroyOffScreenBuffer(long ctx, long display, long fbConfig, int window);
-
- // This is the native for reading the image from the offscreen buffer
- native void readOffScreenBuffer(long ctx, int format, int width, int height);
-
- // This is the native method for doing accumulation.
- native void accum(long ctx, float value );
-
- // This is the native method for doing accumulation return.
- native void accumReturn(long ctx);
-
- // This is the native method for clearing the accumulation buffer.
- native void clearAccum(long ctx);
-
- // This is the native method for getting the number of lights the underlying
- // native library can support.
- native int getNumCtxLights(long ctx);
-
- // Native method for decal 1st child setup
- native boolean decal1stChildSetup(long ctx);
-
- // Native method for decal nth child setup
- native void decalNthChildSetup(long ctx);
-
- // Native method for decal reset
- native void decalReset(long ctx, boolean depthBufferEnable);
-
- // Native method for decal reset
- native void ctxUpdateEyeLightingEnable(long ctx, boolean localEyeLightingEnable);
-
- // The following three methods are used in multi-pass case
-
- // native method for setting blend color
- native void setBlendColor(long ctx, float red, float green,
- float blue, float alpha);
-
- // native method for setting blend func
- native void setBlendFunc(long ctx, int src, int dst);
-
- // native method for setting fog enable flag
- native void setFogEnableFlag(long ctx, boolean enableFlag);
-
- // Setup the full scene antialising in D3D and ogl when GL_ARB_multisamle supported
- native void setFullSceneAntialiasing(long ctx, boolean enable);
-
- // notify D3D that Canvas is resize
- native int resizeD3DCanvas(long ctx);
-
- // notify D3D to toggle between FullScreen and window mode
- native int toggleFullScreenMode(long ctx);
-
- native void setGlobalAlpha(long ctx, float alpha);
- native void disableGlobalAlpha(long ctx);
-
- // Native method to update separate specular color control
- native void updateSeparateSpecularColorEnable(long ctx, boolean control);
-
- // Initialization for D3D when scene begin
- native void beginScene(long ctx);
- native void endScene(long ctx);
-
- // True under Solaris,
- // False under windows when display mode <= 8 bit
- native boolean validGraphicsMode();
-
/**
* The list of lights that are currently being represented in the native
* graphics context.
@@ -1011,108 +905,62 @@ public class Canvas3D extends Canvas {
// and canvas removeNotify() called while Renderer is running
boolean ctxChanged = false;
- // native method for setting light enables
- native void setLightEnables(long ctx, long enableMask, int maxLights);
-
- // native method for setting scene ambient
- native void setSceneAmbient(long ctx, float red, float green, float blue);
-
- // native method for disabling fog
- native void disableFog(long ctx);
-
- // native method for disabling modelClip
- native void disableModelClip(long ctx);
-
- // native method for setting default RenderingAttributes
- native void resetRenderingAttributes(long ctx,
- boolean depthBufferWriteEnableOverride,
- boolean depthBufferEnableOverride);
-
- // native method for setting default texture
- native void resetTextureNative(long ctx, int texUnitIndex);
-
- // native method for activating a particular texture unit
- native void activeTextureUnit(long ctx, int texUnitIndex);
-
- // native method for setting default TexCoordGeneration
- native void resetTexCoordGeneration(long ctx);
-
- // native method for setting default TextureAttributes
- native void resetTextureAttributes(long ctx);
-
- // native method for setting default PolygonAttributes
- native void resetPolygonAttributes(long ctx);
-
- // native method for setting default LineAttributes
- native void resetLineAttributes(long ctx);
-
- // native method for setting default PointAttributes
- native void resetPointAttributes(long ctx);
-
- // native method for setting default TransparencyAttributes
- native void resetTransparency(long ctx, int geometryType,
- int polygonMode, boolean lineAA,
- boolean pointAA);
-
- // native method for setting default ColoringAttributes
- native void resetColoringAttributes(long ctx,
- float r, float g,
- float b, float a,
- boolean enableLight);
-
- // native method for setting Material when no material is present
- native void updateMaterial(long ctx, float r, float g, float b, float a);
-
-
- // native method for updating the texture unit state map
- private native void updateTexUnitStateMap(long ctx, int numActiveTexUnit,
- int[] texUnitStateMap);
-
- /**
- * This native method makes sure that the rendering for this canvas
- * gets done now.
- */
- native void syncRender(long ctx, boolean wait);
-
// Default graphics configuration
private static GraphicsConfiguration defaultGcfg = null;
// Returns default graphics configuration if user passes null
// into the Canvas3D constructor
private static synchronized GraphicsConfiguration defaultGraphicsConfiguration() {
- if (defaultGcfg == null) {
- GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
- defaultGcfg = GraphicsEnvironment.getLocalGraphicsEnvironment().
- getDefaultScreenDevice().getBestConfiguration(template);
- }
- return defaultGcfg;
+ if (defaultGcfg == null) {
+ GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
+ defaultGcfg = GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getBestConfiguration(template);
+ }
+ return defaultGcfg;
}
+ // Returns true if this is a valid graphics configuration, obtained
+ // via a GraphicsConfigTemplate3D.
+ private static boolean isValidConfig(GraphicsConfiguration gconfig) {
+ // If this is a valid GraphicsConfiguration object, then it will
+ // be in the graphicsConfigTable
+ return graphicsConfigTable.containsKey(gconfig);
+ }
+
+ // Checks the given graphics configuration, and throws an exception if
+ // the config is null or invalid.
private static synchronized GraphicsConfiguration
- checkForValidGraphicsConfig(GraphicsConfiguration gconfig) {
-
- if (gconfig == null) {
- // Print out warning if Canvas3D is called with a
- // null GraphicsConfiguration
- System.err.println("************************************************************************");
- System.err.println(J3dI18N.getString("Canvas3D7"));
- System.err.println(J3dI18N.getString("Canvas3D18"));
- System.err.println("************************************************************************");
- return defaultGraphicsConfiguration();
- }
+ checkForValidGraphicsConfig(GraphicsConfiguration gconfig, boolean offScreen) {
+
+ // Issue 266 - for backwards compatibility with legacy applications,
+ // we will accept a null GraphicsConfiguration for an on-screen Canvas3D
+ // only if the "allowNullGraphicsConfig" system property is set to true.
+ if (!offScreen && VirtualUniverse.mc.allowNullGraphicsConfig) {
+ if (gconfig == null) {
+ // Print out warning if Canvas3D is called with a
+ // null GraphicsConfiguration
+ System.err.println(J3dI18N.getString("Canvas3D7"));
+ System.err.println(" " + J3dI18N.getString("Canvas3D18"));
+
+ // Use a default graphics config
+ gconfig = defaultGraphicsConfiguration();
+ }
+ }
- if (!J3dGraphicsConfig.isValidConfig(gconfig)) {
- // Print out warning if Canvas3D is called with a
- // GraphicsConfiguration that wasn't created from a
- // GraphicsConfigTemplate3D (Solaris only).
- System.err.println("************************************************************************");
- System.err.println(J3dI18N.getString("Canvas3D21"));
- System.err.println(J3dI18N.getString("Canvas3D22"));
- System.err.println("************************************************************************");
- return defaultGraphicsConfiguration();
- }
+ // Validate input graphics config
+ if (gconfig == null) {
+ throw new NullPointerException(J3dI18N.getString("Canvas3D19"));
+ } else if (!isValidConfig(gconfig)) {
+ throw new IllegalArgumentException(J3dI18N.getString("Canvas3D17"));
+ }
+
+ return gconfig;
+ }
- return gconfig;
+ // Return the actual graphics config that will be used to construct
+ // the AWT Canvas. This is permitted to be non-unique or null.
+ private static GraphicsConfiguration getGraphicsConfig(GraphicsConfiguration gconfig) {
+ return Pipeline.getPipeline().getGraphicsConfig(gconfig);
}
/**
@@ -1144,11 +992,7 @@ public class Canvas3D extends Canvas {
* GraphicsConfiguration does not support 3D rendering
*/
public Canvas3D(GraphicsConfiguration graphicsConfiguration) {
- this(checkForValidGraphicsConfig(graphicsConfiguration), false);
-
- // XXXX: ENHANCEMENT -- remove call to checkForValidGraphicsConfig.
- // Call should then be:
- // this(graphicsConfiguration, false);
+ this(null, checkForValidGraphicsConfig(graphicsConfiguration, false), false);
}
/**
@@ -1173,64 +1017,71 @@ public class Canvas3D extends Canvas {
*
* @since Java 3D 1.2
*/
- public Canvas3D(GraphicsConfiguration graphicsConfiguration,
- boolean offScreen) {
+ public Canvas3D(GraphicsConfiguration graphicsConfiguration, boolean offScreen) {
+ this(null, checkForValidGraphicsConfig(graphicsConfiguration, offScreen), offScreen);
+ }
- super(graphicsConfiguration);
+ // Private constructor only called by the two public constructors after
+ // they have validated the graphics config (and possibly constructed a new
+ // default config).
+ // The graphics config must be valid, unique, and non-null.
+ private Canvas3D(Object dummyObj1,
+ GraphicsConfiguration graphicsConfiguration,
+ boolean offScreen) {
+ this(dummyObj1,
+ graphicsConfiguration,
+ getGraphicsConfig(graphicsConfiguration),
+ offScreen);
+ }
- if (graphicsConfiguration == null) {
- throw new NullPointerException
- (J3dI18N.getString("Canvas3D19"));
- }
+ // Private constructor only called by the previous private constructor.
+ // The graphicsConfiguration parameter is used by Canvas3D to lookup the
+ // graphics device and graphics template. The graphicsConfiguration2
+ // parameter is generated by the Pipeline from graphicsConfiguration and
+ // is only used to initialize the java.awt.Canvas.
+ private Canvas3D(Object dummyObj1,
+ GraphicsConfiguration graphicsConfiguration,
+ GraphicsConfiguration graphicsConfiguration2,
+ boolean offScreen) {
- if (!J3dGraphicsConfig.isValidConfig(graphicsConfiguration)) {
- throw new IllegalArgumentException
- (J3dI18N.getString("Canvas3D17"));
- }
-
- if (!J3dGraphicsConfig.isValidPixelFormat(graphicsConfiguration)) {
- throw new IllegalArgumentException
- (J3dI18N.getString("Canvas3D17"));
- }
+ super(graphicsConfiguration2);
this.offScreen = offScreen;
this.graphicsConfiguration = graphicsConfiguration;
- // Needed for Win32-D3D only.
- vid = nativeWSobj.getCanvasVid(graphicsConfiguration);
+ // Issue 131: Set the autoOffScreen variable based on whether this
+ // canvas3d implements the AutoOffScreenCanvas3D tagging interface.
+ // Eventually, we may replace this with an actual API.
+ boolean autoOffScreenCanvas3D = false;
+ if (this instanceof com.sun.j3d.exp.swing.impl.AutoOffScreenCanvas3D) {
+ autoOffScreenCanvas3D = true;
+ }
+
+ // Throw an illegal argument exception if an on-screen canvas is tagged
+ // as an auto-off-screen canvas
+ if (autoOffScreenCanvas3D && !offScreen) {
+ throw new IllegalArgumentException(J3dI18N.getString("Canvas3D25"));
+ }
// Issue 163 : Set dirty bits for both Renderer and RenderBin
cvDirtyMask[0] = VIEW_INFO_DIRTY;
cvDirtyMask[1] = VIEW_INFO_DIRTY;
- // Fix for issue 20.
- // Needed for Linux and Solaris.
- GraphicsConfigInfo gcInfo;
- gcInfo = (GraphicsConfigInfo) fbConfigTable.get(graphicsConfiguration);
- if (gcInfo != null) {
- fbConfig = gcInfo.getFBConfig();
- requestedStencilSize = gcInfo.getRequestedStencilSize();
-
- /*
- System.out.println("Canvas3D : requestedStencilSize is " +
- requestedStencilSize);
- System.out.println("Canvas3D creation FBConfig = " + fbConfig +
- " offScreen is " + offScreen );
- */
- // This check is needed for Unix and Win-ogl only. fbConfig should
- // remain as -1, default value, for D3D case.
- if (fbConfig == 0) {
- throw new IllegalArgumentException
- (J3dI18N.getString("Canvas3D23"));
- }
- }
-
+ GraphicsConfigInfo gcInfo = graphicsConfigTable.get(graphicsConfiguration);
+ requestedStencilSize = gcInfo.getGraphicsConfigTemplate3D().getStencilSize();
+
+ fbConfig = Pipeline.getPipeline().getFbConfig(gcInfo);
+
if (offScreen) {
- screen = new Screen3D(graphicsConfiguration, offScreen);
- // TODO: keep a list of off-screen Screen3D objects?
- // Does this list need to be grouped by GraphicsDevice?
+ // Issue 131: set manual rendering flag based on whether this is
+ // an auto-off-screen Canvas3D.
+ manualRendering = !autoOffScreenCanvas3D;
+
+ screen = new Screen3D(graphicsConfiguration, offScreen);
+ // QUESTION: keep a list of off-screen Screen3D objects?
+ // Does this list need to be grouped by GraphicsDevice?
// since this canvas will not receive the addNotify
// callback from AWT, set the added flag here
@@ -1243,22 +1094,26 @@ public class Canvas3D extends Canvas {
// this canvas will not receive the paint callback either,
// so set the necessary flags here as well
firstPaintCalled = true;
- ctx = 0;
+ ctx = null;
evaluateActive();
// create the rendererStructure object
//rendererStructure = new RendererStructure();
offScreenCanvasLoc = new Point(0, 0);
offScreenCanvasSize = new Dimension(0, 0);
- offScreenCanvasClippedLoc = new Point(0, 0);
- offScreenCanvasClippedSize = new Dimension(0, 0);
this.setLocation(offScreenCanvasLoc);
this.setSize(offScreenCanvasSize);
newSize = offScreenCanvasSize;
newPosition = offScreenCanvasLoc;
+ // Issue 131: create event catchers for auto-offScreen
+ if (!manualRendering) {
+ eventCatcher = new EventCatcher(this);
+ canvasViewEventCatcher = new CanvasViewEventCatcher(this);
+ }
} else {
+
GraphicsDevice graphicsDevice;
graphicsDevice = graphicsConfiguration.getDevice();
@@ -1278,24 +1133,30 @@ public class Canvas3D extends Canvas {
}
- drawingSurfaceObject = new DrawingSurfaceObjectAWT
- (this, VirtualUniverse.mc.awt, screen.display, screen.screen,
- VirtualUniverse.mc.xineramaDisabled);
-
lights = new LightRetained[VirtualUniverse.mc.maxLights];
frameCount = new int[VirtualUniverse.mc.maxLights];
for (int i=0; i<frameCount.length;i++) {
frameCount[i] = -1;
}
+ // Construct the drawing surface object for this Canvas3D
+ drawingSurfaceObject =
+ Pipeline.getPipeline().createDrawingSurfaceObject(this);
+
// Get double buffer, stereo available, scene antialiasing
- // flags from template.
+ // flags from graphics config
GraphicsConfigTemplate3D.getGraphicsConfigFeatures(this);
useDoubleBuffer = doubleBufferEnable && doubleBufferAvailable;
useStereo = stereoEnable && stereoAvailable;
useSharedCtx = VirtualUniverse.mc.isSharedCtx;
+ // Issue 131: assert that only an off-screen canvas can be demand-driven
+ assert (!offScreen && manualRendering) == false;
+
+ // Assert that offScreen is *not* double-buffered or stereo
+ assert (offScreen && useDoubleBuffer) == false;
+ assert (offScreen && useStereo) == false;
}
/**
@@ -1364,6 +1225,14 @@ public class Canvas3D extends Canvas {
* to function properly.
*/
public void addNotify() {
+
+ // Issue 131: This method is now being called by JCanvas3D for its
+ // off-screen Canvas3D, so we need to handle off-screen properly here.
+ // Do nothing for manually-rendered off-screen canvases
+ if (manualRendering) {
+ return;
+ }
+
Renderer rdr = null;
if (isRunning && (screen != null)) {
@@ -1378,9 +1247,11 @@ public class Canvas3D extends Canvas {
}
}
}
-
- super.addNotify();
+ // Issue 131: Don't call super for off-screen Canvas3D
+ if (!offScreen) {
+ super.addNotify();
+ }
screen.addUser(this);
parent = this.getParent();
@@ -1394,26 +1265,24 @@ public class Canvas3D extends Canvas {
((Window)parent).addComponentListener(eventCatcher);
}
- if (!offScreen) {
- if(canvasViewEventCatcher.parentList.size() > 0) {
- Component comp;
- //Release and clear.
- for(int i=0; i<canvasViewEventCatcher.parentList.size(); i++) {
- comp = (Component)canvasViewEventCatcher.parentList.get(i);
- comp.removeComponentListener(canvasViewEventCatcher);
- }
- canvasViewEventCatcher.parentList.clear();
- }
-
- Component parent = (Component) this.getParent();
- while(parent != null) {
- parent.addComponentListener(canvasViewEventCatcher);
- canvasViewEventCatcher.parentList.add(parent);
- parent = parent.getParent();
- }
- // Need to traverse up the parent and add listener.
- this.addComponentListener(canvasViewEventCatcher);
- }
+ if(canvasViewEventCatcher.parentList.size() > 0) {
+ Component comp;
+ //Release and clear.
+ for(int i=0; i<canvasViewEventCatcher.parentList.size(); i++) {
+ comp = (Component)canvasViewEventCatcher.parentList.get(i);
+ comp.removeComponentListener(canvasViewEventCatcher);
+ }
+ canvasViewEventCatcher.parentList.clear();
+ }
+
+ Component parent = (Component) this.getParent();
+ while(parent != null) {
+ parent.addComponentListener(canvasViewEventCatcher);
+ canvasViewEventCatcher.parentList.add(parent);
+ parent = parent.getParent();
+ }
+ // Need to traverse up the parent and add listener.
+ this.addComponentListener(canvasViewEventCatcher);
synchronized(dirtyMaskLock) {
cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY;
@@ -1426,9 +1295,16 @@ public class Canvas3D extends Canvas {
validCanvas = true;
added = true;
+ // Since we won't get a paint call for off-screen canvases, we need
+ // to set the first paint and visible flags here
+ if (offScreen) {
+ firstPaintCalled = true;
+ visible = true;
+ }
+
// In case the same canvas is removed and add back,
// we have to change isRunningStatus back to true;
- if (isRunning) {
+ if (isRunning && !fatalError) {
isRunningStatus = true;
}
@@ -1440,7 +1316,7 @@ public class Canvas3D extends Canvas {
if ((view != null) && (view.universe != null)) {
view.universe.checkForEnableEvents();
}
-
+
}
// When this canvas is removed a frame, this notification gets called. We
@@ -1452,9 +1328,13 @@ public class Canvas3D extends Canvas {
* method need to call super.removeNotify() in their removeNotify()
* method for Java 3D to function properly.
*/
-
public void removeNotify() {
+ // Do nothing for manually-rendered off-screen canvases
+ if (manualRendering) {
+ return;
+ }
+
Renderer rdr = null;
if (isRunning && (screen != null)) {
@@ -1470,11 +1350,6 @@ public class Canvas3D extends Canvas {
}
}
- if (!offScreen) {
- firstPaintCalled = false;
- }
-
-
// Note that although renderer userStop is true,
// MasterControl can still schedule renderer to run through
// runMonotor(RUN_RENDERER_CLEANUP) which skip userStop
@@ -1490,23 +1365,10 @@ public class Canvas3D extends Canvas {
removeCtx();
- synchronized (drawingSurfaceObject) {
-
- DrawingSurfaceObjectAWT dso =
- (DrawingSurfaceObjectAWT)drawingSurfaceObject;
- // get nativeDS before it is set to 0 in invalidate()
- long ds = dso.getDS();
- long ds_struct[] = {ds, dso.getDSI()};
- if (ds != 0) {
- VirtualUniverse.mc.postRequest(
- MasterControl.FREE_DRAWING_SURFACE,
- ds_struct);
- }
-
- drawingSurfaceObject.invalidate();
-
- }
+ Pipeline.getPipeline().freeDrawingSurface(this, drawingSurfaceObject);
+ // Clear first paint and visible flags
+ firstPaintCalled = false;
visible = false;
screen.removeUser(this);
@@ -1519,7 +1381,7 @@ public class Canvas3D extends Canvas {
ra = null;
graphicsContext3D = null;
- ctx = 0;
+ ctx = null;
// must be after removeCtx() because
// it will free graphics2D textureID
graphics2D = null;
@@ -1566,9 +1428,7 @@ public class Canvas3D extends Canvas {
parent.requestFocus();
}
- if (!offScreen) {
- added = false;
- }
+ added = false;
if (rdr != null) {
rdr.userStop = false;
@@ -1587,10 +1447,10 @@ public class Canvas3D extends Canvas {
// Also we can't use this as lock, otherwise there is a
// deadlock where updateViewCache get a lock of this and
// get a lock of this component. But Container
- // remove will get a lock of this componet follows by evaluateActive.
+ // remove will get a lock of this component follows by evaluateActive.
synchronized (evaluateLock) {
- if ((visible || offScreen) && firstPaintCalled) {
+ if ((visible || manualRendering) && firstPaintCalled) {
if (!active) {
active = true;
@@ -1771,7 +1631,9 @@ public class Canvas3D extends Canvas {
* off-screen mode.
*/
public final void stopRenderer() {
- if (offScreen)
+ // Issue 131: renderer can't be stopped only if it is an offscreen,
+ // manual canvas. Otherwise, it has to be seen as an onscreen canvas.
+ if (manualRendering)
throw new IllegalStateException(J3dI18N.getString("Canvas3D14"));
if (isRunning) {
@@ -1791,6 +1653,11 @@ public class Canvas3D extends Canvas {
* render the scene graph to the canvas.
*/
public final void startRenderer() {
+ // Issue 260 : ignore attempt to start renderer if fatal error
+ if (fatalError) {
+ return;
+ }
+
if (!isRunning) {
VirtualUniverse.mc.postRequest(MasterControl.START_RENDERER, this);
isRunning = true;
@@ -1808,6 +1675,24 @@ public class Canvas3D extends Canvas {
return isRunning;
}
+ // Returns the state of the fatal error flag
+ boolean isFatalError() {
+ return fatalError;
+ }
+
+ // Sets the fatal error flag to true; stop the renderer for this canvas
+ void setFatalError() {
+ fatalError = true;
+
+ if (isRunning) {
+ isRunning = false;
+
+ if (!manualRendering) {
+ VirtualUniverse.mc.postRequest(MasterControl.STOP_RENDERER, this);
+ }
+ }
+ }
+
/**
* Retrieves a flag indicating whether this Canvas3D is an
@@ -1835,18 +1720,36 @@ public class Canvas3D extends Canvas {
* <p>
*
* @param buffer the image component that will be rendered into by
- * subsequent calls to renderOffScreenBuffer.
+ * subsequent calls to renderOffScreenBuffer. The image component must not
+ * be part of a live scene graph, nor may it subsequently be made part of a
+ * live scene graph while being used as an off-screen buffer; an
+ * IllegalSharingException is thrown in such cases. The buffer may be null,
+ * indicating that the previous off-screen buffer is released without a new
+ * buffer being set.
*
* @exception IllegalStateException if this Canvas3D is not in
* off-screen mode.
+ *
* @exception RestrictedAccessException if an off-screen rendering
* is in process for this Canvas3D.
- * @exception IllegalSharingException if the specified
- * ImageComponent2D is used by more than one Canvas3D.
+ *
+ * @exception IllegalSharingException if the specified ImageComponent2D
+ * is part of a live scene graph
+ *
+ * @exception IllegalSharingException if the specified ImageComponent2D is
+ * being used by an immediate mode context, or by another Canvas3D as
+ * an off-screen buffer.
+ *
+ * @exception IllegalArgumentException if the image class of the specified
+ * ImageComponent2D is <i>not</i> ImageClass.BUFFERED_IMAGE.
+ *
* @exception IllegalArgumentException if the specified
* ImageComponent2D is in by-reference mode and its
- * RenderedImage is not an instance of a BufferedImage or
- * if the ImageComponent2D format is FORMAT_CHANNEL8.
+ * RenderedImage is null.
+ *
+ * @exception IllegalArgumentException if the ImageComponent2D format
+ * is <i>not</i> a 3-component format (e.g., FORMAT_RGB)
+ * or a 4-component format (e.g., FORMAT_RGBA).
*
* @see #renderOffScreenBuffer
* @see Screen3D#setSize(int, int)
@@ -1867,38 +1770,73 @@ public class Canvas3D extends Canvas {
// Check that offScreenBufferPending is not already set
J3dDebug.doAssert(!offScreenBufferPending, "!offScreenBufferPending");
+
+ if (offScreenBuffer != null && offScreenBuffer != buffer) {
+ ImageComponent2DRetained i2dRetained =
+ (ImageComponent2DRetained)offScreenBuffer.retained;
+ i2dRetained.setUsedByOffScreen(false);
+ }
if (buffer != null) {
ImageComponent2DRetained bufferRetained =
(ImageComponent2DRetained)buffer.retained;
if (bufferRetained.byReference &&
- !(bufferRetained.bImage[0] instanceof BufferedImage)) {
+ !(bufferRetained.getRefImage(0) instanceof BufferedImage)) {
throw new IllegalArgumentException(J3dI18N.getString("Canvas3D15"));
}
- if (bufferRetained.format == ImageComponent.FORMAT_CHANNEL8) {
+ if (bufferRetained.getNumberOfComponents() < 3 ) {
throw new IllegalArgumentException(J3dI18N.getString("Canvas3D16"));
}
+ if (buffer.isLive()) {
+ throw new IllegalSharingException(J3dI18N.getString("Canvas3D26"));
+ }
+
+ if (bufferRetained.getInImmCtx()) {
+ throw new IllegalSharingException(J3dI18N.getString("Canvas3D27"));
+ }
+
+ if (buffer != offScreenBuffer && bufferRetained.getUsedByOffScreen()) {
+ throw new IllegalSharingException(J3dI18N.getString("Canvas3D28"));
+ }
+
+ bufferRetained.setUsedByOffScreen(true);
+
width = bufferRetained.width;
height = bufferRetained.height;
- }
+
+ // Issues 347, 348 - assign a canvasId for off-screen Canvas3D
+ if (manualRendering) {
+ if (canvasBit == 0) {
+ canvasId = VirtualUniverse.mc.getCanvasId();
+ canvasBit = 1 << canvasId;
+ }
+ }
+ }
else {
width = height = 0;
- }
- // XXXX: illegalSharing
-
+ // Issues 347, 348 - release canvasId for off-screen Canvas3D
+ if (manualRendering) {
+ if (canvasBit != 0) {
+ VirtualUniverse.mc.freeCanvasId(canvasId);
+ canvasBit = 0;
+ canvasId = 0;
+ }
+ }
+ }
+
if ((offScreenCanvasSize.width != width) ||
(offScreenCanvasSize.height != height)) {
- if (window != 0) {
+ if (drawable != null) {
// Fix for Issue 18 and Issue 175
// Will do destroyOffScreenBuffer in the Renderer thread.
sendDestroyCtxAndOffScreenBuffer();
- window = 0;
+ drawable = null;
}
// set the canvas dimension according to the buffer dimension
@@ -1908,9 +1846,9 @@ public class Canvas3D extends Canvas {
if (width > 0 && height > 0) {
sendCreateOffScreenBuffer();
}
- ctx = 0;
+ ctx = null;
}
- else if (ctx != 0) {
+ else if (ctx != null) {
removeCtx();
}
@@ -1922,7 +1860,6 @@ public class Canvas3D extends Canvas {
}
}
-
/**
* Retrieves the off-screen buffer for this Canvas3D.
*
@@ -1974,10 +1911,18 @@ public class Canvas3D extends Canvas {
*/
public void renderOffScreenBuffer() {
-
if (!offScreen)
throw new IllegalStateException(J3dI18N.getString("Canvas3D1"));
+ // Issue 131: Cannot manually render to an automatic canvas.
+ if (!manualRendering)
+ throw new IllegalStateException(J3dI18N.getString("Canvas3D24"));
+
+ // Issue 260 : Cannot render if we already have a fatal error
+ if (fatalError) {
+ throw new IllegalRenderingStateException(J3dI18N.getString("Canvas3D30"));
+ }
+
if (offScreenBuffer == null)
throw new NullPointerException(J3dI18N.getString("Canvas3D10"));
@@ -2008,44 +1953,8 @@ public class Canvas3D extends Canvas {
return;
}
- // determine the offScreen boundary
- // do the boundary determination here because setCanvasLocation can
- // be done at any time.
-
- if ((offScreenCanvasLoc.x >= screenSize.width) ||
- (offScreenCanvasLoc.y >= screenSize.height))
- return;
-
- if (offScreenCanvasLoc.x < 0) {
- offScreenCanvasClippedLoc.x = 0 - offScreenCanvasLoc.x;
- offScreenCanvasClippedSize.width =
- offScreenCanvasSize.width - offScreenCanvasClippedLoc.x;
- if (offScreenCanvasClippedSize.width > screenSize.width)
- offScreenCanvasClippedSize.width = screenSize.width;
- } else {
- offScreenCanvasClippedLoc.x = 0;
- offScreenCanvasClippedSize.width = offScreenCanvasSize.width;
- if ((offScreenCanvasLoc.x + offScreenCanvasClippedSize.width)
- > screenSize.width)
- offScreenCanvasClippedSize.width =
- screenSize.width - offScreenCanvasLoc.x;
- }
-
-
- int lly = offScreenCanvasLoc.y + offScreenCanvasSize.height;
- if (lly < 0) {
- return;
- } else if (lly <= screenSize.height) {
- offScreenCanvasClippedLoc.y = 0;
- if (offScreenCanvasLoc.y < 0)
- offScreenCanvasClippedSize.height = lly;
- else
- offScreenCanvasClippedSize.height = offScreenCanvasSize.height;
- } else if (lly > screenSize.height) {
- offScreenCanvasClippedSize.height =
- screenSize.height - offScreenCanvasLoc.y;
- offScreenCanvasClippedLoc.y = lly - screenSize.height;
- }
+ // Issue 131: moved code that determines off-screen boundary to separate
+ // method that is called from the renderer
offScreenRendering = true;
@@ -2085,7 +1994,7 @@ public class Canvas3D extends Canvas {
// to do the offscreen rendering now
if (Thread.currentThread() == screen.renderer) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.RENDER_THREAD;
createMessage.type = J3dMessage.RENDER_OFFSCREEN;
createMessage.universe = this.view.universe;
@@ -2112,7 +2021,7 @@ public class Canvas3D extends Canvas {
// XXXX:
// Now we are in trouble, this will cause deadlock if
// waitForOffScreenRendering() is invoked
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.RENDER_THREAD;
createMessage.type = J3dMessage.RENDER_OFFSCREEN;
createMessage.universe = this.view.universe;
@@ -2130,7 +2039,7 @@ public class Canvas3D extends Canvas {
// currentThread() == view.universe.behaviorScheduler
// since the caller may be another universe Behavior
// scheduler.
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.RENDER_THREAD;
createMessage.type = J3dMessage.RENDER_OFFSCREEN;
createMessage.universe = this.view.universe;
@@ -2143,7 +2052,7 @@ public class Canvas3D extends Canvas {
// send a message to renderBin
// Fix for issue 66 : Since view might not been set yet,
// we have to use pendingView instead.
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.RENDER_OFFSCREEN;
createMessage.universe = this.pendingView.universe;
@@ -2174,6 +2083,10 @@ public class Canvas3D extends Canvas {
* @since Java 3D 1.2
*/
public void waitForOffScreenRendering() {
+ // TODO KCR : throw exception if !offScreen
+
+ // TODO KCR Issue 131: throw exception if !manualRendering
+
while (offScreenRendering) {
MasterControl.threadYield();
}
@@ -2297,46 +2210,54 @@ public class Canvas3D extends Canvas {
}
void endOffScreenRendering() {
-
-
-
-
- // Evaluate what the stored format is before reading to offscreen buffer
- if (((ImageComponent2DRetained)offScreenBuffer.retained).isByReference()) {
- ((ImageComponent2DRetained)offScreenBuffer.retained).geomLock.getLock();
- ((ImageComponent2DRetained)offScreenBuffer.retained).evaluateExtensions(extensionsSupported);
- ((ImageComponent2DRetained)offScreenBuffer.retained).geomLock.unLock();
- }
-
-
-
- int bytesPerPixel = ((ImageComponent2DRetained)offScreenBuffer.retained).getEffectiveBytesPerPixel();
- int format = ((ImageComponent2DRetained)offScreenBuffer.retained).getEffectiveFormat();
-
-
- // allocate read buffer space
-
- int size =
- offScreenCanvasSize.width * offScreenCanvasSize.height * bytesPerPixel;
- if (byteBuffer.length < size)
- byteBuffer = new byte[size];
-
-
- // read the image from the offscreen buffer
-
- readOffScreenBuffer(ctx,
- format,
- offScreenCanvasSize.width, offScreenCanvasSize.height);
-
-
- // copy it into the ImageComponent
-
- ((ImageComponent2DRetained)offScreenBuffer.retained).retrieveImage(
- byteBuffer, offScreenCanvasClippedLoc.x, offScreenCanvasClippedLoc.y,
- offScreenCanvasClippedSize.width, offScreenCanvasClippedSize.height);
+
+ ImageComponent2DRetained icRetained = (ImageComponent2DRetained)offScreenBuffer.retained;
+ boolean isByRef = icRetained.isByReference();
+ boolean isYUp = icRetained.isYUp();
+ ImageComponentRetained.ImageData imageData = icRetained.getImageData(false);
+
+ if(!isByRef) {
+ // If icRetained has a null image ( BufferedImage)
+ if (imageData == null) {
+ assert (!isByRef);
+ icRetained.createBlankImageData();
+ imageData = icRetained.getImageData(false);
+ }
+ // Check for possible format conversion in imageData
+ else {
+ // Format convert imageData if format is unsupported.
+ icRetained.evaluateExtensions(this);
+ }
+ // read the image from the offscreen buffer
+ readOffScreenBuffer(ctx, icRetained.getImageFormatTypeIntValue(false),
+ icRetained.getImageDataTypeIntValue(), imageData.get(),
+ offScreenCanvasSize.width, offScreenCanvasSize.height);
+
+ } else {
+ icRetained.geomLock.getLock();
+ // Create a copy of format converted image in imageData if format is unsupported.
+ icRetained.evaluateExtensions(this);
+
+ // read the image from the offscreen buffer
+ readOffScreenBuffer(ctx, icRetained.getImageFormatTypeIntValue(false),
+ icRetained.getImageDataTypeIntValue(), imageData.get(),
+ offScreenCanvasSize.width, offScreenCanvasSize.height);
+
+ // For byRef, we might have to copy buffer back into
+ // the user's referenced ImageComponent2D
+ if(!imageData.isDataByRef()) {
+ if(icRetained.isImageTypeSupported()) {
+ icRetained.copyToRefImage(0);
+ } else {
+ // This method only handle RGBA conversion.
+ icRetained.copyToRefImageWithFormatConversion(0);
+ }
+ }
+
+ icRetained.geomLock.unLock();
+ }
}
-
/**
* Synchronize and swap buffers on a double buffered canvas for
* this Canvas3D object. This method should only be called if the
@@ -2380,7 +2301,7 @@ public class Canvas3D extends Canvas {
if (firstPaintCalled && useDoubleBuffer) {
try {
- if (validCtx && (ctx != 0) && (view != null)) {
+ if (validCtx && (ctx != null) && (view != null)) {
synchronized (drawingSurfaceObject) {
if (validCtx) {
if (!drawingSurfaceObject.renderLock()) {
@@ -2388,7 +2309,7 @@ public class Canvas3D extends Canvas {
return;
}
this.syncRender(ctx, true);
- int status = swapBuffers(ctx, screen.display, window);
+ int status = swapBuffers(ctx, screen.display, drawable);
if (status != NOCHANGE) {
resetImmediateRendering(status);
}
@@ -2409,6 +2330,7 @@ public class Canvas3D extends Canvas {
antialiasingSet = false;
if (reEvaluateCanvasCmd == RESIZE) {
+ assert VirtualUniverse.mc.isD3D();
status = resizeD3DCanvas(ctx);
} else {
status = toggleFullScreenMode(ctx);
@@ -2425,10 +2347,9 @@ public class Canvas3D extends Canvas {
/**
* Wrapper for native createNewContext method.
*/
- long createNewContext(long shareCtx, boolean isSharedCtx) {
- long retVal = createNewContext(this.screen.display,
- this.window,
- this.vid,
+ Context createNewContext(Context shareCtx, boolean isSharedCtx) {
+ Context retVal = createNewContext(this.screen.display,
+ this.drawable,
this.fbConfig,
shareCtx, isSharedCtx,
this.offScreen,
@@ -2436,6 +2357,7 @@ public class Canvas3D extends Canvas {
VirtualUniverse.mc.cgLibraryAvailable);
// compute the max available texture units
maxAvailableTextureUnits = Math.max(maxTextureUnits, maxTextureImageUnits);
+
return retVal;
}
@@ -2443,86 +2365,47 @@ public class Canvas3D extends Canvas {
* Make the context associated with the specified canvas current.
*/
final void makeCtxCurrent() {
- makeCtxCurrent(ctx, screen.display, window);
+ makeCtxCurrent(ctx, screen.display, drawable);
}
/**
* Make the specified context current.
*/
- final void makeCtxCurrent(long ctx) {
- makeCtxCurrent(ctx, screen.display, window);
+ final void makeCtxCurrent(Context ctx) {
+ makeCtxCurrent(ctx, screen.display, drawable);
}
- final void makeCtxCurrent(long ctx, long dpy, int win) {
- if (ctx != screen.renderer.currentCtx || win != screen.renderer.currentWindow) {
+ final void makeCtxCurrent(Context ctx, long dpy, Drawable drawable) {
+ if (ctx != screen.renderer.currentCtx || drawable != screen.renderer.currentDrawable) {
if (!drawingSurfaceObject.isLocked()) {
drawingSurfaceObject.renderLock();
- useCtx(ctx, dpy, win);
+ useCtx(ctx, dpy, drawable);
drawingSurfaceObject.unLock();
} else {
- useCtx(ctx, dpy, win);
+ useCtx(ctx, dpy, drawable);
}
screen.renderer.currentCtx = ctx;
- screen.renderer.currentWindow = win;
+ screen.renderer.currentDrawable = drawable;
}
}
-
- // The native method that sets this ctx to be the current one
- static native boolean useCtx(long ctx, long display, int window);
-
- native void clear(long ctx, float r, float g, float b, int winWidth, int winHeight,
- ImageComponent2DRetained image, int imageScaleMode, byte[] imageYdown);
- native void textureclear(long ctx, int maxX, int maxY,
- float r, float g, float b,
- int winWidth, int winHeight,
- int objectId, int scalemode,
- ImageComponent2DRetained image,
- boolean update);
-
-
- // The native method for swapBuffers
- native int swapBuffers(long ctx, long dpy, int win);
-
- // The native method for videoResize. -- Support DVR.
- native void videoResize(long ctx, long dpy, int win, float dvrFactor);
-
- // The native method for videoResizeCompensation. -- Support DVR.
- native void videoResizeCompensation( long ctx, boolean enable);
-
- // The native method for setting the ModelView matrix.
- native void setModelViewMatrix(long ctx, double[] viewMatrix, double[] modelMatrix);
-
- // The native method for setting the Projection matrix.
- native void setProjectionMatrix(long ctx, double[] projMatrix);
-
- // The native method for setting the Viewport.
- native void setViewport(long ctx, int x, int y, int width, int height);
-
- // used for display Lists
- native void newDisplayList(long ctx, int displayListId);
- native void endDisplayList(long ctx);
- native void callDisplayList(long ctx, int id, boolean isNonUniformScale);
-
- native static void freeDisplayList(long ctx, int id);
- native static void freeTexture(long ctx, int id);
-
- native void composite(long ctx, int px, int py,
- int xmin, int ymin, int xmax, int ymax,
- int rasWidth, byte[] image,
- int winWidth, int winHeight);
-
- native void texturemapping(long ctx,
- int px, int py,
- int xmin, int ymin, int xmax, int ymax,
- int texWidth, int texHeight,
- int rasWidth,
- int format, int objectId,
- byte[] image,
- int winWidth, int winHeight);
-
- native boolean initTexturemapping(long ctx, int texWidth,
- int texHeight, int objectId);
+ // Give the pipeline a chance to release the context; the Pipeline may
+ // or may not ignore this call.
+ void releaseCtx() {
+ if (screen.renderer.currentCtx != null) {
+ boolean needLock = !drawingSurfaceObject.isLocked();
+ if (needLock) {
+ drawingSurfaceObject.renderLock();
+ }
+ if (releaseCtx(screen.renderer.currentCtx, screen.display)) {
+ screen.renderer.currentCtx = null;
+ screen.renderer.currentDrawable = null;
+ }
+ if (needLock) {
+ drawingSurfaceObject.unLock();
+ }
+ }
+ }
/**
@@ -3301,6 +3184,10 @@ public class Canvas3D extends Canvas {
* <td>Float</td>
* </tr>
* <tr>
+ * <td><code>textureNonPowerOfTwoAvailable</code></td>
+ * <td>Boolean</td>
+ * </tr>
+ * <tr>
* <td><code>vertexAttrsMax</code></td>
* <td>Integer</td>
* </tr>
@@ -3584,6 +3471,7 @@ public class Canvas3D extends Canvas {
* LINEAR_DETAIL_RGB as the texture magnification filter mode will
* be ignored. The texture magnification filter mode in effect will
* be BASE_LEVEL_LINEAR.
+ * As of Java 3D 1.5, this property is always false.
* </ul>
* </li>
*
@@ -3621,6 +3509,18 @@ public class Canvas3D extends Canvas {
* layer, and an attempt to set anisotropic filter degree will be ignored.
* </ul>
* </li>
+
+ * <li>
+ * <code>textureNonPowerOfTwoAvailable</code>
+ * <ul>
+ * A Boolean indicating whether or not texture dimensions that are
+ * not powers of two are supported for
+ * for this Canvas3D. If it indicates false, then textures with
+ * non power of two sizes will be ignored. Set the property
+ * j3d.textureEnforcePowerOfTwo to revert to the pre-1.5 behavior
+ * of throwing exceptions for non power of two textures.
+ * </ul>
+ * </li>
*
* <li>
* <code>vertexAttrsMax</code>
@@ -3661,18 +3561,23 @@ public class Canvas3D extends Canvas {
boolean createDummyCtx = false;
synchronized (VirtualUniverse.mc.contextCreationLock) {
- if (ctx == 0) {
+ if (ctx == null) {
createDummyCtx = true;
}
}
-
+
if (createDummyCtx) {
GraphicsConfigTemplate3D.setQueryProps(this);
-
}
+
//create query Properties
createQueryProps();
}
+
+ if (fatalError) {
+ throw new IllegalStateException(J3dI18N.getString("Canvas3D29"));
+ }
+
return queryProps;
}
@@ -3681,7 +3586,7 @@ public class Canvas3D extends Canvas {
// extensions, the context will destroy immediately
// inside the native code after setting the various
// fields in this object
- createQueryContext(screen.display, window, vid,
+ createQueryContext(screen.display, drawable,
fbConfig, offScreen, 1, 1,
VirtualUniverse.mc.glslLibraryAvailable,
VirtualUniverse.mc.cgLibraryAvailable);
@@ -3717,8 +3622,13 @@ public class Canvas3D extends Canvas {
values.add(new Integer(pass));
keys.add("stencilSize");
- // Return the actual stencil size.
- values.add(new Integer(actualStencilSize));
+ // Return the actual stencil size if the user owns it, otherwise
+ // return 0
+ if (userStencilAvailable) {
+ values.add(new Integer(actualStencilSize));
+ } else {
+ values.add(new Integer(0));
+ }
keys.add("compressedGeometry.majorVersionNumber");
values.add(new Integer(GeometryDecompressor.majorVersionNumber));
@@ -3791,6 +3701,14 @@ public class Canvas3D extends Canvas {
values.add(new Boolean(
(textureExtendedFeatures & TEXTURE_LOD_OFFSET) != 0));
+ keys.add("textureNonPowerOfTwoAvailable");
+ if (VirtualUniverse.mc.enforcePowerOfTwo) {
+ values.add(Boolean.FALSE);
+ } else {
+ values.add(new Boolean(
+ (textureExtendedFeatures & TEXTURE_NON_POWER_OF_TWO) != 0));
+ }
+
keys.add("textureCoordSetsMax");
values.add(new Integer(maxTexCoordSets));
@@ -3831,16 +3749,6 @@ public class Canvas3D extends Canvas {
}
- // Set internal render mode to one of FIELD_ALL, FIELD_LEFT or
- // FIELD_RIGHT. Note that it is up to the caller to ensure that
- // stereo is available before setting the mode to FIELD_LEFT or
- // FIELD_RIGHT. The boolean isTRUE for double buffered mode, FALSE
- // foe single buffering.
- native void setRenderMode(long ctx, int mode, boolean doubleBuffer);
-
- // Set glDepthMask.
- native void setDepthBufferWriteEnable(long ctx, boolean mode);
-
/**
* Update the view cache associated with this canvas.
*/
@@ -3885,7 +3793,7 @@ public class Canvas3D extends Canvas {
}
- void resetTexture(long ctx, int texUnitIndex) {
+ void resetTexture(Context ctx, int texUnitIndex) {
// D3D also need to reset texture attributes
this.resetTextureNative(ctx, texUnitIndex);
@@ -3906,7 +3814,6 @@ public class Canvas3D extends Canvas {
void resetTextureBin() {
Object obj;
TextureRetained tex;
- DetailTextureImage detailTex;
// We don't use rdr.objectId for background texture in D3D
// so there is no need to handle rdr.objectId
@@ -3923,18 +3830,14 @@ public class Canvas3D extends Canvas {
if (obj instanceof TextureRetained) {
tex = (TextureRetained) obj;
tex.resourceCreationMask &= ~canvasBit;
- } else {
- detailTex = (DetailTextureImage) obj;
- for (int i=0; i < detailTex.resourceCreationMask.length; i++) {
- detailTex.resourceCreationMask[i] &= ~canvasBit;
- }
- }
+ }
}
}
}
void d3dResize() {
+ assert VirtualUniverse.mc.isD3D();
int status = resizeD3DCanvas(ctx);
antialiasingSet = false;
@@ -3947,6 +3850,7 @@ public class Canvas3D extends Canvas {
}
void d3dToggle() {
+ assert VirtualUniverse.mc.isD3D();
int status = toggleFullScreenMode(ctx);
antialiasingSet = false;
@@ -3957,6 +3861,7 @@ public class Canvas3D extends Canvas {
// use by D3D only
void notifyD3DPeer(int cmd) {
+ assert VirtualUniverse.mc.isD3D();
if (active) {
if (isRunning) {
if ((view != null) &&
@@ -3969,7 +3874,7 @@ public class Canvas3D extends Canvas {
while (isRunningStatus) {
MasterControl.threadYield();
}
- J3dMessage renderMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage renderMessage = new J3dMessage();
renderMessage.threads = J3dThread.RENDER_THREAD;
if (cmd == RESIZE) {
renderMessage.type = J3dMessage.RESIZE_CANVAS;
@@ -4017,8 +3922,6 @@ public class Canvas3D extends Canvas {
void reset() {
int i;
-
- byteBuffer = new byte[1];
currentAppear = new AppearanceRetained();
currentMaterial = new MaterialRetained();
viewFrustum = new CachedFrustum();
@@ -4247,12 +4150,20 @@ public class Canvas3D extends Canvas {
}
}
}
-
- void setModelViewMatrix(long ctx, double[] viewMatrix, Transform3D mTrans) {
+
+ void setProjectionMatrix(Context ctx, Transform3D projTrans) {
+ this.projTrans = projTrans;
+ setProjectionMatrix(ctx, projTrans.mat);
+ }
+
+ void setModelViewMatrix(Context ctx, double[] viewMatrix, Transform3D mTrans) {
setModelViewMatrix(ctx, viewMatrix, mTrans.mat);
if (!useStereo) {
this.modelMatrix = mTrans;
} else {
+ // TODO : This seems wrong to do only for the right eye.
+ // A possible approach is to invalidate the cache at begin of
+ // each eye.
if (rightStereoPass) {
// Only set cache in right stereo pass, otherwise
// if the left stereo pass set the cache value,
@@ -4294,41 +4205,17 @@ public class Canvas3D extends Canvas {
}
}
- // Create the texture unit state map
- void createTexUnitStateMap() {
- // Create the texture unit state map array, which is a mapping from
- // texture unit state to the actual underlying texture unit
- // NOTE: since this is now required to be a 1-to-1 mapping, we will
- // initialize it as such
-
- texUnitStateMap = new int[maxAvailableTextureUnits];
- for (int t = 0; t < maxAvailableTextureUnits; t++) {
- texUnitStateMap[t] = t;
- }
- }
-
- // update the underlying layer of the current texture unit state map
- void updateTexUnitStateMap() {
- updateTexUnitStateMap(ctx, numActiveTexUnit, texUnitStateMap);
- }
-
boolean supportGlobalAlpha() {
return ((extensionsSupported & SUN_GLOBAL_ALPHA) != 0);
}
- boolean supportVideoResize() {
- return ((extensionsSupported & SUN_VIDEO_RESIZE) != 0);
- }
-
- /** enable separate specular color if the functionality
- * is availabe for this canvas and it is not overriden by the
- * property j3d.disableSeparateSpecular.
+ /**
+ * Enable separate specular color if it is not overriden by the
+ * property j3d.disableSeparateSpecular.
*/
void enableSeparateSpecularColor() {
- if (((extensionsSupported & EXT_SEPARATE_SPECULAR_COLOR) != 0) &&
- !VirtualUniverse.mc.disableSeparateSpecularColor) {
- updateSeparateSpecularColorEnable(ctx, true);
- }
+ boolean enable = !VirtualUniverse.mc.disableSeparateSpecularColor;
+ updateSeparateSpecularColorEnable(ctx, enable);
}
final void beginScene() {
@@ -4387,12 +4274,12 @@ public class Canvas3D extends Canvas {
if ((screen != null) &&
(screen.renderer != null) &&
- (ctx != 0)) {
+ (ctx != null)) {
VirtualUniverse.mc.postRequest(MasterControl.FREE_CONTEXT,
new Object[]{this,
new Long(screen.display),
- new Integer(window),
- new Long(ctx)});
+ drawable,
+ ctx});
// Fix for Issue 19
// Wait for the context to be freed unless called from
// a Behavior or from a Rendering thread
@@ -4402,9 +4289,8 @@ public class Canvas3D extends Canvas {
while (ctxTimeStamp != 0) {
MasterControl.threadYield();
}
-
}
- ctx = 0;
+ ctx = null;
}
}
@@ -4491,7 +4377,7 @@ public class Canvas3D extends Canvas {
/**
* update state if neccessary according to the stateUpdatedMask
*/
- void updateState(int pass, int dirtyBits) {
+ void updateState( int dirtyBits) {
if (stateUpdateMask == 0)
@@ -4501,7 +4387,7 @@ public class Canvas3D extends Canvas {
if ((stateUpdateMask & (1 << TEXTUREBIN_BIT)) != 0) {
((TextureBin)
- curStateToUpdate[TEXTUREBIN_BIT]).updateAttributes(this, pass);
+ curStateToUpdate[TEXTUREBIN_BIT]).updateAttributes(this);
}
if ((stateUpdateMask & (1 << RENDERMOLECULE_BIT)) != 0) {
@@ -4520,6 +4406,245 @@ public class Canvas3D extends Canvas {
stateUpdateMask = 0;
}
+
+ // This method updates this Texture2D for raster.
+ // Note : No multi-texture is not used.
+ void updateTextureForRaster(Texture2DRetained texture) {
+
+ // Setup texture and texture attributes for texture unit 0.
+ Pipeline.getPipeline().updateTextureUnitState(ctx, 0, true);
+ setLastActiveTexUnit(0);
+ setNumActiveTexUnit(1);
+
+ texture.updateNative(this);
+ resetTextureAttributes(ctx);
+
+ for(int i=1; i < maxTextureUnits; i++) {
+ resetTexture(ctx, i);
+ }
+
+ // set the active texture unit back to 0
+ activeTextureUnit(ctx, 0);
+
+ // Force the next textureBin to reload.
+ canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
+ }
+
+ void restoreTextureBin() {
+
+ // Need to check TextureBin's shaderBin for null
+ // TextureBin can get clear() if there isn't any RM under it.
+ if((textureBin != null) && (textureBin.shaderBin != null)) {
+ textureBin.updateAttributes(this);
+ }
+ }
+
+ void textureFill(RasterRetained raster, Point2d winCoord,
+ float mapZ, float alpha) {
+
+ int winWidth = canvasViewCache.getCanvasWidth();
+ int winHeight = canvasViewCache.getCanvasHeight();
+
+ int rasterImageWidth = raster.image.width;
+ int rasterImageHeight = raster.image.height;
+
+ float texMinU = 0, texMinV = 0, texMaxU = 0, texMaxV = 0;
+ float mapMinX = 0, mapMinY = 0, mapMaxX = 0, mapMaxY = 0;
+
+ Point rasterSrcOffset = new Point();
+ raster.getSrcOffset(rasterSrcOffset);
+
+ Dimension rasterSize = new Dimension();
+ raster.getSize(rasterSize);
+
+ // System.err.println("rasterSrcOffset " + rasterSrcOffset + " rasterSize " + rasterSize);
+
+ int rasterMinX = rasterSrcOffset.x;
+ int rasterMaxX = rasterSrcOffset.x + rasterSize.width;
+ int rasterMinY = rasterSrcOffset.y;
+ int rasterMaxY = rasterSrcOffset.y + rasterSize.height;
+
+ if ((rasterMinX >= rasterImageWidth) || (rasterMinY >= rasterImageHeight) ||
+ (rasterMaxX <= 0) || (rasterMaxY <= 0)) {
+ return;
+ }
+
+ if (rasterMinX < 0) {
+ rasterMinX = 0;
+ }
+ if (rasterMinY < 0) {
+ rasterMinY = 0;
+ }
+
+ if (rasterMaxX > rasterImageWidth) {
+ rasterMaxX = rasterImageWidth;
+ }
+
+ if (rasterMaxY > rasterImageHeight) {
+ rasterMaxY = rasterImageHeight;
+ }
+
+ texMinU = (float) rasterMinX / (float) rasterImageWidth;
+ texMaxU = (float) rasterMaxX / (float) rasterImageWidth;
+ mapMinX = (float) winCoord.x / (float) winWidth;
+ mapMaxX = (float) (winCoord.x + (rasterMaxX - rasterMinX)) / (float) winWidth;
+
+ if (raster.image.isYUp()) {
+ texMinV = (float) rasterMinY / (float) rasterImageHeight;
+ texMaxV = (float) rasterMaxY / (float) rasterImageHeight;
+ } else {
+ // System.err.println("In yUp is false case");
+ texMinV = 1.0f - (float) rasterMaxY / (float) rasterImageHeight;
+ texMaxV = 1.0f - (float) rasterMinY / (float) rasterImageHeight;
+ }
+
+ mapMinY = 1.0f - ((float) (winCoord.y + (rasterMaxY - rasterMinY)) / (float) winHeight);
+ mapMaxY = 1.0f - ((float) winCoord.y / (float) winHeight);
+
+ textureFillRaster(ctx, texMinU, texMaxU, texMinV, texMaxV,
+ mapMinX, mapMaxX, mapMinY, mapMaxY, mapZ, alpha);
+
+ }
+
+ void textureFill(BackgroundRetained bg, int winWidth, int winHeight) {
+
+ ImageComponentRetained.ImageData imageData =
+ bg.image.getImageData(bg.texture.isUseAsRaster());
+
+ int maxX = imageData.getWidth();
+ int maxY = imageData.getHeight();
+ int width = bg.image.width;
+ int height = bg.image.height;
+
+ float xzoom = (float)winWidth / maxX;
+ float yzoom = (float)winHeight / maxY;
+ float zoom = 0;
+ float texMinU = 0, texMinV = 0, texMaxU = 0, texMaxV = 0, adjustV = 0;
+ float mapMinX = 0, mapMinY = 0, mapMaxX = 0, mapMaxY = 0;
+ float halfWidth = 0, halfHeight = 0;
+ int i = 0, j = 0;
+ switch (bg.imageScaleMode) {
+ case Background.SCALE_NONE:
+ texMinU = 0.0f;
+ texMinV = 0.0f;
+ texMaxU = 1.0f;
+ texMaxV = 1.0f;
+ halfWidth = (float)winWidth/2.0f;
+ halfHeight = (float)winHeight/2.0f;
+ mapMinX = (float) ((0 - halfWidth)/halfWidth);
+ mapMinY = (float) ((0 - halfHeight)/halfHeight);
+ mapMaxX = (float) ((maxX - halfWidth)/halfWidth);
+ mapMaxY = (float) ((maxY - halfHeight)/halfHeight);
+ adjustV = ((float)winHeight - (float)maxY)/halfHeight;
+ mapMinY += adjustV;
+ mapMaxY += adjustV;
+ break;
+ case Background.SCALE_FIT_MIN:
+ zoom = Math.min(xzoom, yzoom);
+ texMinU = 0.0f;
+ texMinV = 0.0f;
+ texMaxU = 1.0f;
+ texMaxV = 1.0f;
+ mapMinX = -1.0f;
+ mapMaxY = 1.0f;
+ if (xzoom < yzoom) {
+ mapMaxX = 1.0f;
+ mapMinY = -1.0f + 2.0f * ( 1.0f - zoom * (float)maxY/(float) winHeight );
+ } else {
+ mapMaxX = -1.0f + zoom * (float)maxX/winWidth * 2;
+ mapMinY = -1.0f;
+ }
+ break;
+ case Background.SCALE_FIT_MAX:
+ zoom = Math.max(xzoom, yzoom);
+ mapMinX = -1.0f;
+ mapMinY = -1.0f;
+ mapMaxX = 1.0f;
+ mapMaxY = 1.0f;
+ if (xzoom < yzoom) {
+ texMinU = 0.0f;
+ texMinV = 0.0f;
+ texMaxU = (float)winWidth/maxX/zoom;
+ texMaxV = 1.0f;
+ } else {
+ texMinU = 0.0f;
+ texMinV = 1.0f - (float)winHeight/maxY/zoom;
+ texMaxU = 1.0f;
+ texMaxV = 1.0f;
+ }
+ break;
+ case Background.SCALE_FIT_ALL:
+ texMinU = 0.0f;
+ texMinV = 0.0f;
+ texMaxU = 1.0f;
+ texMaxV = 1.0f;
+ mapMinX = -1.0f;
+ mapMinY = -1.0f;
+ mapMaxX = 1.0f;
+ mapMaxY = 1.0f;
+ break;
+ case Background.SCALE_REPEAT:
+ i = winWidth/width;
+ j = winHeight/height;
+ texMinU = 0.0f;
+ texMinV = (float)(j + 1) - yzoom;
+ texMaxU = xzoom;
+ texMaxV = (float)(j + 1);
+ mapMinX = -1.0f;
+ mapMinY = -1.0f;
+ mapMaxX = 1.0f;
+ mapMaxY = 1.0f;
+ break;
+ case Background.SCALE_NONE_CENTER:
+ // TODO : Why is there a zoom ?
+ if(xzoom >= 1.0f){
+ texMinU = 0.0f;
+ texMaxU = 1.0f;
+ mapMinX = -(float)maxX/winWidth;
+ mapMaxX = (float)maxX/winWidth;
+ } else {
+ texMinU = 0.5f - (float)winWidth/maxX/2;
+ texMaxU = 0.5f + (float)winWidth/maxX/2;
+ mapMinX = -1.0f;
+ mapMaxX = 1.0f;
+ }
+ if (yzoom >= 1.0f) {
+ texMinV = 0.0f;
+ texMaxV = 1.0f;
+ mapMinY = -(float)maxY/winHeight;
+ mapMaxY = (float)maxY/winHeight;
+ } else {
+ texMinV = 0.5f - (float)winHeight/maxY/2;
+ texMaxV = 0.5f + (float)winHeight/maxY/2;
+ mapMinY = -1.0f;
+ mapMaxY = 1.0f;
+ }
+ break;
+ }
+
+ textureFillBackground(ctx, texMinU, texMaxU, texMinV, texMaxV,
+ mapMinX, mapMaxX, mapMinY, mapMaxY);
+
+ }
+
+
+ void clear(BackgroundRetained bg, int winWidth, int winHeight) {
+
+ clear( ctx, bg.color.x, bg.color.y, bg.color.z);
+
+ // TODO : This is a bug on not mirror bg. Will fix this as a bug after 1.5 beta.
+ // For now, as a workaround, we will check bg.image and bg.image.imageData not null.
+ if((bg.image != null) && (bg.image.imageData != null)) {
+ // setup Texture pipe.
+ updateTextureForRaster(bg.texture);
+
+ textureFill(bg, winWidth, winHeight);
+
+ // Restore texture pipe.
+ restoreTextureBin();
+ }
+ }
+
/**
* obj is either TextureRetained or DetailTextureImage
* if obj is DetailTextureImage then we just clear
@@ -4554,7 +4679,7 @@ public class Canvas3D extends Canvas {
}
// handle free resource in the FreeList
- void freeResourcesInFreeList(long ctx) {
+ void freeResourcesInFreeList(Context ctx) {
Iterator it;
ArrayList list;
int i, val;
@@ -4573,64 +4698,61 @@ public class Canvas3D extends Canvas {
displayListResourceFreeList.clear();
}
- if (textureIdResourceFreeList.size() > 0) {
- for (it = textureIdResourceFreeList.iterator(); it.hasNext();) {
- val = ((Integer) it.next()).intValue();
- if (val <= 0) {
- continue;
- }
- if (val >= textureIDResourceTable.size()) {
- System.out.println("Error in freeResourcesInFreeList : ResourceIDTableSize = " +
- textureIDResourceTable.size() +
- " val = " + val);
- } else {
- textureIDResourceTable.set(val, null);
- }
- freeTexture(ctx, val);
- }
- textureIdResourceFreeList.clear();
- }
+ if (textureIdResourceFreeList.size() > 0) {
+ for (it = textureIdResourceFreeList.iterator(); it.hasNext();) {
+ val = ((Integer) it.next()).intValue();
+ if (val <= 0) {
+ continue;
+ }
+ if (val >= textureIDResourceTable.size()) {
+ System.out.println("Error in freeResourcesInFreeList : ResourceIDTableSize = " +
+ textureIDResourceTable.size() +
+ " val = " + val);
+ } else {
+ Object obj = textureIDResourceTable.get(val);
+ if (obj instanceof TextureRetained) {
+ TextureRetained tex = (TextureRetained) obj;
+ synchronized (tex.resourceLock) {
+ tex.resourceCreationMask &= ~canvasBit;
+ if (tex.resourceCreationMask == 0) {
+ tex.freeTextureId(val);
+ }
+ }
+ }
+
+ textureIDResourceTable.set(val, null);
+ }
+ freeTexture(ctx, val);
+ }
+ textureIdResourceFreeList.clear();
+ }
}
void freeContextResources(Renderer rdr, boolean freeBackground,
- long ctx) {
+ Context ctx) {
Object obj;
TextureRetained tex;
- DetailTextureImage detailTex;
// Just return if we don't have a valid renderer or context
- if (rdr == null || ctx == 0) {
+ if (rdr == null || ctx == null) {
return;
}
if (freeBackground) {
- // Free Background Texture
- // Note that we use non-shared ctx to create
- // it so there is no need to do so in
- // Renderer.freeContextResources()
- if (rdr.objectId > 0) {
- freeTexture(ctx, rdr.objectId);
- VirtualUniverse.mc.freeTexture2DId(rdr.objectId);
- rdr.objectId = -1;
-
- }
- // Free Graphics2D Texture
- if ((graphics2D != null) &&
- (graphics2D.objectId != -1)) {
- freeTexture(ctx, graphics2D.objectId);
- VirtualUniverse.mc.freeTexture2DId(graphics2D.objectId);
- graphics2D.objectId = -1;
- }
+ // Dispose of Graphics2D Texture
+ if (graphics2D != null) {
+ graphics2D.dispose();
+ }
}
-
for (int id = textureIDResourceTable.size()-1; id > 0; id--) {
obj = textureIDResourceTable.get(id);
if (obj == null) {
continue;
}
+ assert id == ((TextureRetained)obj).objectId;
freeTexture(ctx, id);
if (obj instanceof TextureRetained) {
tex = (TextureRetained) obj;
@@ -4641,19 +4763,16 @@ public class Canvas3D extends Canvas {
tex.freeTextureId(id);
}
}
- } else if (obj instanceof DetailTextureImage) {
- detailTex = ((DetailTextureImage) obj);
- detailTex.freeDetailTextureId(id, canvasBit);
}
}
textureIDResourceTable.clear();
- freeAllDisplayListResources();
+ freeAllDisplayListResources(ctx);
}
- void freeAllDisplayListResources() {
+ void freeAllDisplayListResources(Context ctx) {
if ((view != null) && (view.renderBin != null)) {
- view.renderBin.freeAllDisplayListResources(this);
+ view.renderBin.freeAllDisplayListResources(this, ctx);
if (useSharedCtx) {
// We need to rebuild all other Canvas3D resource
// shared by this Canvas3D. Since we didn't
@@ -4665,4 +4784,383 @@ public class Canvas3D extends Canvas {
}
}
+
+
+ // *****************************************************************
+ // Wrappers for native methods go below here
+ // *****************************************************************
+
+ // This is the native method for creating the underlying graphics context.
+ private Context createNewContext(long display, Drawable drawable,
+ long fbConfig, Context shareCtx, boolean isSharedCtx,
+ boolean offScreen,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable) {
+ return Pipeline.getPipeline().createNewContext(this, display, drawable,
+ fbConfig, shareCtx, isSharedCtx,
+ offScreen,
+ glslLibraryAvailable,
+ cgLibraryAvailable);
+ }
+
+ private void createQueryContext(long display, Drawable drawable,
+ long fbConfig, boolean offScreen, int width, int height,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable) {
+ Pipeline.getPipeline().createQueryContext(this, display, drawable,
+ fbConfig, offScreen, width, height,
+ glslLibraryAvailable,
+ cgLibraryAvailable);
+ }
+
+ // This is the native for creating offscreen buffer
+ Drawable createOffScreenBuffer(Context ctx, long display, long fbConfig, int width, int height) {
+ return Pipeline.getPipeline().createOffScreenBuffer(this,
+ ctx, display, fbConfig, width, height);
+ }
+
+ void destroyOffScreenBuffer(Context ctx, long display, long fbConfig, Drawable drawable) {
+ assert drawable != null;
+ Pipeline.getPipeline().destroyOffScreenBuffer(this, ctx, display, fbConfig, drawable);
+ }
+
+ // This is the native for reading the image from the offscreen buffer
+ private void readOffScreenBuffer(Context ctx, int format, int type, Object data, int width, int height) {
+ Pipeline.getPipeline().readOffScreenBuffer(this, ctx, format, type, data, width, height);
+ }
+
+ // The native method for swapBuffers
+ int swapBuffers(Context ctx, long dpy, Drawable drawable) {
+ return Pipeline.getPipeline().swapBuffers(this, ctx, dpy, drawable);
+ }
+
+ // notify D3D that Canvas is resize
+ private int resizeD3DCanvas(Context ctx) {
+ return Pipeline.getPipeline().resizeD3DCanvas(this, ctx);
+ }
+
+ // notify D3D to toggle between FullScreen and window mode
+ private int toggleFullScreenMode(Context ctx) {
+ return Pipeline.getPipeline().toggleFullScreenMode(this, ctx);
+ }
+
+ // -----------------------------------------------------------------------------
+
+ // native method for setting Material when no material is present
+ void updateMaterial(Context ctx, float r, float g, float b, float a) {
+ Pipeline.getPipeline().updateMaterialColor(ctx, r, g, b, a);
+ }
+
+ static void destroyContext(long display, Drawable drawable, Context ctx) {
+ Pipeline.getPipeline().destroyContext(display, drawable, ctx);
+ }
+
+ // This is the native method for doing accumulation.
+ void accum(Context ctx, float value) {
+ Pipeline.getPipeline().accum(ctx, value);
+ }
+
+ // This is the native method for doing accumulation return.
+ void accumReturn(Context ctx) {
+ Pipeline.getPipeline().accumReturn(ctx);
+ }
+
+ // This is the native method for clearing the accumulation buffer.
+ void clearAccum(Context ctx) {
+ Pipeline.getPipeline().clearAccum(ctx);
+ }
+
+ // This is the native method for getting the number of lights the underlying
+ // native library can support.
+ int getNumCtxLights(Context ctx) {
+ return Pipeline.getPipeline().getNumCtxLights(ctx);
+ }
+
+ // Native method for decal 1st child setup
+ boolean decal1stChildSetup(Context ctx) {
+ return Pipeline.getPipeline().decal1stChildSetup(ctx);
+ }
+
+ // Native method for decal nth child setup
+ void decalNthChildSetup(Context ctx) {
+ Pipeline.getPipeline().decalNthChildSetup(ctx);
+ }
+
+ // Native method for decal reset
+ void decalReset(Context ctx, boolean depthBufferEnable) {
+ Pipeline.getPipeline().decalReset(ctx, depthBufferEnable);
+ }
+
+ // Native method for decal reset
+ void ctxUpdateEyeLightingEnable(Context ctx, boolean localEyeLightingEnable) {
+ Pipeline.getPipeline().ctxUpdateEyeLightingEnable(ctx, localEyeLightingEnable);
+ }
+
+ // The following three methods are used in multi-pass case
+
+ // native method for setting blend color
+ void setBlendColor(Context ctx, float red, float green,
+ float blue, float alpha) {
+ Pipeline.getPipeline().setBlendColor(ctx, red, green,
+ blue, alpha);
+ }
+
+ // native method for setting blend func
+ void setBlendFunc(Context ctx, int src, int dst) {
+ Pipeline.getPipeline().setBlendFunc(ctx, src, dst);
+ }
+
+ // native method for setting fog enable flag
+ void setFogEnableFlag(Context ctx, boolean enableFlag) {
+ Pipeline.getPipeline().setFogEnableFlag(ctx, enableFlag);
+ }
+
+ // Setup the full scene antialising in D3D and ogl when GL_ARB_multisamle supported
+ void setFullSceneAntialiasing(Context ctx, boolean enable) {
+ Pipeline.getPipeline().setFullSceneAntialiasing(ctx, enable);
+ }
+
+ void setGlobalAlpha(Context ctx, float alpha) {
+ Pipeline.getPipeline().setGlobalAlpha(ctx, alpha);
+ }
+
+ // Native method to update separate specular color control
+ void updateSeparateSpecularColorEnable(Context ctx, boolean control) {
+ Pipeline.getPipeline().updateSeparateSpecularColorEnable(ctx, control);
+ }
+
+ // Initialization for D3D when scene begin
+ private void beginScene(Context ctx) {
+ Pipeline.getPipeline().beginScene(ctx);
+ }
+ private void endScene(Context ctx) {
+ Pipeline.getPipeline().endScene(ctx);
+ }
+
+ // True under Solaris,
+ // False under windows when display mode <= 8 bit
+ private boolean validGraphicsMode() {
+ return Pipeline.getPipeline().validGraphicsMode();
+ }
+
+ // native method for setting light enables
+ void setLightEnables(Context ctx, long enableMask, int maxLights) {
+ Pipeline.getPipeline().setLightEnables(ctx, enableMask, maxLights);
+ }
+
+ // native method for setting scene ambient
+ void setSceneAmbient(Context ctx, float red, float green, float blue) {
+ Pipeline.getPipeline().setSceneAmbient(ctx, red, green, blue);
+ }
+
+ // native method for disabling fog
+ void disableFog(Context ctx) {
+ Pipeline.getPipeline().disableFog(ctx);
+ }
+
+ // native method for disabling modelClip
+ void disableModelClip(Context ctx) {
+ Pipeline.getPipeline().disableModelClip(ctx);
+ }
+
+ // native method for setting default RenderingAttributes
+ void resetRenderingAttributes(Context ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride) {
+ Pipeline.getPipeline().resetRenderingAttributes(ctx,
+ depthBufferWriteEnableOverride,
+ depthBufferEnableOverride);
+ }
+
+ // native method for setting default texture
+ void resetTextureNative(Context ctx, int texUnitIndex) {
+ Pipeline.getPipeline().resetTextureNative(ctx, texUnitIndex);
+ }
+
+ // native method for activating a particular texture unit
+ void activeTextureUnit(Context ctx, int texUnitIndex) {
+ Pipeline.getPipeline().activeTextureUnit(ctx, texUnitIndex);
+ }
+
+ // native method for setting default TexCoordGeneration
+ void resetTexCoordGeneration(Context ctx) {
+ Pipeline.getPipeline().resetTexCoordGeneration(ctx);
+ }
+
+ // native method for setting default TextureAttributes
+ void resetTextureAttributes(Context ctx) {
+ Pipeline.getPipeline().resetTextureAttributes(ctx);
+ }
+
+ // native method for setting default PolygonAttributes
+ void resetPolygonAttributes(Context ctx) {
+ Pipeline.getPipeline().resetPolygonAttributes(ctx);
+ }
+
+ // native method for setting default LineAttributes
+ void resetLineAttributes(Context ctx) {
+ Pipeline.getPipeline().resetLineAttributes(ctx);
+ }
+
+ // native method for setting default PointAttributes
+ void resetPointAttributes(Context ctx) {
+ Pipeline.getPipeline().resetPointAttributes(ctx);
+ }
+
+ // native method for setting default TransparencyAttributes
+ void resetTransparency(Context ctx, int geometryType,
+ int polygonMode, boolean lineAA,
+ boolean pointAA) {
+ Pipeline.getPipeline().resetTransparency(ctx, geometryType,
+ polygonMode, lineAA,
+ pointAA);
+ }
+
+ // native method for setting default ColoringAttributes
+ void resetColoringAttributes(Context ctx,
+ float r, float g,
+ float b, float a,
+ boolean enableLight) {
+ Pipeline.getPipeline().resetColoringAttributes(ctx,
+ r, g,
+ b, a,
+ enableLight);
+ }
+
+ /**
+ * This native method makes sure that the rendering for this canvas
+ * gets done now.
+ */
+ void syncRender(Context ctx, boolean wait) {
+ Pipeline.getPipeline().syncRender(ctx, wait);
+ }
+
+ // The native method that sets this ctx to be the current one
+ static boolean useCtx(Context ctx, long display, Drawable drawable) {
+ return Pipeline.getPipeline().useCtx(ctx, display, drawable);
+ }
+
+ // Give the Pipeline a chance to release the context. The return
+ // value indicates whether the context was released.
+ private boolean releaseCtx(Context ctx, long dpy) {
+ return Pipeline.getPipeline().releaseCtx(ctx, dpy);
+ }
+
+ void clear(Context ctx, float r, float g, float b) {
+ Pipeline.getPipeline().clear(ctx, r, g, b);
+ }
+
+ void textureFillBackground(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY) {
+ Pipeline.getPipeline().textureFillBackground(ctx, texMinU, texMaxU, texMinV, texMaxV,
+ mapMinX, mapMaxX, mapMinY, mapMaxY);
+ }
+
+ void textureFillRaster(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, float mapZ, float alpha) {
+ Pipeline.getPipeline().textureFillRaster(ctx, texMinU, texMaxU, texMinV, texMaxV,
+ mapMinX, mapMaxX, mapMinY, mapMaxY, mapZ, alpha);
+ }
+
+ void executeRasterDepth(Context ctx, float posX, float posY, float posZ,
+ int srcOffsetX, int srcOffsetY, int rasterWidth, int rasterHeight,
+ int depthWidth, int depthHeight, int depthType, Object depthData) {
+ Pipeline.getPipeline().executeRasterDepth(ctx, posX, posY, posZ,
+ srcOffsetX, srcOffsetY, rasterWidth, rasterHeight, depthWidth, depthHeight, depthType, depthData);
+ }
+
+ // The native method for setting the ModelView matrix.
+ void setModelViewMatrix(Context ctx, double[] viewMatrix, double[] modelMatrix) {
+ Pipeline.getPipeline().setModelViewMatrix(ctx, viewMatrix, modelMatrix);
+ }
+
+ // The native method for setting the Projection matrix.
+ void setProjectionMatrix(Context ctx, double[] projMatrix) {
+ Pipeline.getPipeline().setProjectionMatrix(ctx, projMatrix);
+ }
+
+ // The native method for setting the Viewport.
+ void setViewport(Context ctx, int x, int y, int width, int height) {
+ Pipeline.getPipeline().setViewport(ctx, x, y, width, height);
+ }
+
+ // used for display Lists
+ void newDisplayList(Context ctx, int displayListId) {
+ Pipeline.getPipeline().newDisplayList(ctx, displayListId);
+ }
+ void endDisplayList(Context ctx) {
+ Pipeline.getPipeline().endDisplayList(ctx);
+ }
+ void callDisplayList(Context ctx, int id, boolean isNonUniformScale) {
+ Pipeline.getPipeline().callDisplayList(ctx, id, isNonUniformScale);
+ }
+
+ static void freeDisplayList(Context ctx, int id) {
+ Pipeline.getPipeline().freeDisplayList(ctx, id);
+ }
+ static void freeTexture(Context ctx, int id) {
+ Pipeline.getPipeline().freeTexture(ctx, id);
+ }
+
+ void texturemapping(Context ctx,
+ int px, int py,
+ int xmin, int ymin, int xmax, int ymax,
+ int texWidth, int texHeight,
+ int rasWidth,
+ int format, int objectId,
+ byte[] image,
+ int winWidth, int winHeight) {
+ Pipeline.getPipeline().texturemapping(ctx,
+ px, py,
+ xmin, ymin, xmax, ymax,
+ texWidth, texHeight,
+ rasWidth,
+ format, objectId,
+ image,
+ winWidth, winHeight);
+ }
+
+ boolean initTexturemapping(Context ctx, int texWidth,
+ int texHeight, int objectId) {
+ return Pipeline.getPipeline().initTexturemapping(ctx, texWidth,
+ texHeight, objectId);
+ }
+
+
+ // Set internal render mode to one of FIELD_ALL, FIELD_LEFT or
+ // FIELD_RIGHT. Note that it is up to the caller to ensure that
+ // stereo is available before setting the mode to FIELD_LEFT or
+ // FIELD_RIGHT. The boolean isTRUE for double buffered mode, FALSE
+ // foe single buffering.
+ void setRenderMode(Context ctx, int mode, boolean doubleBuffer) {
+ Pipeline.getPipeline().setRenderMode(ctx, mode, doubleBuffer);
+ }
+
+ // Set glDepthMask.
+ void setDepthBufferWriteEnable(Context ctx, boolean mode) {
+ Pipeline.getPipeline().setDepthBufferWriteEnable(ctx, mode);
+ }
+
+ // Methods to get actual capabilities from Canvas3D
+
+ boolean hasDoubleBuffer() {
+ return Pipeline.getPipeline().hasDoubleBuffer(this);
+ }
+
+ boolean hasStereo() {
+ return Pipeline.getPipeline().hasStereo(this);
+ }
+
+ int getStencilSize() {
+ return Pipeline.getPipeline().getStencilSize(this);
+ }
+
+ boolean hasSceneAntialiasingMultisample() {
+ return Pipeline.getPipeline().hasSceneAntialiasingMultisample(this);
+ }
+
+ boolean hasSceneAntialiasingAccum() {
+ return Pipeline.getPipeline().hasSceneAntialiasingAccum(this);
+ }
+
}
diff --git a/src/classes/share/javax/media/j3d/CanvasViewCache.java b/src/classes/share/javax/media/j3d/CanvasViewCache.java
index 53e2b58..935dbb2 100644
--- a/src/classes/share/javax/media/j3d/CanvasViewCache.java
+++ b/src/classes/share/javax/media/j3d/CanvasViewCache.java
@@ -434,7 +434,8 @@ class CanvasViewCache extends Object {
// XXXX: Peeking at the dirty flag is a hack. Need to revisit this.
boolean vprNotDirty = (viewCache.vpRetained.vprDirtyMask == 0);
- if(!canvas.offScreen &&
+ // Issue 131: If not manual, it has to be considered as an onscreen canvas.
+ if(!canvas.manualRendering &&
(vprNotDirty) &&
(cvcDirtyMask == 0) &&
(scrvcDirtyMask == 0) &&
diff --git a/src/classes/share/javax/media/j3d/CgShaderProgramRetained.java b/src/classes/share/javax/media/j3d/CgShaderProgramRetained.java
index 0eceed3..90893b1 100644
--- a/src/classes/share/javax/media/j3d/CgShaderProgramRetained.java
+++ b/src/classes/share/javax/media/j3d/CgShaderProgramRetained.java
@@ -35,138 +35,250 @@ class CgShaderProgramRetained extends ShaderProgramRetained {
initMirrorObject();
}
- // ShaderAttributeValue methods
+ // ShaderAttributeValue methods
- native ShaderError setUniform1i(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int value);
-
- native ShaderError setUniform1f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float value);
-
- native ShaderError setUniform2i(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int[] value);
-
- native ShaderError setUniform2f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float[] value);
-
- native ShaderError setUniform3i(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int[] value);
-
- native ShaderError setUniform3f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float[] value);
-
- native ShaderError setUniform4i(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int[] value);
-
- native ShaderError setUniform4f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float[] value);
-
- native ShaderError setUniformMatrix3f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float[] value);
+ ShaderError setUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int value) {
+
+ return Pipeline.getPipeline().setCgUniform1i(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float value) {
+
+ return Pipeline.getPipeline().setCgUniform1f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+
+ return Pipeline.getPipeline().setCgUniform2i(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniform2f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
- native ShaderError setUniformMatrix4f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float[] value);
+ ShaderError setUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+
+ return Pipeline.getPipeline().setCgUniform3i(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniform3f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+
+ return Pipeline.getPipeline().setCgUniform4i(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniform4f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniformMatrix3f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniformMatrix4f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
// ShaderAttributeArray methods
- native ShaderError setUniform1iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- int[] value);
-
- native ShaderError setUniform1fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
-
- native ShaderError setUniform2iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- int[] value);
-
- native ShaderError setUniform2fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
-
- native ShaderError setUniform3iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- int[] value);
-
- native ShaderError setUniform3fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
-
- native ShaderError setUniform4iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- int[] value);
-
- native ShaderError setUniform4fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
-
- native ShaderError setUniformMatrix3fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
+ ShaderError setUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
- native ShaderError setUniformMatrix4fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
+ return Pipeline.getPipeline().setCgUniform1iArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+ ShaderError setUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniform1fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+
+ return Pipeline.getPipeline().setCgUniform2iArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniform2fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+
+ return Pipeline.getPipeline().setCgUniform3iArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniform3fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+
+ return Pipeline.getPipeline().setCgUniform4iArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniform4fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniformMatrix3fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setCgUniformMatrix4fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
-
- /* New native interfaces */
- private native ShaderError createNativeShader(long ctx, int shaderType, long[] shaderId);
- private native ShaderError destroyNativeShader(long ctx, long shaderId);
- private native ShaderError compileNativeShader(long ctx, long shaderId, String program);
-
- private native ShaderError createNativeShaderProgram(long ctx, long[] shaderProgramId);
- private native ShaderError destroyNativeShaderProgram(long ctx, long shaderProgramId);
- private native ShaderError linkNativeShaderProgram(long ctx, long shaderProgramId,
- long[] shaderId);
- private native void lookupNativeVertexAttrNames(long ctx, long shaderProgramId,
- int numAttrNames, String[] attrNames, boolean[] errArr);
- private native void lookupNativeShaderAttrNames(long ctx, long shaderProgramId,
- int numAttrNames, String[] attrNames, long[] locArr,
- int[] typeArr, int[] sizeArr, boolean[] isArrayArr);
-
- private native ShaderError useShaderProgram(long ctx, long shaderProgramId);
/**
* Method to return a flag indicating whether this
@@ -179,70 +291,65 @@ class CgShaderProgramRetained extends ShaderProgramRetained {
/**
* Method to create the native shader.
*/
- ShaderError createShader(long ctx, ShaderRetained shader, long[] shaderIdArr) {
- return createNativeShader(ctx, shader.shaderType, shaderIdArr);
+ ShaderError createShader(Context ctx, ShaderRetained shader, ShaderId[] shaderIdArr) {
+ return Pipeline.getPipeline().createCgShader(ctx, shader.shaderType, shaderIdArr);
}
/**
* Method to destroy the native shader.
*/
- ShaderError destroyShader(long ctx, long shaderId) {
- return destroyNativeShader(ctx, shaderId);
+ ShaderError destroyShader(Context ctx, ShaderId shaderId) {
+ return Pipeline.getPipeline().destroyCgShader(ctx, shaderId);
}
/**
* Method to compile the native shader.
*/
- ShaderError compileShader(long ctx, long shaderId, String source) {
- return compileNativeShader(ctx, shaderId, source );
+ ShaderError compileShader(Context ctx, ShaderId shaderId, String source) {
+ return Pipeline.getPipeline().compileCgShader(ctx, shaderId, source );
}
/**
* Method to create the native shader program.
*/
- ShaderError createShaderProgram(long ctx, long[] shaderProgramIdArr) {
- return createNativeShaderProgram(ctx, shaderProgramIdArr);
+ ShaderError createShaderProgram(Context ctx, ShaderProgramId[] shaderProgramIdArr) {
+ return Pipeline.getPipeline().createCgShaderProgram(ctx, shaderProgramIdArr);
}
/**
* Method to destroy the native shader program.
*/
- ShaderError destroyShaderProgram(long ctx, long shaderProgramId) {
- return destroyNativeShaderProgram(ctx, shaderProgramId);
+ ShaderError destroyShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return Pipeline.getPipeline().destroyCgShaderProgram(ctx, shaderProgramId);
}
/**
* Method to link the native shader program.
*/
- ShaderError linkShaderProgram(long ctx, long shaderProgramId, long[] shaderIds) {
- return linkNativeShaderProgram(ctx, shaderProgramId, shaderIds);
+ ShaderError linkShaderProgram(Context ctx, ShaderProgramId shaderProgramId, ShaderId[] shaderIds) {
+ return Pipeline.getPipeline().linkCgShaderProgram(ctx, shaderProgramId, shaderIds);
}
- ShaderError bindVertexAttrName(long ctx, long shaderProgramId, String attrName, int attrIndex) {
+ ShaderError bindVertexAttrName(Context ctx, ShaderProgramId shaderProgramId, String attrName, int attrIndex) {
// This is a no-op for Cg
return null;
}
- void lookupVertexAttrNames(long ctx, long shaderProgramId, String[] attrNames, boolean[] errArr) {
- lookupNativeVertexAttrNames(ctx, shaderProgramId, attrNames.length, attrNames, errArr);
+ void lookupVertexAttrNames(Context ctx, ShaderProgramId shaderProgramId, String[] attrNames, boolean[] errArr) {
+ Pipeline.getPipeline().lookupCgVertexAttrNames(ctx, shaderProgramId, attrNames.length, attrNames, errArr);
}
- void lookupShaderAttrNames(long ctx, long shaderProgramId,
+ void lookupShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId,
String[] attrNames, AttrNameInfo[] attrNameInfoArr) {
int numAttrNames = attrNames.length;
- long[] locArr = new long[numAttrNames];
+ ShaderAttrLoc[] locArr = new ShaderAttrLoc[numAttrNames];
int[] typeArr = new int[numAttrNames];
int[] sizeArr = new int[numAttrNames]; // currently unused
boolean[] isArrayArr = new boolean[numAttrNames];
- // Initialize loc array to -1 (indicating no location)
- for (int i = 0; i < numAttrNames; i++) {
- locArr[i] = -1;
- }
-
- lookupNativeShaderAttrNames(ctx, shaderProgramId,
+ Pipeline.getPipeline().lookupCgShaderAttrNames(ctx, shaderProgramId,
numAttrNames, attrNames, locArr, typeArr, sizeArr, isArrayArr);
for (int i = 0; i < numAttrNames; i++) {
@@ -263,15 +370,15 @@ class CgShaderProgramRetained extends ShaderProgramRetained {
/**
* Method to enable the native shader program.
*/
- ShaderError enableShaderProgram(long ctx, long shaderProgramId) {
- return useShaderProgram(ctx, shaderProgramId);
+ ShaderError enableShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return Pipeline.getPipeline().useCgShaderProgram(ctx, shaderProgramId);
}
/**
* Method to disable the native shader program.
*/
- ShaderError disableShaderProgram(long ctx) {
- return useShaderProgram(ctx, 0);
+ ShaderError disableShaderProgram(Context ctx) {
+ return Pipeline.getPipeline().useCgShaderProgram(ctx, null);
}
diff --git a/src/classes/share/javax/media/j3d/ClipRetained.java b/src/classes/share/javax/media/j3d/ClipRetained.java
index 73a0385..ee18e8b 100644
--- a/src/classes/share/javax/media/j3d/ClipRetained.java
+++ b/src/classes/share/javax/media/j3d/ClipRetained.java
@@ -361,7 +361,7 @@ class ClipRetained extends LeafRetained {
}
final void sendMessage(int attrMask, Object attr, Object attr2) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.CLIP_CHANGED;
createMessage.universe = universe;
diff --git a/src/classes/share/javax/media/j3d/ColoringAttributesRetained.java b/src/classes/share/javax/media/j3d/ColoringAttributesRetained.java
index 4507f9c..d21e01d 100644
--- a/src/classes/share/javax/media/j3d/ColoringAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/ColoringAttributesRetained.java
@@ -141,22 +141,14 @@ class ColoringAttributesRetained extends NodeComponentRetained {
((ColoringAttributesRetained) mirror).set(this);
}
}
- /**
- * These two native methods update the native context
- */
- native void updateNative(long ctx,
- float dRed, float dGreen, float dBlue,
- float red, float green, float blue,
- float alpha,
- boolean lEnable,
- int shadeModel);
-
- void updateNative(long ctx,
+
+ void updateNative(Context ctx,
float dRed, float dGreen, float dBlue,
float alpha, boolean lEnable) {
- updateNative(ctx, dRed, dBlue, dGreen, color.x, color.y,
- color.z, alpha,
- lEnable, shadeModel);
+ Pipeline.getPipeline().updateColoringAttributes(ctx,
+ dRed, dBlue, dGreen, color.x, color.y,
+ color.z, alpha,
+ lEnable, shadeModel);
}
/**
@@ -213,7 +205,7 @@ class ColoringAttributesRetained extends NodeComponentRetained {
ArrayList gaList = Shape3DRetained.getGeomAtomsList(mirror.users, univList);
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.COLORINGATTRIBUTES_CHANGED;
createMessage.universe = null;
@@ -226,7 +218,7 @@ class ColoringAttributesRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.COLORINGATTRIBUTES_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/CompressedGeometryRenderMethod.java b/src/classes/share/javax/media/j3d/CompressedGeometryRenderMethod.java
index 64a72ce..3e53c20 100644
--- a/src/classes/share/javax/media/j3d/CompressedGeometryRenderMethod.java
+++ b/src/classes/share/javax/media/j3d/CompressedGeometryRenderMethod.java
@@ -22,14 +22,13 @@ class CompressedGeometryRenderMethod implements RenderMethod {
/**
* The actual rendering code for this RenderMethod.
*/
- public boolean render(RenderMolecule rm, Canvas3D cv, int pass,
+ public boolean render(RenderMolecule rm, Canvas3D cv,
RenderAtomListInfo ra, int dirtyBits) {
CompressedGeometryRetained cgr ;
-
if (rm.doInfinite) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
while (ra != null) {
renderCompressedGeo(ra, rm, cv);
ra = ra.next;
@@ -42,7 +41,7 @@ class CompressedGeometryRenderMethod implements RenderMethod {
while (ra != null) {
if (cv.ra == ra.renderAtom) {
if (cv.raIsVisible) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
renderCompressedGeo(ra, rm, cv);
isVisible = true;
}
@@ -50,7 +49,7 @@ class CompressedGeometryRenderMethod implements RenderMethod {
else {
if (!VirtualUniverse.mc.viewFrustumCulling ||
ra.renderAtom.localeVwcBounds.intersect(cv.viewFrustum)) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
cv.raIsVisible = true;
renderCompressedGeo(ra, rm, cv);
isVisible = true;
@@ -93,12 +92,9 @@ class CompressedGeometryRenderMethod implements RenderMethod {
return ;
}
- cgr.mirrorGeometry.execute
- (cv, ra.renderAtom, rm.isNonUniformScale,
+ cgr.mirrorGeometry.execute(cv, ra.renderAtom, rm.isNonUniformScale,
(useAlpha && ra.geometry().noAlpha), rm.alpha,
- rm.renderBin.multiScreen,
cv.screen.screen,
- rm.textureBin.attributeBin.ignoreVertexColors,
- -1) ;
+ rm.textureBin.attributeBin.ignoreVertexColors);
}
}
diff --git a/src/classes/share/javax/media/j3d/CompressedGeometryRetained.java b/src/classes/share/javax/media/j3d/CompressedGeometryRetained.java
index fe48f0f..dac05f7 100644
--- a/src/classes/share/javax/media/j3d/CompressedGeometryRetained.java
+++ b/src/classes/share/javax/media/j3d/CompressedGeometryRetained.java
@@ -84,7 +84,7 @@ class CompressedGeometryRetained extends GeometryRetained {
* Formerly native method that returns availability of a native by-reference
* rendering API for compressed geometry.
*/
- private boolean decompressByRef(long ctx) {
+ private boolean decompressByRef(Context ctx) {
return false;
}
@@ -93,14 +93,14 @@ class CompressedGeometryRetained extends GeometryRetained {
* rendering (and acceleration) for compressed geometry of the
* given version.
*/
- private boolean decompressHW(long ctx, int majorVersion, int minorVersion) {
+ private boolean decompressHW(Context ctx, int majorVersion, int minorVersion) {
return false;
}
/**
* Formerly native method that does HW compressed geometry rendering
*/
- private void execute(long ctx, int version, int bufferType,
+ private void execute(Context ctx, int version, int bufferType,
int bufferContents, int renderFlags,
int offset, int size, byte[] geometry) {
@@ -112,8 +112,7 @@ class CompressedGeometryRetained extends GeometryRetained {
*/
void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
boolean updateAlpha, float alpha,
- boolean multiScreen, int screen,
- boolean ignoreVertexColors, int pass) {
+ int screen, boolean ignoreVertexColors) {
// XXXX: alpha udpate
execute(cv.ctx, packedVersion, bufferType, bufferContents,
diff --git a/src/classes/share/javax/media/j3d/Context.java b/src/classes/share/javax/media/j3d/Context.java
new file mode 100644
index 0000000..85ff927
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/Context.java
@@ -0,0 +1,22 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Tagging interface for graphics context objects. The rendering pipelines
+ * will define concrete classes that implement this interface. All code that
+ * uses the tagged objects will be in the pipelines.
+ */
+interface Context {
+ // No methods or constants defined at this time
+}
diff --git a/src/classes/share/javax/media/j3d/DefaultRenderMethod.java b/src/classes/share/javax/media/j3d/DefaultRenderMethod.java
index b45d865..4b96d7b 100644
--- a/src/classes/share/javax/media/j3d/DefaultRenderMethod.java
+++ b/src/classes/share/javax/media/j3d/DefaultRenderMethod.java
@@ -24,23 +24,21 @@ class DefaultRenderMethod implements RenderMethod {
/**
* The actual rendering code for this RenderMethod
*/
- public boolean render(RenderMolecule rm, Canvas3D cv, int pass,
+ public boolean render(RenderMolecule rm, Canvas3D cv,
RenderAtomListInfo ra, int dirtyBits) {
-
+
boolean isVisible = false; // True if any of the RAs is visible.
while (ra != null) {
if (cv.ra == ra.renderAtom) {
if (cv.raIsVisible) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
ra.geometry().execute(cv, ra.renderAtom,
rm.isNonUniformScale,
rm.useAlpha, rm.alpha,
- rm.renderBin.multiScreen,
cv.screen.screen,
rm.textureBin.attributeBin.
- ignoreVertexColors,
- pass);
+ ignoreVertexColors);
isVisible = true;
}
}
@@ -48,14 +46,12 @@ class DefaultRenderMethod implements RenderMethod {
if (!VirtualUniverse.mc.viewFrustumCulling ||
ra.renderAtom.localeVwcBounds.intersect(cv.viewFrustum)) {
cv.raIsVisible = true;
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
ra.geometry().execute(cv, ra.renderAtom, rm.isNonUniformScale,
rm.useAlpha, rm.alpha,
- rm.renderBin.multiScreen,
cv.screen.screen,
rm.textureBin.attributeBin.
- ignoreVertexColors,
- pass);
+ ignoreVertexColors);
isVisible = true;
}
else {
diff --git a/src/classes/share/javax/media/j3d/DetailTextureImage.java b/src/classes/share/javax/media/j3d/DetailTextureImage.java
deleted file mode 100644
index 1c48e23..0000000
--- a/src/classes/share/javax/media/j3d/DetailTextureImage.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-package javax.media.j3d;
-
-import javax.vecmath.*;
-import java.util.*;
-
-
-class DetailTextureImage extends Object {
-
- final static int NFORMAT = 7; // number of texture format
-
- int objectIds[]; // texture object id, one per format
- int refCount[]; // texture bin reference count,
- // to keep track of if the texture
- // object id is still being referenced
- // by an active texture. If it
- // goes to 0 for a particular format,
- // the associated texture object
- // will be destroyed.
-
- int resourceCreationMask[]; // one creation mask per format
-
- ImageComponent2DRetained image = null; // the image itself
-
- Object resourceLock = new Object();
-
- DetailTextureImage(ImageComponent2DRetained img) {
- image = img;
- }
-
- native void bindTexture(long ctx, int objectId);
-
- native void updateTextureImage(long ctx,
- int numLevels, int level,
- int format, int storedFormat,
- int width, int height,
- int boundaryWidth, byte[] data);
-
-
- synchronized void incTextureBinRefCount(int format, TextureBin tb) {
- if (refCount == null) {
- refCount = new int[NFORMAT];
- }
- if (resourceCreationMask == null) {
- resourceCreationMask = new int[NFORMAT];
- }
- refCount[format]++;
-
- if (image != null &&
- (image.isByReference() ||
- image.source.getCapability(ImageComponent.ALLOW_IMAGE_WRITE))) {
- tb.renderBin.addNodeComponent(image);
- }
- }
-
- synchronized void decTextureBinRefCount(int format, TextureBin tb) {
-
- if (refCount != null) {
- refCount[format]--;
- }
- if (image != null &&
- (image.isByReference() ||
- image.source.getCapability(ImageComponent.ALLOW_IMAGE_WRITE))) {
- tb.renderBin.removeNodeComponent(image);
- }
- }
-
-
- synchronized void freeDetailTextureId(int id, int bitMask) {
- synchronized(resourceLock) {
- if (objectIds != null) {
- for (int i=0; i < resourceCreationMask.length; i++) {
- resourceCreationMask[i] &= ~bitMask;
- if (resourceCreationMask[i] == 0) {
- if (objectIds[i] == id) {
- objectIds[i] = -1;
- VirtualUniverse.mc.freeTexture2DId(id);
- break;
- }
- }
- }
- }
-
- }
- }
-
- synchronized void freeTextureId(int format, int id) {
- synchronized(resourceLock) {
- if ((objectIds != null) && (objectIds[format] == id)) {
- objectIds[format] = -1;
- VirtualUniverse.mc.freeTexture2DId(objectIds[format]);
- }
- }
- }
-
- protected void finalize() {
- if (objectIds != null) {
- // memory not yet free
- // send a message to the request renderer
- synchronized (VirtualUniverse.mc.contextCreationLock) {
- boolean found = false;
- for (int i=0; i < objectIds.length; i++) {
- if (objectIds[i] > 0) {
- for (Enumeration e = Screen3D.deviceRendererMap.elements();
- e.hasMoreElements(); ) {
- Renderer rdr = (Renderer) e.nextElement();
- J3dMessage renderMessage = VirtualUniverse.mc.getMessage();
- renderMessage.threads = J3dThread.RENDER_THREAD;
- renderMessage.type = J3dMessage.RENDER_IMMEDIATE;
- renderMessage.universe = null;
- renderMessage.view = null;
- renderMessage.args[0] = null;
- renderMessage.args[1] = new Integer(objectIds[i]);
- renderMessage.args[2] = "2D";
- rdr.rendererStructure.addMessage(renderMessage);
- }
- objectIds[i] = -1;
- found = true;
- }
- }
- if (found) {
- VirtualUniverse.mc.setWorkForRequestRenderer();
- }
- }
- }
- }
-
- void notifyImageComponentImageChanged(ImageComponentRetained image,
- Object value) {
- if (resourceCreationMask != null) {
- synchronized(resourceLock) {
- for (int i = 0; i < NFORMAT; i++) {
- resourceCreationMask[i] = 0;
- }
- }
- }
- }
-
- void bindTexture(Canvas3D cv, int format) {
- synchronized(resourceLock) {
- if (objectIds == null) {
- objectIds = new int[NFORMAT];
- for (int i = 0; i < NFORMAT; i++) {
- objectIds[i] = -1;
- }
- }
-
- if (objectIds[format] == -1) {
- objectIds[format] = VirtualUniverse.mc.getTexture2DId();
- }
- cv.addTextureResource(objectIds[format], this);
- }
-
- bindTexture(cv.ctx, objectIds[format]);
- }
-
-
- void updateNative(Canvas3D cv, int format) {
- if ((cv.textureExtendedFeatures & Canvas3D.TEXTURE_DETAIL) == 0) {
- return;
- }
-
- boolean reloadTexture = false;
-
- // bind the detail texture
-
- bindTexture(cv, format);
-
- if (cv.useSharedCtx && cv.screen.renderer.sharedCtx != 0) {
- if ((resourceCreationMask[format] & cv.screen.renderer.rendererBit)
- == 0) {
- reloadTexture = true;
- cv.makeCtxCurrent(cv.screen.renderer.sharedCtx);
- bindTexture(cv, format);
- }
- } else {
- if ((resourceCreationMask[format] & cv.canvasBit) == 0) {
- reloadTexture = true;
- }
- }
-
- // No D3D support yet
-
- if (reloadTexture) {
-
- updateTextureImage(cv.ctx, 1, 0, format, image.storedYupFormat,
- image.width, image.height, 0, image.imageYup);
-
-
- // Rendered image
-
- }
-
- if (cv.useSharedCtx) {
- cv.makeCtxCurrent(cv.ctx);
- synchronized(resourceLock) {
- resourceCreationMask[format] |= cv.screen.renderer.rendererBit;
- }
- } else {
- synchronized(resourceLock) {
- resourceCreationMask[format] |= cv.canvasBit;
- }
- }
- }
-}
-
-
-
diff --git a/src/classes/share/javax/media/j3d/DirectionalLightRetained.java b/src/classes/share/javax/media/j3d/DirectionalLightRetained.java
index 79c7bf6..9c3f681 100644
--- a/src/classes/share/javax/media/j3d/DirectionalLightRetained.java
+++ b/src/classes/share/javax/media/j3d/DirectionalLightRetained.java
@@ -55,7 +55,7 @@ class DirectionalLightRetained extends LightRetained
*/
void setDirection(Vector3f direction) {
initDirection(direction);
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.LIGHT_CHANGED;
createMessage.universe = universe;
@@ -168,13 +168,11 @@ class DirectionalLightRetained extends LightRetained
}
- native void updateLight(long ctx,
- int lightSlot, float red, float green,
- float blue, float x, float y, float z);
- void update(long ctx, int lightSlot, double scale) {
- updateLight(ctx, lightSlot, color.x, color.y, color.z,
- xformDirection.x, xformDirection.y,
- xformDirection.z);
+ void update(Context ctx, int lightSlot, double scale) {
+ Pipeline.getPipeline().updateDirectionalLight(ctx,
+ lightSlot, color.x, color.y, color.z,
+ xformDirection.x, xformDirection.y,
+ xformDirection.z);
}
// Clones only the retained side, internal use only
diff --git a/src/classes/share/javax/media/j3d/DisplayListRenderMethod.java b/src/classes/share/javax/media/j3d/DisplayListRenderMethod.java
index b452528..d6aeb76 100644
--- a/src/classes/share/javax/media/j3d/DisplayListRenderMethod.java
+++ b/src/classes/share/javax/media/j3d/DisplayListRenderMethod.java
@@ -29,19 +29,17 @@ class DisplayListRenderMethod implements RenderMethod {
*/
int[] buffer = new int[bufferSize];
- native void callDisplayLists(int size, int[] buffer);
-
/**
* The actual rendering code for this RenderMethod
*/
- public boolean render(RenderMolecule rm, Canvas3D cv, int pass,
+ public boolean render(RenderMolecule rm, Canvas3D cv,
RenderAtomListInfo ra,
int dirtyBits) {
if (rm.doInfinite ||
!VirtualUniverse.mc.viewFrustumCulling ||
rm.vwcBounds.intersect(cv.viewFrustum)) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
cv.callDisplayList(cv.ctx, rm.displayListId,
rm.isNonUniformScale);
return true;
@@ -51,11 +49,10 @@ class DisplayListRenderMethod implements RenderMethod {
public boolean renderSeparateDlists(RenderMolecule rm,
Canvas3D cv,
- int pass,
RenderAtomListInfo r, int dirtyBits) {
if (rm.doInfinite) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
while (r != null) {
cv.callDisplayList(cv.ctx,
((GeometryArrayRetained)r.geometry()).dlistId,
@@ -70,7 +67,7 @@ class DisplayListRenderMethod implements RenderMethod {
while (r != null) {
if (cv.ra == r.renderAtom) {
if (cv.raIsVisible) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
cv.callDisplayList(cv.ctx,
((GeometryArrayRetained)r.geometry()).dlistId,
rm.isNonUniformScale);
@@ -79,7 +76,7 @@ class DisplayListRenderMethod implements RenderMethod {
}
else {
if (r.renderAtom.localeVwcBounds.intersect(cv.viewFrustum)) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
cv.raIsVisible = true;
cv.callDisplayList(cv.ctx,
((GeometryArrayRetained)r.geometry()).dlistId,
@@ -101,12 +98,11 @@ class DisplayListRenderMethod implements RenderMethod {
public boolean renderSeparateDlistPerRinfo(RenderMolecule rm,
Canvas3D cv,
- int pass,
RenderAtomListInfo r,
int dirtyBits) {
if (rm.doInfinite) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
while (r != null) {
cv.callDisplayList(cv.ctx,r.renderAtom.dlistIds[r.index],
rm.isNonUniformScale);
@@ -118,7 +114,7 @@ class DisplayListRenderMethod implements RenderMethod {
while (r != null) {
if (cv.ra == r.renderAtom) {
if (cv.raIsVisible) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
cv.callDisplayList(cv.ctx, r.renderAtom.dlistIds[r.index],
rm.isNonUniformScale);
isVisible = true;
@@ -126,7 +122,7 @@ class DisplayListRenderMethod implements RenderMethod {
}
else {
if (r.renderAtom.localeVwcBounds.intersect(cv.viewFrustum)) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
cv.raIsVisible = true;
cv.callDisplayList(cv.ctx, r.renderAtom.dlistIds[r.index],
rm.isNonUniformScale);
@@ -190,7 +186,7 @@ class DisplayListRenderMethod implements RenderMethod {
}
void buildIndividualDisplayList(RenderAtomListInfo ra, Canvas3D cv,
- long ctx) {
+ Context ctx) {
GeometryArrayRetained geo;
geo = (GeometryArrayRetained)ra.geometry();
diff --git a/src/classes/share/javax/media/j3d/DistanceLOD.java b/src/classes/share/javax/media/j3d/DistanceLOD.java
index 2598eb8..948558b 100644
--- a/src/classes/share/javax/media/j3d/DistanceLOD.java
+++ b/src/classes/share/javax/media/j3d/DistanceLOD.java
@@ -177,7 +177,7 @@ public class DistanceLOD extends LOD {
double viewDistance = 0.0;
int nSwitches,i,index=0;
- Transform3D localToWorldTrans = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D localToWorldTrans = new Transform3D();
localToWorldTrans.set(((NodeRetained)this.retained).getCurrentLocalToVworld());
@@ -220,9 +220,6 @@ public class DistanceLOD extends LOD {
sw.setWhichChild(index);
}
}
-
- VirtualUniverse.mc.addToTransformFreeList(localToWorldTrans);
-
// Insert wakeup condition into queue
wakeupOn(wakeupFrame);
diff --git a/src/classes/share/javax/media/j3d/Drawable.java b/src/classes/share/javax/media/j3d/Drawable.java
new file mode 100644
index 0000000..77e9f5a
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/Drawable.java
@@ -0,0 +1,22 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Tagging interface for drawable (window) objects. The rendering pipelines
+ * will define concrete classes that implement this interface. All code that
+ * uses the tagged objects will be in the pipelines.
+ */
+interface Drawable {
+ // No methods or constants defined at this time
+}
diff --git a/src/classes/share/javax/media/j3d/DrawingSurfaceObjectAWT.java b/src/classes/share/javax/media/j3d/DrawingSurfaceObjectAWT.java
index d4dfa23..71d8167 100644
--- a/src/classes/share/javax/media/j3d/DrawingSurfaceObjectAWT.java
+++ b/src/classes/share/javax/media/j3d/DrawingSurfaceObjectAWT.java
@@ -21,27 +21,29 @@ import java.awt.Point;
class DrawingSurfaceObjectAWT extends DrawingSurfaceObject {
// drawing surface
- long nativeDS = 0;
- long dsi = 0;
+ private long nativeDS = 0;
+ private long dsi = 0;
- boolean doLastUnlock = false;
- boolean xineramaDisabled = false;
+ private boolean doLastUnlock = false;
+ private boolean xineramaDisabled = false;
- long display = 0;
- int screenID = 0;
+ private long display = 0;
+ private int screenID = 0;
- static long nativeAWT = 0;
+ private static long nativeAWT = 0;
- native boolean lockAWT(long ds);
- native void unlockAWT(long ds);
- static native void lockGlobal(long awt);
- static native void unlockGlobal(long awt);
- native long getDrawingSurfaceAWT(Canvas3D cv, long awt);
- native long getDrawingSurfaceInfo(long ds);
- static native void freeResource(long awt, long ds, long dsi);
- native int getDrawingSurfaceWindowIdAWT(Canvas3D cv, long ds, long dsi,
- long display, int screenID,
- boolean xineramaDisabled);
+ private native boolean lockAWT(long ds);
+ private native void unlockAWT(long ds);
+ private static native void lockGlobal(long awt);
+ private static native void unlockGlobal(long awt);
+ private native long getDrawingSurfaceAWT(Canvas3D cv, long awt);
+ private native long getDrawingSurfaceInfo(long ds);
+ private static native void freeResource(long awt, long ds, long dsi);
+
+ // TODO: long window
+ private native int getDrawingSurfaceWindowIdAWT(Canvas3D cv, long ds, long dsi,
+ long display, int screenID,
+ boolean xineramaDisabled);
DrawingSurfaceObjectAWT(Canvas3D cv, long awt,
long display, int screenID,
@@ -110,9 +112,10 @@ class DrawingSurfaceObjectAWT extends DrawingSurfaceObject {
if (nativeDS != 0) {
dsi = getDrawingSurfaceInfo(nativeDS);
if (dsi != 0) {
- canvas.window = getDrawingSurfaceWindowIdAWT
+ long nativeDrawable = getDrawingSurfaceWindowIdAWT
(canvas, nativeDS, dsi, display, screenID,
xineramaDisabled);
+ canvas.drawable = new NativeDrawable(nativeDrawable);
}
}
}
diff --git a/src/classes/share/javax/media/j3d/EnvironmentSet.java b/src/classes/share/javax/media/j3d/EnvironmentSet.java
index 200c1ae..35c6cac 100644
--- a/src/classes/share/javax/media/j3d/EnvironmentSet.java
+++ b/src/classes/share/javax/media/j3d/EnvironmentSet.java
@@ -366,9 +366,6 @@ class EnvironmentSet extends Object implements ObjectUpdate{
a.definingRenderingAttributes = null;
a.onUpdateList &= ~AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
- // Add this attributebin to the free list
- renderBin.attrBinFreelist.add(a);
-
if (attributeBinList == null && addAttributeBins.size() == 0) {
// Now remove this environment set from all the lights and fogs
// that use this
diff --git a/src/classes/share/javax/media/j3d/ExceptionStrings.properties b/src/classes/share/javax/media/j3d/ExceptionStrings.properties
index b1541ba..8d13787 100644
--- a/src/classes/share/javax/media/j3d/ExceptionStrings.properties
+++ b/src/classes/share/javax/media/j3d/ExceptionStrings.properties
@@ -42,6 +42,8 @@ Background8=Background: no capability to get application bounds
Background9=Background: no capability to set image scale mode
Background10=Background: no capability to get image scale mode
Background11=Background: illegal image scale mode
+Background12=Background: Live Background with an ImageComponent2D that is being used by a Canvas3D as an off-screen buffer.
+Background13=Background: In Immediate mode context with an ImageComponent2D that is being used by a Canvas3D as an off-screen buffer.
AlternateAppearance0=AlternateAppearance: no capability to write appearance
AlternateAppearance2=AlternateAppearance: no capability to read appearance
AlternateAppearance3=AlternateAppearance: no capability to write influencing bounds
@@ -121,7 +123,7 @@ Canvas3D0=Canvas3D: Cannot swap buffers when the renderer is running
Canvas3D1=Canvas3D: Not in off-screen mode
Canvas3D2=Canvas3D: Off-screening rendering is in progress
Canvas3D3=Canvas3D: The specified ImageComponent2D is used by more than on Canvas3D
-Canvas3D7=*** ERROR: Canvas3D constructed with a null GraphicsConfiguration
+Canvas3D7=WARNING: Canvas3D constructed with null GraphicsConfiguration;
Canvas3D8=Canvas3D: The width of the associated Screen3D's size is <= 0
Canvas3D9=Canvas3D: The height of the associated Screen3D's size is <= 0
Canvas3D10=Canvas3D: Off-screen buffer is null
@@ -130,14 +132,19 @@ Canvas3D12=Canvas3D: The physical width of the associated Screen3D is <= 0
Canvas3D13=Canvas3D: The physical height of the associated Screen3D is <= 0
Canvas3D14=Canvas3D: Illegal operation in off-screen mode
Canvas3D15=Canvas3D: For offscreen rendering, byReference image should be an instance of BufferedImage
-Canvas3D16=Canvas3D: Offscreen rendering does not support FORMAT_CHANNEL8
+Canvas3D16=Canvas3D: Offscreen rendering has to be a 3-component or 4-component format.
Canvas3D17=Canvas3D: GraphicsConfiguration is not compatible with Canvas3D
-Canvas3D18=*** This will cause a NullPointerException in a subsequent release
+Canvas3D18=will attempt to use a default GraphicsConfiguration
Canvas3D19=Canvas3D: null GraphicsConfiguration
Canvas3D20=Canvas3D does not support serialization
-Canvas3D21=*** ERROR: GraphicsConfiguration not created with GraphicsConfigTemplate3D
-Canvas3D22=*** This will cause an IllegalArgumentException in a subsequent release
Canvas3D23=Unable to get FBConfig from GraphicsConfiguration
+Canvas3D24=Canvas3D: Can't force render of offscreen buffer because it is an automatic one.
+Canvas3D25=Canvas3D: AutoOffscreenCanvas3D must be used as off-screen Canvas3D.
+Canvas3D26=Canvas3D: ImageComponent2D is already part of a live scene graph.
+Canvas3D27=Canvas3D: ImageComponent2D is already being used by an immediate mode context.
+Canvas3D28=Canvas3D: ImageComponent2D is already being used by by another Canvas3D as an off-screen buffer.
+Canvas3D29=Canvas3D: Non-recoverable graphics configuration error
+Canvas3D30=Canvas3D: Non-recoverable off-screen rendering error
BoundingPolytope0=BoundingPolytope( Bounds) unrecognized bounds object
BoundingPolytope1=BoundingPolytope( Bounds) unrecognized bounds type
BoundingPolytope2=set( Bounds) unrecognized bounds type
@@ -303,6 +310,9 @@ GeometryArray132=GeometryArray: vertexAttrCount != vertexAttrSizes.length
GeometryArray133=GeometryArray: vertexAttrSize value out of range
GeometryArray134=GeometryArray: vertexAttrSize invalid for this method
GeometryArray135=GeometryArray: USE_COORD_INDEX_ONLY bit cannot be set for non-indexed geometry
+GeometryArray136=GeometryArray: BY_REFERENCE_INDICES bit can be set only for indexed geometry
+GeometryArray137=GeometryArray: BY_REFERENCE_INDICES bit can be set only if BY_REFERENCE bit is also set
+GeometryArray138=GeometryArray: BY_REFERENCE_INDICES bit can be set only if USE_COORD_INDEX_ONLY bit is also set
GeometryDecompressor0=GeometryDecompressor: start+length > data array size
GeometryDecompressor1=GeometryDecompressor: bad delta normal in compressed buffer
GeometryDecompressorRetained0=GeometryDecompressorRetained: bad buffer data type
@@ -328,6 +338,7 @@ Light8=Light: no capability to read scopes
Light9=Light: no capability to append scope
Light11=Light: no capability to write influencing bounds
Light12=Light: no capability to read influencing bounds
+GeometryStripArrayRetained0=Illegal stripVertexCounts
GeometryStripArray0=GeometryStripArray: no capability to get number of strips
GeometryStripArray1=GeometryStripArray: no capability to get strip vertex counts
GeometryStripArray2=GeometryStripArray: no capability to set strip vertex counts
@@ -349,16 +360,30 @@ GraphicsContext3D25=ModelClip: Scene Graph ModelClip may not be in immediate mod
GraphicsContext3D26=Shape3D: Scene Graph Shape3D may not be in immediate mode
GraphicsContext3D27=ImageComponent2D size is smaller than read Raster size
GraphicsContext3D28=DepthComponent size is smaller than read Raster size
+GraphicsContext3D29=GraphicsContext3D: For readRaster, byReference image should be an instance of BufferedImage
+GraphicsContext3D30=GraphicsContext3D: Appearance has an ImageComponent2D used by an OffScreen Canvas3D.
+GraphicsContext3D31=GraphicsContext3D: Background's ImageComponent2D is already being used as an OffScreen Canvas3D.
+GraphicsContext3D32=GraphicsContext3D: Raster's ImageComponent2D is already being used as an OffScreen Canvas3D.
+GraphicsContext3D33=GraphicsContext3D: Raster's ImageComponent2D is not of ImageClass.BUFFERED_IMAGE.
+GraphicsContext3D34=GraphicsContext3D: Raster's ImageComponent2D is in by-reference mode and its RenderedImage is null.
+GraphicsContext3D35=GraphicsContext3D: Raster's ImageComponent2D format is not a 3-component format or a 4-component format.
+GraphicsContext3D36=GraphicsContext3D: Raster and Raster's ImageComponent2D are part of a live scene graph.
+GraphicsContext3D37=GraphicsContext3D: Raster's ImageComponent2D is being used by an immediate mode context, or by a Canvas3D as an off-screen buffer.
ImageComponent0=ImageComponent: no capability to get width
ImageComponent1=ImageComponent: no capability to get height
ImageComponent2=ImageComponent: no capability to get format
-GeometryStripArrayRetained0=Illegal stripVertexCounts
+ImageComponent3=ImageComponent: This image is being used by a Canvas3D as an off-screen buffer.
+ImageComponent4=ImageComponent: The image class of this object is ImageClass.NIO_IMAGE_BUFFER.
ImageComponent2D0=ImageComponent2D: no capability to get image
ImageComponent2D1=ImageComponent2D: no capability to set image
ImageComponent2D2=ImageComponent2D: must be in BY_REFERENCE mode to use this method
ImageComponent2D3=ImageComponent2D: illegal dimension
ImageComponent2D4=ImageComponent2D: must be in BY_COPY mode to use this method
ImageComponent2D5=ImageComponent2D: image is not an instanceof of BufferedImage
+ImageComponent2D6=ImageComponent2D: type mismatch between sub-image and existing image.
+ImageComponent2D7=ImageComponent2D: Nio buffer image must be byReference is true.
+ImageComponent2D8=ImageComponent2D: Nio buffer image must be yUp is true.
+ImageComponent2D9=ImageComponent2D: The image class is not ImageClass.NIO_IMAGE_BUFFER.
ImageComponent3D0=ImageComponent3D: no capability to get depth
ImageComponent3D1=ImageComponent3D - incompatible depth
ImageComponent3D2=ImageComponent3D - incompatible width
@@ -408,6 +433,9 @@ IndexedGeometryArray27=IndexedGeometryArray: index value less than zero
IndexedGeometryArray28=IndexedGeometryArray: no capability to set vertex attribute index
IndexedGeometryArray29=IndexedGeometryArray: no capability to get vertex attribute index
IndexedGeometryArray30=IndexedGeometryArray: index vertexAttr value greater than the array length
+IndexedGeometryArray31=IndexedGeometryArray: cannot access indices directly in BY_REFERENCE_INDICES mode
+IndexedGeometryArray32=IndexedGeometryArray: can access indices by reference only in BY_REFERENCE_INDICES mode
+IndexedGeometryArray33=IndexedGeometryArray: coordIndices array length < initial index index + valid index count
IndexedLineArray0=IndexedLineArray: illegal vertexCount
IndexedLineArray1=IndexedLineArray: illegal indexCount
IndexedGeometryStripArray0=IndexedGeometryStripArray: no capability to get number of strips
@@ -490,6 +518,12 @@ MorphRetained5=Invalid SceneGraphPath encountered : localToVworld is null.
MorphRetained7=Morph: number of weights not same as number of GeometryArrays
MorphRetained8=Morph: sum of all weights is NOT 1.0
MorphRetained9=Morph: vertex attributes are not supported
+NioImageBuffer0=NioImageBuffer: image width is not positive
+NioImageBuffer1=NioImageBuffer: image height is not positive
+NioImageBuffer2=NioImageBuffer: unsupported image type
+NioImageBuffer3=NioImageBuffer: NIO buffer limit is incorrect
+NioImageBuffer4=NioImageBuffer: NIO buffer type does not match image type
+NioImageBuffer5=NioImageBuffer: NIO buffer does not match native byte order of underlying platform
Node0=Node: no capability to read parent
Node1=Node: no capability to set bounds
Node2=Node: no capability to read user bounds
@@ -518,6 +552,8 @@ Picking0=Cannot call picking under a SharedGroup node
Picking2=Picking: Node has no parent and locale. This is illegal!
NodeComponent0=NodeComponent:cloneNodeComponent must be defined in subclass
NodeComponent1=Cannot duplicate a Compiled NodeComponent object
+NodeComponent2=Live NodeComponent with an ImageComponent2D that is being used by a Canvas3D as an off-screen buffer.
+NodeComponent3=In Immediate mode context with an ImageComponent2D that is being used by a Canvas3D as an off-screen buffer.
NodeRetained0=Not supported in a Shared Graph
NodeRetained1=Only supported in a Shared Graph
NodeRetained2=invalid scene graph path
@@ -570,6 +606,7 @@ Raster8=Raster: no capability to get offset
Raster9=Raster: no capability to set size
Raster10=Raster: no capability to set clip mode
Raster11=Raster: no capability to get clip mode
+Raster12=Raster: Live Raster with an ImageComponent2D that is being used by a Canvas3D as an off-screen buffer.
PointArrayRetained0=PickPoint doesn't make sense for geometry-based picking. Java 3D doesn't have spatial information of the surface. Should use PickBounds with BoundingSphere and set radius to a epsilon tolerance.
PointAttributes0=PointAttributes: no capability to set point size
PointAttributes1=PointAttributes: no capability to get point size
@@ -590,6 +627,15 @@ PolygonAttributes12=PolygonAttributes: illegal cull face
QuadArray0=QuadArray: illegal vertexCount
QuadArrayRetained0=PickPoint doesn't make sense for geometry-based picking. Java 3D doesn't have spatial information of the surface. Should use PickBounds with BoundingSphere and set radius to a epsilon tolerance.
PositionPathInterpolator0=PositionPathInterpolator: length of knots and positions must be equal
+Renderer0=Renderer: Unexpected RuntimeException caught during buffer swap
+Renderer1=Renderer: Error initializing GraphicsConfiguration properties
+Renderer2=Renderer: Error creating Canvas3D graphics context for queryProperties()
+Renderer3=Renderer: Error in GraphicsConfigTemplate3D.getBestConfiguration()
+Renderer4=Renderer: Error in GraphicsConfigTemplate3D.isConfigSupported()
+Renderer5=Renderer: Error creating Canvas3D off-screen buffer
+Renderer6=Renderer: Error creating immediate mode Canvas3D graphics context
+Renderer7=Renderer: Error creating Canvas3D graphics context
+Renderer8=Renderer: Unexpected RuntimeException caught during rendering
RenderingAttributes0=RenderingAttributes: no capability to set depth buffer mode
RenderingAttributes1=RenderingAttributes: no capability to get depth buffer mode
RenderingAttributes2=RenderingAttributes: no capability to set depth buffer write mode
@@ -748,7 +794,7 @@ Texture26=Texture: no capability to get anisotropic filter information
Texture27=Texture: Illegal anisotropic filter degree
Texture28=Texture: Illegal minification filter
Texture29=Texture: Illegal magnification filter
-Texture30=Texture: boundary width < 0
+Texture30=Texture: illegal boundary width
Texture31=Texture: illegal boundary mode value
Texture32=Texture: no capability to set base level
Texture33=Texture: no capability to set maximum level
@@ -764,6 +810,8 @@ Texture42=Texture: minimumLOD > maximumLOD
Texture43=Texture: maximumLOD < minimumLOD
Texture44=Texture: no capability to set lod offset
Texture45=Texture: no capability to get lod offset
+Texture46=Texture: illegal width < 1
+Texture47=Texture: illegal height < 1
Texture2D0=Texture: no capability to get detail texture information
Texture2D1=Texture: Illegal detail texture mode value
Texture2D2=Texture: Illegal detail texture level
@@ -926,12 +974,12 @@ ModelClip13=ModelClip: no capability to write influencing bounding leaf
ModelClip14=ModelClip: no capability to read influencing bounding leaf
ModelClipRetained1=ModelClip: illegal node under SharedGroup Branch
MasterControl0=OpenGL is not MT safe
-MasterControl1=Green threads are not supported
MasterControl2=NOTE: simulated multi-texture will not work for programmable shaders
MasterControl3=and will be removed entirely in the next release of Java 3D
J3DBuffer0=Native access to NIO buffer not supported
J3DBuffer1=NIO buffer must be a direct buffer
J3DBuffer2=NIO buffer must match native byte order of underlying platform
+J3DGraphics2D0=Cannot use Graphics2D object after dispose() is called
GLSLShaderProgram0=GLSLShaderProgram: no capability to read names
GLSLShaderProgram1=GLSLShaderProgram: no capability to read shaders
GLSLShaderProgram2=GLSLShaderProgram: Shader has incompatible shading language
diff --git a/src/classes/share/javax/media/j3d/ExponentialFogRetained.java b/src/classes/share/javax/media/j3d/ExponentialFogRetained.java
index 48d9a64..367929c 100644
--- a/src/classes/share/javax/media/j3d/ExponentialFogRetained.java
+++ b/src/classes/share/javax/media/j3d/ExponentialFogRetained.java
@@ -46,7 +46,7 @@ class ExponentialFogRetained extends FogRetained {
*/
void setDensity(float density){
this.density = density;
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.FOG_CHANGED;
createMessage.universe = universe;
@@ -70,7 +70,7 @@ class ExponentialFogRetained extends FogRetained {
// Initialize the mirror object, this needs to be done, when
// renderBin is not accessing any of the fields
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.FOG_CHANGED;
@@ -108,12 +108,10 @@ class ExponentialFogRetained extends FogRetained {
* This method and its native counterpart update the native context
* fog values.
*/
- native void update(long ctx, float red, float green, float blue, float density);
-
- void update(long ctx, double scale) {
+ void update(Context ctx, double scale) {
// Issue 144: recompute the density in EC, and send it to native code
validateDistancesInEc(scale);
- update(ctx, color.x, color.y, color.z, densityInEc);
+ Pipeline.getPipeline().updateExponentialFog(ctx, color.x, color.y, color.z, densityInEc);
}
diff --git a/src/classes/share/javax/media/j3d/FogRetained.java b/src/classes/share/javax/media/j3d/FogRetained.java
index 75ce250..ab1350e 100644
--- a/src/classes/share/javax/media/j3d/FogRetained.java
+++ b/src/classes/share/javax/media/j3d/FogRetained.java
@@ -452,7 +452,7 @@ abstract class FogRetained extends LeafRetained{
* This abstract method is used to update the current native
* context fog values.
*/
- abstract void update(long ctx, double scale);
+ abstract void update(Context ctx, double scale);
void updateImmediateMirrorObject(Object[] objs) {
@@ -715,7 +715,7 @@ abstract class FogRetained extends LeafRetained{
if (scopes.size() > 0) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.FOG_CHANGED;
@@ -771,7 +771,7 @@ abstract class FogRetained extends LeafRetained{
}
final void sendMessage(int attrMask, Object attr) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.universe = universe;
createMessage.type = J3dMessage.FOG_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/FreeListManager.java b/src/classes/share/javax/media/j3d/FreeListManager.java
index 15fa177..3c8df81 100644
--- a/src/classes/share/javax/media/j3d/FreeListManager.java
+++ b/src/classes/share/javax/media/j3d/FreeListManager.java
@@ -18,46 +18,26 @@ class FreeListManager {
private static final boolean DEBUG = false;
// constants that represent the freelists managed by the Manager
- static final int MESSAGE = 0;
- static final int BHLEAF = 1;
- static final int TRANSFORM3D = 2;
- static final int BHINTERNAL = 3;
- static final int DISPLAYLIST = 4;
- static final int TEXTURE2D = 5;
- static final int TEXTURE3D = 6;
- static final int VECTOR3D = 7;
- static final int POINT3D = 8;
- static int MAXINT = 8;
+ static final int DISPLAYLIST = 0;
+ static final int TEXTURE2D = 1;
+ static final int TEXTURE3D = 2;
+
+ private static int maxFreeListNum = 2;
// what list we are going to shrink next
private static int currlist = 0;
- // the freelists managed by the manager
- static MemoryFreeList[] freelist = new MemoryFreeList[MAXINT+1];
-
+ static MemoryFreeList[] freelist = null;
+
static void createFreeLists() {
- freelist[MESSAGE] = new MemoryFreeList("javax.media.j3d.J3dMessage");
- freelist[BHLEAF] = new MemoryFreeList("javax.media.j3d.BHLeafNode");
- freelist[TRANSFORM3D] = new MemoryFreeList("javax.media.j3d.Transform3D");
- freelist[BHINTERNAL] = new MemoryFreeList("javax.media.j3d.BHInternalNode");
- freelist[DISPLAYLIST] = new IntegerFreeList();
- freelist[TEXTURE2D] = new IntegerFreeList();
- freelist[TEXTURE3D] = new IntegerFreeList();
- freelist[POINT3D] = new MemoryFreeList("javax.vecmath.Point3d");
- freelist[VECTOR3D] = new MemoryFreeList("javax.vecmath.Vector3d");
+ maxFreeListNum = 2;
+ freelist = new MemoryFreeList[maxFreeListNum+1];
+ freelist[DISPLAYLIST] = new IntegerFreeList();
+ freelist[TEXTURE2D] = new IntegerFreeList();
+ freelist[TEXTURE3D] = new IntegerFreeList();
+
}
- // allows list to be created. The listId for the new list is returned.
- static int createNewFreeList(String className) {
- MAXINT++;
- MemoryFreeList[] temp = freelist;
- freelist = new MemoryFreeList[MAXINT+1];
- System.arraycopy(temp, 0, freelist, 0, MAXINT+1);
- freelist[MAXINT] = new MemoryFreeList(className);
- return MAXINT;
- }
-
-
// see if the current list can be shrunk
static void manageLists() {
// System.out.println("manageLists");
@@ -66,12 +46,12 @@ class FreeListManager {
}
currlist++;
- if (currlist > MAXINT) currlist = 0;
+ if (currlist > maxFreeListNum) currlist = 0;
}
// return the freelist specified by the list param
static MemoryFreeList getFreeList(int list) {
- if (list < 0 || list > MAXINT) {
+ if (list < 0 || list > maxFreeListNum) {
if (DEBUG) System.out.println("illegal list");
return null;
}
@@ -92,5 +72,4 @@ class FreeListManager {
freelist[listId].clear();
}
-
}
diff --git a/src/classes/share/javax/media/j3d/GLSLShaderProgramRetained.java b/src/classes/share/javax/media/j3d/GLSLShaderProgramRetained.java
index 651d15d..81e7a44 100644
--- a/src/classes/share/javax/media/j3d/GLSLShaderProgramRetained.java
+++ b/src/classes/share/javax/media/j3d/GLSLShaderProgramRetained.java
@@ -29,8 +29,8 @@ class GLSLShaderProgramRetained extends ShaderProgramRetained {
// System.out.println("GLSLShaderProgramRetained : createMirrorObject");
// This method should only call by setLive().
if (mirror == null) {
- GLSLShaderProgramRetained mirrorGLSLSP = new GLSLShaderProgramRetained();
- mirror = mirrorGLSLSP;
+ GLSLShaderProgramRetained mirrorGLSLSP = new GLSLShaderProgramRetained();
+ mirror = mirrorGLSLSP;
mirror.source = source;
}
initMirrorObject();
@@ -38,134 +38,247 @@ class GLSLShaderProgramRetained extends ShaderProgramRetained {
// ShaderAttributeValue methods
- native ShaderError setUniform1i(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int value);
-
- native ShaderError setUniform1f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float value);
-
- native ShaderError setUniform2i(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int[] value);
-
- native ShaderError setUniform2f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float[] value);
-
- native ShaderError setUniform3i(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int[] value);
-
- native ShaderError setUniform3f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float[] value);
-
- native ShaderError setUniform4i(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int[] value);
-
- native ShaderError setUniform4f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float[] value);
-
- native ShaderError setUniformMatrix3f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float[] value);
-
- native ShaderError setUniformMatrix4f(long ctx,
- long shaderProgramId,
- long uniformLocation,
- float[] value);
-
+ ShaderError setUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int value) {
+
+ return Pipeline.getPipeline().setGLSLUniform1i(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float value) {
+
+ return Pipeline.getPipeline().setGLSLUniform1f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform2i(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform2f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform3i(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform3f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform4i(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform4f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniformMatrix3f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
+ ShaderError setUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniformMatrix4f(ctx,
+ shaderProgramId,
+ uniformLocation,
+ value);
+ }
+
// ShaderAttributeArray methods
- native ShaderError setUniform1iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- int[] value);
-
- native ShaderError setUniform1fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
-
- native ShaderError setUniform2iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- int[] value);
-
- native ShaderError setUniform2fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
-
- native ShaderError setUniform3iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- int[] value);
-
- native ShaderError setUniform3fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
-
- native ShaderError setUniform4iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- int[] value);
-
- native ShaderError setUniform4fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
-
- native ShaderError setUniformMatrix3fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
-
- native ShaderError setUniformMatrix4fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
- int numElements,
- float[] value);
-
- /* New native interfaces */
- private native ShaderError createNativeShader(long ctx, int shaderType, long[] shaderId);
- private native ShaderError destroyNativeShader(long ctx, long shaderId);
- private native ShaderError compileNativeShader(long ctx, long shaderId, String program);
-
- private native ShaderError createNativeShaderProgram(long ctx, long[] shaderProgramId);
- private native ShaderError destroyNativeShaderProgram(long ctx, long shaderProgramId);
- private native ShaderError linkNativeShaderProgram(long ctx, long shaderProgramId,
- long[] shaderId);
- private native ShaderError bindNativeVertexAttrName(long ctx, long shaderProgramId,
- String attrName, int attrIndex);
- private native void lookupNativeShaderAttrNames(long ctx, long shaderProgramId,
- int numAttrNames, String[] attrNames, long[] locArr,
- int[] typeArr, int[] sizeArr, boolean[] isArrayArr);
-
- private native ShaderError useShaderProgram(long ctx, long shaderProgramId);
+ ShaderError setUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform1iArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform1fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform2iArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform2fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform3iArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform3fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform4iArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniform4fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniformMatrix3fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
+
+ ShaderError setUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+
+ return Pipeline.getPipeline().setGLSLUniformMatrix4fArray(ctx,
+ shaderProgramId,
+ uniformLocation,
+ numElements,
+ value);
+ }
/**
* Method to return a flag indicating whether this
@@ -178,69 +291,64 @@ class GLSLShaderProgramRetained extends ShaderProgramRetained {
/**
* Method to create the native shader.
*/
- ShaderError createShader(long ctx, ShaderRetained shader, long[] shaderIdArr) {
- return createNativeShader(ctx, shader.shaderType, shaderIdArr);
+ ShaderError createShader(Context ctx, ShaderRetained shader, ShaderId[] shaderIdArr) {
+ return Pipeline.getPipeline().createGLSLShader(ctx, shader.shaderType, shaderIdArr);
}
/**
* Method to destroy the native shader.
*/
- ShaderError destroyShader(long ctx, long shaderId) {
- return destroyNativeShader(ctx, shaderId);
+ ShaderError destroyShader(Context ctx, ShaderId shaderId) {
+ return Pipeline.getPipeline().destroyGLSLShader(ctx, shaderId);
}
/**
* Method to compile the native shader.
*/
- ShaderError compileShader(long ctx, long shaderId, String source) {
- return compileNativeShader(ctx, shaderId, source );
+ ShaderError compileShader(Context ctx, ShaderId shaderId, String source) {
+ return Pipeline.getPipeline().compileGLSLShader(ctx, shaderId, source );
}
/**
* Method to create the native shader program.
*/
- ShaderError createShaderProgram(long ctx, long[] shaderProgramIdArr) {
- return createNativeShaderProgram(ctx, shaderProgramIdArr);
+ ShaderError createShaderProgram(Context ctx, ShaderProgramId[] shaderProgramIdArr) {
+ return Pipeline.getPipeline().createGLSLShaderProgram(ctx, shaderProgramIdArr);
}
/**
* Method to destroy the native shader program.
*/
- ShaderError destroyShaderProgram(long ctx, long shaderProgramId) {
- return destroyNativeShaderProgram(ctx, shaderProgramId);
+ ShaderError destroyShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return Pipeline.getPipeline().destroyGLSLShaderProgram(ctx, shaderProgramId);
}
/**
* Method to link the native shader program.
*/
- ShaderError linkShaderProgram(long ctx, long shaderProgramId, long[] shaderIds) {
- return linkNativeShaderProgram(ctx, shaderProgramId, shaderIds);
+ ShaderError linkShaderProgram(Context ctx, ShaderProgramId shaderProgramId, ShaderId[] shaderIds) {
+ return Pipeline.getPipeline().linkGLSLShaderProgram(ctx, shaderProgramId, shaderIds);
}
- ShaderError bindVertexAttrName(long ctx, long shaderProgramId, String attrName, int attrIndex) {
- return bindNativeVertexAttrName(ctx, shaderProgramId, attrName, attrIndex);
+ ShaderError bindVertexAttrName(Context ctx, ShaderProgramId shaderProgramId, String attrName, int attrIndex) {
+ return Pipeline.getPipeline().bindGLSLVertexAttrName(ctx, shaderProgramId, attrName, attrIndex);
}
- void lookupVertexAttrNames(long ctx, long shaderProgramId, String[] attrNames, boolean[] errArr) {
+ void lookupVertexAttrNames(Context ctx, ShaderProgramId shaderProgramId, String[] attrNames, boolean[] errArr) {
// This method is a no-op for GLSL
}
- void lookupShaderAttrNames(long ctx, long shaderProgramId,
+ void lookupShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId,
String[] attrNames, AttrNameInfo[] attrNameInfoArr) {
int numAttrNames = attrNames.length;
- long[] locArr = new long[numAttrNames];
+ ShaderAttrLoc[] locArr = new ShaderAttrLoc[numAttrNames];
int[] typeArr = new int[numAttrNames];
int[] sizeArr = new int[numAttrNames]; // currently unused
boolean[] isArrayArr = new boolean[numAttrNames];
- // Initialize loc array to -1 (indicating no location)
- for (int i = 0; i < numAttrNames; i++) {
- locArr[i] = -1;
- }
-
- lookupNativeShaderAttrNames(ctx, shaderProgramId,
+ Pipeline.getPipeline().lookupGLSLShaderAttrNames(ctx, shaderProgramId,
numAttrNames, attrNames, locArr, typeArr, sizeArr, isArrayArr);
for (int i = 0; i < numAttrNames; i++) {
@@ -259,15 +367,15 @@ class GLSLShaderProgramRetained extends ShaderProgramRetained {
/**
* Method to enable the native shader program.
*/
- ShaderError enableShaderProgram(long ctx, long shaderProgramId) {
- return useShaderProgram(ctx, shaderProgramId);
+ ShaderError enableShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return Pipeline.getPipeline().useGLSLShaderProgram(ctx, shaderProgramId);
}
/**
* Method to disable the native shader program.
*/
- ShaderError disableShaderProgram(long ctx) {
- return useShaderProgram(ctx, 0);
+ ShaderError disableShaderProgram(Context ctx) {
+ return Pipeline.getPipeline().useGLSLShaderProgram(ctx, null);
}
diff --git a/src/classes/share/javax/media/j3d/GeometryArray.java b/src/classes/share/javax/media/j3d/GeometryArray.java
index e1ca8d6..e2e8ec6 100644
--- a/src/classes/share/javax/media/j3d/GeometryArray.java
+++ b/src/classes/share/javax/media/j3d/GeometryArray.java
@@ -327,10 +327,20 @@ public abstract class GeometryArray extends Geometry {
*/
public static final int VERTEX_ATTRIBUTES = 0x1000;
+ //NVaidya
+ /**
+ * Specifies that the indices in this GeometryArray
+ * are accessed by reference. This flag is only valid for
+ * indexed geometry arrays (subclasses of IndexedGeometryArray) and only
+ * when used in conjunction with the <code>BY_REFERENCE</code> and
+ * <code>USE_COORD_INDEX_ONLY</code> flags.
+ *
+ * @since Java 3D 1.5
+ */
+ public static final int BY_REFERENCE_INDICES = 0x2000;
// Used to keep track of the last bit (for adding new bits only)
- private static final int LAST_FORMAT_BIT = 0x1000;
-
+ private static final int LAST_FORMAT_BIT = 0x2000;
// Scratch arrays for converting Point[234]f to TexCoord[234]f
private TexCoord2f [] texCoord2fArray = null;
@@ -360,7 +370,7 @@ public abstract class GeometryArray extends Geometry {
setDefaultReadCapabilities(readCapabilities);
}
-
+ //NVaidya
/**
* Constructs an empty GeometryArray object with the specified
* number of vertices and vertex format. Defaults are used
@@ -404,7 +414,10 @@ public abstract class GeometryArray extends Geometry {
* is accessed via a J3DBuffer object that wraps an NIO buffer;
* <code>USE_COORD_INDEX_ONLY</code>,
* to indicate that only the coordinate indices are used for indexed
- * geometry arrays.
+ * geometry arrays;
+ * <code>BY_REFERENCE_INDICES</code>, to indicate
+ * that the indices are accessed by reference in indexed
+ * geometry arrays.<p>
*
* @exception IllegalArgumentException if vertexCount &lt; 0
*
@@ -412,7 +425,8 @@ public abstract class GeometryArray extends Geometry {
* include <code>COORDINATES</code>
*
* @exception IllegalArgumentException if the <code>USE_COORD_INDEX_ONLY</code>
- * bit is set for non-indexed geometry arrays (that is, GeometryArray objects
+ * bit or the <code>BY_REFERENCE_INDICES</code> bit is set for
+ * non-indexed geometry arrays (that is, GeometryArray objects
* that are not a subclass of IndexedGeometryArray)
*
* @exception IllegalArgumentException if the <code>INTERLEAVED</code>
@@ -423,6 +437,11 @@ public abstract class GeometryArray extends Geometry {
*
* @exception IllegalArgumentException if the <code>INTERLEAVED</code>
* bit and the <code>VERTEX_ATTRIBUTES</code> bit are both set
+ *
+ * @exception IllegalArgumentException if the
+ * <code>BY_REFERENCE_INDICES</code>
+ * bit is set without the <code>BY_REFERENCE</code> and
+ * <code>USE_COORD_INDEX_ONLY</code> bits being set
*/
public GeometryArray(int vertexCount, int vertexFormat) {
this(vertexCount, vertexFormat,
@@ -431,6 +450,7 @@ public abstract class GeometryArray extends Geometry {
}
+ //NVaidya
/**
* Constructs an empty GeometryArray object with the specified
* number of vertices, vertex format, number of texture coordinate
@@ -462,6 +482,9 @@ public abstract class GeometryArray extends Geometry {
* is accessed via a J3DBuffer object that wraps an NIO buffer;
* <code>USE_COORD_INDEX_ONLY</code>,
* to indicate that only the coordinate indices are used for indexed
+ * geometry arrays;
+ * <code>BY_REFERENCE_INDICES</code>, to indicate
+ * that the indices are accessed by reference in indexed
* geometry arrays.<p>
*
* @param texCoordSetCount the number of texture coordinate sets
@@ -536,7 +559,8 @@ public abstract class GeometryArray extends Geometry {
* include <code>COORDINATES</code>
*
* @exception IllegalArgumentException if the <code>USE_COORD_INDEX_ONLY</code>
- * bit is set for non-indexed geometry arrays (that is, GeometryArray objects
+ * bit or the <code>BY_REFERENCE_INDICES</code> bit is set for
+ * non-indexed geometry arrays (that is, GeometryArray objects
* that are not a subclass of IndexedGeometryArray)
*
* @exception IllegalArgumentException if the <code>INTERLEAVED</code>
@@ -548,6 +572,11 @@ public abstract class GeometryArray extends Geometry {
* @exception IllegalArgumentException if the <code>INTERLEAVED</code>
* bit and the <code>VERTEX_ATTRIBUTES</code> bit are both set
*
+ * @exception IllegalArgumentException if the
+ * <code>BY_REFERENCE_INDICES</code>
+ * bit is set without the <code>BY_REFERENCE</code> and
+ * <code>USE_COORD_INDEX_ONLY</code> bits being set
+ *
* @exception IllegalArgumentException if
* <code>texCoordSetCount&nbsp;&lt;&nbsp;0</code>
*
@@ -564,6 +593,7 @@ public abstract class GeometryArray extends Geometry {
}
+ //NVaidya
/**
* Constructs an empty GeometryArray object with the specified
* number of vertices, vertex format, number of texture coordinate
@@ -597,6 +627,9 @@ public abstract class GeometryArray extends Geometry {
* is accessed via a J3DBuffer object that wraps an NIO buffer;
* <code>USE_COORD_INDEX_ONLY</code>,
* to indicate that only the coordinate indices are used for indexed
+ * geometry arrays;
+ * <code>BY_REFERENCE_INDICES</code>, to indicate
+ * that the indices are accessed by reference in indexed
* geometry arrays.<p>
*
* @param texCoordSetCount the number of texture coordinate sets
@@ -681,7 +714,8 @@ public abstract class GeometryArray extends Geometry {
* include <code>COORDINATES</code>
*
* @exception IllegalArgumentException if the <code>USE_COORD_INDEX_ONLY</code>
- * bit is set for non-indexed geometry arrays (that is, GeometryArray objects
+ * bit or the <code>BY_REFERENCE_INDICES</code> bit is set for
+ * non-indexed geometry arrays (that is, GeometryArray objects
* that are not a subclass of IndexedGeometryArray)
*
* @exception IllegalArgumentException if the <code>INTERLEAVED</code>
@@ -693,6 +727,11 @@ public abstract class GeometryArray extends Geometry {
* @exception IllegalArgumentException if the <code>INTERLEAVED</code>
* bit and the <code>VERTEX_ATTRIBUTES</code> bit are both set
*
+ * @exception IllegalArgumentException if the
+ * <code>BY_REFERENCE_INDICES</code>
+ * bit is set without the <code>BY_REFERENCE</code> and
+ * <code>USE_COORD_INDEX_ONLY</code> bits being set
+ *
* @exception IllegalArgumentException if
* <code>texCoordSetCount&nbsp;&lt;&nbsp;0</code>
*
@@ -748,6 +787,16 @@ public abstract class GeometryArray extends Geometry {
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray135"));
}
+ //NVaidya
+ if ((vertexFormat & BY_REFERENCE_INDICES) != 0) {
+ if (!(this instanceof IndexedGeometryArray))
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray136"));
+ if ((vertexFormat & BY_REFERENCE) == 0)
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray137"));
+ if ((vertexFormat & USE_COORD_INDEX_ONLY) == 0)
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray138"));
+ }
+
if ((vertexFormat & USE_NIO_BUFFER) != 0 &&
(vertexFormat & BY_REFERENCE) == 0)
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray117"));
diff --git a/src/classes/share/javax/media/j3d/GeometryArrayRetained.java b/src/classes/share/javax/media/j3d/GeometryArrayRetained.java
index f50a9e1..5a82c09 100644
--- a/src/classes/share/javax/media/j3d/GeometryArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/GeometryArrayRetained.java
@@ -62,7 +62,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// vertex data in packed format for each screen in multi-screen situation
// if alpha values of each vertex are to be updated
- float mvertexData[][];
+ private float mvertexData[][];
//
// The following offset/stride values are internally computed
@@ -94,14 +94,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
int vertexAttrStride;
// alpha value for transparency and texture blending
- float[] lastAlpha = new float[1];
+ private float[] lastAlpha = new float[1];
float lastScreenAlpha = -1;
int colorChanged = 0;
- // true if alpha value from transparencyAttrubute has changed
- boolean alphaChanged = false;
-
// byte to float scale factor
static final float ByteToFloatScale = 1.0f/255.0f;
@@ -162,7 +159,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
static final int P3D = 0x8;
static final int VERTEX_DEFINED = PF | PD | P3F | P3D;
-
static final int CF = 0x10;
static final int CUB = 0x20;
static final int C3F = 0x40;
@@ -170,19 +166,19 @@ abstract class GeometryArrayRetained extends GeometryRetained{
static final int C3UB = 0x100;
static final int C4UB = 0x200;
static final int COLOR_DEFINED = CF | CUB | C3F | C4F| C3UB | C4UB;
-
+
static final int NF = 0x400;
static final int N3F = 0x800;
static final int NORMAL_DEFINED = NF | N3F;
-
+
static final int TF = 0x1000;
static final int T2F = 0x2000;
static final int T3F = 0x4000;
static final int TEXCOORD_DEFINED = TF | T2F | T3F;
-
+
static final int AF = 0x8000;
static final int VATTR_DEFINED = AF;
-
+
// Flag word indicating the type of by-ref texCoord. We will copy this to
// the vertexType field only when the references for all texture coordinate
// sets are set to non-null values.
@@ -340,12 +336,12 @@ abstract class GeometryArrayRetained extends GeometryRetained{
IndexedGeometryArrayRetained cloneSourceArray = null;
-// private MemoryFreeList pickVectorFreelist =
-// FreeListManager.getFreeList(FreeListManager.PICKVECTOR);
-
static final double EPS = 1.0e-13;
- native void freeD3DArray(boolean deleteVB);
+ void freeD3DArray(boolean deleteVB) {
+ assert VirtualUniverse.mc.isD3D();
+ Pipeline.getPipeline().freeD3DArray(this, deleteVB);
+ }
GeometryArrayRetained() {
dirtyFlag = INDEX_CHANGED|VERTEX_CHANGED;
@@ -363,7 +359,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if (this.refCount > 1) {
// Send to rendering attribute structure,
/*
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.GEOMETRYARRAY_CHANGED;
createMessage.universe = null;
@@ -378,7 +374,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// otherwise, set mirrorGeometry to null (from previous clearLive)
if (this instanceof IndexedGeometryArrayRetained) {
// Send to rendering attribute structure,
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.GEOMETRY_CHANGED;
createMessage.universe = null;
@@ -396,7 +392,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if (this.refCount <= 0) {
if (pVertexBuffers != 0) {
- J3dMessage renderMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage renderMessage = new J3dMessage();
renderMessage.threads = J3dThread.RENDER_THREAD;
renderMessage.type = J3dMessage.RENDER_IMMEDIATE;
renderMessage.universe = null;
@@ -1644,93 +1640,15 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
- // used for GeometryArrays by Copy or interleaved
- private native void execute(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean useAlpha,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int startVIndex, int vcount, int vformat,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetOffset,
- int numActiveTexUnitState,
- int[] texUnitStateMap,
- int vertexAttrCount, int[] vertexAttrSizes,
- float[] varray, float[] cdata, int texUnitIndex, int cdirty);
-
- // used by GeometryArray by Reference with java arrays
- private native void executeVA(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int vcount,
- int vformat,
- int vdefined,
- int coordIndex, float[] vfcoords, double[] vdcoords,
- int colorIndex, float[] cfdata, byte[] cbdata,
- int normalIndex, float[] ndata,
- int vertexAttrCount, int[] vertexAttrSizes,
- int[] vertexAttrIndex, float[][] vertexAttrData,
- int pass, int texcoordmaplength,
- int[] texcoordoffset,
- int numActiveTexUnitState, int[] texunitstatemap,
- int[] texIndex, int texstride, Object[] texCoords,
- int cdirty);
-
- // used by GeometryArray by Reference with NIO buffer
- private native void executeVABuffer(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int vcount,
- int vformat,
- int vdefined,
- int coordIndex,
- Object vcoords,
- int colorIndex,
- Object cdataBuffer,
- float[] cfdata, byte[] cbdata,
- int normalIndex, Object ndata,
- int vertexAttrCount, int[] vertexAttrSizes,
- int[] vertexAttrIndex, Object[] vertexAttrData,
- int pass, int texcoordmaplength,
- int[] texcoordoffset,
- int numActiveTexUnitState, int[] texunitstatemap,
- int[] texIndex, int texstride, Object[] texCoords,
- int cdirty);
-
- // used by GeometryArray by Reference in interleaved format with NIO buffer
- private native void executeInterleavedBuffer(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean useAlpha,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int startVIndex, int vcount, int vformat,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetOffset,
- int numActiveTexUnitState,
- int[] texUnitStateMap,
- Object varray, float[] cdata, int texUnitIndex, int cdirty);
-
- private native void setVertexFormat(long ctx,
- int vformat, boolean useAlpha, boolean ignoreVertexColors);
-
- private native void disableGlobalAlpha(long ctx, int vformat,
- boolean useAlpha, boolean ignoreVertexColors);
-
- void setVertexFormat(boolean useAlpha, boolean ignoreVC, long ctx) {
- setVertexFormat(ctx, vertexFormat, useAlpha, ignoreVC);
+ void setVertexFormat(boolean useAlpha, boolean ignoreVC, Context ctx) {
+ Pipeline.getPipeline().setVertexFormat(ctx,
+ this, vertexFormat, useAlpha, ignoreVC);
}
- void disableGlobalAlpha(long ctx, boolean useAlpha, boolean ignoreVC) {
+ void disableGlobalAlpha(Context ctx, boolean useAlpha, boolean ignoreVC) {
// If global alpha was turned on, then disable it
- disableGlobalAlpha(ctx, vertexFormat, useAlpha, ignoreVC);
+ Pipeline.getPipeline().disableGlobalAlpha(ctx,
+ this, vertexFormat, useAlpha, ignoreVC);
}
@@ -1745,12 +1663,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return mirrorFloatRefColors[0];
}
- // Issue 113
- // TODO: Fix this for screen > 0, for now just ignore transparency
- if (screen > 0) {
- return mirrorFloatRefColors[0];
- }
-
// update alpha only if vertex format includes alpha
if (((vertexFormat | c4fAllocated) & GeometryArray.WITH_ALPHA) == 0)
return mirrorFloatRefColors[0];
@@ -1762,17 +1674,18 @@ abstract class GeometryArrayRetained extends GeometryRetained{
alpha = (float)EPSILON;
}
- // allocate an entry for the last alpha of the screen if needed
- if (lastAlpha == null) {
- lastAlpha = new float[screen + 1];
- lastAlpha[screen] = 1.0f;
- } else if (lastAlpha.length <= screen) {
+ assert lastAlpha != null;
+ assert mirrorFloatRefColors != null;
+ assert mirrorFloatRefColors.length == lastAlpha.length;
+
+ // Issue 113 - reallocate lastAlpha array if needed, but no need to
+ // update the values here
+ if (lastAlpha.length <= screen) {
float[] la = new float[screen + 1];
for (int i = 0; i < lastAlpha.length; i++) {
la[i] = lastAlpha[i];
}
lastAlpha = la;
- lastAlpha[screen] = 1.0f;
}
//System.out.println("updateAlphaInFloatRefColors screen is " + screen
@@ -1780,48 +1693,30 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// mirrorFloatRefColors.length);
// allocate a copy of the color data for the screen if needed.
- // this piece of code is mainly for multi-screens case
+ // this piece of code is only for multi-screens case
if (mirrorFloatRefColors.length <= screen) {
float[][] cfData = new float[screen + 1][];
- float[] cdata;
- int refScreen = -1;
for (int i = 0; i < mirrorFloatRefColors.length; i++) {
cfData[i] = mirrorFloatRefColors[i];
- if (Math.abs(lastAlpha[i] - alpha) < EPSILON) {
- refScreen = i;
- }
}
- cdata = cfData[screen] = new float[4 * vertexCount];
- // copy the data from a reference screen which has the closest
- // alpha values
- if (refScreen >= 0) {
- System.arraycopy(cfData[refScreen], 0, cdata, 0,
- 4 * vertexCount);
- lastAlpha[screen] = lastAlpha[refScreen];
- } else {
- float m = alpha / lastAlpha[0];
- float[] sdata = cfData[0];
+ // Issue 113 - allocate entries for [oldSize..screen];
+ // copy cfData[0] to cfData[oldsize..screen-1] and
+ // lastAlpha[0] to lastAlpha[oldsize..screen-1].
+ for (int i = mirrorFloatRefColors.length; i < screen+1; i++) {
+ cfData[i] = new float[4 * vertexCount];
+ System.arraycopy(cfData[0], 0, cfData[i], 0, 4 * vertexCount);
+ lastAlpha[i] = lastAlpha[0];
+ }
- int j = initialColorIndex * 4;
- for (int i = initialColorIndex; i < validVertexCount; i++) {
- cdata[j] = sdata[j++];
- cdata[j] = sdata[j++];
- cdata[j] = sdata[j++];
- cdata[j] = sdata[j++] * m;
- }
- lastAlpha[screen] = alpha;
- }
- mirrorFloatRefColors = cfData;
+ mirrorFloatRefColors = cfData;
- // reset the colorChanged bit
- colorChanged &= ~(1 << screen);
- dirtyFlag |= COLOR_CHANGED;
-
- return cdata;
+ // Issue 113 - since we copied the data from screen 0, we don't need
+ // to do any further special processing.
}
+ assert lastAlpha[screen] >= 0.0;
/*
System.out.println("updateAlphaInFloatRefColors ** : lastAlpha[screen] " +
lastAlpha[screen]);
@@ -1832,7 +1727,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if ((colorChanged & (1<<screen)) == 0) {
// color data is not modified
- if (Math.abs(lastAlpha[screen] - alpha) < EPSILON) {
+ if (Math.abs(lastAlpha[screen] - alpha) <= EPSILON) {
// and if alpha is the same as the last one,
// just return the data
//System.out.println("updateAlphaInFloatRefColors 0 : alpha is the same as the last one " + alpha);
@@ -1919,12 +1814,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return mirrorUnsignedByteRefColors[0];
}
- // Issue 113
- // TODO: Fix this for screen > 0, for now just ignore transparency
- if (screen > 0) {
- return mirrorUnsignedByteRefColors[0];
- }
-
// update alpha only if vertex format includes alpha
if (((vertexFormat | c4fAllocated) & GeometryArray.WITH_ALPHA) == 0)
return mirrorUnsignedByteRefColors[0];
@@ -1936,59 +1825,45 @@ abstract class GeometryArrayRetained extends GeometryRetained{
alpha = (float)EPSILON;
}
- // allocate an entry for the last alpha of the screen if needed
- if (lastAlpha == null) {
- lastAlpha = new float[screen + 1];
- lastAlpha[screen] = -1.0f;
- } else if (lastAlpha.length <= screen) {
+ assert lastAlpha != null;
+ assert mirrorUnsignedByteRefColors != null;
+ assert mirrorUnsignedByteRefColors.length == lastAlpha.length;
+
+ // Issue 113 - reallocate lastAlpha array if needed, but no need to
+ // update the values here
+ if (lastAlpha.length <= screen) {
float[] la = new float[screen + 1];
for (int i = 0; i < lastAlpha.length; i++) {
la[i] = lastAlpha[i];
}
lastAlpha = la;
- lastAlpha[screen] = -1.0f;
}
// allocate a copy of the color data for the screen if needed.
- // this piece of code is mainly for multi-screens case
+ // this piece of code is only for multi-screens case
if (mirrorUnsignedByteRefColors.length <= screen) {
- byte[][] cfData = new byte[screen + 1][];
- byte[] cdata;
- int refScreen = -1;
+ byte[][] cbData = new byte[screen + 1][];
for (int i = 0; i < mirrorUnsignedByteRefColors.length; i++) {
- cfData[i] = mirrorUnsignedByteRefColors[i];
- if (Math.abs(lastAlpha[i] - alpha) < EPSILON) {
- refScreen = i;
- }
+ cbData[i] = mirrorUnsignedByteRefColors[i];
}
- cdata = cfData[screen] = new byte[4 * vertexCount];
- // copy the data from a reference screen which has the closest
- // alpha values
- if (refScreen >= 0) {
- System.arraycopy(cfData[refScreen], 0, cdata, 0,
- 4 * vertexCount);
- lastAlpha[screen] = lastAlpha[refScreen];
- } else {
- float m = alpha / lastAlpha[0];
- byte[] sdata = cfData[0];
+ // Issue 113 - allocate entries for [oldSize..screen];
+ // copy cbData[0] to cbData[oldsize..screen-1] and
+ // lastAlpha[0] to lastAlpha[oldsize..screen-1].
+ for (int i = mirrorUnsignedByteRefColors.length; i < screen+1; i++) {
+ cbData[i] = new byte[4 * vertexCount];
+ System.arraycopy(cbData[0], 0, cbData[i], 0, 4 * vertexCount);
+ lastAlpha[i] = lastAlpha[0];
+ }
- int j = initialColorIndex * 4;
- for (int i = initialColorIndex; i < validVertexCount; i++) {
- cdata[j] = sdata[j++];
- cdata[j] = sdata[j++];
- cdata[j] = sdata[j++];
- cdata[j] = (byte)(((int)sdata[j++]& 0xff) * m);
- }
- lastAlpha[screen] = alpha;
- }
- mirrorUnsignedByteRefColors = cfData;
- colorChanged &= ~(1 << screen);
- dirtyFlag |= COLOR_CHANGED;
- return cdata;
+ mirrorUnsignedByteRefColors = cbData;
+
+ // Issue 113 - since we copied the data from screen 0, we don't need
+ // to do any further special processing.
}
- /*
+ assert lastAlpha[screen] >= 0.0;
+ /*
System.out.println("updateAlphaInByteRefColors ## : lastAlpha[screen] " +
lastAlpha[screen]);
@@ -1998,7 +1873,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if ((colorChanged & (1<<screen)) == 0) {
// color data is not modified
- if (Math.abs(lastAlpha[screen] - alpha) < EPSILON) {
+ if (Math.abs(lastAlpha[screen] - alpha) <= EPSILON) {
// and if alpha is the same as the last one,
// just return the data
//System.out.println("updateAlphaInByteRefColors 0 : alpha is the same as the last one " + alpha);
@@ -2080,13 +1955,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return retVal;
}
- // Issue 113
- // TODO: Fix this for screen > 0, for now just ignore transparency
- if (screen > 0) {
- retVal[1] = vertexData;
- return retVal;
- }
-
// update alpha only if vertex format includes alpha
if ((vertexFormat & GeometryArray.COLOR) == 0) {
retVal[1] = vertexData;
@@ -2101,81 +1969,61 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
retVal[0] = Boolean.TRUE;
- // allocate an entry for the last alpha of the screen if needed
- if (lastAlpha == null) {
- lastAlpha = new float[screen + 1];
- lastAlpha[screen] = 1.0f;
- } else if (lastAlpha.length <= screen) {
+ assert lastAlpha != null;
+ assert mvertexData == null || mvertexData.length == lastAlpha.length;
+
+ // Issue 113 - reallocate lastAlpha array if needed, but no need to
+ // update the values here
+ if (lastAlpha.length <= screen) {
float[] la = new float[screen + 1];
for (int i = 0; i < lastAlpha.length; i++) {
la[i] = lastAlpha[i];
}
lastAlpha = la;
- lastAlpha[screen] = 1.0f;
}
// allocate a copy of the vertex data for the screen if needed.
- // this piece of code is mainly for multi-screens case
- // NOTE: this might not too much data for just to update alpha
+ // Note that a copy operation only happens in the multi-screens case.
+ // We always use the existing vertexData for screen 0.
if (mvertexData == null || mvertexData.length <= screen) {
float[][] cfData = new float[screen + 1][];
- float[] cdata;
- int refScreen = -1;
+ int oldSize = 1;
if (mvertexData != null) {
+ oldSize = mvertexData.length;
for (int i = 0; i < mvertexData.length; i++) {
cfData[i] = mvertexData[i];
- if (Math.abs(lastAlpha[i] - alpha) < EPSILON) {
- refScreen = i;
- }
}
}
if (cfData[0] == null) {
- cfData[screen] = vertexData;
- }
-
- if (screen > 0)
- cfData[screen] = new float[stride * vertexCount];
-
- cdata = cfData[screen];
-
- // copy the data from a reference screen which has the closest
- // alpha values
- if (refScreen >= 0) {
- System.arraycopy(cfData[refScreen], 0, cdata, 0,
- stride * vertexCount);
- lastAlpha[screen] = lastAlpha[refScreen];
- } else {
- float m = alpha / lastAlpha[0];
- float[] sdata = cfData[0];
+ cfData[0] = vertexData;
+ }
+
+ // Issue 113 - allocate entries for [oldSize..screen];
+ // copy cfData[0] to cfData[oldsize..screen-1] and
+ // lastAlpha[0] to lastAlpha[oldsize..screen-1].
+ if (screen > 0) {
+ for (int i = oldSize; i < screen+1; i++) {
+ cfData[i] = new float[stride * vertexCount];
+ System.arraycopy(cfData[0], 0, cfData[i], 0,
+ stride * vertexCount);
+ lastAlpha[i] = lastAlpha[0];
+ }
+ }
- /*
- // screen 0 data is always up-to-date
- if (screen > 0) {
- System.arraycopy(cfData[0], 0, cdata, 0,
- stride * vertexCount);
- }
- */
+ mvertexData = cfData;
- for (int i = 0, j = colorOffset; i < vertexCount;
- i++, j+=stride) {
- cdata[j+3] = sdata[j+3] * m;
- }
- lastAlpha[screen] = alpha;
- }
- mvertexData = cfData;
- dirtyFlag |= COLOR_CHANGED;
- // reset the colorChanged bit
- colorChanged &= ~(1 << screen);
- retVal[1] = cdata;
- return retVal;
+ // Issue 113 - since we copied the data from screen 0, we don't need
+ // to do any further special processing.
}
+
+ assert lastAlpha[screen] >= 0.0;
if ((colorChanged & (1<<screen)) == 0) {
// color data is not modified
- if (Math.abs(lastAlpha[screen] - alpha) < EPSILON) {
+ if (Math.abs(lastAlpha[screen] - alpha) <= EPSILON) {
// and if alpha is the same as the last one,
// just return the data
retVal[1] = mvertexData[screen];
@@ -2237,15 +2085,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return retVal;
}
- // Issue 113
- // TODO: Fix this for screen > 0, for now just ignore transparency
- if (screen > 0) {
- retVal[1] = null;
- return retVal;
- }
-
// update alpha only if vertex format includes alpha
- if (((vertexFormat | c4fAllocated) & GeometryArray.COLOR) == 0) {
+ if (((vertexFormat | c4fAllocated) & GeometryArray.WITH_ALPHA) == 0) {
retVal[1] = mirrorInterleavedColorPointer[0];
return retVal;
}
@@ -2259,66 +2100,50 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
retVal[0] = Boolean.TRUE;
- // allocate an entry for the last alpha of the screen if needed
- if (lastAlpha == null) {
- lastAlpha = new float[screen + 1];
- lastAlpha[screen] = 1.0f;
- } else if (lastAlpha.length <= screen) {
+ assert lastAlpha != null;
+ assert mirrorInterleavedColorPointer != null;
+ assert mirrorInterleavedColorPointer.length == lastAlpha.length;
+
+ // Issue 113 - reallocate lastAlpha array if needed, but no need to
+ // update the values here
+ if (lastAlpha.length <= screen) {
float[] la = new float[screen + 1];
for (int i = 0; i < lastAlpha.length; i++) {
la[i] = lastAlpha[i];
}
lastAlpha = la;
- lastAlpha[screen] = 1.0f;
}
// allocate a copy of the vertex data for the screen if needed.
- // this piece of code is mainly for multi-screens case
- // NOTE: this might not too much data for just to update alpha
+ // this piece of code is only for multi-screens case
if (mirrorInterleavedColorPointer.length <= screen) {
float[][] cfData = new float[screen + 1][];
- float[] cdata;
- int refScreen = -1;
for (int i = 0; i < mirrorInterleavedColorPointer.length; i++) {
cfData[i] = mirrorInterleavedColorPointer[i];
- if (Math.abs(lastAlpha[i] - alpha) < EPSILON) {
- refScreen = i;
- }
}
- //cdata = cfData[screen] = new float[stride * vertexCount];
- cdata = cfData[screen] = new float[4 * vertexCount];
-
- // copy the data from a reference screen which has the closest
- // alpha values
- if (refScreen >= 0) {
- System.arraycopy(cfData[refScreen], 0, cdata, 0,
- 4 * vertexCount);
- lastAlpha[screen] = lastAlpha[refScreen];
- } else {
- float m = alpha / lastAlpha[0];
- float[] sdata = cfData[0];
-
- for (int i = coffset; i < coffset + (vertexCount << 2); i+=4) {
- cdata[i+3] = sdata[i+3] * m;
- }
+ // Issue 113 - allocate entries for [oldSize..screen];
+ // copy cfData[0] to cfData[oldsize..screen-1] and
+ // lastAlpha[0] to lastAlpha[oldsize..screen-1].
+ for (int i = mirrorInterleavedColorPointer.length; i < screen+1; i++) {
+ cfData[i] = new float[4 * vertexCount];
+ System.arraycopy(cfData[0], 0, cfData[i], 0, 4 * vertexCount);
+ lastAlpha[i] = lastAlpha[0];
+ }
- lastAlpha[screen] = alpha;
- }
mirrorInterleavedColorPointer = cfData;
- // reset the colorChanged bit
- colorChanged &= ~(1 << screen);
- dirtyFlag |= COLOR_CHANGED;
- retVal[1] = cdata;
- return retVal;
+ // Issue 113 - since we copied the data from screen 0, we don't need
+ // to do any further special processing.
}
- if ((colorChanged & (1<<screen)) == 0) {
+ assert lastAlpha[screen] >= 0.0;
+
+ if ((colorChanged & (1<<screen)) == 0) {
// color data is not modified
- if (Math.abs(lastAlpha[screen] - alpha) < EPSILON) {
+ if (Math.abs(lastAlpha[screen] - alpha) <= EPSILON) {
// and if alpha is the same as the last one,
// just return the data
retVal[1] = mirrorInterleavedColorPointer[screen];
@@ -2388,8 +2213,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
boolean updateAlpha, float alpha,
- boolean multiScreen, int screen,
- boolean ignoreVertexColors, int pass) {
+ int screen,
+ boolean ignoreVertexColors) {
int cdirty;
boolean useAlpha = false;
@@ -2427,9 +2252,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
dirtyFlag = 0;
}
- execute(cv.ctx, this, geoType, isNonUniformScale,
+ Pipeline.getPipeline().execute(cv.ctx,
+ this, geoType, isNonUniformScale,
useAlpha,
- multiScreen,
ignoreVertexColors,
initialVertexIndex,
validVertexCount,
@@ -2437,10 +2262,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
texCoordSetCount, texCoordSetMap,
(texCoordSetMap == null) ? 0 : texCoordSetMap.length,
texCoordSetMapOffset,
- cv.numActiveTexUnit, cv.texUnitStateMap,
+ cv.numActiveTexUnit,
vertexAttrCount, vertexAttrSizes,
vdata, null,
- pass, cdirty);
+ cdirty);
}
//By reference with java array
@@ -2473,9 +2298,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
dirtyFlag = 0;
}
- execute(cv.ctx, this, geoType, isNonUniformScale,
+ Pipeline.getPipeline().execute(cv.ctx,
+ this, geoType, isNonUniformScale,
useAlpha,
- multiScreen,
ignoreVertexColors,
initialVertexIndex,
validVertexCount,
@@ -2483,10 +2308,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
texCoordSetCount, texCoordSetMap,
(texCoordSetMap == null) ? 0 : texCoordSetMap.length,
texCoordSetMapOffset,
- cv.numActiveTexUnit, cv.texUnitStateMap,
+ cv.numActiveTexUnit,
vertexAttrCount, vertexAttrSizes,
interLeavedVertexData, cdata,
- pass, cdirty);
+ cdirty);
} // end of interleaved case
@@ -2572,25 +2397,23 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if((vertexType & TEXCOORD_DEFINED) != 0)
vdefined |= TEXCOORD_FLOAT;
- executeVA(cv.ctx, this, geoType, isNonUniformScale,
- multiScreen,
- ignoreVertexColors,
- validVertexCount,
- (vertexFormat | c4fAllocated),
- vdefined,
- initialCoordIndex,
- mirrorFloatRefCoords, mirrorDoubleRefCoords,
- initialColorIndex, cfdata, cbdata,
- initialNormalIndex, mirrorFloatRefNormals,
- vertexAttrCount, vertexAttrSizes,
- initialVertexAttrIndex, mirrorFloatRefVertexAttrs,
- pass,
- ((texCoordSetMap == null) ? 0:texCoordSetMap.length),
- texCoordSetMap,
- cv.numActiveTexUnit,
- cv.texUnitStateMap,
- initialTexCoordIndex,texCoordStride,
- mirrorRefTexCoords, cdirty);
+ Pipeline.getPipeline().executeVA(cv.ctx,
+ this, geoType, isNonUniformScale,
+ ignoreVertexColors,
+ validVertexCount,
+ (vertexFormat | c4fAllocated),
+ vdefined,
+ initialCoordIndex,
+ mirrorFloatRefCoords, mirrorDoubleRefCoords,
+ initialColorIndex, cfdata, cbdata,
+ initialNormalIndex, mirrorFloatRefNormals,
+ vertexAttrCount, vertexAttrSizes,
+ initialVertexAttrIndex, mirrorFloatRefVertexAttrs,
+ ((texCoordSetMap == null) ? 0:texCoordSetMap.length),
+ texCoordSetMap,
+ cv.numActiveTexUnit,
+ initialTexCoordIndex,texCoordStride,
+ mirrorRefTexCoords, cdirty);
}// end of all vertex data being set
}// end of non interleaved case
}// end of by reference with java array
@@ -2629,19 +2452,19 @@ abstract class GeometryArrayRetained extends GeometryRetained{
dirtyFlag = 0;
}
- executeInterleavedBuffer(cv.ctx, this, geoType, isNonUniformScale,
- useAlpha,
- multiScreen,
- ignoreVertexColors,
- initialVertexIndex,
- validVertexCount,
- vertexFormat,
- texCoordSetCount, texCoordSetMap,
- (texCoordSetMap == null) ? 0 : texCoordSetMap.length,
- texCoordSetMapOffset,
- cv.numActiveTexUnit, cv.texUnitStateMap,
- interleavedFloatBufferImpl.getBufferAsObject(), cdata,
- pass, cdirty);
+ Pipeline.getPipeline().executeInterleavedBuffer(cv.ctx,
+ this, geoType, isNonUniformScale,
+ useAlpha,
+ ignoreVertexColors,
+ initialVertexIndex,
+ validVertexCount,
+ vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ (texCoordSetMap == null) ? 0 : texCoordSetMap.length,
+ texCoordSetMapOffset,
+ cv.numActiveTexUnit,
+ interleavedFloatBufferImpl.getBufferAsObject(), cdata,
+ cdirty);
} // end of interleaved case
@@ -2747,89 +2570,32 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if((vertexType & TEXCOORD_DEFINED) != 0)
vdefined |= TEXCOORD_FLOAT;
- executeVABuffer(cv.ctx, this, geoType, isNonUniformScale,
- multiScreen,
- ignoreVertexColors,
- validVertexCount,
- (vertexFormat | c4fAllocated),
- vdefined,
- initialCoordIndex,
- vcoord,
- initialColorIndex,
- cdataBuffer,
- cfdata, cbdata,
- initialNormalIndex,
- normal,
- vertexAttrCount, vertexAttrSizes,
- initialVertexAttrIndex,
- nioFloatBufferRefVertexAttrs,
- pass,
- ((texCoordSetMap == null) ? 0:texCoordSetMap.length),
- texCoordSetMap,
- cv.numActiveTexUnit,
- cv.texUnitStateMap,
- initialTexCoordIndex,texCoordStride,
- refTexCoords, cdirty);
+ Pipeline.getPipeline().executeVABuffer(cv.ctx,
+ this, geoType, isNonUniformScale,
+ ignoreVertexColors,
+ validVertexCount,
+ (vertexFormat | c4fAllocated),
+ vdefined,
+ initialCoordIndex,
+ vcoord,
+ initialColorIndex,
+ cdataBuffer,
+ cfdata, cbdata,
+ initialNormalIndex,
+ normal,
+ vertexAttrCount, vertexAttrSizes,
+ initialVertexAttrIndex,
+ nioFloatBufferRefVertexAttrs,
+ ((texCoordSetMap == null) ? 0:texCoordSetMap.length),
+ texCoordSetMap,
+ cv.numActiveTexUnit,
+ initialTexCoordIndex,texCoordStride,
+ refTexCoords, cdirty);
}// end of all vertex data being set
}// end of non interleaved case
}// end of by reference with nio-buffer case
}
- // used for GeometryArrays
- private native void buildGA(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale, boolean updateAlpha,
- float alpha,
- boolean ignoreVertexColors,
- int startVIndex,
- int vcount, int vformat,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen, int[] texCoordSetMapOffset,
- int vertexAttrCount, int[] vertexAttrSizes,
- double[] xform, double[] nxform,
- float[] varray);
-
- // used to Build Dlist GeometryArray by Reference with java arrays
- private native void buildGAForByRef(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale, boolean updateAlpha,
- float alpha,
- boolean ignoreVertexColors,
- int vcount,
- int vformat,
- int vdefined,
- int coordIndex, float[] vfcoords, double[] vdcoords,
- int colorIndex, float[] cfdata, byte[] cbdata,
- int normalIndex, float[] ndata,
- int vertexAttrCount, int[] vertexAttrSizes,
- int[] vertexAttrIndex, float[][] vertexAttrData,
- int texcoordmaplength,
- int[] texcoordoffset,
- int[] texIndex, int texstride, Object[] texCoords,
- double[] xform, double[] nxform);
-
-
- // used to Build Dlist GeometryArray by Reference with NIO buffer
- // NOTE: NIO buffers are no longer supported in display lists.
- /*
- private native void buildGAForBuffer(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale, boolean updateAlpha,
- float alpha,
- boolean ignoreVertexColors,
- int vcount,
- int vformat,
- int vdefined,
- int coordIndex, Object vcoords,
- int colorIndex, Object cdata,
- int normalIndex, Object ndata,
- int texcoordmaplength,
- int[] texcoordoffset,
- int[] texIndex, int texstride, Object[] texCoords,
- double[] xform, double[] nxform);
- */
-
-
void buildGA(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
boolean updateAlpha, float alpha, boolean ignoreVertexColors,
Transform3D xform, Transform3D nxform) {
@@ -2851,7 +2617,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
System.out.println("calling native buildGA()");
System.out.println("geoType = "+geoType+" initialVertexIndex = "+initialVertexIndex+" validVertexCount = "+validVertexCount+" vertexFormat = "+vertexFormat+" vertexData = "+vertexData);
*/
- buildGA(cv.ctx, this, geoType, isNonUniformScale,
+ Pipeline.getPipeline().buildGA(cv.ctx,
+ this, geoType, isNonUniformScale,
updateAlpha, alpha, ignoreVertexColors,
initialVertexIndex,
validVertexCount, vertexFormat,
@@ -2900,7 +2667,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if((vertexType & TEXCOORD_DEFINED) != 0)
vdefined |= TEXCOORD_FLOAT;
- buildGAForByRef(cv.ctx, this, geoType, isNonUniformScale,
+ Pipeline.getPipeline().buildGAForByRef(cv.ctx,
+ this, geoType, isNonUniformScale,
updateAlpha, alpha,
ignoreVertexColors,
validVertexCount,
@@ -2955,7 +2723,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if((vertexType & TEXCOORD_DEFINED) != 0)
vdefined |= TEXCOORD_FLOAT;
// NOTE : need to add vertex attrs
- buildGAForBuffer(cv.ctx, this, geoType, isNonUniformScale,
+ Pipeline.getPipeline().buildGAForBuffer(cv.ctx,
+ this, geoType, isNonUniformScale,
updateAlpha, alpha,
ignoreVertexColors,
validVertexCount,
@@ -3744,7 +3513,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
gaList.add(Shape3DRetained.getGeomAtom(s));
}
- m[k] = VirtualUniverse.mc.getMessage();
+ m[k] = new J3dMessage();
m[k].type = J3dMessage.GEOMETRY_CHANGED;
// Who to send this message to ?
@@ -6297,8 +6066,23 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
}
}
+
+ //NVaidya
+ // User may or may not have changed indices in updater callback.
+ // We need to presume that the user may indeed have and, thus, will
+ // need to recompute maxCoordIndex unconditionally while
+ // geomLock is still locked.
+ if ((vertexFormat & GeometryArray.BY_REFERENCE_INDICES) != 0) {
+ assert (this instanceof IndexedGeometryArrayRetained);
+
+ if (((IndexedGeometryArrayRetained)this).getCoordIndicesRef() == null) {
+ nullGeo = true;
+ }
+ ((IndexedGeometryArrayRetained)this).doPostUpdaterUpdate();
+ }
}
- dirtyFlag |= VERTEX_CHANGED;
+
+ dirtyFlag |= VERTEX_CHANGED;
colorChanged = 0xffff;
geomLock.unLock();
@@ -6350,7 +6134,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// Setup bounding planes.
Point3d pCoor[] = new Point3d[4];
for(i=0; i<4; i++)
- pCoor[i] = getPoint3d();
+ pCoor[i] = new Point3d();
// left plane.
pCoor[0].set(box.lower.x, box.lower.y, box.lower.z);
@@ -6365,8 +6149,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
null,
dist, iPnt);
}
- // free points
- for (i=0; i<4; i++) freePoint3d(pCoor[i]);
return true;
}
@@ -6381,7 +6163,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
null,
dist, iPnt);
}
- for (i=0; i<4; i++) freePoint3d(pCoor[i]);
return true;
}
@@ -6396,7 +6177,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
null,
dist, iPnt);
}
- for (i=0; i<4; i++) freePoint3d(pCoor[i]);
return true;
}
// top plane.
@@ -6410,7 +6190,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
null,
dist, iPnt);
}
- for (i=0; i<4; i++) freePoint3d(pCoor[i]);
return true;
}
@@ -6425,7 +6204,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
null,
dist, iPnt);
}
- for (i=0; i<4; i++) freePoint3d(pCoor[i]);
return true;
}
@@ -6440,11 +6218,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
null,
dist, iPnt);
}
- for (i=0; i<4; i++) freePoint3d(pCoor[i]);
return true;
}
-
- for (i=0; i<4; i++) freePoint3d(pCoor[i]);
return false;
}
@@ -6455,7 +6230,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
Point3d iPnt)
{
int i, j;
- Vector3d tempV3D = getVector3d();
+ Vector3d tempV3D = new Vector3d();
boolean esFlag;
//Do trivial vertex test.
@@ -6473,7 +6248,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
null, dist, iPnt);
}
- freeVector3d(tempV3D);
return true;
}
}
@@ -6493,25 +6267,22 @@ abstract class GeometryArrayRetained extends GeometryRetained{
dist, iPnt);
}
- freeVector3d(tempV3D);
return true;
}
}
if (coordinates.length < 3) {
-
- freeVector3d(tempV3D);
return false; // We're done with line.
}
// Find rho.
// Compute plane normal.
- Vector3d vec0 = getVector3d(); // Edge vector from point 0 to point 1;
- Vector3d vec1 = getVector3d(); // Edge vector from point 0 to point 2 or 3;
- Vector3d pNrm = getVector3d();
- Vector3d pa = getVector3d();
- Point3d q = getPoint3d();
+ Vector3d vec0 = new Vector3d(); // Edge vector from point 0 to point 1;
+ Vector3d vec1 = new Vector3d(); // Edge vector from point 0 to point 2 or 3;
+ Vector3d pNrm = new Vector3d();
+ Vector3d pa = new Vector3d();
+ Point3d q = new Point3d();
double nLenSq, pqLen, pNrmDotPa, tq;
// compute plane normal for coordinates.
@@ -6533,12 +6304,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if(j == (coordinates.length-1)) {
// System.out.println("(1) Degenerate polygon.");
- freeVector3d(tempV3D);
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
- freeVector3d(pa);
- freePoint3d(q);
return false; // Degenerate polygon.
}
@@ -6554,12 +6319,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
nLenSq = pNrm.lengthSquared();
if( nLenSq == 0.0) {
// System.out.println("(2) Degenerate polygon.");
- freeVector3d(tempV3D);
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
- freeVector3d(pa);
- freePoint3d(q);
return false; // Degenerate polygon.
}
@@ -6572,12 +6331,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
pqLen = Math.sqrt(pNrmDotPa * pNrmDotPa/ nLenSq);
if(pqLen > sphere.radius) {
- freeVector3d(tempV3D);
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
- freeVector3d(pa);
- freePoint3d(q);
return false;
}
@@ -6595,20 +6348,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
pNrm,
dist, iPnt);
}
- freeVector3d(tempV3D);
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
- freeVector3d(pa);
- freePoint3d(q);
return true;
}
- freeVector3d(tempV3D);
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
- freeVector3d(pa);
- freePoint3d(q);
return false;
}
@@ -6945,8 +6686,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
Point3d end)
{
double abLenSq, acLenSq, apLenSq, abDotAp, radiusSq;
- Vector3d ab = getVector3d();
- Vector3d ap = getVector3d();
+ Vector3d ab = new Vector3d();
+ Vector3d ap = new Vector3d();
ab.x = end.x - start.x;
ab.y = end.y - start.y;
@@ -6959,8 +6700,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
abDotAp = ab.dot(ap);
if(abDotAp < 0.0) {
- freeVector3d(ab);
- freeVector3d(ap);
return false; // line segment points away from sphere.
}
@@ -6968,8 +6707,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
acLenSq = abDotAp * abDotAp / abLenSq;
if(acLenSq < abLenSq) {
- freeVector3d(ab);
- freeVector3d(ap);
return false; // C doesn't lies between end points of edge.
}
@@ -6977,13 +6714,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
apLenSq = ap.lengthSquared();
if((apLenSq - acLenSq) <= radiusSq) {
- freeVector3d(ab);
- freeVector3d(ap);
return true;
}
- freeVector3d(ab);
- freeVector3d(ap);
return false;
}
@@ -7095,8 +6828,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
Point3d end, Point3d iPnt)
{
- Vector3d tempV3d = getVector3d();
- Vector3d direction = getVector3d();
+ Vector3d tempV3d = new Vector3d();
+ Vector3d direction = new Vector3d();
double pD, pNrmDotrDir, tr;
// Compute plane D.
@@ -7112,8 +6845,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// edge is parallel to plane.
if(pNrmDotrDir== 0.0) {
// System.out.println("Edge is parallel to plane.");
- freeVector3d(tempV3d);
- freeVector3d(direction);
return false;
}
@@ -7125,8 +6856,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// or exceed the edge's length.
if((tr < 0.0 ) || (tr > 1.0 )) {
// System.out.println("Edge intersects the plane behind the start or exceed end.");
- freeVector3d(tempV3d);
- freeVector3d(direction);
return false;
}
@@ -7134,8 +6863,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
iPnt.y = start.y + tr * direction.y;
iPnt.z = start.z + tr * direction.z;
- freeVector3d(tempV3d);
- freeVector3d(direction);
return true;
}
@@ -7470,10 +7197,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
boolean intersectTriPnt(Point3d v0, Point3d v1, Point3d v2, Point3d u) {
- Vector3d e1 = getVector3d();
- Vector3d e2 = getVector3d();
- Vector3d n1 = getVector3d();
- Vector3d tempV3d = getVector3d();
+ Vector3d e1 = new Vector3d();
+ Vector3d e2 = new Vector3d();
+ Vector3d n1 = new Vector3d();
+ Vector3d tempV3d = new Vector3d();
double d1, du;
@@ -7490,10 +7217,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if(n1.length() == 0.0) {
// System.out.println("(1) Degenerate triangle.");
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(tempV3d);
return false; // Degenerate triangle.
}
@@ -7509,10 +7232,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// no intersection occurs
if(du != 0.0) {
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(tempV3d);
return false;
}
@@ -7549,17 +7268,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// finally, test if u is totally contained in tri.
if(pointInTri(u, v0, v1, v2, i0, i1)) {
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(tempV3d);
return true;
}
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(tempV3d);
return false;
}
@@ -7585,11 +7296,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
Point3d u0, Point3d u1, Point3d u2) {
// System.out.println("In intersectTriTri ...");
- Vector3d e1 = getVector3d();
- Vector3d e2 = getVector3d();
- Vector3d n1 = getVector3d();
- Vector3d n2 = getVector3d();
- Vector3d tempV3d = getVector3d();
+ Vector3d e1 = new Vector3d();
+ Vector3d e2 = new Vector3d();
+ Vector3d n1 = new Vector3d();
+ Vector3d n2 = new Vector3d();
+ Vector3d tempV3d = new Vector3d();
double d1, d2;
double du0, du1, du2, dv0, dv1, dv2;
@@ -7612,11 +7323,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if(n1.length() == 0.0) {
// System.out.println("(1) Degenerate triangle.");
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(n2);
- freeVector3d(tempV3d);
return false; // Degenerate triangle.
}
@@ -7644,11 +7350,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// no intersection occurs
if(du0du1>0.0 && du0du2>0.0) {
// System.out.println("In intersectTriTri : du0du1>0.0 && du0du2>0.0");
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(n2);
- freeVector3d(tempV3d);
return false;
}
@@ -7665,11 +7366,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if(n2.length() == 0.0) {
// System.out.println("(2) Degenerate triangle.");
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(n2);
- freeVector3d(tempV3d);
return false; // Degenerate triangle.
}
@@ -7697,11 +7393,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// no intersection occurs
if(dv0dv1>0.0 && dv0dv2>0.0) {
// System.out.println("In intersectTriTri : dv0dv1>0.0 && dv0dv2>0.0");
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(n2);
- freeVector3d(tempV3d);
return false;
}
// compute direction of intersection line.
@@ -7782,11 +7473,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
else {
// triangles are coplanar
boolean toreturn = coplanarTriTri(n1, v0, v1, v2, u0, u1, u2);
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(n2);
- freeVector3d(tempV3d);
return toreturn;
}
@@ -7821,11 +7507,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// triangles are coplanar
// System.out.println("In intersectTriTri : coplanarTriTri test 2");
boolean toreturn = coplanarTriTri(n2, v0, v1, v2, u0, u1, u2);
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(n2);
- freeVector3d(tempV3d);
return toreturn;
}
@@ -7859,20 +7540,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if(isect1E<isect2S || isect2E<isect1S) {
// System.out.println("In intersectTriTri :isect1E<isect2S || isect2E<isect1S");
// System.out.println("In intersectTriTri : return false");
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(n2);
- freeVector3d(tempV3d);
return false;
}
// System.out.println("In intersectTriTri : return true");
- freeVector3d(e1);
- freeVector3d(e2);
- freeVector3d(n1);
- freeVector3d(n2);
- freeVector3d(tempV3d);
return true;
}
@@ -7881,9 +7552,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
boolean intersectPolygon(Point3d coord1[], Point3d coord2[]) {
int i, j;
- Vector3d vec0 = getVector3d(); // Edge vector from point 0 to point 1;
- Vector3d vec1 = getVector3d(); // Edge vector from point 0 to point 2 or 3;
- Vector3d pNrm = getVector3d();
+ Vector3d vec0 = new Vector3d(); // Edge vector from point 0 to point 1;
+ Vector3d vec1 = new Vector3d(); // Edge vector from point 0 to point 2 or 3;
+ Vector3d pNrm = new Vector3d();
boolean epFlag;
@@ -7906,9 +7577,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if(j == (coord1.length-1)) {
// System.out.println("(1) Degenerate polygon.");
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
return false; // Degenerate polygon.
}
@@ -7923,16 +7591,13 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if(pNrm.length() == 0.0) {
// System.out.println("(2) Degenerate polygon.");
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
return false; // Degenerate polygon.
}
j = 0;
Point3d seg[] = new Point3d[2];
- seg[0] = getPoint3d();
- seg[1] = getPoint3d();
+ seg[0] = new Point3d();
+ seg[1] = new Point3d();
for(i=0; i<coord2.length; i++) {
if(i < (coord2.length-1))
@@ -7949,29 +7614,14 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
if (j==0) {
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
- freePoint3d(seg[0]);
- freePoint3d(seg[1]);
return false;
}
if (coord2.length < 3) {
boolean toreturn = pointIntersectPolygon2D(pNrm, coord1, seg[0]);
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
- freePoint3d(seg[0]);
- freePoint3d(seg[1]);
return toreturn;
} else {
boolean toreturn = edgeIntersectPolygon2D(pNrm, coord1, seg);
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
- freePoint3d(seg[0]);
- freePoint3d(seg[1]);
return toreturn;
}
}
@@ -7997,12 +7647,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
boolean intersectSegment( Point3d coordinates[], Point3d start, Point3d end,
double dist[], Point3d iPnt ) {
boolean result;
- Vector3d direction = getVector3d();
+ Vector3d direction = new Vector3d();
direction.x = end.x - start.x;
direction.y = end.y - start.y;
direction.z = end.z - start.z;
result = intersectRayOrSegment(coordinates, direction, start, dist, iPnt, true);
- freeVector3d(direction);
return result;
}
@@ -8016,9 +7665,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
Vector3d direction, Point3d origin,
double dist[], Point3d iPnt, boolean isSegment) {
Vector3d vec0, vec1, pNrm, tempV3d;
- vec0 = getVector3d();
- vec1 = getVector3d();
- pNrm = getVector3d();
+ vec0 = new Vector3d();
+ vec1 = new Vector3d();
+ pNrm = new Vector3d();
double absNrmX, absNrmY, absNrmZ, pD = 0.0;
double pNrmDotrDir = 0.0;
@@ -8070,9 +7719,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
iPnt);
// put the Vectors on the freelist
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
return isIntersect;
}
@@ -8101,14 +7747,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
break;
}
}
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
return isIntersect;
}
// Plane equation: (p - p0)*pNrm = 0 or p*pNrm = pD;
- tempV3d = getVector3d();
+ tempV3d = new Vector3d();
tempV3d.set((Tuple3d) coordinates[0]);
pD = pNrm.dot(tempV3d);
tempV3d.set((Tuple3d) origin);
@@ -8124,10 +7767,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
(isSegment && (dist[0] > 1.0+EPS))) {
// Ray intersects the plane behind the ray's origin
// or intersect point not fall in Segment
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
- freeVector3d(tempV3d);
return false;
}
@@ -8288,10 +7927,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if (isIntersect) {
dist[0] *= direction.length();
}
- freeVector3d(vec0);
- freeVector3d(vec1);
- freeVector3d(pNrm);
- freeVector3d(tempV3d);
return isIntersect;
}
@@ -8428,7 +8063,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// System.out.println("start " + start + " end " + end );
// System.out.println("ori " + ori + " dir " + dir);
- lDir = getVector3d();
+ lDir = new Vector3d();
lDir.x = (end.x - start.x);
lDir.y = (end.y - start.y);
lDir.z = (end.z - start.z);
@@ -8449,7 +8084,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
iPnt.set(start);
}
}
- freeVector3d(lDir);
return isIntersect;
}
// Find the inverse.
@@ -8468,12 +8102,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if(s<0.0) { // Before the origin of ray.
// System.out.println("Before the origin of ray " + s);
- freeVector3d(lDir);
return false;
}
if((t<0)||(t>1.0)) {// Before or after the end points of line.
// System.out.println("Before or after the end points of line. " + t);
- freeVector3d(lDir);
return false;
}
@@ -8482,7 +8114,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if((tmp1 < (tmp2 - EPS)) || (tmp1 > (tmp2 + EPS))) {
// System.out.println("No intersection : tmp1 " + tmp1 + " tmp2 " + tmp2);
- freeVector3d(lDir);
return false;
}
@@ -8496,7 +8127,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
// System.out.println("Intersected : tmp1 " + tmp1 + " tmp2 " + tmp2);
- freeVector3d(lDir);
return true;
}
@@ -8507,11 +8137,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
boolean intersectCylinder(Point3d coordinates[], PickCylinder cyl,
double dist[], Point3d iPnt) {
- Point3d origin = getPoint3d();
- Point3d end = getPoint3d();
- Vector3d direction = getVector3d();
- Point3d iPnt1 = getPoint3d();
- Vector3d originToIpnt = getVector3d();
+ Point3d origin = new Point3d();
+ Point3d end = new Point3d();
+ Vector3d direction = new Vector3d();
+ Point3d iPnt1 = new Point3d();
+ Vector3d originToIpnt = new Vector3d();
if (iPnt == null) {
iPnt = new Point3d();
@@ -8532,24 +8162,12 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if (cyl instanceof PickCylinderRay) {
if (intersectRay(coordinates,
new PickRay(origin, direction),
- dist, iPnt)) {
-
- freePoint3d(origin);
- freePoint3d(end);
- freeVector3d(direction);
- freeVector3d(originToIpnt);
- freePoint3d(iPnt1);
-
+ dist, iPnt)) {
return true;
}
}
else {
if (intersectSegment(coordinates, origin, end, dist, iPnt)) {
- freePoint3d(origin);
- freePoint3d(end);
- freeVector3d(direction);
- freeVector3d(originToIpnt);
- freePoint3d(iPnt1);
return true;
}
}
@@ -8575,19 +8193,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if (sqDistToEdge <= radius*radius) {
originToIpnt.sub (iPnt1, origin);
dist[0] = originToIpnt.length();
- freePoint3d(origin);
- freePoint3d(end);
- freeVector3d(direction);
- freeVector3d(originToIpnt);
- freePoint3d(iPnt1);
return true;
}
}
- freePoint3d(origin);
- freePoint3d(end);
- freeVector3d(direction);
- freeVector3d(originToIpnt);
- freePoint3d(iPnt1);
return false;
}
@@ -8598,14 +8206,14 @@ abstract class GeometryArrayRetained extends GeometryRetained{
boolean intersectCone(Point3d coordinates[], PickCone cone,
double[] dist, Point3d iPnt) {
- Point3d origin = getPoint3d();
- Point3d end = getPoint3d();
- Vector3d direction = getVector3d();
- Vector3d originToIpnt = getVector3d();
+ Point3d origin = new Point3d();
+ Point3d end = new Point3d();
+ Vector3d direction = new Vector3d();
+ Vector3d originToIpnt = new Vector3d();
double distance;
- Point3d iPnt1 = getPoint3d();
- Vector3d vector = getVector3d();
+ Point3d iPnt1 = new Point3d();
+ Vector3d vector = new Vector3d();
if (iPnt == null) {
iPnt = new Point3d();
@@ -8626,23 +8234,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if (intersectRay(coordinates,
new PickRay (origin, direction),
dist, iPnt)) {
- freePoint3d(origin);
- freePoint3d(end);
- freePoint3d(iPnt1);
- freeVector3d(direction);
- freeVector3d(originToIpnt);
- freeVector3d(vector);
return true;
}
}
else {
if (intersectSegment(coordinates, origin, end, dist, iPnt)) {
- freePoint3d(origin);
- freePoint3d(end);
- freePoint3d(iPnt1);
- freeVector3d(direction);
- freeVector3d(originToIpnt);
- freeVector3d(vector);
return true;
}
}
@@ -8671,21 +8267,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if (sqDistToEdge <= radius*radius) {
// System.out.println ("intersectCone: edge "+i+" intersected");
dist[0] = distance;
- freePoint3d(origin);
- freePoint3d(end);
- freePoint3d(iPnt1);
- freeVector3d(direction);
- freeVector3d(originToIpnt);
- freeVector3d(vector);
return true;
}
}
- freePoint3d(origin);
- freePoint3d(end);
- freePoint3d(iPnt1);
- freeVector3d(direction);
- freeVector3d(originToIpnt);
- freeVector3d(vector);
return false;
}
@@ -8697,11 +8281,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
boolean intersectCylinder(Point3d pt, PickCylinder cyl,
double[] dist) {
- Point3d origin = getPoint3d();
- Point3d end = getPoint3d();
- Vector3d direction = getVector3d();
- Point3d iPnt = getPoint3d();
- Vector3d originToIpnt = getVector3d();
+ Point3d origin = new Point3d();
+ Point3d end = new Point3d();
+ Vector3d direction = new Vector3d();
+ Point3d iPnt = new Point3d();
+ Vector3d originToIpnt = new Vector3d();
// Get cylinder information
cyl.getOrigin (origin);
@@ -8719,18 +8303,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if (sqDist <= radius*radius) {
originToIpnt.sub (iPnt, origin);
dist[0] = originToIpnt.length();
- freePoint3d(origin);
- freePoint3d(end);
- freePoint3d(iPnt);
- freeVector3d(originToIpnt);
- freeVector3d(direction);
return true;
}
- freePoint3d(origin);
- freePoint3d(end);
- freePoint3d(iPnt);
- freeVector3d(originToIpnt);
- freeVector3d(direction);
return false;
}
@@ -8740,11 +8314,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
*/
boolean intersectCone(Point3d pt, PickCone cone, double[] dist)
{
- Point3d origin = getPoint3d();
- Point3d end = getPoint3d();
- Vector3d direction = getVector3d();
- Point3d iPnt = getPoint3d();
- Vector3d originToIpnt = getVector3d();
+ Point3d origin = new Point3d();
+ Point3d end = new Point3d();
+ Vector3d direction = new Vector3d();
+ Point3d iPnt = new Point3d();
+ Vector3d originToIpnt = new Vector3d();
// Get cone information
cone.getOrigin (origin);
@@ -8769,11 +8343,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
radius = Math.tan (cone.getSpreadAngle()) * distance;
if (sqDist <= radius*radius) {
dist[0] = distance;
- freePoint3d(origin);
- freePoint3d(end);
- freePoint3d(iPnt);
- freeVector3d(direction);
- freeVector3d(originToIpnt);
return true;
}
return false;
@@ -10713,18 +10282,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
}
- protected void finalize() {
- // For Pure immediate mode, there is no clearLive so
- // surface will free when JVM do GC
- if (pVertexBuffers != 0) {
- // memory not yet free for immediate mode rendering
- // It is thread safe since D3D only free surface in
- // the next swapBuffer() call which must be in the
- // same renderer threads
- freeD3DArray(true);
- }
- }
-
void freeDlistId() {
if (dlistId != -1) {
VirtualUniverse.mc.freeDisplayListId(dlistObj);
@@ -11115,28 +10672,26 @@ abstract class GeometryArrayRetained extends GeometryRetained{
boolean intersect(Transform3D thisLocalToVworld,
Transform3D otherLocalToVworld, GeometryRetained geom) {
- Transform3D tg = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D t3d = new Transform3D();
boolean isIntersect = false;
if (geom instanceof GeometryArrayRetained ) {
GeometryArrayRetained geomArray = (GeometryArrayRetained) geom;
if (geomArray.validVertexCount >= validVertexCount) {
- tg.invert(otherLocalToVworld);
- tg.mul(thisLocalToVworld);
- isIntersect = intersect(tg, geom);
+ t3d.invert(otherLocalToVworld);
+ t3d.mul(thisLocalToVworld);
+ isIntersect = intersect(t3d, geom);
} else {
- tg.invert(thisLocalToVworld);
- tg.mul(otherLocalToVworld);
- isIntersect = geomArray.intersect(tg, this);
+ t3d.invert(thisLocalToVworld);
+ t3d.mul(otherLocalToVworld);
+ isIntersect = geomArray.intersect(t3d, this);
}
} else {
- tg.invert(thisLocalToVworld);
- tg.mul(otherLocalToVworld);
- isIntersect = geom.intersect(tg, this);
+ t3d.invert(thisLocalToVworld);
+ t3d.mul(otherLocalToVworld);
+ isIntersect = geom.intersect(t3d, this);
}
-
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, tg);
return isIntersect;
}
@@ -11525,23 +11080,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
dist[0] = Math.sqrt(dist[0]);
}
- Vector3d getVector3d() {
- return (Vector3d)FreeListManager.getObject(FreeListManager.VECTOR3D);
- }
-
- void freeVector3d(Vector3d v) {
- FreeListManager.freeObject(FreeListManager.VECTOR3D, v);
- }
-
- Point3d getPoint3d() {
- return (Point3d)FreeListManager.getObject(FreeListManager.POINT3D);
- }
-
- void freePoint3d(Point3d p) {
- FreeListManager.freeObject(FreeListManager.POINT3D, p);
- }
-
-
void handleFrequencyChange(int bit) {
int mask = 0;
if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) {
diff --git a/src/classes/share/javax/media/j3d/GeometryAtom.java b/src/classes/share/javax/media/j3d/GeometryAtom.java
index 087ebdf..659230b 100644
--- a/src/classes/share/javax/media/j3d/GeometryAtom.java
+++ b/src/classes/share/javax/media/j3d/GeometryAtom.java
@@ -177,7 +177,7 @@ class GeometryAtom extends Object implements BHLeafInterface, NnuId {
ra.rListInfo[j] = new RenderAtomListInfo();
ra.rListInfo[j].renderAtom = ra;
ra.rListInfo[j].index = j;
- ra.rListInfo[j].localToVworld = VirtualUniverse.mc.getTransform3D(null);
+ ra.rListInfo[j].localToVworld = new Transform3D();
}
}
@@ -213,7 +213,7 @@ class GeometryAtom extends Object implements BHLeafInterface, NnuId {
ra.rListInfo[j] = new RenderAtomListInfo();
ra.rListInfo[j].renderAtom = ra;
ra.rListInfo[j].index = j;
- ra.rListInfo[j].localToVworld = VirtualUniverse.mc.getTransform3D(null);
+ ra.rListInfo[j].localToVworld = new Transform3D();
}
}
}
diff --git a/src/classes/share/javax/media/j3d/GeometryRetained.java b/src/classes/share/javax/media/j3d/GeometryRetained.java
index 183dba4..3c93e37 100644
--- a/src/classes/share/javax/media/j3d/GeometryRetained.java
+++ b/src/classes/share/javax/media/j3d/GeometryRetained.java
@@ -213,9 +213,7 @@ abstract class GeometryRetained extends NodeComponentRetained {
abstract void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
boolean updateAlpha, float alpha,
- boolean multiScreen, int screen,
- boolean ignoreVertexColors,
- int pass);
+ int screen, boolean ignoreVertexColors);
/**
* This method should return an int indicating the format of the vertices,
@@ -274,21 +272,19 @@ abstract class GeometryRetained extends NodeComponentRetained {
boolean intersect(Transform3D thisLocalToVworld,
Transform3D otherLocalToVworld, GeometryRetained geom) {
- Transform3D tg = VirtualUniverse.mc.getTransform3D(null);
- tg.invert(otherLocalToVworld);
- tg.mul(thisLocalToVworld);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, tg);
- return intersect(tg, geom);
+ Transform3D t3d = new Transform3D();
+ t3d.invert(otherLocalToVworld);
+ t3d.mul(thisLocalToVworld);
+ return intersect(t3d, geom);
}
boolean intersect(Transform3D thisLocalToVworld, Bounds targetBound) {
Bounds transBound = (Bounds) targetBound.clone();
- Transform3D tg = VirtualUniverse.mc.getTransform3D(null);
- tg.invert(thisLocalToVworld);
- transBound.transform(tg);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, tg);
+ Transform3D t3d = new Transform3D();
+ t3d.invert(thisLocalToVworld);
+ transBound.transform(t3d);
return intersect(transBound);
}
diff --git a/src/classes/share/javax/media/j3d/GeometryStructure.java b/src/classes/share/javax/media/j3d/GeometryStructure.java
index a0ea460..bddfac0 100644
--- a/src/classes/share/javax/media/j3d/GeometryStructure.java
+++ b/src/classes/share/javax/media/j3d/GeometryStructure.java
@@ -306,8 +306,7 @@ class GeometryStructure extends J3dStructure {
addBgGeometryAtomList(geomAtom);
continue;
}
- BHLeafNode bhLeafNode = (BHLeafNode)
- VirtualUniverse.mc.getBHNode(BHNode.BH_TYPE_LEAF);
+ BHLeafNode bhLeafNode = new BHLeafNode();
bhLeafNode.leafIF = geomAtom;
geomAtom.bhLeafNode = bhLeafNode;
bhLeafNode.computeBoundingHull();
@@ -317,8 +316,7 @@ class GeometryStructure extends J3dStructure {
} else if (node instanceof GroupRetained) {
synchronized (node) {
GroupRetained group = (GroupRetained) node;
- BHLeafNode bhLeafNode = (BHLeafNode)
- VirtualUniverse.mc.getBHNode(BHNode.BH_TYPE_LEAF);
+ BHLeafNode bhLeafNode = new BHLeafNode();
bhLeafNode.leafIF = group;
group.bhLeafNode = bhLeafNode;
bhLeafNode.computeBoundingHull();
diff --git a/src/classes/share/javax/media/j3d/GraphicsConfigInfo.java b/src/classes/share/javax/media/j3d/GraphicsConfigInfo.java
index 56711dc..a6bbcbb 100644
--- a/src/classes/share/javax/media/j3d/GraphicsConfigInfo.java
+++ b/src/classes/share/javax/media/j3d/GraphicsConfigInfo.java
@@ -12,24 +12,33 @@
package javax.media.j3d;
+/**
+ * Container for the GraphicsTemplate3D and other private data about a selected
+ * GraphicsConfiguration. An instance of this class is created along with an
+ * instance of GrahpicsConfiguration, whenever getBestConfiguration is called.
+ */
class GraphicsConfigInfo {
- private int reqStencilSize = 0;
- private long fbConfig = 0L;
+ private GraphicsConfigTemplate3D graphicsConfigTemplate3D = null;
+ private Object privateData = null;
- int getRequestedStencilSize() {
- return reqStencilSize;
+ GraphicsConfigInfo(GraphicsConfigTemplate3D graphicsConfigTemplate3D) {
+ setGraphicsConfigTemplate3D(graphicsConfigTemplate3D);
}
- void setRequestedStencilSize(int reqSS) {
- reqStencilSize = reqSS;
+ GraphicsConfigTemplate3D getGraphicsConfigTemplate3D() {
+ return graphicsConfigTemplate3D;
}
-
- long getFBConfig() {
- return fbConfig;
+
+ void setGraphicsConfigTemplate3D(GraphicsConfigTemplate3D graphicsConfigTemplate3D) {
+ this.graphicsConfigTemplate3D = graphicsConfigTemplate3D;
}
-
- void setFBConfig(long fbC) {
- fbConfig = fbC;
+
+ Object getPrivateData() {
+ return privateData;
+ }
+
+ void setPrivateData(Object privateData) {
+ this.privateData = privateData;
}
}
diff --git a/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java b/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java
index 99536cc..a09d879 100644
--- a/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java
+++ b/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java
@@ -46,15 +46,7 @@ public class GraphicsConfigTemplate3D extends GraphicsConfigTemplate {
static Object globalLock = new Object();
static Object monitorLock = new Object();
- static boolean threadWaiting = false;
-
- /**
- * The platform dependent template. Since there is no
- * template-specific instance data in the NativeConfigTemplate3D
- * class, we can create one statically.
- */
- static NativeConfigTemplate3D nativeTemplate =
- new NativeConfigTemplate3D();
+ static volatile boolean threadWaiting = false;
/**
* Constructs a GraphicsConfigTemplate3D object with default parameters.
@@ -387,7 +379,8 @@ public class GraphicsConfigTemplate3D extends GraphicsConfigTemplate {
synchronized (monitorLock) {
switch (action) {
case J3dThread.WAIT:
- if (threadWaiting) {
+ // Issue 279 - loop until ready
+ while (threadWaiting) {
try {
monitorLock.wait();
} catch (InterruptedException e) {
diff --git a/src/classes/share/javax/media/j3d/GraphicsContext3D.java b/src/classes/share/javax/media/j3d/GraphicsContext3D.java
index 1369f32..8bfd972 100644
--- a/src/classes/share/javax/media/j3d/GraphicsContext3D.java
+++ b/src/classes/share/javax/media/j3d/GraphicsContext3D.java
@@ -12,6 +12,8 @@
package javax.media.j3d;
+import java.awt.Point;
+import java.awt.image.BufferedImage;
import javax.vecmath.*;
import java.util.Vector;
import java.util.Enumeration;
@@ -100,8 +102,6 @@ public class GraphicsContext3D extends Object {
*/
Canvas3D canvas3d = null;
- int objectId = -1;
-
//
// Graphics state
//
@@ -281,7 +281,8 @@ public class GraphicsContext3D extends Object {
static final int FLUSH2D = 23;
static final int DRAWANDFLUSH2D = 24;
static final int SET_MODELCLIP = 25;
- static final int NCOMMANDS = 26; // needs to be incremented
+ static final int DISPOSE2D = 26;
+ static final int NCOMMANDS = 27; // needs to be incremented
// when a new command is to be
// added to the list
@@ -296,11 +297,9 @@ public class GraphicsContext3D extends Object {
private static final int BUFFER_MODE = 0x1;
private int dirtyMask = 0;
-
// multi-texture
private int numActiveTexUnit = 0;
private int lastActiveTexUnitIndex = 0;
- private boolean toSimulateMultiTex = false;
// for read raster
private volatile boolean readRasterReady = false;
@@ -341,17 +340,62 @@ public class GraphicsContext3D extends Object {
* If the Appearance object is null, default values will be used
* for all appearance attributes - it is as if an
* Appearance node were created using the default constructor.
+ *
* @param appearance the new Appearance object
+ *
+ * @exception IllegalSharingException if the specified appearance refers
+ * to an ImageComponent2D that is being used by a Canvas3D as
+ * an off-screen buffer.
*/
public void setAppearance(Appearance appearance) {
-
- if(appearance == null) {
- if(defaultAppearance == null) {
- defaultAppearance = new Appearance();
- }
- appearance = defaultAppearance;
- }
-
+
+ if(appearance == null) {
+ if(defaultAppearance == null) {
+ defaultAppearance = new Appearance();
+ }
+ appearance = defaultAppearance;
+ } else {
+ // Check whether any ImageComponent2D referred to by
+ // the new appearance is being used as an off-screen buffer and throw
+ // IllegalSharingException if it is.
+ TextureRetained texRetained;
+ ImageComponent[] images;
+ AppearanceRetained appRetained = (AppearanceRetained)appearance.retained;
+ if(appRetained.texture != null) {
+ assert (appRetained.texUnitState == null);
+ texRetained = appRetained.texture;
+ images = texRetained.getImages();
+ if(images != null) {
+ for(int i=0; i<images.length; i++) {
+ if(images[i] != null) {
+ ImageComponentRetained imageRetained = (ImageComponentRetained) images[i].retained;
+ // Do illegal sharing check
+ if(imageRetained.getUsedByOffScreen()) {
+ throw new IllegalSharingException(J3dI18N.getString("GraphicsContext3D30"));
+ }
+ }
+ }
+ }
+ }
+ else if(appRetained.texUnitState != null) {
+ for(int j=0; j<appRetained.texUnitState.length; j++) {
+ texRetained = appRetained.texUnitState[j].texture;
+ images = texRetained.getImages();
+ if(images != null) {
+ for(int i=0; i<images.length; i++) {
+ if(images[i] != null) {
+ ImageComponentRetained imageRetained = (ImageComponentRetained) images[i].retained;
+ // Do illegal sharing check
+ if(imageRetained.getUsedByOffScreen()) {
+ throw new IllegalSharingException(J3dI18N.getString("GraphicsContext3D30"));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
uAppearance = appearance;
if ((canvas3d.view == null) ||
(canvas3d.view.universe == null) ||
@@ -591,16 +635,34 @@ public class GraphicsContext3D extends Object {
* the canvas prior to rendering a new frame. The Background
* node's application region is ignored for immediate-mode
* rendering.
+ *
* @param background the new Background object
+ *
* @exception IllegalSharingException if the Background node
* is part of or is subsequently made part of a live scene graph.
+ *
+ * @exception IllegalSharingException if the specified background node
+ * refers to an ImageComponent2D that is being used by a Canvas3D as
+ * an off-screen buffer.
*/
public void setBackground(Background background) {
+
if (background.isLive()) {
throw new IllegalSharingException(J3dI18N.getString("GraphicsContext3D11"));
}
- if (((BackgroundRetained)background.retained).geometryBranch != null)
+ BackgroundRetained bgRetained = (BackgroundRetained)background.retained;
+ ImageComponent2D image = bgRetained.getImage();
+ if(image != null) {
+ ImageComponent2DRetained imageRetained = (ImageComponent2DRetained) image.retained;
+ if(imageRetained.getUsedByOffScreen()) {
+ throw new IllegalSharingException(J3dI18N.getString("GraphicsContext3D31"));
+ }
+ }
+
+ if (((BackgroundRetained)background.retained).geometryBranch != null) {
throw new IllegalSharingException(J3dI18N.getString("GraphicsContext3D22"));
+ }
+
uBackground = background;
if ((canvas3d.view == null) ||
(canvas3d.view.universe == null) ||
@@ -1068,7 +1130,7 @@ public class GraphicsContext3D extends Object {
doSetModelTransform(t);
}
else {
- Transform3D uModelTransform = VirtualUniverse.mc.getTransform3D(t);
+ Transform3D uModelTransform = new Transform3D(t);
//Transform3D uModelTransform = t;
if (Thread.currentThread() ==
canvas3d.view.universe.behaviorScheduler) {
@@ -1102,7 +1164,7 @@ public class GraphicsContext3D extends Object {
(Thread.currentThread() == canvas3d.screen.renderer)) {
doMultiplyModelTransform(t);
} else {
- Transform3D tt = VirtualUniverse.mc.getTransform3D(t);
+ Transform3D tt = new Transform3D(t);
if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
sendRenderMessage(false, GraphicsContext3D.MULTIPLY_MODEL_TRANSFORM,
tt, null);
@@ -1604,33 +1666,33 @@ public class GraphicsContext3D extends Object {
}
void doClear() {
-
+
if (!canvas3d.firstPaintCalled)
- return;
-
- RenderBin rb = canvas3d.view.renderBin;
- BackgroundRetained back = null;
-
-
- if (this.background != null)
- back = (BackgroundRetained)this.background.retained;
- else
- back = this.black;
-
- // XXXX: This should ideally be done by the renderer (or by the
- // canvas itself) when the canvas is first added to a view.
- /*
- if ((canvas3d.screen.renderer != null) &&
- (canvas3d.screen.renderer.renderBin == null))
- canvas3d.screen.renderer.renderBin = rb;
- */
- // If we are in pure immediate mode, update the view cache
- if (!canvas3d.isRunning)
- updateViewCache(rb);
-
+ return;
+
+ RenderBin rb = canvas3d.view.renderBin;
+ BackgroundRetained back = null;
+
+
+ if (this.background != null)
+ back = (BackgroundRetained)this.background.retained;
+ else
+ back = this.black;
+
+ // XXXX: This should ideally be done by the renderer (or by the
+ // canvas itself) when the canvas is first added to a view.
+ /*
+ if ((canvas3d.screen.renderer != null) &&
+ (canvas3d.screen.renderer.renderBin == null))
+ canvas3d.screen.renderer.renderBin = rb;
+ */
+ // If we are in pure immediate mode, update the view cache
+ if (!canvas3d.isRunning)
+ updateViewCache(rb);
+
// We need to catch NullPointerException when the dsi
// gets yanked from us during a remove.
-
+
try {
// Issue 78 - need to get the drawingSurface info every
// frame; this is necessary since the HDC (window ID)
@@ -1639,215 +1701,167 @@ public class GraphicsContext3D extends Object {
if (!canvas3d.offScreen) {
canvas3d.drawingSurfaceObject.getDrawingSurfaceObjectInfo();
}
-
- if (canvas3d.drawingSurfaceObject.renderLock()) {
- // XXXX : Fix texture
- /*
- if (canvas3d.useSharedCtx) {
- if (canvas3d.screen.renderer.sharedCtx == 0) {
- synchronized (VirtualUniverse.mc.contextCreationLock) {
- canvas3d.screen.renderer.sharedCtx = canvas3d.createNewContext(
- canvas3d.screen.display,
- canvas3d.window, canvas3d.vid, 0, true,
- canvas3d.offScreen);
- canvas3d.screen.renderer.sharedCtxTimeStamp =
- VirtualUniverse.mc.getContextTimeStamp();
- canvas3d.screen.renderer.needToRebuildDisplayList = true;
- }
- }
- }
- */
-
- if (canvas3d.ctx == 0) {
- synchronized (VirtualUniverse.mc.contextCreationLock) {
- canvas3d.ctx = canvas3d.createNewContext(0, false);
- if (canvas3d.ctx == 0) {
- canvas3d.drawingSurfaceObject.unLock();
- return;
- }
-
- canvas3d.ctxTimeStamp =
- VirtualUniverse.mc.getContextTimeStamp();
- canvas3d.screen.renderer.listOfCtxs.add(
- new Long(canvas3d.ctx));
- canvas3d.screen.renderer.listOfCanvases.add(canvas3d);
-
- canvas3d.beginScene();
-
- if (canvas3d.graphics2D != null) {
- canvas3d.graphics2D.init();
- }
-
+
+ if (canvas3d.drawingSurfaceObject.renderLock()) {
+ // XXXX : Fix texture
+ /*
+ if (canvas3d.useSharedCtx) {
+ if (canvas3d.screen.renderer.sharedCtx == 0) {
+ synchronized (VirtualUniverse.mc.contextCreationLock) {
+ canvas3d.screen.renderer.sharedCtx = canvas3d.createNewContext(
+ canvas3d.screen.display,
+ canvas3d.window, 0, true,
+ canvas3d.offScreen);
+ canvas3d.screen.renderer.sharedCtxTimeStamp =
+ VirtualUniverse.mc.getContextTimeStamp();
+ canvas3d.screen.renderer.needToRebuildDisplayList = true;
+ }
+ }
+ }
+ */
+
+ if (canvas3d.ctx == null) {
+ synchronized (VirtualUniverse.mc.contextCreationLock) {
+ canvas3d.ctx = canvas3d.createNewContext(null, false);
+ if (canvas3d.ctx == null) {
+ canvas3d.drawingSurfaceObject.unLock();
+ return;
+ }
+
+ canvas3d.ctxTimeStamp =
+ VirtualUniverse.mc.getContextTimeStamp();
+ canvas3d.screen.renderer.listOfCtxs.add(canvas3d.ctx);
+ canvas3d.screen.renderer.listOfCanvases.add(canvas3d);
+
+ canvas3d.beginScene();
+
+ if (canvas3d.graphics2D != null) {
+ canvas3d.graphics2D.init();
+ }
+
// enable separate specular color
- canvas3d.enableSeparateSpecularColor();
- }
-
+ canvas3d.enableSeparateSpecularColor();
+ }
+
// create the cache texture state in canvas
// for state download checking purpose
if (canvas3d.texUnitState == null) {
canvas3d.createTexUnitState();
}
-
- // Create the texture unit state map
- if (canvas3d.texUnitStateMap == null) {
- canvas3d.createTexUnitStateMap();
+
+ canvas3d.drawingSurfaceObject.contextValidated();
+ canvas3d.screen.renderer.currentCtx = canvas3d.ctx;
+ canvas3d.screen.renderer.currentDrawable = canvas3d.drawable;
+ initializeState();
+ canvas3d.ctxChanged = true;
+ canvas3d.canvasDirty = 0xffff;
+ // Update Appearance
+ updateState(rb, RenderMolecule.SURFACE);
+
+ canvas3d.currentLights = new
+ LightRetained[canvas3d.getNumCtxLights(canvas3d.ctx)];
+
+ for (int j=0; j<canvas3d.currentLights.length; j++) {
+ canvas3d.currentLights[j] = null;
}
+ }
+
+
+ canvas3d.makeCtxCurrent();
+
+ if ((dirtyMask & BUFFER_MODE) != 0) {
+ if (bufferOverride) {
+ canvas3d.setRenderMode(canvas3d.ctx, stereoMode,
+ canvas3d.useDoubleBuffer && !frontBufferRendering);
+ } else {
+ if (!canvas3d.isRunning) {
+ canvas3d.setRenderMode(canvas3d.ctx,
+ Canvas3D.FIELD_ALL,
+ canvas3d.useDoubleBuffer);
+ }
+ }
+ dirtyMask &= ~BUFFER_MODE;
+ }
+
+ Dimension size = canvas3d.getSize();
+ int winWidth = size.width;
+ int winHeight = size.height;
+ boolean isByRefBackgroundImage = false;
+ if (back.image != null) {
+ if (back.image.isByReference()) {
+ back.image.geomLock.getLock();
+ isByRefBackgroundImage = true;
+ }
+
+ back.image.evaluateExtensions(canvas3d);
+ }
+
+ canvas3d.clear(back, winWidth, winHeight);
- canvas3d.drawingSurfaceObject.contextValidated();
- canvas3d.screen.renderer.currentCtx = canvas3d.ctx;
- canvas3d.screen.renderer.currentWindow = canvas3d.window;
- initializeState();
- canvas3d.ctxChanged = true;
- canvas3d.canvasDirty = 0xffff;
- // Update Appearance
- updateState(rb, RenderMolecule.SURFACE);
-
- canvas3d.currentLights = new
- LightRetained[canvas3d.getNumCtxLights(canvas3d.ctx)];
-
- for (int j=0; j<canvas3d.currentLights.length; j++) {
- canvas3d.currentLights[j] = null;
- }
- }
-
-
- canvas3d.makeCtxCurrent();
-
- if ((dirtyMask & BUFFER_MODE) != 0) {
- if (bufferOverride) {
- canvas3d.setRenderMode(canvas3d.ctx, stereoMode,
- canvas3d.useDoubleBuffer && !frontBufferRendering);
- } else {
- if (!canvas3d.isRunning) {
- canvas3d.setRenderMode(canvas3d.ctx,
- Canvas3D.FIELD_ALL,
- canvas3d.useDoubleBuffer);
- }
- }
- dirtyMask &= ~BUFFER_MODE;
- }
-
- Dimension size = canvas3d.getSize();
- int winWidth = size.width;
- int winHeight = size.height;
-
- if (back.image != null && back.image.isByReference()) {
- back.image.geomLock.getLock();
- back.image.evaluateExtensions(canvas3d.extensionsSupported);
- if (!VirtualUniverse.mc.isBackgroundTexture) {
- canvas3d.clear(canvas3d.ctx,
- back.color.x, back.color.y,
- back.color.z, winWidth, winHeight, back.image,
- back.imageScaleMode,
- back.image != null?back.image.imageYdown[0]:null);
- }
- else {
-
- // this is if the background image resizes with the canvas
-// Dimension size = null;
-// canvas3d.getSize(size);
-// int xmax = size.width;
-// int ymax = size.height;
- if (objectId == -1) {
- objectId = VirtualUniverse.mc.getTexture2DId();
- }
-
- canvas3d.textureclear(canvas3d.ctx,
- back.xmax, back.ymax,
- back.color.x, back.color.y,
- back.color.z, winWidth, winHeight,
- objectId, back.imageScaleMode, back.texImage, true);
- }
- back.image.geomLock.unLock();
- }
- else {
- if (!VirtualUniverse.mc.isBackgroundTexture) {
- canvas3d.clear(canvas3d.ctx,
- back.color.x, back.color.y,
- back.color.z, winWidth, winHeight, back.image,
- back.imageScaleMode,
- back.image != null?back.image.imageYdown[0]:null);
- }
- else {
-
- // this is if the background image resizes with the canvas
-// Dimension size = null;
-// canvas3d.getSize(size);
-// int xmax = size.width;
-// int ymax = size.height;
- if (objectId == -1) {
- objectId = VirtualUniverse.mc.getTexture2DId();
- }
-
- canvas3d.textureclear(canvas3d.ctx,
- back.xmax, back.ymax,
- back.color.x, back.color.y,
- back.color.z,
- winWidth, winHeight,
- objectId, back.imageScaleMode, back.texImage, true);
- }
- }
-
- // Set the viewport and view matrices
- if (!canvas3d.isRunning) {
- CanvasViewCache cvCache = canvas3d.canvasViewCache;
- canvas3d.setViewport(canvas3d.ctx,
- 0, 0,
- cvCache.getCanvasWidth(),
- cvCache.getCanvasHeight());
- if (bufferOverride && (stereoMode == STEREO_RIGHT)) {
- canvas3d.setProjectionMatrix(canvas3d.ctx,
- cvCache.getRightProjection().mat);
- canvas3d.setModelViewMatrix(canvas3d.ctx,
- cvCache.getRightVpcToEc().mat,
- rb.vworldToVpc);
- }
- else {
- canvas3d.setProjectionMatrix(canvas3d.ctx,
- cvCache.getLeftProjection().mat);
- canvas3d.setModelViewMatrix(canvas3d.ctx,
- cvCache.getLeftVpcToEc().mat,
- rb.vworldToVpc);
- }
- }
-
- canvas3d.drawingSurfaceObject.unLock();
- }
- } catch (NullPointerException ne) {
- canvas3d.drawingSurfaceObject.unLock();
- throw ne;
- }
+ if (isByRefBackgroundImage) {
+ back.image.geomLock.unLock();
+ }
+
+
+ // Set the viewport and view matrices
+ if (!canvas3d.isRunning) {
+ CanvasViewCache cvCache = canvas3d.canvasViewCache;
+ canvas3d.setViewport(canvas3d.ctx,
+ 0, 0,
+ cvCache.getCanvasWidth(),
+ cvCache.getCanvasHeight());
+ if (bufferOverride && (stereoMode == STEREO_RIGHT)) {
+ canvas3d.setProjectionMatrix(canvas3d.ctx,
+ cvCache.getRightProjection());
+ canvas3d.setModelViewMatrix(canvas3d.ctx,
+ cvCache.getRightVpcToEc().mat,
+ rb.vworldToVpc);
+ } else {
+ canvas3d.setProjectionMatrix(canvas3d.ctx,
+ cvCache.getLeftProjection());
+ canvas3d.setModelViewMatrix(canvas3d.ctx,
+ cvCache.getLeftVpcToEc().mat,
+ rb.vworldToVpc);
+ }
+ }
+
+ canvas3d.drawingSurfaceObject.unLock();
+ }
+ } catch (NullPointerException ne) {
+ canvas3d.drawingSurfaceObject.unLock();
+ throw ne;
+ }
}
-
+
// Method to update compTransform.
private void computeCompositeTransform() {
- ViewPlatform vp;
-
- if ((canvas3d == null) ||
- (canvas3d.view == null) ||
- (((vp = canvas3d.view.getViewPlatform()) == null)) ||
- (((ViewPlatformRetained)(vp.retained)) == null)) {
- compTransform.set(modelTransform);
- return;
- }
-
+ ViewPlatform vp;
+
+ if ((canvas3d == null) ||
+ (canvas3d.view == null) ||
+ (((vp = canvas3d.view.getViewPlatform()) == null)) ||
+ (((ViewPlatformRetained)(vp.retained)) == null)) {
+ compTransform.set(modelTransform);
+ return;
+ }
+
ViewPlatformRetained vpR = (ViewPlatformRetained)vp.retained;
- if ((vpR == null) || (vpR.locale == null)) {
- compTransform.set(modelTransform);
- return;
- }
-
- HiResCoord localeHiRes = vpR.locale.hiRes;
-
- if (localeHiRes.equals(hiRes)) {
- compTransform.set(modelTransform);
- } else {
- Transform3D trans = new Transform3D();
- Vector3d localeTrans = new Vector3d();
- localeHiRes.difference( hiRes, localeTrans );
- trans.setTranslation( localeTrans );
- compTransform.mul(trans, modelTransform);
- }
+ if ((vpR == null) || (vpR.locale == null)) {
+ compTransform.set(modelTransform);
+ return;
+ }
+
+ HiResCoord localeHiRes = vpR.locale.hiRes;
+
+ if (localeHiRes.equals(hiRes)) {
+ compTransform.set(modelTransform);
+ } else {
+ Transform3D trans = new Transform3D();
+ Vector3d localeTrans = new Vector3d();
+ localeHiRes.difference( hiRes, localeTrans );
+ trans.setTranslation( localeTrans );
+ compTransform.mul(trans, modelTransform);
+ }
}
// Method to update the view cache in pure immediate mode
@@ -1892,14 +1906,14 @@ public class GraphicsContext3D extends Object {
LightRetained light;
boolean lightingOn = true;
- if (canvas3d.ctx == 0) {
+ if (canvas3d.ctx == null) {
// Force an initial clear if one has not yet been done
doClear();
}
if (J3dDebug.devPhase && J3dDebug.debug) {
- J3dDebug.doAssert(canvas3d.ctx != 0, "canvas3d.ctx != 0");
+ J3dDebug.doAssert(canvas3d.ctx != null, "canvas3d.ctx != null");
}
// We need to catch NullPointerException when the dsi
@@ -1933,8 +1947,7 @@ public class GraphicsContext3D extends Object {
// (dirtyMask & BUFFER_MODE) above after testing
// PureImmediate mode
canvas3d.setProjectionMatrix(canvas3d.ctx,
- cvCache.getRightProjection().
- mat);
+ cvCache.getRightProjection());
break;
case STEREO_LEFT:
case STEREO_BOTH:
@@ -1944,8 +1957,7 @@ public class GraphicsContext3D extends Object {
// (dirtyMask & BUFFER_MODE) above after testing
// PureImmediate mode
canvas3d.setProjectionMatrix(canvas3d.ctx,
- cvCache.getLeftProjection().
- mat);
+ cvCache.getLeftProjection());
}
}
else if (!canvas3d.isRunning ||
@@ -2057,84 +2069,38 @@ public class GraphicsContext3D extends Object {
((Text3DRetained)geometry.retained).setModelViewMatrix(
vpcToEc, this.drawTransform);
drawGeo = (GeometryRetained)geometry.retained;
- } else if (geometry.retained instanceof RasterRetained) {
- ImageComponent2DRetained img = ((RasterRetained)geometry.retained).image;
- if (img != null && img.isByReference()) {
- img.geomLock.getLock();
- img.evaluateExtensions(canvas3d.extensionsSupported);
- img.geomLock.unLock();
- }
- drawGeo = (GeometryRetained)geometry.retained;
- } else {
+ } else if (geometry.retained instanceof RasterRetained) {
+ ImageComponent2DRetained img = ((RasterRetained)geometry.retained).image;
+ if (img != null) {
+ if(img.isByReference()) {
+ img.geomLock.getLock();
+ img.evaluateExtensions(canvas3d);
+ img.geomLock.unLock();
+ } else {
+ img.evaluateExtensions(canvas3d);
+ }
+ }
+ drawGeo = (GeometryRetained)geometry.retained;
+ } else {
drawGeo = (GeometryRetained)geometry.retained;
}
- if (!toSimulateMultiTex) {
drawGeo.execute(canvas3d, null, isNonUniformScale,
false, alpha,
- ((canvas3d.view.getScreens()).length > 1),
canvas3d.screen.screen,
- ignoreVertexColors,
- -1);
- } else {
- // NOTE: we really should leverage the code in textureBin
- boolean startToSimulate = false;
-
- // simulate multiple texture units
- AppearanceRetained app =
- (AppearanceRetained)appearance.retained;
-
- assert VirtualUniverse.mc.allowSimulatedMultiTexture;
- assert numActiveTexUnit > 1;
- assert app.texUnitState != null;
- assert app.texUnitState.length > 1;
-
- // first turn off fog
- if (fog != null)
- canvas3d.setFogEnableFlag(canvas3d.ctx, false);
-
- for (i = 0; i < app.texUnitState.length; i++) {
- if (app.texUnitState[i] != null &&
- app.texUnitState[i].isTextureEnabled()) {
-
- // turn on fog for the last pass
- if (i == lastActiveTexUnitIndex)
- canvas3d.setFogEnableFlag(canvas3d.ctx, true);
-
- app.texUnitState[i].updateNative(-1, canvas3d,
- false, startToSimulate);
-
- startToSimulate = true;
- drawGeo.execute(canvas3d, null,
- isNonUniformScale, false, alpha,
- ((canvas3d.view.getScreens()).length > 1),
- canvas3d.screen.screen,
- ignoreVertexColors,
- i);
- }
- }
+ ignoreVertexColors);
- // adjust the depth test back to what it was
- // and adjust the blend func to what it it was
- if (startToSimulate) {
- if (app.transparencyAttributes != null) {
- app.transparencyAttributes.updateNative(
- canvas3d.ctx, alpha, geometryType,
- polygonMode, lineAA, pointAA);
- } else {
- canvas3d.resetTransparency(canvas3d.ctx, geometryType,
- polygonMode, lineAA, pointAA);
- }
+ if (geoRetained != null) {
+ if (geoRetained.pVertexBuffers != 0) {
+ // Issue 121: always free D3D vertex buffer memory
+ // after immediate mode rendering
+ geoRetained.freeD3DArray(true);
}
- if (fog != null) {
- canvas3d.setFogEnableFlag(canvas3d.ctx, true);
- }
- }
- if (geoRetained != null)
- geoRetained.geomLock.unLock();
+ geoRetained.geomLock.unLock();
+ }
- canvas3d.drawingSurfaceObject.unLock();
+ canvas3d.drawingSurfaceObject.unLock();
}
} catch (NullPointerException ne) {
canvas3d.drawingSurfaceObject.unLock();
@@ -2145,8 +2111,25 @@ public class GraphicsContext3D extends Object {
/**
* Draw the specified Geometry component object.
* @param geometry the Geometry object to draw.
+ *
+ * @exception IllegalSharingException if the specified geometry is a
+ * Raster that refers to an ImageComponent2D that is being used by a
+ * Canvas3D as an off-screen buffer.
*/
public void draw(Geometry geometry) {
+ // do illegalSharing check
+ if((geometry != null) && (geometry instanceof Raster)) {
+ RasterRetained rasRetained = (RasterRetained) geometry.retained;
+ ImageComponent2D image = rasRetained.getImage();
+ if(image != null) {
+ ImageComponentRetained imageRetained = (ImageComponentRetained) image.retained;
+ // Do illegal sharing check
+ if(imageRetained.getUsedByOffScreen()) {
+ throw new IllegalSharingException(J3dI18N.getString("GraphicsContext3D32"));
+ }
+ }
+ }
+
if ((canvas3d.view == null) || (canvas3d.view.universe == null) ||
(!canvas3d.view.active)) {
return;
@@ -2170,10 +2153,16 @@ public class GraphicsContext3D extends Object {
* setAppearance(Appearance) and draw(Geometry) methods
* passing the appearance and geometry component objects of
* the specified shape node as arguments.
+ *
* @param shape the Shape3D node containing the Appearance component
* object to set and Geometry component object to draw
+ *
* @exception IllegalSharingException if the Shape3D node
* is part of or is subsequently made part of a live scene graph.
+ *
+ * @exception IllegalSharingException if the Shape3D node's Appearance
+ * refers to an ImageComponent2D that is being used by a
+ * Canvas3D as an off-screen buffer.
*/
public void draw(Shape3D shape) {
if (shape.isLive()) {
@@ -2185,16 +2174,6 @@ public class GraphicsContext3D extends Object {
}
/**
- * Native method for readRaster
- */
- native void readRasterNative(long d3dctx,
- int type, int xSrcOffset, int ySrcOffset,
- int width, int height, int hCanvas, int format,
- ImageComponentRetained image,
- DepthComponentRetained depth,
- GraphicsContext3D ctx);
-
- /**
* Read an image from the frame buffer and copy it into the
* ImageComponent and/or DepthComponent
* objects referenced by the specified Raster object.
@@ -2208,18 +2187,52 @@ public class GraphicsContext3D extends Object {
* @param raster the Raster object used to read the
* contents of the frame buffer
*
- * @exception IllegalArgumentException if the Raster's
- * ImageComponent2D is in by-reference mode and its RenderedImage
- * is not an instance of a BufferedImage.
+ * @exception IllegalArgumentException if the image class of the specified
+ * Raster's ImageComponent2D is <i>not</i> ImageClass.BUFFERED_IMAGE.
*
- * @exception IllegalSharingException if the Raster object
- * is part of a live scene graph.
+ * @exception IllegalArgumentException if the specified Raster's
+ * ImageComponent2D is in by-reference mode and its
+ * RenderedImage is null.
+ *
+ * @exception IllegalArgumentException if the the Raster's
+ * ImageComponent2D format
+ * is <i>not</i> a 3-component format (e.g., FORMAT_RGB)
+ * or a 4-component format (e.g., FORMAT_RGBA).
+ *
+ * @exception IllegalSharingException if the Raster object is
+ * part of a live scene graph, or if the Raster's ImageComponent2D is
+ * part of a live scene graph.
+ *
+ * @exception IllegalSharingException if the Raster's ImageComponent2D is
+ * being used by an immediate mode context, or by a Canvas3D as
+ * an off-screen buffer.
*
* @see #flush
* @see ImageComponent
* @see DepthComponent
*/
public void readRaster(Raster raster) {
+ if ((raster != null) && raster.isLive()) {
+ ImageComponent2D image = raster.getImage();
+ if (image != null){
+ ImageComponent2DRetained imageRetained = (ImageComponent2DRetained)image.retained;
+ if (image.getImageClass() != ImageComponent.ImageClass.BUFFERED_IMAGE) {
+ throw new IllegalArgumentException(J3dI18N.getString("GraphicsContext3D33"));
+ }
+ if (image.isByReference() && (image.getImage() == null)) {
+ throw new IllegalArgumentException(J3dI18N.getString("GraphicsContext3D34"));
+ }
+ if (imageRetained.getNumberOfComponents() < 3) {
+ throw new IllegalArgumentException(J3dI18N.getString("GraphicsContext3D35"));
+ }
+ if (image.isLive()) {
+ throw new IllegalSharingException(J3dI18N.getString("GraphicsContext3D36"));
+ }
+ if (imageRetained.getInImmCtx() || imageRetained.getUsedByOffScreen()) {
+ throw new IllegalSharingException(J3dI18N.getString("GraphicsContext3D37"));
+ }
+ }
+ }
if ((canvas3d.view == null) || (canvas3d.view.universe == null) ||
(!canvas3d.view.active)) {
return;
@@ -2242,122 +2255,119 @@ public class GraphicsContext3D extends Object {
}
}
-
-
void doReadRaster(Raster raster) {
-
-
- if (!canvas3d.firstPaintCalled) {
- readRasterReady = true;
- return;
- }
-
- RasterRetained ras = (RasterRetained)raster.retained;
- Dimension canvasSize = canvas3d.getSize();
- int format = 0; // Not use in case of DepthComponent read
-
- if (raster.isLive()) {
- readRasterReady = true;
- throw new IllegalSharingException(J3dI18N.getString("GraphicsContext3D21"));
+ if (!canvas3d.firstPaintCalled) {
+ readRasterReady = true;
+ return;
}
- // XXXX: implement illegal argument exception
- /*
- if (ras.image.byReference &&
- !(ras.image.imageReference instanceof BufferedImage)) {
+ RasterRetained ras = (RasterRetained)raster.retained;
+ Dimension canvasSize = canvas3d.getSize();
+ Dimension rasterSize = new Dimension();
+ ImageComponent2DRetained image = ras.image;
- throw new IllegalArgumentException(...);
- }
- */
+ int format = 0; // Not use in case of DepthComponent read
- if (canvas3d.ctx == 0) {
- // Force an initial clear if one has not yet been done
- doClear();
- }
+ if (canvas3d.ctx == null) {
+ // Force an initial clear if one has not yet been done
+ doClear();
+ }
if (J3dDebug.devPhase && J3dDebug.debug) {
- J3dDebug.doAssert(canvas3d.ctx != 0, "canvas3d.ctx != 0");
+ J3dDebug.doAssert(canvas3d.ctx != null, "canvas3d.ctx != null");
}
-
- // allocate read buffer space
+ ras.getSize(rasterSize);
+ // allocate read buffer space
if ( (ras.type & Raster.RASTER_COLOR) != 0) {
- int bpp = ras.image.getEffectiveBytesPerPixel();
- int size = ras.image.height * ras.image.width
- * bpp;
- format = ras.image.getEffectiveFormat();
- if ((ras.width > ras.image.width) ||
- (ras.height > ras.image.height)) {
- throw new RuntimeException(J3dI18N.getString("GraphicsContext3D27"));
- }
- if (byteBuffer.length < size)
- byteBuffer = new byte[size];
+ if ((rasterSize.width > ras.image.width) ||
+ (rasterSize.height > ras.image.height)) {
+ throw new RuntimeException(J3dI18N.getString("GraphicsContext3D27"));
+ }
}
if ( (ras.type & Raster.RASTER_DEPTH) != 0) {
int size = ras.depthComponent.height * ras.depthComponent.width;
- if (ras.depthComponent.type
- == DepthComponentRetained.DEPTH_COMPONENT_TYPE_FLOAT) {
+ if (ras.depthComponent.type
+ == DepthComponentRetained.DEPTH_COMPONENT_TYPE_FLOAT) {
if (floatBuffer.length < size)
floatBuffer = new float[size];
} else { // type INT or NATIVE
if (intBuffer.length < size)
intBuffer = new int[size];
}
- if ((ras.width > ras.depthComponent.width) ||
- (ras.height > ras.depthComponent.height)) {
- throw new RuntimeException(J3dI18N.getString("GraphicsContext3D28"));
- }
+ if ((rasterSize.width > ras.depthComponent.width) ||
+ (rasterSize.height > ras.depthComponent.height)) {
+ throw new RuntimeException(J3dI18N.getString("GraphicsContext3D28"));
+ }
}
-
+
if ( (ras.type & Raster.RASTER_COLOR) != 0) {
- // If by reference, check if a copy needs to be made
- // and also evaluate the storedFormat ..
- if (ras.image.isByReference()) {
- ras.image.geomLock.getLock();
- ras.image.evaluateExtensions(canvas3d.extensionsSupported);
- ras.image.geomLock.unLock();
- }
- }
+
+ // If by reference, check if a copy needs to be made
+ // and also evaluate the storedFormat ..
+ if (image.isByReference()) {
+ image.geomLock.getLock();
+ image.evaluateExtensions(canvas3d);
+ image.geomLock.unLock();
+ } else {
+ // If image has a null buffer ( BufferedImage)
+ if (image.imageData == null) {
+ image.createBlankImageData();
+ }
+ // Check for possible format conversion in imageData
+ else {
+ // Format convert imageData if format is unsupported.
+ image.evaluateExtensions(canvas3d);
+ }
+ }
+ }
// We need to catch NullPointerException when the dsi
// gets yanked from us during a remove.
try {
- if (canvas3d.drawingSurfaceObject.renderLock()) {
- // Make the context current and read the raster information
- canvas3d.makeCtxCurrent();
- canvas3d.syncRender(canvas3d.ctx, true);
- readRasterNative(canvas3d.ctx,
- ras.type, ras.xSrcOffset, ras.ySrcOffset,
- ras.width, ras.height, canvasSize.height, format,
- ras.image, ras.depthComponent, this);
- canvas3d.drawingSurfaceObject.unLock();
- }
- } catch (NullPointerException ne) {
- canvas3d.drawingSurfaceObject.unLock();
- throw ne;
- }
-
- // flip color image: yUp -> yDown and convert to BufferedImage
- if ( (ras.type & Raster.RASTER_COLOR) != 0) {
- ras.image.retrieveImage(byteBuffer, ras.width, ras.height);
+ if (canvas3d.drawingSurfaceObject.renderLock()) {
+ // Make the context current and read the raster information
+ canvas3d.makeCtxCurrent();
+ canvas3d.syncRender(canvas3d.ctx, true);
+ Point rasterSrcOffset = new Point();
+ ras.getDstOffset(rasterSrcOffset);
+
+ DepthComponentRetained depthComp = ras.depthComponent;
+ int depthType = 0;
+ if(depthComp != null) {
+ depthType = depthComp.type;
+ }
+ Pipeline.getPipeline().readRaster(canvas3d.ctx,
+ ras.type, rasterSrcOffset.x, rasterSrcOffset.y,
+ rasterSize.width, rasterSize.height, canvasSize.height,
+ image.getImageDataTypeIntValue(),
+ image.getImageFormatTypeIntValue(false),
+ image.imageData.get(),
+ depthType, depthComp);
+
+ canvas3d.drawingSurfaceObject.unLock();
+ }
+ } catch (NullPointerException ne) {
+ canvas3d.drawingSurfaceObject.unLock();
+ throw ne;
}
if ( (ras.type & Raster.RASTER_DEPTH) != 0) {
- if (ras.depthComponent.type ==
- DepthComponentRetained.DEPTH_COMPONENT_TYPE_FLOAT)
+ if (ras.depthComponent.type ==
+ DepthComponentRetained.DEPTH_COMPONENT_TYPE_FLOAT)
((DepthComponentFloatRetained)ras.depthComponent).retrieveDepth(
- floatBuffer, ras.width, ras.height);
- else if (ras.depthComponent.type ==
- DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT)
+ floatBuffer, rasterSize.width, rasterSize.height);
+ else if (ras.depthComponent.type ==
+ DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT)
((DepthComponentIntRetained)ras.depthComponent).retrieveDepth(
- intBuffer, ras.width, ras.height);
- else if (ras.depthComponent.type ==
- DepthComponentRetained.DEPTH_COMPONENT_TYPE_NATIVE)
- ((DepthComponentNativeRetained)ras.depthComponent).retrieveDepth(
- intBuffer, ras.width, ras.height);
+ intBuffer, rasterSize.width, rasterSize.height);
+ else if (ras.depthComponent.type ==
+ DepthComponentRetained.DEPTH_COMPONENT_TYPE_NATIVE)
+ ((DepthComponentNativeRetained)ras.depthComponent).retrieveDepth(
+ intBuffer, rasterSize.width, rasterSize.height);
}
- readRasterReady = true;
+ readRasterReady = true;
}
/**
@@ -2386,8 +2396,9 @@ public class GraphicsContext3D extends Object {
sendRenderMessage(true, GraphicsContext3D.FLUSH, waitArg,
null);
}
+ // Issue 131: AutomaticOffscreen canvases must be treated as onscreen ones.
if (wait && canvas3d.active && canvas3d.isRunningStatus &&
- !canvas3d.offScreen) {
+ !canvas3d.manualRendering ) {
// No need to wait if renderer thread is not schedule
runMonitor(J3dThread.WAIT);
}
@@ -2514,7 +2525,6 @@ public class GraphicsContext3D extends Object {
boolean updateState(RenderBin rb, int geometryType) {
boolean useAlpha = false;
- toSimulateMultiTex = false;
numActiveTexUnit = 0;
lastActiveTexUnitIndex = 0;
@@ -2623,24 +2633,8 @@ public class GraphicsContext3D extends Object {
// set the number active texture unit in Canvas3D
canvas3d.setNumActiveTexUnit(numActiveTexUnit);
- } else if (!useShaders && VirtualUniverse.mc.allowSimulatedMultiTexture) {
- // Simulated (multi-pass) multi-texture rendering
-
- toSimulateMultiTex = true;
-
- // will fall back to the multi-pass case;
- // reset all the texture units first
- for (int i = 0; i < prevNumActiveTexUnit; i++) {
- canvas3d.resetTexture(canvas3d.ctx, i);
- }
-
- // set the number active texture unit in Canvas3D
- canvas3d.setNumActiveTexUnit(1);
- }
- else {
- // Exceeded limit, and not using simulated multi-texture
-
- // disable all the texture units
+ } else {
+ // Exceeded limit, disable all the texture units
for (int i = 0; i < prevNumActiveTexUnit; i++) {
canvas3d.resetTexture(canvas3d.ctx, i);
}
@@ -2674,15 +2668,6 @@ public class GraphicsContext3D extends Object {
// If the image is by reference, check if the image
// should be processed
if (app.texture != null) {
- for (int f = 0; f < app.texture.numFaces; f++) {
- for (int k = 0; k < app.texture.maxLevels; k++) {
- if (app.texture.images[f][k].isByReference()) {
- app.texture.images[f][k].geomLock.getLock();
- app.texture.images[f][k].evaluateExtensions(canvas3d.extensionsSupported);
- app.texture.images[f][k].geomLock.unLock();
- }
- }
- }
app.texture.updateNative(canvas3d);
canvas3d.canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY|Canvas3D.TEXTUREATTRIBUTES_DIRTY;
numActiveTexUnit = 1;
@@ -3008,7 +2993,7 @@ public class GraphicsContext3D extends Object {
// send a message to the request renderer
- J3dMessage renderMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage renderMessage = new J3dMessage();
renderMessage.threads = J3dThread.RENDER_THREAD;
renderMessage.type = J3dMessage.RENDER_IMMEDIATE;
renderMessage.universe = null;
@@ -3041,7 +3026,7 @@ public class GraphicsContext3D extends Object {
return;
}
// send a message to the request sound scheduling
- J3dMessage soundMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage soundMessage = new J3dMessage();
soundMessage.threads = J3dThread.SOUND_SCHEDULER;
soundMessage.type = J3dMessage.RENDER_IMMEDIATE;
soundMessage.universe = canvas3d.view.universe;
diff --git a/src/classes/share/javax/media/j3d/GroupRetained.java b/src/classes/share/javax/media/j3d/GroupRetained.java
index 3861c1c..e27ff91 100644
--- a/src/classes/share/javax/media/j3d/GroupRetained.java
+++ b/src/classes/share/javax/media/j3d/GroupRetained.java
@@ -155,7 +155,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
if (source.isLive()) {
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.COLLISION_BOUND_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM |
J3dThread.UPDATE_GEOMETRY;
@@ -231,14 +231,16 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
messages = new J3dMessage[numMessages];
for (int i = 0; i < numMessages; i++) {
- messages[i] = VirtualUniverse.mc.getMessage();
+ messages[i] = new J3dMessage();
}
}
if(oldchildr != null) {
oldchildr.setParent(null);
checkClearLive(oldchildr, messages, 0, index, null);
- universe.notifyStructureChangeListeners(false, this.source, (BranchGroup)oldchildr.source);
+ if (this.source.isLive()) {
+ universe.notifyStructureChangeListeners(false, this.source, (BranchGroup)oldchildr.source);
+ }
}
removeChildrenData(index);
@@ -250,7 +252,9 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
return;
}
- universe.notifyStructureChangeListeners(true, this.source, (BranchGroup)child);
+ if (this.source.isLive()) {
+ universe.notifyStructureChangeListeners(true, this.source, (BranchGroup)child);
+ }
NodeRetained childr = (NodeRetained) child.retained;
childr.setParent(this);
children.set(index, childr);
@@ -558,7 +562,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
messages = new J3dMessage[numMessages];
for (int i=0; i<numMessages; i++) {
- messages[i] = VirtualUniverse.mc.getMessage();
+ messages[i] = new J3dMessage();
messages[i].type = J3dMessage.INVALID_TYPE;
}
@@ -600,9 +604,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
for (int i=0; i < numMessages; i++) {
if (messages[i].type != J3dMessage.INVALID_TYPE) {
ms[k++] = messages[i];
- } else {
- VirtualUniverse.mc.addMessageToFreelists(messages[i]);
- }
+ }
}
if (ms != null) {
VirtualUniverse.mc.processMessage(ms);
@@ -1363,7 +1365,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
// Since we want to update collisionVwcBounds when
// transform change in TransformStructure.
TransformGroupRetained tg;
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.threads = J3dThread.UPDATE_GEOMETRY;
message.universe = universe;
// send message to GeometryStructure to add/remove this
@@ -1567,7 +1569,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
messages = new J3dMessage[numMessages];
messageIndex = 0;
for(int mIndex=0; mIndex < numMessages; mIndex++) {
- messages[mIndex] = VirtualUniverse.mc.getMessage();
+ messages[mIndex] = new J3dMessage();
}
sendMessages = true;
}
@@ -1745,7 +1747,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
messages = new J3dMessage[numMessages];
messageIndex = 0;
for(int mIndex=0; mIndex < numMessages; mIndex++) {
- messages[mIndex] = VirtualUniverse.mc.getMessage();
+ messages[mIndex] = new J3dMessage();
}
sendMessages = true;
}
@@ -2962,7 +2964,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
if (source.isLive() && collisionBound == null && autoCompute
&& mirrorGroup != null) {
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.COLLISION_BOUND_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM |
J3dThread.UPDATE_GEOMETRY;
@@ -2978,7 +2980,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
if (source.isLive() && !boundsAutoCompute &&
collisionBound == null && mirrorGroup != null) {
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.COLLISION_BOUND_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM |
J3dThread.UPDATE_GEOMETRY;
diff --git a/src/classes/share/javax/media/j3d/IllegalRenderingStateException.java b/src/classes/share/javax/media/j3d/IllegalRenderingStateException.java
index de93adc..903ec37 100644
--- a/src/classes/share/javax/media/j3d/IllegalRenderingStateException.java
+++ b/src/classes/share/javax/media/j3d/IllegalRenderingStateException.java
@@ -13,8 +13,8 @@
package javax.media.j3d;
/**
- * Indicates an illegal state for rendering. This exception is currently
- * unused.
+ * Indicates an illegal state for rendering. This is typically some sort of
+ * resource or graphics device error encountered during rendering.
*/
public class IllegalRenderingStateException extends IllegalStateException {
diff --git a/src/classes/share/javax/media/j3d/ImageComponent.java b/src/classes/share/javax/media/j3d/ImageComponent.java
index d6ab908..deaccc1 100644
--- a/src/classes/share/javax/media/j3d/ImageComponent.java
+++ b/src/classes/share/javax/media/j3d/ImageComponent.java
@@ -161,10 +161,45 @@ public abstract class ImageComponent extends NodeComponent {
*/
public static final int FORMAT_CHANNEL8 = 10;
- // Internal variable for checking validity of formats
- // Change this if any more formats are added or removed
+ // Internal variable for checking validity of formats
+ // Change this if any more formats are added or removed
static final int FORMAT_TOTAL = 10;
+
+ /**
+ * Used to specify the class of the image being wrapped.
+ *
+ * @since Java 3D 1.5
+ */
+ public enum ImageClass {
+ /**
+ * Indicates that this ImageComponent object wraps a BufferedImage
+ * object. This is the default state. Note that the image class will
+ * be BUFFERED_IMAGE following a call to set(RenderedImage image)
+ * if we are in by-copy mode, or if the image is an instance of
+ * BufferedImage.
+ */
+ BUFFERED_IMAGE,
+
+ /**
+ * Indicates that this ImageComponent object wraps a RenderedImage
+ * object that is <i>not</i> a BufferedImage. Note that the image class
+ * of an ImageComponent following a call to set(RenderedImage image)
+ * will be RENDERED_IMAGE, if and only if the image is not an instance
+ * of BufferedImage and the ImageComponent is in by-reference mode.
+ */
+ RENDERED_IMAGE,
+
+ /**
+ * Indicates that this ImageComponent object wraps an NioImageBuffer
+ * object. Note that an ImageComponent in this state must not be used
+ * as the off-screen buffer of a Canvas3D nor as the target of a
+ * readRaster operation.
+ */
+ NIO_IMAGE_BUFFER,
+ }
+
+
/**
* Specifies that this ImageComponent object allows reading its
* size component information (width, height, and depth).
@@ -335,10 +370,21 @@ public abstract class ImageComponent extends NodeComponent {
* @exception RestrictedAccessException if the method is called
* when this object is part of live or compiled scene graph.
*
+ * @exception IllegalStateException if the image class of this object
+ * is ImageClass.NIO_IMAGE_BUFFER.
+ *
+ * @deprecated as of Java 3D 1.5, the yUp flag should only be set at object
+ * construction time.
+ *
* @since Java 3D 1.2
*/
public void setYUp(boolean yUp) {
checkForLiveOrCompiled();
+
+ // check for illegal image class
+ if (((ImageComponentRetained)this.retained).getImageClass() == ImageClass.NIO_IMAGE_BUFFER) {
+ throw new IllegalStateException("ImageComponent4");
+ }
((ImageComponentRetained)this.retained).setYUp(yUp);
}
@@ -357,4 +403,18 @@ public abstract class ImageComponent extends NodeComponent {
return ((ImageComponentRetained)this.retained).isYUp();
}
+
+ /**
+ * Retrieves the image class of this ImageComponent object.
+ *
+ * @return the image class of this ImageComponent,
+ * one of: ImageClass.BUFFERED_IMAGE,
+ * ImageClass.RENDERED_IMAGE, or ImageClass.NIO_IMAGE_BUFFER.
+ *
+ * @since Java 3D 1.5
+ */
+ public ImageClass getImageClass() {
+ return ((ImageComponentRetained)this.retained).getImageClass();
+ }
+
}
diff --git a/src/classes/share/javax/media/j3d/ImageComponent2D.java b/src/classes/share/javax/media/j3d/ImageComponent2D.java
index d46db4b..9bb31ef 100644
--- a/src/classes/share/javax/media/j3d/ImageComponent2D.java
+++ b/src/classes/share/javax/media/j3d/ImageComponent2D.java
@@ -42,6 +42,9 @@ import java.awt.image.RenderedImage;
* </code>
* </ul>
*
+ * <p>
+ * As of Java 3D 1.5, an ImageComponent2D accepts an NioImageBuffer object
+ * as an alternative to a RenderedImage.
*/
public class ImageComponent2D extends ImageComponent {
@@ -51,7 +54,12 @@ public class ImageComponent2D extends ImageComponent {
/**
* Constructs a 2D image component object using the specified
- * format, width, and height, and a null image.
+ * format, width, and height. Default values are used for
+ * all other parameters. The default values are as follows:
+ * <ul>
+ * image : null<br>
+ * imageClass : ImageClass.BUFFERED_IMAGE<br>
+ * </ul>
*
* @param format the image component format, one of: FORMAT_RGB,
* FORMAT_RGBA, etc.
@@ -72,6 +80,8 @@ public class ImageComponent2D extends ImageComponent {
/**
* Constructs a 2D image component object using the specified format
* and BufferedImage. A copy of the BufferedImage is made.
+ * The image class is set to ImageClass.BUFFERED_IMAGE.
+ * Default values are used for all other parameters.
*
* @param format the image component format, one of: FORMAT_RGB,
* FORMAT_RGBA, etc.
@@ -81,13 +91,15 @@ public class ImageComponent2D extends ImageComponent {
*/
public ImageComponent2D(int format, BufferedImage image) {
- ((ImageComponent2DRetained)this.retained).processParams(format, image.getWidth(null), image.getHeight(null), 1);
+ ((ImageComponent2DRetained)this.retained).processParams(format, image.getWidth(), image.getHeight(), 1);
((ImageComponent2DRetained)this.retained).set(image);
}
/**
* Constructs a 2D image component object using the specified format
* and RenderedImage. A copy of the RenderedImage is made.
+ * The image class is set to ImageClass.BUFFERED_IMAGE.
+ * Default values are used for all other parameters.
*
* @param format the image component format, one of: FORMAT_RGB,
* FORMAT_RGBA, etc.
@@ -106,8 +118,8 @@ public class ImageComponent2D extends ImageComponent {
/**
* Constructs a 2D image component object using the specified
- * format, width, height, byReference flag, and yUp flag, and
- * a null image.
+ * format, width, height, byReference flag, and yUp flag.
+ * Default values are used for all other parameters.
*
* @param format the image component format, one of: FORMAT_RGB,
* FORMAT_RGBA, etc.
@@ -132,7 +144,6 @@ public class ImageComponent2D extends ImageComponent {
boolean byReference,
boolean yUp) {
-
((ImageComponentRetained)this.retained).setByReference(byReference);
((ImageComponentRetained)this.retained).setYUp(yUp);
((ImageComponent2DRetained)this.retained).processParams(format, width, height, 1);
@@ -141,6 +152,7 @@ public class ImageComponent2D extends ImageComponent {
/**
* Constructs a 2D image component object using the specified format,
* BufferedImage, byReference flag, and yUp flag.
+ * The image class is set to ImageClass.BUFFERED_IMAGE.
*
* @param format the image component format, one of: FORMAT_RGB,
* FORMAT_RGBA, etc.
@@ -161,16 +173,19 @@ public class ImageComponent2D extends ImageComponent {
boolean byReference,
boolean yUp) {
-
((ImageComponentRetained)this.retained).setByReference(byReference);
((ImageComponentRetained)this.retained).setYUp(yUp);
- ((ImageComponent2DRetained)this.retained).processParams(format, image.getWidth(null), image.getHeight(null), 1);
+ ((ImageComponent2DRetained)this.retained).processParams(format, image.getWidth(), image.getHeight(), 1);
((ImageComponent2DRetained)this.retained).set(image);
}
/**
* Constructs a 2D image component object using the specified format,
* RenderedImage, byReference flag, and yUp flag.
+ * The image class is set to ImageClass.RENDERED_IMAGE if the byReferece
+ * flag is true and the specified RenderedImage is <i>not</i> an instance
+ * of BufferedImage. In all other cases, the image class is set to
+ * ImageClass.BUFFERED_IMAGE.
*
* @param format the image component format, one of: FORMAT_RGB,
* FORMAT_RGBA, etc.
@@ -187,32 +202,72 @@ public class ImageComponent2D extends ImageComponent {
* @since Java 3D 1.2
*/
public ImageComponent2D(int format,
- RenderedImage image,
- boolean byReference,
- boolean yUp) {
-
+ RenderedImage image,
+ boolean byReference,
+ boolean yUp) {
+
+ ((ImageComponentRetained)this.retained).setByReference(byReference);
+ ((ImageComponentRetained)this.retained).setYUp(yUp);
+ ((ImageComponent2DRetained)this.retained).processParams(format, image.getWidth(), image.getHeight(), 1);
+ ((ImageComponent2DRetained)this.retained).set(image);
+ }
- ((ImageComponentRetained)this.retained).setByReference(byReference);
- ((ImageComponentRetained)this.retained).setYUp(yUp);
- ((ImageComponent2DRetained)this.retained).processParams(format, image.getWidth(), image.getHeight(), 1);
- ((ImageComponent2DRetained)this.retained).set(image);
+ /**
+ * Constructs a 2D image component object using the specified format,
+ * NioImageBuffer, byReference flag, and yUp flag.
+ * The image class is set to ImageClass.NIO_IMAGE_BUFFER.
+ *
+ * @param format the image component format, one of: FORMAT_RGB,
+ * FORMAT_RGBA, etc.
+ * @param image the NioImageBuffer used to create this 2D image component
+ * @param byReference a flag that indicates whether the data is copied
+ * into this image component object or is accessed by reference.
+ * @param yUp a flag that indicates the y-orientation of this image
+ * component. If yUp is set to true, the origin of the image is
+ * the lower left; otherwise, the origin of the image is the upper
+ * left.
+ *
+ * @exception IllegalArgumentException if format is invalid, or if
+ * the width or height of the image are not positive.
+ *
+ * @exception IllegalArgumentException if the byReference flag is false.
+ *
+ * @exception IllegalArgumentException if the yUp flag is false.
+ *
+ * @since Java 3D 1.5
+ */
+ public ImageComponent2D(int format,
+ NioImageBuffer image,
+ boolean byReference,
+ boolean yUp) {
+
+ ((ImageComponentRetained)this.retained).setByReference(byReference);
+ ((ImageComponentRetained)this.retained).setYUp(yUp);
+ ((ImageComponent2DRetained)this.retained).processParams(format, image.getWidth(), image.getHeight(), 1);
+ ((ImageComponent2DRetained)this.retained).set(image);
}
/**
* Sets this image component to the specified BufferedImage
- * object. If the data access mode is not by-reference, then the
+ * object.
+ * If the data access mode is not by-reference, then the
* BufferedImage data is copied into this object. If
* the data access mode is by-reference, then a reference to the
* BufferedImage is saved, but the data is not necessarily
* copied.
+ * <p>
+ * The image class is set to ImageClass.BUFFERED_IMAGE.
*
* @param image BufferedImage object containing the image.
- * The format and size must be the same as the current format in this
+ * Its size must be the same as the current size of this
* ImageComponent2D object.
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalArgumentException if the width and height of the
+ * specified image is not equal to the width and height of this
+ * ImageComponent object.
*/
public void set(BufferedImage image) {
if (isLiveOrCompiled()) {
@@ -231,14 +286,23 @@ public class ImageComponent2D extends ImageComponent {
* the data access mode is by-reference, a reference to the
* RenderedImage is saved, but the data is not necessarily
* copied.
+ * <p>
+ * The image class is set to ImageClass.RENDERED_IMAGE if the the
+ * data access mode is by-reference and the specified
+ * RenderedImage is <i>not</i> an instance of BufferedImage. In all
+ * other cases, the image class is set to ImageClass.BUFFERED_IMAGE.
*
* @param image RenderedImage object containing the image.
- * The format and size must be the same as the current format in this
+ * Its size must be the same as the current size of this
* ImageComponent2D object.
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalArgumentException if the width and height of the
+ * specified image is not equal to the width and height of this
+ * ImageComponent object.
+ *
* @since Java 3D 1.2
*/
public void set(RenderedImage image) {
@@ -252,6 +316,43 @@ public class ImageComponent2D extends ImageComponent {
}
/**
+ * Sets this image component to the specified NioImageBuffer
+ * object. If the data access mode is not by-reference, the
+ * NioImageBuffer data is copied into this object. If
+ * the data access mode is by-reference, a reference to the
+ * NioImageBuffer is saved, but the data is not necessarily
+ * copied.
+ * <p>
+ * The image class is set to ImageClass.NIO_IMAGE_BUFFER.
+ *
+ * @param image NioImageBuffer object containing the image.
+ * Its size must be the same as the current size of this
+ * ImageComponent2D object.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalStateException if this ImageComponent object
+ * is <i>not</i> yUp.
+ *
+ * @exception IllegalArgumentException if the width and height of the
+ * specified image is not equal to the width and height of this
+ * ImageComponent object.
+ *
+ * @since Java 3D 1.5
+ */
+ public void set(NioImageBuffer image) {
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_IMAGE_WRITE)) {
+ throw new CapabilityNotSetException(
+ J3dI18N.getString("ImageComponent2D1"));
+ }
+ }
+
+ ((ImageComponent2DRetained)this.retained).set(image);
+ }
+
+ /**
* Retrieves the image from this ImageComponent2D object. If the
* data access mode is not by-reference, a copy of the image
* is made. If the data access mode is by-reference, the
@@ -264,9 +365,8 @@ public class ImageComponent2D extends ImageComponent {
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
- * @exception IllegalStateException if the data access mode is
- * by-reference and the image referenced by this ImageComponent2D
- * object is not an instance of BufferedImage.
+ * @exception IllegalStateException if the image class is not
+ * ImageClass.BUFFERED_IMAGE.
*/
public BufferedImage getImage() {
if (isLiveOrCompiled()) {
@@ -296,6 +396,9 @@ public class ImageComponent2D extends ImageComponent {
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalStateException if the image class is not one of:
+ * ImageClass.BUFFERED_IMAGE or ImageClass.RENDERED_IMAGE.
+ *
* @since Java 3D 1.2
*/
public RenderedImage getRenderedImage() {
@@ -306,6 +409,35 @@ public class ImageComponent2D extends ImageComponent {
return ((ImageComponent2DRetained)this.retained).getImage();
}
+ /**
+ * Retrieves the image from this ImageComponent2D object. If the
+ * data access mode is not by-reference, a copy of the image
+ * is made. If the data access mode is by-reference, the
+ * reference is returned.
+ *
+ * @return either a new NioImageBuffer object created from the data
+ * in this image component, or the NioImageBuffer object referenced
+ * by this image component.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalStateException if the image class is not
+ * ImageClass.NIO_IMAGE_BUFFER.
+ *
+ * @since Java 3D 1.5
+ */
+ public NioImageBuffer getNioImage() {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ImageComponent.ALLOW_IMAGE_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("ImageComponent2D0"));
+ }
+ }
+ return ((ImageComponent2DRetained)this.retained).getNioImage();
+
+ }
+
/**
* Modifies a contiguous subregion of the image component.
@@ -313,8 +445,8 @@ public class ImageComponent2D extends ImageComponent {
* starting at the offset (srcX, srcY) of the specified
* RenderedImage object will be copied into the image component
* starting at the offset (dstX, dstY) of the ImageComponent2D object.
- * The RenderedImage object must be of the same format as the current
- * format of this object.
+ * The specified RenderedImage object must be of the same format as
+ * the current RenderedImage object in this image component.
* This method can only be used if the data access mode is
* by-copy. If it is by-reference, see updateData().
*
@@ -332,15 +464,19 @@ public class ImageComponent2D extends ImageComponent {
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
+ *
* @exception IllegalStateException if the data access mode is
* <code>BY_REFERENCE</code>.
+ *
* @exception IllegalArgumentException if <code>width</code> or
* <code>height</code> of
* the subregion exceeds the dimension of the image of this object.
+ *
* @exception IllegalArgumentException if <code>dstX</code> < 0, or
* (<code>dstX</code> + <code>width</code>) > width of this object, or
* <code>dstY</code> < 0, or
* (<code>dstY</code> + <code>height</code>) > height of this object.
+ *
* @exception IllegalArgumentException if <code>srcX</code> < 0, or
* (<code>srcX</code> + <code>width</code>) > width of the RenderedImage
* object containing the subimage, or
@@ -348,6 +484,12 @@ public class ImageComponent2D extends ImageComponent {
* (<code>srcY</code> + <code>height</code>) > height of the
* RenderedImage object containing the subimage.
*
+ * @exception IllegalArgumentException if the specified RenderedImage
+ * is not compatible with the existing RenderedImage.
+ *
+ * @exception IllegalStateException if the image class is not one of:
+ * ImageClass.BUFFERED_IMAGE or ImageClass.RENDERED_IMAGE.
+ *
* @since Java 3D 1.3
*/
public void setSubImage(RenderedImage image, int width, int height,
@@ -457,7 +599,7 @@ public class ImageComponent2D extends ImageComponent {
public NodeComponent cloneNodeComponent() {
ImageComponent2DRetained rt = (ImageComponent2DRetained) retained;
- ImageComponent2D img = new ImageComponent2D(rt.format,
+ ImageComponent2D img = new ImageComponent2D(rt.getFormat(),
rt.width,
rt.height,
rt.byReference,
@@ -485,15 +627,26 @@ public class ImageComponent2D extends ImageComponent {
* @see NodeComponent#setDuplicateOnCloneTree
*/
void duplicateAttributes(NodeComponent originalNodeComponent,
- boolean forceDuplicate) {
- super.duplicateAttributes(originalNodeComponent, forceDuplicate);
-
- RenderedImage img = ((ImageComponent2DRetained)
- originalNodeComponent.retained).getImage();
-
- if (img != null) {
- ((ImageComponent2DRetained) retained).set(img);
- }
+ boolean forceDuplicate) {
+ super.duplicateAttributes(originalNodeComponent, forceDuplicate);
+
+ ImageComponent.ImageClass imageClass =
+ ((ImageComponentRetained)originalNodeComponent.retained).getImageClass();
+ if(imageClass == ImageComponent.ImageClass.NIO_IMAGE_BUFFER) {
+ NioImageBuffer nioImg = ((ImageComponent2DRetained)
+ originalNodeComponent.retained).getNioImage();
+
+ if(nioImg != null) {
+ ((ImageComponent2DRetained) retained).set(nioImg);
+ }
+ } else {
+ RenderedImage img = ((ImageComponent2DRetained)
+ originalNodeComponent.retained).getImage();
+
+ if (img != null) {
+ ((ImageComponent2DRetained) retained).set(img);
+ }
+ }
}
/**
diff --git a/src/classes/share/javax/media/j3d/ImageComponent2DRetained.java b/src/classes/share/javax/media/j3d/ImageComponent2DRetained.java
index 50680bf..b754b36 100644
--- a/src/classes/share/javax/media/j3d/ImageComponent2DRetained.java
+++ b/src/classes/share/javax/media/j3d/ImageComponent2DRetained.java
@@ -22,1238 +22,243 @@ import java.awt.color.ColorSpace;
*/
class ImageComponent2DRetained extends ImageComponentRetained {
- private int rasterRefCnt = 0; // number of raster using this object
- private int textureRefCnt = 0; // number of texture using this object
- private DetailTextureImage detailTexture = null; // will reference a
- // DetailTexture object if
- // this image is being
- // referenced as a detail image
-
- // use in D3D to map object to surface pointer
- int hashId;
- native void freeD3DSurface(int hashId);
-
- float[] lastAlpha = new float[1];
-
- static final double EPSILON = 1.0e-6;
-
- // dirty mask to track if the image has been changed since the last
- // alpha update. The nth bit in the mask represents the dirty bit
- // of the image for screen nth. If nth bit is set, then the image
- // needs to be updated with the current alpha values.
- int imageChanged = 0;
+ // used in D3D to map object to surface pointer
+ int hashId;
ImageComponent2DRetained() {
hashId = hashCode();
}
-
+
/**
- * Copies the specified BufferedImage to this 2D image component object.
- * @param image BufferedImage object containing the image.
+ * This method handles NioImageBuffer
+ * Refers or copies the specified NioImageBuffer to this 2D image component object.
+ * @param image NioImageBuffer object containing the image.
* The format and size must be the same as the current format in this
* ImageComponent2D object.
*/
- final void set(BufferedImage image) {
- int width = image.getWidth(null);
- int height = image.getHeight(null);
+ void set(NioImageBuffer image) {
- if (width != this.width)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponent2DRetained0"));
+ int width = image.getWidth();
+ int height = image.getHeight();
- if (height != this.height)
+ if (!byReference) {
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponent2D7"));
+ }
+ if (!yUp) {
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponent2D8"));
+ }
+
+ if (width != this.width) {
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponent2DRetained0"));
+ }
+ if (height != this.height) {
throw new IllegalArgumentException(J3dI18N.getString("ImageComponent2DRetained1"));
+ }
+
+ geomLock.getLock();
- int imageBytes;
- // Note, currently only EXT_ABGR and EXT_BGR are not copied, if
- // its going to be copied, do it at set time (at this time, the
- // renderer is running in parallel), if we delay it until
- // renderBin:updateObject time (when it calls evaluateExtension),
- // we are stalling the renderer
- geomLock.getLock();
- if (!byReference || (byReference && willBeCopied(image))) {
- imageBytes = height * width * bytesPerPixelIfStored;
- if (usedByTexture || ! usedByRaster) {
- // ==> (usedByTexture) || (! usedByTexture && ! usedByRaster)
-
- if (imageYup == null || imageYup.length < imageBytes) {
- imageYup = new byte[imageBytes];
- imageYupAllocated = true;
- }
-
- // buffered image -> imageYup
- storedYupFormat = internalFormat;
- bytesPerYupPixelStored = getBytesStored(storedYupFormat);
- copyImage(image, imageYup, true, 0, storedYupFormat,
- bytesPerYupPixelStored);
- imageYupClass = BUFFERED_IMAGE;
- }
-
- if (usedByRaster) {
- imageYdownClass = BUFFERED_IMAGE;
- storedYdownFormat = internalFormat;
- bytesPerYdownPixelStored = getBytesStored(storedYdownFormat);
-
- if (imageYdown[0] == null || imageYdown[0].length < imageBytes) {
- imageYdown[0] = new byte[imageBytes];
- imageYdownAllocated = true;
- }
-
- if (imageYup != null){
- //imageYup -> imageYdown
- setImageYdown(imageYup, imageYdown[0]);
- } else {
- // buffered image -> imageYdown
- copyImage(image, imageYdown[0], false, 0,
- storedYdownFormat, bytesPerYdownPixelStored);
- }
- }
- // If its byRef case, but we copied because we know that
- // the underlying native API cannot support this case!
- if (byReference) {
- bImage[0] = image;
- if (usedByTexture || !usedByRaster)
- imageYupCacheDirty = false;
- else
- imageYupCacheDirty = true;
-
- if (usedByRaster)
- imageYdownCacheDirty = false;
- else
- imageYdownCacheDirty = true;
-
- }
- else {
- imageDirty[0] = true;
- }
-
- }
- // If its by reference, then make a copy only if necessary
- else {
- imageYupCacheDirty = true;
- imageYdownCacheDirty = true;
- bImage[0] = image;
- }
- imageChanged = 0xffff;
- lastAlpha[0] = 1.0f;
- geomLock.unLock();
-
- if (source.isLive()) {
- freeSurface();
-
- // send a IMAGE_CHANGED message in order to
- // notify all the users of the change
- sendMessage(IMAGE_CHANGED, null);
- }
- }
-
-
- boolean willBeCopied(RenderedImage image) {
- return shouldImageBeCopied(getImageType(image),
- (Canvas3D.EXT_ABGR|Canvas3D.EXT_BGR), image);
- }
-
-
-
- // NOTE, IMPORTANT: any additions to the biType tested , should be added to
- // the willBeCopied() function
- final boolean shouldImageBeCopied(int biType, int ext, RenderedImage ri) {
-
- if (!byReference)
- return true;
-
- if ((((ext & Canvas3D.EXT_ABGR) != 0) &&
- ((biType == BufferedImage.TYPE_4BYTE_ABGR) &&
- (format == ImageComponent.FORMAT_RGBA8))) ||
- (((ext & Canvas3D.EXT_BGR) != 0) &&
- ((biType == BufferedImage.TYPE_3BYTE_BGR) &&
- (format == ImageComponent.FORMAT_RGB))) ||
- ((biType == BufferedImage.TYPE_BYTE_GRAY) &&
- (format == ImageComponent.FORMAT_CHANNEL8)) ||
- (is4ByteRGBAOr3ByteRGB(ri))) {
- /* ||XXXX: Don't do short for now!
- ((biType == BufferedImage.TYPE_USHORT_GRAY) &&
- (format == ImageComponent.FORMAT_CHANNEL8)
- */
-
- return false;
- }
- return true;
- }
-
- final int getStoredFormat(int biType, RenderedImage ri) {
- int f = 0;
- switch(biType) {
- case BufferedImage.TYPE_4BYTE_ABGR:
- f= BYTE_ABGR;
- break;
- case BufferedImage.TYPE_BYTE_GRAY:
- f= BYTE_GRAY;
- break;
- case BufferedImage.TYPE_USHORT_GRAY:
- f = USHORT_GRAY;
- break;
- case BufferedImage.TYPE_3BYTE_BGR:
- f = BYTE_BGR;
- break;
- case BufferedImage.TYPE_CUSTOM:
- if (is4ByteRGBAOr3ByteRGB(ri)) {
- SampleModel sm = ri.getSampleModel();
- if (sm.getNumBands() == 3) {
- f = BYTE_RGB;
- }
- else {
- f = BYTE_RGBA;
- }
- }
- break;
- default:
- // Should never come here
- }
- return f;
- }
-
- final void set(RenderedImage image) {
+ setImageClass(image);
- if (image instanceof BufferedImage) {
- set(((BufferedImage)image));
- }
- else {
- /*
- // Create a buffered image from renderImage
- ColorModel cm = image.getColorModel();
- WritableRaster wRaster = image.copyData(null);
- BufferedImage bi = new BufferedImage(cm,
- wRaster,
- cm.isAlphaPremultiplied()
- ,null);
- set(bi);
- }
- */
- int width = image.getWidth();
- int height = image.getHeight();
+ // This is a byRef image.
+ setRefImage(image,0);
- if (width != this.width)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponent2DRetained0"));
-
- if (height != this.height)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponent2DRetained1"));
-
- int imageBytes;
- // Note, currently only EXT_ABGR and EXT_BGR are not copied, if
- // its going to be copied, do it at set time (at this time, the
- // renderer is running in parallel), if we delay it until
- // renderBin:updateObject time (when it calls evaluateExtension),
- // we are stalling the renderer
- geomLock.getLock();
- if (!byReference ||(byReference && willBeCopied(image))) {
- imageBytes = height * width * bytesPerPixelIfStored;
- if (usedByTexture || ! usedByRaster) {
- if (imageYup == null || imageYup.length < imageBytes) {
- imageYup = new byte[imageBytes];
- imageYupAllocated = true;
- }
-
- // buffered image -> imageYup
- storedYupFormat = internalFormat;
- bytesPerYupPixelStored = getBytesStored(storedYupFormat);
- copyImage(image, imageYup, true, 0, storedYupFormat,
- bytesPerYupPixelStored);
- imageYupClass = BUFFERED_IMAGE;
- }
-
- if (usedByRaster) {
+ // Reset this flag to true, incase it was set to false due to
+ // the previous image type.
+ abgrSupported = true;
- imageYdownClass = BUFFERED_IMAGE;
- storedYdownFormat = internalFormat;
- bytesPerYdownPixelStored = getBytesStored(storedYdownFormat);
+ imageTypeIsSupported = isImageTypeSupported(image);
- if (imageYdown[0] == null || imageYdown[0].length < imageBytes) {
- imageYdown[0] = new byte[imageBytes];
- imageYdownAllocated = true;
- }
-
- if (imageYup != null)
- //imageYup -> imageYdown
- setImageYdown(imageYup, imageYdown[0]);
- else
- // buffered image -> imageYdown
- copyImage(image, imageYdown[0], false, 0,
- storedYdownFormat, bytesPerYdownPixelStored);
- }
- if (byReference) {
- bImage[0] = image;
- if (usedByTexture || !usedByRaster)
- imageYupCacheDirty = false;
- else
- imageYupCacheDirty = true;
-
- if (usedByRaster)
- imageYdownCacheDirty = false;
- else
- imageYdownCacheDirty = true;
- }
- else {
- imageDirty[0] = true;
- }
- }
- // If its by reference, then make a copy only if necessary
- else {
- imageYupCacheDirty = true;
- imageYdownCacheDirty = true;
- bImage[0] = image;
- }
+ if (imageTypeIsSupported) {
+
+ /* Use reference when ( format is OK, Yup is true, and byRef is true). */
+ // Create image data object with the byRef image. */
+ imageData = createNioImageBufferDataObject(image);
+
+ } else {
+ // Handle abgrSupported is false case.
+ imageData = createNioImageBufferDataObject(null);
+ copyUnsupportedNioImageToImageData(image, 0, 0, 0, 0, width, height, imageData);
- }
- imageChanged = 0xffff;
- lastAlpha[0] = 1.0f;
- geomLock.unLock();
- if (source.isLive()) {
- freeSurface();
+ }
+
+ geomLock.unLock();
+
+ if (source.isLive()) {
+ freeSurface();
+
+ // send a IMAGE_CHANGED message in order to
+ // notify all the users of the change
sendMessage(IMAGE_CHANGED, null);
- }
+ }
}
-
- /**
- * Retrieves a copy of the image in this ImageComponent2D object.
- * @return a new BufferedImage object created from the image in this
- * ImageComponent2D object
+
+ /**
+ * This method handles both BufferedImage and RenderedImage
+ * Copies the specified RenderedImage to this 2D image component object.
+ * @param image RenderedImage object containing the image.
+ * The format and size must be the same as the current format in this
+ * ImageComponent2D object.
*/
- final RenderedImage getImage() {
- if (!byReference && imageDirty[0]) {
- imageDirty[0] = false;
- retrieveBufferedImage(0);
- }
- return bImage[0];
- }
-
- // allocate storage for imageYdown
- // set imageYdown and free imageYup if necessary
- final void setRasterRef() {
- // Ref case will be handled by evaluateExtension();
- if (usedByRaster)
- return;
-
- usedByRaster = true;
-
- if (format == ImageComponent.FORMAT_CHANNEL8)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponent2DRetained2"));
-
- if (!byReference) {
- if (imageYdown[0] == null && imageYup != null) {
- imageYdown[0] = new byte[height * width * bytesPerYupPixelStored];
- imageYdownAllocated = true;
-
- // imageYup -> imageYdown
- imageYdownClass = BUFFERED_IMAGE;
- storedYdownFormat = storedYupFormat;
- bytesPerYdownPixelStored = bytesPerYupPixelStored;
- setImageYdown(imageYup, imageYdown[0]);
- }
- if (usedByTexture == false) {
- imageYup = null;
- imageYupAllocated = false;
- }
-
- }
- else {
- if (willBeCopied(bImage[0])) {
- geomLock.getLock();
- if (imageYdownCacheDirty) {
- if (imageYdown[0] == null) {
-
- if (imageYup != null) {
- storedYdownFormat = storedYupFormat;
- bytesPerYdownPixelStored = bytesPerYupPixelStored;
- imageYdown[0] =new byte[height*width *bytesPerYdownPixelStored];
- setImageYdown(imageYup, imageYdown[0]);
- }
- else {
- imageYdown[0] = new byte[height * width * bytesPerPixelIfStored];
- bytesPerYdownPixelStored = bytesPerPixelIfStored;
- storedYdownFormat = internalFormat;
-
- if (bImage[0] instanceof BufferedImage) {
- copyImage(((BufferedImage)bImage[0]),
- imageYdown[0], false, 0,
- storedYdownFormat,
- bytesPerYdownPixelStored);
- }
- else {
- copyImage(bImage[0], imageYdown[0], false, 0,
- storedYdownFormat,
- bytesPerYdownPixelStored);
- }
- }
- imageYdownClass = BUFFERED_IMAGE;
- imageYdownAllocated = true;
- }
- imageYdownCacheDirty = false;
- }
- geomLock.unLock();
- }
- else {
- geomLock.getLock();
- imageYdownCacheDirty = true;
- geomLock.unLock();
- }
- /*
- // Can't do this - since I don't know which extension
- // will be supported, if Ydown is going away then
- // this code will be useful
- else if (yUp) {
- geomLock.getLock();
- if (imageYdownCacheDirty) {
- storeRasterImageWithFlip(bImage[0]);
- imageYdownCacheDirty = false;
- }
- geomLock.unLock();
- }
- */
- }
- }
-
- // allocate storage for imageYup
- // set imageYup and free imageYdown if necessary
- final void setTextureRef() {
- // Ref case will be handled by evaluateExtension();
- if (usedByTexture)
- return;
-
- usedByTexture = true;
-
- if (!byReference) {
-
- if (imageYup == null && imageYdown[0] != null) {
- storedYupFormat = storedYdownFormat;
- bytesPerYupPixelStored = bytesPerYdownPixelStored;
- imageYup = new byte[height * width * bytesPerYupPixelStored];
- // imageYdown -> imageYup
- setImageYup(imageYdown[0], imageYup);
- imageYupClass = BUFFERED_IMAGE;
- imageYupAllocated = true;
- }
- if (usedByRaster == false) {
- imageYdown[0] = null;
- imageYdownAllocated = false;
- }
-
- }
- // If the image will not be stored by reference, because
- // the format is not supported by the underlying API
- else {
- if (willBeCopied(bImage[0])) {
- geomLock.getLock();
- if (imageYupCacheDirty) {
- if (imageYup == null) {
- if (imageYdown[0] != null) {
- // imageYdown -> imageYup
- storedYupFormat = storedYdownFormat;
- bytesPerYupPixelStored = bytesPerYdownPixelStored;
- imageYup = new byte[height * width * bytesPerYupPixelStored];
- setImageYup(imageYdown[0], imageYup);
- }
- else {
- imageYup = new byte[height * width * bytesPerPixelIfStored];
- bytesPerYupPixelStored = bytesPerPixelIfStored;
- storedYupFormat = internalFormat;
-
- if (bImage[0] instanceof BufferedImage) {
- copyImage(((BufferedImage)bImage[0]), imageYup,
- true, 0, storedYupFormat,
- bytesPerYupPixelStored);
- }
- else {
- copyImage(bImage[0], imageYup, true, 0,
- storedYupFormat,
- bytesPerYupPixelStored);
- }
- }
- imageYupClass = BUFFERED_IMAGE;
- imageYupAllocated = true;
- }
- imageYupCacheDirty = false;
- }
- geomLock.unLock();
- }
- else {
- geomLock.getLock();
- imageYupCacheDirty = true;
- geomLock.unLock();
- }
- /*
- // Can't do this - since I don't know which extension
- // will be supported, if Ydown is going away then
- // this code will be useful
-
- // If Image will not be stored by reference because
- // of wrong orienetation
- else if (!yUp) {
- geomLock.getLock();
- if (imageYupCacheDirty) {
- storeTextureImageWithFlip(bImage[0]);
- imageYupCacheDirty = false;
- }
- geomLock.unLock();
- }
- */
- }
-
- }
-
-
- // copy imageYup to imageYdown in reverse scanline order
- final void setImageYdown(byte[] src, byte[] dst) {
- int scanLineSize = width * bytesPerYdownPixelStored;
- int srcOffset, dstOffset, i;
-
- for (srcOffset = (height - 1) * scanLineSize, dstOffset = 0,
- i = 0; i < height; i++,
- srcOffset -= scanLineSize, dstOffset += scanLineSize) {
-
- System.arraycopy(src, srcOffset, dst, dstOffset,
- scanLineSize);
+ void set(RenderedImage image) {
+
+ int width = image.getWidth();
+ int height = image.getHeight();
+
+ if (width != this.width) {
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponent2DRetained0"));
}
-
- }
-
- // Preserve the incoming format of thre renderImage, but maybe
- // flip the image or make a plain copy
- // Used only for raster
- final void copyRImage(RenderedImage image, byte[] dst, boolean flip,
- int bPerPixel) {
-
- int numX = image.getNumXTiles();
- int numY = image.getNumYTiles();
- int tilew = image.getTileWidth();
- int tileh = image.getTileHeight();
- int i, j, h;
- java.awt.image.Raster ras;
- int tileLineBytes = tilew * bPerPixel;
- int x = image.getMinTileX();
- int y = image.getMinTileY();
- int srcOffset, dstOffset;
- int dstLineBytes = 0;
- int tileStart;
- int tileBytes = tileh * tilew * numX * bPerPixel;
- int dstStart;
- int tmph, tmpw, curw, curh;
- int rowOffset, colOffset;
- int sign;
-
- if (flip) {
- dstLineBytes =width * bPerPixel;
- tileStart = (height - 1) * dstLineBytes;
- dstLineBytes = -(dstLineBytes);
- }
- else {
- tileStart = 0;
- dstLineBytes = width * bPerPixel;
- }
- // convert from Ydown to Yup for texture
- int minX = image.getMinX();
- int minY = image.getMinY();
- int xoff = image.getTileGridXOffset();
- int yoff = image.getTileGridYOffset();
- int endXTile = x * tilew + xoff+tilew;
- int endYTile = y * tileh + yoff+tileh;
- tmpw = width;
- tmph = height;
- // Check if the width is less than the tile itself ..
- curw = (endXTile - minX);
- curh = (endYTile - minY);
-
- if (tmpw < curw) {
- curw = tmpw;
- }
-
- if (tmph < curh) {
- curh = tmph;
- }
- int startw = curw ;
-
- rowOffset = (tilew - curw) * bPerPixel;
- colOffset = tilew * (tileh - curh) * bPerPixel;
- int bytesCopied = 0;
- srcOffset = rowOffset + colOffset;
-
-
- for (i = y; i < y+numY; i++) {
- dstStart = tileStart;
- curw = startw;
- tmpw = width;
- for (j = x; j < x+numX; j++) {
- ras = image.getTile(j,i);
- byte[] src = ((DataBufferByte)ras.getDataBuffer()).getData();
- dstOffset = dstStart;
- bytesCopied = curw * bPerPixel;
- for (h = 0;h < curh; h++) {
- System.arraycopy(src, srcOffset, dst, dstOffset,
- bytesCopied);
- srcOffset += tileLineBytes;
- dstOffset += dstLineBytes;
- }
- srcOffset = colOffset;
- dstStart += curw * bPerPixel;
- tmpw -= curw;
- if (tmpw < tilew)
- curw = tmpw;
- else
- curw = tilew;
- }
- srcOffset = rowOffset;
- colOffset = 0;
- tileStart += curh * dstLineBytes;
- tmph -= curh;
- if (tmph < tileh)
- curh = tmph;
- else
- curh = tileh;
- }
- }
-
- // copy imageYdown to imageYup in reverse scanline order
- final void setImageYup(byte[] src, byte[] dst) {
- int scanLineSize = width * bytesPerYupPixelStored;
- int srcOffset, dstOffset, i;
-
- for (srcOffset = 0, dstOffset = (height - 1) * scanLineSize,
- i = 0; i < height; i++,
- srcOffset += scanLineSize, dstOffset -= scanLineSize) {
-
- System.arraycopy(src, srcOffset, dst, dstOffset,
- scanLineSize);
+ if (height != this.height) {
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponent2DRetained1"));
+ }
+
+ setImageClass(image);
+
+ geomLock.getLock();
+
+ if (byReference) {
+ setRefImage(image,0);
+ }
+
+ // Reset this flag to true, incase it was set to false due to
+ // the previous image type.
+ abgrSupported = true;
+
+ imageTypeIsSupported = isImageTypeSupported(image);
+
+ if (imageTypeIsSupported) {
+
+ if (byReference && yUp) {
+ /* Use reference when ( format is OK, Yup is true, and byRef is true). */
+ // System.err.println("ImageComponent2DRetained.set() : (imageTypeSupported && byReference && yUp) --- (1)");
+ if (image instanceof BufferedImage) {
+ // Create image data object with the byRef image. */
+ imageData = createRenderedImageDataObject(image);
+ }
+ else {
+ // System.err.println("byRef and not BufferedImage !!!");
+ imageData = null;
+ }
+
+ } else {
+ // Either not byRef or not yUp or not both
+ // System.err.println("ImageComponent2DRetained.set() : (imageTypeSupported && ((!byReference && yUp) || (imageTypeSupported && !yUp)) --- (2)");
+
+ // Create image data object with buffer for image. */
+ imageData = createRenderedImageDataObject(null);
+ copySupportedImageToImageData(image, 0, imageData);
+ }
+
+ } else {
+ // image type is unsupported, need to create a supported local copy.
+ // TODO : borrow code from JAI to convert to right format.
+ // System.err.println("ImageComponent2DRetained.set() : (imageTypeSupported == false) --- (4)");
+ /* Will use the code segment in copy() method */
+
+ // Create image data object with buffer for image. */
+ imageData = createRenderedImageDataObject(null);
+ copyUnsupportedImageToImageData(image, 0, imageData);
+
+ }
+
+ geomLock.unLock();
+
+ if (source.isLive()) {
+ freeSurface();
+
+ // send a IMAGE_CHANGED message in order to
+ // notify all the users of the change
+ sendMessage(IMAGE_CHANGED, null);
}
}
- // Lock out user thread from modifying usedByRaster and
- // usedByTexture variables by using synchronized routines
- final void evaluateExtensions(int ext) {
- int i;
- int imageBytes;
- RenderedImage image = bImage[0];
-
- // System.out.println("!!!!!!!!!!!!!imageYupCacheDirty = "+imageYupCacheDirty);
- // System.out.println("!!!!!!!!!!!!!imageYdownCacheDirty = "+imageYdownCacheDirty);
- // System.out.println("!!!!!!!!!!!!!usedByTexture = "+usedByTexture);
- // System.out.println("!!!!!!!!!!!!!usedByRaster = "+usedByRaster);
-
-
- if (!imageYupCacheDirty && !imageYdownCacheDirty) {
- return;
- }
-
- int riType = getImageType(image);
-
- // Thread.dumpStack();
- if (usedByTexture == true || ! usedByRaster) {
- // If the image is already allocated, then return
- // nothing to do!
- // Since this is a new image, the app may have changed the image
- // when it was not live, so re-compute, until the image is allocated
- // for this pass!
- // System.out.println("!!!!!!!!!!!!!imageYupCacheDirty = "+imageYupCacheDirty);
- if (!imageYupCacheDirty) {
- evaluateRaster(riType, ext);
- return;
- }
- if (shouldImageBeCopied(riType, ext, image)) {
-
- imageBytes = height * width * bytesPerPixelIfStored;
- if (imageYup == null || !imageYupAllocated) {
- imageYup = new byte[imageBytes];
- imageYupAllocated = true;
- }
- // buffered image -> imageYup
- bytesPerYupPixelStored = bytesPerPixelIfStored;
- storedYupFormat = internalFormat;
- copyImage(image, imageYup, true, 0,
- storedYupFormat, bytesPerYupPixelStored);
- imageYupClass = BUFFERED_IMAGE;
- imageYupCacheDirty = false;
- }
- else {
- // This image is already valid ..
- if (!imageYupCacheDirty) {
- evaluateRaster(riType, ext);
- return;
- }
- storedYupFormat = getStoredFormat(riType, image);
- bytesPerYupPixelStored = getBytesStored(storedYupFormat);
-
- // It does not have to be copied, but we
- // have to copy because the incoming image is
- // ydown
- if (!yUp) {
- storeTextureImageWithFlip(image);
- }
- else {
- if (image instanceof BufferedImage) {
- byte[] tmpImage = ((DataBufferByte)((BufferedImage)image).getRaster().getDataBuffer()).getData();
- imageYup = tmpImage;
- imageYupAllocated = false;
- imageYupClass = BUFFERED_IMAGE;
- }
- else {
- numXTiles = image.getNumXTiles();
- numYTiles = image.getNumYTiles();
- tilew = image.getTileWidth();
- tileh = image.getTileHeight();
- minTileX = image.getMinTileX();
- minTileY = image.getMinTileY();
- minX = image.getMinX();
- minY = image.getMinY();
- tileGridXOffset =image.getTileGridXOffset();
- tileGridYOffset = image.getTileGridYOffset();
- imageYupAllocated = false;
- imageYupClass = RENDERED_IMAGE;
- imageYup = null;
- }
- }
-
- }
- if (usedByRaster == false) {
- imageYdown[0] = null;
- imageYdownAllocated = false;
- }
- }
- evaluateRaster(riType, ext);
- }
-
- void evaluateRaster(int riType, int ext) {
- int i;
- int imageBytes;
- RenderedImage image = bImage[0];
-
- if (usedByRaster) {
- // If the image is already allocated, then return
- // nothing to do!
- if (!imageYdownCacheDirty) {
- return;
- }
- if (shouldImageBeCopied(riType, ext, image)) {
- // System.out.println("Raster Image is copied");
- imageBytes = height * width * bytesPerPixelIfStored;
- if (imageYdown[0] == null || !imageYdownAllocated || imageYdown[0].length < imageBytes){
- imageYdown[0] = new byte[imageBytes];
- imageYdownAllocated = true;
- }
- if (imageYup != null) {
- storedYdownFormat = storedYupFormat;
- bytesPerYdownPixelStored = bytesPerYupPixelStored;
- setImageYdown(imageYup, imageYdown[0]);
- }
- else {
- // buffered image -> imageYup
- storedYdownFormat = internalFormat;
- bytesPerYdownPixelStored = bytesPerPixelIfStored;
- copyImage(image, imageYdown[0], false, 0,
- storedYdownFormat, bytesPerYdownPixelStored);
- }
- imageYdownCacheDirty = false;
- imageYdownClass = BUFFERED_IMAGE;
- }
- else {
- // This image is already valid ..
- if (!imageYdownCacheDirty) {
- return;
- }
- storedYdownFormat = getStoredFormat(riType, image);
- bytesPerYdownPixelStored = getBytesStored(storedYdownFormat);
- if (yUp) {
- storeRasterImageWithFlip(image);
- }
- else {
- if (image instanceof BufferedImage) {
- byte[] tmpImage = ((DataBufferByte)((BufferedImage)image).getRaster().getDataBuffer()).getData();
- imageYdown[0] = tmpImage;
- imageYdownAllocated = false;
- imageYdownClass = BUFFERED_IMAGE;
- // System.out.println("Raster Image is stored by ref");
- }
- else {
- // Right now, always copy since opengl rasterpos is
- // too restrictive
- imageBytes = width*height*bytesPerYdownPixelStored;
- if (imageYdown[0] == null || !imageYdownAllocated ||imageYdown[0].length < imageBytes){
- imageYdown[0] = new byte[imageBytes];
- imageYdownAllocated = true;
- }
- imageYdownClass = BUFFERED_IMAGE;
- copyRImage(image,imageYdown[0], false, bytesPerYdownPixelStored);
- // System.out.println("Copying by ref RImage");
-
- /*
- numXTiles = image.getNumXTiles();
- numYTiles = image.getNumYTiles();
- tilew = image.getTileWidth();
- tileh = image.getTileHeight();
- minTileX = image.getMinTileX();
- minTileY = image.getMinTileY();
- imageYdownAllocated = false;
- imageYdownClass = RENDERED_IMAGE;
- imageYdown = null;
- */
- }
- imageYdownCacheDirty = false;
- }
-
-
- }
- if (usedByTexture == false) {
- imageYup = null;
- imageYupAllocated = false;
- }
- }
- }
-
- void storeRasterImageWithFlip(RenderedImage image) {
- int imageBytes;
-
- if (image instanceof BufferedImage) {
- imageBytes = width*height*bytesPerYdownPixelStored;
- if (imageYdown[0] == null || !imageYdownAllocated ||imageYdown[0].length < imageBytes){
- imageYdown[0] = new byte[imageBytes];
- imageYdownAllocated = true;
- }
- imageYdownClass = BUFFERED_IMAGE;
- imageYdownCacheDirty = false;
- byte[] tmpImage = ((DataBufferByte)((BufferedImage)image).getRaster().getDataBuffer()).getData();
- setImageYdown(tmpImage, imageYdown[0]);
- }
- else {
- // Right now, always copy since opengl rasterpos is
- // too restrictive
-
- imageBytes = width*height*bytesPerYdownPixelStored;
- if (imageYdown[0] == null || !imageYdownAllocated ||imageYdown[0].length < imageBytes){
- imageYdown[0] = new byte[imageBytes];
- imageYdownAllocated = true;
- }
- imageYdownClass = BUFFERED_IMAGE;
- imageYdownCacheDirty = false;
- copyRImage(image, imageYdown[0], true, bytesPerYdownPixelStored);
- }
- }
-
- void storeTextureImageWithFlip(RenderedImage image) {
- int imageBytes;
-
- if (image instanceof BufferedImage) {
- byte[] tmpImage = ((DataBufferByte)((BufferedImage)image).getRaster().getDataBuffer()).getData();
-
- if (imageYup == null || !imageYupAllocated) {
- imageBytes = width*height*bytesPerYupPixelStored;
- imageYup = new byte[imageBytes];
- imageYupAllocated = true;
- }
- imageYupClass = BUFFERED_IMAGE;
- setImageYup(tmpImage, imageYup);
- imageYupCacheDirty = false;
-
- }
- else {
- if (imageYup == null || !imageYupAllocated) {
- imageBytes = width*height*bytesPerYupPixelStored;
- imageYup = new byte[imageBytes];
- imageYupAllocated = true;
- }
- imageYupClass = BUFFERED_IMAGE;
- copyRImage(image, imageYup, true, bytesPerYupPixelStored);
- imageYupCacheDirty = false;
- }
- }
-
- void setLive(boolean inBackgroundGroup, int refCount) {
- super.setLive(inBackgroundGroup, refCount);
- }
-
- void clearLive(int refCount) {
- super.clearLive(refCount);
- if (this.refCount <= 0) {
- freeSurface();
- }
- }
-
- void freeSurface() {
- if (VirtualUniverse.mc.isD3D()) {
- freeD3DSurface(hashId);
- }
- }
-
- protected void finalize() {
- // For Pure immediate mode, there is no clearLive so
- // surface will free when JVM do GC
- freeSurface();
- }
- void updateAlpha(Canvas3D cv, int screen, float alpha) {
- // if alpha is smaller than EPSILON, set it to EPSILON, so that
- // even if alpha is equal to 0, we will not completely lose
- int i, j;
- byte byteAlpha;
- float rndoff = 0.0f;
-
- // the original alpha value
- if (alpha <= EPSILON) {
- alpha = (float)EPSILON;
- }
- // System.out.println("========> updateAlpha, this = "+this);
- // Lock out the other renderers ..
- synchronized (this) {
- // If by reference, the image has been copied, but aset has occured
- // or if the format is not RGBA, then copy
- // Thread.dumpStack();
- if (isByReference() && ((storedYdownFormat != internalFormat) || ((imageChanged & 1) != 0))) {
- int imageBytes = height * width * bytesPerPixelIfStored;
- if (imageYdown[0] == null || !imageYdownAllocated|| imageYdown[0].length < imageBytes)
- imageYdown[0] = new byte[imageBytes];
- bytesPerYdownPixelStored = bytesPerPixelIfStored;
- storedYdownFormat = internalFormat;
- copyImage(bImage[0],imageYdown[0], false, 0,
- storedYdownFormat, bytesPerYdownPixelStored);
- imageYdownCacheDirty = false;
- imageYdownClass = BUFFERED_IMAGE;
- imageYdownAllocated = true;
- imageChanged &= ~1;
- freeSurface();
- }
-
- // allocate an entry for the last alpha of the screen if needed
- if (lastAlpha == null) {
- lastAlpha = new float[screen+1];
- lastAlpha[screen] = 1.0f;
- }
- else if (lastAlpha.length <= screen) {
- float[] la = new float[screen+1];
- for (i = 0; i < lastAlpha.length; i++) {
- la[i] = lastAlpha[i];
- }
- lastAlpha = la;
- lastAlpha[screen] = 1.0f;
- }
- // allocate a copy of the color data for the screen if needed.
- // this piece of code is mainly for multi-screens case
- if (imageYdown.length <= screen) {
- byte[][] bdata = new byte[screen+1][];
- byte[] idata;
- int refScreen = -1;
-
- int imageBytes = height * width * bytesPerYdownPixelStored;
- idata = bdata[screen] = new byte[imageBytes];
- for (i = 0; i < imageYdown.length; i++) {
- bdata[i] = imageYdown[i];
- if (Math.abs(lastAlpha[i] - alpha) < EPSILON) {
- refScreen = i;
- }
- }
-
- if (noAlpha) {
- byteAlpha = (byte) (alpha * 255.0f + 0.5);
- for (j=3,i=0; i< width * height; i++,j+=4) {
- idata[j] = byteAlpha;
- }
- }
- else {
-
- // copy the data from a reference screen which has the closest
- // alpha values
- if (refScreen >= 0) {
- System.arraycopy(imageYdown[refScreen], 0, idata, 0, imageBytes);
- lastAlpha[screen] = lastAlpha[refScreen];
- }
- else {
- float m = alpha/lastAlpha[0];
- if (m < 1.0f)
- rndoff = 0.5f;
- else
- rndoff = -0.5f;
-
- byte[] srcData = imageYdown[0];
- for (i = 0, j = 0; i < width * height; i++, j+= 4) {
- System.arraycopy(srcData, j, idata, j, 3);
- idata[j+3] =(byte)( ((int)srcData[j+3] & 0xff) * m + rndoff);
- }
- lastAlpha[screen] = alpha;
- }
- }
- imageYdown = bdata;
-
- imageChanged &= ~(1 << screen);
- freeSurface();
- return;
- }
+ void setSubImage(RenderedImage image, int width, int height,
+ int srcX, int srcY, int dstX, int dstY) {
- if ((imageChanged & (1<< screen)) == 0) {
- // color data is not modified
- // if alpha is different, update the alpha values
- int val = -1;
- if (Math.abs(lastAlpha[screen] - alpha) > EPSILON) {
- byte[] idata = imageYdown[screen];
- if (noAlpha) {
- byteAlpha = (byte) (alpha * 255.0f + 0.5);
- for (j=3,i=0; i< width * height; i++,j+=4) {
- idata[j] = byteAlpha;
- }
- }
- else {
- float m = alpha/lastAlpha[screen];
- if (m < 1.0f)
- rndoff = 0.5f;
- else
- rndoff = -0.5f;
-
- for (i = 0, j = 3; i < width * height; i++, j+= 4) {
- idata[j] =(byte)( ((int)idata[j] & 0xff) * m + rndoff);
- }
- }
- freeSurface();
- }
- }
- else {
- // color data is modified
- if (screen == 0) {
- // just update alpha values since screen 0 data is
- // already updated in copyImage()
- byte[] idata = imageYdown[0];
- if (noAlpha) {
- byteAlpha = (byte) (alpha * 255.0f + 0.5);
- for (j=3,i=0; i< width * height; i++,j+=4) {
- idata[j] = byteAlpha;
- }
- }
- else {
- for (i = 0, j = 3; i < width * height; i++, j+= 4) {
- idata[j] =(byte)( ((int)idata[j] & 0xff) * alpha + 0.5);
- }
- }
-
- }
- else {
- // update color values from screen 0 data
- float m;
- byte[] ddata = imageYdown[screen];
- if (noAlpha) {
- byteAlpha = (byte) (alpha * 255.0f + 0.5);
- for (j=3,i=0; i< width * height; i++,j+=4) {
- ddata[j] = byteAlpha;
- }
- }
- else {
- if ((imageChanged & 1) == 0) {
- // alpha is up to date in screen 0
- m = alpha / lastAlpha[0];
- }
- else {
- m = alpha;
- }
+ if (!isSubImageTypeEqual(image)) {
+ throw new IllegalStateException(
+ J3dI18N.getString("ImageComponent2D6"));
+ }
- if (m < 1.0f)
- rndoff = 0.5f;
- else
- rndoff = -0.5f;
+ // Can't be byReference
+ assert (!byReference);
+ assert (imageData != null);
+
+ geomLock.getLock();
+
+ if (imageTypeIsSupported) {
+ // Either not byRef or not yUp or not both
+ // System.err.println("ImageComponent2DRetained.setSubImage() : (imageTypeSupported ) --- (1)");
+ if (image instanceof BufferedImage) {
+ copyImageLineByLine((BufferedImage)image, srcX, srcY, dstX, dstY, 0, width, height, imageData);
+ }
+ else {
+ copySupportedImageToImageData(image, srcX, srcY, dstX, dstY, 0, width, height, imageData);
+ }
+ } else {
+ // image type is unsupported, need to create a supported local copy.
+ // TODO : Should look into borrow code from JAI to convert to right format.
+ // System.err.println("ImageComponent2DRetained.setSubImage() : (imageTypeSupported == false) --- (2)");
+ if (image instanceof BufferedImage) {
+ copyUnsupportedImageToImageData((BufferedImage)image, srcX, srcY, dstX, dstY, 0, width, height, imageData);
+ }
+ else {
+ copyUnsupportedImageToImageData(image, srcX, srcY, dstX, dstY, 0, width, height, imageData);
+ }
+ }
+ geomLock.unLock();
- byte[] sdata = imageYdown[0];
+ if (source.isLive()) {
- for (i = 0, j = 0; i < width * height; i++, j+= 4) {
- System.arraycopy(sdata, j, ddata, j, 3);
- ddata[j+3] =(byte)( ((int)sdata[j+3] & 0xff) * m + rndoff);
- }
- }
- }
- freeSurface();
- }
- lastAlpha[screen] = alpha;
- imageChanged &= ~(1 << screen);
- }
- }
+ // XXXX: check whether this is needed
+ freeSurface();
+ // send a SUBIMAGE_CHANGED message in order to
+ // notify all the users of the change
- int getEffectiveBytesPerPixel() {
- if (byReference) {
- if (usedByTexture || !usedByRaster)
- return bytesPerYupPixelStored;
- else
- return bytesPerYdownPixelStored;
- }
- else {
- return bytesPerPixelIfStored;
- }
- }
+ ImageComponentUpdateInfo info;
+ info = new ImageComponentUpdateInfo();
+ info.x = dstX;
+ info.y = dstY;
+ info.z = 0;
+ info.width = width;
+ info.height = height;
- int getEffectiveFormat() {
- if (byReference) {
- if (usedByTexture || !usedByRaster)
- return storedYupFormat;
- else
- return storedYdownFormat;
- }
- else {
- return internalFormat;
- }
- }
+ sendMessage(SUBIMAGE_CHANGED, info);
+ }
+ }
/**
- * retrieve image data from read buffer to ImageComponent's
- * internal representation
- */
- final void retrieveImage(byte[] buf, int wRead, int hRead) {
- retrieveImage(buf, 0, 0, wRead, hRead);
+ * Retrieves a copy of the image in this ImageComponent2D object.
+ * @return a new RenderedImage object created from the image in this
+ * ImageComponent2D object
+ */
+ RenderedImage getImage() {
+
+ if (isByReference()) {
+ return (RenderedImage) getRefImage(0);
+ }
+
+ if(imageData != null) {
+ return imageData.createBufferedImage(0);
+ }
+
+ return null;
}
-
/**
- * retrieve a subimage data from read buffer to ImageComponent's
- * internal representation
- */
- final void retrieveImage(byte[] buf, int xRead, int yRead, int
- wRead, int hRead) {
-
- int srcOffset, dstOffset, h,w,i,j;
- int dstWidth;
-
- byte[] bdata;
-
-
- // If byReference, then copy to the reference image immediately after
- // readRaster or offscreenbuffer
-
- // In the by reference case, they should have set and image, before
- // calling readRaster, so there should be a valid imageYup or imageYdown
- // as used by texture or raster
-
- // Note the format of the glReadPixels is based on storedFormat
- // so, we can do a direct copy
-
- int bpp = getEffectiveBytesPerPixel();
- int format = getEffectiveFormat();
-
- if (!byReference) {
-
- dstWidth = width * bytesPerPixelIfStored;
- if ((usedByTexture || !usedByRaster)&& (imageYup == null)) {
- imageYup = new byte[height * dstWidth];
- bytesPerYupPixelStored = bytesPerPixelIfStored;
- storedYupFormat = internalFormat;
- imageYupAllocated = true;
- }
- if (usedByRaster && imageYdown[0] == null) {
- imageYdown[0] = new byte[height * dstWidth];
- bytesPerYdownPixelStored = bytesPerPixelIfStored;
- storedYdownFormat = internalFormat;
- imageYdownAllocated = true;
- }
- }
-
-
- int srcWidth = wRead * bpp;
- int srcLineBytes = width * bpp;
-
- /*
- System.out.println("bytesPerYdownPixelStored = "+bytesPerYdownPixelStored+" bpp = "+bpp);
- System.out.println("storedYdownFormat = "+storedYdownFormat+" format = "+format);
- System.out.println("bytesPerPixelIfStored = "+bytesPerPixelIfStored+" internalformat = "+internalFormat);
- System.out.println("imageYup = "+imageYup+" imageYdown = "+imageYdown[0]);
- System.out.println("===> usedByRaster = "+usedByRaster);
- */
-
- // array copy by scanline
-
- //position of a raster specifies the upper-left corner
- // copy yUp -> yDown
- imageDirty [0] = true;
-
- if (usedByRaster) {
- dstWidth = width * bytesPerYdownPixelStored;
- srcOffset = (yRead * srcLineBytes) + (xRead * bpp);
-
- dstOffset = ((height - yRead - 1)) * dstWidth +
- (xRead * bytesPerYdownPixelStored);
- // If by Reference and a copy has not been made ...
- if (byReference && storedYdownFormat != internalFormat) {
- bdata =((DataBufferByte) ((BufferedImage)bImage[0]).getRaster().getDataBuffer()).getData();
- imageDirty [0] = false;
- }
- else {
- bdata = imageYdown[0];
- }
- if (storedYdownFormat == format) {
- for (h = 0; h < hRead; h++,
- srcOffset += srcLineBytes, dstOffset -= dstWidth) {
- System.arraycopy(buf, srcOffset, bdata, dstOffset, srcWidth);
- }
- }
- else { // Would be one of the stored formats to RGBA
- // Convert from one of the byRef formats to RGBA
- switch(format) {
- case BYTE_ABGR:
- for (h = 0; h < hRead; h++,
- srcOffset += srcLineBytes, dstOffset -= dstWidth) {
- int offset = dstOffset;
- for (w = 0; w < srcWidth; w +=bpp) {
- bdata[offset++] = buf[srcOffset+w+3];
- bdata[offset++] = buf[srcOffset+w+2];
- bdata[offset++] = buf[srcOffset+w+1];
- bdata[offset++] = buf[srcOffset+w];
-
- }
- }
- break;
- case BYTE_BGR:
-
- for (h = 0; h < hRead; h++,
- srcOffset += srcLineBytes, dstOffset -= dstWidth) {
- int offset = dstOffset;
- for (w = 0; w < srcWidth; w +=bpp) {
- bdata[offset++] = buf[srcOffset+w+2];
- bdata[offset++] = buf[srcOffset+w+1];
- bdata[offset++] = buf[srcOffset+w];
- bdata[offset++] = (byte)0xff;
-
- }
- }
- break;
-
- }
- }
- }
-
- if (usedByTexture || !usedByRaster) {
- imageYupCacheDirty = true;
- dstWidth = width * bytesPerYupPixelStored;
- srcOffset = (yRead * srcLineBytes) + (xRead * bpp);
+ * Retrieves the reference of the nio image in this ImageComponent2D object.
+ */
+ NioImageBuffer getNioImage() {
- // If by Reference and a copy has not been made ...
- if (byReference && storedYupFormat != internalFormat) {
- bdata =((DataBufferByte) ((BufferedImage)bImage[0]).getRaster().getDataBuffer()).getData();
- imageDirty [0] = false;
- }
- else {
- bdata = imageYup;
- }
- // If used by texture, then storedYupFormat is always equal to format
- if (storedYupFormat == format) {
- for (dstOffset = srcOffset,
- h = 0; h < hRead; h++,
- srcOffset += srcLineBytes, dstOffset += dstWidth) {
- System.arraycopy(buf, srcOffset, bdata, dstOffset, srcWidth);
- }
- }
- }
- // If its by reference and a copy has been made, make the user's copy
- // up-to-date
-
- if (byReference && imageDirty[0]) {
- imageDirty [0] = false;
- if (usedByTexture || !usedByRaster) {
- copyBufferedImageWithFormatConversion(true, 0);
- }
- else {
- copyBufferedImageWithFormatConversion(false, 0);
- }
- }
- imageChanged = 0xffff;
- lastAlpha[0] = 1.0f;
+ if (getImageClass() != ImageComponent.ImageClass.NIO_IMAGE_BUFFER) {
+ throw new IllegalStateException(J3dI18N.getString("ImageComponent2D9"));
+ }
+
+ assert (byReference == true);
+
+ return (NioImageBuffer) getRefImage(0);
}
/**
@@ -1265,29 +270,41 @@ class ImageComponent2DRetained extends ImageComponentRetained {
int x, int y, int width, int height) {
geomLock.getLock();
-
// call the user supplied updateData method to update the data
updater.updateData((ImageComponent2D)source, x, y, width, height);
- // update the internal copy of the image data if a copy has been
- // made
- if (imageYupAllocated) {
- copyImage(bImage[0], (x + bImage[0].getMinX()),
- (y + bImage[0].getMinY()), imageYup, x, y,
- true, 0, width, height, storedYupFormat,
- bytesPerYupPixelStored);
- }
-
-
- if (imageYdownAllocated) {
- copyImage(bImage[0], (x + bImage[0].getMinX()),
- (y + bImage[0].getMinY()), imageYdown[0], x, y,
- false, 0, width, height, storedYdownFormat,
- bytesPerYdownPixelStored);
- }
-
- imageDirty[0] = true;
-
+ Object refImage = getRefImage(0);
+ assert (refImage != null);
+ assert (imageData != null);
+
+ // Check is data copied internally.
+ if(!imageData.isDataByRef()) {
+ // update the internal copy of the image data if a copy has been
+ // made
+ if (imageTypeIsSupported) {
+ assert !(refImage instanceof NioImageBuffer);
+
+ if (refImage instanceof BufferedImage) {
+ copyImageLineByLine((BufferedImage)refImage, x, y, x, y, 0, width, height, imageData);
+ } else {
+ RenderedImage ri = (RenderedImage)refImage;
+ copySupportedImageToImageData(ri, (x + ri.getMinX()), (y + ri.getMinY()), x, y, 0, width, height, imageData);
+ }
+ } else {
+ // image type is unsupported, need to create a supported local copy.
+ // TODO : Should look into borrow code from JAI to convert to right format.
+ if (refImage instanceof BufferedImage) {
+ copyUnsupportedImageToImageData((BufferedImage)refImage, x, y, x, y, 0, width, height, imageData);
+ } else if (refImage instanceof RenderedImage) {
+ RenderedImage ri = (RenderedImage)refImage;
+ copyUnsupportedImageToImageData(ri, (x + ri.getMinX()), (y + ri.getMinY()), x, y, 0, width, height, imageData);
+ } else if (refImage instanceof NioImageBuffer) {
+ copyUnsupportedNioImageToImageData((NioImageBuffer)refImage, x, y, x, y, width, height, imageData);
+ } else {
+ assert false;
+ }
+ }
+ }
geomLock.unLock();
@@ -1301,7 +318,7 @@ class ImageComponent2DRetained extends ImageComponentRetained {
ImageComponentUpdateInfo info;
- info = VirtualUniverse.mc.getFreeImageUpdateInfo();
+ info = new ImageComponentUpdateInfo();
info.x = x;
info.y = y;
info.z = 0;
@@ -1311,74 +328,58 @@ class ImageComponent2DRetained extends ImageComponentRetained {
sendMessage(SUBIMAGE_CHANGED, info);
}
}
+
+ ImageComponentRetained createNextLevelMipMapImage() {
+
+ int xScale, yScale, newWidth, newHeight;
+
+ if (width > 1) {
+ newWidth = width >> 1;
+ xScale = 2;
+ } else {
+ newWidth = 1;
+ xScale = 1;
+ }
+ if (height > 1) {
+ newHeight = height >> 1;
+ yScale = 2;
+ } else {
+ newHeight = 1;
+ yScale = 1;
+ }
+
+ ImageComponent2DRetained newImage = new ImageComponent2DRetained();
+ newImage.processParams(getFormat(), newWidth, newHeight, 1);
+ newImage.setImageFormatType(getImageFormatType());
+ newImage.setUnitsPerPixel(getUnitsPerPixel());
+ newImage.imageData = newImage.createRenderedImageDataObject(null);
+
+ newImage.scaleImage(xScale, yScale, 0, this);
+
+ return newImage;
+ }
- void setSubImage(RenderedImage image, int width, int height,
- int srcX, int srcY, int dstX, int dstY) {
-
- geomLock.getLock();
-
- if (imageYupAllocated) {
- copyImage(image, srcX, srcY, imageYup, dstX, dstY,
- true, 0, width, height, storedYupFormat,
- bytesPerYupPixelStored);
- }
-
- if (imageYdownAllocated) {
- copyImage(image, srcX, srcY, imageYdown[0],
- dstX, dstY, false, 0, width, height,
- storedYdownFormat, bytesPerYdownPixelStored);
+ void clearLive(int refCount) {
+ super.clearLive(refCount);
+ if (this.refCount <= 0) {
+ freeSurface();
}
-
- imageDirty[0] = true;
-
- geomLock.unLock();
-
-
- if (source.isLive()) {
-
- // XXXX: check whether this is needed
- freeSurface();
-
- // send a SUBIMAGE_CHANGED message in order to
- // notify all the users of the change
-
- ImageComponentUpdateInfo info;
-
- info = VirtualUniverse.mc.getFreeImageUpdateInfo();
- info.x = dstX;
- info.y = dstY;
- info.z = 0;
- info.width = width;
- info.height = height;
-
- sendMessage(SUBIMAGE_CHANGED, info);
- }
}
- synchronized void updateMirrorObject(int component, Object value) {
-
- super.updateMirrorObject(component, value);
-
- if (detailTexture != null) {
- if (((component & IMAGE_CHANGED) != 0) ||
- ((component & SUBIMAGE_CHANGED) != 0)) {
-
- // notify detailTexture of image change
-
- detailTexture.notifyImageComponentImageChanged(this, value);
- }
+ void freeSurface() {
+ if (VirtualUniverse.mc.isD3D()) {
+ Pipeline.getPipeline().freeD3DSurface(this, hashId);
}
}
+ // TODO KCR ISSUE 121 : REPLACE THIS WITH A WEAK REFERENCE OR OTHER SCHEME
+ // Issue 121 : Stop using finalize() to clean up state
+ // Use similar approach as in handling ogl Texture resource cleanup.
+// protected void finalize() {
+// System.err.println("finalize: " + this);
+//// // For Pure immediate mode, there is no clearLive so
+//// // surface will free when JVM do GC
+//// freeSurface();
+// }
- synchronized void setDetailTexture(DetailTextureImage tex) {
- detailTexture = tex;
- }
-
- synchronized DetailTextureImage getDetailTexture() {
- if (detailTexture == null) {
- detailTexture = new DetailTextureImage(this);
- }
- return detailTexture;
- }
}
diff --git a/src/classes/share/javax/media/j3d/ImageComponent3D.java b/src/classes/share/javax/media/j3d/ImageComponent3D.java
index 9127277..6c0238c 100644
--- a/src/classes/share/javax/media/j3d/ImageComponent3D.java
+++ b/src/classes/share/javax/media/j3d/ImageComponent3D.java
@@ -41,6 +41,7 @@ import java.awt.image.RenderedImage;
* ic.set(0, ri);<br>
* </code>
* </ul>
+ *
*/
public class ImageComponent3D extends ImageComponent {
@@ -53,6 +54,7 @@ public class ImageComponent3D extends ImageComponent {
* all other parameters. The default values are as follows:
* <ul>
* array of images : null<br>
+ * imageClass : ImageClass.BUFFERED_IMAGE<br>
* </ul>
*
* @param format the image component format, one of: FORMAT_RGB,
@@ -71,25 +73,26 @@ public class ImageComponent3D extends ImageComponent {
int depth) {
((ImageComponent3DRetained)this.retained).processParams(format, width, height, depth);
- ((ImageComponent3DRetained)this.retained).setDepth(depth);
}
/**
* Constructs a 3D image component object using the specified format,
* and the BufferedImage array.
+ * The image class is set to ImageClass.BUFFERED_IMAGE.
* Default values are used for all other parameters.
+ *
* @param format the image component format, one of: FORMAT_RGB,
* FORMAT_RGBA etc.
* @param images an array of BufferedImage objects. The
* first image in the array determines the width and height of this
* ImageComponent3D.
+ *
* @exception IllegalArgumentException if format is invalid, or if
* the width or height of the first image are not positive.
*/
public ImageComponent3D(int format, BufferedImage[] images) {
((ImageComponent3DRetained)this.retained).processParams(format,
images[0].getWidth(null), images[0].getHeight(null), images.length);
- ((ImageComponent3DRetained)this.retained).setDepth(images.length);
for (int i=0; i<images.length; i++) {
((ImageComponent3DRetained)this.retained).set(i, images[i]);
}
@@ -98,12 +101,15 @@ public class ImageComponent3D extends ImageComponent {
/**
* Constructs a 3D image component object using the specified format,
* and the RenderedImage array.
+ * The image class is set to ImageClass.BUFFERED_IMAGE.
* Default values are used for all other parameters.
+ *
* @param format the image component format, one of: FORMAT_RGB,
* FORMAT_RGBA etc.
* @param images an array of RenderedImage objects. The
* first image in the array determines the width and height of this
* ImageComponent3D.
+ *
* @exception IllegalArgumentException if format is invalid, or if
* the width or height of the first image are not positive.
*
@@ -113,7 +119,6 @@ public class ImageComponent3D extends ImageComponent {
((ImageComponent3DRetained)this.retained).processParams(format,
images[0].getWidth(), images[0].getHeight(), images.length);
- ((ImageComponent3DRetained)this.retained).setDepth(images.length);
for (int i=0; i<images.length; i++) {
((ImageComponent3DRetained)this.retained).set(i, images[i]);
}
@@ -153,13 +158,13 @@ public class ImageComponent3D extends ImageComponent {
((ImageComponentRetained)this.retained).setByReference(byReference);
((ImageComponentRetained)this.retained).setYUp(yUp);
((ImageComponent3DRetained)this.retained).processParams(format, width, height, depth);
- ((ImageComponent3DRetained)this.retained).setDepth(depth);
}
/**
* Constructs a 3D image component object using the specified format,
* BufferedImage array, byReference flag, and yUp flag.
- * Default values are used for all other parameters.
+ * The image class is set to ImageClass.BUFFERED_IMAGE.
+ *
* @param format the image component format, one of: FORMAT_RGB,
* FORMAT_RGBA etc.
* @param images an array of BufferedImage objects. The
@@ -171,6 +176,7 @@ public class ImageComponent3D extends ImageComponent {
* component. If yUp is set to true, the origin of the image is
* the lower left; otherwise, the origin of the image is the upper
* left.
+ *
* @exception IllegalArgumentException if format is invalid, or if
* the width or height of the first image are not positive.
*
@@ -184,8 +190,8 @@ public class ImageComponent3D extends ImageComponent {
((ImageComponentRetained)this.retained).setByReference(byReference);
((ImageComponentRetained)this.retained).setYUp(yUp);
- ((ImageComponent3DRetained)this.retained).processParams(format, images[0].getWidth(null), images[0].getHeight(null), images.length);
- ((ImageComponent3DRetained)this.retained).setDepth(images.length);
+ ((ImageComponent3DRetained)this.retained).processParams(format,
+ images[0].getWidth(null), images[0].getHeight(null), images.length);
for (int i=0; i<images.length; i++) {
((ImageComponent3DRetained)this.retained).set(i, images[i]);
}
@@ -194,7 +200,11 @@ public class ImageComponent3D extends ImageComponent {
/**
* Constructs a 3D image component object using the specified format,
* RenderedImage array, byReference flag, and yUp flag.
- * Default values are used for all other parameters.
+ * The image class is set to ImageClass.RENDERED_IMAGE if the byReference
+ * flag is true and any of the specified RenderedImages is <i>not</i> an
+ * instance of BufferedImage. In all other cases, the image class is set to
+ * ImageClass.BUFFERED_IMAGE.
+ *
* @param format the image component format, one of: FORMAT_RGB,
* FORMAT_RGBA etc.
* @param images an array of RenderedImage objects. The
@@ -216,19 +226,67 @@ public class ImageComponent3D extends ImageComponent {
boolean byReference,
boolean yUp) {
-
((ImageComponentRetained)this.retained).setByReference(byReference);
((ImageComponentRetained)this.retained).setYUp(yUp);
- ((ImageComponent3DRetained)this.retained).processParams(format, images[0].getWidth(), images[0].getHeight(), images.length);
- ((ImageComponent3DRetained)this.retained).setDepth(images.length);
+ ((ImageComponent3DRetained)this.retained).processParams(format,
+ images[0].getWidth(), images[0].getHeight(), images.length);
+ for (int i=0; i<images.length; i++) {
+ ((ImageComponent3DRetained)this.retained).set(i, images[i]);
+ }
+ }
+
+ /**
+ * Constructs a 3D image component object using the specified format,
+ * NioImageBuffer array, byReference flag, and yUp flag.
+ * The image class is set to ImageClass.NIO_IMAGE_BUFFER.
+ *
+ * @param format the image component format, one of: FORMAT_RGB,
+ * FORMAT_RGBA etc.
+ * @param images an array of NioImageBuffer objects. The
+ * first image in the array determines the width and height of this
+ * ImageComponent3D.
+ * @param byReference a flag that indicates whether the data is copied
+ * into this image component object or is accessed by reference.
+ * @param yUp a flag that indicates the y-orientation of this image
+ * component. If yUp is set to true, the origin of the image is
+ * the lower left; otherwise, the origin of the image is the upper
+ * left.
+ *
+ * @exception IllegalArgumentException if format is invalid, or if
+ * the width or height of the first image are not positive.
+ *
+ * @exception IllegalArgumentException if the byReference flag is false.
+ *
+ * @exception IllegalArgumentException if the yUp flag is false.
+ *
+ * @exception UnsupportedOperationException this method is not supported
+ * for Java 3D 1.5.
+ *
+ * @since Java 3D 1.5
+ */
+ public ImageComponent3D(int format,
+ NioImageBuffer[] images,
+ boolean byReference,
+ boolean yUp) {
+
+
+ throw new UnsupportedOperationException();
+ /*
+ ((ImageComponentRetained)this.retained).setByReference(byReference);
+ ((ImageComponentRetained)this.retained).setYUp(yUp);
+ ((ImageComponent3DRetained)this.retained).processParams(format,
+ images[0].getWidth(), images[0].getHeight(), images.length);
for (int i=0; i<images.length; i++) {
((ImageComponent3DRetained)this.retained).set(i, images[i]);
}
+ */
}
/**
* Retrieves the depth of this 3D image component object.
- * @return the format of this 3D image component object
+ *
+ * @return the depth of this 3D image component object
+ *
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*/
@@ -247,14 +305,23 @@ public class ImageComponent3D extends ImageComponent {
* then a shallow copy of the array of references to the
* BufferedImage objects is made, but the BufferedImage
* data is not necessarily copied.
+ * <p>
+ * The image class is set to ImageClass.BUFFERED_IMAGE.
*
* @param images array of BufferedImage objects containing the image.
- * The format and size must be the same as the current format in the
- * image component.
+ * The size (width and height) of each image must be the same as the
+ * size of the image component, and the length of the images array
+ * must equal the depth of the image component.
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalArgumentException if the length of the images array is
+ * not equal to the depth of this ImageComponent object.
+ *
+ * @exception IllegalArgumentException if the width and height of each
+ * image in the images array is not equal to the width and height of this
+ * ImageComponent object.
*/
public void set(BufferedImage[] images) {
checkForLiveOrCompiled();
@@ -275,14 +342,27 @@ public class ImageComponent3D extends ImageComponent {
* then a shallow copy of the array of references to the
* RenderedImage objects is made, but the RenderedImage
* data is not necessarily copied.
+ * <p>
+ * The image class is set to ImageClass.RENDERED_IMAGE if the data access
+ * mode is by-reference and any of the specified RenderedImages
+ * is <i>not</i> an instance of BufferedImage. In all other cases,
+ * the image class is set to ImageClass.BUFFERED_IMAGE.
*
* @param images array of RenderedImage objects containing the image.
- * The format and size must be the same as the current format in the
- * image component.
+ * The size (width and height) of each image must be the same as the
+ * size of the image component, and the length of the images array
+ * must equal the depth of the image component.
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalArgumentException if the length of the images array is
+ * not equal to the depth of this ImageComponent object.
+ *
+ * @exception IllegalArgumentException if the width and height of each
+ * image in the images array is not equal to the width and height of this
+ * ImageComponent object.
+ *
* @since Java 3D 1.2
*/
public void set(RenderedImage[] images) {
@@ -298,6 +378,55 @@ public class ImageComponent3D extends ImageComponent {
}
/**
+ * Sets the array of images in this image component to the
+ * specified array of NioImageBuffer objects. If the data access
+ * mode is not by-reference, then the NioImageBuffer data is copied
+ * into this object. If the data access mode is by-reference,
+ * then a shallow copy of the array of references to the
+ * NioImageBuffer objects is made, but the NioImageBuffer
+ * data is not necessarily copied.
+ * <p>
+ * The image class is set to ImageClass.NIO_IMAGE_BUFFER.
+ *
+ * @param images array of NioImageBuffer objects containing the image.
+ * The size (width and height) of each image must be the same as the
+ * size of the image component, and the length of the images array
+ * must equal the depth of the image component.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalStateException if this ImageComponent object
+ * is <i>not</i> yUp.
+ *
+ * @exception IllegalArgumentException if the length of the images array is
+ * not equal to the depth of this ImageComponent object.
+ *
+ * @exception IllegalArgumentException if the width and height of each
+ * image in the images array is not equal to the width and height of this
+ * ImageComponent object.
+ *
+ * @exception UnsupportedOperationException this method is not supported
+ * for Java 3D 1.5.
+ *
+ * @since Java 3D 1.5
+ */
+ public void set(NioImageBuffer[] images) {
+
+ throw new UnsupportedOperationException();
+ /*
+ checkForLiveOrCompiled();
+ int depth = ((ImageComponent3DRetained)this.retained).getDepth();
+
+ if (depth != images.length)
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponent3D1"));
+ for (int i=0; i<depth; i++) {
+ ((ImageComponent3DRetained)this.retained).set(i, images[i]);
+ }
+ */
+ }
+
+ /**
* Sets this image component at the specified index to the
* specified BufferedImage object. If the data access mode is not
* by-reference, then the BufferedImage data is copied into this
@@ -305,15 +434,21 @@ public class ImageComponent3D extends ImageComponent {
* reference to the BufferedImage is saved, but the data is not
* necessarily copied.
*
- * @param index the image index
+ * @param index the image index.
+ * The index must be less than the depth of this ImageComponent3D object.
+ *
* @param image BufferedImage object containing the image.
- * The format and size must be the same as the current format in this
- * ImageComponent3D object. The index must not exceed the depth of this
+ * The size (width and height) must be the same as the current size of this
* ImageComponent3D object.
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalStateException if the image class is not
+ * ImageClass.BUFFERED_IMAGE.
+ *
+ * @exception IllegalArgumentException if the width and height the image
+ * is not equal to the width and height of this ImageComponent object.
*/
public void set(int index, BufferedImage image) {
checkForLiveOrCompiled();
@@ -334,30 +469,71 @@ public class ImageComponent3D extends ImageComponent {
* reference to the RenderedImage is saved, but the data is not
* necessarily copied.
*
- * @param index the image index
+ * @param index the image index.
+ * The index must be less than the depth of this ImageComponent3D object.
+ *
* @param image RenderedImage object containing the image.
- * The format and size must be the same as the current format in this
- * ImageComponent3D object. The index must not exceed the depth of this
+ * The size (width and height) must be the same as the current size of this
* ImageComponent3D object.
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalStateException if the image class is not one of:
+ * ImageClass.BUFFERED_IMAGE or ImageClass.RENDERED_IMAGE.
+ *
+ * @exception IllegalArgumentException if the width and height the image
+ * is not equal to the width and height of this ImageComponent object.
+ *
* @since Java 3D 1.2
*/
public void set(int index, RenderedImage image) {
checkForLiveOrCompiled();
- if (image.getWidth() != this.getWidth())
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponent3D2"));
-
- if (image.getHeight() != this.getHeight())
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponent3D4"));
-
+ // For RenderedImage the width and height checking is done in the retained.
((ImageComponent3DRetained)this.retained).set(index, image);
}
/**
+ * Sets this image component at the specified index to the
+ * specified NioImageBuffer object. If the data access mode is not
+ * by-reference, then the NioImageBuffer data is copied into this
+ * object. If the data access mode is by-reference, then a
+ * reference to the NioImageBuffer is saved, but the data is not
+ * necessarily copied.
+ *
+ * @param index the image index.
+ * The index must be less than the depth of this ImageComponent3D object.
+ *
+ * @param image NioImageBuffer object containing the image.
+ * The size (width and height) must be the same as the current size of this
+ * ImageComponent3D object.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalStateException if the image class is not
+ * ImageClass.NIO_IMAGE_BUFFER.
+ *
+ * @exception IllegalArgumentException if the width and height the image
+ * is not equal to the width and height of this ImageComponent object.
+ *
+ * @exception UnsupportedOperationException this method is not supported
+ * for Java 3D 1.5.
+ *
+ * @since Java 3D 1.5
+ */
+ public void set(int index, NioImageBuffer image) {
+
+ throw new UnsupportedOperationException();
+ /*
+ checkForLiveOrCompiled();
+ // For NioImageBuffer the width and height checking is done in the retained.
+ ((ImageComponent3DRetained)this.retained).set(index, image);
+ */
+ }
+
+ /**
* Retrieves the images from this ImageComponent3D object. If the
* data access mode is not by-reference, then a copy of the images
* is made. If the data access mode is by-reference, then the
@@ -371,9 +547,8 @@ public class ImageComponent3D extends ImageComponent {
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
- * @exception IllegalStateException if the data access mode is
- * by-reference and any image referenced by this ImageComponent3D
- * object is not an instance of BufferedImage.
+ * @exception IllegalStateException if the image class is not
+ * ImageClass.BUFFERED_IMAGE.
*/
public BufferedImage[] getImage() {
if (isLiveOrCompiled())
@@ -396,10 +571,12 @@ public class ImageComponent3D extends ImageComponent {
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalStateException if the image class is not one of:
+ * ImageClass.BUFFERED_IMAGE or ImageClass.RENDERED_IMAGE.
+ *
* @since Java 3D 1.2
*/
public RenderedImage[] getRenderedImage() {
-
if (isLiveOrCompiled())
if(!this.getCapability(ImageComponent.ALLOW_IMAGE_READ))
throw new CapabilityNotSetException(J3dI18N.getString("ImageComponent3D3"));
@@ -407,21 +584,50 @@ public class ImageComponent3D extends ImageComponent {
}
/**
+ * Retrieves the images from this ImageComponent3D object. If the
+ * data access mode is not by-reference, then a copy of the images
+ * is made. If the data access mode is by-reference, then the
+ * references are returned.
+ *
+ * @return either a new array of new RenderedImage objects created from
+ * the data
+ * in this image component, or a new array of
+ * references to the RenderedImages that this image component refers to.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalStateException if the image class is not
+ * ImageClass.NIO_IMAGE_BUFFER.
+ *
+ * @exception UnsupportedOperationException this method is not supported
+ * for Java 3D 1.5.
+ *
+ * @since Java 3D 1.5
+ */
+ public NioImageBuffer[] getNioImage() {
+
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* Retrieves one of the images from this ImageComponent3D object. If the
* data access mode is not by-reference, then a copy of the image
* is made. If the data access mode is by-reference, then the
* reference is returned.
*
- * @param index the index of the image to retrieve
+ * @param index the index of the image to retrieve.
+ * The index must be less than the depth of this ImageComponent3D object.
+ *
* @return either a new BufferedImage object created from the data
* in this image component, or the BufferedImage object referenced
* by this image component.
+ *
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
- * @exception IllegalStateException if the data access mode is
- * by-reference and the image referenced by this ImageComponent3D
- * object at the specified index is not an instance of BufferedImage.
+ * @exception IllegalStateException if the image class is not
+ * ImageClass.BUFFERED_IMAGE.
*/
public BufferedImage getImage(int index) {
if (isLiveOrCompiled())
@@ -441,13 +647,19 @@ public class ImageComponent3D extends ImageComponent {
* is made. If the data access mode is by-reference, then the
* reference is returned.
*
- * @param index the index of the image to retrieve
+ * @param index the index of the image to retrieve.
+ * The index must be less than the depth of this ImageComponent3D object.
+ *
* @return either a new RenderedImage object created from the data
* in this image component, or the RenderedImage object referenced
* by this image component.
+ *
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalStateException if the image class is not one of:
+ * ImageClass.BUFFERED_IMAGE or ImageClass.RENDERED_IMAGE.
+ *
* @since Java 3D 1.2
*/
public RenderedImage getRenderedImage(int index) {
@@ -459,6 +671,35 @@ public class ImageComponent3D extends ImageComponent {
}
/**
+ * Retrieves one of the images from this ImageComponent3D object. If the
+ * data access mode is not by-reference, then a copy of the image
+ * is made. If the data access mode is by-reference, then the
+ * reference is returned.
+ *
+ * @param index the index of the image to retrieve.
+ * The index must be less than the depth of this ImageComponent3D object.
+ *
+ * @return either a new NioImageBuffer object created from the data
+ * in this image component, or the NioImageBuffer object referenced
+ * by this image component.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalStateException if the image class is not
+ * ImageClass.NIO_IMAGE_BUFFER.
+ *
+ * @exception UnsupportedOperationException this method is not supported
+ * for Java 3D 1.5.
+ *
+ * @since Java 3D 1.5
+ */
+ public NioImageBuffer getNioImage(int index) {
+
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* Modifies a contiguous subregion of a particular slice of
* image of this ImageComponent3D object.
* Block of data of dimension (width * height)
@@ -471,8 +712,8 @@ public class ImageComponent3D extends ImageComponent {
* This method can only be used if the data access mode is
* by-copy. If it is by-reference, see updateData().
*
- * @param index index of the image to be modified. The index must not
- * exceed the depth of the object.
+ * @param index index of the image to be modified.
+ * The index must be less than the depth of this ImageComponent3D object.
* @param image RenderedImage object containing the subimage.
* @param width width of the subregion.
* @param height height of the subregion.
@@ -485,15 +726,19 @@ public class ImageComponent3D extends ImageComponent {
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
+ *
* @exception IllegalStateException if the data access mode is
* <code>BY_REFERENCE</code>.
+ *
* @exception IllegalArgumentException if <code>width</code> or
* <code>height</code> of
* the subregion exceeds the dimension of the image in this object.
+ *
* @exception IllegalArgumentException if <code>dstX</code> < 0, or
* (<code>dstX</code> + <code>width</code>) > width of this object, or
* <code>dstY</code> < 0, or
* (<code>dstY</code> + <code>height</code>) > height of this object.
+ *
* @exception IllegalArgumentException if <code>srcX</code> < 0, or
* (<code>srcX</code> + <code>width</code>) > width of the RenderedImage
* object containing the subimage, or
@@ -501,6 +746,12 @@ public class ImageComponent3D extends ImageComponent {
* (<code>srcY</code> + <code>height</code>) > height of the
* RenderedImage object containing the subimage.
*
+ * @exception IllegalArgumentException if the specified RenderedImage
+ * is not compatible with the existing RenderedImage.
+ *
+ * @exception IllegalStateException if the image class is not one of:
+ * ImageClass.BUFFERED_IMAGE or ImageClass.RENDERED_IMAGE.
+ *
* @since Java 3D 1.3
*/
public void setSubImage(int index, RenderedImage image,
@@ -550,8 +801,8 @@ public class ImageComponent3D extends ImageComponent {
* <p>
* @param updater object whose updateData callback method will be
* called to update the data referenced by this ImageComponent3D object.
- * @param index index of the image to be modified. The index must
- * not exceed the depth of this object.
+ * @param index index of the image to be modified.
+ * The index must be less than the depth of this ImageComponent3D object.
* @param x starting X offset of the subregion.
* @param y starting Y offset of the subregion.
* @param width width of the subregion.
@@ -617,7 +868,7 @@ public class ImageComponent3D extends ImageComponent {
public NodeComponent cloneNodeComponent() {
ImageComponent3DRetained rt = (ImageComponent3DRetained) retained;
- ImageComponent3D img = new ImageComponent3D(rt.format,
+ ImageComponent3D img = new ImageComponent3D(rt.getFormat(),
rt.width,
rt.height,
rt.depth);
@@ -656,7 +907,7 @@ public class ImageComponent3D extends ImageComponent {
void duplicateAttributes(NodeComponent originalNodeComponent,
boolean forceDuplicate) {
super.duplicateAttributes(originalNodeComponent, forceDuplicate);
-
+ // TODO : Handle NioImageBuffer if its supported.
RenderedImage imgs[] = ((ImageComponent3DRetained)
originalNodeComponent.retained).getImage();
diff --git a/src/classes/share/javax/media/j3d/ImageComponent3DRetained.java b/src/classes/share/javax/media/j3d/ImageComponent3DRetained.java
index 21813f8..91947bb 100644
--- a/src/classes/share/javax/media/j3d/ImageComponent3DRetained.java
+++ b/src/classes/share/javax/media/j3d/ImageComponent3DRetained.java
@@ -20,7 +20,6 @@ import java.awt.image.*;
*/
class ImageComponent3DRetained extends ImageComponentRetained {
- int depth; // Depth of 3D image
void setDepth(int depth) {
this.depth = depth;
@@ -30,7 +29,7 @@ class ImageComponent3DRetained extends ImageComponentRetained {
* Retrieves the depth of this 3D image component object.
* @return the format of this 3D image component object
*/
- final int getDepth() {
+ int getDepth() {
return depth;
}
@@ -43,19 +42,135 @@ class ImageComponent3DRetained extends ImageComponentRetained {
* ImageComponent3D object. The index must not exceed the depth of this
* ImageComponent3D object.
*/
- final void set(int index, BufferedImage image) {
- if (imageYup == null)
- imageYup = new byte[height * width * depth * bytesPerPixelIfStored];
- imageDirty[index] = true;
- storedYupFormat = internalFormat;
- bytesPerYupPixelStored = bytesPerPixelIfStored;
- copyImage(image, imageYup, true, index, storedYupFormat,
- bytesPerYupPixelStored);
- if (byReference)
- bImage[index] = image;
- }
+ void set(int index, BufferedImage image) {
+
+ geomLock.getLock();
+
+ if(byReference) {
+ setRefImage(image,0);
+ }
- final void set(int index, RenderedImage image) {
+ if(imageData == null) {
+ // Only do this once, on the first image
+ // Reset this flag to true, incase it was set to false due to
+ // the previous image type.
+ abgrSupported = true;
+ imageTypeIsSupported = isImageTypeSupported(image);
+ imageData = createRenderedImageDataObject(null);
+ }
+ else {
+ if(getImageType() != evaluateImageType(image)) {
+ // TODO need to throw illegal state exception
+ }
+ }
+
+ if (imageTypeIsSupported) {
+ copySupportedImageToImageData(image, index, imageData);
+ } else {
+ // image type is unsupported, need to create a supported local copy.
+ // TODO : borrow code from JAI to convert to right format.
+ copyUnsupportedImageToImageData(image, index, imageData);
+
+ }
+
+ geomLock.unLock();
+
+ if (source.isLive()) {
+ // freeSurface();
+
+ // send a IMAGE_CHANGED message in order to
+ // notify all the users of the change
+ sendMessage(IMAGE_CHANGED, null);
+ }
+ }
+
+ /**
+ * Copies the specified BufferedImage to this 3D image component
+ * object at the specified index.
+ * @param index the image index
+ * @param images BufferedImage object containing the image.
+ * The format and size must be the same as the current format in this
+ * ImageComponent3D object. The index must not exceed the depth of this
+ * ImageComponent3D object.
+ *
+ void set(int index, NioImageBuffer nioImage) {
+
+ int width = nioImage.getWidth();
+ int height = nioImage.getHeight();
+
+ if (!byReference) {
+ throw new IllegalArgumentException(J3dI18N.getString("Need_New_Message_XXXXXImageComponent2D7"));
+ }
+ if (!yUp) {
+ throw new IllegalArgumentException(J3dI18N.getString("Need_New_Message_XXXXXImageComponent2D8"));
+ }
+
+ if (width != this.width) {
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponent3D2"));
+ }
+ if (height != this.height) {
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponent3D4"));
+ }
+
+ geomLock.getLock();
+
+ setImageClass(nioImage);
+
+ // This is a byRef image.
+ setRefImage(nioImage,0);
+
+ if(imageData == null) {
+ // Only do this once, on the first image
+ // Reset this flag to true, incase it was set to false due to
+ // the previous image type.
+ abgrSupported = true;
+
+ imageTypeIsSupported = isImageTypeSupported(nioImage);
+
+
+ // TODO : Need to handle null ....
+ imageData = createNioImageBufferDataObject(null);
+ }
+ else {
+
+ //if(getImageType() != evaluateImageType(image)) {
+ // TODO need to throw illegal state exception
+ //}
+
+ }
+
+ if (imageTypeIsSupported) {
+ // TODO : Need to handle this ..... case ....
+ // copySupportedImageToImageData(image, index, imageData);
+ } else {
+ // System.err.println("Image format is unsupported -- illogical case");
+ throw new AssertionError();
+ }
+
+ geomLock.unLock();
+
+ if (source.isLive()) {
+ // freeSurface();
+
+ // send a IMAGE_CHANGED message in order to
+ // notify all the users of the change
+ sendMessage(IMAGE_CHANGED, null);
+ }
+ }
+ */
+
+ void set(int index, RenderedImage image) {
+
+ int width = image.getWidth();
+ int height = image.getHeight();
+
+ if (width != this.width) {
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponent3D2"));
+ }
+ if (height != this.height) {
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponent3D4"));
+ }
+
if (image instanceof BufferedImage) {
set(index, ((BufferedImage)image));
}
@@ -76,20 +191,21 @@ class ImageComponent3DRetained extends ImageComponentRetained {
* @return a new array of new BufferedImage objects created from the
* images in this ImageComponent3D object
*/
- final RenderedImage[] getRenderedImage() {
+ RenderedImage[] getRenderedImage() {
int i;
- RenderedImage bi[] = new RenderedImage[bImage.length];
+ RenderedImage bi[] = new RenderedImage[depth];
+
if (!byReference) {
for (i=0; i<depth; i++) {
- if (imageDirty[i]) {
- retrieveBufferedImage(i);
- }
+ bi[i] = imageData.createBufferedImage(i);
}
}
- for (i = 0; i < bImage.length; i++) {
- bi[i] = bImage[i];
- }
- // If by reference, then the image should not be dirty
+ else {
+ for (i = 0; i < depth; i++) {
+ bi[i] = imageData.createBufferedImage(i);
+ }
+ }
+
return bi;
}
@@ -99,25 +215,24 @@ class ImageComponent3DRetained extends ImageComponentRetained {
* @return a new array of new BufferedImage objects created from the
* images in this ImageComponent3D object
*/
- final BufferedImage[] getImage() {
+ BufferedImage[] getImage() {
int i;
- BufferedImage bi[] = new BufferedImage[bImage.length];
+ BufferedImage bi[] = new BufferedImage[depth];
if (!byReference) {
for (i=0; i<depth; i++) {
- if (imageDirty[i]) {
- retrieveBufferedImage(i);
- }
+ bi[i] = imageData.createBufferedImage(i);
}
}
-
- for (i = 0; i < bImage.length; i++) {
- if (!(bImage[i] instanceof BufferedImage)) {
- throw new IllegalStateException(J3dI18N.getString("ImageComponent3DRetained0"));
- }
- bi[i] = (BufferedImage) bImage[i];
- }
- // If by reference, then the image should not be dirty
+ else {
+ for (i = 0; i < depth; i++) {
+ bi[i] = imageData.createBufferedImage(i);
+ if (!(bi[i] instanceof BufferedImage)) {
+ throw new IllegalStateException(J3dI18N.getString("ImageComponent3DRetained0"));
+ }
+
+ }
+ }
return bi;
}
@@ -127,13 +242,12 @@ class ImageComponent3DRetained extends ImageComponentRetained {
* @return a new BufferedImage objects created from the
* image at the specified index in this ImageComponent3D object
*/
- final RenderedImage getImage(int index) {
+ RenderedImage getImage(int index) {
if (!byReference) {
- if (imageDirty[index]) {
- retrieveBufferedImage(index);
- }
+ return imageData.createBufferedImage(index);
}
- return bImage[index];
+
+ return (RenderedImage) getRefImage(index);
}
/**
@@ -149,17 +263,32 @@ class ImageComponent3DRetained extends ImageComponentRetained {
// call the user supplied updateData method to update the data
updater.updateData((ImageComponent3D)source, index, x, y, width, height);
+ RenderedImage refImage = (RenderedImage) getRefImage(index);
+ assert (refImage != null);
+ assert (imageData != null);
+
+
// update the internal copy of the image data if a copy has been
// made
- if (imageYupAllocated) {
- copyImage(bImage[0], (x + bImage[0].getMinX()),
- (y + bImage[0].getMinY()), imageYup, x, y,
- true, index, width, height, storedYupFormat,
- bytesPerYupPixelStored);
+ int srcX = x + refImage.getMinX();
+ int srcY = y + refImage.getMinY();
+
+ if (imageTypeIsSupported) {
+ if (refImage instanceof BufferedImage) {
+ copyImageLineByLine((BufferedImage)refImage, srcX, srcY, x, y, index, width, height, imageData);
+ } else {
+ copySupportedImageToImageData(refImage, srcX, srcY, x, y, index, width, height, imageData);
+ }
+ } else {
+ // image type is unsupported, need to create a supported local copy.
+ // TODO : Should look into borrow code from JAI to convert to right format.
+ if (refImage instanceof BufferedImage) {
+ copyUnsupportedImageToImageData((BufferedImage)refImage, srcX, srcY, x, y, index, width, height, imageData);
+ } else {
+ copyUnsupportedImageToImageData(refImage, srcX, srcY, x, y, index, width, height, imageData);
+ }
}
-
- imageDirty[index] = true;
-
+
geomLock.unLock();
@@ -170,7 +299,7 @@ class ImageComponent3DRetained extends ImageComponentRetained {
ImageComponentUpdateInfo info;
- info = VirtualUniverse.mc.getFreeImageUpdateInfo();
+ info = new ImageComponentUpdateInfo();
info.x = x;
info.y = y;
info.z = index;
@@ -184,15 +313,37 @@ class ImageComponent3DRetained extends ImageComponentRetained {
void setSubImage(int index, RenderedImage image, int width, int height,
int srcX, int srcY, int dstX, int dstY) {
- geomLock.getLock();
-
- if (imageYupAllocated) {
- copyImage(image, srcX, srcY, imageYup, dstX, dstY,
- true, index, width, height, storedYupFormat,
- bytesPerYupPixelStored);
+ if(!isSubImageTypeEqual(image)) {
+ throw new IllegalStateException(
+ J3dI18N.getString("ImageComponent2D6"));
}
- imageDirty[index] = true;
+ // Can't be byReference
+ assert (!byReference);
+ assert (imageData != null);
+
+ geomLock.getLock();
+
+ if (imageTypeIsSupported) {
+ // Either not byRef or not yUp or not both
+ // System.err.println("ImageComponen3DRetained.setSubImage() : (imageTypeSupported ) --- (1)");
+ if (image instanceof BufferedImage) {
+ copyImageLineByLine((BufferedImage)image, srcX, srcY, dstX, dstY, index, width, height, imageData);
+ }
+ else {
+ copySupportedImageToImageData(image, srcX, srcY, dstX, dstY, index, width, height, imageData);
+ }
+ } else {
+ // image type is unsupported, need to create a supported local copy.
+ // TODO : Should look into borrow code from JAI to convert to right format.
+ // System.err.println("ImageComponent3DRetained.setSubImage() : (imageTypeSupported == false) --- (2)");
+ if (image instanceof BufferedImage) {
+ copyUnsupportedImageToImageData((BufferedImage)image, srcX, srcY, dstX, dstY, index, width, height, imageData);
+ }
+ else {
+ copyUnsupportedImageToImageData(image, srcX, srcY, dstX, dstY, index, width, height, imageData);
+ }
+ }
geomLock.unLock();
@@ -204,7 +355,7 @@ class ImageComponent3DRetained extends ImageComponentRetained {
ImageComponentUpdateInfo info;
- info = VirtualUniverse.mc.getFreeImageUpdateInfo();
+ info = new ImageComponentUpdateInfo();
info.x = dstX;
info.y = dstY;
info.z = index;
@@ -214,4 +365,35 @@ class ImageComponent3DRetained extends ImageComponentRetained {
sendMessage(SUBIMAGE_CHANGED, info);
}
}
+
+ ImageComponentRetained createNextLevelMipMapImage() {
+
+ int xScale, yScale, newWidth, newHeight;
+
+ if (width > 1) {
+ newWidth = width >> 1;
+ xScale = 2;
+ } else {
+ newWidth = 1;
+ xScale = 1;
+ }
+ if (height > 1) {
+ newHeight = height >> 1;
+ yScale = 2;
+ } else {
+ newHeight = 1;
+ yScale = 1;
+ }
+
+ ImageComponent3DRetained newImage = new ImageComponent3DRetained();
+ newImage.processParams(getFormat(), newWidth, newHeight, depth);
+ newImage.imageData = newImage.createRenderedImageDataObject(null);
+
+ for (int i = 0; i < depth; i++) {
+ newImage.scaleImage(xScale, yScale, depth, this);
+ }
+
+ return newImage;
+
+ }
}
diff --git a/src/classes/share/javax/media/j3d/ImageComponentRetained.java b/src/classes/share/javax/media/j3d/ImageComponentRetained.java
index c62ca24..2279b89 100644
--- a/src/classes/share/javax/media/j3d/ImageComponentRetained.java
+++ b/src/classes/share/javax/media/j3d/ImageComponentRetained.java
@@ -12,10 +12,17 @@
package javax.media.j3d;
+import java.nio.Buffer;
import java.util.*;
import java.awt.image.*;
import java.awt.color.ColorSpace;
-import java.awt.Transparency;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.RenderedImage;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+
/**
* Abstract class that is used to define 2D or 3D ImageComponent classes
@@ -25,1033 +32,438 @@ import java.awt.Transparency;
*/
abstract class ImageComponentRetained extends NodeComponentRetained {
- int format; // PixelArray format (RGB, RGBA, ALPHA, etc.)
+
+ // change flag
+ static final int IMAGE_CHANGED = 0x01;
+ static final int SUBIMAGE_CHANGED = 0x02;
+
+ static final int TYPE_BYTE_BGR = 0x1;
+ static final int TYPE_BYTE_RGB = 0x2;
+ static final int TYPE_BYTE_ABGR = 0x4;
+ static final int TYPE_BYTE_RGBA = 0x8;
+ static final int TYPE_BYTE_LA = 0x10;
+ static final int TYPE_BYTE_GRAY = 0x20;
+ static final int TYPE_USHORT_GRAY = 0x40;
+ static final int TYPE_INT_BGR = 0x80;
+ static final int TYPE_INT_RGB = 0x100;
+ static final int TYPE_INT_ARGB = 0x200;
+
+ enum ImageFormatType {
+ TYPE_UNKNOWN,
+ TYPE_BYTE_BGR,
+ TYPE_BYTE_RGB,
+ TYPE_BYTE_ABGR,
+ TYPE_BYTE_RGBA,
+ TYPE_BYTE_LA,
+ TYPE_BYTE_GRAY,
+ TYPE_USHORT_GRAY,
+ TYPE_INT_BGR,
+ TYPE_INT_RGB,
+ TYPE_INT_ARGB
+ }
+
+ static final int IMAGE_DATA_TYPE_BYTE_ARRAY = 0x1000;
+ static final int IMAGE_DATA_TYPE_INT_ARRAY = 0x2000;
+ static final int IMAGE_DATA_TYPE_BYTE_BUFFER = 0x4000;
+ static final int IMAGE_DATA_TYPE_INT_BUFFER = 0x8000;
+
+ enum ImageDataType {
+ TYPE_NULL,
+ TYPE_BYTE_ARRAY,
+ TYPE_INT_ARRAY,
+ TYPE_BYTE_BUFFER,
+ TYPE_INT_BUFFER
+ }
+
+ private int apiFormat; // The format set by user.
int width; // Width of PixelArray
int height; // Height of PixelArray
- byte[][] imageYdown = new byte[1][]; // 2D array of pixel values in
- // one of various formats - Y downwards
- byte[] imageYup; // 2D or 3D array of pixel values in
- // one of various formats - Y upwards
-
- int bytesPerPixel; // computed from input format
- boolean usedByRaster = false; // used by a raster object?
- boolean usedByTexture = false; // used by a texture object?
-
- boolean byReference = false; // Is the imageComponent by reference
- boolean yUp = false;
-
- // array of Buffered image
- // This will store the refImage array, if the imagecomponent
- // is by reference
- RenderedImage[] bImage;
- boolean[] imageDirty; // array of image dirty flag
-
- boolean noAlpha = false;
-
- // Format of the Yup and Ydown image
- // in the case of "by Copy" it is RGBA
- // In the case of "by ref" it may be one of the original
- // formats supported by OpenGL
- /*
- int storedFormat;
- */
- int bytesPerPixelIfStored; // Number of bytes if a copy is made
- int storedYupFormat;
- int storedYdownFormat;
-
- int bytesPerYupPixelStored;
- int bytesPerYdownPixelStored;
+ int depth; // Depth of PixelArray
+ boolean byReference = false; // Is the imageComponent by reference
+ boolean yUp = false;
+ boolean imageTypeIsSupported;
+ boolean abgrSupported = true;
+ boolean npotSupported = true;
+ private int unitsPerPixel;
+ private int numberOfComponents;
- int internalFormat; // Used when a copy is made, RGBA, LA, L
- boolean imageYupAllocated = false;
- boolean imageYdownAllocated = false;
-
- // If cache is dirty (clearLive, setLive has occureed), then
- // extension based cache needs to be re-evaluated
- boolean imageYupCacheDirty = false;
- boolean imageYdownCacheDirty = false;
+ // Note : This is unuse for NioImageBuffer.
+ // The image type of the input image. Using the constant in BufferedImage
+ private int imageType;
-
- static final int BYTE_RGBA = 0x1;
- static final int BYTE_ABGR = 0x2;
- static final int BYTE_GRAY = 0x4;
- static final int USHORT_GRAY = 0x8;
- static final int BYTE_LA = 0x10;
- static final int BYTE_BGR = 0x20;
- static final int BYTE_RGB = 0x40;
-
- int imageYupClass = 0;
- int imageYdownClass = 0;
- static final int BUFFERED_IMAGE = 0x1;
- static final int RENDERED_IMAGE = 0x2;
+ private ImageFormatType imageFormatType = ImageFormatType.TYPE_UNKNOWN;
+ ImageData imageData;
+ private ImageComponent.ImageClass imageClass = ImageComponent.ImageClass.BUFFERED_IMAGE;
- // change flag
- static final int IMAGE_CHANGED = 0x01;
- static final int SUBIMAGE_CHANGED = 0x02;
+ // To support Non power of 2 (NPOT) image
+ // if enforceNonPowerOfTwoSupport is true (for examples Raster and Background)
+ // and imageData is a non power of 2 image
+ // and graphics driver doesn't support NPOT extension.
+ private ImageData imageDataPowerOfTwo;
+ private AffineTransformOp powerOfTwoATOp;
+ private boolean enforceNonPowerOfTwoSupport = false;
+ private boolean usedByOffScreenCanvas = false;
+
+ // This will store the referenced Images for reference case.
+ // private RenderedImage refImage[] = null;
+ private Object refImage[] = null;
// Lock used in the "by ref case"
GeometryLock geomLock = new GeometryLock();
-
- int minTileX = 0;
- int minTileY = 0;
- int minTileZ = 0;
-
+
int tilew = 0;
int tileh = 0;
- int tiled = 0;
-
int numXTiles = 0;
int numYTiles = 0;
- int numZTiles = 0;
-
- int tileGridXOffset = 0;
- int tileGridYOffset = 0;
-
-
- int minX = 0;
- int minY = 0;
// lists of Node Components that are referencing this ImageComponent
// object. This list is used to notify the referencing node components
// of any changes of this ImageComponent.
-
ArrayList userList = new ArrayList();
-
+
+ abstract ImageComponentRetained createNextLevelMipMapImage();
+
/**
* Retrieves the width of this image component object.
* @return the width of this image component object
- */
- final int getWidth() {
+ */
+ int getWidth() {
return width;
}
-
+
/**
* Retrieves the height of this image component object.
* @return the height of this image component object
- */
- final int getHeight() {
+ */
+ int getHeight() {
return height;
}
-
- /**
- * Retrieves the format of this image component object.
- * @return the format of this image component object
- */
- final int getFormat() {
- return format;
- }
-
+
/**
- * Check if ImageComponent parameters have valid values..
+ * Retrieves the apiFormat of this image component object.
+ *
+ * @return the apiFormat of this image component object
*/
- void processParams(int format, int width, int height, int depth) {
- if (width < 1)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained0"));
-
- if (height < 1)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained1"));
-
- if (depth < 1)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained2"));
-
- if (format < 1 || format > ImageComponent.FORMAT_TOTAL)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained3"));
- this.format = format;
- this.width = width;
- this.height = height;
- imageDirty = new boolean[depth];
- for (int i=0; i< depth; i++)
- imageDirty[i] = false;
- bImage = new RenderedImage[depth];
-
- noAlpha = (format == ImageComponent.FORMAT_RGB ||
- format == ImageComponent.FORMAT_RGB4 ||
- format == ImageComponent.FORMAT_R3_G3_B2 ||
- format == ImageComponent.FORMAT_RGB5);
-
- // If the format is 8bit per component, we may send it down
- // to OpenGL directly if its by ref case
- switch (format) {
- case ImageComponent.FORMAT_RGB:// same as ImageComponent.FORMAT_RGB8
- bytesPerPixel = 3;
- bytesPerPixelIfStored = 4;
- internalFormat = BYTE_RGBA;
- break;
- case ImageComponent.FORMAT_RGBA:// same as ImageComponent.FORMAT_RGBA8
- bytesPerPixel = 4;
- bytesPerPixelIfStored = 4;
- internalFormat = BYTE_RGBA;
- break;
- case ImageComponent.FORMAT_RGB5:
- bytesPerPixel = 2;
- bytesPerPixelIfStored = 4;
- internalFormat = BYTE_RGBA;
- break;
- case ImageComponent.FORMAT_RGB5_A1:
- bytesPerPixel = 2;
- bytesPerPixelIfStored = 4;
- internalFormat = BYTE_RGBA;
- break;
- case ImageComponent.FORMAT_RGB4:
- bytesPerPixel = 2;
- bytesPerPixelIfStored = 4;
- internalFormat = BYTE_RGBA;
- break;
- case ImageComponent.FORMAT_RGBA4:
- bytesPerPixel = 2;
- bytesPerPixelIfStored = 4;
- internalFormat = BYTE_RGBA;
- break;
- case ImageComponent.FORMAT_R3_G3_B2:
- bytesPerPixel = 1;
- bytesPerPixelIfStored = 4;
- internalFormat = BYTE_RGBA;
- break;
- case ImageComponent.FORMAT_LUM4_ALPHA4:
- bytesPerPixel = 1;
- bytesPerPixelIfStored = 2;
- internalFormat = BYTE_LA;
- break;
- case ImageComponent.FORMAT_LUM8_ALPHA8:
- bytesPerPixel = 2;
- bytesPerPixelIfStored = 2;
- internalFormat = BYTE_LA;
- break;
- case ImageComponent.FORMAT_CHANNEL8:
- bytesPerPixel = 1;
- bytesPerPixelIfStored = 1;
- internalFormat = BYTE_GRAY;
- break;
- default:
- // ERROR
+ int getFormat() {
+ return apiFormat;
+ }
+
+ void setFormat(int format) {
+ this.apiFormat = format;
+ }
+
+ void setByReference(boolean byReference) {
+ this.byReference = byReference;
+ }
+
+ boolean isByReference() {
+ return byReference;
+ }
+
+ void setYUp( boolean yUp) {
+ this.yUp = yUp;
+ }
+
+ boolean isYUp() {
+ return yUp;
+ }
+
+ int getUnitsPerPixel() {
+ return unitsPerPixel;
+ }
+
+ void setUnitsPerPixel(int ipp) {
+ unitsPerPixel = ipp;
+ }
+
+ ImageComponent.ImageClass getImageClass() {
+ return imageClass;
+ }
+
+ void setImageClass(RenderedImage image) {
+ if(image instanceof BufferedImage) {
+ imageClass = ImageComponent.ImageClass.BUFFERED_IMAGE;
+ } else {
+ imageClass = ImageComponent.ImageClass.RENDERED_IMAGE;
}
}
-
- void setTextureRef() {
- usedByTexture = true;
+
+ void setImageClass(NioImageBuffer image) {
+ imageClass = ImageComponent.ImageClass.NIO_IMAGE_BUFFER;
}
-
- void setRasterRef() {
- usedByRaster = true;
+
+ void setEnforceNonPowerOfTwoSupport(boolean npot) {
+ this.enforceNonPowerOfTwoSupport = npot;
}
-
-
- boolean formatMatches(int format, RenderedImage ri) {
-
- // there is no RenderedImage format that matches BYTE_LA
- if (format == BYTE_LA) {
- return false;
- }
-
- int riFormat = getImageType(ri);
-
- if ((format == BYTE_ABGR && riFormat == BufferedImage.TYPE_4BYTE_ABGR)
- || (format == BYTE_BGR && riFormat == BufferedImage.TYPE_3BYTE_BGR)
- || (format == BYTE_GRAY && riFormat == BufferedImage.TYPE_BYTE_GRAY)
- || (format == USHORT_GRAY && riFormat ==
- BufferedImage.TYPE_USHORT_GRAY)) {
- return true;
- }
-
- if (riFormat == BufferedImage.TYPE_CUSTOM) {
- if (is4ByteRGBAOr3ByteRGB(ri)) {
- int numBands = ri.getSampleModel().getNumBands();
- if (numBands == 3 && format == BYTE_RGB) {
- return true;
- } else if (numBands == 4 && format == BYTE_RGBA) {
- return true;
- }
- }
- }
-
- return false;
+
+ void setUsedByOffScreen(boolean used) {
+ usedByOffScreenCanvas = used;
}
-
- /**
- * copy complete region of a RenderedImage
- */
- final void copyImage(RenderedImage ri, byte[] image,
- boolean usedByTexture, int depth,
- int imageFormat, int imageBytesPerPixel) {
-
- if (ri instanceof BufferedImage) {
- copyImage((BufferedImage)ri, 0, 0, image, 0, 0,
- usedByTexture, depth, width, height,
- imageFormat, imageBytesPerPixel);
- } else {
- copyImage(ri, ri.getMinX(), ri.getMinY(),
- image, 0, 0, usedByTexture, depth, width, height,
- imageFormat, imageBytesPerPixel);
- }
+
+ boolean getUsedByOffScreen() {
+ return usedByOffScreenCanvas;
}
-
-
- /**
- * copy subregion of a RenderedImage
- */
- final void copyImage(RenderedImage ri, int srcX, int srcY,
- byte[] image, int dstX, int dstY,
- boolean usedByTexture, int depth,
- int copywidth, int copyheight,
- int imageFormat, int imageBytesPerPixel) {
-
- if (ri instanceof BufferedImage) {
- copyImage((BufferedImage)ri, srcX, srcY, image, dstX, dstY,
- usedByTexture, depth, copywidth, copyheight,
- imageFormat, imageBytesPerPixel);
- return;
- }
-
-
- int w, h, i, j, m, n;
- int dstBegin;
- Object pixel = null;
- java.awt.image.Raster ras;
- int lineBytes = width * imageBytesPerPixel; // nbytes per line in
- // dst image buffer
- int sign; // -1 for going down
- int dstLineBytes; // sign * lineBytes
- int tileStart; // destination buffer offset
- // at the next left most tile
-
- int offset;
-
- ColorModel cm = ri.getColorModel();
-
- int xoff = ri.getTileGridXOffset(); // tile origin x offset
- int yoff = ri.getTileGridYOffset(); // tile origin y offset
- int minTileX = ri.getMinTileX(); // min tile x index
- int minTileY = ri.getMinTileY(); // min tile y index
- tilew = ri.getTileWidth(); // tile width in pixels
- tileh = ri.getTileHeight(); // tile height in pixels
-
-
- // determine the first tile of the image
-
- float mt;
-
- mt = (float)(srcX - xoff) / (float)tilew;
- if (mt < 0) {
- minTileX = (int)(mt - 1);
- } else {
- minTileX = (int)mt;
- }
-
- mt = (float)(srcY - yoff) / (float)tileh;
- if (mt < 0) {
- minTileY = (int)(mt - 1);
- } else {
- minTileY = (int)mt;
- }
-
-
- // determine the pixel offset of the upper-left corner of the
- // first tile
-
- int startXTile = minTileX * tilew + xoff;
- int startYTile = minTileY * tileh + yoff;
-
-
- // image dimension in the first tile
-
- int curw = (startXTile + tilew - srcX);
- int curh = (startYTile + tileh - srcY);
-
-
- // check if the to-be-copied region is less than the tile image
- // if so, update the to-be-copied dimension of this tile
-
- if (curw > copywidth) {
- curw = copywidth;
- }
-
- if (curh > copyheight) {
- curh = copyheight;
- }
-
-
- // save the to-be-copied width of the left most tile
-
- int startw = curw;
-
-
- // temporary variable for dimension of the to-be-copied region
-
- int tmpw = copywidth;
- int tmph = copyheight;
-
-
- // offset of the first pixel of the tile to be copied; offset is
- // relative to the upper left corner of the title
-
- int x = srcX - startXTile;
- int y = srcY - startYTile;
-
-
- // determine the number of tiles in each direction that the
- // image spans
-
- numXTiles = (copywidth + x) / tilew;
- numYTiles = (copyheight + y) / tileh;
-
- if (((float)(copywidth + x ) % (float)tilew) > 0) {
- numXTiles += 1;
- }
-
- if (((float)(copyheight + y ) % (float)tileh) > 0) {
- numYTiles += 1;
- }
-
-/*
- System.out.println("-----------------------------------------------");
- System.out.println("minTileX= " + minTileX + " minTileY= " + minTileY);
- System.out.println("numXTiles= " + numXTiles + " numYTiles= " + numYTiles);
- System.out.println("tilew= " + tilew + " tileh= " + tileh);
- System.out.println("xoff= " + xoff + " yoff= " + yoff);
- System.out.println("startXTile= " + startXTile + " startYTile= " + startYTile);
- System.out.println("srcX= " + srcX + " srcY= " + srcY);
- System.out.println("copywidth= " + copywidth + " copyheight= " + copyheight);
-
- System.out.println("rminTileX= " + ri.getMinTileX() + " rminTileY= " + ri.getMinTileY());
- System.out.println("rnumXTiles= " + ri.getNumXTiles() + " rnumYTiles= " + ri.getNumYTiles());
-*/
-
- if ((!yUp && usedByTexture) ||
- (yUp && !usedByTexture)) {
-
- // destination buffer offset
-
- tileStart = ((height - dstY - 1) * width + dstX)
- * imageBytesPerPixel;
-
- sign = -1;
- dstLineBytes = -lineBytes;
- } else {
-
- // destination buffer offset
-
- tileStart = (dstY * width + dstX) * imageBytesPerPixel;
- sign = 1;
- dstLineBytes = lineBytes;
- }
-
-/*
- System.out.println("tileStart= " + tileStart + " dstLineBytes= " + dstLineBytes);
- System.out.println("startw= " + startw);
-*/
-
- // allocate memory for a pixel
-
- ras = ri.getTile(minTileX,minTileY);
- pixel = getDataElementBuffer(ras);
-
- if (formatMatches(imageFormat, ri)) {
- byte[] src;
- int srcOffset, dstOffset;
- int tileLineBytes= tilew * imageBytesPerPixel;
- int copyBytes;
-
- for (n = minTileY; n < minTileY+numYTiles; n++) {
-
- dstBegin = tileStart; // destination buffer offset
- tmpw = copywidth; // reset the width to be copied
- curw = startw; // reset the width to be copied of
- // the left most tile
- x = srcX - startXTile; // reset the starting x offset of
- // the left most tile
-
- for (m = minTileX; m < minTileX+numXTiles; m++) {
-
- // retrieve the raster for the next tile
- ras = ri.getTile(m,n);
- src = ((DataBufferByte)ras.getDataBuffer()).getData();
-
- srcOffset = (y * tilew + x) * imageBytesPerPixel;
- dstOffset = dstBegin;
-
- copyBytes = curw * imageBytesPerPixel;
-
- //System.out.println("curh = "+curh+" curw = "+curw);
- //System.out.println("x = "+x+" y = "+y);
-
- for (h = 0; h < curh; h++) {
- System.arraycopy(src, srcOffset, image, dstOffset,
- copyBytes);
- srcOffset += tileLineBytes;
- dstOffset += dstLineBytes;
- }
-
- // advance the destination buffer offset
- dstBegin += curw * imageBytesPerPixel;
-
- // move to the next tile in x direction
- x = 0;
-
- // determine the width of copy region of the next tile
-
- tmpw -= curw;
- if (tmpw < tilew) {
- curw = tmpw;
- } else {
- curw = tilew;
- }
- }
-
-
- // we are done copying an array of tiles in the x direction
- // advance the tileStart offset
-
- tileStart += width * imageBytesPerPixel * curh * sign;
-
-
- // move to the next set of tiles in y direction
- y = 0;
-
- // determine the height of copy region for the next set
- // of tiles
- tmph -= curh;
- if (tmph < tileh) {
- curh = tmph;
- } else {
- curh = tileh;
- }
- }
- return;
- }
-
- switch(format) {
- case ImageComponent.FORMAT_RGBA8:
- case ImageComponent.FORMAT_RGB5_A1:
- case ImageComponent.FORMAT_RGBA4: {
- // System.out.println("Case 1: byReference = "+byReference);
- for (n = minTileY; n < minTileY+numYTiles; n++) {
-
- dstBegin = tileStart; // destination buffer offset
- tmpw = copywidth; // reset the width to be copied
- curw = startw; // reset the width to be copied of
- // the left most tile
- x = srcX - startXTile; // reset the starting x offset of
- // the left most tile
-
- for (m = minTileX; m < minTileX+numXTiles; m++) {
-
- // retrieve the raster for the next tile
- ras = ri.getTile(m,n);
-
- j = dstBegin;
- offset = 0;
-
- //System.out.println("curh = "+curh+" curw = "+curw);
- //System.out.println("x = "+x+" y = "+y);
-
- for (h = y; h < (y + curh); h++) {
- // System.out.println("j = "+j);
- for (w = x; w < (x + curw); w++) {
- ras.getDataElements(w, h, pixel);
- image[j++] = (byte)cm.getRed(pixel);
- image[j++] = (byte)cm.getGreen(pixel);
- image[j++] = (byte)cm.getBlue(pixel);
- image[j++] = (byte)cm.getAlpha(pixel);
- }
- offset += dstLineBytes;
- j = dstBegin + offset;
- }
-
- // advance the destination buffer offset
- dstBegin += curw * imageBytesPerPixel;
-
- // move to the next tile in x direction
- x = 0;
-
- // determine the width of copy region of the next tile
-
- tmpw -= curw;
- if (tmpw < tilew) {
- curw = tmpw;
- } else {
- curw = tilew;
- }
- }
-
-
- // we are done copying an array of tiles in the x direction
- // advance the tileStart offset
-
- tileStart += width * imageBytesPerPixel * curh * sign;
-
-
- // move to the next set of tiles in y direction
- y = 0;
-
- // determine the height of copy region for the next set
- // of tiles
- tmph -= curh;
- if (tmph < tileh) {
- curh = tmph;
- } else {
- curh = tileh;
- }
- }
- }
- break;
- case ImageComponent.FORMAT_RGB8:
- case ImageComponent.FORMAT_RGB5:
- case ImageComponent.FORMAT_RGB4:
- case ImageComponent.FORMAT_R3_G3_B2: {
- for (n = minTileY; n < minTileY+numYTiles; n++) {
-
- dstBegin = tileStart; // destination buffer offset
- tmpw = copywidth; // reset the width to be copied
- curw = startw; // reset the width to be copied of
- // the left most tile
- x = srcX - startXTile; // reset the starting x offset of
- // the left most tile
-
- for (m = minTileX; m < minTileX+numXTiles; m++) {
-
- // retrieve the raster for the next tile
- ras = ri.getTile(m,n);
-
- j = dstBegin;
- offset = 0;
-
- //System.out.println("curh = "+curh+" curw = "+curw);
- //System.out.println("x = "+x+" y = "+y);
-
- for (h = y; h < (y + curh); h++) {
- // System.out.println("j = "+j);
- for (w = x; w < (x + curw); w++) {
- ras.getDataElements(w, h, pixel);
- image[j++] = (byte)cm.getRed(pixel);
- image[j++] = (byte)cm.getGreen(pixel);
- image[j++] = (byte)cm.getBlue(pixel);
- image[j++] = (byte)255;
- }
- offset += dstLineBytes;
- j = dstBegin + offset;
- }
-
- // advance the destination buffer offset
- dstBegin += curw * imageBytesPerPixel;
-
- // move to the next tile in x direction
- x = 0;
-
- // determine the width of copy region of the next tile
-
- tmpw -= curw;
- if (tmpw < tilew) {
- curw = tmpw;
- } else {
- curw = tilew;
- }
- }
-
-
- // we are done copying an array of tiles in the x direction
- // advance the tileStart offset
-
- tileStart += width * imageBytesPerPixel * curh * sign;
-
-
- // move to the next set of tiles in y direction
- y = 0;
-
- // determine the height of copy region for the next set
- // of tiles
- tmph -= curh;
- if (tmph < tileh) {
- curh = tmph;
- } else {
- curh = tileh;
- }
- }
- }
- break;
- case ImageComponent.FORMAT_LUM8_ALPHA8:
- case ImageComponent.FORMAT_LUM4_ALPHA4: {
- for (n = minTileY; n < minTileY+numYTiles; n++) {
-
- dstBegin = tileStart; // destination buffer offset
- tmpw = copywidth; // reset the width to be copied
- curw = startw; // reset the width to be copied of
- // the left most tile
- x = srcX - startXTile; // reset the starting x offset of
- // the left most tile
-
- for (m = minTileX; m < minTileX+numXTiles; m++) {
-
- // retrieve the raster for the next tile
- ras = ri.getTile(m,n);
-
- j = dstBegin;
- offset = 0;
-
- //System.out.println("curh = "+curh+" curw = "+curw);
- //System.out.println("x = "+x+" y = "+y);
-
- for (h = y; h < (y + curh); h++) {
- // System.out.println("j = "+j);
- for (w = x; w < (x + curw); w++) {
- ras.getDataElements(w, h, pixel);
- image[j++] = (byte)cm.getRed(pixel);
- image[j++] = (byte)cm.getAlpha(pixel);
- }
- offset += dstLineBytes;
- j = dstBegin + offset;
- }
-
- // advance the destination buffer offset
- dstBegin += curw * imageBytesPerPixel;
-
- // move to the next tile in x direction
- x = 0;
-
- // determine the width of copy region of the next tile
-
- tmpw -= curw;
- if (tmpw < tilew) {
- curw = tmpw;
- } else {
- curw = tilew;
- }
- }
-
-
- // we are done copying an array of tiles in the x direction
- // advance the tileStart offset
-
- tileStart += width * imageBytesPerPixel * curh * sign;
-
-
- // move to the next set of tiles in y direction
- y = 0;
-
- // determine the height of copy region for the next set
- // of tiles
- tmph -= curh;
- if (tmph < tileh) {
- curh = tmph;
- } else {
- curh = tileh;
- }
- }
- }
- break;
- case ImageComponent.FORMAT_CHANNEL8: {
- for (n = minTileY; n < minTileY+numYTiles; n++) {
-
- dstBegin = tileStart; // destination buffer offset
- tmpw = copywidth; // reset the width to be copied
- curw = startw; // reset the width to be copied of
- // the left most tile
- x = srcX - startXTile; // reset the starting x offset of
- // the left most tile
-
- for (m = minTileX; m < minTileX+numXTiles; m++) {
-
- // retrieve the raster for the next tile
- ras = ri.getTile(m,n);
-
- j = dstBegin;
- offset = 0;
-
- //System.out.println("curh = "+curh+" curw = "+curw);
- //System.out.println("x = "+x+" y = "+y);
-
- for (h = y; h < (y + curh); h++) {
- // System.out.println("j = "+j);
- for (w = x; w < (x + curw); w++) {
- ras.getDataElements(w, h, pixel);
- image[j++] = (byte)cm.getRed(pixel);
- }
- offset += dstLineBytes;
- j = dstBegin + offset;
- }
-
- // advance the destination buffer offset
- dstBegin += curw * imageBytesPerPixel;
-
- // move to the next tile in x direction
- x = 0;
-
- // determine the width of copy region of the next tile
-
- tmpw -= curw;
- if (tmpw < tilew) {
- curw = tmpw;
- } else {
- curw = tilew;
- }
- }
-
-
- // we are done copying an array of tiles in the x direction
- // advance the tileStart offset
-
- tileStart += width * imageBytesPerPixel * curh * sign;
-
-
- // move to the next set of tiles in y direction
- y = 0;
-
- // determine the height of copy region for the next set
- // of tiles
- tmph -= curh;
- if (tmph < tileh) {
- curh = tmph;
- } else {
- curh = tileh;
- }
- }
- }
- break;
- default:
- break;
- }
+
+ int getNumberOfComponents() {
+ return numberOfComponents;
}
-
-
- /**
- * Copy entire image data from Buffered Image to
- * ImageComponent's internal representation
- */
- final void copyImage(BufferedImage bi, byte[] image,
- boolean usedByTexture, int depth,
- int imageFormat, int imageBytesPerPixel) {
- copyImage(bi, 0, 0, image, 0, 0, usedByTexture, depth,
- width, height, imageFormat, imageBytesPerPixel);
+
+ void setNumberOfComponents(int numberOfComponents) {
+ this.numberOfComponents = numberOfComponents;
}
-
- /**
- * Copy specified region of image data from Buffered Image to
- * ImageComponent's internal representation
- */
- final void copyImage(BufferedImage bi, int srcX, int srcY,
- byte[] image, int dstX, int dstY, boolean usedByTexture,
- int depth, int copywidth, int copyheight,
- int imageFormat, int imageBytesPerPixel) {
-
- int w, h, i, j;
- int rowBegin, // src begin row index
- srcBegin, // src begin offset
- dstBegin, // dst begin offset
- rowInc, // row increment
- // -1 --- ydown
- // 1 --- yup
- row;
- Object pixel = null;
-
- rowBegin = srcY;
- rowInc = 1;
-
- int dstBytesPerRow = width * imageBytesPerPixel; // bytes per row
- // in dst image
-
- if ((!yUp && usedByTexture) || (yUp && !usedByTexture)) {
- dstBegin = (depth * width * height +
- (height - dstY - 1) * width + dstX) *
- imageBytesPerPixel;
-
- dstBytesPerRow = - 1 * dstBytesPerRow;
-
- } else {
- dstBegin = (dstY * width + dstX) * imageBytesPerPixel;
- }
-
- // if the image format matches the format of the incoming
- // buffered image, then do a straight copy, else do the
- // format conversion while copying the data
-
- if (formatMatches(imageFormat, bi)) {
- byte[] byteData =
- ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- int copyBytes = copywidth * imageBytesPerPixel;
- int scanline = width * imageBytesPerPixel;
-
- srcBegin = (rowBegin * width + srcX) * imageBytesPerPixel;
- for (h = 0; h < copyheight; h++) {
- System.arraycopy(byteData, srcBegin, image, dstBegin, copyBytes);
- dstBegin += dstBytesPerRow;
- srcBegin += scanline;
- }
- } else {
-
- int biType = bi.getType();
- if ((biType == BufferedImage.TYPE_INT_ARGB ||
- biType == BufferedImage.TYPE_INT_RGB) &&
- (format == ImageComponent.FORMAT_RGBA8 ||
- format == ImageComponent.FORMAT_RGB8)) {
-
- // optimized cases
-
- int[] intData =
- ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- int rowOffset = rowInc * width;
- int intPixel;
-
- srcBegin = rowBegin * width + srcX;
-
- if (biType == BufferedImage.TYPE_INT_ARGB &&
- format == ImageComponent.FORMAT_RGBA8) {
- for (h = 0; h < copyheight; h++) {
- i = srcBegin;
- j = dstBegin;
- for (w = 0; w < copywidth; w++, i++) {
- intPixel = intData[i];
- image[j++] = (byte)((intPixel >> 16) & 0xff);
- image[j++] = (byte)((intPixel >> 8) & 0xff);
- image[j++] = (byte)(intPixel & 0xff);
- image[j++] = (byte)((intPixel >> 24) & 0xff);
- }
- srcBegin += rowOffset;
- dstBegin += dstBytesPerRow;
- }
- } else { // format == ImageComponent.FORMAT_RGB8
- for (h = 0; h < copyheight; h++) {
- i = srcBegin;
- j = dstBegin;
- for (w = 0; w < copywidth; w++, i++) {
- intPixel = intData[i];
- image[j++] = (byte)((intPixel >> 16) & 0xff);
- image[j++] = (byte)((intPixel >> 8) & 0xff);
- image[j++] = (byte)(intPixel & 0xff);
- image[j++] = (byte)255;
- }
- srcBegin += rowOffset;
- dstBegin += dstBytesPerRow;
- }
- }
-
- } else if ((biType == BufferedImage.TYPE_BYTE_GRAY) &&
- (format == ImageComponent.FORMAT_CHANNEL8)) {
-
- byte[] byteData =
- ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- int rowOffset = rowInc * width;
-
- j = dstBegin;
- srcBegin = rowBegin * width + srcX;
-
- for (h = 0; h < copyheight;
- h++, j += width, srcBegin += rowOffset) {
- System.arraycopy(byteData, srcBegin, image, j, copywidth);
- }
- } else {
- // non-optimized cases
-
- WritableRaster ras = bi.getRaster();
- ColorModel cm = bi.getColorModel();
- pixel = getDataElementBuffer(ras);
-
- switch(format) {
- case ImageComponent.FORMAT_RGBA8:
- case ImageComponent.FORMAT_RGB5_A1:
- case ImageComponent.FORMAT_RGBA4: {
- for (row = rowBegin, h = 0;
- h < copyheight; h++, row += rowInc) {
- j = dstBegin;
- for (w = srcX; w < (copywidth + srcX); w++) {
- ras.getDataElements(w, row, pixel);
- image[j++] = (byte)cm.getRed(pixel);
- image[j++] = (byte)cm.getGreen(pixel);
- image[j++] = (byte)cm.getBlue(pixel);
- image[j++] = (byte)cm.getAlpha(pixel);
- }
- dstBegin += dstBytesPerRow;
- }
- }
+
+ int getImageDataTypeIntValue() {
+ int idtValue = -1;
+ switch(imageData.imageDataType) {
+ case TYPE_BYTE_ARRAY:
+ idtValue = IMAGE_DATA_TYPE_BYTE_ARRAY;
break;
-
- case ImageComponent.FORMAT_RGB8:
- case ImageComponent.FORMAT_RGB5:
- case ImageComponent.FORMAT_RGB4:
- case ImageComponent.FORMAT_R3_G3_B2: {
- for (row = rowBegin, h = 0;
- h < copyheight; h++, row += rowInc) {
- j = dstBegin;
- for (w = srcX; w < (copywidth + srcX); w++) {
- ras.getDataElements(w, row, pixel);
- image[j++] = (byte)cm.getRed(pixel);
- image[j++] = (byte)cm.getGreen(pixel);
- image[j++] = (byte)cm.getBlue(pixel);
- image[j++] = (byte)255;
- }
- dstBegin += dstBytesPerRow;
- }
- }
+ case TYPE_INT_ARRAY:
+ idtValue = IMAGE_DATA_TYPE_INT_ARRAY;
break;
-
- case ImageComponent.FORMAT_LUM8_ALPHA8:
- case ImageComponent.FORMAT_LUM4_ALPHA4: {
- for (row = rowBegin, h = 0;
- h < copyheight; h++, row += rowInc) {
- j = dstBegin;
- for (w = srcX; w < (copywidth + srcX); w++) {
- ras.getDataElements(w, row, pixel);
- image[j++] = (byte)cm.getRed(pixel);
- image[j++] = (byte)cm.getAlpha(pixel);
- }
- dstBegin += dstBytesPerRow;
- }
- }
- break;
-
- case ImageComponent.FORMAT_CHANNEL8: {
- for (row = rowBegin, h = 0;
- h < copyheight; h++, row += rowInc) {
- j = dstBegin;
- for (w = srcX; w < (copywidth + srcX); w++) {
- ras.getDataElements(w, row, pixel);
- image[j++] = (byte)cm.getRed(pixel);
- }
- dstBegin += dstBytesPerRow;
- }
+ case TYPE_BYTE_BUFFER:
+ idtValue = IMAGE_DATA_TYPE_BYTE_BUFFER;
+ break;
+ case TYPE_INT_BUFFER:
+ idtValue = IMAGE_DATA_TYPE_INT_BUFFER;
+ break;
+ default :
+ assert false;
+ }
+ return idtValue;
+
+ }
+
+ int getImageFormatTypeIntValue(boolean powerOfTwoData) {
+ int iftValue = -1;
+ switch(imageFormatType) {
+ case TYPE_BYTE_BGR:
+ iftValue = TYPE_BYTE_BGR;
+ break;
+ case TYPE_BYTE_RGB:
+ iftValue = TYPE_BYTE_RGB;
+ break;
+ case TYPE_BYTE_ABGR:
+ iftValue = TYPE_BYTE_ABGR;
+ break;
+ case TYPE_BYTE_RGBA:
+ if((imageDataPowerOfTwo != null) && (powerOfTwoData)) {
+ iftValue = TYPE_BYTE_ABGR;
}
- break;
+ else {
+ iftValue = TYPE_BYTE_RGBA;
}
+ break;
+ case TYPE_BYTE_LA:
+ iftValue = TYPE_BYTE_LA;
+ break;
+ case TYPE_BYTE_GRAY:
+ iftValue = TYPE_BYTE_GRAY;
+ break;
+ case TYPE_USHORT_GRAY:
+ iftValue = TYPE_USHORT_GRAY;
+ break;
+ case TYPE_INT_BGR:
+ iftValue = TYPE_INT_BGR;
+ break;
+ case TYPE_INT_RGB:
+ iftValue = TYPE_INT_RGB;
+ break;
+ case TYPE_INT_ARGB:
+ iftValue = TYPE_INT_ARGB;
+ break;
+ default:
+ throw new AssertionError();
+ }
+ return iftValue;
+ }
+
+ // Note: This method for RenderedImage, can't be used by NioImageBuffer.
+ int getImageType() {
+ return imageType;
+ }
+
+ void setImageFormatType(ImageFormatType ift) {
+ this.imageFormatType = ift;
+ }
+
+ ImageFormatType getImageFormatType() {
+ return this.imageFormatType;
+ }
+
+ void setRefImage(Object image, int index) {
+ this.refImage[index] = image;
+ }
+
+ Object getRefImage(int index) {
+ return this.refImage[index];
+ }
+
+ ImageData getImageData(boolean npotSupportNeeded) {
+ if(npotSupportNeeded) {
+ assert enforceNonPowerOfTwoSupport;
+ if(imageDataPowerOfTwo != null) {
+ return imageDataPowerOfTwo;
}
- }
- }
-
+ }
+ return imageData;
+ }
-
-
- final int getBytesStored(int f) {
- int val = 0;
- switch(f) {
- case BYTE_RGBA:
- val = 4;
- break;
- case BYTE_ABGR:
- val = 4;
- break;
- case BYTE_GRAY:
- val = 1;
- break;
- case USHORT_GRAY:
- val = 2;
- break;
- case BYTE_LA:
- val = 2;
- break;
- case BYTE_BGR:;
- val = 3;
- break;
- case BYTE_RGB:;
- val = 3;
- break;
- }
- return val;
+ boolean isImageTypeSupported() {
+ return imageTypeIsSupported;
}
-
-
- boolean is4ByteRGBAOr3ByteRGB(RenderedImage ri) {
+
+ /**
+ * Check if ImageComponent parameters have valid values.
+ */
+ void processParams(int format, int width, int height, int depth) {
+ if (width < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained0"));
+
+ if (height < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained1"));
+
+ if (depth < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained2"));
+
+ // If the format is 8bit per component, we may send it down
+ // to OpenGL directly if its by ref case
+ switch (format) {
+ case ImageComponent.FORMAT_RGB:// same as ImageComponent.FORMAT_RGB8
+ case ImageComponent.FORMAT_RGB4: // Need to be Deprecated
+ case ImageComponent.FORMAT_RGB5: // Need to be Deprecated
+ case ImageComponent.FORMAT_R3_G3_B2: // Need to be Deprecated
+ numberOfComponents = 3;
+ break;
+ case ImageComponent.FORMAT_RGBA:// same as ImageComponent.FORMAT_RGBA8
+ case ImageComponent.FORMAT_RGB5_A1: // Need to be Deprecated
+ case ImageComponent.FORMAT_RGBA4: // Need to be Deprecated
+ numberOfComponents = 4;
+ break;
+ case ImageComponent.FORMAT_LUM4_ALPHA4: // Need to be Deprecated
+ case ImageComponent.FORMAT_LUM8_ALPHA8:
+ numberOfComponents = 2;
+ break;
+ case ImageComponent.FORMAT_CHANNEL8:
+ numberOfComponents = 1;
+ break;
+ default:
+ throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained3"));
+ }
+
+ this.setFormat(format);
+ this.width = width;
+ this.height = height;
+ this.depth = depth;
+ refImage = new Object[depth];
+ }
+
+ int evaluateImageType(RenderedImage ri) {
+ int imageType = BufferedImage.TYPE_CUSTOM;
+
+ if (ri instanceof BufferedImage) {
+ imageType = ((BufferedImage)ri).getType();
+
+ if(imageType != BufferedImage.TYPE_CUSTOM) {
+ return imageType;
+ }
+ }
+
+ // System.err.println("This is a RenderedImage or BufferedImage with TYPE_CUSTOM. It imageType classification may not be correct.");
+
+ ColorModel cm = ri.getColorModel();
+ ColorSpace cs = cm.getColorSpace();
+ SampleModel sm = ri.getSampleModel();
+
+ int csType = cs.getType();
+ boolean isAlphaPre = cm.isAlphaPremultiplied();
+
+
+ if (csType == ColorSpace.TYPE_GRAY && cm instanceof ComponentColorModel) {
+ if (sm.getDataType() == DataBuffer.TYPE_BYTE) {
+ imageType = BufferedImage.TYPE_BYTE_GRAY;
+ } else if (sm.getDataType() == DataBuffer.TYPE_USHORT) {
+ imageType = BufferedImage.TYPE_USHORT_GRAY;
+ }
+ }
+
+ // RGB , only interested in BYTE ABGR and BGR for now
+ // all others will be copied to a buffered image
+ else if(csType == ColorSpace.TYPE_RGB) {
+ int comparedBit = 0;
+ int smDataType = sm.getDataType();
+ if(smDataType == DataBuffer.TYPE_BYTE) {
+ comparedBit = 8;
+ } else if(smDataType == DataBuffer.TYPE_INT) {
+ comparedBit = 32;
+ }
+
+ if(comparedBit != 0) {
+ int numBands = sm.getNumBands();
+ if (cm instanceof ComponentColorModel &&
+ sm instanceof PixelInterleavedSampleModel) {
+ PixelInterleavedSampleModel csm =
+ (PixelInterleavedSampleModel) sm;
+ int[] offs = csm.getBandOffsets();
+ ComponentColorModel ccm = (ComponentColorModel)cm;
+ int[] nBits = ccm.getComponentSize();
+ boolean isNBit = true;
+ for (int i=0; i < numBands; i++) {
+ if (nBits[i] != comparedBit) {
+ isNBit = false;
+ break;
+ }
+ }
+
+ // Handle TYPE_BYTE
+ if( comparedBit == 8) {
+ if (isNBit &&
+ offs[0] == numBands-1 &&
+ offs[1] == numBands-2 &&
+ offs[2] == numBands-3) {
+ if (numBands == 3) {
+ imageType = BufferedImage.TYPE_3BYTE_BGR;
+ } else if (offs[3] == 0) {
+ imageType = (isAlphaPre
+ ? BufferedImage.TYPE_4BYTE_ABGR_PRE
+ : BufferedImage.TYPE_4BYTE_ABGR);
+ }
+ }
+ }
+ //Handle TYPE_INT
+ else {
+ if (isNBit) {
+ if (numBands == 3) {
+ if(offs[0] == numBands-1 &&
+ offs[1] == numBands-2 &&
+ offs[2] == numBands-3) {
+ imageType = BufferedImage.TYPE_INT_BGR;
+ } else if(offs[0] == 0 &&
+ offs[1] == 1 &&
+ offs[2] == 2) {
+ imageType = BufferedImage.TYPE_INT_RGB;
+ }
+ } else if(offs[0] == 3 &&
+ offs[1] == 0 &&
+ offs[2] == 1 &&
+ offs[3] == 2) {
+ imageType = (isAlphaPre
+ ? BufferedImage.TYPE_INT_ARGB_PRE
+ : BufferedImage.TYPE_INT_ARGB);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return imageType;
+ }
+
+ // Assume ri's imageType is BufferedImage.TYPE_CUSTOM
+ boolean is3ByteRGB(RenderedImage ri) {
boolean value = false;
int i;
- int biType = getImageType(ri);
- if (biType != BufferedImage.TYPE_CUSTOM)
- return false;
ColorModel cm = ri.getColorModel();
ColorSpace cs = cm.getColorSpace();
SampleModel sm = ri.getSampleModel();
@@ -1059,11 +471,11 @@ abstract class ImageComponentRetained extends NodeComponentRetained {
int csType = cs.getType();
if ( csType == ColorSpace.TYPE_RGB) {
int numBands = sm.getNumBands();
- if (sm.getDataType() == DataBuffer.TYPE_BYTE) {
+ if ((numBands == 3) && (sm.getDataType() == DataBuffer.TYPE_BYTE)) {
if (cm instanceof ComponentColorModel &&
- sm instanceof PixelInterleavedSampleModel) {
- PixelInterleavedSampleModel csm =
- (PixelInterleavedSampleModel) sm;
+ sm instanceof PixelInterleavedSampleModel) {
+ PixelInterleavedSampleModel csm =
+ (PixelInterleavedSampleModel) sm;
int[] offs = csm.getBandOffsets();
ComponentColorModel ccm = (ComponentColorModel)cm;
int[] nBits = ccm.getComponentSize();
@@ -1075,55 +487,33 @@ abstract class ImageComponentRetained extends NodeComponentRetained {
}
}
if (is8Bit &&
- offs[0] == 0 &&
- offs[1] == 1 &&
- offs[2] == 2) {
- if (numBands == 3) {
- if (format == ImageComponent.FORMAT_RGB)
- value = true;
- }
- else if (offs[3] == 3 && !isAlphaPre) {
- if (format == ImageComponent.FORMAT_RGBA)
- value = true;
- }
+ offs[0] == 0 &&
+ offs[1] == 1 &&
+ offs[2] == 2) {
+ value = true;
}
}
}
}
return value;
}
-
- final int getImageType(RenderedImage ri) {
- int imageType = BufferedImage.TYPE_CUSTOM;
+
+ // Assume ri's imageType is BufferedImage.TYPE_CUSTOM
+ boolean is4ByteRGBA(RenderedImage ri) {
+ boolean value = false;
int i;
-
- if (ri instanceof BufferedImage) {
- return ((BufferedImage)ri).getType();
- }
ColorModel cm = ri.getColorModel();
ColorSpace cs = cm.getColorSpace();
SampleModel sm = ri.getSampleModel();
- int csType = cs.getType();
boolean isAlphaPre = cm.isAlphaPremultiplied();
- if ( csType != ColorSpace.TYPE_RGB) {
- if (csType == ColorSpace.TYPE_GRAY &&
- cm instanceof ComponentColorModel) {
- if (sm.getDataType() == DataBuffer.TYPE_BYTE) {
- imageType = BufferedImage.TYPE_BYTE_GRAY;
- } else if (sm.getDataType() == DataBuffer.TYPE_USHORT) {
- imageType = BufferedImage.TYPE_USHORT_GRAY;
- }
- }
- }
- // RGB , only interested in BYTE ABGR and BGR for now
- // all others will be copied to a buffered image
- else {
+ int csType = cs.getType();
+ if ( csType == ColorSpace.TYPE_RGB) {
int numBands = sm.getNumBands();
- if (sm.getDataType() == DataBuffer.TYPE_BYTE) {
+ if ((numBands == 4) && (sm.getDataType() == DataBuffer.TYPE_BYTE)) {
if (cm instanceof ComponentColorModel &&
- sm instanceof PixelInterleavedSampleModel) {
- PixelInterleavedSampleModel csm =
- (PixelInterleavedSampleModel) sm;
+ sm instanceof PixelInterleavedSampleModel) {
+ PixelInterleavedSampleModel csm =
+ (PixelInterleavedSampleModel) sm;
int[] offs = csm.getBandOffsets();
ComponentColorModel ccm = (ComponentColorModel)cm;
int[] nBits = ccm.getComponentSize();
@@ -1135,425 +525,2209 @@ abstract class ImageComponentRetained extends NodeComponentRetained {
}
}
if (is8Bit &&
- offs[0] == numBands-1 &&
- offs[1] == numBands-2 &&
- offs[2] == numBands-3) {
- if (numBands == 3) {
- imageType = BufferedImage.TYPE_3BYTE_BGR;
+ offs[0] == 0 &&
+ offs[1] == 1 &&
+ offs[2] == 2 &&
+ offs[3] == 3 && !isAlphaPre) {
+ value = true;
+ }
+ }
+ }
+ }
+ return value;
+ }
+
+ // Note: This method for RenderedImage, can't be used by NioImageBuffer.
+ /* Check if sub-image type matches image type */
+ boolean isSubImageTypeEqual(RenderedImage ri) {
+ int subImageType = evaluateImageType(ri);
+
+ // This test is likely too loose, but the specification isn't clear either.
+ // Assuming TYPE_CUSTOM of sub-image == the TYPE_CUSTOM of existing image.
+ if(imageType == subImageType) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ // This method only support caller of offScreenBuffer and readRaster.
+ void createBlankImageData() {
+
+ assert (imageData == null);
+
+ switch(numberOfComponents) {
+ case 4:
+ imageType = BufferedImage.TYPE_INT_ARGB;
+ imageFormatType = ImageFormatType.TYPE_INT_ARGB;
+ unitsPerPixel = 1;
+ break;
+
+ case 3:
+ imageType = BufferedImage.TYPE_INT_RGB;
+ imageFormatType = ImageFormatType.TYPE_INT_RGB;
+ unitsPerPixel = 1;
+ break;
+ default:
+ // Only valid for 3 and 4 channel case. ( Read back from framebuffer )
+ assert false;
+ }
+
+ imageTypeIsSupported = true;
+ imageData = createRenderedImageDataObject(null);
+
+ }
+
+ // This method will set imageType, imageFormatType, and unitsPerPixel
+ // as it evaluates NioImageBuffer is supported. It will also reset
+ // abgrSupported.
+ boolean isImageTypeSupported(NioImageBuffer nioImgBuf) {
+
+ boolean isSupported = true;
+ NioImageBuffer.ImageType nioImageType = nioImgBuf.getImageType();
+
+ switch(numberOfComponents) {
+ case 4:
+ if(nioImageType == NioImageBuffer.ImageType.TYPE_4BYTE_ABGR) {
+ // TODO : This approach will lead to a very slow path
+ // for unsupported case.
+ if(abgrSupported) {
+ imageFormatType = ImageFormatType.TYPE_BYTE_ABGR;
+ } else {
+ // Unsupported format on HW, switch to slow copy.
+ imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
+ isSupported = false;
+ }
+ unitsPerPixel = 4;
+ } else if(nioImageType == NioImageBuffer.ImageType.TYPE_4BYTE_RGBA) {
+ imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
+ unitsPerPixel = 4;
+ } else if(nioImageType == NioImageBuffer.ImageType.TYPE_INT_ARGB) {
+ imageFormatType = ImageFormatType.TYPE_INT_ARGB;
+ unitsPerPixel = 1;
+ } else {
+ throw new RuntimeException("Not yet implemented");
+ }
+ break;
+
+ case 3:
+ if(nioImageType == NioImageBuffer.ImageType.TYPE_3BYTE_BGR) {
+ imageFormatType = ImageFormatType.TYPE_BYTE_BGR;
+ unitsPerPixel = 3;
+ } else if(nioImageType == NioImageBuffer.ImageType.TYPE_3BYTE_RGB) {
+ imageFormatType = ImageFormatType.TYPE_BYTE_RGB;
+ unitsPerPixel = 3;
+ } else if(nioImageType == NioImageBuffer.ImageType.TYPE_INT_BGR) {
+ imageFormatType = ImageFormatType.TYPE_INT_BGR;
+ unitsPerPixel = 1;
+ } else if(nioImageType == NioImageBuffer.ImageType.TYPE_INT_RGB) {
+ imageFormatType = ImageFormatType.TYPE_INT_RGB;
+ unitsPerPixel = 1;
+ } else {
+ throw new RuntimeException("Not yet implemented");
+ }
+ break;
+
+ case 2:
+ throw new RuntimeException("Not yet implemented");
+ case 1:
+ if(nioImageType == NioImageBuffer.ImageType.TYPE_BYTE_GRAY) {
+ imageFormatType = ImageFormatType.TYPE_BYTE_GRAY;
+ unitsPerPixel = 1;
+ } else {
+ throw new RuntimeException("Not yet implemented");
+ }
+ break;
+
+ default:
+ throw new AssertionError();
+ }
+
+ return isSupported;
+ }
+
+ // This method will set imageType, imageFormatType, and unitsPerPixel
+ // as it evaluates RenderedImage is supported. It will also reset
+ // abgrSupported.
+ boolean isImageTypeSupported(RenderedImage ri) {
+
+ boolean isSupported = true;
+ imageType = evaluateImageType(ri);
+
+ switch(numberOfComponents) {
+ case 4:
+ if(imageType == BufferedImage.TYPE_4BYTE_ABGR) {
+
+ // TODO : This approach will lead to a very slow path
+ // for unsupported case.
+ if(abgrSupported) {
+ imageFormatType = ImageFormatType.TYPE_BYTE_ABGR;
+ } else {
+ // Unsupported format on HW, switch to slow copy.
+ imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
+ isSupported = false;
+ }
+ unitsPerPixel = 4;
+ } else if(imageType == BufferedImage.TYPE_INT_ARGB) {
+ imageFormatType = ImageFormatType.TYPE_INT_ARGB;
+ unitsPerPixel = 1;
+ } else if(is4ByteRGBA(ri)) {
+ imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
+ unitsPerPixel = 4;
+ } else {
+ // System.err.println("Image format is unsupported --- Case 4");
+ // Convert unsupported format to TYPE_BYTE_RGBA.
+ imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
+ isSupported = false;
+ unitsPerPixel = 4;
+ }
+ break;
+
+ case 3:
+ if(imageType == BufferedImage.TYPE_3BYTE_BGR) {
+ imageFormatType = ImageFormatType.TYPE_BYTE_BGR;
+ unitsPerPixel = 3;
+ } else if(imageType == BufferedImage.TYPE_INT_BGR) {
+ imageFormatType = ImageFormatType.TYPE_INT_BGR;
+ unitsPerPixel = 1;
+ } else if(imageType == BufferedImage.TYPE_INT_RGB) {
+ imageFormatType = ImageFormatType.TYPE_INT_RGB;
+ unitsPerPixel = 1;
+ } else if(is3ByteRGB(ri)) {
+ imageFormatType = ImageFormatType.TYPE_BYTE_RGB;
+ unitsPerPixel = 3;
+ } else {
+ // System.err.println("Image format is unsupported --- Case 3");
+ // Convert unsupported format to TYPE_BYTE_RGB.
+ imageFormatType = ImageFormatType.TYPE_BYTE_RGB;
+ isSupported = false;
+ unitsPerPixel = 3;
+ }
+ break;
+
+ case 2:
+ // System.err.println("Image format is unsupported --- Case 2");
+ // Convert unsupported format to TYPE_BYTE_LA.
+ imageFormatType = ImageFormatType.TYPE_BYTE_LA;
+ isSupported = false;
+ unitsPerPixel = 2;
+ break;
+
+ case 1:
+ if(imageType == BufferedImage.TYPE_BYTE_GRAY) {
+ imageFormatType = ImageFormatType.TYPE_BYTE_GRAY;
+ unitsPerPixel = 1;
+ } else {
+ // System.err.println("Image format is unsupported --- Case 1");
+ // Convert unsupported format to TYPE_BYTE_GRAY.
+ imageFormatType = ImageFormatType.TYPE_BYTE_GRAY;
+ isSupported = false;
+ unitsPerPixel = 1;
+ }
+ break;
+
+ default:
+ throw new AssertionError();
+ }
+
+ return isSupported;
+ }
+
+ /*
+ * This method assume that the following members have been initialized :
+ * width, height, depth, imageFormatType, and unitsPerPixel.
+ */
+ ImageData createNioImageBufferDataObject(NioImageBuffer nioImageBuffer) {
+
+ switch(imageFormatType) {
+ case TYPE_BYTE_GRAY:
+ case TYPE_BYTE_LA:
+ case TYPE_BYTE_RGB:
+ case TYPE_BYTE_BGR:
+ case TYPE_BYTE_RGBA:
+ case TYPE_BYTE_ABGR:
+ if(nioImageBuffer != null) {
+ return new ImageData(ImageDataType.TYPE_BYTE_BUFFER,
+ width * height * depth * unitsPerPixel,
+ width, height, nioImageBuffer);
+ } else {
+ // This is needed only if abgr is unsupported.
+ return new ImageData(ImageDataType.TYPE_BYTE_BUFFER,
+ width * height * depth * unitsPerPixel,
+ width, height);
+ }
+ case TYPE_INT_RGB:
+ case TYPE_INT_BGR:
+ case TYPE_INT_ARGB:
+ return new ImageData(ImageDataType.TYPE_INT_BUFFER,
+ width * height * depth * unitsPerPixel,
+ width, height, nioImageBuffer);
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ /*
+ * This method assume that the following members have been initialized :
+ * depth, imageType, imageFormatType, and unitsPerPixel.
+ */
+ ImageData createRenderedImageDataObject(RenderedImage byRefImage, int dataWidth, int dataHeight) {
+ switch(imageFormatType) {
+ case TYPE_BYTE_GRAY:
+ case TYPE_BYTE_LA:
+ case TYPE_BYTE_RGB:
+ case TYPE_BYTE_BGR:
+ case TYPE_BYTE_RGBA:
+ case TYPE_BYTE_ABGR:
+ if(byRefImage != null) {
+ return new ImageData(ImageDataType.TYPE_BYTE_ARRAY,
+ dataWidth * dataHeight * depth * unitsPerPixel,
+ dataWidth, dataHeight, byRefImage);
+ } else {
+ return new ImageData(ImageDataType.TYPE_BYTE_ARRAY,
+ dataWidth * dataHeight * depth * unitsPerPixel,
+ dataWidth, dataHeight);
+ }
+ case TYPE_INT_RGB:
+ case TYPE_INT_BGR:
+ case TYPE_INT_ARGB:
+ if(byRefImage != null) {
+ return new ImageData(ImageDataType.TYPE_INT_ARRAY,
+ dataWidth * dataHeight * depth * unitsPerPixel,
+ dataWidth, dataHeight, byRefImage);
+ } else {
+ return new ImageData(ImageDataType.TYPE_INT_ARRAY,
+ dataWidth * dataHeight * depth * unitsPerPixel,
+ dataWidth, dataHeight);
+ }
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ private void updateImageDataPowerOfTwo(int depthIndex) {
+ assert enforceNonPowerOfTwoSupport;
+ BufferedImage bufImage = imageData.createBufferedImage(depthIndex);
+ BufferedImage scaledImg = powerOfTwoATOp.filter(bufImage, null);
+ copySupportedImageToImageData(scaledImg, 0, imageDataPowerOfTwo);
+ }
+
+ /*
+ * This method assume that the following members have been initialized :
+ * width, height, depth, imageType, imageFormatType, and bytesPerPixel.
+ */
+ ImageData createRenderedImageDataObject(RenderedImage byRefImage) {
+
+ return createRenderedImageDataObject(byRefImage, width, height);
+
+ }
+
+
+ /**
+ * Copy specified region of image data from RenderedImage to
+ * ImageComponent's imageData object
+ */
+ void copySupportedImageToImageData(RenderedImage ri, int srcX, int srcY,
+ int dstX, int dstY, int depthIndex, int copyWidth, int copyHeight, ImageData data) {
+
+ assert (data != null);
+
+ ColorModel cm = ri.getColorModel();
+
+ int xoff = ri.getTileGridXOffset(); // tile origin x offset
+ int yoff = ri.getTileGridYOffset(); // tile origin y offset
+ int minTileX = ri.getMinTileX(); // min tile x index
+ int minTileY = ri.getMinTileY(); // min tile y index
+ tilew = ri.getTileWidth(); // tile width in pixels
+ tileh = ri.getTileHeight(); // tile height in pixels
+
+ // determine the first tile of the image
+ float mt;
+
+ mt = (float)(srcX - xoff) / (float)tilew;
+ if (mt < 0) {
+ minTileX = (int)(mt - 1);
+ } else {
+ minTileX = (int)mt;
+ }
+
+ mt = (float)(srcY - yoff) / (float)tileh;
+ if (mt < 0) {
+ minTileY = (int)(mt - 1);
+ } else {
+ minTileY = (int)mt;
+ }
+
+ // determine the pixel offset of the upper-left corner of the
+ // first tile
+ int startXTile = minTileX * tilew + xoff;
+ int startYTile = minTileY * tileh + yoff;
+
+ // image dimension in the first tile
+ int curw = (startXTile + tilew - srcX);
+ int curh = (startYTile + tileh - srcY);
+
+ // check if the to-be-copied region is less than the tile image
+ // if so, update the to-be-copied dimension of this tile
+ if (curw > copyWidth) {
+ curw = copyWidth;
+ }
+
+ if (curh > copyHeight) {
+ curh = copyHeight;
+ }
+
+ // save the to-be-copied width of the left most tile
+ int startw = curw;
+
+ // temporary variable for dimension of the to-be-copied region
+ int tmpw = copyWidth;
+ int tmph = copyHeight;
+
+ // offset of the first pixel of the tile to be copied; offset is
+ // relative to the upper left corner of the title
+ int x = srcX - startXTile;
+ int y = srcY - startYTile;
+
+ // determine the number of tiles in each direction that the
+ // image spans
+ numXTiles = (copyWidth + x) / tilew;
+ numYTiles = (copyHeight + y) / tileh;
+
+ if (((float)(copyWidth + x ) % (float)tilew) > 0) {
+ numXTiles += 1;
+ }
+
+ if (((float)(copyHeight + y ) % (float)tileh) > 0) {
+ numYTiles += 1;
+ }
+
+ int offset;
+ int w, h, i, j, m, n;
+ int dstBegin;
+ Object pixel = null;
+ java.awt.image.Raster ras;
+ int lineUnits; // nbytes per line in dst image buffer
+ int sign; // -1 for going down
+ int dstLineUnits; // sign * lineUnits
+ int tileStart; // destination buffer offset
+ // at the next left most tile
+
+ byte[] dstByteBuffer = null;
+ int[] dstIntBuffer = null;
+
+ switch(data.getType()) {
+ case TYPE_BYTE_ARRAY:
+ dstByteBuffer = data.getAsByteArray();
+ break;
+ case TYPE_INT_ARRAY:
+ dstIntBuffer = data.getAsIntArray();
+ break;
+ default:
+ assert false;
+ }
+
+ int dataWidth = data.dataWidth;
+ int dataHeight = data.dataHeight;
+
+ lineUnits = dataWidth * unitsPerPixel;
+ if (yUp) {
+ // destination buffer offset
+ tileStart = (depthIndex * dataWidth * dataHeight + dstY * dataWidth + dstX) * unitsPerPixel;
+ sign = 1;
+ dstLineUnits = lineUnits;
+ } else {
+ // destination buffer offset
+ tileStart = (depthIndex * dataWidth * dataHeight + (dataHeight - dstY - 1) * dataWidth + dstX) * unitsPerPixel;
+ sign = -1;
+ dstLineUnits = -lineUnits;
+ }
+
+/*
+ System.err.println("tileStart= " + tileStart + " dstLineUnits= " + dstLineUnits);
+ System.err.println("startw= " + startw);
+ */
+
+ // allocate memory for a pixel
+ ras = ri.getTile(minTileX,minTileY);
+ pixel = getDataElementBuffer(ras);
+
+ int srcOffset, dstOffset;
+ int tileLineUnits = tilew * unitsPerPixel;
+ int copyUnits;
+
+ for (n = minTileY; n < minTileY+numYTiles; n++) {
+
+ dstBegin = tileStart; // destination buffer offset
+ tmpw = copyWidth; // reset the width to be copied
+ curw = startw; // reset the width to be copied of
+ // the left most tile
+ x = srcX - startXTile; // reset the starting x offset of
+ // the left most tile
+
+ for (m = minTileX; m < minTileX+numXTiles; m++) {
+
+ // retrieve the raster for the next tile
+ ras = ri.getTile(m,n);
+
+ srcOffset = (y * tilew + x) * unitsPerPixel;
+ dstOffset = dstBegin;
+
+ copyUnits = curw * unitsPerPixel;
+
+ //System.err.println("curh = "+curh+" curw = "+curw);
+ //System.err.println("x = "+x+" y = "+y);
+
+ switch(data.getType()) {
+ case TYPE_BYTE_ARRAY:
+ byte[] srcByteBuffer = ((DataBufferByte)ras.getDataBuffer()).getData();
+ for (h = 0; h < curh; h++) {
+ System.arraycopy(srcByteBuffer, srcOffset, dstByteBuffer, dstOffset,
+ copyUnits);
+ srcOffset += tileLineUnits;
+ dstOffset += dstLineUnits;
}
- else if (offs[3] == 0) {
- imageType = (isAlphaPre
- ? BufferedImage.TYPE_4BYTE_ABGR_PRE
- : BufferedImage.TYPE_4BYTE_ABGR);
+ break;
+ case TYPE_INT_ARRAY:
+ int[] srcIntBuffer = ((DataBufferInt)ras.getDataBuffer()).getData();
+ for (h = 0; h < curh; h++) {
+ System.arraycopy(srcIntBuffer, srcOffset, dstIntBuffer, dstOffset,
+ copyUnits);
+ srcOffset += tileLineUnits;
+ dstOffset += dstLineUnits;
}
+ break;
+ default:
+ assert false;
+ }
+
+ // advance the destination buffer offset
+ dstBegin += curw * unitsPerPixel;
+
+ // move to the next tile in x direction
+ x = 0;
+
+ // determine the width of copy region of the next tile
+
+ tmpw -= curw;
+ if (tmpw < tilew) {
+ curw = tmpw;
+ } else {
+ curw = tilew;
+ }
+ }
+
+ // we are done copying an array of tiles in the x direction
+ // advance the tileStart offset
+ tileStart += dataWidth * unitsPerPixel * curh * sign;
+
+ // move to the next set of tiles in y direction
+ y = 0;
+
+ // determine the height of copy region for the next set
+ // of tiles
+ tmph -= curh;
+ if (tmph < tileh) {
+ curh = tmph;
+ } else {
+ curh = tileh;
+ }
+ }
+
+ if((imageData == data) && (imageDataPowerOfTwo != null)) {
+ updateImageDataPowerOfTwo(depthIndex);
+ }
+ }
+
+ // Quick line by line copy
+ void copyImageLineByLine(BufferedImage bi, int srcX, int srcY,
+ int dstX, int dstY, int depthIndex, int copyWidth, int copyHeight, ImageData data) {
+
+ assert (data != null);
+
+ int h;
+ int rowBegin, // src begin row index
+ srcBegin, // src begin offset
+ dstBegin; // dst begin offset
+
+ int dataWidth = data.dataWidth;
+ int dataHeight = data.dataHeight;
+ int dstUnitsPerRow = dataWidth * unitsPerPixel; // bytes per row in dst image
+ rowBegin = srcY;
+
+ if (yUp) {
+ dstBegin = (depthIndex * dataWidth * dataHeight + dstY * dataWidth + dstX) * unitsPerPixel;
+ } else {
+ dstBegin = (depthIndex * dataWidth * dataHeight + (dataHeight - dstY - 1) * dataWidth + dstX) * unitsPerPixel;
+ dstUnitsPerRow = - 1 * dstUnitsPerRow;
+ }
+
+ int copyUnits = copyWidth * unitsPerPixel;
+ int srcWidth = bi.getWidth();
+ int srcUnitsPerRow = srcWidth * unitsPerPixel;
+ srcBegin = (rowBegin * srcWidth + srcX) * unitsPerPixel;
+
+ switch(data.getType()) {
+ case TYPE_BYTE_ARRAY:
+ byte[] srcByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
+ byte[] dstByteBuffer = data.getAsByteArray();
+ for (h = 0; h < copyHeight; h++) {
+ System.arraycopy(srcByteBuffer, srcBegin, dstByteBuffer, dstBegin, copyUnits);
+ dstBegin += dstUnitsPerRow;
+ srcBegin += srcUnitsPerRow;
+ }
+ break;
+
+ case TYPE_INT_ARRAY:
+ int[] srcIntBuffer = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ int[] dstIntBuffer = data.getAsIntArray();
+ for (h = 0; h < copyHeight; h++) {
+ System.arraycopy(srcIntBuffer, srcBegin, dstIntBuffer, dstBegin, copyUnits);
+ dstBegin += dstUnitsPerRow;
+ srcBegin += srcUnitsPerRow;
+ }
+ break;
+ default:
+ assert false;
+ }
+
+ if((imageData == data) && (imageDataPowerOfTwo != null)) {
+ updateImageDataPowerOfTwo(depthIndex);
+ }
+ }
+
+ // Quick block copy for yUp image
+ void copyImageByBlock(BufferedImage bi, int depthIndex, ImageData data) {
+
+ assert ((data != null) && yUp);
+
+ int dataWidth = data.dataWidth;
+ int dataHeight = data.dataHeight;
+
+ int dstBegin; // dst begin offset
+ dstBegin = depthIndex * dataWidth * dataHeight * unitsPerPixel;
+
+ switch(imageData.getType()) {
+ case TYPE_BYTE_ARRAY:
+ byte[] srcByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
+ byte[] dstByteBuffer = data.getAsByteArray();
+ System.arraycopy(srcByteBuffer, 0, dstByteBuffer, dstBegin, (dataWidth * dataHeight * unitsPerPixel));
+ break;
+ case TYPE_INT_ARRAY:
+ int[] srcIntBuffer = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ int[] dstIntBuffer = data.getAsIntArray();
+ System.arraycopy(srcIntBuffer, 0, dstIntBuffer, dstBegin, (dataWidth * dataHeight * unitsPerPixel));
+ break;
+ default:
+ assert false;
+ }
+
+ if((imageData == data) && (imageDataPowerOfTwo != null)) {
+ updateImageDataPowerOfTwo(depthIndex);
+ }
+
+ }
+
+ /**
+ * copy complete region of a RenderedImage to ImageComponent's imageData object.
+ */
+ void copySupportedImageToImageData(RenderedImage ri, int depthIndex, ImageData data) {
+
+ if (ri instanceof BufferedImage) {
+ if(yUp) {
+ /* Use quick block copy when ( format is OK, Yup is true, and byRef is false). */
+ // System.err.println("ImageComponentRetained.copySupportedImageToImageData() : (imageTypeSupported && !byReference && yUp) --- (2 BI)");
+ copyImageByBlock((BufferedImage)ri, depthIndex, data);
+ } else {
+ /* Use quick inverse line by line copy when (format is OK and Yup is false). */
+ // System.err.println("ImageComponentRetained.copySupportedImageToImageData() : (imageTypeSupported && !yUp) --- (3 BI)");
+ copyImageLineByLine((BufferedImage)ri, 0, 0, 0, 0, depthIndex, data.dataWidth, data.dataHeight, data);
+ }
+ } else {
+ // System.err.println("ImageComponentRetained.copySupportedImageToImageData() : (imageTypeSupported && !byReference ) --- (2 RI)");
+ copySupportedImageToImageData(ri, ri.getMinX(), ri.getMinY(), 0, 0, depthIndex, data.dataWidth, data.dataHeight, data);
+
+ /*
+ * An alternative approach.
+ *
+ // Create a buffered image from renderImage
+ ColorModel cm = ri.getColorModel();
+ WritableRaster wRaster = ri.copyData(null);
+ BufferedImage bi = new BufferedImage(cm,
+ wRaster,
+ cm.isAlphaPremultiplied()
+ ,null);
+
+ copySupportedImageToImageData((BufferedImage)ri, 0, 0, 0, 0, depthIndex, data.dataWidth, data.dataHeight, data);
+
+ *
+ *
+ */
+ }
+ }
+
+ /*
+ * copy the complete unsupported NioImageBuffer into a supported BYTE_BUFFER format
+ */
+ void copyUnsupportedNioImageToImageData(NioImageBuffer nioImage, int srcX, int srcY,
+ int dstX, int dstY, int copyWidth, int copyHeight, ImageData iData) {
+
+ assert (iData.getType() == ImageDataType.TYPE_BYTE_BUFFER);
+ assert (getImageFormatType() == ImageFormatType.TYPE_BYTE_RGBA);
+
+ int length = copyWidth * copyHeight;
+ ByteBuffer srcBuffer = (ByteBuffer) nioImage.getDataBuffer();
+ srcBuffer.rewind();
+ ByteBuffer dstBuffer = iData.getAsByteBuffer();
+ dstBuffer.rewind();
+
+ // Do copy and swap.
+ for(int i = 0; i < length; i +=4) {
+ dstBuffer.put(i, srcBuffer.get(i+3));
+ dstBuffer.put(i+1, srcBuffer.get(i+2));
+ dstBuffer.put(i+2, srcBuffer.get(i+1));
+ dstBuffer.put(i+3, srcBuffer.get(i));
+ }
+ }
+
+ /*
+ * copy the complete unsupported image into a supported BYTE_ARRAY format
+ */
+ void copyUnsupportedImageToImageData(RenderedImage ri, int depthIndex, ImageData data) {
+
+ assert (data.getType() == ImageDataType.TYPE_BYTE_ARRAY);
+
+ if (ri instanceof BufferedImage) {
+ copyUnsupportedImageToImageData((BufferedImage)ri, 0, 0, 0, 0,
+ depthIndex, data.dataWidth, data.dataHeight, data);
+ } else {
+ copyUnsupportedImageToImageData(ri, ri.getMinX(), ri.getMinY(),
+ 0, 0, depthIndex, data.dataWidth, data.dataHeight, data);
+ }
+ }
+
+ void copyUnsupportedImageToImageData(BufferedImage bi, int srcX, int srcY,
+ int dstX, int dstY, int depthIndex, int copyWidth, int copyHeight, ImageData data) {
+
+ int w, h, i, j;
+ int rowBegin, // src begin row index
+ srcBegin, // src begin offset
+ dstBegin, // dst begin offset
+ rowInc, // row increment
+ // -1 --- ydown
+ // 1 --- yup
+ row;
+
+ rowBegin = srcY;
+ rowInc = 1;
+
+ assert (data != null);
+
+ int dataWidth = data.dataWidth;
+ int dataHeight = data.dataHeight;
+ int dstBytesPerRow = dataWidth * unitsPerPixel; // bytes per row in dst image
+
+ if (yUp) {
+ dstBegin = (depthIndex * dataWidth * dataHeight + dstY * dataWidth + dstX) * unitsPerPixel;
+ } else {
+ dstBegin = (depthIndex * dataWidth * dataHeight + (dataHeight - dstY - 1) * dataWidth + dstX) * unitsPerPixel;
+ dstBytesPerRow = - 1 * dstBytesPerRow;
+ }
+
+ WritableRaster ras = bi.getRaster();
+ ColorModel cm = bi.getColorModel();
+ Object pixel = getDataElementBuffer(ras);
+
+ byte[] dstBuffer = data.getAsByteArray();
+
+ switch(numberOfComponents) {
+ case 4: {
+ for (row = rowBegin, h = 0;
+ h < copyHeight; h++, row += rowInc) {
+ j = dstBegin;
+ for (w = srcX; w < (copyWidth + srcX); w++) {
+ ras.getDataElements(w, row, pixel);
+ dstBuffer[j++] = (byte)cm.getRed(pixel);
+ dstBuffer[j++] = (byte)cm.getGreen(pixel);
+ dstBuffer[j++] = (byte)cm.getBlue(pixel);
+ dstBuffer[j++] = (byte)cm.getAlpha(pixel);
+ }
+ dstBegin += dstBytesPerRow;
+ }
+ }
+ break;
+
+ case 3: {
+ for (row = rowBegin, h = 0;
+ h < copyHeight; h++, row += rowInc) {
+ j = dstBegin;
+ for (w = srcX; w < (copyWidth + srcX); w++) {
+ ras.getDataElements(w, row, pixel);
+ dstBuffer[j++] = (byte)cm.getRed(pixel);
+ dstBuffer[j++] = (byte)cm.getGreen(pixel);
+ dstBuffer[j++] = (byte)cm.getBlue(pixel);
+ }
+ dstBegin += dstBytesPerRow;
+ }
+ }
+ break;
+
+ case 2: {
+ for (row = rowBegin, h = 0;
+ h < copyHeight; h++, row += rowInc) {
+ j = dstBegin;
+ for (w = srcX; w < (copyWidth + srcX); w++) {
+ ras.getDataElements(w, row, pixel);
+ dstBuffer[j++] = (byte)cm.getRed(pixel);
+ dstBuffer[j++] = (byte)cm.getAlpha(pixel);
}
+ dstBegin += dstBytesPerRow;
}
}
+ break;
+
+ case 1: {
+ for (row = rowBegin, h = 0;
+ h < copyHeight; h++, row += rowInc) {
+ j = dstBegin;
+ for (w = srcX; w < (copyWidth + srcX); w++) {
+ ras.getDataElements(w, row, pixel);
+ dstBuffer[j++] = (byte)cm.getRed(pixel);
+ }
+ dstBegin += dstBytesPerRow;
+ }
+ }
+ break;
+ default:
+ assert false;
+ }
+
+ if((imageData == data) && (imageDataPowerOfTwo != null)) {
+ updateImageDataPowerOfTwo(depthIndex);
}
- return imageType;
}
+
+ void copyUnsupportedImageToImageData(RenderedImage ri, int srcX, int srcY,
+ int dstX, int dstY, int depthIndex, int copyWidth, int copyHeight, ImageData data) {
+
+ int w, h, i, j, m, n;
+ int dstBegin;
+ Object pixel = null;
+ java.awt.image.Raster ras;
+ // dst image buffer
+ int sign; // -1 for going down
+ int dstLineBytes; // sign * lineBytes
+ int tileStart; // destination buffer offset
+ // at the next left most tile
+
+ int offset;
+
+ ColorModel cm = ri.getColorModel();
+
+ int xoff = ri.getTileGridXOffset(); // tile origin x offset
+ int yoff = ri.getTileGridYOffset(); // tile origin y offset
+ int minTileX = ri.getMinTileX(); // min tile x index
+ int minTileY = ri.getMinTileY(); // min tile y index
+ tilew = ri.getTileWidth(); // tile width in pixels
+ tileh = ri.getTileHeight(); // tile height in pixels
+
+ // determine the first tile of the image
+
+ float mt;
+
+ mt = (float)(srcX - xoff) / (float)tilew;
+ if (mt < 0) {
+ minTileX = (int)(mt - 1);
+ } else {
+ minTileX = (int)mt;
+ }
+
+ mt = (float)(srcY - yoff) / (float)tileh;
+ if (mt < 0) {
+ minTileY = (int)(mt - 1);
+ } else {
+ minTileY = (int)mt;
+ }
+
+ // determine the pixel offset of the upper-left corner of the
+ // first tile
+ int startXTile = minTileX * tilew + xoff;
+ int startYTile = minTileY * tileh + yoff;
+
+
+ // image dimension in the first tile
+ int curw = (startXTile + tilew - srcX);
+ int curh = (startYTile + tileh - srcY);
+
+ // check if the to-be-copied region is less than the tile image
+ // if so, update the to-be-copied dimension of this tile
+ if (curw > copyWidth) {
+ curw = copyWidth;
+ }
+
+ if (curh > copyHeight) {
+ curh = copyHeight;
+ }
+
+ // save the to-be-copied width of the left most tile
+ int startw = curw;
+
+
+ // temporary variable for dimension of the to-be-copied region
+ int tmpw = copyWidth;
+ int tmph = copyHeight;
+
+
+ // offset of the first pixel of the tile to be copied; offset is
+ // relative to the upper left corner of the title
+ int x = srcX - startXTile;
+ int y = srcY - startYTile;
+
+
+ // determine the number of tiles in each direction that the
+ // image spans
+
+ numXTiles = (copyWidth + x) / tilew;
+ numYTiles = (copyHeight + y) / tileh;
+
+ if (((float)(copyWidth + x ) % (float)tilew) > 0) {
+ numXTiles += 1;
+ }
+
+ if (((float)(copyHeight + y ) % (float)tileh) > 0) {
+ numYTiles += 1;
+ }
+
+ assert (data != null);
+ int dataWidth = data.dataWidth;
+ int dataHeight = data.dataHeight;
+ int lineBytes = dataWidth * unitsPerPixel; // nbytes per line in
+
+ if (yUp) {
+ // destination buffer offset
+ tileStart = (depthIndex * dataWidth * dataHeight + dstY * dataWidth + dstX) * unitsPerPixel;
+ sign = 1;
+ dstLineBytes = lineBytes;
+ } else {
+ // destination buffer offset
+ tileStart = (depthIndex * dataWidth * dataHeight + (dataHeight - dstY - 1) * dataWidth + dstX) * unitsPerPixel;
+ sign = -1;
+ dstLineBytes = -lineBytes;
+ }
+
+/*
+ System.err.println("tileStart= " + tileStart + " dstLineBytes= " + dstLineBytes);
+ System.err.println("startw= " + startw);
+ */
+
+ // allocate memory for a pixel
+ ras = ri.getTile(minTileX,minTileY);
+ pixel = getDataElementBuffer(ras);
+ byte[] dstBuffer = imageData.getAsByteArray();
+
+ switch(numberOfComponents) {
+ case 4: {
+ // System.err.println("Case 1: byReference = "+byReference);
+ for (n = minTileY; n < minTileY+numYTiles; n++) {
+
+ dstBegin = tileStart; // destination buffer offset
+ tmpw = copyWidth; // reset the width to be copied
+ curw = startw; // reset the width to be copied of
+ // the left most tile
+ x = srcX - startXTile; // reset the starting x offset of
+ // the left most tile
+
+ for (m = minTileX; m < minTileX+numXTiles; m++) {
+
+ // retrieve the raster for the next tile
+ ras = ri.getTile(m,n);
+
+ j = dstBegin;
+ offset = 0;
+
+ //System.err.println("curh = "+curh+" curw = "+curw);
+ //System.err.println("x = "+x+" y = "+y);
+
+ for (h = y; h < (y + curh); h++) {
+ // System.err.println("j = "+j);
+ for (w = x; w < (x + curw); w++) {
+ ras.getDataElements(w, h, pixel);
+ dstBuffer[j++] = (byte)cm.getRed(pixel);
+ dstBuffer[j++] = (byte)cm.getGreen(pixel);
+ dstBuffer[j++] = (byte)cm.getBlue(pixel);
+ dstBuffer[j++] = (byte)cm.getAlpha(pixel);
+ }
+ offset += dstLineBytes;
+ j = dstBegin + offset;
+ }
+
+ // advance the destination buffer offset
+ dstBegin += curw * unitsPerPixel;
+
+ // move to the next tile in x direction
+ x = 0;
+
+ // determine the width of copy region of the next tile
+
+ tmpw -= curw;
+ if (tmpw < tilew) {
+ curw = tmpw;
+ } else {
+ curw = tilew;
+ }
+ }
+
+ // we are done copying an array of tiles in the x direction
+ // advance the tileStart offset
+
+ tileStart += dataWidth * unitsPerPixel * curh * sign;
+
+ // move to the next set of tiles in y direction
+ y = 0;
+
+ // determine the height of copy region for the next set
+ // of tiles
+ tmph -= curh;
+ if (tmph < tileh) {
+ curh = tmph;
+ } else {
+ curh = tileh;
+ }
+ }
+ }
+ break;
+ case 3: {
+ for (n = minTileY; n < minTileY+numYTiles; n++) {
+
+ dstBegin = tileStart; // destination buffer offset
+ tmpw = copyWidth; // reset the width to be copied
+ curw = startw; // reset the width to be copied of
+ // the left most tile
+ x = srcX - startXTile; // reset the starting x offset of
+ // the left most tile
+
+ for (m = minTileX; m < minTileX+numXTiles; m++) {
+
+ // retrieve the raster for the next tile
+ ras = ri.getTile(m,n);
+
+ j = dstBegin;
+ offset = 0;
+
+ //System.err.println("curh = "+curh+" curw = "+curw);
+ //System.err.println("x = "+x+" y = "+y);
+
+ for (h = y; h < (y + curh); h++) {
+ // System.err.println("j = "+j);
+ for (w = x; w < (x + curw); w++) {
+ ras.getDataElements(w, h, pixel);
+ dstBuffer[j++] = (byte)cm.getRed(pixel);
+ dstBuffer[j++] = (byte)cm.getGreen(pixel);
+ dstBuffer[j++] = (byte)cm.getBlue(pixel);
+ }
+ offset += dstLineBytes;
+ j = dstBegin + offset;
+ }
+
+ // advance the destination buffer offset
+ dstBegin += curw * unitsPerPixel;
+
+ // move to the next tile in x direction
+ x = 0;
+
+ // determine the width of copy region of the next tile
+
+ tmpw -= curw;
+ if (tmpw < tilew) {
+ curw = tmpw;
+ } else {
+ curw = tilew;
+ }
+ }
+
+ // we are done copying an array of tiles in the x direction
+ // advance the tileStart offset
+
+ tileStart += dataWidth * unitsPerPixel * curh * sign;
+
+ // move to the next set of tiles in y direction
+ y = 0;
+
+ // determine the height of copy region for the next set
+ // of tiles
+ tmph -= curh;
+ if (tmph < tileh) {
+ curh = tmph;
+ } else {
+ curh = tileh;
+ }
+ }
+ }
+ break;
+ case 2: {
+ for (n = minTileY; n < minTileY+numYTiles; n++) {
+
+ dstBegin = tileStart; // destination buffer offset
+ tmpw = copyWidth; // reset the width to be copied
+ curw = startw; // reset the width to be copied of
+ // the left most tile
+ x = srcX - startXTile; // reset the starting x offset of
+ // the left most tile
+
+ for (m = minTileX; m < minTileX+numXTiles; m++) {
+
+ // retrieve the raster for the next tile
+ ras = ri.getTile(m,n);
+
+ j = dstBegin;
+ offset = 0;
+
+ //System.err.println("curh = "+curh+" curw = "+curw);
+ //System.err.println("x = "+x+" y = "+y);
+
+ for (h = y; h < (y + curh); h++) {
+ // System.err.println("j = "+j);
+ for (w = x; w < (x + curw); w++) {
+ ras.getDataElements(w, h, pixel);
+ dstBuffer[j++] = (byte)cm.getRed(pixel);
+ dstBuffer[j++] = (byte)cm.getAlpha(pixel);
+ }
+ offset += dstLineBytes;
+ j = dstBegin + offset;
+ }
+
+ // advance the destination buffer offset
+ dstBegin += curw * unitsPerPixel;
+
+ // move to the next tile in x direction
+ x = 0;
+
+ // determine the width of copy region of the next tile
+
+ tmpw -= curw;
+ if (tmpw < tilew) {
+ curw = tmpw;
+ } else {
+ curw = tilew;
+ }
+ }
+
+
+ // we are done copying an array of tiles in the x direction
+ // advance the tileStart offset
+
+ tileStart += dataWidth * unitsPerPixel * curh * sign;
+
+
+ // move to the next set of tiles in y direction
+ y = 0;
+
+ // determine the height of copy region for the next set
+ // of tiles
+ tmph -= curh;
+ if (tmph < tileh) {
+ curh = tmph;
+ } else {
+ curh = tileh;
+ }
+ }
+ }
+ break;
+ case 1: {
+ for (n = minTileY; n < minTileY+numYTiles; n++) {
+
+ dstBegin = tileStart; // destination buffer offset
+ tmpw = copyWidth; // reset the width to be copied
+ curw = startw; // reset the width to be copied of
+ // the left most tile
+ x = srcX - startXTile; // reset the starting x offset of
+ // the left most tile
+
+ for (m = minTileX; m < minTileX+numXTiles; m++) {
+
+ // retrieve the raster for the next tile
+ ras = ri.getTile(m,n);
+
+ j = dstBegin;
+ offset = 0;
+
+ //System.err.println("curh = "+curh+" curw = "+curw);
+ //System.err.println("x = "+x+" y = "+y);
+
+ for (h = y; h < (y + curh); h++) {
+ // System.err.println("j = "+j);
+ for (w = x; w < (x + curw); w++) {
+ ras.getDataElements(w, h, pixel);
+ dstBuffer[j++] = (byte)cm.getRed(pixel);
+ }
+ offset += dstLineBytes;
+ j = dstBegin + offset;
+ }
+
+ // advance the destination buffer offset
+ dstBegin += curw * unitsPerPixel;
+
+ // move to the next tile in x direction
+ x = 0;
+
+ // determine the width of copy region of the next tile
+
+ tmpw -= curw;
+ if (tmpw < tilew) {
+ curw = tmpw;
+ } else {
+ curw = tilew;
+ }
+ }
+
+ // we are done copying an array of tiles in the x direction
+ // advance the tileStart offset
+ tileStart += dataWidth * unitsPerPixel * curh * sign;
+
+ // move to the next set of tiles in y direction
+ y = 0;
+
+ // determine the height of copy region for the next set
+ // of tiles
+ tmph -= curh;
+ if (tmph < tileh) {
+ curh = tmph;
+ } else {
+ curh = tileh;
+ }
+ }
+ }
+ break;
+
+ default:
+ assert false;
+ }
+
+ if((imageData == data) && (imageDataPowerOfTwo != null)) {
+ updateImageDataPowerOfTwo(depthIndex);
+ }
+ }
+
+ // Lock out user thread from modifying variables by using synchronized routines
+ void evaluateExtensions(Canvas3D canvas) {
+ // For performance reason the ordering of the following 2 statements is intentional.
+ // So that we only need to do format conversion for imageData only
+ evaluateExtABGR(canvas.extensionsSupported);
+ evaluateExtNonPowerOfTwo(canvas.textureExtendedFeatures);
+
+ }
+
+
+ void evaluateExtABGR(int ext) {
+
+
+ // If abgrSupported is false, a copy has been created so
+ // we don't have to check again.
+ if(!abgrSupported) {
+ return;
+ }
+
+ if(getImageFormatType() != ImageFormatType.TYPE_BYTE_ABGR) {
+ return;
+ }
+
+ if((ext & Canvas3D.EXT_ABGR) != 0) {
+ return;
+ }
+
+ // ABGR is unsupported, set flag to false.
+ abgrSupported = false;
+ convertImageDataFromABGRToRGBA();
+
+ }
+
+ private int getClosestPowerOf2(int value) {
+
+ if (value < 1)
+ return value;
+
+ int powerValue = 1;
+ for (;;) {
+ powerValue *= 2;
+ if (value < powerValue) {
+ // Found max bound of power, determine which is closest
+ int minBound = powerValue/2;
+ if ((powerValue - value) >
+ (value - minBound))
+ return minBound;
+ else
+ return powerValue;
+ }
+ }
+ }
+
+ void evaluateExtNonPowerOfTwo(int ext) {
+
+ // If npotSupported is false, a copy power of two image has been created
+ // so we don't have to check again.
+ if(!npotSupported) {
+ return;
+ }
+ if (imageData == null && !isByReference()) {
+ return;
+ }
+ if((ext & Canvas3D.TEXTURE_NON_POWER_OF_TWO) != 0) {
+ return;
+ }
+
+ // NPOT is unsupported, set flag to false.
+ npotSupported = false;
+
+ // scale to power of 2 for texture mapping
+ //xmax and ymax are in BackgroundRetained.
+ /* xmax = width;
+ ymax = height; */
+ int npotWidth = getClosestPowerOf2(width);
+ int npotHeight = getClosestPowerOf2(height);
+ float xScale = (float)npotWidth/(float)width;
+ float yScale = (float)npotHeight/(float)height;
+
+ // scale if scales aren't 1.0
+ if (!(xScale == 1.0f && yScale == 1.0f)) {
+ RenderedImage ri = null;
+
+ if (imageData == null) {
+ // This is a byRef, support format and is a RenderedImage case.
+ // See ImageComponent2DRetained.set(RenderedImage image)
+ ri = (RenderedImage) getRefImage(0);
+ if(!(ri instanceof BufferedImage)) {
+ // Create a buffered image from renderImage
+ ColorModel cm = ri.getColorModel();
+ WritableRaster wRaster = ri.copyData(null);
+ ri = new BufferedImage(cm,
+ wRaster,
+ cm.isAlphaPremultiplied()
+ ,null);
+
+ // Create image data object with buffer for image. */
+ imageData = createRenderedImageDataObject(null);
+ copySupportedImageToImageData(ri, 0, imageData);
+ }
+ }
+
+ assert imageData != null;
+ ri = imageData.createBufferedImage(0);
+
+ AffineTransform at = AffineTransform.getScaleInstance(xScale,
+ yScale);
+ powerOfTwoATOp = new AffineTransformOp(at,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+ BufferedImage scaledImg = powerOfTwoATOp.filter((BufferedImage)ri, null);
+
+ imageDataPowerOfTwo = createRenderedImageDataObject(null, npotWidth, npotHeight);
+ // Since ri is created from imageData, it's imageType is supported.
+ copySupportedImageToImageData(scaledImg, 0, imageDataPowerOfTwo);
+
+ } else {
+ imageDataPowerOfTwo = null;
+ }
+ }
+
+ void convertImageDataFromABGRToRGBA() {
+
+ // Unsupported format on HW, switch to slow copy.
+ imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
+ imageTypeIsSupported = false;
+
+ // Only need to convert imageData
+ imageData.convertFromABGRToRGBA();
+
+ }
-
/**
- * Retrieves the bufferedImage at the specified depth level
- */
- final void retrieveBufferedImage(int depth) {
-
- // create BufferedImage if one doesn't exist
- if (bImage[depth] == null) {
- if (format == ImageComponent.FORMAT_RGBA ||
- format == ImageComponent.FORMAT_RGBA4 ||
- format == ImageComponent.FORMAT_RGB5_A1 ||
- format == ImageComponent.FORMAT_LUM4_ALPHA4 ||
- format == ImageComponent.FORMAT_LUM8_ALPHA8) {
- bImage[depth] = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_ARGB);
- }
- else
- bImage[depth] = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_RGB);
+ * Copy supported ImageType from ImageData to the user defined bufferedImage
+ */
+ void copyToRefImage(int depth) {
+ int h;
+ int rowBegin, // src begin row index
+ srcBegin, // src begin offset
+ dstBegin; // dst begin offset
+
+ // refImage has to be a BufferedImage for off screen and read raster
+ assert refImage[depth] != null;
+ assert (refImage[depth] instanceof BufferedImage);
+
+ BufferedImage bi = (BufferedImage)refImage[depth];
+ int dstUnitsPerRow = width * unitsPerPixel; // bytes per row in dst image
+ rowBegin = 0;
+
+ if (yUp) {
+ dstBegin = (depth * width * height) * unitsPerPixel;
+ } else {
+ dstBegin = (depth * width * height + (height - 1) * width ) * unitsPerPixel;
+ dstUnitsPerRow = - 1 * dstUnitsPerRow;
}
-
- if (usedByTexture || !usedByRaster) {
- copyToBufferedImage(imageYup, depth, true);
- } else {
- copyToBufferedImage(imageYdown[0], depth, false);
- }
- imageDirty[depth] = false;
-
+
+ int scanline = width * unitsPerPixel;
+ srcBegin = (rowBegin * width ) * unitsPerPixel;
+
+ switch(imageData.getType()) {
+ case TYPE_BYTE_ARRAY:
+ byte[] dstByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
+ byte[] srcByteBuffer = imageData.getAsByteArray();
+ for (h = 0; h < height; h++) {
+ System.arraycopy(srcByteBuffer, srcBegin, dstByteBuffer, dstBegin, scanline);
+ dstBegin += dstUnitsPerRow;
+ srcBegin += scanline;
+ }
+ break;
+
+ case TYPE_INT_ARRAY:
+ int[] dstIntBuffer = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ int[] srcIntBuffer = imageData.getAsIntArray();
+ for (h = 0; h < height; h++) {
+ System.arraycopy(srcIntBuffer, srcBegin, dstIntBuffer, dstBegin, scanline);
+ dstBegin += dstUnitsPerRow;
+ srcBegin += scanline;
+ }
+ break;
+ default:
+ assert false;
+ }
+
}
-
+
/**
* Copy Image from RGBA to the user defined bufferedImage
*/
- final void copyBufferedImageWithFormatConversion(boolean usedByTexture, int depth) {
+ void copyToRefImageWithFormatConversion(int depth) {
int w, h, i, j;
int dstBegin, dstInc, dstIndex, dstIndexInc;
- // Note that if a copy has been made, then its always a bufferedImage
- // and not a renderedImage
- BufferedImage bi = (BufferedImage)bImage[depth];
- int biType = bi.getType();
- byte[] buf;
-
- // convert from Ydown to Yup for texture
- if (!yUp) {
- if (usedByTexture == true) {
- dstInc = -1 * width;
- dstBegin = (height - 1) * width;
- dstIndex = height -1;
- dstIndexInc = -1;
- buf = imageYup;
- } else {
- dstInc = width;
- dstBegin = 0;
- dstIndex = 0;
- dstIndexInc = 1;
- buf = imageYdown[0];
- }
- }
- else {
- if (usedByTexture == true) {
- dstInc = width;
- dstBegin = 0;
- dstIndex = 0;
- dstIndexInc = 1;
- buf = imageYup;
- }
- else {
- dstInc = -1 * width;
- dstBegin = (height - 1) * width;
- dstIndex = height -1;
- dstIndexInc = -1;
- buf = imageYdown[0];
- }
- }
-
- switch (biType) {
- case BufferedImage.TYPE_INT_ARGB:
- int[] intData =
- ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- // Multiply by 4 to get the byte incr and start point
- j = 0;
- for(h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=4, i++) {
- intData[i] = (((buf[j+3] &0xff) << 24) | // a
- ((buf[j] &0xff) << 16) | // r
- ((buf[j+1] &0xff) << 8) | // g
- (buf[j+2] & 0xff)); // b
-
-
- }
- }
- break;
-
- case BufferedImage.TYPE_INT_RGB:
- intData =
- ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- // Multiply by 4 to get the byte incr and start point
- j = 0;
- for(h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=4, i++) {
- intData[i] = (0xff000000 | // a
- ((buf[j] &0xff) << 16) | // r
- ((buf[j+1] &0xff) << 8) | // g
- (buf[j+2] & 0xff)); // b
-
-
- }
- }
- break;
-
- case BufferedImage.TYPE_4BYTE_ABGR:
- byte[] byteData =
- ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- // Multiply by 4 to get the byte incr and start point
- j = 0;
- for(h = 0; h < height; h++, dstBegin += (dstInc << 2)) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=4) {
-
- byteData[i++] = buf[j+3]; // a
- byteData[i++] = buf[j+2]; // b
- byteData[i++] = buf[j+1];// g
- byteData[i++] = buf[j]; // r
- }
- }
- break;
- case BufferedImage.TYPE_INT_BGR:
- intData =
- ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- // Multiply by 4 to get the byte incr and start point
- j = 0;
-
- for(h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=4, i++) {
- intData[i] = (0xff000000 | // a
- ((buf[j] &0xff) ) | // r
- ((buf[j+1] &0xff) << 8) | // g
- (buf[j+2] & 0xff)<< 16); // b
-
-
- }
- }
- break;
- case BufferedImage.TYPE_BYTE_GRAY:
- byteData =
- ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- j = 0;
- for( h = 0; h < height; h++, dstBegin += dstInc) {
- System.arraycopy(byteData, dstBegin, buf, j, width);
- j += width;
- }
- break;
- case BufferedImage.TYPE_USHORT_GRAY:
- int pixel;
- j = 0;
- short[] shortData =
- ((DataBufferShort)bi.getRaster().getDataBuffer()).getData();
- // Multiply by 4 to get the byte incr and start point
- for(h = 0; h < height; h++, dstBegin+= dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, i++, j++) {
- shortData[i] = (short)buf[j];
- }
- }
- break;
-
- default:
- j = 0;
- for( h = 0; h < height; h++, dstIndex += dstIndexInc) {
- i = dstIndex;
- for (w = 0; w < width; w++, j+=4) {
- pixel = (((buf[j+3] &0xff) << 24) | // a
- ((buf[j] &0xff) << 16) | // r
- ((buf[j+1] &0xff) << 8) | // g
- (buf[j+2] & 0xff)); // b
- bi.setRGB(w, i, pixel);
-
- }
- }
- break;
- }
-
+ // refImage has to be a BufferedImage for off screen and read raster
+ assert refImage[depth] != null;
+ assert (refImage[depth] instanceof BufferedImage);
+
+ BufferedImage bi = (BufferedImage)refImage[depth];
+ int biType = bi.getType();
+ byte[] buf = imageData.getAsByteArray();
+
+ // convert from Ydown to Yup for texture
+ if (!yUp) {
+ dstInc = -1 * width;
+ dstBegin = (height - 1) * width;
+ dstIndex = height -1;
+ dstIndexInc = -1;
+ } else {
+ dstInc = width;
+ dstBegin = 0;
+ dstIndex = 0;
+ dstIndexInc = 1;
+ }
+
+ switch (biType) {
+ case BufferedImage.TYPE_INT_ARGB:
+ int[] intData =
+ ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ // Multiply by 4 to get the byte incr and start point
+ j = 0;
+ for(h = 0; h < height; h++, dstBegin += dstInc) {
+ i = dstBegin;
+ for (w = 0; w < width; w++, j+=4, i++) {
+ intData[i] = (((buf[j+3] &0xff) << 24) | // a
+ ((buf[j] &0xff) << 16) | // r
+ ((buf[j+1] &0xff) << 8) | // g
+ (buf[j+2] & 0xff)); // b
+
+
+ }
+ }
+ break;
+
+ case BufferedImage.TYPE_INT_RGB:
+ intData =
+ ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ // Multiply by 4 to get the byte incr and start point
+ j = 0;
+ for(h = 0; h < height; h++, dstBegin += dstInc) {
+ i = dstBegin;
+ for (w = 0; w < width; w++, j+=4, i++) {
+ intData[i] = (0xff000000 | // a
+ ((buf[j] &0xff) << 16) | // r
+ ((buf[j+1] &0xff) << 8) | // g
+ (buf[j+2] & 0xff)); // b
+
+
+ }
+ }
+ break;
+
+ case BufferedImage.TYPE_4BYTE_ABGR:
+ byte[] byteData =
+ ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
+ // Multiply by 4 to get the byte incr and start point
+ j = 0;
+ for(h = 0; h < height; h++, dstBegin += (dstInc << 2)) {
+ i = dstBegin;
+ for (w = 0; w < width; w++, j+=4) {
+
+ byteData[i++] = buf[j+3]; // a
+ byteData[i++] = buf[j+2]; // b
+ byteData[i++] = buf[j+1];// g
+ byteData[i++] = buf[j]; // r
+ }
+ }
+ break;
+ case BufferedImage.TYPE_INT_BGR:
+ intData =
+ ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ // Multiply by 4 to get the byte incr and start point
+ j = 0;
+
+ for(h = 0; h < height; h++, dstBegin += dstInc) {
+ i = dstBegin;
+ for (w = 0; w < width; w++, j+=4, i++) {
+ intData[i] = (0xff000000 | // a
+ ((buf[j] &0xff) ) | // r
+ ((buf[j+1] &0xff) << 8) | // g
+ (buf[j+2] & 0xff)<< 16); // b
+
+
+ }
+ }
+ break;
+ case BufferedImage.TYPE_BYTE_GRAY:
+ byteData =
+ ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
+ j = 0;
+ for( h = 0; h < height; h++, dstBegin += dstInc) {
+ System.arraycopy(byteData, dstBegin, buf, j, width);
+ j += width;
+ }
+ break;
+ case BufferedImage.TYPE_USHORT_GRAY:
+ int pixel;
+ j = 0;
+ short[] shortData =
+ ((DataBufferShort)bi.getRaster().getDataBuffer()).getData();
+ // Multiply by 4 to get the byte incr and start point
+ for(h = 0; h < height; h++, dstBegin+= dstInc) {
+ i = dstBegin;
+ for (w = 0; w < width; w++, i++, j++) {
+ shortData[i] = (short)buf[j];
+ }
+ }
+ break;
+
+ default:
+ j = 0;
+ for( h = 0; h < height; h++, dstIndex += dstIndexInc) {
+ i = dstIndex;
+ for (w = 0; w < width; w++, j+=4) {
+ pixel = (((buf[j+3] &0xff) << 24) | // a
+ ((buf[j] &0xff) << 16) | // r
+ ((buf[j+1] &0xff) << 8) | // g
+ (buf[j+2] & 0xff)); // b
+ bi.setRGB(w, i, pixel);
+
+ }
+ }
+ break;
+ }
+
}
- /**
- * Copy image data from ImageComponent's internal representation
- * to Buffered Image
- */
- final void copyToBufferedImage(byte[] buf, int depth,
- boolean usedByTexture) {
-
- int w, h, i, j;
- int dstBegin, dstInc, srcBegin;
-
-
- // convert from Ydown to Yup for texture
- if (!yUp) {
- if (usedByTexture == true) {
- srcBegin = depth * width * height * bytesPerYupPixelStored;
- dstInc = -1 * width;
- dstBegin = (height - 1) * width;
- } else {
- srcBegin = 0;
- dstInc = width;
- dstBegin = 0;
- }
- }
- else {
- if (usedByTexture == true) {
- srcBegin = 0;
- dstInc = width;
- dstBegin = 0;
- }
- else {
- srcBegin = depth * width * height * bytesPerYdownPixelStored;
- dstInc = -1 * width;
- dstBegin = (height - 1) * width;
- }
- }
-
- // Note that if a copy has been made, then its always a bufferedImage
- // and not a renderedImage
- int[] intData = ((DataBufferInt)
- ((BufferedImage)bImage[depth]).getRaster().getDataBuffer()).getData();
-
- switch(format) {
- case ImageComponent.FORMAT_RGBA8:
- case ImageComponent.FORMAT_RGB5_A1:
- case ImageComponent.FORMAT_RGBA4:
-
- for (j = srcBegin, h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=4, i++) {
- intData[i] = ((buf[j+3] & 0xff) << 24) |
- ((buf[j] & 0xff) << 16) |
- ((buf[j+1] & 0xff) << 8) |
- (buf[j+2] & 0xff);
+ void scaleImage(int xScale, int yScale, int depthIndex, ImageComponentRetained origImage) {
+
+ byte[] dstByteBuffer = null;
+ byte[] srcByteBuffer = null;
+ int[] dstIntBuffer = null;
+ int[] srcIntBuffer = null;
+ int dStart, sStart;
+
+ switch(imageData.getType()) {
+ case TYPE_BYTE_ARRAY:
+ dstByteBuffer = imageData.getAsByteArray();
+ srcByteBuffer = origImage.imageData.getAsByteArray();
+ dStart = depthIndex * width * height * unitsPerPixel;
+ sStart = depthIndex * origImage.width * origImage.height * unitsPerPixel;
+ scaleImage(xScale, yScale, dStart, sStart, origImage, dstByteBuffer, srcByteBuffer);
+ break;
+ case TYPE_INT_ARRAY:
+ dstIntBuffer = imageData.getAsIntArray();
+ srcIntBuffer = origImage.imageData.getAsIntArray();
+ dStart = depthIndex * width * height * unitsPerPixel;
+ sStart = depthIndex * origImage.width * origImage.height * unitsPerPixel;
+ scaleImage(xScale, yScale, dStart, sStart, origImage, dstIntBuffer, srcIntBuffer);
+ break;
+ default:
+ assert false;
+ }
+
+ }
+
+ void scaleImage(int xScale, int yScale, int dStart, int sStart, ImageComponentRetained origImage,
+ byte[] dData, byte[] sData) {
+
+ int dOffset = 0;
+ int sOffset = 0;
+ int sLineIncr = unitsPerPixel * origImage.width;
+ int sPixelIncr = unitsPerPixel << 1;
+
+ assert ((xScale != 1) || (yScale != 1));
+
+ if (yScale == 1) {
+ for (int x = 0; x < width; x++) {
+ for (int k = 0; k < unitsPerPixel; k++) {
+ dData[dStart + dOffset + k] = (byte)
+ (((int)(sData[sStart + sOffset + k] & 0xff) +
+ (int)(sData[sStart + sOffset + k
+ + unitsPerPixel] & 0xff) + 1) >> 1);
}
+ dOffset += unitsPerPixel;
+ sOffset += sPixelIncr;
}
- break;
-
-
- case ImageComponent.FORMAT_RGB8:
- case ImageComponent.FORMAT_RGB5:
- case ImageComponent.FORMAT_RGB4:
- case ImageComponent.FORMAT_R3_G3_B2:
- for (j = srcBegin, h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=4, i++) {
- intData[i] = ((buf[j] & 0xff) << 16) |
- ((buf[j+1] & 0xff) << 8) |
- (buf[j+2] & 0xff);
- }
- }
- break;
-
- case ImageComponent.FORMAT_LUM8_ALPHA8:
- case ImageComponent.FORMAT_LUM4_ALPHA4:
- for (j = srcBegin, h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=2, i++) {
- intData[i] = ((buf[j+1] & 0xff) << 24) |
- ((buf[j] & 0xff) << 16);
+ } else if (xScale == 1) {
+ for (int y = 0; y < height; y++) {
+ for (int k = 0; k < unitsPerPixel; k++) {
+ dData[dStart + dOffset + k] = (byte)
+ (((int)(sData[sStart + sOffset + k] & 0xff) +
+ (int)(sData[sStart + sOffset + k
+ + sLineIncr] & 0xff) + 1) >> 1);
}
- }
- break;
-
- case ImageComponent.FORMAT_CHANNEL8:
- for (j = srcBegin, h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j++, i++) {
- intData[i] = ((buf[j] & 0xff) << 16);
+ dOffset += unitsPerPixel;
+ sOffset += sLineIncr;
+ }
+ } else {
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ for (int k = 0; k < unitsPerPixel; k++) {
+ dData[dStart + dOffset + k] = (byte)
+ (((int)(sData[sStart + sOffset + k] & 0xff) +
+ (int)(sData[sStart + sOffset + k
+ + unitsPerPixel] & 0xff) +
+ (int)(sData[sStart + sOffset + k
+ + sLineIncr] & 0xff) +
+ (int)(sData[sStart + sOffset + k + sLineIncr +
+ + unitsPerPixel] & 0xff) + 2) >> 2);
+ }
+ dOffset += unitsPerPixel;
+ sOffset += sPixelIncr;
}
- }
- break;
- }
+ sOffset += sLineIncr;
+ }
+ }
}
-
- Object getData(DataBuffer buffer) {
- Object data = null;
- switch (buffer.getDataType()) {
- case DataBuffer.TYPE_BYTE:
- data = ((DataBufferByte)buffer).getData();
- break;
- case DataBuffer.TYPE_INT:
- data = ((DataBufferInt)buffer).getData();
- break;
- case DataBuffer.TYPE_SHORT:
- data = ((DataBufferShort)buffer).getData();
- break;
- }
- return data;
+
+ void scaleImage(int xScale, int yScale, int dStart, int sStart, ImageComponentRetained origImage,
+ int[] dData, int[] sData) {
+
+ int dOffset = 0;
+ int sOffset = 0;
+ int sLineIncr = origImage.width;
+ int sPixelIncr = 2;
+
+ assert ((xScale != 1) || (yScale != 1));
+
+ int sTemp1, sTemp2;
+ int[] comp = new int[4];
+ if (yScale == 1) {
+ for (int x = 0; x < width; x++) {
+ sTemp1 = sData[sStart + sOffset];
+ sTemp2 = sData[sStart + sOffset + 1];
+ // Unpack and compute
+ for (int k = 0; k < numberOfComponents; k++) {
+ comp[k] = ((sTemp1 & 0xff) + (sTemp2 & 0xff) + 1) >> 1;
+ sTemp1 = sTemp1 >> 8;
+ sTemp2 = sTemp2 >> 8;
+ }
+ // Pack back computed value.
+ sTemp1 = comp[numberOfComponents - 1];
+ if(numberOfComponents > 1) {
+ for (int k = numberOfComponents - 2; k >= 0; k--) {
+ sTemp1 = (sTemp1 << 8) + comp[k];
+ }
+ }
+ dData[dStart + dOffset] = sTemp1;
+
+ dOffset += 1;
+ sOffset += sPixelIncr;
+ }
+ } else if (xScale == 1) {
+ for (int y = 0; y < height; y++) {
+ sTemp1 = sData[sStart + sOffset];
+ sTemp2 = sData[sStart + sOffset + sLineIncr];
+ // Unpack and compute
+ for (int k = 0; k < numberOfComponents; k++) {
+ comp[k] = ((sTemp1 & 0xff) + (sTemp2 & 0xff) + 1) >> 1;
+ sTemp1 = sTemp1 >> 8;
+ sTemp2 = sTemp2 >> 8;
+ }
+ // Pack back computed value.
+ sTemp1 = comp[numberOfComponents - 1];
+ if(numberOfComponents > 1) {
+ for (int k = numberOfComponents - 2; k >= 0; k--) {
+ sTemp1 = (sTemp1 << 8) + comp[k];
+ }
+ }
+ dData[dStart + dOffset] = sTemp1;
+
+ dOffset += 1;
+ sOffset += sLineIncr;
+ }
+ } else {
+ int sTemp3, sTemp4;
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ sTemp1 = sData[sStart + sOffset];
+ sTemp2 = sData[sStart + sOffset + 1];
+ sTemp3 = sData[sStart + sOffset + sLineIncr];
+ sTemp4 = sData[sStart + sOffset + sLineIncr + 1];
+ // Unpack and compute
+ for (int k = 0; k < numberOfComponents; k++) {
+ comp[k] = ((sTemp1 & 0xff) + (sTemp2 & 0xff) +
+ (sTemp3 & 0xff) + (sTemp4 & 0xff) + 2) >> 2;
+ sTemp1 = sTemp1 >> 8;
+ sTemp2 = sTemp2 >> 8;
+ sTemp3 = sTemp3 >> 8;
+ sTemp4 = sTemp4 >> 8;
+ }
+ // Pack back computed value.
+ sTemp1 = comp[numberOfComponents - 1];
+ if(numberOfComponents > 1) {
+ for (int k = numberOfComponents - 2; k >= 0; k--) {
+ sTemp1 = (sTemp1 << 8) + comp[k];
+ }
+ }
+ dData[dStart + dOffset] = sTemp1;
+
+ dOffset += 1;
+ sOffset += sPixelIncr;
+ }
+ sOffset += sLineIncr;
+ }
+ }
}
-
- final void setByReference(boolean byReference) {
- this.byReference = byReference;
- }
-
- final boolean isByReference() {
- return byReference;
- }
-
- final void setYUp( boolean yUp) {
- this.yUp = yUp;
- }
-
- final boolean isYUp() {
- return yUp;
- }
-
- // Add a user to the userList
- synchronized void addUser(NodeComponentRetained node) {
+
+
+ // Add a user to the userList
+ synchronized void addUser(NodeComponentRetained node) {
userList.add(node);
- }
-
- // Add a user to the userList
- synchronized void removeUser(NodeComponentRetained node) {
- int i = userList.indexOf(node);
- if (i >= 0) {
- userList.remove(i);
- }
- }
-
- /**
- * ImageComponent object doesn't really have mirror object.
- * But it's using the updateMirrorObject interface to propagate
- * the changes to the users
- */
- synchronized void updateMirrorObject(int component, Object value) {
-
- //System.out.println("ImageComponent.updateMirrorObject");
-
- Object user;
-
- if (((component & IMAGE_CHANGED) != 0) ||
- ((component & SUBIMAGE_CHANGED) != 0)) {
- synchronized(userList) {
+ }
+
+ // Add a user to the userList
+ synchronized void removeUser(NodeComponentRetained node) {
+ int i = userList.indexOf(node);
+ if (i >= 0) {
+ userList.remove(i);
+ }
+ }
+
+ /*
+ *
+ * @exception IllegalSharingException if this image is
+ * being used by a Canvas3D as an off-screen buffer.
+ */
+ void setLive(boolean inBackgroundGroup, int refCount) {
+ // Do illegalSharing check.
+ if(getUsedByOffScreen()) {
+ throw new IllegalSharingException(J3dI18N.getString("ImageComponent3"));
+ }
+ super.setLive(inBackgroundGroup, refCount);
+ }
+
+ /**
+ * ImageComponent object doesn't really have mirror object.
+ * But it's using the updateMirrorObject interface to propagate
+ * the changes to the users
+ */
+ synchronized void updateMirrorObject(int component, Object value) {
+
+ //System.err.println("ImageComponent.updateMirrorObject");
+
+ Object user;
+
+ if (((component & IMAGE_CHANGED) != 0) ||
+ ((component & SUBIMAGE_CHANGED) != 0)) {
+ synchronized(userList) {
for (int i = userList.size()-1; i >=0; i--) {
- user = userList.get(i);
- if (user != null) {
- if (user instanceof TextureRetained) {
- ((TextureRetained)user).notifyImageComponentImageChanged(this, (ImageComponentUpdateInfo)value);
- } else if (user instanceof RasterRetained) {
- ((RasterRetained)user).notifyImageComponentImageChanged(this, (ImageComponentUpdateInfo)value);
- } else if (user instanceof BackgroundRetained) {
- ((BackgroundRetained)user).notifyImageComponentImageChanged(this, (ImageComponentUpdateInfo)value);
- }
- }
- }
- }
-
- // return the subimage update info to the free list
- if (value != null) {
- VirtualUniverse.mc.addFreeImageUpdateInfo(
- (ImageComponentUpdateInfo)value);
- }
- }
- }
-
- final void sendMessage(int attrMask, Object attr) {
-
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ user = userList.get(i);
+ if (user != null) {
+ if (user instanceof TextureRetained) {
+ ((TextureRetained)user).notifyImageComponentImageChanged(this, (ImageComponentUpdateInfo)value);
+ } else if (user instanceof RasterRetained) {
+ ((RasterRetained)user).notifyImageComponentImageChanged(this, (ImageComponentUpdateInfo)value);
+ } else if (user instanceof BackgroundRetained) {
+ ((BackgroundRetained)user).notifyImageComponentImageChanged(this, (ImageComponentUpdateInfo)value);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ final void sendMessage(int attrMask, Object attr) {
+
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES |
- J3dThread.UPDATE_RENDER;
+ J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.IMAGE_COMPONENT_CHANGED;
createMessage.universe = null;
createMessage.args[0] = this;
createMessage.args[1]= new Integer(attrMask);
createMessage.args[2] = attr;
- createMessage.args[3] = new Integer(changedFrequent);
+ createMessage.args[3] = new Integer(changedFrequent);
VirtualUniverse.mc.processMessage(createMessage);
- }
-
+ }
+
void handleFrequencyChange(int bit) {
- if (bit == ImageComponent.ALLOW_IMAGE_WRITE) {
- setFrequencyChangeMask(ImageComponent.ALLOW_IMAGE_WRITE, 0x1);
- }
+ if (bit == ImageComponent.ALLOW_IMAGE_WRITE) {
+ setFrequencyChangeMask(ImageComponent.ALLOW_IMAGE_WRITE, 0x1);
+ }
}
-
+
static Object getDataElementBuffer(java.awt.image.Raster ras) {
- int nc = ras.getNumDataElements();
-
+ int nc = ras.getNumDataElements();
+
switch (ras.getTransferType()) {
- case DataBuffer.TYPE_INT:
- return new int[nc];
- case DataBuffer.TYPE_BYTE:
- return new byte[nc];
- case DataBuffer.TYPE_USHORT:
- case DataBuffer.TYPE_SHORT:
- return new short[nc];
- case DataBuffer.TYPE_FLOAT:
- return new float[nc];
- case DataBuffer.TYPE_DOUBLE:
- return new double[nc];
- }
- // Should not happen
- return null;
- }
-}
+ case DataBuffer.TYPE_INT:
+ return new int[nc];
+ case DataBuffer.TYPE_BYTE:
+ return new byte[nc];
+ case DataBuffer.TYPE_USHORT:
+ case DataBuffer.TYPE_SHORT:
+ return new short[nc];
+ case DataBuffer.TYPE_FLOAT:
+ return new float[nc];
+ case DataBuffer.TYPE_DOUBLE:
+ return new double[nc];
+ }
+ // Should not happen
+ return null;
+ }
+
+ /**
+ * Wrapper class for image data.
+ * Currently supports byte array and int array.
+ * Will eventually support NIO ByteBuffer and IntBuffer.
+ */
+ class ImageData {
+
+ private Object data = null;
+ private ImageDataType imageDataType = ImageDataType.TYPE_NULL;
+ private int length = 0;
+ private boolean dataIsByRef = false;
+ private int dataWidth, dataHeight;
+
+ /**
+ * Constructs a new ImageData buffer of the specified type with the
+ * specified length.
+ */
+ ImageData(ImageDataType imageDataType, int length, int dataWidth, int dataHeight) {
+ this.imageDataType = imageDataType;
+ this.length = length;
+ this.dataWidth = dataWidth;
+ this.dataHeight = dataHeight;
+ this.dataIsByRef = false;
+
+ switch (imageDataType) {
+ case TYPE_BYTE_ARRAY:
+ data = new byte[length];
+ break;
+ case TYPE_INT_ARRAY:
+ data = new int[length];
+ break;
+ case TYPE_BYTE_BUFFER:
+ ByteOrder order = ByteOrder.nativeOrder();
+ data = ByteBuffer.allocateDirect(length).order(order);
+ break;
+ case TYPE_INT_BUFFER:
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Constructs a new ImageData buffer of the specified type with the
+ * specified length and the specified byRefImage as data.
+ */
+ ImageData(ImageDataType imageDataType, int length, int dataWidth, int dataHeight,
+ Object byRefImage) {
+ BufferedImage bi;
+ NioImageBuffer nio;
+
+ this.imageDataType = imageDataType;
+ this.length = length;
+ this.dataWidth = dataWidth;
+ this.dataHeight = dataHeight;
+ this.dataIsByRef = true;
+
+ switch (imageDataType) {
+ case TYPE_BYTE_ARRAY:
+ bi = (BufferedImage) byRefImage;
+ data = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
+ break;
+ case TYPE_INT_ARRAY:
+ bi = (BufferedImage) byRefImage;
+ data = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ break;
+ case TYPE_BYTE_BUFFER:
+ case TYPE_INT_BUFFER:
+ nio = (NioImageBuffer) byRefImage;
+ data = nio.getDataBuffer();
+ break;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Constructs a new ImageData buffer from the specified
+ * object. This object stores a reference to the input image data.
+ */
+ ImageData(Object data, boolean isByRef) {
+ this.data = data;
+ dataIsByRef = isByRef;
+ dataWidth = ((ImageData) data).dataWidth;
+ dataHeight = ((ImageData) data).dataHeight;
+
+ if (data == null) {
+ imageDataType = ImageDataType.TYPE_NULL;
+ length = 0;
+ } else if (data instanceof byte[]) {
+ imageDataType = ImageDataType.TYPE_BYTE_ARRAY;
+ length = ((byte[]) data).length;
+ } else if (data instanceof int[]) {
+ imageDataType = ImageDataType.TYPE_INT_ARRAY;
+ length = ((int[]) data).length;
+ } else if (data instanceof ByteBuffer) {
+ imageDataType = ImageDataType.TYPE_BYTE_BUFFER;
+ length = ((ByteBuffer) data).limit();
+ } else if (data instanceof IntBuffer) {
+ imageDataType = ImageDataType.TYPE_INT_BUFFER;
+ length = ((IntBuffer) data).limit();
+ } else {
+ assert false;
+ }
+ }
+
+ /**
+ * Returns the type of this DataBuffer.
+ */
+ ImageDataType getType() {
+ return imageDataType;
+ }
+
+ /**
+ * Returns the number of elements in this DataBuffer.
+ */
+ int length() {
+ return length;
+ }
+
+ /**
+ * Returns the width of this DataBuffer.
+ */
+ int getWidth() {
+ return dataWidth;
+ }
+
+ /**
+ * Returns the height of this DataBuffer.
+ */
+ int getHeight() {
+ return dataHeight;
+ }
+
+ /**
+ * Returns this DataBuffer as an Object.
+ */
+ Object get() {
+ return data;
+ }
+
+ /**
+ * Returns is this data is byRef. No internal data is made.
+ */
+ boolean isDataByRef() {
+ return dataIsByRef;
+ }
+
+
+ /**
+ * Returns this DataBuffer as a byte array.
+ */
+ byte[] getAsByteArray() {
+ return (byte[]) data;
+ }
+
+ /**
+ * Returns this DataBuffer as an int array.
+ */
+ int[] getAsIntArray() {
+ return (int[]) data;
+ }
+
+ /**
+ * Returns this DataBuffer as an nio ByteBuffer.
+ */
+ ByteBuffer getAsByteBuffer() {
+ return (ByteBuffer) data;
+ }
+
+ /**
+ * Returns this DataBuffer as an nio IntBuffer.
+ */
+ IntBuffer getAsIntBuffer() {
+ return (IntBuffer) data;
+ }
+
+ // Handle TYPE_BYTE_LA only
+ void copyByLineAndExpand(BufferedImage bi, int depthIndex) {
+ int h;
+ int srcBegin, // src begin offset
+ dstBegin; // dst begin offset
+
+ assert (imageData.getType() == ImageDataType.TYPE_BYTE_ARRAY);
+ assert (imageFormatType == ImageFormatType.TYPE_BYTE_LA);
+
+ int unitsPerRow = width * unitsPerPixel; // bytes per row
+ int scanline = unitsPerRow;
+ if (yUp) {
+ srcBegin = (depthIndex * width * height) * unitsPerPixel;
+ } else {
+ srcBegin = (depthIndex * width * height + (height - 1) * width) * unitsPerPixel;
+ unitsPerRow = - 1 * unitsPerRow;
+ }
+
+ dstBegin = 0;
+ // ABGR is 4 bytes per pixel
+ int dstUnitsPerRow = width * 4;
+
+ byte[] dstByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
+ byte[] srcByteBuffer = imageData.getAsByteArray();
+ for (h = 0; h < height; h++) {
+ for( int v = 0, w = 0; w < scanline; w += unitsPerPixel, v += 4) {
+ dstByteBuffer[dstBegin+v] = srcByteBuffer[srcBegin+w+1]; // Alpha
+ dstByteBuffer[dstBegin+v+1] = 0;
+ dstByteBuffer[dstBegin+v+2] = 0;
+ dstByteBuffer[dstBegin+v+3] = srcByteBuffer[srcBegin+w]; // Red
+ }
+
+ dstBegin += dstUnitsPerRow;
+ srcBegin += unitsPerRow;
+ }
+
+ }
+
+ // Quick line by line copy
+ void copyByLine(BufferedImage bi, int depthIndex, boolean swapNeeded) {
+
+ int h;
+ int srcBegin, // src begin offset
+ dstBegin; // dst begin offset
+
+ int unitsPerRow = width * unitsPerPixel; // bytes per row
+ int copyUnits = unitsPerRow;
+ if (yUp) {
+ srcBegin = (depthIndex * width * height) * unitsPerPixel;
+ } else {
+ srcBegin = (depthIndex * width * height + (height - 1) * width) * unitsPerPixel;
+ unitsPerRow = - 1 * unitsPerRow;
+ }
+
+ dstBegin = 0;
+
+ switch(imageData.getType()) {
+ case TYPE_BYTE_ARRAY:
+ byte[] dstByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
+ byte[] srcByteBuffer = imageData.getAsByteArray();
+ for (h = 0; h < height; h++) {
+ if(!swapNeeded) {
+ System.arraycopy(srcByteBuffer, srcBegin,
+ dstByteBuffer, dstBegin, copyUnits);
+ } else {
+ if(imageFormatType == ImageFormatType.TYPE_BYTE_RGB) {
+ assert (unitsPerPixel == 3);
+ for(int w = 0; w < copyUnits; w += unitsPerPixel) {
+ dstByteBuffer[dstBegin+w] = srcByteBuffer[srcBegin+w+2];
+ dstByteBuffer[dstBegin+w+1] = srcByteBuffer[srcBegin+w+1];
+ dstByteBuffer[dstBegin+w+2] = srcByteBuffer[srcBegin+w];
+ }
+ } else if(imageFormatType == ImageFormatType.TYPE_BYTE_RGBA) {
+ assert (unitsPerPixel == 4);
+ for(int w = 0; w < copyUnits; w += unitsPerPixel) {
+ dstByteBuffer[dstBegin+w] = srcByteBuffer[srcBegin+w+3];
+ dstByteBuffer[dstBegin+w+1] = srcByteBuffer[srcBegin+w+2];
+ dstByteBuffer[dstBegin+w+2] = srcByteBuffer[srcBegin+w+1];
+ dstByteBuffer[dstBegin+w+3] = srcByteBuffer[srcBegin+w];
+ }
+ } else {
+ assert false;
+ }
+ }
+ dstBegin += copyUnits;
+ srcBegin += unitsPerRow;
+ }
+ break;
+
+ // INT case doesn't required to handle swapNeeded
+ case TYPE_INT_ARRAY:
+ assert (!swapNeeded);
+ int[] dstIntBuffer = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ int[] srcIntBuffer = imageData.getAsIntArray();
+ for (h = 0; h < height; h++) {
+ System.arraycopy(srcIntBuffer, srcBegin, dstIntBuffer, dstBegin, copyUnits);
+ dstBegin += copyUnits;
+ srcBegin += unitsPerRow;
+ }
+ break;
+ default:
+ assert false;
+ }
+ }
+
+ void copyByBlock(BufferedImage bi, int depthIndex) {
+ // src begin offset
+ int srcBegin = depthIndex * width * height * unitsPerPixel;
+
+ switch(imageData.getType()) {
+ case TYPE_BYTE_ARRAY:
+ byte[] dstByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
+ byte[] srcByteBuffer = imageData.getAsByteArray();
+ System.arraycopy(srcByteBuffer, srcBegin, dstByteBuffer, 0, (height * width * unitsPerPixel));
+ break;
+ case TYPE_INT_ARRAY:
+ int[] dstIntBuffer = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
+ int[] srcIntBuffer = imageData.getAsIntArray();
+ System.arraycopy(srcIntBuffer, srcBegin, dstIntBuffer, 0, (height * width * unitsPerPixel));
+ break;
+ default:
+ assert false;
+ }
+ }
+
+ // Need to check for imageData is null. if it is null return null.
+ BufferedImage createBufferedImage(int depthIndex) {
+ if(data != null) {
+ int bufferType = BufferedImage.TYPE_CUSTOM;
+ boolean swapNeeded = false;
+
+ switch(imageFormatType) {
+ case TYPE_BYTE_BGR:
+ bufferType = BufferedImage.TYPE_3BYTE_BGR;
+ break;
+ case TYPE_BYTE_RGB:
+ bufferType = BufferedImage.TYPE_3BYTE_BGR;
+ swapNeeded = true;
+ break;
+ case TYPE_BYTE_ABGR:
+ bufferType = BufferedImage.TYPE_4BYTE_ABGR;
+ break;
+ case TYPE_BYTE_RGBA:
+ bufferType = BufferedImage.TYPE_4BYTE_ABGR;
+ swapNeeded = true;
+ break;
+ // This is a special case. Need to handle separately.
+ case TYPE_BYTE_LA:
+ bufferType = BufferedImage.TYPE_4BYTE_ABGR;
+ break;
+ case TYPE_BYTE_GRAY:
+ bufferType = BufferedImage.TYPE_BYTE_GRAY;
+ break;
+ case TYPE_INT_BGR:
+ bufferType = BufferedImage.TYPE_INT_BGR;
+ break;
+ case TYPE_INT_RGB:
+ bufferType = BufferedImage.TYPE_INT_RGB;
+ break;
+ case TYPE_INT_ARGB:
+ bufferType = BufferedImage.TYPE_INT_ARGB;
+ break;
+ // Unsupported case, so shouldn't be here.
+ case TYPE_USHORT_GRAY:
+ bufferType = BufferedImage.TYPE_USHORT_GRAY;
+ default:
+ assert false;
+
+ }
+
+ BufferedImage bi = new BufferedImage(width, height, bufferType);
+ if((!swapNeeded) && (imageFormatType != ImageFormatType.TYPE_BYTE_LA)) {
+ if(yUp) {
+ copyByBlock(bi, depthIndex);
+ } else {
+ copyByLine(bi, depthIndex, false);
+ }
+ } else if(swapNeeded) {
+ copyByLine(bi, depthIndex, swapNeeded);
+ } else if(imageFormatType == ImageFormatType.TYPE_BYTE_LA) {
+ copyByLineAndExpand(bi, depthIndex);
+ } else {
+ assert false;
+ }
+
+ return bi;
+
+ }
+ return null;
+ }
+
+ void convertFromABGRToRGBA() {
+ int i;
+
+ if(imageDataType == ImageComponentRetained.ImageDataType.TYPE_BYTE_ARRAY) {
+ // Note : Highly inefficient for depth > 0 case.
+ // This method doesn't take into account of depth, it is assuming that
+ // depth == 0, which is true for ImageComponent2D.
+ byte[] srcBuffer, dstBuffer;
+ srcBuffer = getAsByteArray();
+
+ if(dataIsByRef) {
+ dstBuffer = new byte[length];
+ // Do copy and swap.
+ for(i = 0; i < length; i +=4) {
+ dstBuffer[i] = srcBuffer[i+3];
+ dstBuffer[i+1] = srcBuffer[i+2];
+ dstBuffer[i+2] = srcBuffer[i+1];
+ dstBuffer[i+3] = srcBuffer[i];
+ }
+ data = dstBuffer;
+ dataIsByRef = false;
+
+ } else {
+ byte a, b;
+ // Do swap in place.
+ for(i = 0; i < length; i +=4) {
+ a = srcBuffer[i];
+ b = srcBuffer[i+1];
+ srcBuffer[i] = srcBuffer[i+3];
+ srcBuffer[i+1] = srcBuffer[i+2];
+ srcBuffer[i+2] = b;
+ srcBuffer[i+3] = a;
+ }
+ }
+ }
+ else if(imageDataType == ImageComponentRetained.ImageDataType.TYPE_BYTE_BUFFER) {
+
+ assert dataIsByRef;
+ ByteBuffer srcBuffer, dstBuffer;
+
+ srcBuffer = getAsByteBuffer();
+ srcBuffer.rewind();
+
+ ByteOrder order = ByteOrder.nativeOrder();
+ dstBuffer = ByteBuffer.allocateDirect(length).order(order);
+ dstBuffer.rewind();
+
+ // Do copy and swap.
+ for(i = 0; i < length; i +=4) {
+ dstBuffer.put(i, srcBuffer.get(i+3));
+ dstBuffer.put(i+1, srcBuffer.get(i+2));
+ dstBuffer.put(i+2, srcBuffer.get(i+1));
+ dstBuffer.put(i+3, srcBuffer.get(i));
+ }
+
+ dataIsByRef = false;
+
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/classes/share/javax/media/j3d/IndexedGeometryArray.java b/src/classes/share/javax/media/j3d/IndexedGeometryArray.java
index 67f8914..ae51edc 100644
--- a/src/classes/share/javax/media/j3d/IndexedGeometryArray.java
+++ b/src/classes/share/javax/media/j3d/IndexedGeometryArray.java
@@ -286,6 +286,10 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* than or equal to the number of vertices actually defined for
* the particular component's array.
*
+ * @exception ArrayIndexOutOfBoundsException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE_INDICES</code> and
+ * <code>coordIndices.length &lt; (initialIndexIndex + validIndexCount)</code>.
+ *
* @since Java 3D 1.3
*/
public void setValidIndexCount(int validIndexCount) {
@@ -341,6 +345,10 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* than or equal to the number of vertices actually defined for
* the particular component's array.
*
+ * @exception ArrayIndexOutOfBoundsException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE_INDICES</code> and
+ * <code>coordIndices.length &lt; (initialIndexIndex + validIndexCount)</code>.
+ *
* @since Java 3D 1.3
*/
public void setInitialIndexIndex(int initialIndexIndex) {
@@ -470,6 +478,7 @@ public abstract class IndexedGeometryArray extends GeometryArray {
}
+ //NVaidya
/**
* Sets the coordinate index associated with the vertex at
* the specified index for this object.
@@ -488,15 +497,25 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* coordinateIndex is out of range if it is less than 0 or is
* greater than or equal to the number of vertices actually
* defined for the coordinate array.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE_INDICES</code>.
*/
public void setCoordinateIndex(int index, int coordinateIndex) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_COORDINATE_INDEX_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("IndexedGeometryArray1"));
+
+ //NVaidya
+ int format = ((IndexedGeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE_INDICES) != 0)
+ throw new IllegalStateException(J3dI18N.getString("IndexedGeometryArray31"));
((IndexedGeometryArrayRetained)this.retained).setCoordinateIndex(index, coordinateIndex);
}
+
+ //NVaidya
/**
* Sets the coordinate indices associated with the vertices starting at
* the specified index for this object.
@@ -515,15 +534,64 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* is out of range. An element is out of range if it is less than 0
* or is greater than or equal to the number of vertices actually
* defined for the coordinate array.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE_INDICES</code>.
*/
public void setCoordinateIndices(int index, int coordinateIndices[]) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_COORDINATE_INDEX_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("IndexedGeometryArray1"));
+
+ //NVaidya
+ int format = ((IndexedGeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE_INDICES) != 0)
+ throw new IllegalStateException(J3dI18N.getString("IndexedGeometryArray31"));
((IndexedGeometryArrayRetained)this.retained).setCoordinateIndices(index, coordinateIndices);
}
+ //NVaidya
+ /**
+ * Sets the coordinate indices array reference to the specified array.
+ * If the coordinate indices array reference is null, the entire
+ * geometry array object is treated as if it were null--any
+ * Shape3D or Morph node that uses this geometry array will not be drawn.
+ *
+ * @param coordIndices an array of indices to which a reference
+ * will be set.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is not <code>BY_REFERENCE_INDICES</code>.
+ *
+ * @exception ArrayIndexOutOfBoundsException if any element of the
+ * coordIndices array whose destination position is in the range
+ * <code>[initialIndexIndex, initialIndexIndex+validIndexCount-1]</code>
+ * is out of range. An element is out of range if it is less than 0
+ * or is greater than or equal to the number of vertices actually
+ * defined for the coordinate array.
+ *
+ * @exception ArrayIndexOutOfBoundsException if
+ * <code>coordIndices.length &lt; (initialIndexIndex + validIndexCount)</code>.
+ *
+ * @since Java 3D 1.5
+ */
+ public void setCoordIndicesRef(int coordIndices[]) {
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_REF_DATA_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray86"));
+
+ //NVaidya
+ int format = ((IndexedGeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE_INDICES) == 0)
+ throw new IllegalStateException(J3dI18N.getString("IndexedGeometryArray32"));
+
+ ((IndexedGeometryArrayRetained)this.retained).setCoordIndicesRef(coordIndices);
+ }
+
/**
* Sets the color index associated with the vertex at
* the specified index for this object.
@@ -816,38 +884,81 @@ public abstract class IndexedGeometryArray extends GeometryArray {
((IndexedGeometryArrayRetained)this.retained).setVertexAttrIndices(vertexAttrNum, index, vertexAttrIndices);
}
+ //NVaidya
/**
- * Retrieves the coordinate index associated with the vertex at
- * the specified index for this object.
- * @param index the vertex index
- * @return the coordinate index
+ * Retrieves the coordinate index associated with the vertex at
+ * the specified index for this object.
+ * @param index the vertex index
+ * @return the coordinate index
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
- */
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE_INDICES</code>.
+ */
public int getCoordinateIndex(int index) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_COORDINATE_INDEX_READ))
throw new CapabilityNotSetException(J3dI18N.getString("IndexedGeometryArray9"));
+
+ //NVaidya
+ int format = ((IndexedGeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE_INDICES) != 0)
+ throw new IllegalStateException(J3dI18N.getString("IndexedGeometryArray31"));
return ((IndexedGeometryArrayRetained)this.retained).getCoordinateIndex(index);
}
- /**
- * Retrieves the coordinate indices associated with the vertices starting at
- * the specified index for this object.
- * @param index the vertex index
- * @param coordinateIndices array that will receive the coordinate indices
+ //NVaidya
+ /**
+ * Retrieves the coordinate indices associated with the vertices starting at
+ * the specified index for this object.
+ * @param index the vertex index
+ * @param coordinateIndices array that will receive the coordinate indices
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
- */
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE_INDICES</code>.
+ */
public void getCoordinateIndices(int index, int coordinateIndices[]) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_COORDINATE_INDEX_READ))
throw new CapabilityNotSetException(J3dI18N.getString("IndexedGeometryArray9"));
+
+ //NVaidya
+ int format = ((IndexedGeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE_INDICES) != 0)
+ throw new IllegalStateException(J3dI18N.getString("IndexedGeometryArray31"));
((IndexedGeometryArrayRetained)this.retained).getCoordinateIndices(index, coordinateIndices);
}
+ //NVaidya
+ /**
+ * Returns a reference to the coordinate indices associated with
+ * the vertices
+ * @return the coordinate indices array
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is not <code>BY_REFERENCE_INDICES</code>.
+ *
+ * @since Java 3D 1.5
+ */
+ public int[] getCoordIndicesRef() {
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_REF_DATA_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray87"));
+
+ int format = ((IndexedGeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE_INDICES) == 0)
+ throw new IllegalStateException(J3dI18N.getString("IndexedGeometryArray32"));
+
+ return ((IndexedGeometryArrayRetained)this.retained).getCoordIndicesRef();
+ }
+
/**
* Retrieves the color index associated with the vertex at
* the specified index for this object.
diff --git a/src/classes/share/javax/media/j3d/IndexedGeometryArrayRetained.java b/src/classes/share/javax/media/j3d/IndexedGeometryArrayRetained.java
index 5fb7ba7..e53565b 100644
--- a/src/classes/share/javax/media/j3d/IndexedGeometryArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/IndexedGeometryArrayRetained.java
@@ -13,13 +13,8 @@
package javax.media.j3d;
import javax.vecmath.*;
-import java.util.Vector;
import java.util.ArrayList;
-import com.sun.j3d.internal.ByteBufferWrapper;
-import com.sun.j3d.internal.BufferWrapper;
import com.sun.j3d.internal.FloatBufferWrapper;
-import com.sun.j3d.internal.DoubleBufferWrapper;
-
/**
* The IndexedGeometryArray object contains arrays of positional coordinates,
@@ -60,7 +55,10 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
// index arrays if USE_COORD_INDEX_ONLY is not set
boolean notUCIO = (this.vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0;
- if((this.vertexFormat & GeometryArray.COORDINATES) != 0)
+ //NVaidya
+ // Only allocate indexCoord if BY_REFERENCE_INDICES not set
+ if(((this.vertexFormat & GeometryArray.COORDINATES) != 0) &&
+ ((this.vertexFormat & GeometryArray.BY_REFERENCE_INDICES) == 0))
this.indexCoord = new int[indexCount];
if(((this.vertexFormat & GeometryArray.NORMALS) != 0) && notUCIO)
@@ -626,6 +624,120 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
}
}
+ //NVaidya
+ /**
+ * Sets the coordinate indices by reference to the specified array
+ * @param coordinateIndices an array of coordinate indices
+ */
+ final void setCoordIndicesRef(int coordinateIndices[]) {
+ int newMax = 0;
+
+ if (coordinateIndices != null) {
+ if (coordinateIndices.length < initialIndexIndex + validIndexCount) {
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray33"));
+ }
+
+ //
+ // option 1: could fake the args to "re-use" doIndicesCheck()
+ //NVaidya
+ // newMax = doIndicesCheck(0, maxCoordIndex, coordinateIndices, coordinateIndices);
+ // if (newMax > maxCoordIndex) {
+ // doErrorCheck(newMax);
+ // }
+ //
+ // option 2: same logic as in setInitialIndexIndex: Better, I Think ?
+ // computeMaxIndex() doesn't check for index < 0 while doIndicesCheck() does.
+ // So, a new method computeMaxIndexWithCheck
+ //NVaidya
+ newMax = computeMaxIndexWithCheck(initialIndexIndex, validIndexCount, coordinateIndices);
+ if (newMax > maxCoordIndex) {
+ doErrorCheck(newMax);
+ }
+ }
+
+ if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) {
+ if ((vertexFormat & GeometryArray.COLOR) != 0) {
+ maxColorIndex = newMax;
+ }
+ if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ for (int i = 0; i < texCoordSetCount; i++) {
+ maxTexCoordIndices[i] = newMax;
+ }
+ }
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ maxVertexAttrIndices[i] = newMax;
+ }
+ }
+ if ((vertexFormat & GeometryArray.NORMALS) != 0) {
+ maxNormalIndex = newMax;
+ }
+ }
+
+ geomLock.getLock();
+ dirtyFlag |= INDEX_CHANGED;
+ maxCoordIndex = newMax;
+ this.indexCoord = coordinateIndices;
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(true);
+ }
+ }
+
+ //NVaidya
+ /**
+ * trigger from GeometryArrayRetained#updateData()
+ * to recompute maxCoordIndex and perform index integrity checks
+ */
+ final void doPostUpdaterUpdate() {
+ // user may have called setCoordIndicesRef and/or
+ // changed contents of indexCoord array. Thus, need to
+ // recompute maxCoordIndex unconditionally (and redundantly
+ // if user had only invoked setCoordIndicesRef but not also
+ // changed contents). geomLock is currently locked.
+
+ // Option 1:
+ // simply call setCoordIndicesRef(indexCoord); but this seems to cause
+ // deadlock or freeze - probably because the !inUpdater branch sends
+ // out too many sendDataChangedMessage(true) - occurs if updateData
+ // method is called rapidly.
+ // setCoordIndicesRef(indexCoord);
+
+ // Option 2:
+ // use only necessary code from setCoordIndicesRef
+ // System.out.println("IndexedGeometryArrayretained#doUpdaterUpdate");
+ int newMax = 0;
+
+ if (indexCoord != null) {
+ newMax = computeMaxIndexWithCheck(initialIndexIndex, validIndexCount, indexCoord);
+ if (newMax > maxCoordIndex) {
+ doErrorCheck(newMax);
+ }
+ }
+
+ if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) {
+ if ((vertexFormat & GeometryArray.COLOR) != 0) {
+ maxColorIndex = newMax;
+ }
+ if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ for (int i = 0; i < texCoordSetCount; i++) {
+ maxTexCoordIndices[i] = newMax;
+ }
+ }
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ maxVertexAttrIndices[i] = newMax;
+ }
+ }
+ if ((vertexFormat & GeometryArray.NORMALS) != 0) {
+ maxNormalIndex = newMax;
+ }
+ }
+
+ dirtyFlag |= INDEX_CHANGED;
+ maxCoordIndex = newMax;
+ }
+
/**
* Sets the color index associated with the vertex at
* the specified index for this object.
@@ -781,9 +893,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* the specified index for the specified vertex attribute number
* for this object.
*/
- public void setVertexAttrIndex(int vertexAttrNum,
- int index,
- int vertexAttrIndex) {
+ void setVertexAttrIndex(int vertexAttrNum,
+ int index,
+ int vertexAttrIndex) {
int newMax;
int [] indices = this.indexVertexAttr[vertexAttrNum];
@@ -806,9 +918,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* starting at the specified index for the specified vertex attribute number
* for this object.
*/
- public void setVertexAttrIndices(int vertexAttrNum,
- int index,
- int[] vertexAttrIndices) {
+ void setVertexAttrIndices(int vertexAttrNum,
+ int index,
+ int[] vertexAttrIndices) {
int i, j, num = vertexAttrIndices.length;
int [] indices = this.indexVertexAttr[vertexAttrNum];
@@ -854,6 +966,15 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
}
}
+ //NVaidya
+ /**
+ * Returns a reference to the coordinate indices associated
+ * with the vertices
+ */
+ final int[] getCoordIndicesRef() {
+ return this.indexCoord;
+ }
+
/**
* Retrieves the color index associated with the vertex at
* the specified index for this object.
@@ -936,8 +1057,8 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* the specified index for the specified vertex attribute number
* for this object.
*/
- public int getVertexAttrIndex(int vertexAttrNum,
- int index) {
+ int getVertexAttrIndex(int vertexAttrNum,
+ int index) {
int [] indices = this.indexVertexAttr[vertexAttrNum];
@@ -949,9 +1070,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* starting at the specified index for the specified vertex attribute number
* for this object.
*/
- public void getVertexAttrIndices(int vertexAttrNum,
- int index,
- int[] vertexAttrIndices) {
+ void getVertexAttrIndices(int vertexAttrNum,
+ int index,
+ int[] vertexAttrIndices) {
int i, j, num = vertexAttrIndices.length;
int [] indices = this.indexVertexAttr[vertexAttrNum];
@@ -961,124 +1082,26 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
}
}
- // by-copy or interleaved, by reference, Java arrays
- private native void executeIndexedGeometry(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean useAlpha,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int initialIndexIndex,
- int indexCount,
- int vertexCount, int vformat,
- int vertexAttrCount, int[] vertexAttrSizes,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetOffset,
- int numActiveTexUnitState,
- int[] texUnitStateMap,
- float[] varray, float[] cdata,
- int texUnitIndex, int cdirty,
- int[] indexCoord);
-
- // interleaved, by reference, nio buffer
- private native void executeIndexedGeometryBuffer(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean useAlpha,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int initialIndexIndex,
- int indexCount,
- int vertexCount, int vformat,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetOffset,
- int numActiveTexUnitState,
- int[] texUnitStateMap,
- Object varray, float[] cdata,
- int texUnitIndex, int cdirty,
- int[] indexCoord);
-
- // non interleaved, by reference, Java arrays
- private native void executeIndexedGeometryVA(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int initialIndexIndex,
- int validIndexCount,
- int vertexCount,
- int vformat,
- int vdefined,
- float[] vfcoords, double[] vdcoords,
- float[] cfdata, byte[] cbdata,
- float[] ndata,
- int vertexAttrCount, int[] vertexAttrSizes,
- float[][] vertexAttrData,
- int pass, int texcoordmaplength,
- int[] texcoordoffset,
- int numActiveTexUnitState, int[] texunitstatemap,
- int texstride, Object[] texCoords,
- int cdirty,
- int[] indexCoord);
-
- // non interleaved, by reference, nio buffer
- private native void executeIndexedGeometryVABuffer(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int initialIndexIndex,
- int validIndexCount,
- int vertexCount,
- int vformat,
- int vdefined,
- Object vcoords,
- Object cdataBuffer,
- float[] cfdata, byte[] cbdata,
- Object normal,
- int vertexAttrCount, int[] vertexAttrSizes,
- Object[] vertexAttrData,
- int pass, int texcoordmaplength,
- int[] texcoordoffset,
- int numActiveTexUnitState, int[] texunitstatemap,
- int texstride, Object[] texCoords,
- int cdirty,
- int[] indexCoord);
-
- // by-copy geometry
- private native void buildIndexedGeometry(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale, boolean updateAlpha,
- float alpha,
- boolean ignoreVertexColors,
- int initialIndexIndex,
- int validIndexCount,
- int vertexCount,
- int vformat,
- int vertexAttrCount, int[] vertexAttrSizes,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetMapOffset,
- double[] xform, double[] nxform,
- float[] varray, int[] indexCoord);
-
void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
boolean updateAlpha, float alpha,
- boolean multiScreen, int screen,
- boolean ignoreVertexColors, int pass) {
+ int screen, boolean ignoreVertexColors) {
+
int cdirty;
boolean useAlpha = false;
Object[] retVal;
if (mirrorGeometry != null) {
mirrorGeometry.execute(cv, ra, isNonUniformScale, updateAlpha, alpha,
- multiScreen, screen,
- ignoreVertexColors, pass);
+ screen, ignoreVertexColors);
return;
}
- //By reference with java array
+
+ // Check if index array is null; if yes, don't draw anything
+ if (indexCoord == null) {
+ return;
+ }
+
+ //By reference with java array
if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) {
if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) {
float[] vdata;
@@ -1111,9 +1134,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
dirtyFlag = 0;
}
- executeIndexedGeometry(cv.ctx, this, geoType, isNonUniformScale,
+ Pipeline.getPipeline().executeIndexedGeometry(cv.ctx,
+ this, geoType, isNonUniformScale,
useAlpha,
- multiScreen,
ignoreVertexColors,
initialIndexIndex,
validIndexCount,
@@ -1124,16 +1147,16 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
texCoordSetCount, texCoordSetMap,
(texCoordSetMap == null) ? 0 : texCoordSetMap.length,
texCoordSetMapOffset,
- cv.numActiveTexUnit, cv.texUnitStateMap,
+ cv.numActiveTexUnit,
vdata, null,
- pass, cdirty, indexCoord);
+ cdirty, indexCoord);
} // end of non by reference
else if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) {
if(interLeavedVertexData == null)
return;
-
+
float[] cdata = null;
synchronized (this) {
@@ -1157,9 +1180,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
dirtyFlag = 0;
}
- executeIndexedGeometry(cv.ctx, this, geoType, isNonUniformScale,
+ Pipeline.getPipeline().executeIndexedGeometry(cv.ctx,
+ this, geoType, isNonUniformScale,
useAlpha,
- multiScreen,
ignoreVertexColors,
initialIndexIndex,
validIndexCount,
@@ -1169,9 +1192,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
texCoordSetCount, texCoordSetMap,
(texCoordSetMap == null) ? 0 : texCoordSetMap.length,
texCoordSetMapOffset,
- cv.numActiveTexUnit, cv.texUnitStateMap,
+ cv.numActiveTexUnit,
interLeavedVertexData, cdata,
- pass, cdirty, indexCoord);
+ cdirty, indexCoord);
} //end of interleaved
else {
// Check if a vertexformat is set, but the array is null
@@ -1252,8 +1275,8 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
if((vertexType & TEXCOORD_DEFINED) != 0)
vdefined |= TEXCOORD_FLOAT;
- executeIndexedGeometryVA(cv.ctx, this, geoType, isNonUniformScale,
- multiScreen,
+ Pipeline.getPipeline().executeIndexedGeometryVA(cv.ctx,
+ this, geoType, isNonUniformScale,
ignoreVertexColors,
initialIndexIndex,
validIndexCount,
@@ -1265,11 +1288,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
mirrorFloatRefNormals,
vertexAttrCount, vertexAttrSizes,
mirrorFloatRefVertexAttrs,
- pass,
((texCoordSetMap == null) ? 0:texCoordSetMap.length),
texCoordSetMap,
cv.numActiveTexUnit,
- cv.texUnitStateMap,
texCoordStride,
mirrorRefTexCoords, cdirty, indexCoord);
}
@@ -1304,20 +1325,20 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
dirtyFlag = 0;
}
- executeIndexedGeometryBuffer(cv.ctx, this, geoType, isNonUniformScale,
- useAlpha,
- multiScreen,
- ignoreVertexColors,
- initialIndexIndex,
- validIndexCount,
- maxCoordIndex + 1,
- vertexFormat,
- texCoordSetCount, texCoordSetMap,
- (texCoordSetMap == null) ? 0 : texCoordSetMap.length,
- texCoordSetMapOffset,
- cv.numActiveTexUnit, cv.texUnitStateMap,
- interleavedFloatBufferImpl.getBufferAsObject(), cdata,
- pass, cdirty, indexCoord);
+ Pipeline.getPipeline().executeIndexedGeometryBuffer(cv.ctx,
+ this, geoType, isNonUniformScale,
+ useAlpha,
+ ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ maxCoordIndex + 1,
+ vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ (texCoordSetMap == null) ? 0 : texCoordSetMap.length,
+ texCoordSetMapOffset,
+ cv.numActiveTexUnit,
+ interleavedFloatBufferImpl.getBufferAsObject(), cdata,
+ cdirty, indexCoord);
} //end of interleaved
else {
// Check if a vertexformat is set, but the array is null
@@ -1417,9 +1438,8 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
vdefined |= TEXCOORD_FLOAT;
}
- executeIndexedGeometryVABuffer(cv.ctx,
+ Pipeline.getPipeline().executeIndexedGeometryVABuffer(cv.ctx,
this, geoType, isNonUniformScale,
- multiScreen,
ignoreVertexColors,
initialIndexIndex,
validIndexCount,
@@ -1432,11 +1452,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
normal,
vertexAttrCount, vertexAttrSizes,
nioFloatBufferRefVertexAttrs,
- pass,
((texCoordSetMap == null) ? 0:texCoordSetMap.length),
texCoordSetMap,
cv.numActiveTexUnit,
- cv.texUnitStateMap,
texCoordStride,
refTexCoords, cdirty, indexCoord);
@@ -1488,7 +1506,8 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
dirtyFlag = 0;
}
- buildIndexedGeometry(cv.ctx, this, geoType, isNonUniformScale,
+ Pipeline.getPipeline().buildIndexedGeometry(cv.ctx,
+ this, geoType, isNonUniformScale,
updateAlpha, alpha, ignoreVertexColors,
initialIndexIndex,
validIndexCount,
@@ -1601,6 +1620,22 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
}
+ //NVaidya
+ // same as computeMaxIndex method but checks for index < 0
+ int computeMaxIndexWithCheck(int initial, int count, int[] indices) {
+ int maxIndex = 0;
+ for (int i = initial; i < (initial+count); i++) {
+ // Throw an exception, since index is negative
+ if (indices[i] < 0)
+ throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray27"));
+ if (indices[i] > maxIndex) {
+ maxIndex = indices[i];
+ }
+ }
+ return maxIndex;
+
+ }
+
void setValidIndexCount(int validIndexCount) {
if (validIndexCount < 0) {
throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray21"));
@@ -1608,6 +1643,11 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
if ((initialIndexIndex + validIndexCount) > indexCount) {
throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray22"));
}
+ if ((vertexFormat & GeometryArray.BY_REFERENCE_INDICES) != 0) {
+ if (indexCoord != null && indexCoord.length < initialIndexIndex + validIndexCount) {
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray33"));
+ }
+ }
int newCoordMax =0;
int newColorIndex=0;
int newNormalIndex=0;
@@ -1688,12 +1728,18 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
if ((initialIndexIndex + validIndexCount) > indexCount) {
throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray22"));
}
+ if ((vertexFormat & GeometryArray.BY_REFERENCE_INDICES) != 0) {
+ if (indexCoord != null && indexCoord.length < initialIndexIndex + validIndexCount) {
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray33"));
+ }
+ }
+
int newCoordMax =0;
int newColorIndex=0;
int newNormalIndex=0;
int[] newTexCoordIndex = null;
int[] newVertexAttrIndex = null;
-
+
newCoordMax = computeMaxIndex(initialIndexIndex, validIndexCount, indexCoord);
doErrorCheck(newCoordMax);
if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
diff --git a/src/classes/share/javax/media/j3d/InputDeviceBlockingThread.java b/src/classes/share/javax/media/j3d/InputDeviceBlockingThread.java
index f0fdd26..b96e824 100644
--- a/src/classes/share/javax/media/j3d/InputDeviceBlockingThread.java
+++ b/src/classes/share/javax/media/j3d/InputDeviceBlockingThread.java
@@ -21,9 +21,10 @@ class InputDeviceBlockingThread extends Thread {
// blocking device that this thread manages
private InputDevice device;
- private boolean running = true;
- private boolean waiting = false;
+ private volatile boolean running = true;
private volatile boolean stop = false;
+ private boolean waiting = false;
+ private boolean ready = false;
private static int numInstances = 0;
private int instanceNum = -1;
@@ -69,30 +70,35 @@ class InputDeviceBlockingThread extends Thread {
}
void finish() {
- stop = true;
- while (!waiting) {
- MasterControl.threadYield();
- }
-
- runMonitor(STOP);
+ stop = true;
+ runMonitor(STOP);
}
synchronized void runMonitor(int action) {
switch (action) {
case WAIT:
- try {
- waiting = true;
- wait();
- } catch (InterruptedException e) {}
- waiting = false;
+ // Issue 279 - loop until ready
+ while (running && !ready) {
+ waiting = true;
+ try {
+ wait();
+ } catch (InterruptedException e) {}
+ waiting = false;
+ }
+ ready = false;
break;
case NOTIFY:
- notify();
+ ready = true;
+ if (waiting) {
+ notify();
+ }
break;
case STOP:
running = false;
- notify();
+ if (waiting) {
+ notify();
+ }
break;
}
}
diff --git a/src/classes/share/javax/media/j3d/J3DBuffer.java b/src/classes/share/javax/media/j3d/J3DBuffer.java
index 7cd5bf9..27f70ed 100644
--- a/src/classes/share/javax/media/j3d/J3DBuffer.java
+++ b/src/classes/share/javax/media/j3d/J3DBuffer.java
@@ -207,13 +207,8 @@ public class J3DBuffer {
return bufferImpl;
}
- // Native method to verify that we can access a direct NIO buffer
- // from native code
- private native static long getNativeAddress(java.nio.Buffer buffer);
-
private static boolean checkNativeBufferAccess(java.nio.Buffer buffer) {
- // TODO: uncomment out the call to getNativeAddress and implement it
- if (buffer == null /*|| getNativeAddress(buffer) == 0L*/) {
+ if (buffer == null /*|| !Pipeline.getPipeline().checkNativeBufferAccess(buffer)*/) {
return false;
}
else {
diff --git a/src/classes/share/javax/media/j3d/J3DGraphics2DImpl.java b/src/classes/share/javax/media/j3d/J3DGraphics2DImpl.java
index d52381c..7521434 100644
--- a/src/classes/share/javax/media/j3d/J3DGraphics2DImpl.java
+++ b/src/classes/share/javax/media/j3d/J3DGraphics2DImpl.java
@@ -28,6 +28,7 @@ import java.awt.font.*;
*/
final class J3DGraphics2DImpl extends J3DGraphics2D {
+ private boolean hasBeenDisposed = false;
private Graphics2D offScreenGraphics2D;
private BufferedImage g3dImage = null;
private byte[] data = null;
@@ -45,9 +46,8 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
private Point2D.Float ptDst2 = new Point2D.Float();
private Color xOrModeColor = null;
private volatile boolean initCtx = false;
- private boolean threadWaiting = false;
+ private volatile boolean threadWaiting = false;
static final Color blackTransparent = new Color(0,0,0,0);
- private boolean useDrawPixel = VirtualUniverse.mc.isJ3dG2dDrawPixel;
int objectId = -1;
// Package scope contructor
@@ -55,7 +55,7 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
canvas3d = c;
synchronized (VirtualUniverse.mc.contextCreationLock) {
- if (c.ctx == 0) {
+ if (c.ctx == null) {
// create a dummy bufferImage
width = 1;
height = 1;
@@ -117,6 +117,10 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
* rendering to be complete before returning from this call.
*/
public void flush(boolean waiting) {
+
+ if (hasBeenDisposed) {
+ throw new IllegalStateException(J3dI18N.getString("J3DGraphics2D0"));
+ }
if (!isFlushed) {
// Composite g3dImage into Canvas3D
@@ -162,8 +166,10 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
// copy the data into a byte buffer that will be passed to opengl
void doFlush() {
+ assert !hasBeenDisposed;
+
// clip to offscreen buffer size
- if (canvas3d.ctx == 0) {
+ if (canvas3d.ctx == null) {
canvas3d.getGraphicsContext3D().doClear();
}
@@ -208,7 +214,10 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
final void copyImage(BufferedImage bi, byte[] image,
int width, int height,
int x1, int y1, int x2, int y2) {
- int biType = bi.getType();
+
+ assert !hasBeenDisposed;
+
+ int biType = bi.getType();
int w, h, i, j;
int row, rowBegin, rowInc, dstBegin;
@@ -286,7 +295,7 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
void sendRenderMessage(boolean renderRun, int command,
Object arg1, Object arg2, Object arg3) {
// send a message to the request renderer
- J3dMessage renderMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage renderMessage = new J3dMessage();
renderMessage.threads = J3dThread.RENDER_THREAD;
renderMessage.type = J3dMessage.RENDER_IMMEDIATE;
renderMessage.universe = null;
@@ -575,10 +584,6 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
offScreenGraphics2D.copyArea(x, y, width, height, dx, dy);
}
- public final void dispose() {
- offScreenGraphics2D.dispose();
- }
-
public final void draw(Shape s) {
Rectangle rect = s.getBounds();
validate(rect.x, rect.y,
@@ -867,17 +872,52 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
offScreenGraphics2D.fillRect(x, y, width, height);
}
- public void finalize() {
- if (objectId >= 0) {
- VirtualUniverse.mc.freeTexture2DId(objectId);
- }
- offScreenGraphics2D.finalize();
+ // Issue 121 - release all resources, mark as disposed
+ public void dispose() {
+
+ if (Thread.currentThread() == canvas3d.screen.renderer) {
+ doDispose();
+ } else {
+ // Behavior Scheduler or other threads
+ // XXXX: may not be legal for behaviorScheduler
+ // May cause deadlock if it is in behaviorScheduler
+ // and we wait for Renderer to finish
+ boolean renderRun = (Thread.currentThread() !=
+ canvas3d.view.universe.behaviorScheduler);
+ sendRenderMessage(renderRun, GraphicsContext3D.DISPOSE2D,
+ null, null, null);
+ }
+
+
+ }
+
+ public void doDispose() {
+
+ if (hasBeenDisposed) {
+ return;
+ }
+
+ if (objectId != -1) {
+ canvas3d.freeTexture(canvas3d.ctx, objectId);
+ VirtualUniverse.mc.freeTexture2DId(objectId);
+ objectId = -1;
+ }
+
+ // Dispose of the underlying Graphics2D
+ offScreenGraphics2D.dispose();
+
+ // Mark as disposed
+ hasBeenDisposed = true;
}
public void drawAndFlushImage(BufferedImage img, int x, int y,
ImageObserver observer) {
- if (!(initCtx && abgr &&
+ if (hasBeenDisposed) {
+ throw new IllegalStateException(J3dI18N.getString("J3DGraphics2D0"));
+ }
+
+ if (!(initCtx && abgr &&
(img.getType() == BufferedImage.TYPE_4BYTE_ABGR))) {
drawImage(img, x, y, observer);
flush(false);
@@ -900,11 +940,14 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
void doDrawAndFlushImage(BufferedImage img, int x, int y,
ImageObserver observer) {
- int imgWidth = img.getWidth(observer);
+
+ assert !hasBeenDisposed;
+
+ int imgWidth = img.getWidth(observer);
int imgHeight = img.getHeight(observer);
int px, py, x1, y1, x2, y2;
- if (canvas3d.ctx == 0) {
+ if (canvas3d.ctx == null) {
canvas3d.getGraphicsContext3D().doClear();
}
@@ -961,50 +1004,41 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
try {
if (!canvas3d.drawingSurfaceObject.renderLock()) {
return;
- }
+ }
+
+ if (!initTexMap) {
+ if (objectId == -1) {
+ objectId = VirtualUniverse.mc.getTexture2DId();
+ }
+ texWidth = getGreaterPowerOf2(w);
+ texHeight = getGreaterPowerOf2(h);
+
+ // Canvas got resize, need to init texture map again
+ // in Renderer thread
+ if (!canvas3d.initTexturemapping(canvas3d.ctx,
+ texWidth, texHeight,
+ objectId)) {
+ // Fail to get the texture surface, most likely
+ // there is not enough texture memory
+ initTexMap = false;
+ VirtualUniverse.mc.freeTexture2DId(objectId);
+ objectId = -1;
+ // TODO : Need to find a better way to report no resource problem --- Chien.
+ System.err.println("J3DGraphics2DImpl.copyDataToCanvas() : Fail to get texture resources ...");
+
+ } else {
+ initTexMap = true;
+ }
+ }
+ if (initTexMap) {
+ canvas3d.texturemapping(canvas3d.ctx, px, py,
+ x1, y1, x2, y2,
+ texWidth, texHeight, w,
+ (abgr ? ImageComponentRetained.TYPE_BYTE_ABGR:
+ ImageComponentRetained.TYPE_BYTE_RGBA),
+ objectId, data, width, height);
+ }
- if (useDrawPixel) {
- canvas3d.composite(canvas3d.ctx, px, py,
- x1, y1, x2, y2, w, data, width, height);
- } else {
- if (!initTexMap) {
- if (objectId == -1) {
- objectId = VirtualUniverse.mc.getTexture2DId();
- }
- texWidth = getGreaterPowerOf2(w);
- texHeight = getGreaterPowerOf2(h);
-
- // Canvas got resize, need to init texture map again
- // in Renderer thread
- if (!canvas3d.initTexturemapping(canvas3d.ctx,
- texWidth, texHeight,
- objectId)) {
- // Fail to get the texture surface, most likely
- // there is not enough texture memory
- initTexMap = false;
- VirtualUniverse.mc.freeTexture2DId(objectId);
- objectId = -1;
- // Use DrawPixel next time
- useDrawPixel = true;
- } else {
- initTexMap = true;
- }
- }
- if (initTexMap) {
- canvas3d.texturemapping(canvas3d.ctx, px, py,
- x1, y1, x2, y2,
- texWidth, texHeight, w,
- (abgr ? ImageComponentRetained.BYTE_ABGR:
- ImageComponentRetained.BYTE_RGBA),
- objectId, data, width, height);
- } else {
- // Fall back to composite for this round
- canvas3d.composite(canvas3d.ctx, px, py,
- x1, y1, x2, y2, w, data,
- width, height);
-
- }
- }
canvas3d.drawingSurfaceObject.unLock();
} catch (NullPointerException ne) {
canvas3d.drawingSurfaceObject.unLock();
@@ -1043,7 +1077,8 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
*/
synchronized void runMonitor(int action) {
if (action == J3dThread.WAIT) {
- if (threadWaiting) {
+ // Issue 279 - loop until ready
+ while (threadWaiting) {
try {
wait();
} catch (InterruptedException e){}
diff --git a/src/classes/share/javax/media/j3d/J3dClock.java b/src/classes/share/javax/media/j3d/J3dClock.java
index 307f988..438b945 100644
--- a/src/classes/share/javax/media/j3d/J3dClock.java
+++ b/src/classes/share/javax/media/j3d/J3dClock.java
@@ -28,16 +28,6 @@ class J3dClock {
}
/**
- * Method to return a high-resolution timer value.
- *
- * NOTE: when we no longer support JDK 1.4.2 we can replace this
- * method with System.nanoTime().
- */
- private static long getHiResTimerValue() {
- return MasterControl.getNativeTimerValue();
- }
-
- /**
* Returns the current time in milliseconds. This is a more
* accurate version of System.currentTimeMillis and should be used in
* its place.
@@ -45,19 +35,15 @@ class J3dClock {
* @return the current time in milliseconds.
*/
static long currentTimeMillis() {
- return (getHiResTimerValue() / nsecPerMsec) + deltaTime;
+ return (System.nanoTime() / nsecPerMsec) + deltaTime;
}
static {
- // Ensure that the native libraries are loaded (this can be removed
- // once we switch to using System.nanoTime()
- VirtualUniverse.loadLibraries();
-
// Call time methods once without using their values to ensure that
// the methods are "warmed up". We need to make sure that the actual
// calls that we use take place as close together as possible in time.
System.currentTimeMillis();
- getHiResTimerValue();
+ System.nanoTime();
// Compute deltaTime between System.currentTimeMillis()
// and the high-res timer, use a synchronized block to force both calls
@@ -65,7 +51,7 @@ class J3dClock {
long baseTime, baseTimerValue;
synchronized (J3dClock.class) {
baseTime = System.currentTimeMillis();
- baseTimerValue = getHiResTimerValue();
+ baseTimerValue = System.nanoTime();
}
deltaTime = baseTime - (baseTimerValue / nsecPerMsec);
}
diff --git a/src/classes/share/javax/media/j3d/J3dMessage.java b/src/classes/share/javax/media/j3d/J3dMessage.java
index 41fa2bc..0838c54 100644
--- a/src/classes/share/javax/media/j3d/J3dMessage.java
+++ b/src/classes/share/javax/media/j3d/J3dMessage.java
@@ -160,8 +160,7 @@ class J3dMessage extends Object {
final synchronized void decRefcount() {
if (--refcount == 0) {
clear();
- FreeListManager.freeObject(FreeListManager.MESSAGE, this);
- }
+ }
}
final synchronized int getRefcount() {
diff --git a/src/classes/share/javax/media/j3d/J3dNotification.java b/src/classes/share/javax/media/j3d/J3dNotification.java
index 807cadf..34ba699 100644
--- a/src/classes/share/javax/media/j3d/J3dNotification.java
+++ b/src/classes/share/javax/media/j3d/J3dNotification.java
@@ -22,6 +22,7 @@ class J3dNotification extends Object {
*/
static final int INVALID_TYPE = -1;
static final int SHADER_ERROR = 0;
+ static final int RENDERING_ERROR = 1;
/**
* This holds the type of this message
@@ -39,4 +40,5 @@ class J3dNotification extends Object {
static final int MAX_ARGS = 6;
Object[] args = new Object[MAX_ARGS];
+
}
diff --git a/src/classes/share/javax/media/j3d/J3dThread.java b/src/classes/share/javax/media/j3d/J3dThread.java
index c585d62..a650ded 100644
--- a/src/classes/share/javax/media/j3d/J3dThread.java
+++ b/src/classes/share/javax/media/j3d/J3dThread.java
@@ -76,7 +76,13 @@ abstract class J3dThread extends Thread {
/**
* This indicates that this thread is alive and running
*/
- private boolean running = true;
+ private volatile boolean running = true;
+
+ /**
+ * This flag is set by the RUN action of runMonitor to indicate that the
+ * waiting thread has work to do.
+ */
+ private volatile boolean ready = false;
/**
* The thread data for this thread
@@ -84,7 +90,7 @@ abstract class J3dThread extends Thread {
private J3dThreadData[] data = null;
/**
- * This indicates that this thread is ready
+ * This indicates that this thread is started and able to accept work
*/
private volatile boolean started = false;
@@ -121,7 +127,7 @@ abstract class J3dThread extends Thread {
/**
* Flag to indicate that this thread is waiting to be notify
*/
- volatile boolean waiting = false;
+ private volatile boolean waiting = false;
/**
* Some variables used to name threads correctly
@@ -220,7 +226,7 @@ abstract class J3dThread extends Thread {
/**
* This initializes this thread. Once this method returns, the thread is
- * ready to do work.
+ * able to accept work.
*/
void initialize() {
this.start();
@@ -233,11 +239,11 @@ abstract class J3dThread extends Thread {
* This causes the threads run method to exit.
*/
void finish() {
+ // NOTE: This spin loop is probably not necessary.
while (!waiting) {
MasterControl.threadYield();
}
runMonitor(STOP, 0,null);
-
}
/**
@@ -257,36 +263,52 @@ abstract class J3dThread extends Thread {
synchronized void runMonitor(int action, long referenceTime,
Object[] args) {
switch (action) {
- case WAIT:
- try {
- started = true;
- waiting = true;
- wait();
- } catch (InterruptedException e) {
- System.err.println(e);
+ case WAIT:
+ started = true;
+ // Issue 279 - loop until ready
+ while (!ready && running) {
+ waiting = true;
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ System.err.println(e);
+ }
+ waiting = false;
}
- waiting = false;
+ ready = false;
break;
- case NOTIFY_AND_WAIT:
+
+ case NOTIFY_AND_WAIT:
VirtualUniverse.mc.runMonitor(MasterControl.THREAD_DONE, null,
- null, null, this);
- try {
- waiting = true;
- wait();
- } catch (InterruptedException e) {
- System.err.println(e);
+ null, null, this);
+ // Issue 279 - loop until ready
+ while (!ready && running) {
+ waiting = true;
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ System.err.println(e);
+ }
+ waiting = false;
}
- waiting = false;
+ ready = false;
break;
- case RUN:
- this.referenceTime = referenceTime;
- this.args = args;
- notify();
+
+ case RUN:
+ this.referenceTime = referenceTime;
+ this.args = args;
+ ready = true;
+ if (waiting) {
+ notify();
+ }
+ break;
+
+ case STOP:
+ running = false;
+ if (waiting) {
+ notify();
+ }
break;
- case STOP:
- running = false;
- notify();
- break;
}
}
@@ -303,6 +325,7 @@ abstract class J3dThread extends Thread {
void cleanup() {
active = false;
running = true;
+ ready = false;
data = null;
started = true;
lastWaitTimestamp = 0;
diff --git a/src/classes/share/javax/media/j3d/LightBin.java b/src/classes/share/javax/media/j3d/LightBin.java
index a92e638..51d4aab 100644
--- a/src/classes/share/javax/media/j3d/LightBin.java
+++ b/src/classes/share/javax/media/j3d/LightBin.java
@@ -338,8 +338,7 @@ class LightBin extends Object implements ObjectUpdate {
}
e.prev = null;
e.next = null;
- renderBin.envSetFreelist.add(e);
-
+
if (environmentSetList == null && insertEnvSet.size() == 0) {
renderBin.removeLightBin(this);
geometryBackground = null;
diff --git a/src/classes/share/javax/media/j3d/LightRetained.java b/src/classes/share/javax/media/j3d/LightRetained.java
index 9126311..e4b7766 100644
--- a/src/classes/share/javax/media/j3d/LightRetained.java
+++ b/src/classes/share/javax/media/j3d/LightRetained.java
@@ -209,7 +209,7 @@ abstract class LightRetained extends LeafRetained {
initScope(scope, index);
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
scopeInfo[0] = addScopeList;
scopeInfo[1] = removeScopeList;
scopeInfo[2] = (scopes.size() > 0 ? Boolean.TRUE: Boolean.FALSE);
@@ -560,7 +560,7 @@ abstract class LightRetained extends LeafRetained {
* This method is implemented by each light for rendering
* context updates. This default one does nothing.
*/
- abstract void update(long ctx, int lightSlot, double scale);
+ abstract void update(Context ctx, int lightSlot, double scale);
// This routine is called when rendering Env structure
@@ -847,7 +847,7 @@ abstract class LightRetained extends LeafRetained {
}
J3dMessage initMessage(int num) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.LIGHT_CHANGED;
@@ -952,7 +952,7 @@ abstract class LightRetained extends LeafRetained {
if (scopes.size() > 0) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
LightRetained[] mlts = new LightRetained[newlyAddedMirrorLights.size()];
for (int i = 0; i < mlts.length; i++) {
mlts[i] = (LightRetained)newlyAddedMirrorLights.get(i);
@@ -1036,7 +1036,7 @@ abstract class LightRetained extends LeafRetained {
}
void sendMessage(int attrMask, Object attr) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.LIGHT_CHANGED;
createMessage.universe = universe;
diff --git a/src/classes/share/javax/media/j3d/LineAttributesRetained.java b/src/classes/share/javax/media/j3d/LineAttributesRetained.java
index a82228a..5765db9 100644
--- a/src/classes/share/javax/media/j3d/LineAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/LineAttributesRetained.java
@@ -215,21 +215,12 @@ class LineAttributesRetained extends NodeComponentRetained {
/**
- * This (native) method updates the native context.
- */
- native void updateNative(long ctx,
- float lineWidth, int linePattern,
- int linePatternMask,
- int linePatternScaleFactor,
- boolean lineAntialiasing);
-
- /**
* This method updates the native context.
*/
- void updateNative(long ctx) {
- updateNative(ctx,
- lineWidth, linePattern, linePatternMask,
- linePatternScaleFactor, lineAntialiasing);
+ void updateNative(Context ctx) {
+ Pipeline.getPipeline().updateLineAttributes(ctx,
+ lineWidth, linePattern, linePatternMask,
+ linePatternScaleFactor, lineAntialiasing);
}
@@ -292,7 +283,7 @@ class LineAttributesRetained extends NodeComponentRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.LINEATTRIBUTES_CHANGED;
createMessage.universe = null;
@@ -305,7 +296,7 @@ class LineAttributesRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.LINEATTRIBUTES_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/LinearFogRetained.java b/src/classes/share/javax/media/j3d/LinearFogRetained.java
index ef03698..fbb4270 100644
--- a/src/classes/share/javax/media/j3d/LinearFogRetained.java
+++ b/src/classes/share/javax/media/j3d/LinearFogRetained.java
@@ -49,7 +49,7 @@ class LinearFogRetained extends FogRetained {
*/
void setFrontDistance(double frontDistance){
this.frontDistance = frontDistance;
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.FOG_CHANGED;
createMessage.universe = universe;
@@ -78,7 +78,7 @@ class LinearFogRetained extends FogRetained {
*/
void setBackDistance(double backDistance){
this.backDistance = backDistance;
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.FOG_CHANGED;
createMessage.universe = universe;
@@ -98,12 +98,10 @@ class LinearFogRetained extends FogRetained {
* This method and its native counterpart update the native context
* fog values.
*/
- native void update(long ctx, float red, float green, float blue,
- double fdist, double bdist);
-
- void update(long ctx, double scale) {
+ void update(Context ctx, double scale) {
validateDistancesInEc(scale);
- update(ctx, color.x, color.y, color.z, frontDistanceInEc, backDistanceInEc);
+ Pipeline.getPipeline().updateLinearFog(ctx,
+ color.x, color.y, color.z, frontDistanceInEc, backDistanceInEc);
}
@@ -115,7 +113,7 @@ class LinearFogRetained extends FogRetained {
// Initialize the mirror object, this needs to be done, when
// renderBin is not accessing any of the fields
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.FOG_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/Locale.java b/src/classes/share/javax/media/j3d/Locale.java
index 0be5f36..92f9a3b 100644
--- a/src/classes/share/javax/media/j3d/Locale.java
+++ b/src/classes/share/javax/media/j3d/Locale.java
@@ -210,7 +210,7 @@ public class Locale extends Object {
bgr.setLive(s);
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER| J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.type = J3dMessage.ORDERED_GROUP_INSERTED;
createMessage.universe = universe;
@@ -222,7 +222,7 @@ public class Locale extends Object {
VirtualUniverse.mc.processMessage(createMessage);
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.type = J3dMessage.VIEWSPECIFICGROUP_INIT;
createMessage.universe = universe;
@@ -232,7 +232,7 @@ public class Locale extends Object {
VirtualUniverse.mc.processMessage(createMessage);
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = s.notifyThreads;
createMessage.type = J3dMessage.INSERT_NODES;
createMessage.universe = universe;
@@ -252,7 +252,7 @@ public class Locale extends Object {
b.executeInitialize();
}
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_BEHAVIOR;
createMessage.type = J3dMessage.BEHAVIOR_ACTIVATE;
createMessage.universe = universe;
@@ -334,7 +334,7 @@ public class Locale extends Object {
bgr.setLocale(null);
if (messages == null) {
- destroyMessage = VirtualUniverse.mc.getMessage();
+ destroyMessage = new J3dMessage();
} else {
destroyMessage = messages[startIndex++];
}
@@ -348,7 +348,7 @@ public class Locale extends Object {
if (messages == null) {
VirtualUniverse.mc.processMessage(destroyMessage);
- destroyMessage = VirtualUniverse.mc.getMessage();
+ destroyMessage = new J3dMessage();
} else {
destroyMessage = messages[startIndex++];
}
@@ -360,7 +360,7 @@ public class Locale extends Object {
if (messages == null) {
VirtualUniverse.mc.processMessage(destroyMessage);
- destroyMessage = VirtualUniverse.mc.getMessage();
+ destroyMessage = new J3dMessage();
} else {
destroyMessage = messages[startIndex++];
}
@@ -439,7 +439,7 @@ public class Locale extends Object {
universe.setLiveState.reset(this);
obgr.clearLive(universe.setLiveState);
- destroyMessage = VirtualUniverse.mc.getMessage();
+ destroyMessage = new J3dMessage();
destroyMessage.threads = J3dThread.UPDATE_RENDER| J3dThread.UPDATE_RENDERING_ENVIRONMENT;
destroyMessage.type = J3dMessage.ORDERED_GROUP_REMOVED;
@@ -450,7 +450,7 @@ public class Locale extends Object {
destroyMessage.args[4] = universe.setLiveState.ogCIOTableList.toArray();
VirtualUniverse.mc.processMessage(destroyMessage);
- destroyMessage = VirtualUniverse.mc.getMessage();
+ destroyMessage = new J3dMessage();
destroyMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
destroyMessage.type = J3dMessage.VIEWSPECIFICGROUP_CLEAR;
destroyMessage.universe = universe;
@@ -459,7 +459,7 @@ public class Locale extends Object {
VirtualUniverse.mc.processMessage(destroyMessage);
- destroyMessage = VirtualUniverse.mc.getMessage();
+ destroyMessage = new J3dMessage();
destroyMessage.threads = universe.setLiveState.notifyThreads;
destroyMessage.type = J3dMessage.REMOVE_NODES;
destroyMessage.universe = universe;
@@ -493,7 +493,7 @@ public class Locale extends Object {
nbgr.setLive(universe.setLiveState);
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER| J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.type = J3dMessage.ORDERED_GROUP_INSERTED;
createMessage.universe = universe;
@@ -505,7 +505,7 @@ public class Locale extends Object {
VirtualUniverse.mc.processMessage(createMessage);
// XXXX: make these two into one message
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = universe.setLiveState.notifyThreads;
createMessage.type = J3dMessage.INSERT_NODES;
createMessage.universe = universe;
@@ -529,7 +529,7 @@ public class Locale extends Object {
((BehaviorRetained) behaviorNodes[i]).executeInitialize();
}
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_BEHAVIOR;
createMessage.type = J3dMessage.BEHAVIOR_ACTIVATE;
createMessage.universe = universe;
@@ -1068,14 +1068,4 @@ public class Locale extends Object {
}
- /**
- * Cleans up resources associated with this Locale
- */
- protected void finalize() {
- // free nodeId
- if (universe != null && nodeId != null) {
- universe.nodeIdFreeList.addElement(nodeId);
- nodeId = null;
- }
- }
}
diff --git a/src/classes/share/javax/media/j3d/MasterControl.java b/src/classes/share/javax/media/j3d/MasterControl.java
index ddb311f..655e9f6 100644
--- a/src/classes/share/javax/media/j3d/MasterControl.java
+++ b/src/classes/share/javax/media/j3d/MasterControl.java
@@ -20,8 +20,6 @@ package javax.media.j3d;
import java.util.*;
import java.awt.*;
-import java.io.File;
-
class MasterControl {
@@ -32,25 +30,16 @@ class MasterControl {
static final int SET_WORK = 1;
static final int RUN_THREADS = 2;
static final int THREAD_DONE = 3;
- static final int WAIT_FOR_ALL = 4;
static final int SET_WORK_FOR_REQUEST_RENDERER = 5;
static final int RUN_RENDERER_CLEANUP = 6;
- static final int SLEEP = 7;
// The thread states for MC
static final int SLEEPING = 0;
static final int RUNNING = 1;
- static final int WAITING_FOR_THREAD = 2;
static final int WAITING_FOR_THREADS = 3;
static final int WAITING_FOR_CPU = 4;
static final int WAITING_FOR_RENDERER_CLEANUP = 5;
- // The Rendering API's that we currently know about
- static final int RENDER_OPENGL_SOLARIS = 0;
- static final int RENDER_OPENGL_WIN32 = 1;
- static final int RENDER_DIRECT3D = 2;
- static final int RENDER_OPENGL_LINUX = 3;
-
// Constants used in renderer thread argument
static final Integer REQUESTRENDER = new Integer(Renderer.REQUESTRENDER);
static final Integer RENDER = new Integer(Renderer.RENDER);
@@ -127,12 +116,6 @@ class MasterControl {
*/
private int numActiveViews = 0;
- // A freelist for ImageComponentUpdateInfo
- private ImageComponentUpdateInfo[] imageUpdateInfoList =
- new ImageComponentUpdateInfo[2];
- private int numFreeImageUpdateInfo = 0;
-
-
/**
* The list of active universes get from View
*/
@@ -295,15 +278,11 @@ class MasterControl {
*/
static long systemStartTime = 0L;
- // The rendering API we are using
- private int renderingAPI = RENDER_OPENGL_SOLARIS;
- static boolean isD3DAPI = false;
-
- // Are we on a Win32 system
- static boolean isWin32 = false;
-
- // The class that describes the low level rendering code
- private NativeAPIInfo nativeAPIInfo = null;
+ // Flag indicating that we are on a Windows OS
+ private static boolean isWindowsOs = false;
+
+ // Flag indicating we are on MacOS
+ private static boolean isMacOs = false;
// This is a counter for texture id's, valid id starts from 1
private int textureIdCount = 0;
@@ -322,14 +301,6 @@ class MasterControl {
// This is a counter for rendererBit
private int rendererCount = 0;
- /*
- // Flag that indicates whether the JVM is version JDK1.5 or later.
- // If so, then the jvm15OrBetter flag is set to true, indicating that
- // 1.5 functionality can be used.
- // We don't use any JDK 1.5 features yet, so this is a placeholder.
- static boolean jvm15OrBetter = false;
- */
-
// Flag that indicates whether to shared display context or not
boolean isSharedCtx = false;
@@ -356,6 +327,16 @@ class MasterControl {
// be in display list.
boolean vertexAttrsInDisplayList = false;
+ // Issue 249 - flag that indicates whether the soleUser optimization is permitted
+ boolean allowSoleUser = false;
+
+ // Issue 266 - Flag indicating whether null graphics configs are allowed
+ // Set by -Dj3d.allowNullGraphicsConfig property
+ // Setting this flag causes Canvas3D to allow a null GraphicsConfiguration
+ // for on-screen canvases. This is only for backward compatibility with
+ // legacy applications.
+ boolean allowNullGraphicsConfig = false;
+
// The global shading language being used. Using a ShaderProgram
// with a shading language other than the one specified by
// globalShadingLanguage will cause a ShaderError to be generated,
@@ -368,7 +349,7 @@ class MasterControl {
static boolean cgLibraryAvailable = false;
static boolean glslLibraryAvailable = false;
-
+
// REQUESTCLEANUP messages argument
static Integer REMOVEALLCTXS_CLEANUP = new Integer(1);
static Integer REMOVECTX_CLEANUP = new Integer(2);
@@ -388,20 +369,17 @@ class MasterControl {
// Flag that indicates whether to lock the DSI while rendering
boolean doDsiRenderLock = false;
-
- // Flag that indicates whether J3DGraphics2D uses texturemapping
- // instead of drawpixel for composite the buffers
- boolean isJ3dG2dDrawPixel = false;
-
- // flag that indicates whether BackgroundRetained uses texturemapping
- // or drawpixel clear the background
- boolean isBackgroundTexture = true;
+
+ // Flag that indicates the pre-1.5 behavior of enforcing power-of-two
+ // textures. If set, then any non-power-of-two textures will throw an
+ // exception.
+ boolean enforcePowerOfTwo = false;
// Flag that indicates whether the framebuffer is sharing the
// Z-buffer with both the left and right eyes when in stereo mode.
// If this is true, we need to clear the Z-buffer between rendering
// to the left and right eyes.
- boolean sharedStereoZBuffer;
+ boolean sharedStereoZBuffer = true;
// True to disable all underlying multisampling API so it uses
// the setting in the driver.
@@ -410,11 +388,11 @@ class MasterControl {
// False to disable compiled vertex array extensions if support
boolean isCompiledVertexArray = true;
- // False to disable rescale normal if OGL support
- boolean isForceNormalized = false;
-
- // True to allow simulated (multi-pass) multi-texture
- boolean allowSimulatedMultiTexture = false;
+ // Number of reserved vertex attribute locations for GLSL (must be at
+ // least 1).
+ // Issue 269 - need to reserve up to 6 vertex attribtue locations to ensure
+ // that we don't collide with a predefined gl_* attribute on nVidia cards.
+ int glslVertexAttrOffset = 6;
// Hashtable that maps a GraphicsDevice to its associated
// Screen3D--this is only used for on-screen Canvas3Ds
@@ -435,7 +413,7 @@ class MasterControl {
// Root ThreadGroup for creating Java 3D threads
private static ThreadGroup rootThreadGroup;
- // Thread priority for all Java3D threads
+ // Thread priority for all Java 3D threads
private static int threadPriority;
static private Object mcThreadLock = new Object();
@@ -443,40 +421,11 @@ class MasterControl {
private ArrayList timestampUpdateList = new ArrayList(3);
private UnorderList freeMessageList = new UnorderList(8);
-
- // System properties containing the native library search PATH
- // The order listed is the order in which they will be searched
- private static final String[] systemPathProps = {
- "sun.boot.library.path",
- "java.library.path"
- };
+ // Native AWT object
long awt;
- private native long getAWT();
-
- // Method to initialize the native J3D library
- private native boolean initializeJ3D(boolean disableXinerama);
- // Method to verify whether the native Cg library is available
- private static native boolean loadNativeCgLibrary(String[] libpath);
-
- // Method to get number of procesor
- private native int getNumberOfProcessor();
-
- // Methods to set/get system thread concurrency
- private native void setThreadConcurrency(int newLevel);
- private native int getThreadConcurrency();
-
- // Native method to get the high-resolution timer value.
- // This method is only called by the J3dClock.getHiResTimerValue.
- // It is defined as a MasterControl method for convenience, so we don't
- // have to have yet another class with native methods.
- //
- // NOTE: once we drop support for JDK 1.4.2, this method will go away.
- static native long getNativeTimerValue();
-
- // Maximum lights supported by the native API
- private native int getMaximumLights();
+ // Maximum number of lights
int maxLights;
// This is used for D3D only
@@ -509,15 +458,9 @@ class MasterControl {
*/
MasterControl() {
assert librariesLoaded;
-
- // Get AWT handle
- awt = getAWT();
- // Get native API information
- nativeAPIInfo = new NativeAPIInfo();
- renderingAPI = nativeAPIInfo.getRenderingAPI();
- isD3DAPI = (renderingAPI == RENDER_DIRECT3D);
- isWin32 = isD3DAPI || (renderingAPI == RENDER_OPENGL_WIN32);
+ // Get AWT handle
+ awt = Pipeline.getPipeline().getAWT();
// Initialize the start time upon which alpha's and behaviors
// are synchronized to (if it isn't already set).
@@ -532,7 +475,7 @@ class MasterControl {
}
// Check to see whether shared contexts are allowed
- if (getRenderingAPI() != RENDER_DIRECT3D) {
+ if (!isD3D()) {
isSharedCtx =
getBooleanProperty("j3d.sharedctx", isSharedCtx, "shared contexts");
}
@@ -586,23 +529,6 @@ class MasterControl {
isCompiledVertexArray,
"compiled vertex array");
- isForceNormalized =
- getBooleanProperty("j3d.forceNormalized",
- isForceNormalized,
- "force normalized");
-
- allowSimulatedMultiTexture =
- getBooleanProperty("j3d.simulatedMultiTexture",
- allowSimulatedMultiTexture,
- "simulated multi-texture");
-
- if (allowSimulatedMultiTexture) {
- System.err.println("************************************************************************");
- System.err.println(J3dI18N.getString("MasterControl2"));
- System.err.println(J3dI18N.getString("MasterControl3"));
- System.err.println("************************************************************************");
- }
-
boolean j3dOptimizeSpace =
getBooleanProperty("j3d.optimizeForSpace", true,
"optimize for space");
@@ -625,36 +551,30 @@ class MasterControl {
doDsiRenderLock = getBooleanProperty("j3d.renderLock",
doDsiRenderLock,
"render lock");
+
+ // Check to see whether we enforce power-of-two textures
+ enforcePowerOfTwo = getBooleanProperty("j3d.textureEnforcePowerOfTwo",
+ enforcePowerOfTwo,
+ "checking power-of-two textures");
- // Check to see whether J3DGraphics2D uses texturemapping
- // or drawpixel to composite the buffers
- isJ3dG2dDrawPixel = getBooleanProperty("j3d.g2ddrawpixel",
- isJ3dG2dDrawPixel,
- "Graphics2D DrawPixel");
+ // Issue 249 - check to see whether the soleUser optimization is permitted
+ allowSoleUser = getBooleanProperty("j3d.allowSoleUser",
+ allowSoleUser,
+ "sole-user mode");
- // Check to see whether BackgroundRetained uses texturemapping
- // or drawpixel clear the background
- if (!isD3D()) {
- isBackgroundTexture =
- getBooleanProperty("j3d.backgroundtexture",
- isBackgroundTexture,
- "background texture");
- } else {
- // D3D always uses background texture and uses
- // canvas.clear() instead of canvas.textureclear() in Renderer
- isBackgroundTexture = false;
- }
+ // Issue 266 - check to see whether null graphics configs are allowed
+ allowNullGraphicsConfig = getBooleanProperty("j3d.allowNullGraphicsConfig",
+ allowNullGraphicsConfig,
+ "null graphics configs");
// Check to see if stereo mode is sharing the Z-buffer for both eyes.
- boolean defaultSharedStereoZBuffer =
- getRenderingAPI() != RENDER_OPENGL_SOLARIS;
sharedStereoZBuffer =
getBooleanProperty("j3d.sharedstereozbuffer",
- defaultSharedStereoZBuffer,
+ sharedStereoZBuffer,
"shared stereo Z buffer");
// Get the maximum number of concurrent threads (CPUs)
- final int defaultThreadLimit = getNumberOfProcessor()+1;
+ final int defaultThreadLimit = getNumberOfProcessors() + 1;
Integer threadLimit =
(Integer) java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
@@ -664,7 +584,6 @@ class MasterControl {
}
});
-
cpuLimit = threadLimit.intValue();
if (cpuLimit < 1)
cpuLimit = 1;
@@ -673,22 +592,6 @@ class MasterControl {
cpuLimit);
}
- // Ensure that there are at least enough system threads to
- // support all of Java 3D's threads running in parallel
- int threadConcurrency = getThreadConcurrency();
- if (J3dDebug.debug) {
- System.err.println("System threadConcurrency = " +
- threadConcurrency);
- }
- if (threadConcurrency != -1 && threadConcurrency < (cpuLimit + 1)) {
- threadConcurrency = cpuLimit + 1;
- if (J3dDebug.debug) {
- System.err.println("Setting system threadConcurrency to " +
- threadConcurrency);
- }
- setThreadConcurrency(threadConcurrency);
- }
-
// Get the input device scheduler sampling time
Integer samplingTime =
(Integer) java.security.AccessController.doPrivileged(
@@ -705,17 +608,34 @@ class MasterControl {
+ samplingTime + " ms");
}
- // See if Xinerama should be disabled for better performance.
+ // Get the glslVertexAttrOffset
+ final int defaultGLSLVertexAttrOffset = glslVertexAttrOffset;
+ Integer vattrOffset =
+ (Integer) java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction() {
+ public Object run() {
+ return Integer.getInteger("j3d.glslVertexAttrOffset",
+ defaultGLSLVertexAttrOffset);
+ }
+ });
+
+ glslVertexAttrOffset = vattrOffset.intValue();
+ if (glslVertexAttrOffset < 1) {
+ glslVertexAttrOffset = 1;
+ }
+ if (J3dDebug.debug || glslVertexAttrOffset != defaultGLSLVertexAttrOffset) {
+ System.err.println("Java 3D: glslVertexAttrOffset = " +
+ glslVertexAttrOffset);
+ }
+
+ // See if Xinerama should be disabled for better performance.
boolean disableXinerama = false;
if (getProperty("j3d.disableXinerama") != null) {
disableXinerama = true;
}
// Initialize the native J3D library
- if (!initializeJ3D(disableXinerama)) {
- if (isGreenThreadUsed()) {
- System.err.print(J3dI18N.getString("MasterControl1"));
- }
+ if (!Pipeline.getPipeline().initializeJ3D(disableXinerama)) {
throw new RuntimeException(J3dI18N.getString("MasterControl0"));
}
@@ -728,10 +648,24 @@ class MasterControl {
System.err.println("Java 3D: could not disable Xinerama");
}
+ // Check for obsolete properties
+ String[] obsoleteProps = {
+ "j3d.backgroundtexture",
+ "j3d.forceNormalized",
+ "j3d.g2ddrawpixel",
+ "j3d.simulatedMultiTexture",
+ "j3d.useFreeLists",
+ };
+ for (int i = 0; i < obsoleteProps.length; i++) {
+ if (getProperty(obsoleteProps[i]) != null) {
+ System.err.println(obsoleteProps[i] + " : property ignored");
+ }
+ }
+
// Get the maximum Lights
- maxLights = getMaximumLights();
+ maxLights = Pipeline.getPipeline().getMaximumLights();
- // create the freelists
+ // create the freelists
FreeListManager.createFreeLists();
// create an array canvas use registers
@@ -777,98 +711,87 @@ class MasterControl {
(msg + " disabled"));
}
- // Java 3D only supports native threads
- boolean isGreenThreadUsed() {
- return false;
- }
-
-
/**
- * Method to load the native libraries needed by Java 3D. This is
+ * Method to create and initialize the rendering Pipeline object,
+ * and to load the native libraries needed by Java 3D. This is
* called by the static initializer in VirtualUniverse <i>before</i>
* the MasterControl object is created.
*/
static void loadLibraries() {
assert !librariesLoaded;
- // This works around a native load library bug
- try {
- java.awt.Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit();
- toolkit = null; // just making sure GC collects this
- } catch (java.awt.AWTError e) {
- }
-
- // Load the JAWT native library
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction() {
- public Object run() {
- System.loadLibrary("jawt");
- return null;
- }
- });
-
- // Load the native J3D library
- final String oglLibraryName = "j3dcore-ogl";
- final String d3dLibraryName = "j3dcore-d3d";
- final String libraryName = (String)
- java.security.AccessController.doPrivileged(new
- java.security.PrivilegedAction() {
- public Object run() {
- String libName = oglLibraryName;
-
- // If it is a Windows OS, we want to support dynamic native library selection (ogl, d3d)
- String osName = System.getProperty("os.name");
- if (osName != null && osName.startsWith("Windows")) {
- // XXXX : Should eventually support a more flexible dynamic
- // selection scheme via an API call.
- String str = System.getProperty("j3d.rend");
- if (str != null && str.equals("d3d")) {
- libName = d3dLibraryName;
- }
- }
+ // Set global flags indicating whether we are running on Windows or MacOS
+ String osName = getProperty("os.name");
+ isWindowsOs = osName != null && osName.startsWith("Windows");
+ isMacOs = osName != null && osName.startsWith("Mac");
+
+//KCR: System.err.println("MasterControl.loadLibraries()");
+//KCR: System.err.println(" osName = \"" + osName + "\"" +
+//KCR: ", isWindowsOs = " + isWindowsOs +
+//KCR: ", isMacOs = " + isMacOs);
+
+ // Initialize the Pipeline object associated with the
+ // renderer specified by the "j3d.rend" system property.
+ //
+ // XXXX : We should consider adding support for a more flexible,
+ // dynamic selection scheme via an API call.
+
+ // Default rendering pipeline is the JOGL pipeline on MacOS and the
+ // native OpenGL pipeline on all other platforms.
+ Pipeline.Type pipelineType =
+ isMacOs ? Pipeline.Type.JOGL : Pipeline.Type.NATIVE_OGL;
+
+ String rendStr = getProperty("j3d.rend");
+ if (rendStr == null) {
+ // Use default pipeline
+ } else if (rendStr.equals("ogl") && !isMacOs) {
+ pipelineType = Pipeline.Type.NATIVE_OGL;
+ } else if (rendStr.equals("d3d") && isWindowsOs) {
+ pipelineType = Pipeline.Type.NATIVE_D3D;
+ } else if (rendStr.equals("jogl")) {
+ pipelineType = Pipeline.Type.JOGL;
+ } else if (rendStr.equals("noop")) {
+ pipelineType = Pipeline.Type.NOOP;
+ } else {
+ System.err.println("Java 3D: Unrecognized renderer: " + rendStr);
+ // Use default pipeline
+ }
- System.loadLibrary(libName);
- return libName;
- }
- });
+//KCR: System.err.println(" using " + pipelineType + " pipeline");
+
+ // Construct the singleton Pipeline instance
+ Pipeline.createPipeline(pipelineType);
+
+ // Get the global j3d.shadingLanguage system property
+ final String slStr = getProperty("j3d.shadingLanguage");
+ if (slStr != null) {
+ boolean found = false;
+ if (slStr.equals("GLSL")) {
+ globalShadingLanguage = Shader.SHADING_LANGUAGE_GLSL;
+ found = true;
+ } else if (slStr.equals("Cg")) {
+ globalShadingLanguage = Shader.SHADING_LANGUAGE_CG;
+ found = true;
+ }
- // Get the global j3d.shadingLanguage property
- final String slStr = getProperty("j3d.shadingLanguage");
- if (slStr != null) {
- boolean found = false;
- if (slStr.equals("GLSL")) {
- globalShadingLanguage = Shader.SHADING_LANGUAGE_GLSL;
- found = true;
- }
- else if (slStr.equals("Cg")) {
- globalShadingLanguage = Shader.SHADING_LANGUAGE_CG;
- found = true;
- }
+ if (found) {
+ System.err.println("Java 3D: Setting global shading language to " + slStr);
+ } else {
+ System.err.println("Java 3D: Unrecognized shading language: " + slStr);
+ }
+ }
- if (found) {
- System.err.println("Java 3D: Setting global shading language to " + slStr);
- }
- else {
- System.err.println("Java 3D: Unrecognized shading language: " + slStr);
- }
- }
+ // Load all required libraries
+ Pipeline.getPipeline().loadLibraries(globalShadingLanguage);
// Check whether the Cg library is available
if (globalShadingLanguage == Shader.SHADING_LANGUAGE_CG) {
- String cgLibraryName = libraryName + "-cg";
- String[] libpath = setupLibPath(systemPathProps, cgLibraryName);
- if (loadNativeCgLibrary(libpath)) {
- cgLibraryAvailable = true;
- }
+ cgLibraryAvailable = Pipeline.getPipeline().isCgLibraryAvailable();
}
-
+
// Check whether the GLSL library is available
if (globalShadingLanguage == Shader.SHADING_LANGUAGE_GLSL) {
- if (libraryName == oglLibraryName) {
- // No need to verify that GLSL is available, since GLSL is part
- // of OpenGL as an extension (or part of core in 2.0)
- glslLibraryAvailable = true;
- }
+ glslLibraryAvailable = Pipeline.getPipeline().isGLSLLibraryAvailable();
}
assert !(glslLibraryAvailable && cgLibraryAvailable) :
@@ -879,46 +802,6 @@ class MasterControl {
/**
- * Parse the specified System properties containing a PATH and return an
- * array of Strings, where each element is an absolute filename consisting of
- * the individual component of the path concatenated with the (relative)
- * library file name. Only those absolute filenames that exist are included.
- * If no absolute filename is found, we will try the relative library name.
- */
- private static String[] setupLibPath(String[] props, String libName) {
- ArrayList pathList = new ArrayList();
-
- String filename = System.mapLibraryName(libName);
- for (int n = 0; n < props.length; n++) {
- String pathString = getProperty(props[n]);
- boolean done = false;
- int posStart = 0;
- while (!done) {
- int posEnd = pathString.indexOf(File.pathSeparator, posStart);
- if (posEnd == -1) {
- posEnd = pathString.length();
- done = true;
- }
- String pathDir = pathString.substring(posStart, posEnd);
- File pathFile = new File(pathDir, filename);
- if (pathFile.exists()) {
- pathList.add(pathFile.getAbsolutePath());
- }
-
- posStart = posEnd + 1;
- }
- }
-
- // If no absolute path names exist, add in the relative library name
- if (pathList.size() == 0) {
- pathList.add(filename);
- }
-
- return (String[])pathList.toArray(new String[0]);
- }
-
-
- /**
* Invoke from InputDeviceScheduler to create an
* InputDeviceBlockingThread.
*/
@@ -997,8 +880,7 @@ class MasterControl {
* This returns the a unused displayListId
*/
Integer getDisplayListId() {
- return (Integer)
- FreeListManager.getObject(FreeListManager.DISPLAYLIST);
+ return (Integer) FreeListManager.getObject(FreeListManager.DISPLAYLIST);
}
void freeDisplayListId(Integer id) {
@@ -1017,11 +899,12 @@ class MasterControl {
synchronized (textureIdLock) {
if (textureIds.size() > 0) {
- return ((Integer)FreeListManager.
+ id = ((Integer)FreeListManager.
getObject(FreeListManager.TEXTURE2D)).intValue();
} else {
- return (++textureIdCount);
+ id = (++textureIdCount);
}
+ return id;
}
}
@@ -1079,72 +962,6 @@ class MasterControl {
}
}
}
-
- Transform3D getTransform3D(Transform3D val) {
- Transform3D t;
- t = (Transform3D)
- FreeListManager.getObject(FreeListManager.TRANSFORM3D);
- if (val != null) t.set(val);
- return t;
- }
-
- void addToTransformFreeList(Transform3D t) {
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t);
- }
-
-
- ImageComponentUpdateInfo getFreeImageUpdateInfo() {
- ImageComponentUpdateInfo info;
-
- synchronized (imageUpdateInfoList) {
- if (numFreeImageUpdateInfo > 0) {
- numFreeImageUpdateInfo--;
- info = (ImageComponentUpdateInfo)
- imageUpdateInfoList[numFreeImageUpdateInfo];
- } else {
- info = new ImageComponentUpdateInfo();
- }
- }
- return (info);
- }
-
- void addFreeImageUpdateInfo(ImageComponentUpdateInfo info) {
- synchronized (imageUpdateInfoList) {
- if (imageUpdateInfoList.length == numFreeImageUpdateInfo) {
- ImageComponentUpdateInfo[] newFreeList =
- new ImageComponentUpdateInfo[numFreeImageUpdateInfo * 2];
- System.arraycopy(imageUpdateInfoList, 0, newFreeList, 0,
- numFreeImageUpdateInfo);
- newFreeList[numFreeImageUpdateInfo++] = info;
- imageUpdateInfoList = newFreeList;
- } else {
- imageUpdateInfoList[numFreeImageUpdateInfo++] = info;
- }
- }
- }
-
- void addFreeImageUpdateInfo(ArrayList freeList) {
- ImageComponentUpdateInfo info;
-
- synchronized (imageUpdateInfoList) {
- int len = numFreeImageUpdateInfo + freeList.size();
-
- if (imageUpdateInfoList.length <= len) {
- ImageComponentUpdateInfo[] newFreeList =
- new ImageComponentUpdateInfo[len * 2];
- System.arraycopy(imageUpdateInfoList, 0, newFreeList, 0,
- numFreeImageUpdateInfo);
- imageUpdateInfoList = newFreeList;
- }
-
- for (int i = 0; i < freeList.size(); i++) {
- info = (ImageComponentUpdateInfo) freeList.get(i);
- if (info != null) {
- imageUpdateInfoList[numFreeImageUpdateInfo++] = info;
- }
- }
- }
- }
/**
@@ -1270,77 +1087,29 @@ class MasterControl {
}
/**
- * Returns the native rendering layer we are using
+ * Returns whether we are using D3D.
+ * TODO: most code that cares about this should move into the pipeline
*/
- final int getRenderingAPI() {
- return renderingAPI;
- }
-
final boolean isD3D() {
- return isD3DAPI;
+ return Pipeline.getPipeline().getPipelineType() == Pipeline.Type.NATIVE_D3D;
}
/**
- * This method increments and returns the next time value
- * timeLock must get before this procedure is invoked
+ * Returns whether we are running on Windows
+ * TODO: most code that cares about this should move into the pipeline
*/
- final long getTime() {
- return (time++);
+ final boolean isWindows() {
+ return isWindowsOs;
}
-
-
- /**
- * This adds a BHNode to one of the list of BHNodes
- */
- void addBHNodeToFreelists(BHNode bH) {
- bH.parent = null;
- bH.mark = false;
-
- if (bH.nodeType == BHNode.BH_TYPE_INTERNAL) {
- ((BHInternalNode)bH).lChild = null;
- ((BHInternalNode)bH).rChild = null;
- FreeListManager.freeObject(FreeListManager.BHINTERNAL, bH);
- }
- else if (bH.nodeType == BHNode.BH_TYPE_LEAF) {
- ((BHLeafNode)(bH)).leafIF = null;
- FreeListManager.freeObject(FreeListManager.BHLEAF, bH);
- }
- }
-
/**
- * This gets a message from the free list. If there isn't any,
- * it creates one.
+ * This method increments and returns the next time value
+ * timeLock must get before this procedure is invoked
*/
- BHNode getBHNode(int type) {
-
- if (type == BHNode.BH_TYPE_LEAF) {
- return (BHNode) FreeListManager.getObject(FreeListManager.BHLEAF);
- }
-
- if (type == BHNode.BH_TYPE_INTERNAL) {
- return (BHNode)
- FreeListManager.getObject(FreeListManager.BHINTERNAL);
- }
- return null;
+ final long getTime() {
+ return (time++);
}
-
- /**
- * This adds a message to the list of messages
- */
- final void addMessageToFreelists(J3dMessage m) {
- FreeListManager.freeObject(FreeListManager.MESSAGE, m);
- }
-
- /**
- * This gets a message from the free list. If there isn't any,
- * it creates one.
- */
- final J3dMessage getMessage() {
- return (J3dMessage) FreeListManager.getObject(FreeListManager.MESSAGE);
- }
-
/**
* This takes a given message and parses it out to the structures and
@@ -1493,7 +1262,6 @@ class MasterControl {
if (message.getRefcount() == 0) {
message.clear();
- addMessageToFreelists(message);
}
}
}
@@ -1685,183 +1453,189 @@ class MasterControl {
}
/**
- * This snapshots the time values to be used for this iteration
+ * This snapshots the time values to be used for this iteration.
+ * Note that this method is called without the timeLock held.
+ * We must synchronize on timeLock to prevent updating
+ * thread.lastUpdateTime from user thread in sendMessage()
+ * or sendRunMessage().
*/
private void updateTimeValues() {
- int i=0;
- J3dThreadData lastThread=null;
- J3dThreadData thread=null;
- long lastTime = currentTime;
-
- currentTime = getTime();
-
- J3dThreadData threads[] = (J3dThreadData [])
- stateWorkThreads.toArray(false);
- int size = stateWorkThreads.arraySize();
-
- while (i<lastTransformStructureThread) {
- thread = threads[i++];
-
- if ((thread.lastUpdateTime > thread.lastRunTime) &&
- !thread.thread.userStop) {
- lastThread = thread;
- thread.needsRun = true;
- thread.threadOpts = J3dThreadData.CONT_THREAD;
- thread.lastRunTime = currentTime;
- } else {
- thread.needsRun = false;
- }
- }
-
- if (lastThread != null) {
- lastThread.threadOpts = J3dThreadData.WAIT_ALL_THREADS;
- lastThread = null;
- }
-
- while (i<lastStructureUpdateThread) {
- thread = threads[i++];
- if ((thread.lastUpdateTime > thread.lastRunTime) &&
- !thread.thread.userStop) {
- lastThread = thread;
- thread.needsRun = true;
- thread.threadOpts = J3dThreadData.CONT_THREAD;
- thread.lastRunTime = currentTime;
- } else {
- thread.needsRun = false;
- }
- }
- if (lastThread != null) {
- lastThread.threadOpts = J3dThreadData.WAIT_ALL_THREADS;
- lastThread = null;
- }
-
- while (i<size) {
- thread = threads[i++];
- if ((thread.lastUpdateTime > thread.lastRunTime) &&
- !thread.thread.userStop) {
- lastThread = thread;
- thread.needsRun = true;
- thread.threadOpts = J3dThreadData.CONT_THREAD;
- thread.lastRunTime = currentTime;
- } else {
- thread.needsRun = false;
- }
- }
- if (lastThread != null) {
- lastThread.threadOpts = J3dThreadData.WAIT_ALL_THREADS;
- lastThread = null;
- }
-
+ synchronized (timeLock) {
+ int i=0;
+ J3dThreadData lastThread=null;
+ J3dThreadData thread=null;
+ long lastTime = currentTime;
+
+ currentTime = getTime();
+
+ J3dThreadData threads[] = (J3dThreadData [])
+ stateWorkThreads.toArray(false);
+ int size = stateWorkThreads.arraySize();
+
+ while (i<lastTransformStructureThread) {
+ thread = threads[i++];
+
+ if ((thread.lastUpdateTime > thread.lastRunTime) &&
+ !thread.thread.userStop) {
+ lastThread = thread;
+ thread.needsRun = true;
+ thread.threadOpts = J3dThreadData.CONT_THREAD;
+ thread.lastRunTime = currentTime;
+ } else {
+ thread.needsRun = false;
+ }
+ }
- threads = (J3dThreadData []) renderWorkThreads.toArray(false);
- size = renderWorkThreads.arraySize();
- View v;
- J3dThreadData lastRunThread = null;
- waitTimestamp++;
- sleepTime = 0L;
-
- boolean threadToRun = false; // Not currently used
-
- // Fix for Issue 12: loop through the list of threads, calling
- // computeCycleTime() exactly once per view. This ensures that
- // all threads for a given view see consistent values for
- // isMinCycleTimeAchieve and sleepTime.
- v = null;
- for (i=0; i<size; i++) {
- thread = threads[i];
- if (thread.view != v) {
- thread.view.computeCycleTime();
- // Set sleepTime to the value needed to satify the
- // minimum cycle time of the slowest view
- if (thread.view.sleepTime > sleepTime) {
- sleepTime = thread.view.sleepTime;
- }
- }
- v = thread.view;
- }
+ if (lastThread != null) {
+ lastThread.threadOpts = J3dThreadData.WAIT_ALL_THREADS;
+ lastThread = null;
+ }
- v = null;
- for (i=0; i<size; i++) {
- thread = threads[i];
- if (thread.canvas == null) { // Only for swap thread
- ((Object []) thread.threadArgs)[3] = null;
- }
- if ((thread.lastUpdateTime > thread.lastRunTime) &&
- !thread.thread.userStop) {
-
- if (thread.thread.lastWaitTimestamp == waitTimestamp) {
- // This renderer thread is repeated. We must wait
- // until all previous renderer threads done before
- // allowing this thread to continue. Note that
- // lastRunThread can't be null in this case.
- waitTimestamp++;
- if (thread.view != v) {
- // A new View is start
- v = thread.view;
- threadToRun = true;
- lastRunThread.threadOpts =
- (J3dThreadData.STOP_TIMER |
- J3dThreadData.WAIT_ALL_THREADS);
- ((Object []) lastRunThread.threadArgs)[3] = lastRunThread.view;
- thread.threadOpts = (J3dThreadData.START_TIMER |
- J3dThreadData.CONT_THREAD);
- } else {
- if ((lastRunThread.threadOpts &
- J3dThreadData.START_TIMER) != 0) {
- lastRunThread.threadOpts =
- (J3dThreadData.START_TIMER |
- J3dThreadData.WAIT_ALL_THREADS);
-
- } else {
- lastRunThread.threadOpts =
- J3dThreadData.WAIT_ALL_THREADS;
- }
- thread.threadOpts = J3dThreadData.CONT_THREAD;
-
- }
- } else {
- if (thread.view != v) {
- v = thread.view;
- threadToRun = true;
- // Although the renderer thread is not
- // repeated. We still need to wait all
- // previous renderer threads if new View
- // start.
- if (lastRunThread != null) {
- lastRunThread.threadOpts =
- (J3dThreadData.STOP_TIMER |
- J3dThreadData.WAIT_ALL_THREADS);
- ((Object []) lastRunThread.threadArgs)[3]
- = lastRunThread.view;
- }
- thread.threadOpts = (J3dThreadData.START_TIMER |
- J3dThreadData.CONT_THREAD);
- } else {
- thread.threadOpts = J3dThreadData.CONT_THREAD;
- }
- }
- thread.thread.lastWaitTimestamp = waitTimestamp;
- thread.needsRun = true;
- thread.lastRunTime = currentTime;
- lastRunThread = thread;
- } else {
- thread.needsRun = false;
- }
- }
+ while (i<lastStructureUpdateThread) {
+ thread = threads[i++];
+ if ((thread.lastUpdateTime > thread.lastRunTime) &&
+ !thread.thread.userStop) {
+ lastThread = thread;
+ thread.needsRun = true;
+ thread.threadOpts = J3dThreadData.CONT_THREAD;
+ thread.lastRunTime = currentTime;
+ } else {
+ thread.needsRun = false;
+ }
+ }
+ if (lastThread != null) {
+ lastThread.threadOpts = J3dThreadData.WAIT_ALL_THREADS;
+ lastThread = null;
+ }
+ while (i<size) {
+ thread = threads[i++];
+ if ((thread.lastUpdateTime > thread.lastRunTime) &&
+ !thread.thread.userStop) {
+ lastThread = thread;
+ thread.needsRun = true;
+ thread.threadOpts = J3dThreadData.CONT_THREAD;
+ thread.lastRunTime = currentTime;
+ } else {
+ thread.needsRun = false;
+ }
+ }
+ if (lastThread != null) {
+ lastThread.threadOpts = J3dThreadData.WAIT_ALL_THREADS;
+ lastThread = null;
+ }
- if (lastRunThread != null) {
- lastRunThread.threadOpts =
- (J3dThreadData.STOP_TIMER |
- J3dThreadData.WAIT_ALL_THREADS|
- J3dThreadData.LAST_STOP_TIMER);
- lockGeometry = true;
- ((Object []) lastRunThread.threadArgs)[3] = lastRunThread.view;
- } else {
- lockGeometry = false;
- }
-
+ threads = (J3dThreadData []) renderWorkThreads.toArray(false);
+ size = renderWorkThreads.arraySize();
+ View v;
+ J3dThreadData lastRunThread = null;
+ waitTimestamp++;
+ sleepTime = 0L;
+
+ boolean threadToRun = false; // Not currently used
+
+ // Fix for Issue 12: loop through the list of threads, calling
+ // computeCycleTime() exactly once per view. This ensures that
+ // all threads for a given view see consistent values for
+ // isMinCycleTimeAchieve and sleepTime.
+ v = null;
+ for (i=0; i<size; i++) {
+ thread = threads[i];
+ if (thread.view != v) {
+ thread.view.computeCycleTime();
+ // Set sleepTime to the value needed to satify the
+ // minimum cycle time of the slowest view
+ if (thread.view.sleepTime > sleepTime) {
+ sleepTime = thread.view.sleepTime;
+ }
+ }
+ v = thread.view;
+ }
+
+ v = null;
+ for (i=0; i<size; i++) {
+ thread = threads[i];
+ if (thread.canvas == null) { // Only for swap thread
+ ((Object []) thread.threadArgs)[3] = null;
+ }
+ if ((thread.lastUpdateTime > thread.lastRunTime) &&
+ !thread.thread.userStop) {
+
+ if (thread.thread.lastWaitTimestamp == waitTimestamp) {
+ // This renderer thread is repeated. We must wait
+ // until all previous renderer threads done before
+ // allowing this thread to continue. Note that
+ // lastRunThread can't be null in this case.
+ waitTimestamp++;
+ if (thread.view != v) {
+ // A new View is start
+ v = thread.view;
+ threadToRun = true;
+ lastRunThread.threadOpts =
+ (J3dThreadData.STOP_TIMER |
+ J3dThreadData.WAIT_ALL_THREADS);
+ ((Object []) lastRunThread.threadArgs)[3] = lastRunThread.view;
+ thread.threadOpts = (J3dThreadData.START_TIMER |
+ J3dThreadData.CONT_THREAD);
+ } else {
+ if ((lastRunThread.threadOpts &
+ J3dThreadData.START_TIMER) != 0) {
+ lastRunThread.threadOpts =
+ (J3dThreadData.START_TIMER |
+ J3dThreadData.WAIT_ALL_THREADS);
+
+ } else {
+ lastRunThread.threadOpts =
+ J3dThreadData.WAIT_ALL_THREADS;
+ }
+ thread.threadOpts = J3dThreadData.CONT_THREAD;
+
+ }
+ } else {
+ if (thread.view != v) {
+ v = thread.view;
+ threadToRun = true;
+ // Although the renderer thread is not
+ // repeated. We still need to wait all
+ // previous renderer threads if new View
+ // start.
+ if (lastRunThread != null) {
+ lastRunThread.threadOpts =
+ (J3dThreadData.STOP_TIMER |
+ J3dThreadData.WAIT_ALL_THREADS);
+ ((Object []) lastRunThread.threadArgs)[3]
+ = lastRunThread.view;
+ }
+ thread.threadOpts = (J3dThreadData.START_TIMER |
+ J3dThreadData.CONT_THREAD);
+ } else {
+ thread.threadOpts = J3dThreadData.CONT_THREAD;
+ }
+ }
+ thread.thread.lastWaitTimestamp = waitTimestamp;
+ thread.needsRun = true;
+ thread.lastRunTime = currentTime;
+ lastRunThread = thread;
+ } else {
+ thread.needsRun = false;
+ }
+ }
+
+
+ if (lastRunThread != null) {
+ lastRunThread.threadOpts =
+ (J3dThreadData.STOP_TIMER |
+ J3dThreadData.WAIT_ALL_THREADS|
+ J3dThreadData.LAST_STOP_TIMER);
+ lockGeometry = true;
+ ((Object []) lastRunThread.threadArgs)[3] = lastRunThread.view;
+ } else {
+ lockGeometry = false;
+ }
+ }
+
+ // Issue 275 - go to sleep without holding timeLock
// Sleep for the amount of time needed to satisfy the minimum
// cycle time for all views.
if (sleepTime > 0) {
@@ -1873,7 +1647,6 @@ class MasterControl {
}
// System.err.println("MasterControl: done sleeping");
}
-
}
private void createUpdateThread(J3dStructure structure) {
@@ -2162,7 +1935,6 @@ class MasterControl {
}
rdr.onScreen = null;
rdr.offScreen = null;
-
}
// cleanup ThreadData corresponds to the view in renderer
@@ -2290,9 +2062,7 @@ class MasterControl {
synchronized (VirtualUniverse.mc.deviceScreenMap) {
deviceScreenMap.clear();
}
- FreeListManager.clearList(FreeListManager.MESSAGE);
- FreeListManager.clearList(FreeListManager.BHLEAF);
- FreeListManager.clearList(FreeListManager.BHINTERNAL);
+
mirrorObjects.clear();
// Note: We should not clear the DISPLAYLIST/TEXTURE
// list here because other structure may release them
@@ -2306,7 +2076,6 @@ class MasterControl {
renderOnceList.clear();
timestampUpdateList.clear();
- FreeListManager.clearList(FreeListManager.TRANSFORM3D);
defaultRenderMethod = null;
text3DRenderMethod = null;
vertexArrayRenderMethod = null;
@@ -2395,7 +2164,15 @@ class MasterControl {
// offScreen canvases will be handled by the
// request renderer, so don't add offScreen canvas
// the render list
- if (!cv.offScreen) {
+ //
+ // Issue 131: Automatic offscreen canvases need to
+ // be added to onscreen list. Special case.
+ //
+ // TODO KCR Issue 131: this should probably be
+ // changed to a list of screens since multiple
+ // off-screen canvases (either auto or manual) can
+ // be used by the same renderer
+ if (!cv.manualRendering) {
screen.renderer.onScreen = screen;
} else {
screen.renderer.offScreen = screen;
@@ -2866,7 +2643,8 @@ class MasterControl {
for (int k=0; k < canvasList.length; k++) {
if (j < canvasList[k].length) {
Canvas3D cv = canvasList[k][j];
- if (cv.active && cv.isRunningStatus && !cv.offScreen) {
+ // Issue 131: setup renderer unless manualRendering
+ if (cv.active && cv.isRunningStatus && !cv.manualRendering ) {
if (cv.screen.renderer == null) {
continue;
}
@@ -2887,7 +2665,8 @@ class MasterControl {
Canvas3D cv = canvasList[j][k];
// create swap thread only if there is at
// least one active canvas
- if (cv.active && cv.isRunningStatus && !cv.offScreen) {
+ // Issue 131: only if not manualRendering
+ if (cv.active && cv.isRunningStatus && !cv.manualRendering) {
if (cv.screen.renderer == null) {
// Should not happen
continue;
@@ -2988,7 +2767,7 @@ class MasterControl {
void sendRenderMessage(GraphicsConfiguration gc,
Object arg, Integer mtype) {
Renderer rdr = createRenderer(gc);
- J3dMessage renderMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage renderMessage = new J3dMessage();
renderMessage.threads = J3dThread.RENDER_THREAD;
renderMessage.type = J3dMessage.RENDER_IMMEDIATE;
renderMessage.universe = null;
@@ -3011,12 +2790,16 @@ class MasterControl {
// Assert the master control thread is created.
J3dDebug.doAssert((mcThread != null), "mcThread != null");
Renderer rdr = createRenderer(c.graphicsConfiguration);
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.RENDER_THREAD;
createMessage.type = J3dMessage.DESTROY_CTX_AND_OFFSCREENBUFFER;
createMessage.universe = null;
createMessage.view = null;
createMessage.args[0] = c;
+ // Fix for issue 340: send display, drawable & ctx in msg
+ createMessage.args[1] = new Long(c.screen.display);
+ createMessage.args[2] = c.drawable;
+ createMessage.args[3] = c.ctx;
rdr.rendererStructure.addMessage(createMessage);
synchronized (requestObjList) {
setWorkForRequestRenderer();
@@ -3051,7 +2834,7 @@ class MasterControl {
// Fix for Issue 72 : call createRenderer rather than getting
// the renderer from the canvas.screen object
Renderer rdr = createRenderer(c.graphicsConfiguration);
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.RENDER_THREAD;
createMessage.type = J3dMessage.CREATE_OFFSCREENBUFFER;
createMessage.universe = null;
@@ -3195,7 +2978,10 @@ class MasterControl {
threadListsChanged = true;
}
} else if (type == START_RENDERER) {
- ((Canvas3D) o).isRunningStatus = true;
+ Canvas3D c3d = (Canvas3D) o;
+ if (!c3d.isFatalError()) {
+ c3d.isRunningStatus = true;
+ }
threadListsChanged = true;
} else if (type == STOP_RENDERER) {
if (o instanceof Canvas3D) {
@@ -3225,7 +3011,7 @@ class MasterControl {
}
rendererRun = true;
} else if (type == FREE_DRAWING_SURFACE) {
- DrawingSurfaceObjectAWT.freeDrawingSurface(o);
+ Pipeline.getPipeline().freeDrawingSurfaceNative(o);
} else if (type == GETBESTCONFIG) {
GraphicsConfiguration gc = ((GraphicsConfiguration [])
((GraphicsConfigTemplate3D) o).testCfg)[0];
@@ -3569,22 +3355,27 @@ class MasterControl {
}
}
break;
+
case THREAD_DONE:
if (state != WAITING_FOR_RENDERER_CLEANUP) {
+
threadPending--;
- if (nthread.type == J3dThread.RENDER_THREAD) {
+ assert threadPending >= 0 : ("threadPending = " + threadPending);
+ if (nthread.type == J3dThread.RENDER_THREAD) {
View v = (View) nthread.args[3];
if (v != null) { // STOP_TIMER
v.stopTime = J3dClock.currentTimeMillis();
}
-
+
if (--renderPending == 0) {
renderWaiting = false;
}
+ assert renderPending >= 0 : ("renderPending = " + renderPending);
} else {
if (--statePending == 0) {
stateWaiting = false;
}
+ assert statePending >= 0 : ("statePending = " + statePending);
}
if (state == WAITING_FOR_CPU || state == WAITING_FOR_THREADS) {
notify();
@@ -3594,19 +3385,12 @@ class MasterControl {
state = RUNNING;
}
break;
- case WAIT_FOR_ALL:
- while (threadPending != 0) {
- state = WAITING_FOR_THREADS;
- try {
- wait();
- } catch (InterruptedException e) {
- System.err.println(e);
- }
- }
- break;
+
case CHECK_FOR_WORK:
if (!workToDo) {
state = SLEEPING;
+ // NOTE: this could wakeup spuriously (see issue 279), but it
+ // will not cause any problems.
try {
wait();
} catch (InterruptedException e) {
@@ -3616,12 +3400,14 @@ class MasterControl {
}
workToDo = false;
break;
+
case SET_WORK:
workToDo = true;
if (state == SLEEPING) {
notify();
}
break;
+
case SET_WORK_FOR_REQUEST_RENDERER:
requestRenderWorkToDo = true;
workToDo = true;
@@ -3630,45 +3416,29 @@ class MasterControl {
notify();
}
break;
+
case RUN_RENDERER_CLEANUP:
nthread.runMonitor(J3dThread.RUN, currentTime,
rendererCleanupArgs);
state = WAITING_FOR_RENDERER_CLEANUP;
- try {
- wait();
- } catch (InterruptedException e) {
- System.err.println(e);
- }
+ // Issue 279 - loop until state is set to running
+ while (state != RUNNING) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ System.err.println(e);
+ }
+ }
break;
- case SLEEP:
- state = SLEEPING;
- try {
- wait(sleepTime);
- } catch (InterruptedException e) {
- System.err.println(e);
- }
+
+ default:
+ // Should never get here
+ assert false : "missing case in switch statement";
}
}
// Static initializer
static {
- /*
- // Determine whether the JVM is version JDK1.5 or later.
- // XXXX: replace this with code that checks for the existence
- // of a class or method that is defined in 1.5, but not in 1.4
- String versionString =
- (String) java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction() {
- public Object run() {
- return System.getProperty("java.version");
- }
- });
- jvm15OrBetter = !(versionString.startsWith("1.4") ||
- versionString.startsWith("1.3") ||
- versionString.startsWith("1.2") ||
- versionString.startsWith("1.1"));
- */
-
// create ThreadGroup
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
@@ -3828,4 +3598,9 @@ class MasterControl {
// even whether) we sleep
}
}
+
+ // Return the number of available processors
+ private int getNumberOfProcessors() {
+ return Runtime.getRuntime().availableProcessors();
+ }
}
diff --git a/src/classes/share/javax/media/j3d/MaterialRetained.java b/src/classes/share/javax/media/j3d/MaterialRetained.java
index 06ddef8..4417aaa 100644
--- a/src/classes/share/javax/media/j3d/MaterialRetained.java
+++ b/src/classes/share/javax/media/j3d/MaterialRetained.java
@@ -409,21 +409,10 @@ class MaterialRetained extends NodeComponentRetained {
/**
* Updates the native context.
*/
- native void updateNative(long ctx,
- float red, float green, float blue, float alpha,
- float ared, float agreen, float ablue,
- float ered, float egreen, float eblue,
- float dred, float dgreen, float dblue,
- float sred, float sgreen, float sblue,
- float shininess, int colorTarget, boolean enable);
-
- /**
- * Updates the native context.
- */
- void updateNative(long ctx,
+ void updateNative(Context ctx,
float red, float green, float blue, float alpha,
boolean enableLighting) {
- updateNative(ctx, red, green, blue, alpha,
+ Pipeline.getPipeline().updateMaterial(ctx, red, green, blue, alpha,
ambientColor.x, ambientColor.y, ambientColor.z,
emissiveColor.x, emissiveColor.y, emissiveColor.z,
diffuseColor.x, diffuseColor.y, diffuseColor.z,
@@ -516,7 +505,7 @@ class MaterialRetained extends NodeComponentRetained {
ArrayList gaList = Shape3DRetained.getGeomAtomsList(mirror.users, univList);
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.MATERIAL_CHANGED;
createMessage.universe = null;
@@ -528,7 +517,7 @@ class MaterialRetained extends NodeComponentRetained {
int size = univList.size();
for(int i=0; i<size; i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.MATERIAL_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/MediaContainerRetained.java b/src/classes/share/javax/media/j3d/MediaContainerRetained.java
index e5dda5b..f029fec 100644
--- a/src/classes/share/javax/media/j3d/MediaContainerRetained.java
+++ b/src/classes/share/javax/media/j3d/MediaContainerRetained.java
@@ -14,10 +14,6 @@ package javax.media.j3d;
import java.net.URL;
import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.io.File;
-import java.security.*;
-import java.io.InputStream;
/**
* The MediaContainerRetained object defines all rendering state that can
@@ -183,7 +179,7 @@ class MediaContainerRetained extends NodeComponentRetained {
*/
void dispatchMessage() {
// Send message including a integer argumentD
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.SOUND_SCHEDULER;
createMessage.type = J3dMessage.MEDIA_CONTAINER_CHANGED;
createMessage.universe = null;
diff --git a/src/classes/share/javax/media/j3d/ModelClipRetained.java b/src/classes/share/javax/media/j3d/ModelClipRetained.java
index b1e3365..f76c967 100644
--- a/src/classes/share/javax/media/j3d/ModelClipRetained.java
+++ b/src/classes/share/javax/media/j3d/ModelClipRetained.java
@@ -577,9 +577,6 @@ class ModelClipRetained extends LeafRetained {
* This method and its native counterpart update the native context
* model clip planes.
*/
- native void update(long ctx, int planeNum, boolean enableFlag,
- double A, double B, double C, double D);
-
void update(Canvas3D cv, int enableMask) {
cv.setModelViewMatrix(cv.ctx,
cv.vworldToEc.mat,
@@ -587,10 +584,10 @@ class ModelClipRetained extends LeafRetained {
update(cv.ctx, enableMask, getLastLocalToVworld());
}
- void update(long ctx, int enableMask, Transform3D trans) {
+ void update(Context ctx, int enableMask, Transform3D trans) {
if (!VirtualUniverse.mc.isD3D()) {
for (int i = 0; i < 6; i ++) {
- update(ctx, i, ((enableMask & (1 << i)) != 0),
+ Pipeline.getPipeline().updateModelClip(ctx, i, ((enableMask & (1 << i)) != 0),
xformPlanes[i].x, xformPlanes[i].y,
xformPlanes[i].z, xformPlanes[i].w);
}
@@ -613,10 +610,10 @@ class ModelClipRetained extends LeafRetained {
xformPlanes[i].z, xformPlanes[i].w);
vec.normalize();
invtrans.transform(vec);
- update(ctx, i, true, vec.x, vec.y, vec.z, vec.w);
+ Pipeline.getPipeline().updateModelClip(ctx, i, true, vec.x, vec.y, vec.z, vec.w);
} else {
- update(ctx, i, false, 0, 0, 0, 0);
+ Pipeline.getPipeline().updateModelClip(ctx, i, false, 0, 0, 0, 0);
}
}
}
@@ -853,7 +850,7 @@ class ModelClipRetained extends LeafRetained {
// Initialize the mirror object, this needs to be done, when
// renderBin is not accessing any of the fields
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.MODELCLIP_CHANGED;
@@ -914,7 +911,7 @@ class ModelClipRetained extends LeafRetained {
if (scopes.size() > 0) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT;
createMessage.universe = universe;
createMessage.type = J3dMessage.MODELCLIP_CHANGED;
@@ -1026,7 +1023,7 @@ class ModelClipRetained extends LeafRetained {
}
final void sendMessage(int attrMask, Object attr1, Object attr2) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.MODELCLIP_CHANGED;
createMessage.universe = universe;
diff --git a/src/classes/share/javax/media/j3d/MorphRetained.java b/src/classes/share/javax/media/j3d/MorphRetained.java
index a91567e..b063fb2 100644
--- a/src/classes/share/javax/media/j3d/MorphRetained.java
+++ b/src/classes/share/javax/media/j3d/MorphRetained.java
@@ -138,7 +138,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
if (source.isLive()) {
// Notify Geometry Structure to set mirror shape collision
// bound and check for collision
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.COLLISION_BOUND_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM;
message.universe = universe;
@@ -154,7 +154,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
void setBounds(Bounds bounds) {
super.setBounds(bounds);
if (source.isLive() && !boundsAutoCompute) {
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.REGION_BOUND_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM |
targetThreads;
@@ -297,7 +297,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
shape.setMorphGeometry(morphedGeometryArray, mirrorShape3D);
J3dMessage mChangeMessage = null;
- mChangeMessage = VirtualUniverse.mc.getMessage();
+ mChangeMessage = new J3dMessage();
mChangeMessage.type = J3dMessage.MORPH_CHANGED;
mChangeMessage.threads = (J3dThread.UPDATE_GEOMETRY |
J3dThread.UPDATE_TRANSFORM);
@@ -377,7 +377,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
else
size = 1;
J3dMessage[] createMessage = new J3dMessage[size];
- createMessage[0] = VirtualUniverse.mc.getMessage();
+ createMessage[0] = new J3dMessage();
createMessage[0].threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT |
J3dThread.UPDATE_RENDER;
createMessage[0].type = J3dMessage.MORPH_CHANGED;
@@ -398,7 +398,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
createMessage[0].args[3] = obj;
createMessage[0].args[4] = Shape3DRetained.getGeomAtomsArray(mirrorShape3D);
if(visibleIsDirty) {
- createMessage[1] = VirtualUniverse.mc.getMessage();
+ createMessage[1] = new J3dMessage();
createMessage[1].threads = J3dThread.UPDATE_GEOMETRY;
createMessage[1].type = J3dMessage.SHAPE3D_CHANGED;
createMessage[1].universe = universe;
@@ -431,7 +431,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
if (((Morph)this.source).isLive()) {
// Send a message
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT |
J3dThread.UPDATE_RENDER;;
createMessage.type = J3dMessage.MORPH_CHANGED;
@@ -568,7 +568,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
if (source.isLive()) {
((GeometryArrayRetained)morphedGeometryArray.retained).updateData(this);
J3dMessage mChangeMessage = null;
- mChangeMessage = VirtualUniverse.mc.getMessage();
+ mChangeMessage = new J3dMessage();
mChangeMessage.type = J3dMessage.MORPH_CHANGED;
mChangeMessage.threads = (J3dThread.UPDATE_GEOMETRY |
J3dThread.UPDATE_TRANSFORM);
@@ -1447,7 +1447,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
// Need to clone the geometry , if its indexed ...
if (refCount == 1 && this.geometryArrays[0] instanceof IndexedGeometryArrayRetained) {
- J3dMessage mChangeMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage mChangeMessage = new J3dMessage();
mChangeMessage.type = J3dMessage.MORPH_CHANGED;
mChangeMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
mChangeMessage.args[0] = this;
@@ -1650,7 +1650,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
localBounds = getBounds();
super.setBoundsAutoCompute(autoCompute);
if (source.isLive()) {
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.BOUNDS_AUTO_COMPUTE_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM |
J3dThread.UPDATE_GEOMETRY |
@@ -1666,7 +1666,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
void updateBounds() {
localBounds = getEffectiveBounds();
if (source.isLive()) {
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.BOUNDS_AUTO_COMPUTE_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM |
J3dThread.UPDATE_GEOMETRY |
diff --git a/src/classes/share/javax/media/j3d/NativeAPIInfo.java b/src/classes/share/javax/media/j3d/NativeAPIInfo.java
deleted file mode 100644
index 62b1f69..0000000
--- a/src/classes/share/javax/media/j3d/NativeAPIInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-/*
- * Portions of this code were derived from work done by the Blackdown
- * group (www.blackdown.org), who did the initial Linux implementation
- * of the Java 3D API.
- */
-
-package javax.media.j3d;
-
-class NativeAPIInfo {
-
- /**
- * Returns the rendering API being used.
- * @return the rendering API, one of:
- * <code>MasterControl.RENDER_OPENGL_LINUX</code>,
- * <code>MasterControl.RENDER_OPENGL_SOLARIS</code>,
- * <code>MasterControl.RENDER_OPENGL_WIN32</code>,
- * or <code>MasterControl.RENDER_DIRECT3D</code>
- */
- native int getRenderingAPI();
-}
diff --git a/src/classes/share/javax/media/j3d/NativeContext.java b/src/classes/share/javax/media/j3d/NativeContext.java
new file mode 100644
index 0000000..62a3e0b
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/NativeContext.java
@@ -0,0 +1,31 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Graphics context objects for native rendering pipeline.
+ */
+class NativeContext implements Context {
+
+ // Native context pointer
+ private long nativeCtx;
+
+ NativeContext(long nativeCtx) {
+ this.nativeCtx = nativeCtx;
+ }
+
+ long getNativeCtx() {
+ return nativeCtx;
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/NativeDrawable.java b/src/classes/share/javax/media/j3d/NativeDrawable.java
new file mode 100644
index 0000000..73fb9d3
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/NativeDrawable.java
@@ -0,0 +1,32 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Graphics Drawable objects for native rendering pipeline.
+ */
+class NativeDrawable implements Drawable {
+
+ // Native drawable pointer. On Windows it is the native HDC.
+ // On X11 it is the handle to the native X11 drawable.
+ private long nativeDrawable;
+
+ NativeDrawable(long nativeDrawable) {
+ this.nativeDrawable = nativeDrawable;
+ }
+
+ long getNativeDrawable() {
+ return nativeDrawable;
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/NativePipeline.java b/src/classes/share/javax/media/j3d/NativePipeline.java
new file mode 100644
index 0000000..1a3288f
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/NativePipeline.java
@@ -0,0 +1,3325 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.io.File;
+import java.util.ArrayList;
+
+/**
+ * Concrete implementation of Pipeline class for native OGL and D3D rendering
+ * pipeline.
+ */
+class NativePipeline extends Pipeline {
+
+ // System properties containing the native library search PATH
+ // The order listed is the order in which they will be searched
+ private static final String[] systemPathProps = {
+ "sun.boot.library.path",
+ "java.library.path"
+ };
+
+ // Prefix for native libraries
+ private static final String libPrefix = "j3dcore";
+
+ // Boolean indicating whether we are using D3D or OGL
+ private boolean isD3D;
+
+ // Renderer name, either "ogl" or "d3d"
+ private String rendererName;
+
+ // Flags indicating whether the Cg or GLSL libraries are available.
+ private boolean cgLibraryAvailable = false;
+ private boolean glslLibraryAvailable = false;
+
+ /**
+ * The platform dependent template. Since there is no
+ * template-specific instance data in the NativeConfigTemplate3D
+ * class, we can create one statically.
+ */
+ private static NativeConfigTemplate3D nativeTemplate = new NativeConfigTemplate3D();
+
+ /**
+ * Constructor for singleton NativePipeline instance
+ */
+ protected NativePipeline() {
+ }
+
+ /**
+ * Initialize the pipeline
+ */
+ void initialize(Pipeline.Type pipelineType) {
+ super.initialize(pipelineType);
+
+ // This works around a native load library bug
+ try {
+ java.awt.Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit();
+ toolkit = null; // just making sure GC collects this
+ } catch (java.awt.AWTError e) {
+ }
+
+ switch (pipelineType) {
+ case NATIVE_OGL:
+ isD3D = false;
+ rendererName = "ogl";
+ break;
+ case NATIVE_D3D:
+ isD3D = true;
+ rendererName = "d3d";
+ break;
+ default:
+ assert false; // Should never get here
+ }
+ }
+
+ /**
+ * Load all of the required libraries
+ */
+ void loadLibraries(int globalShadingLanguage) {
+ // Load the native JAWT library
+ loadLibrary("jawt");
+
+ // Load the native rendering library
+ String libraryName = libPrefix + "-" + rendererName;
+ loadLibrary(libraryName);
+
+ // Check whether the Cg library is available
+ if (globalShadingLanguage == Shader.SHADING_LANGUAGE_CG) {
+ String cgLibraryName = libPrefix + "-" + rendererName + "-cg";
+ String[] libpath = setupLibPath(cgLibraryName);
+ cgLibraryAvailable = loadNativeCgLibrary(libpath);
+ }
+
+ // Check whether the GLSL library is available
+ if (globalShadingLanguage == Shader.SHADING_LANGUAGE_GLSL) {
+ if (getPipelineType() == Pipeline.Type.NATIVE_OGL) {
+ // No need to verify that GLSL is available, since GLSL is part
+ // of OpenGL as an extension (or part of core in 2.0)
+ glslLibraryAvailable = true;
+ }
+ }
+ }
+
+ /**
+ * Returns true if the Cg library is loaded and available. Note that this
+ * does not necessarily mean that Cg is supported by the graphics card.
+ */
+ boolean isCgLibraryAvailable() {
+ return cgLibraryAvailable;
+ }
+
+ /**
+ * Returns true if the GLSL library is loaded and available. Note that this
+ * does not necessarily mean that GLSL is supported by the graphics card.
+ */
+ boolean isGLSLLibraryAvailable() {
+ return glslLibraryAvailable;
+ }
+
+ /**
+ * Load the specified native library.
+ */
+ private void loadLibrary(String libName) {
+ final String libraryName = libName;
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction() {
+ public Object run() {
+ System.loadLibrary(libraryName);
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Parse the specified System properties containing a PATH and return an
+ * array of Strings, where each element is an absolute filename consisting of
+ * the individual component of the path concatenated with the (relative)
+ * library file name. Only those absolute filenames that exist are included.
+ * If no absolute filename is found, we will try the relative library name.
+ */
+ private String[] setupLibPath(String libName) {
+ final String libraryName = libName;
+ return (String[])
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction() {
+ public Object run() {
+ ArrayList pathList = new ArrayList();
+
+ String filename = System.mapLibraryName(libraryName);
+ for (int n = 0; n < systemPathProps.length; n++) {
+ String pathString = System.getProperty(systemPathProps[n]);
+ boolean done = false;
+ int posStart = 0;
+ while (!done) {
+ int posEnd = pathString.indexOf(File.pathSeparator, posStart);
+ if (posEnd == -1) {
+ posEnd = pathString.length();
+ done = true;
+ }
+ String pathDir = pathString.substring(posStart, posEnd);
+ File pathFile = new File(pathDir, filename);
+ if (pathFile.exists()) {
+ pathList.add(pathFile.getAbsolutePath());
+ }
+
+ posStart = posEnd + 1;
+ }
+ }
+
+ // If no absolute path names exist, add in the relative library name
+ if (pathList.size() == 0) {
+ pathList.add(filename);
+ }
+
+ return (String[])pathList.toArray(new String[0]);
+ }
+ });
+ }
+
+ // Method to verify whether the native Cg library is available
+ private native boolean loadNativeCgLibrary(String[] libpath);
+
+
+ //
+ // Methods to box/unbox various native objects
+ //
+
+ private long unbox(Context ctx) {
+ if (ctx == null) {
+ return 0;
+ } else {
+ return ((NativeContext)ctx).getNativeCtx();
+ }
+ }
+
+ private Context boxContext(long nativeCtx) {
+ if (nativeCtx == 0) {
+ return null;
+ } else {
+ return new NativeContext(nativeCtx);
+ }
+ }
+
+ private long unbox(Drawable drawable) {
+ if (drawable == null) {
+ return 0;
+ } else {
+ return ((NativeDrawable)drawable).getNativeDrawable();
+ }
+ }
+
+ private Drawable boxDrawable(long nativeDrawable) {
+ if (nativeDrawable == 0) {
+ return null;
+ } else {
+ return new NativeDrawable(nativeDrawable);
+ }
+ }
+
+ private long unbox(ShaderProgramId shaderProgramId) {
+ if (shaderProgramId == null) {
+ return 0;
+ } else {
+ return ((NativeShaderObject)shaderProgramId).getNativeId();
+ }
+ }
+
+ private ShaderProgramId boxShaderProgramId(long nativeId) {
+ if (nativeId == 0) {
+ return null;
+ } else {
+ return new NativeShaderObject(nativeId);
+ }
+ }
+
+ private long unbox(ShaderId shaderId) {
+ if (shaderId == null) {
+ return 0;
+ } else {
+ return ((NativeShaderObject)shaderId).getNativeId();
+ }
+ }
+
+ private ShaderId boxShaderId(long nativeId) {
+ if (nativeId == 0) {
+ return null;
+ } else {
+ return new NativeShaderObject(nativeId);
+ }
+ }
+
+ private long unbox(ShaderAttrLoc attrLoc) {
+ if (attrLoc == null) {
+ return -1;
+ } else {
+ return ((NativeShaderObject)attrLoc).getNativeId();
+ }
+ }
+
+ private ShaderAttrLoc boxShaderAttrLoc(long nativeId) {
+ if (nativeId == -1) {
+ return null;
+ } else {
+ return new NativeShaderObject(nativeId);
+ }
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GeometryArrayRetained methods
+ //
+
+ // Used by D3D to free vertex buffer
+ native void freeD3DArray(GeometryArrayRetained geo, boolean deleteVB);
+
+ // used for GeometryArrays by Copy or interleaved
+ native void execute(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[] varray, float[] cdata, int cdirty);
+
+ void execute(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[] varray, float[] cdata, int cdirty) {
+ execute(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale,
+ useAlpha,
+ ignoreVertexColors,
+ startVIndex, vcount, vformat,
+ texCoordSetCount, texCoordSetMap,
+ texCoordSetMapLen,
+ texCoordSetOffset,
+ numActiveTexUnitState,
+ vertexAttrCount, vertexAttrSizes,
+ varray, cdata, cdirty);
+ }
+
+ // used by GeometryArray by Reference with java arrays
+ native void executeVA(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, float[] vfcoords, double[] vdcoords,
+ int colorIndex, float[] cfdata, byte[] cbdata,
+ int normalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty);
+
+ void executeVA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, float[] vfcoords, double[] vdcoords,
+ int colorIndex, float[] cfdata, byte[] cbdata,
+ int normalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty) {
+ executeVA(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale,
+ ignoreVertexColors,
+ vcount,
+ vformat,
+ vdefined,
+ coordIndex, vfcoords, vdcoords,
+ colorIndex, cfdata, cbdata,
+ normalIndex, ndata,
+ vertexAttrCount, vertexAttrSizes,
+ vertexAttrIndex, vertexAttrData,
+ texcoordmaplength,
+ texcoordoffset,
+ numActiveTexUnitState,
+ texIndex, texstride, texCoords,
+ cdirty);
+ }
+
+ // used by GeometryArray by Reference with NIO buffer
+ native void executeVABuffer(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex,
+ Object vcoords,
+ int colorIndex,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ int normalIndex, Object ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, Object[] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty);
+
+ void executeVABuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex,
+ Object vcoords,
+ int colorIndex,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ int normalIndex, Object ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, Object[] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty) {
+ executeVABuffer(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale,
+ ignoreVertexColors,
+ vcount,
+ vformat,
+ vdefined,
+ coordIndex,
+ vcoords,
+ colorIndex,
+ cdataBuffer,
+ cfdata, cbdata,
+ normalIndex, ndata,
+ vertexAttrCount, vertexAttrSizes,
+ vertexAttrIndex, vertexAttrData,
+ texcoordmaplength,
+ texcoordoffset,
+ numActiveTexUnitState,
+ texIndex, texstride, texCoords,
+ cdirty);
+ }
+
+ // used by GeometryArray by Reference in interleaved format with NIO buffer
+ native void executeInterleavedBuffer(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ Object varray, float[] cdata, int cdirty);
+
+ void executeInterleavedBuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ Object varray, float[] cdata, int cdirty) {
+ executeInterleavedBuffer(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale,
+ useAlpha,
+ ignoreVertexColors,
+ startVIndex, vcount, vformat,
+ texCoordSetCount, texCoordSetMap,
+ texCoordSetMapLen,
+ texCoordSetOffset,
+ numActiveTexUnitState,
+ varray, cdata, cdirty);
+ }
+
+ native void setVertexFormat(long ctx, GeometryArrayRetained geo,
+ int vformat, boolean useAlpha, boolean ignoreVertexColors);
+
+ void setVertexFormat(Context ctx, GeometryArrayRetained geo,
+ int vformat, boolean useAlpha, boolean ignoreVertexColors) {
+ setVertexFormat(unbox(ctx), geo,
+ vformat, useAlpha, ignoreVertexColors);
+ }
+
+ native void disableGlobalAlpha(long ctx, GeometryArrayRetained geo, int vformat,
+ boolean useAlpha, boolean ignoreVertexColors);
+
+ void disableGlobalAlpha(Context ctx, GeometryArrayRetained geo, int vformat,
+ boolean useAlpha, boolean ignoreVertexColors) {
+ disableGlobalAlpha(unbox(ctx), geo, vformat,
+ useAlpha, ignoreVertexColors);
+ }
+
+ // used for GeometryArrays
+ native void buildGA(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int startVIndex,
+ int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen, int[] texCoordSetMapOffset,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ double[] xform, double[] nxform,
+ float[] varray);
+
+ void buildGA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int startVIndex,
+ int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen, int[] texCoordSetMapOffset,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ double[] xform, double[] nxform,
+ float[] varray) {
+ buildGA(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale, updateAlpha,
+ alpha,
+ ignoreVertexColors,
+ startVIndex,
+ vcount, vformat,
+ texCoordSetCount, texCoordSetMap,
+ texCoordSetMapLen, texCoordSetMapOffset,
+ vertexAttrCount, vertexAttrSizes,
+ xform, nxform,
+ varray);
+ }
+
+ // used to Build Dlist GeometryArray by Reference with java arrays
+ native void buildGAForByRef(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, float[] vfcoords, double[] vdcoords,
+ int colorIndex, float[] cfdata, byte[] cbdata,
+ int normalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int[] texIndex, int texstride, Object[] texCoords,
+ double[] xform, double[] nxform);
+
+ void buildGAForByRef(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, float[] vfcoords, double[] vdcoords,
+ int colorIndex, float[] cfdata, byte[] cbdata,
+ int normalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int[] texIndex, int texstride, Object[] texCoords,
+ double[] xform, double[] nxform) {
+ buildGAForByRef(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale, updateAlpha,
+ alpha,
+ ignoreVertexColors,
+ vcount,
+ vformat,
+ vdefined,
+ coordIndex, vfcoords, vdcoords,
+ colorIndex, cfdata, cbdata,
+ normalIndex, ndata,
+ vertexAttrCount, vertexAttrSizes,
+ vertexAttrIndex, vertexAttrData,
+ texcoordmaplength,
+ texcoordoffset,
+ texIndex, texstride, texCoords,
+ xform, nxform);
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // IndexedGeometryArrayRetained methods
+ //
+
+ // by-copy or interleaved, by reference, Java arrays
+ native void executeIndexedGeometry(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ float[] varray, float[] cdata,
+ int cdirty,
+ int[] indexCoord);
+
+ void executeIndexedGeometry(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ float[] varray, float[] cdata,
+ int cdirty,
+ int[] indexCoord) {
+ executeIndexedGeometry(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale,
+ useAlpha,
+ ignoreVertexColors,
+ initialIndexIndex,
+ indexCount,
+ vertexCount, vformat,
+ vertexAttrCount, vertexAttrSizes,
+ texCoordSetCount, texCoordSetMap,
+ texCoordSetMapLen,
+ texCoordSetOffset,
+ numActiveTexUnitState,
+ varray, cdata,
+ cdirty,
+ indexCoord);
+ }
+
+ // interleaved, by reference, nio buffer
+ native void executeIndexedGeometryBuffer(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ Object varray, float[] cdata,
+ int cdirty,
+ int[] indexCoord);
+
+ void executeIndexedGeometryBuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ Object varray, float[] cdata,
+ int cdirty,
+ int[] indexCoord) {
+ executeIndexedGeometryBuffer(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale,
+ useAlpha,
+ ignoreVertexColors,
+ initialIndexIndex,
+ indexCount,
+ vertexCount, vformat,
+ texCoordSetCount, texCoordSetMap,
+ texCoordSetMapLen,
+ texCoordSetOffset,
+ numActiveTexUnitState,
+ varray, cdata,
+ cdirty,
+ indexCoord);
+ }
+
+ // non interleaved, by reference, Java arrays
+ native void executeIndexedGeometryVA(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ float[] vfcoords, double[] vdcoords,
+ float[] cfdata, byte[] cbdata,
+ float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int texstride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord);
+
+ void executeIndexedGeometryVA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ float[] vfcoords, double[] vdcoords,
+ float[] cfdata, byte[] cbdata,
+ float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int texstride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord) {
+ executeIndexedGeometryVA(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale,
+ ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ vertexCount,
+ vformat,
+ vdefined,
+ vfcoords, vdcoords,
+ cfdata, cbdata,
+ ndata,
+ vertexAttrCount, vertexAttrSizes,
+ vertexAttrData,
+ texcoordmaplength,
+ texcoordoffset,
+ numActiveTexUnitState,
+ texstride, texCoords,
+ cdirty,
+ indexCoord);
+ }
+
+ // non interleaved, by reference, nio buffer
+ native void executeIndexedGeometryVABuffer(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ Object vcoords,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ Object normal,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ Object[] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int texstride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord);
+
+ void executeIndexedGeometryVABuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ Object vcoords,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ Object normal,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ Object[] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int texstride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord) {
+ executeIndexedGeometryVABuffer(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale,
+ ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ vertexCount,
+ vformat,
+ vdefined,
+ vcoords,
+ cdataBuffer,
+ cfdata, cbdata,
+ normal,
+ vertexAttrCount, vertexAttrSizes,
+ vertexAttrData,
+ texcoordmaplength,
+ texcoordoffset,
+ numActiveTexUnitState,
+ texstride, texCoords,
+ cdirty,
+ indexCoord);
+ }
+
+ // by-copy geometry
+ native void buildIndexedGeometry(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetMapOffset,
+ double[] xform, double[] nxform,
+ float[] varray, int[] indexCoord);
+
+ void buildIndexedGeometry(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetMapOffset,
+ double[] xform, double[] nxform,
+ float[] varray, int[] indexCoord) {
+ buildIndexedGeometry(unbox(ctx),
+ geo, geo_type,
+ isNonUniformScale, updateAlpha,
+ alpha,
+ ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ vertexCount,
+ vformat,
+ vertexAttrCount, vertexAttrSizes,
+ texCoordSetCount, texCoordSetMap,
+ texCoordSetMapLen,
+ texCoordSetMapOffset,
+ xform, nxform,
+ varray, indexCoord);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GraphicsContext3D methods
+ //
+
+ native void readRaster(long ctx,
+ int type, int xSrcOffset, int ySrcOffset,
+ int width, int height, int hCanvas,
+ int imageDataType,
+ int imageFormat,
+ Object imageBuffer,
+ int depthFormat,
+ Object depthBuffer);
+
+ void readRaster(Context ctx,
+ int type, int xSrcOffset, int ySrcOffset,
+ int width, int height, int hCanvas,
+ int imageDataType,
+ int imageFormat,
+ Object imageBuffer,
+ int depthFormat,
+ Object depthBuffer) {
+ readRaster(unbox(ctx),
+ type, xSrcOffset, ySrcOffset,
+ width, height, hCanvas,
+ imageDataType,
+ imageFormat, imageBuffer,
+ depthFormat, depthBuffer);
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // CgShaderProgramRetained methods
+ //
+
+ // ShaderAttributeValue methods
+
+ native ShaderError setCgUniform1i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int value);
+
+ ShaderError setCgUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int value) {
+ return setCgUniform1i(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setCgUniform1f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float value);
+
+ ShaderError setCgUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float value) {
+ return setCgUniform1f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setCgUniform2i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ ShaderError setCgUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return setCgUniform2i(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setCgUniform2f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ ShaderError setCgUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return setCgUniform2f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setCgUniform3i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ ShaderError setCgUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return setCgUniform3i(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setCgUniform3f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ ShaderError setCgUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return setCgUniform3f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setCgUniform4i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ ShaderError setCgUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return setCgUniform4i(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setCgUniform4f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ ShaderError setCgUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return setCgUniform4f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setCgUniformMatrix3f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ ShaderError setCgUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return setCgUniformMatrix3f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setCgUniformMatrix4f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ ShaderError setCgUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return setCgUniformMatrix4f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ // ShaderAttributeArray methods
+
+ native ShaderError setCgUniform1iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ ShaderError setCgUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return setCgUniform1iArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setCgUniform1fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setCgUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setCgUniform1fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setCgUniform2iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ ShaderError setCgUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return setCgUniform2iArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setCgUniform2fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setCgUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setCgUniform2fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setCgUniform3iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ ShaderError setCgUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return setCgUniform3iArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setCgUniform3fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setCgUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setCgUniform3fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setCgUniform4iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ ShaderError setCgUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return setCgUniform4iArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setCgUniform4fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setCgUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setCgUniform4fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setCgUniformMatrix3fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setCgUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setCgUniformMatrix3fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setCgUniformMatrix4fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setCgUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setCgUniformMatrix4fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ // Native interfaces for shader compilation, etc.
+ native ShaderError createCgShader(long ctx, int shaderType, long[] shaderId);
+
+ ShaderError createCgShader(Context ctx, int shaderType, ShaderId[] shaderId) {
+ long[] nativeId = new long[1];
+ ShaderError err = createCgShader(unbox(ctx), shaderType, nativeId);
+ shaderId[0] = boxShaderId(nativeId[0]);
+ return err;
+ }
+
+ native ShaderError destroyCgShader(long ctx, long shaderId);
+
+ ShaderError destroyCgShader(Context ctx, ShaderId shaderId) {
+ return destroyCgShader(unbox(ctx), unbox(shaderId));
+ }
+
+ native ShaderError compileCgShader(long ctx, long shaderId, String program);
+
+ ShaderError compileCgShader(Context ctx, ShaderId shaderId, String program) {
+ return compileCgShader(unbox(ctx), unbox(shaderId), program);
+ }
+
+ native ShaderError createCgShaderProgram(long ctx, long[] shaderProgramId);
+
+ ShaderError createCgShaderProgram(Context ctx, ShaderProgramId[] shaderProgramId) {
+ long[] nativeId = new long[1];
+ ShaderError err = createCgShaderProgram(unbox(ctx), nativeId);
+ shaderProgramId[0] = boxShaderProgramId(nativeId[0]);
+ return err;
+ }
+
+ native ShaderError destroyCgShaderProgram(long ctx, long shaderProgramId);
+
+ ShaderError destroyCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return destroyCgShaderProgram(unbox(ctx), unbox(shaderProgramId));
+ }
+
+ native ShaderError linkCgShaderProgram(long ctx, long shaderProgramId,
+ long[] shaderIds);
+
+ ShaderError linkCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId,
+ ShaderId[] shaderIds) {
+
+ assert shaderIds != null;
+ long[] nativeIds = new long[shaderIds.length];
+ for (int i = 0; i < shaderIds.length; i++) {
+ nativeIds[i] = unbox(shaderIds[i]);
+ }
+ return linkCgShaderProgram(unbox(ctx), unbox(shaderProgramId),
+ nativeIds);
+ }
+
+ native void lookupCgVertexAttrNames(long ctx, long shaderProgramId,
+ int numAttrNames, String[] attrNames, boolean[] errArr);
+
+ void lookupCgVertexAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, boolean[] errArr) {
+ lookupCgVertexAttrNames(unbox(ctx), unbox(shaderProgramId),
+ numAttrNames, attrNames, errArr);
+ }
+
+ native void lookupCgShaderAttrNames(long ctx, long shaderProgramId,
+ int numAttrNames, String[] attrNames, long[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr);
+
+ void lookupCgShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, ShaderAttrLoc[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr) {
+
+ assert numAttrNames == locArr.length;
+ long[] nativeLocArr = new long[numAttrNames];
+ for (int i = 0; i < numAttrNames; i++) {
+ // Initialize to invalid native location
+ nativeLocArr[i] = -1;
+ }
+ lookupCgShaderAttrNames(unbox(ctx), unbox(shaderProgramId),
+ numAttrNames, attrNames, nativeLocArr,
+ typeArr, sizeArr, isArrayArr);
+ for (int i = 0; i < numAttrNames; i++) {
+ locArr[i] = boxShaderAttrLoc(nativeLocArr[i]);
+ }
+ }
+
+ native ShaderError useCgShaderProgram(long ctx, long shaderProgramId);
+
+ ShaderError useCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return useCgShaderProgram(unbox(ctx), unbox(shaderProgramId));
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GLSLShaderProgramRetained methods
+ //
+
+ // ShaderAttributeValue methods
+
+ native ShaderError setGLSLUniform1i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int value);
+
+ ShaderError setGLSLUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int value) {
+ return setGLSLUniform1i(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setGLSLUniform1f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float value);
+
+ ShaderError setGLSLUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float value) {
+ return setGLSLUniform1f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setGLSLUniform2i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ ShaderError setGLSLUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return setGLSLUniform2i(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setGLSLUniform2f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ ShaderError setGLSLUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return setGLSLUniform2f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setGLSLUniform3i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ ShaderError setGLSLUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return setGLSLUniform3i(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setGLSLUniform3f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ ShaderError setGLSLUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return setGLSLUniform3f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setGLSLUniform4i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ ShaderError setGLSLUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return setGLSLUniform4i(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setGLSLUniform4f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ ShaderError setGLSLUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return setGLSLUniform4f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setGLSLUniformMatrix3f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ ShaderError setGLSLUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return setGLSLUniformMatrix3f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ native ShaderError setGLSLUniformMatrix4f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ ShaderError setGLSLUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return setGLSLUniformMatrix4f(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ value);
+ }
+
+ // ShaderAttributeArray methods
+
+ native ShaderError setGLSLUniform1iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ ShaderError setGLSLUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return setGLSLUniform1iArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setGLSLUniform1fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setGLSLUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setGLSLUniform1fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setGLSLUniform2iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ ShaderError setGLSLUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return setGLSLUniform2iArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setGLSLUniform2fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setGLSLUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setGLSLUniform2fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setGLSLUniform3iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ ShaderError setGLSLUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return setGLSLUniform3iArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setGLSLUniform3fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setGLSLUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setGLSLUniform3fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setGLSLUniform4iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ ShaderError setGLSLUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return setGLSLUniform4iArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setGLSLUniform4fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setGLSLUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setGLSLUniform4fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setGLSLUniformMatrix3fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setGLSLUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setGLSLUniformMatrix3fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ native ShaderError setGLSLUniformMatrix4fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ ShaderError setGLSLUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return setGLSLUniformMatrix4fArray(unbox(ctx),
+ unbox(shaderProgramId),
+ unbox(uniformLocation),
+ numElements,
+ value);
+ }
+
+ // native interfaces for shader compilation, etc.
+ native ShaderError createGLSLShader(long ctx, int shaderType, long[] shaderId);
+
+ ShaderError createGLSLShader(Context ctx, int shaderType, ShaderId[] shaderId) {
+ long[] nativeId = new long[1];
+ ShaderError err = createGLSLShader(unbox(ctx), shaderType, nativeId);
+ shaderId[0] = boxShaderId(nativeId[0]);
+ return err;
+ }
+ native ShaderError destroyGLSLShader(long ctx, long shaderId);
+
+ ShaderError destroyGLSLShader(Context ctx, ShaderId shaderId) {
+ return destroyGLSLShader(unbox(ctx), unbox(shaderId));
+ }
+ native ShaderError compileGLSLShader(long ctx, long shaderId, String program);
+
+ ShaderError compileGLSLShader(Context ctx, ShaderId shaderId, String program) {
+ return compileGLSLShader(unbox(ctx), unbox(shaderId), program);
+ }
+
+ native ShaderError createGLSLShaderProgram(long ctx, long[] shaderProgramId);
+
+ ShaderError createGLSLShaderProgram(Context ctx, ShaderProgramId[] shaderProgramId) {
+ long[] nativeId = new long[1];
+ ShaderError err = createGLSLShaderProgram(unbox(ctx), nativeId);
+ shaderProgramId[0] = boxShaderProgramId(nativeId[0]);
+ return err;
+ }
+ native ShaderError destroyGLSLShaderProgram(long ctx, long shaderProgramId);
+
+ ShaderError destroyGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return destroyGLSLShaderProgram(unbox(ctx), unbox(shaderProgramId));
+ }
+ native ShaderError linkGLSLShaderProgram(long ctx, long shaderProgramId,
+ long[] shaderId);
+
+ ShaderError linkGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId,
+ ShaderId[] shaderIds) {
+ assert shaderIds != null;
+ long[] nativeIds = new long[shaderIds.length];
+ for (int i = 0; i < shaderIds.length; i++) {
+ nativeIds[i] = unbox(shaderIds[i]);
+ }
+ return linkGLSLShaderProgram(unbox(ctx), unbox(shaderProgramId),
+ nativeIds);
+ }
+ native ShaderError bindGLSLVertexAttrName(long ctx, long shaderProgramId,
+ String attrName, int attrIndex);
+
+ ShaderError bindGLSLVertexAttrName(Context ctx, ShaderProgramId shaderProgramId,
+ String attrName, int attrIndex) {
+ return bindGLSLVertexAttrName(unbox(ctx), unbox(shaderProgramId),
+ attrName, attrIndex);
+ }
+ native void lookupGLSLShaderAttrNames(long ctx, long shaderProgramId,
+ int numAttrNames, String[] attrNames, long[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr);
+
+ void lookupGLSLShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, ShaderAttrLoc[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr) {
+
+ assert numAttrNames == locArr.length;
+ long[] nativeLocArr = new long[numAttrNames];
+ for (int i = 0; i < numAttrNames; i++) {
+ // Initialize to invalid native location
+ nativeLocArr[i] = -1;
+ }
+ lookupGLSLShaderAttrNames(unbox(ctx), unbox(shaderProgramId),
+ numAttrNames, attrNames, nativeLocArr,
+ typeArr, sizeArr, isArrayArr);
+ for (int i = 0; i < numAttrNames; i++) {
+ locArr[i] = boxShaderAttrLoc(nativeLocArr[i]);
+ }
+ }
+
+ native ShaderError useGLSLShaderProgram(long ctx, long shaderProgramId);
+
+ ShaderError useGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return useGLSLShaderProgram(unbox(ctx), unbox(shaderProgramId));
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ImageComponent2DRetained methods
+ //
+
+ // free d3d surface referred to by id
+ native void freeD3DSurface(ImageComponent2DRetained image, int hashId);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Renderer methods
+ //
+
+ native void cleanupRenderer();
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ColoringAttributesRetained methods
+ //
+
+ native void updateColoringAttributes(long ctx,
+ float dRed, float dGreen, float dBlue,
+ float red, float green, float blue,
+ float alpha,
+ boolean lEnable,
+ int shadeModel);
+
+ void updateColoringAttributes(Context ctx,
+ float dRed, float dGreen, float dBlue,
+ float red, float green, float blue,
+ float alpha,
+ boolean lEnable,
+ int shadeModel) {
+ updateColoringAttributes(unbox(ctx),
+ dRed, dGreen, dBlue,
+ red, green, blue,
+ alpha,
+ lEnable,
+ shadeModel);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // DirectionalLightRetained methods
+ //
+
+ native void updateDirectionalLight(long ctx,
+ int lightSlot, float red, float green,
+ float blue, float x, float y, float z);
+
+ void updateDirectionalLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float x, float y, float z) {
+ updateDirectionalLight(unbox(ctx),
+ lightSlot, red, green,
+ blue, x, y, z);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PointLightRetained methods
+ //
+
+ native void updatePointLight(long ctx,
+ int lightSlot, float red, float green,
+ float blue, float ax, float ay, float az,
+ float px, float py, float pz);
+
+ void updatePointLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float ax, float ay, float az,
+ float px, float py, float pz) {
+ updatePointLight(unbox(ctx),
+ lightSlot, red, green,
+ blue, ax, ay, az,
+ px, py, pz);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // SpotLightRetained methods
+ //
+
+ native void updateSpotLight(long ctx,
+ int lightSlot, float red, float green,
+ float blue, float ax, float ay, float az,
+ float px, float py, float pz, float spreadAngle,
+ float concentration, float dx, float dy,
+ float dz);
+
+ void updateSpotLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float ax, float ay, float az,
+ float px, float py, float pz, float spreadAngle,
+ float concentration, float dx, float dy,
+ float dz) {
+ updateSpotLight(unbox(ctx),
+ lightSlot, red, green,
+ blue, ax, ay, az,
+ px, py, pz, spreadAngle,
+ concentration, dx, dy,
+ dz);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ExponentialFogRetained methods
+ //
+
+ native void updateExponentialFog(long ctx,
+ float red, float green, float blue,
+ float density);
+
+ void updateExponentialFog(Context ctx,
+ float red, float green, float blue,
+ float density) {
+ updateExponentialFog(unbox(ctx),
+ red, green, blue,
+ density);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // LinearFogRetained methods
+ //
+
+ native void updateLinearFog(long ctx,
+ float red, float green, float blue,
+ double fdist, double bdist);
+
+ void updateLinearFog(Context ctx,
+ float red, float green, float blue,
+ double fdist, double bdist) {
+ updateLinearFog(unbox(ctx),
+ red, green, blue,
+ fdist, bdist);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // LineAttributesRetained methods
+ //
+
+ native void updateLineAttributes(long ctx,
+ float lineWidth, int linePattern,
+ int linePatternMask,
+ int linePatternScaleFactor,
+ boolean lineAntialiasing);
+
+ void updateLineAttributes(Context ctx,
+ float lineWidth, int linePattern,
+ int linePatternMask,
+ int linePatternScaleFactor,
+ boolean lineAntialiasing) {
+ updateLineAttributes(unbox(ctx),
+ lineWidth, linePattern,
+ linePatternMask,
+ linePatternScaleFactor,
+ lineAntialiasing);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // MaterialRetained methods
+ //
+
+ native void updateMaterial(long ctx,
+ float red, float green, float blue, float alpha,
+ float ared, float agreen, float ablue,
+ float ered, float egreen, float eblue,
+ float dred, float dgreen, float dblue,
+ float sred, float sgreen, float sblue,
+ float shininess, int colorTarget, boolean enable);
+
+ void updateMaterial(Context ctx,
+ float red, float green, float blue, float alpha,
+ float ared, float agreen, float ablue,
+ float ered, float egreen, float eblue,
+ float dred, float dgreen, float dblue,
+ float sred, float sgreen, float sblue,
+ float shininess, int colorTarget, boolean enable) {
+ updateMaterial(unbox(ctx),
+ red, green, blue, alpha,
+ ared, agreen, ablue,
+ ered, egreen, eblue,
+ dred, dgreen, dblue,
+ sred, sgreen, sblue,
+ shininess, colorTarget, enable);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ModelClipRetained methods
+ //
+
+ native void updateModelClip(long ctx, int planeNum, boolean enableFlag,
+ double A, double B, double C, double D);
+
+ void updateModelClip(Context ctx, int planeNum, boolean enableFlag,
+ double A, double B, double C, double D) {
+ updateModelClip(unbox(ctx), planeNum, enableFlag,
+ A, B, C, D);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PointAttributesRetained methods
+ //
+
+ native void updatePointAttributes(long ctx, float pointSize, boolean pointAntialiasing);
+
+ void updatePointAttributes(Context ctx, float pointSize, boolean pointAntialiasing) {
+ updatePointAttributes(unbox(ctx), pointSize, pointAntialiasing);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PolygonAttributesRetained methods
+ //
+
+ native void updatePolygonAttributes(long ctx,
+ int polygonMode, int cullFace,
+ boolean backFaceNormalFlip,
+ float polygonOffset,
+ float polygonOffsetFactor);
+
+ void updatePolygonAttributes(Context ctx,
+ int polygonMode, int cullFace,
+ boolean backFaceNormalFlip,
+ float polygonOffset,
+ float polygonOffsetFactor) {
+ updatePolygonAttributes(unbox(ctx),
+ polygonMode, cullFace,
+ backFaceNormalFlip,
+ polygonOffset,
+ polygonOffsetFactor);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // RenderingAttributesRetained methods
+ //
+
+ // TODO : Need to handle stencil operation on the native side -- Chien
+ native void updateRenderingAttributes(long ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride,
+ boolean depthBufferEnable,
+ boolean depthBufferWriteEnable,
+ int depthTestFunction,
+ float alphaTestValue, int alphaTestFunction,
+ boolean ignoreVertexColors,
+ boolean rasterOpEnable, int rasterOp,
+ boolean userStencilAvailable, boolean stencilEnable,
+ int stencilFailOp, int stencilZFailOp, int stencilZPassOp,
+ int stencilFunction, int stencilReferenceValue,
+ int stencilCompareMask, int stencilWriteMask );
+
+ void updateRenderingAttributes(Context ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride,
+ boolean depthBufferEnable,
+ boolean depthBufferWriteEnable,
+ int depthTestFunction,
+ float alphaTestValue, int alphaTestFunction,
+ boolean ignoreVertexColors,
+ boolean rasterOpEnable, int rasterOp,
+ boolean userStencilAvailable, boolean stencilEnable,
+ int stencilFailOp, int stencilZFailOp, int stencilZPassOp,
+ int stencilFunction, int stencilReferenceValue,
+ int stencilCompareMask, int stencilWriteMask ) {
+ updateRenderingAttributes(unbox(ctx),
+ depthBufferWriteEnableOverride,
+ depthBufferEnableOverride,
+ depthBufferEnable,
+ depthBufferWriteEnable,
+ depthTestFunction,
+ alphaTestValue, alphaTestFunction,
+ ignoreVertexColors,
+ rasterOpEnable, rasterOp,
+ userStencilAvailable, stencilEnable,
+ stencilFailOp, stencilZFailOp, stencilZPassOp,
+ stencilFunction, stencilReferenceValue,
+ stencilCompareMask, stencilWriteMask );
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TexCoordGenerationRetained methods
+ //
+
+ /**
+ * This method updates the native context:
+ * trans contains eyeTovworld transform in d3d
+ * trans contains vworldToEye transform in ogl
+ */
+ native void updateTexCoordGeneration(long ctx,
+ boolean enable, int genMode, int format,
+ float planeSx, float planeSy, float planeSz, float planeSw,
+ float planeTx, float planeTy, float planeTz, float planeTw,
+ float planeRx, float planeRy, float planeRz, float planeRw,
+ float planeQx, float planeQy, float planeQz, float planeQw,
+ double[] trans);
+
+ void updateTexCoordGeneration(Context ctx,
+ boolean enable, int genMode, int format,
+ float planeSx, float planeSy, float planeSz, float planeSw,
+ float planeTx, float planeTy, float planeTz, float planeTw,
+ float planeRx, float planeRy, float planeRz, float planeRw,
+ float planeQx, float planeQy, float planeQz, float planeQw,
+ double[] trans) {
+ updateTexCoordGeneration(unbox(ctx),
+ enable, genMode, format,
+ planeSx, planeSy, planeSz, planeSw,
+ planeTx, planeTy, planeTz, planeTw,
+ planeRx, planeRy, planeRz, planeRw,
+ planeQx, planeQy, planeQz, planeQw,
+ trans);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TransparencyAttributesRetained methods
+ //
+
+ native void updateTransparencyAttributes(long ctx,
+ float alpha, int geometryType,
+ int polygonMode,
+ boolean lineAA, boolean pointAA,
+ int transparencyMode,
+ int srcBlendFunction,
+ int dstBlendFunction);
+
+ void updateTransparencyAttributes(Context ctx,
+ float alpha, int geometryType,
+ int polygonMode,
+ boolean lineAA, boolean pointAA,
+ int transparencyMode,
+ int srcBlendFunction,
+ int dstBlendFunction) {
+ updateTransparencyAttributes(unbox(ctx),
+ alpha, geometryType,
+ polygonMode,
+ lineAA, pointAA,
+ transparencyMode,
+ srcBlendFunction,
+ dstBlendFunction);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureAttributesRetained methods
+ //
+
+ native void updateTextureAttributes(long ctx,
+ double[] transform, boolean isIdentity, int textureMode,
+ int perspCorrectionMode, float red,
+ float green, float blue, float alpha,
+ int textureFormat);
+
+ void updateTextureAttributes(Context ctx,
+ double[] transform, boolean isIdentity, int textureMode,
+ int perspCorrectionMode, float red,
+ float green, float blue, float alpha,
+ int textureFormat) {
+ updateTextureAttributes(unbox(ctx),
+ transform, isIdentity, textureMode,
+ perspCorrectionMode, red,
+ green, blue, alpha,
+ textureFormat);
+ }
+
+ native void updateRegisterCombiners(long ctx,
+ double[] transform, boolean isIdentity, int textureMode,
+ int perspCorrectionMode, float red,
+ float green, float blue, float alpha,
+ int textureFormat,
+ int combineRgbMode, int combineAlphaMode,
+ int[] combineRgbSrc, int[] combineAlphaSrc,
+ int[] combineRgbFcn, int[] combineAlphaFcn,
+ int combineRgbScale, int combineAlphaScale);
+
+ void updateRegisterCombiners(Context ctx,
+ double[] transform, boolean isIdentity, int textureMode,
+ int perspCorrectionMode, float red,
+ float green, float blue, float alpha,
+ int textureFormat,
+ int combineRgbMode, int combineAlphaMode,
+ int[] combineRgbSrc, int[] combineAlphaSrc,
+ int[] combineRgbFcn, int[] combineAlphaFcn,
+ int combineRgbScale, int combineAlphaScale) {
+ updateRegisterCombiners(unbox(ctx),
+ transform, isIdentity, textureMode,
+ perspCorrectionMode, red,
+ green, blue, alpha,
+ textureFormat,
+ combineRgbMode, combineAlphaMode,
+ combineRgbSrc, combineAlphaSrc,
+ combineRgbFcn, combineAlphaFcn,
+ combineRgbScale, combineAlphaScale);
+ }
+
+ native void updateTextureColorTable(long ctx, int numComponents,
+ int colorTableSize,
+ int[] colorTable);
+
+ void updateTextureColorTable(Context ctx, int numComponents,
+ int colorTableSize,
+ int[] colorTable) {
+ updateTextureColorTable(unbox(ctx), numComponents,
+ colorTableSize,
+ colorTable);
+ }
+
+ native void updateCombiner(long ctx,
+ int combineRgbMode, int combineAlphaMode,
+ int[] combineRgbSrc, int[] combineAlphaSrc,
+ int[] combineRgbFcn, int[] combineAlphaFcn,
+ int combineRgbScale, int combineAlphaScale);
+
+ void updateCombiner(Context ctx,
+ int combineRgbMode, int combineAlphaMode,
+ int[] combineRgbSrc, int[] combineAlphaSrc,
+ int[] combineRgbFcn, int[] combineAlphaFcn,
+ int combineRgbScale, int combineAlphaScale) {
+ updateCombiner(unbox(ctx),
+ combineRgbMode, combineAlphaMode,
+ combineRgbSrc, combineAlphaSrc,
+ combineRgbFcn, combineAlphaFcn,
+ combineRgbScale, combineAlphaScale);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureUnitStateRetained methods
+ //
+
+ native void updateTextureUnitState(long ctx, int unitIndex, boolean enableFlag);
+
+ void updateTextureUnitState(Context ctx, int unitIndex, boolean enableFlag) {
+ updateTextureUnitState(unbox(ctx), unitIndex, enableFlag);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureRetained methods
+ // Texture2DRetained methods
+ //
+
+ native void bindTexture2D(long ctx, int objectId, boolean enable);
+
+ void bindTexture2D(Context ctx, int objectId, boolean enable) {
+ bindTexture2D(unbox(ctx), objectId, enable);
+ }
+
+ native void updateTexture2DImage(long ctx,
+ int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int imageDataType, Object data);
+
+ void updateTexture2DImage(Context ctx,
+ int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int imageDataType, Object data) {
+ updateTexture2DImage(unbox(ctx),
+ numLevels, level,
+ textureFormat, imageFormat,
+ width, height,
+ boundaryWidth,
+ imageDataType, data);
+ }
+
+ native void updateTexture2DSubImage(long ctx,
+ int level, int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int imageDataType, Object data);
+
+ void updateTexture2DSubImage(Context ctx,
+ int level, int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int imageDataType, Object data) {
+ updateTexture2DSubImage(unbox(ctx),
+ level, xoffset, yoffset,
+ textureFormat, imageFormat,
+ imgXOffset, imgYOffset,
+ tilew, width, height,
+ imageDataType, data);
+ }
+
+ native void updateTexture2DLodRange(long ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod);
+
+ void updateTexture2DLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+ updateTexture2DLodRange(unbox(ctx),
+ baseLevel, maximumLevel,
+ minimumLod, maximumLod);
+ }
+
+ native void updateTexture2DLodOffset(long ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ);
+
+ void updateTexture2DLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ) {
+ updateTexture2DLodOffset(unbox(ctx),
+ lodOffsetX, lodOffsetY,
+ lodOffsetZ);
+ }
+
+ native void updateTexture2DBoundary(long ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha);
+
+ void updateTexture2DBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha) {
+ updateTexture2DBoundary(unbox(ctx),
+ boundaryModeS, boundaryModeT,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+ }
+
+ native void updateTexture2DFilterModes(long ctx,
+ int minFilter, int magFilter);
+
+ void updateTexture2DFilterModes(Context ctx,
+ int minFilter, int magFilter) {
+ updateTexture2DFilterModes(unbox(ctx),
+ minFilter, magFilter);
+ }
+
+ native void updateTexture2DSharpenFunc(long ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts);
+
+ void updateTexture2DSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
+ updateTexture2DSharpenFunc(unbox(ctx),
+ numSharpenTextureFuncPts,
+ sharpenTextureFuncPts);
+ }
+
+ native void updateTexture2DFilter4Func(long ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts);
+
+ void updateTexture2DFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+ updateTexture2DFilter4Func(unbox(ctx),
+ numFilter4FuncPts,
+ filter4FuncPts);
+ }
+
+ native void updateTexture2DAnisotropicFilter(long ctx, float degree);
+
+ void updateTexture2DAnisotropicFilter(Context ctx, float degree) {
+ updateTexture2DAnisotropicFilter(unbox(ctx), degree);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Texture3DRetained methods
+ //
+
+ native void bindTexture3D(long ctx, int objectId, boolean enable);
+
+ void bindTexture3D(Context ctx, int objectId, boolean enable) {
+ bindTexture3D(unbox(ctx), objectId, enable);
+ }
+
+ native void updateTexture3DImage(long ctx,
+ int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height, int depth,
+ int boundaryWidth,
+ int imageDataType, Object imageData);
+
+ void updateTexture3DImage(Context ctx,
+ int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height, int depth,
+ int boundaryWidth,
+ int imageDataType, Object imageData) {
+ updateTexture3DImage(unbox(ctx),
+ numLevels, level,
+ textureFormat, imageFormat,
+ width, height, depth,
+ boundaryWidth,
+ imageDataType, imageData);
+ }
+
+ native void updateTexture3DSubImage(long ctx,
+ int level,
+ int xoffset, int yoffset, int zoffset,
+ int textureFormat, int imageFormat,
+ int imgXoffset, int imgYoffset, int imgZoffset,
+ int tilew, int tileh,
+ int width, int height, int depth,
+ int imageDataType, Object imageData);
+
+ void updateTexture3DSubImage(Context ctx,
+ int level,
+ int xoffset, int yoffset, int zoffset,
+ int textureFormat, int imageFormat,
+ int imgXoffset, int imgYoffset, int imgZoffset,
+ int tilew, int tileh,
+ int width, int height, int depth,
+ int imageDataType, Object imageData) {
+ updateTexture3DSubImage(unbox(ctx),
+ level,
+ xoffset, yoffset, zoffset,
+ textureFormat, imageFormat,
+ imgXoffset, imgYoffset, imgZoffset,
+ tilew, tileh,
+ width, height, depth,
+ imageDataType, imageData);
+ }
+
+ native void updateTexture3DLodRange(long ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod);
+
+ void updateTexture3DLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+ updateTexture3DLodRange(unbox(ctx),
+ baseLevel, maximumLevel,
+ minimumLod, maximumLod);
+ }
+
+ native void updateTexture3DLodOffset(long ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ);
+
+ void updateTexture3DLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ) {
+ updateTexture3DLodOffset(unbox(ctx),
+ lodOffsetX, lodOffsetY,
+ lodOffsetZ);
+ }
+
+ native void updateTexture3DBoundary(long ctx,
+ int boundaryModeS, int boundaryModeT,
+ int boundaryModeR, float boundaryRed,
+ float boundaryGreen, float boundaryBlue,
+ float boundaryAlpha);
+
+
+ void updateTexture3DBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ int boundaryModeR, float boundaryRed,
+ float boundaryGreen, float boundaryBlue,
+ float boundaryAlpha) {
+ updateTexture3DBoundary(unbox(ctx),
+ boundaryModeS, boundaryModeT,
+ boundaryModeR, boundaryRed,
+ boundaryGreen, boundaryBlue,
+ boundaryAlpha);
+ }
+
+ native void updateTexture3DFilterModes(long ctx,
+ int minFilter, int magFilter);
+
+ void updateTexture3DFilterModes(Context ctx,
+ int minFilter, int magFilter) {
+ updateTexture3DFilterModes(unbox(ctx),
+ minFilter, magFilter);
+ }
+
+ native void updateTexture3DSharpenFunc(long ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts);
+
+ void updateTexture3DSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
+ updateTexture3DSharpenFunc(unbox(ctx),
+ numSharpenTextureFuncPts,
+ sharpenTextureFuncPts);
+ }
+
+ native void updateTexture3DFilter4Func(long ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts);
+
+ void updateTexture3DFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+ updateTexture3DFilter4Func(unbox(ctx),
+ numFilter4FuncPts,
+ filter4FuncPts);
+ }
+
+ native void updateTexture3DAnisotropicFilter(long ctx, float degree);
+
+ void updateTexture3DAnisotropicFilter(Context ctx, float degree) {
+ updateTexture3DAnisotropicFilter(unbox(ctx), degree);
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureCubeMapRetained methods
+ //
+
+ native void bindTextureCubeMap(long ctx, int objectId, boolean enable);
+
+ void bindTextureCubeMap(Context ctx, int objectId, boolean enable) {
+ bindTextureCubeMap(unbox(ctx), objectId, enable);
+ }
+
+ native void updateTextureCubeMapImage(long ctx,
+ int face, int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int imageDataType, Object imageData);
+
+ void updateTextureCubeMapImage(Context ctx,
+ int face, int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int imageDataType, Object imageData) {
+ updateTextureCubeMapImage(unbox(ctx),
+ face, numLevels, level,
+ textureFormat, imageFormat,
+ width, height,
+ boundaryWidth,
+ imageDataType, imageData);
+ }
+
+ native void updateTextureCubeMapSubImage(long ctx,
+ int face, int level, int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int imageDataType, Object imageData);
+
+ void updateTextureCubeMapSubImage(Context ctx,
+ int face, int level, int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int imageDataType, Object imageData) {
+ updateTextureCubeMapSubImage(unbox(ctx),
+ face, level, xoffset, yoffset,
+ textureFormat, imageFormat,
+ imgXOffset, imgYOffset,
+ tilew, width, height,
+ imageDataType, imageData);
+ }
+
+ native void updateTextureCubeMapLodRange(long ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod);
+
+ void updateTextureCubeMapLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+ updateTextureCubeMapLodRange(unbox(ctx),
+ baseLevel, maximumLevel,
+ minimumLod, maximumLod);
+ }
+
+ native void updateTextureCubeMapLodOffset(long ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ);
+
+ void updateTextureCubeMapLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ) {
+ updateTextureCubeMapLodOffset(unbox(ctx),
+ lodOffsetX, lodOffsetY,
+ lodOffsetZ);
+ }
+
+ native void updateTextureCubeMapBoundary(long ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha);
+
+ void updateTextureCubeMapBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha) {
+ updateTextureCubeMapBoundary(unbox(ctx),
+ boundaryModeS, boundaryModeT,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+ }
+
+ native void updateTextureCubeMapFilterModes(long ctx,
+ int minFilter, int magFilter);
+
+ void updateTextureCubeMapFilterModes(Context ctx,
+ int minFilter, int magFilter) {
+ updateTextureCubeMapFilterModes(unbox(ctx),
+ minFilter, magFilter);
+ }
+
+ native void updateTextureCubeMapSharpenFunc(long ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts);
+
+ void updateTextureCubeMapSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
+ updateTextureCubeMapSharpenFunc(unbox(ctx),
+ numSharpenTextureFuncPts,
+ sharpenTextureFuncPts);
+ }
+
+ native void updateTextureCubeMapFilter4Func(long ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts);
+
+ void updateTextureCubeMapFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+ updateTextureCubeMapFilter4Func(unbox(ctx),
+ numFilter4FuncPts,
+ filter4FuncPts);
+ }
+
+ native void updateTextureCubeMapAnisotropicFilter(long ctx, float degree);
+
+ void updateTextureCubeMapAnisotropicFilter(Context ctx, float degree) {
+ updateTextureCubeMapAnisotropicFilter(unbox(ctx), degree);
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // MasterControl methods
+ //
+
+ // Method to return the AWT object
+ native long getAWT();
+
+ // Method to initialize the native J3D library
+ native boolean initializeJ3D(boolean disableXinerama);
+
+ // Maximum lights supported by the native API
+ native int getMaximumLights();
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Canvas3D methods
+ //
+
+ // This is the native method for creating the underlying graphics context.
+ native long createNewContext(Canvas3D cv, long display, long drawable,
+ long fbConfig, long shareCtx, boolean isSharedCtx,
+ boolean offScreen,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable);
+
+ // This is the native method for creating the underlying graphics context.
+ Context createNewContext(Canvas3D cv, long display, Drawable drawable,
+ long fbConfig, Context shareCtx, boolean isSharedCtx,
+ boolean offScreen,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable) {
+
+ long nativeCtx = createNewContext(cv, display, unbox(drawable),
+ fbConfig, unbox(shareCtx), isSharedCtx,
+ offScreen,
+ glslLibraryAvailable,
+ cgLibraryAvailable);
+
+ return boxContext(nativeCtx);
+ }
+
+ native void createQueryContext(Canvas3D cv, long display, long drawable,
+ long fbConfig, boolean offScreen, int width, int height,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable);
+
+ void createQueryContext(Canvas3D cv, long display, Drawable drawable,
+ long fbConfig, boolean offScreen, int width, int height,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable) {
+
+ createQueryContext(cv, display, unbox(drawable),
+ fbConfig, offScreen, width, height,
+ glslLibraryAvailable,
+ cgLibraryAvailable);
+ }
+
+ // This is the native for creating offscreen buffer
+ native long createOffScreenBuffer(Canvas3D cv, long ctx, long display, long fbConfig, int width, int height);
+
+ Drawable createOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, int width, int height) {
+ long nativeDrawable = createOffScreenBuffer(cv, unbox(ctx), display, fbConfig, width, height);
+ return boxDrawable(nativeDrawable);
+ }
+
+ native void destroyOffScreenBuffer(Canvas3D cv, long ctx, long display, long fbConfig, long drawable);
+
+ void destroyOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, Drawable drawable) {
+ destroyOffScreenBuffer(cv, unbox(ctx), display, fbConfig, unbox(drawable));
+ }
+
+ // This is the native for reading the image from the offscreen buffer
+ native void readOffScreenBuffer(Canvas3D cv, long ctx, int format, int type, Object data, int width, int height);
+
+ void readOffScreenBuffer(Canvas3D cv, Context ctx, int format, int type, Object data, int width, int height) {
+ readOffScreenBuffer(cv, unbox(ctx), format, type, data, width, height);
+ }
+
+ // The native method for swapBuffers
+ native int swapBuffers(Canvas3D cv, long ctx, long dpy, long drawable);
+
+ int swapBuffers(Canvas3D cv, Context ctx, long dpy, Drawable drawable) {
+ return swapBuffers(cv, unbox(ctx), dpy, unbox(drawable));
+ }
+
+
+ // notify D3D that Canvas is resize
+ native int resizeD3DCanvas(Canvas3D cv, long ctx);
+
+ int resizeD3DCanvas(Canvas3D cv, Context ctx) {
+ return resizeD3DCanvas(cv, unbox(ctx));
+ }
+
+
+ // notify D3D to toggle between FullScreen and window mode
+ native int toggleFullScreenMode(Canvas3D cv, long ctx);
+
+ int toggleFullScreenMode(Canvas3D cv, Context ctx) {
+ return toggleFullScreenMode(cv, unbox(ctx));
+ }
+
+
+ // native method for setting Material when no material is present
+ native void updateMaterialColor(long ctx, float r, float g, float b, float a);
+
+ void updateMaterialColor(Context ctx, float r, float g, float b, float a) {
+ updateMaterialColor(unbox(ctx), r, g, b, a);
+ }
+
+
+ native void destroyContext(long display, long drawable, long ctx);
+
+ void destroyContext(long display, Drawable drawable, Context ctx) {
+ assert display != 0 || VirtualUniverse.mc.isWindows();
+ assert ctx != null;
+ assert drawable != null;
+ destroyContext(display, unbox(drawable), unbox(ctx));
+ }
+
+
+ // This is the native method for doing accumulation.
+ native void accum(long ctx, float value);
+
+ void accum(Context ctx, float value) {
+ accum(unbox(ctx), value);
+ }
+
+
+ // This is the native method for doing accumulation return.
+ native void accumReturn(long ctx);
+
+ void accumReturn(Context ctx) {
+ accumReturn(unbox(ctx));
+ }
+
+
+ // This is the native method for clearing the accumulation buffer.
+ native void clearAccum(long ctx);
+
+ void clearAccum(Context ctx) {
+ clearAccum(unbox(ctx));
+ }
+
+
+ // This is the native method for getting the number of lights the underlying
+ // native library can support.
+ native int getNumCtxLights(long ctx);
+
+ int getNumCtxLights(Context ctx) {
+ return getNumCtxLights(unbox(ctx));
+ }
+
+
+ // Native method for decal 1st child setup
+ native boolean decal1stChildSetup(long ctx);
+
+ boolean decal1stChildSetup(Context ctx) {
+ return decal1stChildSetup(unbox(ctx));
+ }
+
+
+ // Native method for decal nth child setup
+ native void decalNthChildSetup(long ctx);
+
+ void decalNthChildSetup(Context ctx) {
+ decalNthChildSetup(unbox(ctx));
+ }
+
+
+ // Native method for decal reset
+ native void decalReset(long ctx, boolean depthBufferEnable);
+
+ void decalReset(Context ctx, boolean depthBufferEnable) {
+ decalReset(unbox(ctx), depthBufferEnable);
+ }
+
+
+ // Native method for decal reset
+ native void ctxUpdateEyeLightingEnable(long ctx, boolean localEyeLightingEnable);
+
+ void ctxUpdateEyeLightingEnable(Context ctx, boolean localEyeLightingEnable) {
+ ctxUpdateEyeLightingEnable(unbox(ctx), localEyeLightingEnable);
+ }
+
+
+ // The following three methods are used in multi-pass case
+
+ // native method for setting blend color
+ native void setBlendColor(long ctx, float red, float green,
+ float blue, float alpha);
+
+ void setBlendColor(Context ctx, float red, float green,
+ float blue, float alpha) {
+ setBlendColor(unbox(ctx), red, green,
+ blue, alpha);
+ }
+
+
+ // native method for setting blend func
+ native void setBlendFunc(long ctx, int src, int dst);
+
+ void setBlendFunc(Context ctx, int src, int dst) {
+ setBlendFunc(unbox(ctx), src, dst);
+ }
+
+
+ // native method for setting fog enable flag
+ native void setFogEnableFlag(long ctx, boolean enableFlag);
+
+ void setFogEnableFlag(Context ctx, boolean enableFlag) {
+ setFogEnableFlag(unbox(ctx), enableFlag);
+ }
+
+
+ // Setup the full scene antialising in D3D and ogl when GL_ARB_multisamle supported
+ native void setFullSceneAntialiasing(long ctx, boolean enable);
+
+ void setFullSceneAntialiasing(Context ctx, boolean enable) {
+ setFullSceneAntialiasing(unbox(ctx), enable);
+ }
+
+
+ native void setGlobalAlpha(long ctx, float alpha);
+
+ void setGlobalAlpha(Context ctx, float alpha) {
+ setGlobalAlpha(unbox(ctx), alpha);
+ }
+
+
+ // Native method to update separate specular color control
+ native void updateSeparateSpecularColorEnable(long ctx, boolean control);
+
+ void updateSeparateSpecularColorEnable(Context ctx, boolean control) {
+ updateSeparateSpecularColorEnable(unbox(ctx), control);
+ }
+
+
+ // Initialization for D3D when scene begin
+ native void beginScene(long ctx);
+
+ void beginScene(Context ctx) {
+ beginScene(unbox(ctx));
+ }
+
+ native void endScene(long ctx);
+
+ void endScene(Context ctx) {
+ endScene(unbox(ctx));
+ }
+
+
+ // True under Solaris,
+ // False under windows when display mode <= 8 bit
+ native boolean validGraphicsMode();
+
+ // native method for setting light enables
+ native void setLightEnables(long ctx, long enableMask, int maxLights);
+
+ void setLightEnables(Context ctx, long enableMask, int maxLights) {
+ setLightEnables(unbox(ctx), enableMask, maxLights);
+ }
+
+
+ // native method for setting scene ambient
+ native void setSceneAmbient(long ctx, float red, float green, float blue);
+
+ void setSceneAmbient(Context ctx, float red, float green, float blue) {
+ setSceneAmbient(unbox(ctx), red, green, blue);
+ }
+
+
+ // native method for disabling fog
+ native void disableFog(long ctx);
+
+ void disableFog(Context ctx) {
+ disableFog(unbox(ctx));
+ }
+
+
+ // native method for disabling modelClip
+ native void disableModelClip(long ctx);
+
+ void disableModelClip(Context ctx) {
+ disableModelClip(unbox(ctx));
+ }
+
+
+ // native method for setting default RenderingAttributes
+ native void resetRenderingAttributes(long ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride);
+
+ void resetRenderingAttributes(Context ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride) {
+ resetRenderingAttributes(unbox(ctx),
+ depthBufferWriteEnableOverride,
+ depthBufferEnableOverride);
+ }
+
+
+ // native method for setting default texture
+ native void resetTextureNative(long ctx, int texUnitIndex);
+
+ void resetTextureNative(Context ctx, int texUnitIndex) {
+ resetTextureNative(unbox(ctx), texUnitIndex);
+ }
+
+
+ // native method for activating a particular texture unit
+ native void activeTextureUnit(long ctx, int texUnitIndex);
+
+ void activeTextureUnit(Context ctx, int texUnitIndex) {
+ activeTextureUnit(unbox(ctx), texUnitIndex);
+ }
+
+
+ // native method for setting default TexCoordGeneration
+ native void resetTexCoordGeneration(long ctx);
+
+ void resetTexCoordGeneration(Context ctx) {
+ resetTexCoordGeneration(unbox(ctx));
+ }
+
+
+ // native method for setting default TextureAttributes
+ native void resetTextureAttributes(long ctx);
+
+ void resetTextureAttributes(Context ctx) {
+ resetTextureAttributes(unbox(ctx));
+ }
+
+
+ // native method for setting default PolygonAttributes
+ native void resetPolygonAttributes(long ctx);
+
+ void resetPolygonAttributes(Context ctx) {
+ resetPolygonAttributes(unbox(ctx));
+ }
+
+
+ // native method for setting default LineAttributes
+ native void resetLineAttributes(long ctx);
+
+ void resetLineAttributes(Context ctx) {
+ resetLineAttributes(unbox(ctx));
+ }
+
+
+ // native method for setting default PointAttributes
+ native void resetPointAttributes(long ctx);
+
+ void resetPointAttributes(Context ctx) {
+ resetPointAttributes(unbox(ctx));
+ }
+
+
+ // native method for setting default TransparencyAttributes
+ native void resetTransparency(long ctx, int geometryType,
+ int polygonMode, boolean lineAA,
+ boolean pointAA);
+
+ void resetTransparency(Context ctx, int geometryType,
+ int polygonMode, boolean lineAA,
+ boolean pointAA) {
+ resetTransparency(unbox(ctx), geometryType,
+ polygonMode, lineAA,
+ pointAA);
+ }
+
+
+ // native method for setting default ColoringAttributes
+ native void resetColoringAttributes(long ctx,
+ float r, float g,
+ float b, float a,
+ boolean enableLight);
+
+ void resetColoringAttributes(Context ctx,
+ float r, float g,
+ float b, float a,
+ boolean enableLight) {
+ resetColoringAttributes(unbox(ctx),
+ r, g,
+ b, a,
+ enableLight);
+ }
+
+ /**
+ * This native method makes sure that the rendering for this canvas
+ * gets done now.
+ */
+ native void syncRender(long ctx, boolean wait);
+
+ void syncRender(Context ctx, boolean wait) {
+ syncRender(unbox(ctx), wait);
+ }
+
+
+ // The native method that sets this ctx to be the current one
+ native boolean useCtx(long ctx, long display, long drawable);
+
+ boolean useCtx(Context ctx, long display, Drawable drawable) {
+ assert display != 0 || VirtualUniverse.mc.isWindows();
+ return useCtx(unbox(ctx), display, unbox(drawable));
+ }
+
+ native void clear(long ctx, float r, float g, float b);
+
+ void clear(Context ctx, float r, float g, float b) {
+ clear(unbox(ctx), r, g, b);
+
+ }
+
+ native void textureFillBackground(long ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY);
+
+ void textureFillBackground(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY) {
+ textureFillBackground(unbox(ctx), texMinU, texMaxU, texMinV, texMaxV,
+ mapMinX, mapMaxX, mapMinY, mapMaxY);
+ }
+
+ native void textureFillRaster(long ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, float mapZ, float alpha);
+
+ void textureFillRaster(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, float mapZ, float alpha) {
+ textureFillRaster(unbox(ctx), texMinU, texMaxU, texMinV, texMaxV,
+ mapMinX, mapMaxX, mapMinY, mapMaxY, mapZ, alpha);
+ }
+
+ native void executeRasterDepth(long ctx, float posX, float posY, float posZ,
+ int srcOffsetX, int srcOffsetY, int rasterWidth, int rasterHeight,
+ int depthWidth, int depthHeight, int depthType, Object depthData);
+
+ void executeRasterDepth(Context ctx, float posX, float posY, float posZ,
+ int srcOffsetX, int srcOffsetY, int rasterWidth, int rasterHeight,
+ int depthWidth, int depthHeight, int depthType, Object depthData) {
+ executeRasterDepth(unbox(ctx), posX, posY, posZ, srcOffsetX, srcOffsetY,
+ rasterWidth, rasterHeight, depthWidth, depthHeight, depthType, depthData);
+ }
+
+ // The native method for setting the ModelView matrix.
+ native void setModelViewMatrix(long ctx, double[] viewMatrix, double[] modelMatrix);
+
+ void setModelViewMatrix(Context ctx, double[] viewMatrix, double[] modelMatrix) {
+ setModelViewMatrix(unbox(ctx), viewMatrix, modelMatrix);
+ }
+
+
+ // The native method for setting the Projection matrix.
+ native void setProjectionMatrix(long ctx, double[] projMatrix);
+
+ void setProjectionMatrix(Context ctx, double[] projMatrix) {
+ setProjectionMatrix(unbox(ctx), projMatrix);
+ }
+
+
+ // The native method for setting the Viewport.
+ native void setViewport(long ctx, int x, int y, int width, int height);
+
+ void setViewport(Context ctx, int x, int y, int width, int height) {
+ setViewport(unbox(ctx), x, y, width, height);
+ }
+
+
+ // used for display Lists
+ native void newDisplayList(long ctx, int displayListId);
+
+ void newDisplayList(Context ctx, int displayListId) {
+ newDisplayList(unbox(ctx), displayListId);
+ }
+
+ native void endDisplayList(long ctx);
+
+ void endDisplayList(Context ctx) {
+ endDisplayList(unbox(ctx));
+ }
+
+ native void callDisplayList(long ctx, int id, boolean isNonUniformScale);
+
+ void callDisplayList(Context ctx, int id, boolean isNonUniformScale) {
+ callDisplayList(unbox(ctx), id, isNonUniformScale);
+ }
+
+
+ native void freeDisplayList(long ctx, int id);
+
+ void freeDisplayList(Context ctx, int id) {
+ freeDisplayList(unbox(ctx), id);
+ }
+
+ native void freeTexture(long ctx, int id);
+
+ void freeTexture(Context ctx, int id) {
+ freeTexture(unbox(ctx), id);
+ }
+
+ native void texturemapping(long ctx,
+ int px, int py,
+ int xmin, int ymin, int xmax, int ymax,
+ int texWidth, int texHeight,
+ int rasWidth,
+ int format, int objectId,
+ byte[] image,
+ int winWidth, int winHeight);
+
+ void texturemapping(Context ctx,
+ int px, int py,
+ int xmin, int ymin, int xmax, int ymax,
+ int texWidth, int texHeight,
+ int rasWidth,
+ int format, int objectId,
+ byte[] image,
+ int winWidth, int winHeight) {
+ texturemapping(unbox(ctx),
+ px, py,
+ xmin, ymin, xmax, ymax,
+ texWidth, texHeight,
+ rasWidth,
+ format, objectId,
+ image,
+ winWidth, winHeight);
+ }
+
+
+ native boolean initTexturemapping(long ctx, int texWidth,
+ int texHeight, int objectId);
+
+ boolean initTexturemapping(Context ctx, int texWidth,
+ int texHeight, int objectId) {
+ return initTexturemapping(unbox(ctx), texWidth,
+ texHeight, objectId);
+ }
+
+
+
+ // Set internal render mode to one of FIELD_ALL, FIELD_LEFT or
+ // FIELD_RIGHT. Note that it is up to the caller to ensure that
+ // stereo is available before setting the mode to FIELD_LEFT or
+ // FIELD_RIGHT. The boolean isTRUE for double buffered mode, FALSE
+ // foe single buffering.
+ native void setRenderMode(long ctx, int mode, boolean doubleBuffer);
+
+ void setRenderMode(Context ctx, int mode, boolean doubleBuffer) {
+ setRenderMode(unbox(ctx), mode, doubleBuffer);
+ }
+
+
+ // Set glDepthMask.
+ native void setDepthBufferWriteEnable(long ctx, boolean mode);
+
+ void setDepthBufferWriteEnable(Context ctx, boolean mode) {
+ setDepthBufferWriteEnable(unbox(ctx), mode);
+ }
+
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Canvas3D / GraphicsConfigTemplate3D methods - logic dealing with
+ // native graphics configuration or drawing surface
+ //
+
+ // Return a graphics config based on the one passed in. Note that we can
+ // assert that the input config is non-null and was created from a
+ // GraphicsConfigTemplate3D.
+ // This method must return a valid GraphicsConfig, or else it must throw
+ // an exception if one cannot be returned.
+ GraphicsConfiguration getGraphicsConfig(GraphicsConfiguration gconfig) {
+//KCR: System.err.println("NativePipeline.getGraphicsConfig()");
+
+ // Just return the input graphics config
+ return gconfig;
+ }
+
+ // Get the native FBconfig pointer
+ long getFbConfig(GraphicsConfigInfo gcInfo) {
+ long fbConfig = ((Long)gcInfo.getPrivateData()).longValue();
+ if (fbConfig == 0L) {
+ throw new IllegalArgumentException(J3dI18N.getString("Canvas3D23"));
+ }
+
+ return fbConfig;
+ }
+
+ // Get best graphics config from pipeline
+ GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate3D gct,
+ GraphicsConfiguration[] gc) {
+ return nativeTemplate.getBestConfiguration(gct, gc);
+ }
+
+ // Determine whether specified graphics config is supported by pipeline
+ boolean isGraphicsConfigSupported(GraphicsConfigTemplate3D gct,
+ GraphicsConfiguration gc) {
+ return nativeTemplate.isGraphicsConfigSupported(gct, gc);
+ }
+
+ // Methods to get actual capabilities from Canvas3D
+ boolean hasDoubleBuffer(Canvas3D cv) {
+ return nativeTemplate.hasDoubleBuffer(cv);
+ }
+
+ boolean hasStereo(Canvas3D cv) {
+ return nativeTemplate.hasStereo(cv);
+ }
+
+ int getStencilSize(Canvas3D cv) {
+ return nativeTemplate.getStencilSize(cv);
+ }
+
+ boolean hasSceneAntialiasingMultisample(Canvas3D cv) {
+ return nativeTemplate.hasSceneAntialiasingMultisample(cv);
+ }
+
+ boolean hasSceneAntialiasingAccum(Canvas3D cv) {
+ return nativeTemplate.hasSceneAntialiasingAccum(cv);
+ }
+
+ // Methods to get native WS display and screen
+ long getDisplay() {
+ return NativeScreenInfo.getDisplay();
+ }
+ int getScreen(GraphicsDevice graphicsDevice) {
+ return NativeScreenInfo.getScreen(graphicsDevice);
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // DrawingSurfaceObject methods
+ //
+
+ // Method to construct a new DrawingSurfaceObject
+ DrawingSurfaceObject createDrawingSurfaceObject(Canvas3D cv) {
+ return new DrawingSurfaceObjectAWT(cv,
+ VirtualUniverse.mc.awt, cv.screen.display, cv.screen.screen,
+ VirtualUniverse.mc.xineramaDisabled);
+ }
+
+
+ // Method to free the drawing surface object
+ // (called from Canvas3D.removeNotify)
+ void freeDrawingSurface(Canvas3D cv, DrawingSurfaceObject drawingSurfaceObject) {
+ synchronized (drawingSurfaceObject) {
+ DrawingSurfaceObjectAWT dso =
+ (DrawingSurfaceObjectAWT)drawingSurfaceObject;
+ // get nativeDS before it is set to 0 in invalidate()
+ long ds = dso.getDS();
+ long ds_struct[] = {ds, dso.getDSI()};
+ if (ds != 0) {
+ VirtualUniverse.mc.postRequest(
+ MasterControl.FREE_DRAWING_SURFACE,
+ ds_struct);
+ }
+
+ drawingSurfaceObject.invalidate();
+ }
+ }
+
+ // Method to free the native drawing surface object
+ void freeDrawingSurfaceNative(Object o) {
+ DrawingSurfaceObjectAWT.freeDrawingSurface(o);
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/NativeShaderObject.java b/src/classes/share/javax/media/j3d/NativeShaderObject.java
new file mode 100644
index 0000000..050fb37
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/NativeShaderObject.java
@@ -0,0 +1,31 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Shader objects for native rendering pipeline.
+ */
+class NativeShaderObject implements ShaderProgramId, ShaderId, ShaderAttrLoc {
+
+ // Native shader object;
+ private long nativeId;
+
+ NativeShaderObject(long nativeId) {
+ this.nativeId = nativeId;
+ }
+
+ long getNativeId() {
+ return nativeId;
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/NioImageBuffer.java b/src/classes/share/javax/media/j3d/NioImageBuffer.java
new file mode 100644
index 0000000..91ebe92
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/NioImageBuffer.java
@@ -0,0 +1,379 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+
+/**
+ * The NioImageBuffer class is a container for an image whose DataBuffer
+ * is specified via a java.nio.Buffer. An an NioImageBuffer can be wrapped by
+ * an ImageComponent and used for texture mapping, or for rendering Raster
+ * objects or background images. An NioImageBuffer must not be used as the
+ * buffer of an off-screen Canvas3D, or for reading back a raster image.
+ *
+ * @see ImageComponent2D
+ * @see ImageComponent3D
+ *
+ * @since Java 3D 1.5
+ */
+public class NioImageBuffer {
+
+ /**
+ * Used to specify the type of the image.
+ */
+ public enum ImageType {
+ /**
+ * Represents an image with 8-bit RGB color components,
+ * corresponding to a Windows-style BGR color model, with the
+ * colors Blue, Green, and Red stored in 3 consecutive
+ * bytes for each pixel.
+ * The data buffer must be a ByteBuffer when using this imageType.
+ */
+ TYPE_3BYTE_BGR,
+
+ /**
+ * Represents an image with 8-bit RGB color components with
+ * Red, Green, and Blue, stored in 3 consecutive
+ * bytes for each pixel.
+ * The data buffer must be a ByteBuffer when using this imageType.
+ */
+ TYPE_3BYTE_RGB,
+
+ /**
+ * Represents an image with 8-bit RGBA color components with
+ * Alpha, Blue, Green, and Red stored in 4 consecutive
+ * bytes for each pixel.
+ * The data buffer must be a ByteBuffer when using this imageType.
+ */
+ TYPE_4BYTE_ABGR,
+
+ /**
+ * Represents an image with 8-bit RGBA color components with
+ * Red, Green, Blue, and Alpha stored in 4 consecutive
+ * bytes for each pixel.
+ * The data buffer must be a ByteBuffer when using this imageType.
+ */
+ TYPE_4BYTE_RGBA,
+
+ /**
+ * Represents a unsigned byte grayscale image, non-indexed.
+ * The data buffer must be a ByteBuffer when using this imageType.
+ */
+ TYPE_BYTE_GRAY,
+
+ /**
+ * Represents an image with 8-bit RGBA color components packed
+ * into integer pixels.
+ * The data buffer must be an IntBuffer when using this imageType.
+ */
+ TYPE_INT_ARGB,
+
+ /**
+ * Represents an image with 8-bit RGB color components,
+ * corresponding to a Windows- or Solaris- style BGR color model,
+ * with the colors Blue, Green, and Red packed into integer
+ * pixels.
+ * The data buffer must be an IntBuffer when using this imageType.
+ */
+ TYPE_INT_BGR,
+
+ /**
+ * Represents an image with 8-bit RGB color components packed into
+ * integer pixels.
+ * The data buffer must be an IntBuffer when using this imageType.
+ */
+ TYPE_INT_RGB,
+
+ }
+
+
+ /**
+ * Enum for type of buffer
+ */
+ enum BufferType {
+ BYTE_BUFFER,
+ INT_BUFFER,
+ }
+
+
+ // Width and height of image
+ int width;
+ int height;
+
+ // TYpe of image
+ ImageType imageType;
+
+ // Cached buffer
+ Buffer buffer;
+
+ // Type of NIO Buffer: byte or int
+ BufferType bufferType;
+
+ // Number of bytes allocated per pixel
+ int bytesPerPixel;
+
+ // Number of byte or int elements per pixel
+ int elementsPerPixel;
+
+ /**
+ * Constructs an NIO image buffer of the specified size and type.
+ * A direct NIO buffer of the correct type (ByteBuffer or IntBuffer)
+ * and size to match the input parameters
+ * is allocated.
+ *
+ * @param width width of the image
+ * @param height height of the image
+ * @param imageType type of the image.
+ *
+ * @exception IllegalArgumentException if width < 1 or height < 1
+ * @exception NullPointerException if imageType is null
+ */
+ public NioImageBuffer(int width, int height, ImageType imageType) {
+
+ processParams(width, height, imageType);
+
+ ByteBuffer tmpBuffer = ByteBuffer.allocateDirect(width * height * bytesPerPixel);
+ switch (bufferType) {
+ case BYTE_BUFFER:
+ buffer = tmpBuffer;
+ break;
+
+ case INT_BUFFER:
+ buffer = tmpBuffer.order(ByteOrder.nativeOrder()).asIntBuffer();
+ break;
+
+ default:
+ // We should never get here
+ throw new AssertionError("missing case statement");
+ }
+ }
+
+ /**
+ * Constructs an NIO image buffer of the specified size and type, using
+ * the specified dataBuffer.
+ * The the byte order of the specified dataBuffer must match the native
+ * byte order of the underlying platform.
+ * For best performance, the NIO buffer should be a direct buffer.
+ *
+ * @param width width of the image
+ * @param height height of the image
+ * @param imageType type of the image.
+ * @param dataBuffer an NIO buffer of the correct type (ByteBuffer or
+ * IntBuffer) to match the specified imageType.
+ * This constructor will create a new view of
+ * the buffer, and will call <code>rewind</code> on that view,
+ * such that elements 0 through <code>dataBuffer.limit()-1</code>
+ * will be available internally. The number of elements in
+ * the buffer must be exactly <code>width*height*numElementsPerPixel</code>,
+ * where <code>numElementsPerPixel</code> is
+ * 3 for TYPE_3BYTE_BGR and TYPE_3BYTE_RGB,
+ * 4 for TYPE_4BYTE_ABGR and TYPE_4BYTE_RGBA,
+ * and 1 for all other types.
+ *
+ * @exception IllegalArgumentException if width < 1 or height < 1
+ * @exception NullPointerException if imageType or dataBuffer is null
+ * @exception IllegalArgumentException if the type of the dataBuffer does
+ * not match the imageType
+ * @exception IllegalArgumentException if <code>dataBuffer.limit() !=
+ * width*height*numElementsPerPixel</code>
+ * @exception IllegalArgumentException if the byte order of the specified
+ * dataBuffer does not match the native byte order of the underlying
+ * platform.
+ */
+ public NioImageBuffer(int width, int height, ImageType imageType,
+ Buffer dataBuffer) {
+
+ processParams(width, height, imageType);
+ setDataBuffer(dataBuffer);
+ }
+
+ /**
+ * Gets the width of this data buffer.
+ *
+ * @return the width of this data buffer.
+ */
+ public int getWidth() {
+ return width;
+ }
+
+ /**
+ * Gets the height of this data buffer.
+ *
+ * @return the width of this data buffer.
+ */
+ public int getHeight() {
+ return height;
+ }
+
+ /**
+ * Gets the image type of this data buffer.
+ *
+ * @return the image type of this data buffer.
+ */
+ public ImageType getImageType() {
+ return imageType;
+ }
+
+ /**
+ * Sets the data buffer to the specified input data buffer.
+ * The the byte order of the specified dataBuffer must match the native
+ * byte order of the underlying platform.
+ * For best performance, the NIO buffer should be a direct buffer.
+ *
+ * @param dataBuffer an NIO buffer of the correct type (ByteBuffer or
+ * IntBuffer) to match the imageType of this
+ * NioImageBuffer. This method will create a new view of
+ * the buffer, and will call <code>rewind</code> on that view,
+ * such that elements 0 through <code>dataBuffer.limit()-1</code>
+ * will be available internally. The number of elements in
+ * the buffer must be exactly <code>width*height*numElementsPerPixel</code>,
+ * where <code>numElementsPerPixel</code> is
+ * 3 for TYPE_3BYTE_BGR and TYPE_3BYTE_RGB,
+ * 4 for TYPE_4BYTE_ABGR and TYPE_4BYTE_RGBA,
+ * and 1 for all other types.
+ *
+ * @exception NullPointerException if dataBuffer is null
+ * @exception IllegalArgumentException if the type of the dataBuffer does
+ * not match the imageType
+ * @exception IllegalArgumentException if <code>dataBuffer.limit() !=
+ * width*height*numElementsPerPixel</code>
+ * @exception IllegalArgumentException if the byte order of the specified
+ * dataBuffer does not match the native byte order of the underlying
+ * platform.
+ */
+ public void setDataBuffer(Buffer dataBuffer) {
+ if (dataBuffer == null) {
+ throw new NullPointerException();
+ }
+
+ if (dataBuffer.limit() != width*height*elementsPerPixel) {
+ throw new IllegalArgumentException(J3dI18N.getString("NioImageBuffer3"));
+ }
+
+ switch (bufferType) {
+ case BYTE_BUFFER:
+ if (!(dataBuffer instanceof ByteBuffer)) {
+ throw new IllegalArgumentException(J3dI18N.getString("NioImageBuffer4"));
+ }
+ buffer = ((ByteBuffer)dataBuffer).duplicate().rewind();
+ break;
+
+ case INT_BUFFER:
+ if (!(dataBuffer instanceof IntBuffer)) {
+ throw new IllegalArgumentException(J3dI18N.getString("NioImageBuffer4"));
+ }
+
+ if (((IntBuffer)dataBuffer).order() != ByteOrder.nativeOrder()) {
+ throw new IllegalArgumentException(J3dI18N.getString("NioImageBuffer5"));
+ }
+ buffer = ((IntBuffer)dataBuffer).duplicate().rewind();
+ break;
+
+ default:
+ // We should never get here
+ throw new AssertionError("missing case statement");
+ }
+ }
+
+ /**
+ * Gets the data buffer to the specified input data buffer.
+ *
+ * @return a view of the current data buffer for this NIO image buffer.
+ * This view will be rewound such that elements 0
+ * through <code>dataBuffer.limit()-1</code> are available.
+ */
+ public Buffer getDataBuffer() {
+ Buffer tmpBuffer = null;
+
+ switch (bufferType) {
+ case BYTE_BUFFER:
+ tmpBuffer = ((ByteBuffer)buffer).duplicate();
+ break;
+
+ case INT_BUFFER:
+ tmpBuffer = ((IntBuffer)buffer).duplicate();
+ break;
+
+ default:
+ // We should never get here
+ throw new AssertionError("missing case statement");
+ }
+
+ return tmpBuffer.rewind();
+ }
+
+
+ // Sanity check the input parameters, calculate the buffer type and
+ // the number of bytes per pixel
+ private void processParams(int width, int height, ImageType imageType) {
+ if (width < 1) {
+ throw new IllegalArgumentException(J3dI18N.getString("NioImageBuffer0"));
+ }
+
+ if (height < 1) {
+ throw new IllegalArgumentException(J3dI18N.getString("NioImageBuffer1"));
+ }
+
+ switch (imageType) {
+ case TYPE_3BYTE_BGR:
+ bufferType = BufferType.BYTE_BUFFER;
+ bytesPerPixel = 3;
+ elementsPerPixel = 3;
+ break;
+
+ case TYPE_3BYTE_RGB:
+ bufferType = BufferType.BYTE_BUFFER;
+ bytesPerPixel = 3;
+ elementsPerPixel = 3;
+ break;
+
+ case TYPE_4BYTE_ABGR:
+ bufferType = BufferType.BYTE_BUFFER;
+ bytesPerPixel = 4;
+ elementsPerPixel = 4;
+ break;
+
+ case TYPE_4BYTE_RGBA:
+ bufferType = BufferType.BYTE_BUFFER;
+ bytesPerPixel = 4;
+ elementsPerPixel = 4;
+ break;
+
+ case TYPE_BYTE_GRAY:
+ bufferType = BufferType.BYTE_BUFFER;
+ bytesPerPixel = 1;
+ elementsPerPixel = 1;
+ break;
+
+ case TYPE_INT_ARGB:
+ case TYPE_INT_BGR:
+ case TYPE_INT_RGB:
+ bufferType = BufferType.INT_BUFFER;
+ bytesPerPixel = 4;
+ elementsPerPixel = 1;
+ break;
+
+ default:
+ // We should never get here
+ throw new AssertionError("missing case statement");
+ }
+
+ this.width = width;
+ this.height = height;
+ this.imageType = imageType;
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/NodeComponent.java b/src/classes/share/javax/media/j3d/NodeComponent.java
index 524814e..0498ae5 100644
--- a/src/classes/share/javax/media/j3d/NodeComponent.java
+++ b/src/classes/share/javax/media/j3d/NodeComponent.java
@@ -265,4 +265,29 @@ public abstract class NodeComponent extends SceneGraphObject {
boolean duplicateChild() {
return getDuplicateOnCloneTree();
}
+
+ /*
+ * @exception IllegalSharingException if this NodeComponent is live and
+ * the specified image is being used by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalSharingException if this NodeComponent is
+ * being used by an immediate mode context and
+ * the specified image is being used by a Canvas3D as an off-screen buffer.
+ */
+ void validateImageIllegalSharing(ImageComponent image) {
+ // Do illegal sharing check
+ if(image != null) {
+ ImageComponentRetained imageRetained = (ImageComponentRetained) image.retained;
+ NodeComponentRetained ncRetained = (NodeComponentRetained)this.retained;
+ if(imageRetained.getUsedByOffScreen()) {
+ if(isLive()) {
+ throw new IllegalSharingException(J3dI18N.getString("NodeComponent2"));
+ }
+ if(ncRetained.getInImmCtx()) {
+ throw new IllegalSharingException(J3dI18N.getString("NodeComponent3"));
+ }
+ }
+ }
+ }
+
}
diff --git a/src/classes/share/javax/media/j3d/NodeComponentRetained.java b/src/classes/share/javax/media/j3d/NodeComponentRetained.java
index 8b25c27..5af65a0 100644
--- a/src/classes/share/javax/media/j3d/NodeComponentRetained.java
+++ b/src/classes/share/javax/media/j3d/NodeComponentRetained.java
@@ -43,7 +43,7 @@ class NodeComponentRetained extends SceneGraphObjectRetained {
// In the case of Appearance, its a bitmask of all components
int changedFrequent = 0;
int compChanged = 0;
-
+
// Increment the refcount. If this is the first, mark it as live.
void doSetLive(boolean inBackgroundGroup, int refCount) {
int oldRefCount = this.refCount;
@@ -212,21 +212,13 @@ class NodeComponentRetained extends SceneGraphObjectRetained {
mirror = null;
}
- // Evaluate state based on the following extensions
- void evaluateExtensions(int extensions) {
- }
-
-
-
-
void setFrequencyChangeMask(int bit, int mask) {
- // Record only the inf->frequent change
if (source.getCapabilityIsFrequent(bit))
changedFrequent |= mask;
else if (!source.isLive()) {
+ // Record the freq->infreq change only for non-live node components
changedFrequent &= ~mask;
}
-
}
protected Object clone() {
diff --git a/src/classes/share/javax/media/j3d/NodeRetained.java b/src/classes/share/javax/media/j3d/NodeRetained.java
index 7742891..bb833a4 100644
--- a/src/classes/share/javax/media/j3d/NodeRetained.java
+++ b/src/classes/share/javax/media/j3d/NodeRetained.java
@@ -363,10 +363,9 @@ abstract class NodeRetained extends SceneGraphObjectRetained implements NnuId {
}
if((nodeR instanceof TransformGroupRetained) && (nodeR != caller)) {
- Transform3D t1 = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D t1 = new Transform3D();
((TransformGroupRetained)(nodeR)).transform.getWithLock(t1);
l2Vw.mul(t1);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t1);
} else if ((nodeR == caller) && (staticTransform != null)) {
l2Vw.mul(staticTransform.transform);
}
diff --git a/src/classes/share/javax/media/j3d/NoopDrawingSurfaceObject.java b/src/classes/share/javax/media/j3d/NoopDrawingSurfaceObject.java
new file mode 100644
index 0000000..5fb3c01
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/NoopDrawingSurfaceObject.java
@@ -0,0 +1,57 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * The DrawingSurfaceObject class is used to manage native drawing surface
+ */
+class NoopDrawingSurfaceObject extends DrawingSurfaceObject {
+
+ NoopDrawingSurfaceObject(Canvas3D cv) {
+ super(cv);
+
+ System.err.println("NoopDrawingSurfaceObject constructed");
+ }
+
+ synchronized boolean renderLock() {
+ System.err.println("NoopDrawingSurfaceObject.renderLock()");
+ gotDsiLock = true;
+ return true;
+ }
+
+ synchronized void unLock() {
+ System.err.println("NoopDrawingSurfaceObject.unLock()");
+ gotDsiLock = false;
+ }
+
+ synchronized void getDrawingSurfaceObjectInfo() {
+ if (canvas.drawable == null) {
+ System.err.println(
+ "NoopDrawingSurfaceObject.getDrawingSurfaceObjectInfo: window = "
+ + canvas.drawable);
+
+ canvas.drawable = new NoopDrawable();
+ }
+ }
+
+ synchronized void invalidate() {
+ System.err.println("NoopDrawingSurfaceObject.invalidate()");
+ }
+
+ /**
+ * Dummy drawable for noop pipeline
+ */
+ static class NoopDrawable implements Drawable {
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/NoopPipeline.java b/src/classes/share/javax/media/j3d/NoopPipeline.java
new file mode 100644
index 0000000..09e7b04
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/NoopPipeline.java
@@ -0,0 +1,1561 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+
+/**
+ * Concrete implementation of Pipeline class for the noop rendering
+ * pipeline.
+ */
+class NoopPipeline extends Pipeline {
+
+ // Flags indicating whether the Cg or GLSL libraries are available.
+ private boolean cgLibraryAvailable = false;
+
+ /**
+ * Constructor for singleton NoopPipeline instance
+ */
+ protected NoopPipeline() {
+ }
+
+ /**
+ * Initialize the pipeline
+ */
+ void initialize(Pipeline.Type pipelineType) {
+ super.initialize(pipelineType);
+
+ assert pipelineType == Pipeline.Type.NOOP;
+ }
+
+ /**
+ * Load all of the required libraries
+ */
+ void loadLibraries(int globalShadingLanguage) {
+ }
+
+ /**
+ * Returns true if the Cg library is loaded and available. Note that this
+ * does not necessarily mean that Cg is supported by the graphics card.
+ */
+ boolean isCgLibraryAvailable() {
+ return cgLibraryAvailable;
+ }
+
+ /**
+ * Returns true if the GLSL library is loaded and available. Note that this
+ * does not necessarily mean that GLSL is supported by the graphics card.
+ */
+ boolean isGLSLLibraryAvailable() {
+ return true;
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GeometryArrayRetained methods
+ //
+
+ // Used by D3D to free vertex buffer
+ void freeD3DArray(GeometryArrayRetained geo, boolean deleteVB) {
+ }
+
+ // used for GeometryArrays by Copy or interleaved
+ void execute(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[] varray, float[] cdata, int cdirty) {
+ }
+
+ // used by GeometryArray by Reference with java arrays
+ void executeVA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, float[] vfcoords, double[] vdcoords,
+ int colorIndex, float[] cfdata, byte[] cbdata,
+ int normalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty) {
+ }
+
+ // used by GeometryArray by Reference with NIO buffer
+ void executeVABuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex,
+ Object vcoords,
+ int colorIndex,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ int normalIndex, Object ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, Object[] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty) {
+ }
+
+ // used by GeometryArray by Reference in interleaved format with NIO buffer
+ void executeInterleavedBuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ Object varray, float[] cdata, int cdirty) {
+ }
+
+ void setVertexFormat(Context ctx, GeometryArrayRetained geo,
+ int vformat, boolean useAlpha, boolean ignoreVertexColors) {
+ }
+
+ void disableGlobalAlpha(Context ctx, GeometryArrayRetained geo, int vformat,
+ boolean useAlpha, boolean ignoreVertexColors) {
+ }
+
+ // used for GeometryArrays
+ void buildGA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int startVIndex,
+ int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen, int[] texCoordSetMapOffset,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ double[] xform, double[] nxform,
+ float[] varray) {
+ }
+
+ // used to Build Dlist GeometryArray by Reference with java arrays
+ void buildGAForByRef(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, float[] vfcoords, double[] vdcoords,
+ int colorIndex, float[] cfdata, byte[] cbdata,
+ int normalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int[] texIndex, int texstride, Object[] texCoords,
+ double[] xform, double[] nxform) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // IndexedGeometryArrayRetained methods
+ //
+
+ // by-copy or interleaved, by reference, Java arrays
+ void executeIndexedGeometry(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ float[] varray, float[] cdata,
+ int cdirty,
+ int[] indexCoord) {
+ }
+
+ // interleaved, by reference, nio buffer
+ void executeIndexedGeometryBuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ Object varray, float[] cdata,
+ int cdirty,
+ int[] indexCoord) {
+ }
+
+ // non interleaved, by reference, Java arrays
+ void executeIndexedGeometryVA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ float[] vfcoords, double[] vdcoords,
+ float[] cfdata, byte[] cbdata,
+ float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int texstride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord) {
+ }
+
+ // non interleaved, by reference, nio buffer
+ void executeIndexedGeometryVABuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ Object vcoords,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ Object normal,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ Object[] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int texstride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord) {
+ }
+
+ // by-copy geometry
+ void buildIndexedGeometry(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetMapOffset,
+ double[] xform, double[] nxform,
+ float[] varray, int[] indexCoord) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GraphicsContext3D methods
+ //
+
+ void readRaster(Context ctx,
+ int type, int xSrcOffset, int ySrcOffset,
+ int width, int height, int hCanvas,
+ int imageDataType, int imageFormat,
+ Object imageBuffer,
+ int depthFormat,
+ Object depthBuffer) {
+
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // CgShaderProgramRetained methods
+ //
+
+ // ShaderAttributeValue methods
+
+ ShaderError setCgUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int value) {
+ return null;
+ }
+
+ ShaderError setCgUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float value) {
+ return null;
+ }
+
+ ShaderError setCgUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return null;
+ }
+
+ // ShaderAttributeArray methods
+
+ ShaderError setCgUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setCgUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ // interfaces for shader compilation, etc.
+ ShaderError createCgShader(Context ctx, int shaderType, ShaderId[] shaderId) {
+ return null;
+ }
+ ShaderError destroyCgShader(Context ctx, ShaderId shaderId) {
+ return null;
+ }
+ ShaderError compileCgShader(Context ctx, ShaderId shaderId, String program) {
+ return null;
+ }
+
+ ShaderError createCgShaderProgram(Context ctx, ShaderProgramId[] shaderProgramId) {
+ return null;
+ }
+ ShaderError destroyCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return null;
+ }
+ ShaderError linkCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId,
+ ShaderId[] shaderIds) {
+ return null;
+ }
+ void lookupCgVertexAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, boolean[] errArr) {
+ }
+ void lookupCgShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, ShaderAttrLoc[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr) {
+ }
+
+ ShaderError useCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return null;
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GLSLShaderProgramRetained methods
+ //
+
+ // ShaderAttributeValue methods
+
+ ShaderError setGLSLUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value) {
+ return null;
+ }
+
+ // ShaderAttributeArray methods
+
+ ShaderError setGLSLUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ ShaderError setGLSLUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value) {
+ return null;
+ }
+
+ // interfaces for shader compilation, etc.
+ ShaderError createGLSLShader(Context ctx, int shaderType, ShaderId[] shaderId) {
+ return null;
+ }
+ ShaderError destroyGLSLShader(Context ctx, ShaderId shaderId) {
+ return null;
+ }
+ ShaderError compileGLSLShader(Context ctx, ShaderId shaderId, String program) {
+ return null;
+ }
+
+ ShaderError createGLSLShaderProgram(Context ctx, ShaderProgramId[] shaderProgramId) {
+ return null;
+ }
+ ShaderError destroyGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return null;
+ }
+ ShaderError linkGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId,
+ ShaderId[] shaderIds) {
+ return null;
+ }
+ ShaderError bindGLSLVertexAttrName(Context ctx, ShaderProgramId shaderProgramId,
+ String attrName, int attrIndex) {
+ return null;
+ }
+ void lookupGLSLShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, ShaderAttrLoc[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr) {
+ }
+
+ ShaderError useGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
+ return null;
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ImageComponent2DRetained methods
+ //
+
+ // free d3d surface referred to by id
+ void freeD3DSurface(ImageComponent2DRetained image, int hashId) {
+ }
+
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Renderer methods
+ //
+
+ void cleanupRenderer() {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ColoringAttributesRetained methods
+ //
+
+ void updateColoringAttributes(Context ctx,
+ float dRed, float dGreen, float dBlue,
+ float red, float green, float blue,
+ float alpha,
+ boolean lEnable,
+ int shadeModel) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // DirectionalLightRetained methods
+ //
+
+ void updateDirectionalLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float x, float y, float z) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PointLightRetained methods
+ //
+
+ void updatePointLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float ax, float ay, float az,
+ float px, float py, float pz) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // SpotLightRetained methods
+ //
+
+ void updateSpotLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float ax, float ay, float az,
+ float px, float py, float pz, float spreadAngle,
+ float concentration, float dx, float dy,
+ float dz) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ExponentialFogRetained methods
+ //
+
+ void updateExponentialFog(Context ctx,
+ float red, float green, float blue,
+ float density) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // LinearFogRetained methods
+ //
+
+ void updateLinearFog(Context ctx,
+ float red, float green, float blue,
+ double fdist, double bdist) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // LineAttributesRetained methods
+ //
+
+ void updateLineAttributes(Context ctx,
+ float lineWidth, int linePattern,
+ int linePatternMask,
+ int linePatternScaleFactor,
+ boolean lineAntialiasing) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // MaterialRetained methods
+ //
+
+ void updateMaterial(Context ctx,
+ float red, float green, float blue, float alpha,
+ float ared, float agreen, float ablue,
+ float ered, float egreen, float eblue,
+ float dred, float dgreen, float dblue,
+ float sred, float sgreen, float sblue,
+ float shininess, int colorTarget, boolean enable) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ModelClipRetained methods
+ //
+
+ void updateModelClip(Context ctx, int planeNum, boolean enableFlag,
+ double A, double B, double C, double D) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PointAttributesRetained methods
+ //
+
+ void updatePointAttributes(Context ctx, float pointSize, boolean pointAntialiasing) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PolygonAttributesRetained methods
+ //
+
+ void updatePolygonAttributes(Context ctx,
+ int polygonMode, int cullFace,
+ boolean backFaceNormalFlip,
+ float polygonOffset,
+ float polygonOffsetFactor) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // RenderingAttributesRetained methods
+ //
+
+ void updateRenderingAttributes(Context ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride,
+ boolean depthBufferEnable,
+ boolean depthBufferWriteEnable,
+ int depthTestFunction,
+ float alphaTestValue, int alphaTestFunction,
+ boolean ignoreVertexColors,
+ boolean rasterOpEnable, int rasterOp,
+ boolean userStencilAvailable, boolean stencilEnable,
+ int stencilFailOp, int stencilZFailOp, int stencilZPassOp,
+ int stencilFunction, int stencilReferenceValue,
+ int stencilCompareMask, int stencilWriteMask ) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TexCoordGenerationRetained methods
+ //
+
+ /**
+ * This method updates the native context:
+ * trans contains eyeTovworld transform in d3d
+ * trans contains vworldToEye transform in ogl
+ */
+ void updateTexCoordGeneration(Context ctx,
+ boolean enable, int genMode, int format,
+ float planeSx, float planeSy, float planeSz, float planeSw,
+ float planeTx, float planeTy, float planeTz, float planeTw,
+ float planeRx, float planeRy, float planeRz, float planeRw,
+ float planeQx, float planeQy, float planeQz, float planeQw,
+ double[] trans) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TransparencyAttributesRetained methods
+ //
+
+ void updateTransparencyAttributes(Context ctx,
+ float alpha, int geometryType,
+ int polygonMode,
+ boolean lineAA, boolean pointAA,
+ int transparencyMode,
+ int srcBlendFunction,
+ int dstBlendFunction) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureAttributesRetained methods
+ //
+
+ void updateTextureAttributes(Context ctx,
+ double[] transform, boolean isIdentity, int textureMode,
+ int perspCorrectionMode, float red,
+ float green, float blue, float alpha,
+ int textureFormat) {
+ }
+
+ void updateRegisterCombiners(Context ctx,
+ double[] transform, boolean isIdentity, int textureMode,
+ int perspCorrectionMode, float red,
+ float green, float blue, float alpha,
+ int textureFormat,
+ int combineRgbMode, int combineAlphaMode,
+ int[] combineRgbSrc, int[] combineAlphaSrc,
+ int[] combineRgbFcn, int[] combineAlphaFcn,
+ int combineRgbScale, int combineAlphaScale) {
+ }
+
+ void updateTextureColorTable(Context ctx, int numComponents,
+ int colorTableSize,
+ int[] colorTable) {
+ }
+
+ void updateCombiner(Context ctx,
+ int combineRgbMode, int combineAlphaMode,
+ int[] combineRgbSrc, int[] combineAlphaSrc,
+ int[] combineRgbFcn, int[] combineAlphaFcn,
+ int combineRgbScale, int combineAlphaScale) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureUnitStateRetained methods
+ //
+
+ void updateTextureUnitState(Context ctx, int unitIndex, boolean enableFlag) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureRetained methods
+ // Texture2DRetained methods
+ //
+
+ void bindTexture2D(Context ctx, int objectId, boolean enable) {
+ }
+
+ void updateTexture2DImage(Context ctx,
+ int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int imageDataType, Object data) {
+ }
+
+ void updateTexture2DSubImage(Context ctx,
+ int level, int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int imageDataType, Object data) {
+ }
+
+ void updateTexture2DLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+ }
+
+ void updateTexture2DLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ) {
+ }
+
+ void updateTexture2DBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha) {
+ }
+
+ void updateTexture2DFilterModes(Context ctx,
+ int minFilter, int magFilter) {
+ }
+
+ void updateTexture2DSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
+ }
+
+ void updateTexture2DFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+ }
+
+ void updateTexture2DAnisotropicFilter(Context ctx, float degree) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Texture3DRetained methods
+ //
+
+ void bindTexture3D(Context ctx, int objectId, boolean enable) {
+ }
+
+ void updateTexture3DImage(Context ctx,
+ int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height, int depth,
+ int boundaryWidth,
+ int imageDataType, Object imageData) {
+ }
+
+ void updateTexture3DSubImage(Context ctx,
+ int level,
+ int xoffset, int yoffset, int zoffset,
+ int textureFormat, int imageFormat,
+ int imgXoffset, int imgYoffset, int imgZoffset,
+ int tilew, int tileh,
+ int width, int height, int depth,
+ int imageTypeData, Object imageData) {
+ }
+
+ void updateTexture3DLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+ }
+
+ void updateTexture3DLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ) {
+ }
+
+ void updateTexture3DBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ int boundaryModeR, float boundaryRed,
+ float boundaryGreen, float boundaryBlue,
+ float boundaryAlpha) {
+ }
+
+ void updateTexture3DFilterModes(Context ctx,
+ int minFilter, int magFilter) {
+ }
+
+ void updateTexture3DSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
+ }
+
+ void updateTexture3DFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+ }
+
+ void updateTexture3DAnisotropicFilter(Context ctx, float degree) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureCubeMapRetained methods
+ //
+
+ void bindTextureCubeMap(Context ctx, int objectId, boolean enable) {
+ }
+
+ void updateTextureCubeMapImage(Context ctx,
+ int face, int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int imageDataType, Object imageData) {
+ }
+
+ void updateTextureCubeMapSubImage(Context ctx,
+ int face, int level, int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int imageDataType, Object imageData) {
+ }
+
+ void updateTextureCubeMapLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+ }
+
+ void updateTextureCubeMapLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ) {
+ }
+
+ void updateTextureCubeMapBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha) {
+ }
+
+ void updateTextureCubeMapFilterModes(Context ctx,
+ int minFilter, int magFilter) {
+ }
+
+ void updateTextureCubeMapSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
+ }
+
+ void updateTextureCubeMapFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+ }
+
+ void updateTextureCubeMapAnisotropicFilter(Context ctx, float degree) {
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // MasterControl methods
+ //
+
+ // Method to return the AWT object
+ long getAWT() {
+ return 0L;
+ }
+
+ // Method to initialize the native J3D library
+ boolean initializeJ3D(boolean disableXinerama) {
+ return true;
+ }
+
+ // Maximum lights supported by the native API
+ int getMaximumLights() {
+ return 8;
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Canvas3D methods - native wrappers
+ //
+
+ // This is the native method for creating the underlying graphics context.
+ Context createNewContext(Canvas3D cv, long display, Drawable drawable,
+ long fbConfig, Context shareCtx, boolean isSharedCtx,
+ boolean offScreen,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable) {
+ return new NoopContext();
+ }
+
+ void createQueryContext(Canvas3D cv, long display, Drawable drawable,
+ long fbConfig, boolean offScreen, int width, int height,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable) {
+ }
+
+ // This is the native for creating offscreen buffer
+ Drawable createOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, int width, int height) {
+ return null;
+ }
+
+ void destroyOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, Drawable drawable) {
+ }
+
+ // This is the native for reading the image from the offscreen buffer
+ void readOffScreenBuffer(Canvas3D cv, Context ctx, int format, int type, Object data, int width, int height) {
+ }
+
+ // The native method for swapBuffers
+ int swapBuffers(Canvas3D cv, Context ctx, long dpy, Drawable drawable) {
+ return 0;
+ }
+
+ // notify D3D that Canvas is resize
+ int resizeD3DCanvas(Canvas3D cv, Context ctx) {
+ return 0;
+ }
+
+ // notify D3D to toggle between FullScreen and window mode
+ int toggleFullScreenMode(Canvas3D cv, Context ctx) {
+ return 0;
+ }
+
+ // native method for setting Material when no material is present
+ void updateMaterialColor(Context ctx, float r, float g, float b, float a) {
+ }
+
+ void destroyContext(long display, Drawable drawable, Context ctx) {
+ }
+
+ // This is the native method for doing accumulation.
+ void accum(Context ctx, float value) {
+ }
+
+ // This is the native method for doing accumulation return.
+ void accumReturn(Context ctx) {
+ }
+
+ // This is the native method for clearing the accumulation buffer.
+ void clearAccum(Context ctx) {
+ }
+
+ // This is the native method for getting the number of lights the underlying
+ // native library can support.
+ int getNumCtxLights(Context ctx) {
+ return 0;
+ }
+
+ // Native method for decal 1st child setup
+ boolean decal1stChildSetup(Context ctx) {
+ return false;
+ }
+
+ // Native method for decal nth child setup
+ void decalNthChildSetup(Context ctx) {
+ }
+
+ // Native method for decal reset
+ void decalReset(Context ctx, boolean depthBufferEnable) {
+ }
+
+ // Native method for decal reset
+ void ctxUpdateEyeLightingEnable(Context ctx, boolean localEyeLightingEnable) {
+ }
+
+ // The following three methods are used in multi-pass case
+
+ // native method for setting blend color
+ void setBlendColor(Context ctx, float red, float green,
+ float blue, float alpha) {
+ }
+
+ // native method for setting blend func
+ void setBlendFunc(Context ctx, int src, int dst) {
+ }
+
+ // native method for setting fog enable flag
+ void setFogEnableFlag(Context ctx, boolean enableFlag) {
+ }
+
+ // Setup the full scene antialising in D3D and ogl when GL_ARB_multisamle supported
+ void setFullSceneAntialiasing(Context ctx, boolean enable) {
+ }
+
+ void setGlobalAlpha(Context ctx, float alpha) {
+ }
+
+ // Native method to update separate specular color control
+ void updateSeparateSpecularColorEnable(Context ctx, boolean control) {
+ }
+
+ // Initialization for D3D when scene begin
+ void beginScene(Context ctx) {
+ }
+ void endScene(Context ctx) {
+ }
+
+ // True under Solaris,
+ // False under windows when display mode <= 8 bit
+ boolean validGraphicsMode() {
+ return true;
+ }
+
+ // native method for setting light enables
+ void setLightEnables(Context ctx, long enableMask, int maxLights) {
+ }
+
+ // native method for setting scene ambient
+ void setSceneAmbient(Context ctx, float red, float green, float blue) {
+ }
+
+ // native method for disabling fog
+ void disableFog(Context ctx) {
+ }
+
+ // native method for disabling modelClip
+ void disableModelClip(Context ctx) {
+ }
+
+ // native method for setting default RenderingAttributes
+ void resetRenderingAttributes(Context ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride) {
+ }
+
+ // native method for setting default texture
+ void resetTextureNative(Context ctx, int texUnitIndex) {
+ }
+
+ // native method for activating a particular texture unit
+ void activeTextureUnit(Context ctx, int texUnitIndex) {
+ }
+
+ // native method for setting default TexCoordGeneration
+ void resetTexCoordGeneration(Context ctx) {
+ }
+
+ // native method for setting default TextureAttributes
+ void resetTextureAttributes(Context ctx) {
+ }
+
+ // native method for setting default PolygonAttributes
+ void resetPolygonAttributes(Context ctx) {
+ }
+
+ // native method for setting default LineAttributes
+ void resetLineAttributes(Context ctx) {
+ }
+
+ // native method for setting default PointAttributes
+ void resetPointAttributes(Context ctx) {
+ }
+
+ // native method for setting default TransparencyAttributes
+ void resetTransparency(Context ctx, int geometryType,
+ int polygonMode, boolean lineAA,
+ boolean pointAA) {
+ }
+
+ // native method for setting default ColoringAttributes
+ void resetColoringAttributes(Context ctx,
+ float r, float g,
+ float b, float a,
+ boolean enableLight) {
+ }
+
+ /**
+ * This native method makes sure that the rendering for this canvas
+ * gets done now.
+ */
+ void syncRender(Context ctx, boolean wait) {
+ }
+
+ // The native method that sets this ctx to be the current one
+ boolean useCtx(Context ctx, long display, Drawable drawable) {
+ return true;
+ }
+
+ void clear(Context ctx, float r, float g, float b) {
+
+ }
+
+ void textureFillBackground(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY) {
+
+ }
+
+ void textureFillRaster(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, float mapZ, float alpha) {
+
+ }
+
+ void executeRasterDepth(Context ctx, float posX, float posY, float posZ,
+ int srcOffsetX, int srcOffsetY, int rasterWidth, int rasterHeight,
+ int depthWidth, int depthHeight, int depthType, Object depthData) {
+
+ }
+
+ // The native method for setting the ModelView matrix.
+ void setModelViewMatrix(Context ctx, double[] viewMatrix, double[] modelMatrix) {
+ }
+
+ // The native method for setting the Projection matrix.
+ void setProjectionMatrix(Context ctx, double[] projMatrix) {
+ }
+
+ // The native method for setting the Viewport.
+ void setViewport(Context ctx, int x, int y, int width, int height) {
+ }
+
+ // used for display Lists
+ void newDisplayList(Context ctx, int displayListId) {
+ }
+ void endDisplayList(Context ctx) {
+ }
+ void callDisplayList(Context ctx, int id, boolean isNonUniformScale) {
+ }
+
+ void freeDisplayList(Context ctx, int id) {
+ }
+ void freeTexture(Context ctx, int id) {
+ }
+
+ void texturemapping(Context ctx,
+ int px, int py,
+ int xmin, int ymin, int xmax, int ymax,
+ int texWidth, int texHeight,
+ int rasWidth,
+ int format, int objectId,
+ byte[] image,
+ int winWidth, int winHeight) {
+ }
+
+ boolean initTexturemapping(Context ctx, int texWidth,
+ int texHeight, int objectId) {
+ return true;
+ }
+
+
+ // Set internal render mode to one of FIELD_ALL, FIELD_LEFT or
+ // FIELD_RIGHT. Note that it is up to the caller to ensure that
+ // stereo is available before setting the mode to FIELD_LEFT or
+ // FIELD_RIGHT. The boolean isTRUE for double buffered mode, FALSE
+ // foe single buffering.
+ void setRenderMode(Context ctx, int mode, boolean doubleBuffer) {
+ }
+
+ // Set glDepthMask.
+ void setDepthBufferWriteEnable(Context ctx, boolean mode) {
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Canvas3D / GraphicsConfigTemplate3D methods - logic dealing with
+ // native graphics configuration or drawing surface
+ //
+
+ // Return a graphics config based on the one passed in. Note that we can
+ // assert that the input config is non-null and was created from a
+ // GraphicsConfigTemplate3D.
+ // This method must return a valid GraphicsConfig, or else it must throw
+ // an exception if one cannot be returned.
+ GraphicsConfiguration getGraphicsConfig(GraphicsConfiguration gconfig) {
+ System.err.println("NoopPipeline.getGraphicsConfig()");
+ return gconfig;
+ }
+
+ // Get the native FBconfig pointer
+ long getFbConfig(GraphicsConfigInfo gcInfo) {
+ return 0L;
+ }
+
+
+ // Get best graphics config from pipeline
+ GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate3D gct,
+ GraphicsConfiguration[] gc) {
+
+ GraphicsConfiguration gc1 = GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration();
+ // We need to cache the GraphicsTemplate3D
+ synchronized (Canvas3D.graphicsConfigTable) {
+ if (Canvas3D.graphicsConfigTable.get(gc1) == null) {
+ GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(gct);
+// gcInfo.setPrivateData(privateData);
+ Canvas3D.graphicsConfigTable.put(gc1, gcInfo);
+ }
+ }
+ return gc1;
+ }
+
+ // Determine whether specified graphics config is supported by pipeline
+ boolean isGraphicsConfigSupported(GraphicsConfigTemplate3D gct,
+ GraphicsConfiguration gc) {
+ return true;
+ }
+
+ // Methods to get actual capabilities from Canvas3D
+ boolean hasDoubleBuffer(Canvas3D cv) {
+ return true;
+ }
+
+ boolean hasStereo(Canvas3D cv) {
+ return false;
+ }
+
+ int getStencilSize(Canvas3D cv) {
+ return 0;
+ }
+
+ boolean hasSceneAntialiasingMultisample(Canvas3D cv) {
+ return false;
+ }
+
+ boolean hasSceneAntialiasingAccum(Canvas3D cv) {
+ return false;
+ }
+
+ // Methods to get native WS display and screen
+ long getDisplay() {
+ return 0L;
+ }
+
+ int getScreen(GraphicsDevice graphicsDevice) {
+ return 0;
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // DrawingSurfaceObject methods
+ //
+
+ // Method to construct a new DrawingSurfaceObject
+ DrawingSurfaceObject createDrawingSurfaceObject(Canvas3D cv) {
+ return new NoopDrawingSurfaceObject(cv);
+ }
+
+ // Method to free the drawing surface object
+ void freeDrawingSurface(Canvas3D cv, DrawingSurfaceObject drawingSurfaceObject) {
+ // This method is a no-op
+ }
+
+ // Method to free the native drawing surface object
+ void freeDrawingSurfaceNative(Object o) {
+ // This method is a no-op
+ }
+
+ /**
+ * Dummy context for noop pipeline
+ */
+ static class NoopContext implements Context {
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/NotificationThread.java b/src/classes/share/javax/media/j3d/NotificationThread.java
index ac0598a..321213d 100644
--- a/src/classes/share/javax/media/j3d/NotificationThread.java
+++ b/src/classes/share/javax/media/j3d/NotificationThread.java
@@ -67,6 +67,9 @@ class NotificationThread extends Thread {
case J3dNotification.SHADER_ERROR:
n.universe.notifyShaderErrorListeners((ShaderError)n.args[0]);
break;
+ case J3dNotification.RENDERING_ERROR:
+ VirtualUniverse.notifyRenderingErrorListeners((RenderingError)n.args[0]);
+ break;
default:
System.err.println("J3dNotification.processNotifications: unrecognized type = " + n.type);
}
diff --git a/src/classes/share/javax/media/j3d/OrderedGroupRetained.java b/src/classes/share/javax/media/j3d/OrderedGroupRetained.java
index 5548178..f1bb2b9 100644
--- a/src/classes/share/javax/media/j3d/OrderedGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/OrderedGroupRetained.java
@@ -74,7 +74,7 @@ class OrderedGroupRetained extends GroupRetained {
System.arraycopy(cIOArr, 0, newArr,
0, newArr.length);
J3dMessage m;
- m = VirtualUniverse.mc.getMessage();
+ m = new J3dMessage();
m.threads = J3dThread.UPDATE_RENDER;
m.type = J3dMessage.ORDERED_GROUP_TABLE_CHANGED;
m.universe = universe;
diff --git a/src/classes/share/javax/media/j3d/OrientedShape3DRenderMethod.java b/src/classes/share/javax/media/j3d/OrientedShape3DRenderMethod.java
index 945f974..8153e13 100644
--- a/src/classes/share/javax/media/j3d/OrientedShape3DRenderMethod.java
+++ b/src/classes/share/javax/media/j3d/OrientedShape3DRenderMethod.java
@@ -21,7 +21,7 @@ package javax.media.j3d;
class OrientedShape3DRenderMethod implements RenderMethod {
- public boolean render(RenderMolecule rm, Canvas3D cv, int pass,
+ public boolean render(RenderMolecule rm, Canvas3D cv,
RenderAtomListInfo ra, int dirtyBits) {
boolean useAlpha;
boolean isNonUniformScale;
@@ -35,7 +35,7 @@ class OrientedShape3DRenderMethod implements RenderMethod {
rm.textureBin.attributeBin.ignoreVertexColors, cv.ctx);
if (rm.doInfinite) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
while (ra != null) {
trans = ra.infLocalToVworld;
isNonUniformScale = !trans.isCongruent();
@@ -44,10 +44,8 @@ class OrientedShape3DRenderMethod implements RenderMethod {
ra.geometry().execute(cv, ra.renderAtom, isNonUniformScale,
(useAlpha && ra.geometry().noAlpha),
rm.alpha,
- rm.renderBin.multiScreen,
cv.screen.screen,
- rm.textureBin.attributeBin.ignoreVertexColors,
- pass);
+ rm.textureBin.attributeBin.ignoreVertexColors);
ra = ra.next;
}
return true;
@@ -57,7 +55,7 @@ class OrientedShape3DRenderMethod implements RenderMethod {
while (ra != null) {
if (cv.ra == ra.renderAtom) {
if (cv.raIsVisible) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
trans = ra.localToVworld;
isNonUniformScale = !trans.isCongruent();
@@ -65,18 +63,16 @@ class OrientedShape3DRenderMethod implements RenderMethod {
ra.geometry().execute(cv, ra.renderAtom, isNonUniformScale,
(useAlpha && ra.geometry().noAlpha),
rm.alpha,
- rm.renderBin.multiScreen,
cv.screen.screen,
rm.textureBin.attributeBin.
- ignoreVertexColors,
- pass);
+ ignoreVertexColors);
isVisible = true;
}
}
else {
if (!VirtualUniverse.mc.viewFrustumCulling ||
ra.renderAtom.localeVwcBounds.intersect(cv.viewFrustum)) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
cv.raIsVisible = true;
trans = ra.localToVworld;
isNonUniformScale = !trans.isCongruent();
@@ -85,11 +81,9 @@ class OrientedShape3DRenderMethod implements RenderMethod {
ra.geometry().execute(cv, ra.renderAtom, isNonUniformScale,
(useAlpha && ra.geometry().noAlpha),
rm.alpha,
- rm.renderBin.multiScreen,
cv.screen.screen,
rm.textureBin.attributeBin.
- ignoreVertexColors,
- pass);
+ ignoreVertexColors);
isVisible = true;
}
else {
diff --git a/src/classes/share/javax/media/j3d/OrientedShape3DRetained.java b/src/classes/share/javax/media/j3d/OrientedShape3DRetained.java
index 7c007b9..044876f 100644
--- a/src/classes/share/javax/media/j3d/OrientedShape3DRetained.java
+++ b/src/classes/share/javax/media/j3d/OrientedShape3DRetained.java
@@ -228,7 +228,7 @@ class OrientedShape3DRetained extends Shape3DRetained {
}
void sendChangedMessage(int component, Object attr) {
- J3dMessage changeMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage changeMessage = new J3dMessage();
changeMessage.type = J3dMessage.ORIENTEDSHAPE3D_CHANGED;
changeMessage.threads = targetThreads ;
changeMessage.universe = universe;
diff --git a/src/classes/share/javax/media/j3d/Pipeline.java b/src/classes/share/javax/media/j3d/Pipeline.java
new file mode 100644
index 0000000..d06532a
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/Pipeline.java
@@ -0,0 +1,1403 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+
+/**
+ * Abstract pipeline class for rendering pipeline methods. All rendering
+ * pipeline methods are defined here.
+ */
+abstract class Pipeline {
+ // Singleton pipeline instance
+ private static Pipeline pipeline;
+
+ // Supported rendering pipelines
+ enum Type {
+ // Native rendering pipelines using OGL or D3D library
+ NATIVE_OGL,
+ NATIVE_D3D,
+
+ // Java rendering pipeline using Java Bindings for OpenGL
+ JOGL,
+
+ // No-op rendering pipeline
+ NOOP,
+ }
+
+ // Type of rendering pipeline (as defined above)
+ private Type pipelineType = null;
+
+ protected Pipeline() {
+ }
+
+ /**
+ * Initialize the Pipeline. Called exactly once by
+ * MasterControl.loadLibraries() to create the singleton
+ * Pipeline object.
+ */
+ static void createPipeline(Type pipelineType) {
+ String className = null;
+ switch (pipelineType) {
+ case NATIVE_OGL:
+ case NATIVE_D3D:
+ className = "javax.media.j3d.NativePipeline";
+ break;
+ case JOGL:
+ className = "javax.media.j3d.JoglPipeline";
+ break;
+ case NOOP:
+ className = "javax.media.j3d.NoopPipeline";
+ break;
+ default:
+ // Should not get here
+ throw new AssertionError("missing case statement");
+ }
+
+ final String pipelineClassName = className;
+ pipeline = (Pipeline)
+ java.security.AccessController.doPrivileged(new
+ java.security.PrivilegedAction() {
+ public Object run() {
+ try {
+ Class pipelineClass = Class.forName(pipelineClassName);
+ return pipelineClass.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+
+ pipeline.initialize(pipelineType);
+ }
+
+ /**
+ * Returns the singleton Pipeline object.
+ */
+ static Pipeline getPipeline() {
+ return pipeline;
+ }
+
+ /**
+ * Initializes the pipeline object. Only called by initPipeline.
+ * Pipeline subclasses may override this, but must call
+ * super.initialize(pipelineType);
+ */
+ void initialize(Type pipelineType) {
+ setPipelineType(pipelineType);
+ }
+
+ /**
+ * Sets the pipeline type. Only called by initialize.
+ */
+ private void setPipelineType(Type pipelineType) {
+ this.pipelineType = pipelineType;
+ }
+
+ /**
+ * Returns the pipeline type
+ */
+ Type getPipelineType() {
+ return pipelineType;
+ }
+
+ /**
+ * Returns the pipeline name
+ */
+ String getPipelineName() {
+ switch (pipelineType) {
+ case NATIVE_OGL:
+ return "NATIVE_OGL";
+ case NATIVE_D3D:
+ return "NATIVE_D3D";
+ case JOGL:
+ return "JOGL";
+ case NOOP:
+ return "NOOP";
+ default:
+ // Should not get here
+ throw new AssertionError("missing case statement");
+ }
+ }
+
+ /**
+ * Returns the renderer name
+ */
+ String getRendererName() {
+ switch (pipelineType) {
+ case NATIVE_OGL:
+ case JOGL:
+ return "OpenGL";
+ case NATIVE_D3D:
+ return "DirectX";
+ case NOOP:
+ return "None";
+ default:
+ // Should not get here
+ throw new AssertionError("missing case statement");
+ }
+ }
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Methods to initialize and load required libraries (from MasterControl)
+ //
+
+ /**
+ * Load all of the required libraries
+ */
+ abstract void loadLibraries(int globalShadingLanguage);
+
+ /**
+ * Returns true if the Cg library is loaded and available. Note that this
+ * does not necessarily mean that Cg is supported by the graphics card.
+ */
+ abstract boolean isCgLibraryAvailable();
+
+ /**
+ * Returns true if the GLSL library is loaded and available. Note that this
+ * does not necessarily mean that GLSL is supported by the graphics card.
+ */
+ abstract boolean isGLSLLibraryAvailable();
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GeometryArrayRetained methods
+ //
+
+ // Used by D3D to free vertex buffer
+ abstract void freeD3DArray(GeometryArrayRetained geo, boolean deleteVB);
+
+ // used for GeometryArrays by Copy or interleaved
+ abstract void execute(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[] varray, float[] cdata, int cdirty);
+
+ // used by GeometryArray by Reference with java arrays
+ abstract void executeVA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, float[] vfcoords, double[] vdcoords,
+ int colorIndex, float[] cfdata, byte[] cbdata,
+ int normalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty);
+
+ // used by GeometryArray by Reference with NIO buffer
+ abstract void executeVABuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex,
+ Object vcoords,
+ int colorIndex,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ int normalIndex, Object ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, Object[] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty);
+
+ // used by GeometryArray by Reference in interleaved format with NIO buffer
+ abstract void executeInterleavedBuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ Object varray, float[] cdata, int cdirty);
+
+ abstract void setVertexFormat(Context ctx, GeometryArrayRetained geo,
+ int vformat, boolean useAlpha, boolean ignoreVertexColors);
+
+ abstract void disableGlobalAlpha(Context ctx, GeometryArrayRetained geo, int vformat,
+ boolean useAlpha, boolean ignoreVertexColors);
+
+ // used for GeometryArrays
+ abstract void buildGA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int startVIndex,
+ int vcount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen, int[] texCoordSetMapOffset,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ double[] xform, double[] nxform,
+ float[] varray);
+
+ // used to Build Dlist GeometryArray by Reference with java arrays
+ abstract void buildGAForByRef(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, float[] vfcoords, double[] vdcoords,
+ int colorIndex, float[] cfdata, byte[] cbdata,
+ int normalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int[] texIndex, int texstride, Object[] texCoords,
+ double[] xform, double[] nxform);
+
+ // used to Build Dlist GeometryArray by Reference with NIO buffer
+ // NOTE: NIO buffers are no longer supported in display lists. We
+ // have no plans to add this support.
+ /*
+ abstract void buildGAForBuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, Object vcoords,
+ int colorIndex, Object cdata,
+ int normalIndex, Object ndata,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int[] texIndex, int texstride, Object[] texCoords,
+ double[] xform, double[] nxform);
+ */
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // IndexedGeometryArrayRetained methods
+ //
+
+ // by-copy or interleaved, by reference, Java arrays
+ abstract void executeIndexedGeometry(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ float[] varray, float[] cdata,
+ int cdirty,
+ int[] indexCoord);
+
+ // interleaved, by reference, nio buffer
+ abstract void executeIndexedGeometryBuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ Object varray, float[] cdata,
+ int cdirty,
+ int[] indexCoord);
+
+ // non interleaved, by reference, Java arrays
+ abstract void executeIndexedGeometryVA(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ float[] vfcoords, double[] vdcoords,
+ float[] cfdata, byte[] cbdata,
+ float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int texstride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord);
+
+ // non interleaved, by reference, nio buffer
+ abstract void executeIndexedGeometryVABuffer(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ Object vcoords,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ Object normal,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ Object[] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState,
+ int texstride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord);
+
+ // by-copy geometry
+ abstract void buildIndexedGeometry(Context ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int texCoordSetMapLen,
+ int[] texCoordSetMapOffset,
+ double[] xform, double[] nxform,
+ float[] varray, int[] indexCoord);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GraphicsContext3D methods
+ //
+
+ // Native method for readRaster
+ abstract void readRaster(Context ctx,
+ int type, int xSrcOffset, int ySrcOffset,
+ int width, int height, int hCanvas,
+ int imageDataType,
+ int imageFormat,
+ Object imageBuffer,
+ int depthFormat,
+ Object depthBuffer);
+
+ // ---------------------------------------------------------------------
+
+ //
+ // CgShaderProgramRetained methods
+ //
+
+ // ShaderAttributeValue methods
+
+ abstract ShaderError setCgUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int value);
+
+ abstract ShaderError setCgUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float value);
+
+ abstract ShaderError setCgUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value);
+
+ abstract ShaderError setCgUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value);
+
+ abstract ShaderError setCgUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value);
+
+ abstract ShaderError setCgUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value);
+
+ abstract ShaderError setCgUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value);
+
+ abstract ShaderError setCgUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value);
+
+ abstract ShaderError setCgUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value);
+
+ abstract ShaderError setCgUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value);
+
+ // ShaderAttributeArray methods
+
+ abstract ShaderError setCgUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setCgUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setCgUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setCgUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setCgUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setCgUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setCgUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setCgUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setCgUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setCgUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ // abstract interfaces for shader compilation, etc.
+ abstract ShaderError createCgShader(Context ctx, int shaderType, ShaderId[] shaderId);
+ abstract ShaderError destroyCgShader(Context ctx, ShaderId shaderId);
+ abstract ShaderError compileCgShader(Context ctx, ShaderId shaderId, String program);
+
+ abstract ShaderError createCgShaderProgram(Context ctx, ShaderProgramId[] shaderProgramId);
+ abstract ShaderError destroyCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId);
+ abstract ShaderError linkCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId,
+ ShaderId[] shaderIds);
+ abstract void lookupCgVertexAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, boolean[] errArr);
+ abstract void lookupCgShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, ShaderAttrLoc[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr);
+
+ abstract ShaderError useCgShaderProgram(Context ctx, ShaderProgramId shaderProgramId);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // GLSLShaderProgramRetained methods
+ //
+
+ // ShaderAttributeValue methods
+
+ abstract ShaderError setGLSLUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int value);
+
+ abstract ShaderError setGLSLUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float value);
+
+ abstract ShaderError setGLSLUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value);
+
+ abstract ShaderError setGLSLUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value);
+
+ abstract ShaderError setGLSLUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value);
+
+ abstract ShaderError setGLSLUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value);
+
+ abstract ShaderError setGLSLUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int[] value);
+
+ abstract ShaderError setGLSLUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value);
+
+ abstract ShaderError setGLSLUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value);
+
+ abstract ShaderError setGLSLUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ float[] value);
+
+ // ShaderAttributeArray methods
+
+ abstract ShaderError setGLSLUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setGLSLUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setGLSLUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setGLSLUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setGLSLUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setGLSLUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setGLSLUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setGLSLUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setGLSLUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setGLSLUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
+ int numElements,
+ float[] value);
+
+ // abstract interfaces for shader compilation, etc.
+ abstract ShaderError createGLSLShader(Context ctx, int shaderType, ShaderId[] shaderId);
+ abstract ShaderError destroyGLSLShader(Context ctx, ShaderId shaderId);
+ abstract ShaderError compileGLSLShader(Context ctx, ShaderId shaderId, String program);
+
+ abstract ShaderError createGLSLShaderProgram(Context ctx, ShaderProgramId[] shaderProgramId);
+ abstract ShaderError destroyGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId);
+ abstract ShaderError linkGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId,
+ ShaderId[] shaderIds);
+ abstract ShaderError bindGLSLVertexAttrName(Context ctx, ShaderProgramId shaderProgramId,
+ String attrName, int attrIndex);
+ abstract void lookupGLSLShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId,
+ int numAttrNames, String[] attrNames, ShaderAttrLoc[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr);
+
+ abstract ShaderError useGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ImageComponent2DRetained methods
+ //
+
+ // free d3d surface referred to by id
+ abstract void freeD3DSurface(ImageComponent2DRetained image, int hashId);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // J3DBuffer methods
+ //
+
+ // Method to verify that we can access a direct NIO buffer
+ // from native code
+ boolean checkNativeBufferAccess(java.nio.Buffer buffer) {
+ // Return true by default. Pipeline can override and implement, if
+ // we decide that it is necessary.
+ return true;
+ }
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Renderer methods
+ //
+
+ abstract void cleanupRenderer();
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ColoringAttributesRetained methods
+ //
+
+ abstract void updateColoringAttributes(Context ctx,
+ float dRed, float dGreen, float dBlue,
+ float red, float green, float blue,
+ float alpha,
+ boolean lEnable,
+ int shadeModel);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // DirectionalLightRetained methods
+ //
+
+ abstract void updateDirectionalLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float x, float y, float z);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PointLightRetained methods
+ //
+
+ abstract void updatePointLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float ax, float ay, float az,
+ float px, float py, float pz);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // SpotLightRetained methods
+ //
+
+ abstract void updateSpotLight(Context ctx,
+ int lightSlot, float red, float green,
+ float blue, float ax, float ay, float az,
+ float px, float py, float pz, float spreadAngle,
+ float concentration, float dx, float dy,
+ float dz);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ExponentialFogRetained methods
+ //
+
+ abstract void updateExponentialFog(Context ctx,
+ float red, float green, float blue,
+ float density);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // LinearFogRetained methods
+ //
+
+ abstract void updateLinearFog(Context ctx,
+ float red, float green, float blue,
+ double fdist, double bdist);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // LineAttributesRetained methods
+ //
+
+ abstract void updateLineAttributes(Context ctx,
+ float lineWidth, int linePattern,
+ int linePatternMask,
+ int linePatternScaleFactor,
+ boolean lineAntialiasing);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // MaterialRetained methods
+ //
+
+ abstract void updateMaterial(Context ctx,
+ float red, float green, float blue, float alpha,
+ float ared, float agreen, float ablue,
+ float ered, float egreen, float eblue,
+ float dred, float dgreen, float dblue,
+ float sred, float sgreen, float sblue,
+ float shininess, int colorTarget, boolean enable);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // ModelClipRetained methods
+ //
+
+ abstract void updateModelClip(Context ctx, int planeNum, boolean enableFlag,
+ double A, double B, double C, double D);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PointAttributesRetained methods
+ //
+
+ abstract void updatePointAttributes(Context ctx, float pointSize, boolean pointAntialiasing);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // PolygonAttributesRetained methods
+ //
+
+ abstract void updatePolygonAttributes(Context ctx,
+ int polygonMode, int cullFace,
+ boolean backFaceNormalFlip,
+ float polygonOffset,
+ float polygonOffsetFactor);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // RenderingAttributesRetained methods
+ //
+
+ abstract void updateRenderingAttributes(Context ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride,
+ boolean depthBufferEnable,
+ boolean depthBufferWriteEnable,
+ int depthTestFunction,
+ float alphaTestValue, int alphaTestFunction,
+ boolean ignoreVertexColors,
+ boolean rasterOpEnable, int rasterOp,
+ boolean userStencilAvailable, boolean stencilEnable,
+ int stencilFailOp, int stencilZFailOp, int stencilZPassOp,
+ int stencilFunction, int stencilReferenceValue,
+ int stencilCompareMask, int stencilWriteMask );
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TexCoordGenerationRetained methods
+ //
+
+ /**
+ * This method updates the native context:
+ * trans contains eyeTovworld transform in d3d
+ * trans contains vworldToEye transform in ogl
+ */
+ abstract void updateTexCoordGeneration(Context ctx,
+ boolean enable, int genMode, int format,
+ float planeSx, float planeSy, float planeSz, float planeSw,
+ float planeTx, float planeTy, float planeTz, float planeTw,
+ float planeRx, float planeRy, float planeRz, float planeRw,
+ float planeQx, float planeQy, float planeQz, float planeQw,
+ double[] trans);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TransparencyAttributesRetained methods
+ //
+
+ abstract void updateTransparencyAttributes(Context ctx,
+ float alpha, int geometryType,
+ int polygonMode,
+ boolean lineAA, boolean pointAA,
+ int transparencyMode,
+ int srcBlendFunction,
+ int dstBlendFunction);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureAttributesRetained methods
+ //
+
+ abstract void updateTextureAttributes(Context ctx,
+ double[] transform, boolean isIdentity, int textureMode,
+ int perspCorrectionMode, float red,
+ float green, float blue, float alpha,
+ int textureFormat);
+
+ abstract void updateRegisterCombiners(Context ctx,
+ double[] transform, boolean isIdentity, int textureMode,
+ int perspCorrectionMode, float red,
+ float green, float blue, float alpha,
+ int textureFormat,
+ int combineRgbMode, int combineAlphaMode,
+ int[] combineRgbSrc, int[] combineAlphaSrc,
+ int[] combineRgbFcn, int[] combineAlphaFcn,
+ int combineRgbScale, int combineAlphaScale);
+
+ abstract void updateTextureColorTable(Context ctx, int numComponents,
+ int colorTableSize,
+ int[] colorTable);
+
+ abstract void updateCombiner(Context ctx,
+ int combineRgbMode, int combineAlphaMode,
+ int[] combineRgbSrc, int[] combineAlphaSrc,
+ int[] combineRgbFcn, int[] combineAlphaFcn,
+ int combineRgbScale, int combineAlphaScale);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureUnitStateRetained methods
+ //
+
+ abstract void updateTextureUnitState(Context ctx, int unitIndex, boolean enableFlag);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureRetained methods
+ // Texture2DRetained methods
+ //
+
+ abstract void bindTexture2D(Context ctx, int objectId, boolean enable);
+
+ abstract void updateTexture2DImage(Context ctx,
+ int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int imageDataType, Object data);
+
+ abstract void updateTexture2DSubImage(Context ctx,
+ int level, int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int imageDataType, Object data);
+
+ abstract void updateTexture2DLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod);
+
+ abstract void updateTexture2DLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ);
+
+ abstract void updateTexture2DBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha);
+
+ abstract void updateTexture2DFilterModes(Context ctx,
+ int minFilter, int magFilter);
+
+ abstract void updateTexture2DSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts);
+
+ abstract void updateTexture2DFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts);
+
+ abstract void updateTexture2DAnisotropicFilter(Context ctx, float degree);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Texture3DRetained methods
+ //
+
+ abstract void bindTexture3D(Context ctx, int objectId, boolean enable);
+
+ abstract void updateTexture3DImage(Context ctx,
+ int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height, int depth,
+ int boundaryWidth,
+ int imageDataType, Object imageData);
+
+ abstract void updateTexture3DSubImage(Context ctx,
+ int level,
+ int xoffset, int yoffset, int zoffset,
+ int textureFormat, int imageFormat,
+ int imgXoffset, int imgYoffset, int imgZoffset,
+ int tilew, int tileh,
+ int width, int height, int depth,
+ int imageDataType, Object imageData);
+
+ abstract void updateTexture3DLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod);
+
+ abstract void updateTexture3DLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ);
+
+ abstract void updateTexture3DBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ int boundaryModeR, float boundaryRed,
+ float boundaryGreen, float boundaryBlue,
+ float boundaryAlpha);
+
+ abstract void updateTexture3DFilterModes(Context ctx,
+ int minFilter, int magFilter);
+
+ abstract void updateTexture3DSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts);
+
+ abstract void updateTexture3DFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts);
+
+ abstract void updateTexture3DAnisotropicFilter(Context ctx, float degree);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // TextureCubeMapRetained methods
+ //
+
+ abstract void bindTextureCubeMap(Context ctx, int objectId, boolean enable);
+
+ abstract void updateTextureCubeMapImage(Context ctx,
+ int face, int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int imageDataType, Object imageData);
+
+ abstract void updateTextureCubeMapSubImage(Context ctx,
+ int face, int level, int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int imageDataType, Object imageData);
+
+ abstract void updateTextureCubeMapLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod);
+
+ abstract void updateTextureCubeMapLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ);
+
+ abstract void updateTextureCubeMapBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha);
+
+ abstract void updateTextureCubeMapFilterModes(Context ctx,
+ int minFilter, int magFilter);
+
+ abstract void updateTextureCubeMapSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts);
+
+ abstract void updateTextureCubeMapFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts);
+
+ abstract void updateTextureCubeMapAnisotropicFilter(Context ctx, float degree);
+
+ // ---------------------------------------------------------------------
+
+ //
+ // MasterControl methods
+ //
+
+ // Method to return the AWT object
+ abstract long getAWT();
+
+ // Method to initialize the native J3D library
+ abstract boolean initializeJ3D(boolean disableXinerama);
+
+ // Maximum lights supported by the native API
+ abstract int getMaximumLights();
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Canvas3D methods - native wrappers
+ //
+
+ // This is the native method for creating the underlying graphics context.
+ abstract Context createNewContext(Canvas3D cv, long display, Drawable drawable,
+ long fbConfig, Context shareCtx, boolean isSharedCtx,
+ boolean offScreen,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable);
+
+ abstract void createQueryContext(Canvas3D cv, long display, Drawable drawable,
+ long fbConfig, boolean offScreen, int width, int height,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable);
+
+ // This is the native for creating offscreen buffer
+ abstract Drawable createOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, int width, int height);
+
+ abstract void destroyOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, Drawable drawable);
+
+ // This is the native for reading the image from the offscreen buffer
+ abstract void readOffScreenBuffer(Canvas3D cv, Context ctx, int format, int type, Object data, int width, int height);
+
+ // The native method for swapBuffers
+ abstract int swapBuffers(Canvas3D cv, Context ctx, long dpy, Drawable drawable);
+
+ // notify D3D that Canvas is resize
+ abstract int resizeD3DCanvas(Canvas3D cv, Context ctx);
+
+ // notify D3D to toggle between FullScreen and window mode
+ abstract int toggleFullScreenMode(Canvas3D cv, Context ctx);
+
+ // native method for setting Material when no material is present
+ abstract void updateMaterialColor(Context ctx, float r, float g, float b, float a);
+
+ abstract void destroyContext(long display, Drawable drawable, Context ctx);
+
+ // This is the native method for doing accumulation.
+ abstract void accum(Context ctx, float value);
+
+ // This is the native method for doing accumulation return.
+ abstract void accumReturn(Context ctx);
+
+ // This is the native method for clearing the accumulation buffer.
+ abstract void clearAccum(Context ctx);
+
+ // This is the native method for getting the number of lights the underlying
+ // native library can support.
+ abstract int getNumCtxLights(Context ctx);
+
+ // Native method for decal 1st child setup
+ abstract boolean decal1stChildSetup(Context ctx);
+
+ // Native method for decal nth child setup
+ abstract void decalNthChildSetup(Context ctx);
+
+ // Native method for decal reset
+ abstract void decalReset(Context ctx, boolean depthBufferEnable);
+
+ // Native method for decal reset
+ abstract void ctxUpdateEyeLightingEnable(Context ctx, boolean localEyeLightingEnable);
+
+ // The following three methods are used in multi-pass case
+
+ // native method for setting blend color
+ abstract void setBlendColor(Context ctx, float red, float green,
+ float blue, float alpha);
+
+ // native method for setting blend func
+ abstract void setBlendFunc(Context ctx, int src, int dst);
+
+ // native method for setting fog enable flag
+ abstract void setFogEnableFlag(Context ctx, boolean enableFlag);
+
+ // Setup the full scene antialising in D3D and ogl when GL_ARB_multisamle supported
+ abstract void setFullSceneAntialiasing(Context ctx, boolean enable);
+
+ abstract void setGlobalAlpha(Context ctx, float alpha);
+
+ // Native method to update separate specular color control
+ abstract void updateSeparateSpecularColorEnable(Context ctx, boolean control);
+
+ // Initialization for D3D when scene begin
+ abstract void beginScene(Context ctx);
+ abstract void endScene(Context ctx);
+
+ // True under Solaris,
+ // False under windows when display mode <= 8 bit
+ abstract boolean validGraphicsMode();
+
+ // native method for setting light enables
+ abstract void setLightEnables(Context ctx, long enableMask, int maxLights);
+
+ // native method for setting scene ambient
+ abstract void setSceneAmbient(Context ctx, float red, float green, float blue);
+
+ // native method for disabling fog
+ abstract void disableFog(Context ctx);
+
+ // native method for disabling modelClip
+ abstract void disableModelClip(Context ctx);
+
+ // native method for setting default RenderingAttributes
+ abstract void resetRenderingAttributes(Context ctx,
+ boolean depthBufferWriteEnableOverride,
+ boolean depthBufferEnableOverride);
+
+ // native method for setting default texture
+ abstract void resetTextureNative(Context ctx, int texUnitIndex);
+
+ // native method for activating a particular texture unit
+ abstract void activeTextureUnit(Context ctx, int texUnitIndex);
+
+ // native method for setting default TexCoordGeneration
+ abstract void resetTexCoordGeneration(Context ctx);
+
+ // native method for setting default TextureAttributes
+ abstract void resetTextureAttributes(Context ctx);
+
+ // native method for setting default PolygonAttributes
+ abstract void resetPolygonAttributes(Context ctx);
+
+ // native method for setting default LineAttributes
+ abstract void resetLineAttributes(Context ctx);
+
+ // native method for setting default PointAttributes
+ abstract void resetPointAttributes(Context ctx);
+
+ // native method for setting default TransparencyAttributes
+ abstract void resetTransparency(Context ctx, int geometryType,
+ int polygonMode, boolean lineAA,
+ boolean pointAA);
+
+ // native method for setting default ColoringAttributes
+ abstract void resetColoringAttributes(Context ctx,
+ float r, float g,
+ float b, float a,
+ boolean enableLight);
+
+ /**
+ * This native method makes sure that the rendering for this canvas
+ * gets done now.
+ */
+ abstract void syncRender(Context ctx, boolean wait);
+
+ // The native method that sets this ctx to be the current one
+ abstract boolean useCtx(Context ctx, long display, Drawable drawable);
+
+ // Optionally release the context. A pipeline may override this and
+ // returns true if the context was released.
+ boolean releaseCtx(Context ctx, long dpy) {
+ return false;
+ }
+
+ abstract void clear(Context ctx, float r, float g, float b);
+
+ abstract void textureFillBackground(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY);
+
+ abstract void textureFillRaster(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
+ float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, float mapZ, float alpha);
+
+ abstract void executeRasterDepth(Context ctx, float posX, float posY, float posZ,
+ int srcOffsetX, int srcOffsetY, int rasterWidth, int rasterHeight, int depthWidth, int depthHeight,
+ int depthType, Object depthData);
+
+ // The native method for setting the ModelView matrix.
+ abstract void setModelViewMatrix(Context ctx, double[] viewMatrix, double[] modelMatrix);
+
+ // The native method for setting the Projection matrix.
+ abstract void setProjectionMatrix(Context ctx, double[] projMatrix);
+
+ // The native method for setting the Viewport.
+ abstract void setViewport(Context ctx, int x, int y, int width, int height);
+
+ // used for display Lists
+ abstract void newDisplayList(Context ctx, int displayListId);
+ abstract void endDisplayList(Context ctx);
+ abstract void callDisplayList(Context ctx, int id, boolean isNonUniformScale);
+
+ abstract void freeDisplayList(Context ctx, int id);
+ abstract void freeTexture(Context ctx, int id);
+
+ abstract void texturemapping(Context ctx,
+ int px, int py,
+ int xmin, int ymin, int xmax, int ymax,
+ int texWidth, int texHeight,
+ int rasWidth,
+ int format, int objectId,
+ byte[] image,
+ int winWidth, int winHeight);
+
+ abstract boolean initTexturemapping(Context ctx, int texWidth,
+ int texHeight, int objectId);
+
+
+ // Set internal render mode to one of FIELD_ALL, FIELD_LEFT or
+ // FIELD_RIGHT. Note that it is up to the caller to ensure that
+ // stereo is available before setting the mode to FIELD_LEFT or
+ // FIELD_RIGHT. The boolean isTRUE for double buffered mode, FALSE
+ // foe single buffering.
+ abstract void setRenderMode(Context ctx, int mode, boolean doubleBuffer);
+
+ // Set glDepthMask.
+ abstract void setDepthBufferWriteEnable(Context ctx, boolean mode);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // Canvas3D / GraphicsConfigTemplate3D methods - logic dealing with
+ // native graphics configuration or drawing surface
+ //
+
+ // Return a graphics config based on the one passed in. Note that we can
+ // assert that the input config is non-null and was created from a
+ // GraphicsConfigTemplate3D.
+ // This method must return a valid GraphicsConfig, or else it must throw
+ // an exception if one cannot be returned.
+ abstract GraphicsConfiguration getGraphicsConfig(GraphicsConfiguration gconfig);
+
+ // Get the native FBconfig pointer
+ abstract long getFbConfig(GraphicsConfigInfo gcInfo);
+
+ // Get best graphics config from pipeline
+ abstract GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate3D gct,
+ GraphicsConfiguration[] gc);
+
+ // Determine whether specified graphics config is supported by pipeline
+ abstract boolean isGraphicsConfigSupported(GraphicsConfigTemplate3D gct,
+ GraphicsConfiguration gc);
+
+ // Methods to get actual capabilities from Canvas3D
+ abstract boolean hasDoubleBuffer(Canvas3D cv);
+ abstract boolean hasStereo(Canvas3D cv);
+ abstract int getStencilSize(Canvas3D cv);
+ abstract boolean hasSceneAntialiasingMultisample(Canvas3D cv);
+ abstract boolean hasSceneAntialiasingAccum(Canvas3D cv);
+
+ // Methods to get native WS display and screen
+ abstract long getDisplay();
+ abstract int getScreen(GraphicsDevice graphicsDevice);
+
+
+ // ---------------------------------------------------------------------
+
+ //
+ // DrawingSurfaceObject methods
+ //
+
+ // Method to construct a new DrawingSurfaceObject
+ abstract DrawingSurfaceObject createDrawingSurfaceObject(Canvas3D cv);
+
+ // Method to free the drawing surface object
+ abstract void freeDrawingSurface(Canvas3D cv, DrawingSurfaceObject drawingSurfaceObject);
+
+ // Method to free the native drawing surface object
+ abstract void freeDrawingSurfaceNative(Object o);
+
+}
diff --git a/src/classes/share/javax/media/j3d/PointAttributesRetained.java b/src/classes/share/javax/media/j3d/PointAttributesRetained.java
index b5d7536..207119b 100644
--- a/src/classes/share/javax/media/j3d/PointAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/PointAttributesRetained.java
@@ -112,13 +112,8 @@ class PointAttributesRetained extends NodeComponentRetained {
/**
* Update the native context
*/
- native void updateNative(long ctx, float pointSize, boolean pointAntialiasing);
-
- /**
- * Update the native context
- */
- void updateNative(long ctx) {
- updateNative(ctx, pointSize, pointAntialiasing);
+ void updateNative(Context ctx) {
+ Pipeline.getPipeline().updatePointAttributes(ctx, pointSize, pointAntialiasing);
}
@@ -167,7 +162,7 @@ class PointAttributesRetained extends NodeComponentRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.POINTATTRIBUTES_CHANGED;
createMessage.universe = null;
@@ -180,7 +175,7 @@ class PointAttributesRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.POINTATTRIBUTES_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/PointLightRetained.java b/src/classes/share/javax/media/j3d/PointLightRetained.java
index 34f390e..d93926f 100644
--- a/src/classes/share/javax/media/j3d/PointLightRetained.java
+++ b/src/classes/share/javax/media/j3d/PointLightRetained.java
@@ -173,18 +173,14 @@ class PointLightRetained extends LightRetained {
* updates a point light. This includes its color, attenuation,
* and its transformed position.
*/
- native void updateLight(long ctx, int lightSlot, float red, float green,
- float blue, float ax, float ay, float az,
- float px, float py, float pz);
-
- void update(long ctx, int lightSlot, double scale) {
+ void update(Context ctx, int lightSlot, double scale) {
validateAttenuationInEc(scale);
- updateLight(ctx, lightSlot, color.x, color.y, color.z,
- attenuation.x, linearAttenuationInEc,
- quadraticAttenuationInEc,
- xformPosition.x, xformPosition.y,
- xformPosition.z);
-
+ Pipeline.getPipeline().updatePointLight(ctx,
+ lightSlot, color.x, color.y, color.z,
+ attenuation.x, linearAttenuationInEc,
+ quadraticAttenuationInEc,
+ xformPosition.x, xformPosition.y,
+ xformPosition.z);
}
void setLive(SetLiveState s) {
@@ -300,7 +296,7 @@ class PointLightRetained extends LightRetained {
void sendMessage(int attrMask, Object attr) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.universe = universe;
createMessage.type = J3dMessage.LIGHT_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/PolygonAttributesRetained.java b/src/classes/share/javax/media/j3d/PolygonAttributesRetained.java
index 1dbcc6c..243c6db 100644
--- a/src/classes/share/javax/media/j3d/PolygonAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/PolygonAttributesRetained.java
@@ -235,19 +235,10 @@ class PolygonAttributesRetained extends NodeComponentRetained {
/**
* Updates the native context
*/
- native void updateNative(long ctx,
- int polygonMode, int cullFace,
- boolean backFaceNormalFlip,
- float polygonOffset,
- float polygonOffsetFactor);
-
- /**
- * Updates the native context
- */
- void updateNative(long ctx) {
- updateNative(ctx,
- polygonMode, cullFace, backFaceNormalFlip,
- polygonOffset, polygonOffsetFactor);
+ void updateNative(Context ctx) {
+ Pipeline.getPipeline().updatePolygonAttributes(ctx,
+ polygonMode, cullFace, backFaceNormalFlip,
+ polygonOffset, polygonOffsetFactor);
}
/**
@@ -308,7 +299,7 @@ class PolygonAttributesRetained extends NodeComponentRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.POLYGONATTRIBUTES_CHANGED;
createMessage.universe = null;
@@ -320,7 +311,7 @@ class PolygonAttributesRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.POLYGONATTRIBUTES_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/QuadArrayRetained.java b/src/classes/share/javax/media/j3d/QuadArrayRetained.java
index a2ceb62..ab47626 100644
--- a/src/classes/share/javax/media/j3d/QuadArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/QuadArrayRetained.java
@@ -438,13 +438,13 @@ class QuadArrayRetained extends GeometryArrayRetained {
int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
initialVertexIndex : initialCoordIndex);
- Point3d pnt0 = getPoint3d();
- Point3d pnt1 = getPoint3d();
- Point3d pnt2 = getPoint3d();
- Point3d pnt3 = getPoint3d();
- Vector3d vec = getVector3d();
- Vector3d normal = getVector3d();
- Vector3d tmpvec = getVector3d();
+ Point3d pnt0 = new Point3d();
+ Point3d pnt1 = new Point3d();
+ Point3d pnt2 = new Point3d();
+ Point3d pnt3 = new Point3d();
+ Vector3d vec = new Vector3d();
+ Vector3d normal = new Vector3d();
+ Vector3d tmpvec = new Vector3d();
double area;
double totalarea = 0;
@@ -497,13 +497,6 @@ class QuadArrayRetained extends GeometryArrayRetained {
centroid.y *= area;
centroid.z *= area;
}
- freeVector3d(tmpvec);
- freeVector3d(vec);
- freeVector3d(normal);
- freePoint3d(pnt0);
- freePoint3d(pnt1);
- freePoint3d(pnt2);
- freePoint3d(pnt3);
}
int getClassType() {
diff --git a/src/classes/share/javax/media/j3d/Raster.java b/src/classes/share/javax/media/j3d/Raster.java
index f65cd07..1bdbe55 100644
--- a/src/classes/share/javax/media/j3d/Raster.java
+++ b/src/classes/share/javax/media/j3d/Raster.java
@@ -226,6 +226,9 @@ public class Raster extends Geometry {
* color data
* @param depthComponent the DepthComponent object containing the depth
* (z-buffer) data
+ *
+ * @exception IllegalArgumentException if the image class of the specified
+ * ImageComponent2D is ImageClass.NIO_IMAGE_BUFFER.
*/
public Raster(Point3f pos,
int type,
@@ -259,7 +262,10 @@ public class Raster extends Geometry {
* @param image the ImageComponent2D object containing the
* color data
* @param depthComponent the DepthComponent object containing the depth
- * (z-buffer) data
+ * (z-buffer) data
+ *
+ * @exception IllegalArgumentException if the image class of the specified
+ * ImageComponent2D is ImageClass.NIO_IMAGE_BUFFER.
*/
public Raster(Point3f pos,
int type,
@@ -297,6 +303,9 @@ public class Raster extends Geometry {
* @param depthComponent the DepthComponent object containing the depth
* (z-buffer) data
*
+ * @exception IllegalArgumentException if the image class of the specified
+ * ImageComponent2D is ImageClass.NIO_IMAGE_BUFFER.
+ *
* @since Java 3D 1.3
*/
public Raster(Point3f pos,
@@ -308,6 +317,7 @@ public class Raster extends Geometry {
ImageComponent2D image,
DepthComponent depthComponent) {
+
// set default read capabilities
setDefaultReadCapabilities(readCapabilities);
@@ -617,15 +627,36 @@ public class Raster extends Geometry {
/**
* Sets the pixel array used to copy pixels to/from a Canvas3D.
* This is used when the type is RASTER_COLOR or RASTER_COLOR_DEPTH.
+ *
* @param image the ImageComponent2D object containing the
* color data
+ *
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalSharingException if this Raster is live and
+ * the specified image is being used by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalArgumentException if the image class of the specified
+ * ImageComponent2D is ImageClass.NIO_IMAGE_BUFFER.
+ *
*/
public void setImage(ImageComponent2D image) {
+
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_IMAGE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Raster3"));
+
+ // Do illegal sharing check
+ if(image != null) {
+ ImageComponent2DRetained imageRetained = (ImageComponent2DRetained) image.retained;
+ if(imageRetained.getUsedByOffScreen()) {
+ if(isLive()) {
+ throw new IllegalSharingException(J3dI18N.getString("Raster12"));
+ }
+ }
+ }
+
((RasterRetained)this.retained).setImage(image);
}
diff --git a/src/classes/share/javax/media/j3d/RasterRetained.java b/src/classes/share/javax/media/j3d/RasterRetained.java
index 85356a7..5a20a45 100644
--- a/src/classes/share/javax/media/j3d/RasterRetained.java
+++ b/src/classes/share/javax/media/j3d/RasterRetained.java
@@ -31,37 +31,20 @@ class RasterRetained extends GeometryRetained {
*/
int type = Raster.RASTER_COLOR;
- int clipMode = Raster.CLIP_POSITION;
- Point3f position = new Point3f();
- int xSrcOffset = 0;
- int ySrcOffset = 0;
-
- // Used internally in CLIP_IMAGE mode
- private int xOffset = 0;
- private int yOffset = 0;
-
- int width = 0;
- int height = 0;
- int xDstOffset = 0;
- int yDstOffset = 0;
+ private int clipMode = Raster.CLIP_POSITION;
+ private Point3f position = new Point3f();
+ private int xSrcOffset = 0;
+ private int ySrcOffset = 0;
+ private int width = 0;
+ private int height = 0;
+ private int xDstOffset = 0;
+ private int yDstOffset = 0;
ImageComponent2DRetained image = null;
+ Texture2DRetained texture = null;
DepthComponentRetained depthComponent = null;
- float lastAlpha = 1.0f;
-
- private Point3d adjPos; // Position of the Raster after adjusting for dstOffset
- private Point2d winCoord; // Position of Raster in window coordinates
- private Transform3D vwip; // Vworld to Image plate transform
- // false when computeWinCoord() get null RenderMolecule.
- // In this case rendering is skip.
- private boolean validVwip;
-
RasterRetained() {
this.geoType = GEO_TYPE_RASTER;
-
- vwip = new Transform3D();
- adjPos = new Point3d();
- winCoord = new Point2d();
}
/**
@@ -183,18 +166,16 @@ class RasterRetained extends GeometryRetained {
this.width = width;
this.height = height;
geomLock.unLock();
- }
-
+ }
/**
- * Sets the size of the array of pixels to be copied.
+ * Gets the size of the array of pixels to be copied.
* @param size the new size
*/
final void getSize(Dimension size) {
size.setSize(width, height);
}
-
/**
* Sets the destination pixel offset of the upper-left
* corner of the rendered image relative to the transformed position.
@@ -218,42 +199,79 @@ class RasterRetained extends GeometryRetained {
/**
+ * Initializes the raster image to the specified image.
+ * @param image new ImageCompoent2D object used as the raster image
+ */
+ final void initImage(ImageComponent2D img) {
+
+ int texFormat;
+
+ if(img == null) {
+ image = null;
+ texture = null;
+ return;
+ }
+
+ image = (ImageComponent2DRetained) img.retained;
+ image.setEnforceNonPowerOfTwoSupport(true);
+ switch(image.getNumberOfComponents()) {
+ case 1:
+ texFormat = Texture.INTENSITY;
+ break;
+ case 2:
+ texFormat = Texture.LUMINANCE_ALPHA;
+ break;
+ case 3:
+ texFormat = Texture.RGB;
+ break;
+ case 4:
+ texFormat = Texture.RGBA;
+ break;
+ default:
+ assert false;
+ return;
+ }
+
+ Texture2D tex2D = new Texture2D(Texture.BASE_LEVEL, texFormat,
+ img.getWidth(), img.getHeight());
+ texture = (Texture2DRetained) tex2D.retained;
+ texture.setUseAsRaster(true);
+ texture.initImage(0,img);
+
+ }
+
+ /**
* Sets the pixel array used to copy pixels to/from a Canvas3D.
* This is used when the type is RASTER_COLOR or RASTER_COLOR_DEPTH.
* @param image the ImageComponent2D object containing the
* color data
*/
- final void setImage(ImageComponent2D image) {
- ImageComponent2DRetained oldImage = this.image;
-
- if (this.source.isLive()) {
-
- if (this.image != null) {
- this.image.clearLive(refCount);
- }
- if (image != null) {
- ((ImageComponent2DRetained)image.retained).setLive(inBackgroundGroup, refCount);
- }
- }
-
- geomLock.getLock();
- if (image != null) {
- ImageComponent2DRetained rimage =
- (ImageComponent2DRetained)image.retained;
- rimage.setRasterRef();
- this.image = rimage;
- } else {
- this.image = null;
- }
-
-
-
- // Set the lastAlpha to 1.0f
- lastAlpha = 1.0f;
- geomLock.unLock();
- sendChangedMessage((J3dThread.UPDATE_RENDER|J3dThread.UPDATE_RENDERING_ATTRIBUTES),
- oldImage, this.image);
- }
+ final void setImage(ImageComponent2D img) {
+
+ if((img != null) &&
+ (img.getImageClass() == ImageComponent.ImageClass.NIO_IMAGE_BUFFER)) {
+ throw new IllegalArgumentException(J3dI18N.getString("Background14"));
+ }
+
+ TextureRetained oldTex = this.texture;
+ geomLock.getLock();
+ if (source.isLive()) {
+ if (this.texture != null) {
+ this.texture.clearLive(refCount);
+ }
+ }
+
+ initImage(img);
+ if (source.isLive()) {
+ if (texture != null) {
+ texture.setLive(inBackgroundGroup, refCount);
+ }
+
+ sendChangedMessage((J3dThread.UPDATE_RENDER|J3dThread.UPDATE_RENDERING_ATTRIBUTES),
+ oldTex, this.texture);
+ }
+ geomLock.unLock();
+ }
/**
* Retrieves the current pixel array object.
@@ -271,7 +289,8 @@ class RasterRetained extends GeometryRetained {
* depth (z-buffer) data
*/
final void setDepthComponent(DepthComponent depthComponent) {
- if (this.source.isLive()) {
+ geomLock.getLock();
+ if (this.source.isLive()) {
if (this.depthComponent != null) {
this.depthComponent.clearLive(refCount);
}
@@ -279,7 +298,7 @@ class RasterRetained extends GeometryRetained {
((DepthComponentRetained)depthComponent.retained).setLive(inBackgroundGroup, refCount);
}
}
- geomLock.getLock();
+
if (depthComponent == null) {
this.depthComponent = null;
} else {
@@ -301,8 +320,8 @@ class RasterRetained extends GeometryRetained {
void setLive(boolean inBackgroundGroup, int refCount) {
super.doSetLive(inBackgroundGroup, refCount);
- if (image != null) {
- image.setLive(inBackgroundGroup, refCount);
+ if (texture != null) {
+ texture.setLive(inBackgroundGroup, refCount);
}
if (depthComponent != null) {
depthComponent.setLive(inBackgroundGroup, refCount);
@@ -321,8 +340,8 @@ class RasterRetained extends GeometryRetained {
void clearLive(int refCount) {
super.clearLive(refCount);
- if (image != null)
- image.clearLive(refCount);
+ if (texture != null)
+ texture.clearLive(refCount);
if (depthComponent != null)
depthComponent.clearLive(refCount);
}
@@ -373,7 +392,7 @@ class RasterRetained extends GeometryRetained {
int numMessages = universeList.size();
J3dMessage[] m = new J3dMessage[numMessages];
for (int i=0; i<numMessages; i++) {
- m[i] = VirtualUniverse.mc.getMessage();
+ m[i] = new J3dMessage();
m[i].type = J3dMessage.GEOMETRY_CHANGED;
m[i].threads = threads;
m[i].args[0] = Shape3DRetained.
@@ -393,168 +412,83 @@ class RasterRetained extends GeometryRetained {
}
- /**
- * Native method that does the rendering
- */
- native void execute(long ctx, GeometryRetained geo,
- boolean updateAlpha, float alpha,
- int type, int width, int height,
- int xSrcOffset, int ySrcOffset,
- float x, float y, float z, byte[] image);
- /*
- native void executeTiled(long ctx, GeometryRetained geo,
- int format, int width, int height,
- int xSrcOffset, int ySrcOffset,
- int deltaw, int deltah,
- float x, float y, float z, byte[] image);
- */
-
- void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
- boolean updateAlpha, float alpha,
- boolean multiScreen, int screen,
- boolean ignoreVertexColors, int pass) {
-
- // Compute the offset position of the raster
- // This has to be done at render time because we need access
- // to the Canvas3D info
-
- // Check if adjusted position needs to be computed
-
- validVwip = true;
- adjPos.set((double)position.x, (double)position.y, (double)position.z);
-
- if(xDstOffset != 0 || yDstOffset != 0) {
- getOffsetPos(cv, ra, adjPos);
- }
-
- xOffset = xSrcOffset;
- yOffset = ySrcOffset;
- // Check if the image needs to be clipped
-
- if (clipMode == Raster.CLIP_IMAGE)
- clipImage(cv, ra, adjPos);
-
- if (!validVwip) {
- return;
- }
- if ((image != null) && !image.imageYdownCacheDirty) {
- // If its a null image do nothing ..
- if (image != null && image.imageYdown[0] != null) {
- // Handle alpha, if necessary
- // Note, raster always makes a copy, so we can update alpha
- // in the image
- if (updateAlpha) {
- // Update Alpha value per screen
- // If the image is by reference, force a copy, since
- // we need to copy the alpha values
- image.updateAlpha(cv, screen, alpha);
- execute(cv.ctx, this, updateAlpha, alpha,
- type, width, height, xOffset, yOffset,
- (float)adjPos.x, (float)adjPos.y , (float)adjPos.z,
- image.imageYdown[screen]);
- }
- else {
- execute(cv.ctx, this, updateAlpha, alpha,
- type, width, height, xOffset, yOffset,
- (float)adjPos.x, (float)adjPos.y , (float)adjPos.z,
- image.imageYdown[0]);
- }
- }
- }
- /*
- else {
- // Should never come here ...
- if ((type & Raster.RASTER_COLOR) != 0){
- // Send down the tiles
- int tilew = image.tilew;
- int tileh = image.tileh;
- int w = width, h = height;
- int curw, curh;
- int xo = xOffset, yo = yOffset;
- float xpos = position.x, ypos = position.y;
- // First find the tile {x.y} to start from
- int tileX = 0, tileY = 0;
- while (xo > tilew) {
- tileX++;
- xo -= tilew;
- }
-
- while (yo > tileh) {
- tileY++;
- yo -= tileh;
- }
- int initTileY = image.minTileY+tileY;
- int initTileX = image.minTileX+tileX;
- int m,n;
- int deltaw, deltah = 0;
- curh = tileh - yo;
- for (m = initTileY; m < image.minTileY+image.numYTiles; m++) {
- curw = tilew - xo;
- deltaw = 0;
- w = width;
- for (n = initTileX; n < image.minTileX+image.numXTiles; n++) {
- java.awt.image.Raster ras;
- ras = image.bImage[0].getTile(n,m);
- byte[] tmpImage = ((DataBufferByte)ras.getDataBuffer()).getData();
- if (w <curw) {
- curw = w;
- }
- executeTiled(cv.ctx, this, image.storedYdownFormat,
- curw,
- curh,
- xo, yo,
- deltaw, deltah,
- (float)adjPos.x, (float)adjPos.y , (float)adjPos.z,
- tmpImage);
-
- xo = 0;
- w -= curw;
- if (w == 0)
- break;
- deltaw += curw;
- curw = tilew;
- }
- yo = 0;
- h -= curh;
- if (h == 0)
- break;
- deltah += curh;
- curh = tileh;
- if (h < curh)
- curh = h;
- xo = xOffset;
- }
- }
- if ((type & Raster.RASTER_DEPTH) != 0) {
- execute(cv.ctx, this, updateAlpha, alpha,
- Raster.RASTER_DEPTH, width, height,
- xOffset, yOffset,
- (float)adjPos.x, (float)adjPos.y , (float)adjPos.z,
- image.imageYdown[screen]);
- }
- }
- */
+ void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
+ boolean updateAlpha, float alpha,
+ int screen, boolean ignoreVertexColors) {
+
+ // Compute the offset position of the raster
+ // This has to be done at render time because we need access
+ // to the Canvas3D info
+
+ // Check if adjusted position needs to be computed
+ Point3d adjPos = new Point3d(); // Position of the Raster after adjusting for dstOffset
+ adjPos.set(position);
+
+ Point2d winCoord = new Point2d(); // Position of Raster in window coordinates
+ Transform3D localToImagePlate = new Transform3D(); // Local to Image plate transform
+
+ Point3d clipCoord = computeWinCoord(cv, ra, winCoord, adjPos, localToImagePlate);
+
+ // Test raster for out of bounds in Z.
+ if (clipCoord == null) {
+ return;
+ }
+
+ if(clipMode == Raster.CLIP_POSITION) {
+ // Do trivial reject test on Raster position.
+ if(!isRasterClipPositionInside(clipCoord)) {
+ return;
+ }
+ }
+
+ // Add the destination offset to the Raster position in window coordinates
+ winCoord.x += xDstOffset;
+ winCoord.y += yDstOffset;
+
+ // System.err.println("Step 2 : adjPos " + adjPos + " winCoord " + winCoord);
+
+
+ if((type == Raster.RASTER_COLOR) || (type == Raster.RASTER_COLOR_DEPTH)) {
+ float devCoordZ = (float) (clipCoord.z * 0.5 - 0.5);
+ // Do textfill stuffs
+ if (texture != null) {
+ // setup Texture pipe.
+ cv.updateTextureForRaster(texture);
+
+ cv.textureFill(this, winCoord, (float) devCoordZ, alpha);
+
+ // Restore texture pipe.
+ cv.restoreTextureBin();
+ }
+
+ }
+
+ if((type == Raster.RASTER_DEPTH) || (type == Raster.RASTER_COLOR_DEPTH)) {
+
+ Point2i srcOffset = new Point2i(xSrcOffset, ySrcOffset);
+
+ if (clipMode == Raster.CLIP_IMAGE) {
+ clipImage(cv, ra, winCoord, srcOffset);
+ }
+
+ computeObjCoord(cv, winCoord, adjPos, localToImagePlate);
+
+ cv.executeRasterDepth(cv.ctx,
+ (float) adjPos.x,
+ (float) adjPos.y,
+ (float) adjPos.z,
+ srcOffset.x,
+ srcOffset.y,
+ width,
+ height,
+ depthComponent.width,
+ depthComponent.height,
+ depthComponent.type,
+ ((DepthComponentIntRetained) depthComponent).depthData);
+
+ }
}
- /**
- * Computes the position of the origin of this Raster in object coordinates
- * The origin is the top-left corner offset by the destination offset
- * The offset position is returned in objCoord
- *
- * @param objCoord - Position of the Raster in object coordinates
- * @return nothing. The offset position is returned in objCoord
- */
- private void getOffsetPos(Canvas3D canvas, RenderAtom ra, Point3d objCoord) {
- computeWinCoord(canvas, ra, winCoord, objCoord);
-
- // Add the destination offset to the Raster position in window coordinates
- winCoord.x -= xDstOffset;
- winCoord.y -= yDstOffset;
-
- // Now back transform this offset pt. from window to object coordinates
- computeObjCoord(canvas, winCoord, objCoord);
- // pt. is now in object space again
- }
/**
* Clips the image against the window. This method simulates
@@ -564,29 +498,12 @@ class RasterRetained extends GeometryRetained {
* clipping against the right and bottom edges will be handled by
* the underlying graphics library automatically.
*/
- private void clipImage(Canvas3D canvas, RenderAtom ra, Point3d objCoord) {
- // check if window coordinates have already been calculated by
- // getOffsetPos().
-
- if(xDstOffset == 0 && yDstOffset == 0) {
- double x = objCoord.x;
- double y = objCoord.y;
- double z = objCoord.z;
- computeWinCoord(canvas, ra, winCoord, objCoord);
-
- if ((winCoord.x > 0) && (winCoord.y > 0)) {
- objCoord.x = x;
- objCoord.y = y;
- objCoord.z = z;
- return; // no need to clip
- }
- } else {
- if ((winCoord.x > 0) && (winCoord.y > 0)) {
- return;
- }
- }
-
-
+ private void clipImage(Canvas3D canvas, RenderAtom ra, Point2d winCoord, Point2i srcOffset) {
+
+ if ((winCoord.x > 0) && (winCoord.y > 0)) {
+ return;
+ }
+
// Check if the Raster point will be culled
// Note that w use 1 instead of 0, because when hardware
// tranform the coordinate back to winCoord it may get
@@ -595,37 +512,32 @@ class RasterRetained extends GeometryRetained {
// (see bug 4732965)
if(winCoord.x < 1) {
// Negate the window position and use this as the offset
- xOffset = (int)-winCoord.x+1;
+ srcOffset.x = (int)-winCoord.x+1;
winCoord.x = 1;
}
if(winCoord.y < 1) {
// Negate the window position and use this as the offset
- yOffset = (int)-winCoord.y+1;
+ srcOffset.y = (int)-winCoord.y+1;
winCoord.y = 1;
}
//check if user-specified subimage is smaller than the clipped image
- if (xOffset < xSrcOffset)
- xOffset = xSrcOffset;
- if(yOffset < ySrcOffset)
- yOffset = ySrcOffset;
- // back transform to object coords
- if(xDstOffset == 0 && yDstOffset == 0)
- // Image plate to local Xform needs to be computed
- computeObjCoord(canvas, winCoord, objCoord);
- else {
- // vwip should contain the Imageplate to Local transform
- // (it was computed by computeObjCoord).
- // We can simply use the previously computed value here
- canvas.getPixelLocationInImagePlate(winCoord.x, winCoord.y,
- objCoord.z, objCoord);
- vwip.transform(objCoord);
- }
+ if (srcOffset.x < xSrcOffset)
+ srcOffset.x = xSrcOffset;
+ if(srcOffset.y < ySrcOffset)
+ srcOffset.y = ySrcOffset;
+
+ }
+
+ private boolean isRasterClipPositionInside(Point3d clipCoord) {
+ return (clipCoord.x >= -1.0) && (clipCoord.x <= 1.0) &&
+ (clipCoord.y >= -1.0) && (clipCoord.y <= 1.0);
}
- private void computeObjCoord(Canvas3D canvas, Point2d winCoord, Point3d objCoord) {
+ private void computeObjCoord(Canvas3D canvas, Point2d winCoord, Point3d objCoord,
+ Transform3D localToImagePlate) {
// Back transform this pt. from window to object coordinates
// Assumes this method is ALWAYS called after computeWinCoord has been
// called. computeWinCoord calculates the Vworld to Image Plate Xform.
@@ -635,29 +547,52 @@ class RasterRetained extends GeometryRetained {
objCoord);
// Get image plate to object coord transform
// inv(P x M)
- vwip.invert();
- vwip.transform(objCoord);
+ localToImagePlate.invert();
+ localToImagePlate.transform(objCoord);
}
- private void computeWinCoord(Canvas3D canvas, RenderAtom ra,
- Point2d winCoord, Point3d objCoord) {
+ private Point3d computeWinCoord(Canvas3D canvas, RenderAtom ra,
+ Point2d winCoord, Point3d objCoord,
+ Transform3D localToImagePlate) {
// Get local to Vworld transform
RenderMolecule rm = ra.renderMolecule;
if (rm == null) {
// removeRenderAtom() may set ra.renderMolecule to null
// in RenderBin before this renderer thread run.
- validVwip = false;
- return;
- }
- // MT safe issue: We can't reference ra.renderMolecule below since
+ return null;
+ }
+
+ // MT safe issue: We can't reference ra.renderMolecule below since
// RenderBin thread may set it to null anytime. Use rm instead.
Transform3D lvw = rm.localToVworld[rm.localToVworldIndex[
NodeRetained.LAST_LOCAL_TO_VWORLD]];
-
+
+
+ Point3d clipCoord3 = new Point3d();
+ clipCoord3.set(objCoord);
+ Point4d clipCoord4 = new Point4d();
+
+ // Transform point from local coord. to clipping coord.
+ lvw.transform(clipCoord3);
+ canvas.vworldToEc.transform(clipCoord3);
+ canvas.projTrans.transform(clipCoord3, clipCoord4);
+
+ // clip check in Z
+ if((clipCoord4.w <= 0.0) ||
+ (clipCoord4.z > clipCoord4.w) || (-clipCoord4.z > clipCoord4.w)) {
+
+ return null;
+ }
+ double invW = 1.0 / clipCoord4.w;
+
+ clipCoord3.x = clipCoord4.x * invW;
+ clipCoord3.y = clipCoord4.y * invW;
+ clipCoord3.z = clipCoord4.z * invW;
+
// Get Vworld to image plate Xform
- canvas.getLastVworldToImagePlate(vwip);
+ canvas.getLastVworldToImagePlate(localToImagePlate);
// v' = vwip x lvw x v
// where v' = transformed vertex,
@@ -666,13 +601,16 @@ class RasterRetained extends GeometryRetained {
// v = vertex
// Compute composite local to image plate Xform
- vwip.mul(lvw);
+ localToImagePlate.mul(lvw);
// Transform the Raster's position from object to world coordinates
- vwip.transform(objCoord);
+ localToImagePlate.transform(objCoord);
+
// Get the window coordinates of this point
canvas.getPixelLocationFromImagePlate(objCoord, winCoord);
+
+ return clipCoord3;
}
int getClassType() {
diff --git a/src/classes/share/javax/media/j3d/RenderBin.java b/src/classes/share/javax/media/j3d/RenderBin.java
index a9cfe36..81cc46a 100644
--- a/src/classes/share/javax/media/j3d/RenderBin.java
+++ b/src/classes/share/javax/media/j3d/RenderBin.java
@@ -94,18 +94,6 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
*/
ArrayList positionDirtyList = new ArrayList(5);
-
- /**
- * A set of freelists for RenderBin type objects
- */
- ArrayList lightBinFreelist = new ArrayList(5);
- ArrayList envSetFreelist = new ArrayList(5);
- ArrayList attrBinFreelist = new ArrayList(5);
- ArrayList shaderBinFreelist = new ArrayList(5);
- ArrayList textureBinFreelist = new ArrayList(5);
- ArrayList renderMoleculeFreelist = new ArrayList(5);
- ArrayList transparentInfoFreeList = new ArrayList(5);
-
/**
* Used when ColoringAttributes is null
*/
@@ -176,9 +164,8 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
private Comparator transparencySortComparator = null;
- ArrayList toBeAddedTextureResourceFreeList = new ArrayList(5);
- ArrayList displayListResourceFreeList = new ArrayList(5);
- boolean resourceToFree = false;
+ private ArrayList toBeAddedTextureResourceFreeList = new ArrayList(5);
+ private ArrayList displayListResourceFreeList = new ArrayList(5);
// a list of top level OrderedGroups
ArrayList orderedBins = new ArrayList(5);
@@ -197,7 +184,8 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
int envDirty = 0;
- boolean reEvaluateBg = true;
+ private boolean reEvaluateBg = true;
+ private boolean reloadBgTexture = true;
boolean reEvaluateClip = true;
@@ -305,13 +293,6 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
*/
ArrayList dirtyReferenceGeomList = new ArrayList(5);
-
- /**
- * used by geometry execute routines to determine if the
- * alpha values can be zapped
- */
- boolean multiScreen = false;
-
// list of all Oriented RenderAtoms
ArrayList orientedRAs = new ArrayList(5);
@@ -411,7 +392,6 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
TextureRetained tex;
Integer texIdObj;
int size;
- DetailTextureImage dtex;
// System.out.println("dirtyRenderMoleculeList.size = "+dirtyRenderMoleculeList.size());
// System.out.println("reEvaluateBg = "+reEvaluateBg);
@@ -704,23 +684,31 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
//System.out.println("newNodeComponentlist.size= " + size);
Canvas3D canvases[] = view.getCanvases();
for (i = 0; i < size; i++) {
- // Evaluate the nodeComponentList for all the canvases
- ImageComponentRetained nc = (ImageComponentRetained)newNodeComponentList.get(i);
- // Only evalaute extension for by-ref Images
- if (nc.isByReference()) {
- nc.geomLock.getLock();
- for (j = 0; j <canvases.length; j++) {
- // If the context is null, then the extension
- // will be evaluated during context creation in
- // the renderer
- if (canvases[j].ctx != 0) {
- nc.evaluateExtensions(canvases[j].extensionsSupported);
- }
- }
- nc.geomLock.unLock();
- }
- nodeComponentList.add(nc);
- }
+ // Evaluate the nodeComponentList for all the canvases
+ ImageComponent2DRetained nc = (ImageComponent2DRetained)newNodeComponentList.get(i);
+ if (nc.isByReference()) {
+ nc.geomLock.getLock();
+ for (j = 0; j <canvases.length; j++) {
+ // If the context is null, then the extension
+ // will be evaluated during context creation in
+ // the renderer
+ if (canvases[j].ctx != null) {
+ nc.evaluateExtensions(canvases[j]);
+ }
+ }
+ nc.geomLock.unLock();
+ } else {
+ for (j = 0; j <canvases.length; j++) {
+ // If the context is null, then the extension
+ // will be evaluated during context creation in
+ // the renderer
+ if (canvases[j].ctx != null) {
+ nc.evaluateExtensions(canvases[j]);
+ }
+ }
+ }
+ nodeComponentList.add(nc);
+ }
}
size = removeNodeComponentList.size();
@@ -737,22 +725,30 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
Canvas3D canvases[] = view.getCanvases();
for (i = 0; i < size; i++) {
// Evaluate the nodeComponentList for all the canvases
- ImageComponentRetained nc =
- (ImageComponentRetained)dirtyNodeComponentList.get(i);
- // Only evalaute extension for by-ref Images
+ ImageComponent2DRetained nc =
+ (ImageComponent2DRetained)dirtyNodeComponentList.get(i);
if (nc.isByReference()) {
nc.geomLock.getLock();
for (j = 0; j <canvases.length; j++) {
// If the context is null, then the extension
// will be evaluated during context creation in
// the renderer
- if (canvases[j].ctx != 0) {
- nc.evaluateExtensions(
- canvases[j].extensionsSupported);
+ if (canvases[j].ctx != null) {
+ nc.evaluateExtensions( canvases[j]);
}
}
nc.geomLock.unLock();
}
+ else {
+ for (j = 0; j <canvases.length; j++) {
+ // If the context is null, then the extension
+ // will be evaluated during context creation in
+ // the renderer
+ if (canvases[j].ctx != null) {
+ nc.evaluateExtensions(canvases[j]);
+ }
+ }
+ }
}
}
@@ -768,8 +764,9 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
}
view.vDirtyMask |= View.CLIP_DIRTY;
}
-
- multiScreen = ((view.getScreens()).length > 1);
+
+ // Issue 113 - multiScreen no longer used
+// multiScreen = ((view.getScreens()).length > 1);
// renderBin is ready now, so send the offScreen message
size = offScreenMessage.size();
@@ -1089,7 +1086,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
ra = arr[i];
GeometryArrayRetained geo = (GeometryArrayRetained) ra.geometry();
- if ((cv.ctx != 0) &&
+ if ((cv.ctx != null) &&
((geo.resourceCreationMask & cv.canvasBit) == 0) ||
(geo.getDlistTimeStamp(cv.canvasBit) !=
cv.ctxTimeStamp)) {
@@ -1107,7 +1104,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
// add this geometry's dlist to be freed
if (geo.isDlistUserSetEmpty(this)) {
- if (cv.ctx != 0) {
+ if (cv.ctx != null) {
canvases[j].displayListResourceFreeList.add(geo.dlistObj);
}
geo.resourceCreationMask &= ~canvases[j].canvasBit;
@@ -1153,6 +1150,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
dirtyRenderMoleculeList.clear();
dirtyReferenceGeomList.clear();
reEvaluateBg = false;
+ reloadBgTexture = false;
textureBinList.clear();
newNodeComponentList.clear();
removeNodeComponentList.clear();
@@ -1174,7 +1172,6 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
RenderMolecule rm;
TextureRetained tex;
Integer texIdObj;
- DetailTextureImage dtex;
if (rdr == null)
return;
@@ -1235,25 +1232,6 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
rdr.textureIdResourceFreeList.add(texIdObj);
tex.resourceCreationMask &= ~rdr.rendererBit;
}
- if (tex instanceof Texture2DRetained) {
- dtex = ((Texture2DRetained) tex).detailTexture;
- if ((dtex != null) &&
- ((dtex.resourceCreationMask[tex.format] & rdr.rendererBit) != 0)) {
- id = dtex.objectIds[tex.format];
- if ((id >= rdr.textureIDResourceTable.size()) ||
- (rdr.textureIDResourceTable.get(id) != dtex)) {
- id = rdr.textureIDResourceTable.indexOf(dtex);
- if (id <= 0) {
- continue;
- }
- }
- texIdObj = new Integer(id);
- if (!rdr.textureIdResourceFreeList.contains(texIdObj)) {
- rdr.textureIdResourceFreeList.add(texIdObj);
- dtex.resourceCreationMask[tex.format] &= ~rdr.rendererBit;
- }
- }
- }
}
}
@@ -1282,7 +1260,6 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
RenderMolecule rm;
TextureRetained tex;
Integer texIdObj;
- DetailTextureImage dtex;
// update dirtyRenderMoleculeList for each canvas
for (i = 0; i < canvases.length; i++) {
@@ -1330,35 +1307,11 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
}
}
-
if ((tex.resourceCreationMask & cv.canvasBit) != 0) {
texIdObj = new Integer(id);
cv.textureIdResourceFreeList.add(texIdObj);
tex.resourceCreationMask &= ~cv.canvasBit;
}
- if (tex instanceof Texture2DRetained) {
- dtex = ((Texture2DRetained) tex).detailTexture;
- if ((dtex != null) &&
- ((dtex.resourceCreationMask[tex.format] & cv.canvasBit) != 0)) {
- id = dtex.objectIds[tex.format];
- if ((id >= cv.textureIDResourceTable.size()) ||
- (cv.textureIDResourceTable.get(id) != dtex)) {
- id = cv.textureIDResourceTable.indexOf(dtex);
- if (id <= 0) {
- continue;
- }
- }
- texIdObj = new Integer(id);
- // XXXX: The following code seems wrong -- why add it to
- // the list if it is already there? Maybe one is for the
- // texture and the other (idential value) is for the
- // detail texture?
- if (cv.textureIdResourceFreeList.contains(texIdObj)) {
- cv.textureIdResourceFreeList.add(texIdObj);
- dtex.resourceCreationMask[tex.format] &= ~cv.canvasBit;
- }
- }
- }
}
// Take care of display list that should be freed
size = displayListResourceFreeList.size();
@@ -1427,8 +1380,10 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
break;
case J3dMessage.BACKGROUND_CHANGED:
BackgroundRetained bg = (BackgroundRetained)m.args[0];
- if (universe.renderingEnvironmentStructure.isBgScopedToThisView(bg, view))
+ if (universe.renderingEnvironmentStructure.isBgScopedToThisView(bg, view)) {
reEvaluateBg = true;
+ reloadBgTexture = true;
+ }
m.decRefcount();
break;
case J3dMessage.CLIP_CHANGED:
@@ -3167,19 +3122,26 @@ System.out.println("......tb.soleUser= " +
addGeometryDlist(ra);
// Raster send this message only for setImage()
- if (g instanceof RasterRetained) {
- Object[] objs = (Object[]) args[2];
- ImageComponentRetained oldImage = (ImageComponentRetained) objs[0];
- ImageComponentRetained newImage = (ImageComponentRetained) objs[1];
-
- RasterRetained geo = (RasterRetained)ra.geometry();
- if (oldImage != null && oldImage.isByReference()) {
- removeNodeComponent(oldImage);
- }
- if (newImage != null && newImage.isByReference()) {
- addNodeComponent(newImage);
- }
- }
+ if (g instanceof RasterRetained) {
+ Object[] objs = (Object[]) args[2];
+ Texture2DRetained oldTex = (Texture2DRetained) objs[0];
+ Texture2DRetained newTex = (Texture2DRetained) objs[1];
+
+ RasterRetained geo = (RasterRetained)ra.geometry();
+ if (oldTex != null) {
+ addTextureResourceFreeList(oldTex);
+ ImageComponentRetained oldImage = oldTex.images[0][0];
+ if (oldImage != null) {
+ removeNodeComponent(oldImage);
+ }
+ }
+ if (newTex != null) {
+ ImageComponentRetained newImage = newTex.images[0][0];
+ if (newImage != null) {
+ addNodeComponent(newImage);
+ }
+ }
+ }
}
@@ -3223,7 +3185,8 @@ System.out.println("......tb.soleUser= " +
ArrayList rmList, ArrayList dlistPerRinfoList,
ArrayList raList, boolean useSharedCtx ) {
int size, i, bitMask;
- long ctx, timeStamp;
+ Context ctx;
+ long timeStamp;
if (useSharedCtx) {
ctx = cv.screen.renderer.sharedCtx;
@@ -3285,10 +3248,9 @@ System.out.println("......tb.soleUser= " +
}
void removeRenderMolecule(RenderMolecule rm) {
- renderMoleculeFreelist.add(rm);
- if ((rm.primaryMoleculeType &(RenderMolecule.DLIST_MOLECULE|RenderMolecule.SEPARATE_DLIST_PER_RINFO_MOLECULE)) != 0)
- renderMoleculeList.remove(rm);
+ if ((rm.primaryMoleculeType &(RenderMolecule.DLIST_MOLECULE|RenderMolecule.SEPARATE_DLIST_PER_RINFO_MOLECULE)) != 0)
+ renderMoleculeList.remove(rm);
}
void updateAllRenderMolecule(Canvas3D cv) {
@@ -3422,7 +3384,7 @@ System.out.println("......tb.soleUser= " +
for(int k = 0; k < ra.rListInfo.length; k++) {
if (ra.rListInfo[k].localToVworld == null) {
- ra.rListInfo[k].localToVworld = VirtualUniverse.mc.getTransform3D(null);
+ ra.rListInfo[k].localToVworld = new Transform3D();
}
}
@@ -4474,7 +4436,7 @@ System.out.println("......tb.soleUser= " +
ra.dirtyMask |= RenderAtom.IS_ORIENTED;
for(int k = 0; k < ra.rListInfo.length; k++) {
if (ra.rListInfo[k].localToVworld == null) {
- ra.rListInfo[k].localToVworld = VirtualUniverse.mc.getTransform3D(null);
+ ra.rListInfo[k].localToVworld = new Transform3D();
}
}
}
@@ -4702,18 +4664,12 @@ System.out.println("......tb.soleUser= " +
* This gets a new EnviornmentSet. It creates one if there are none
* on the freelist.
*/
- private EnvironmentSet getEnvironmentSet(RenderAtom ra, LightRetained[] lights,
- FogRetained fog, ModelClipRetained modelClip) {
- EnvironmentSet envSet;
-
- if (envSetFreelist.size() > 0) {
- envSet = (EnvironmentSet)envSetFreelist.remove(
- envSetFreelist.size()-1);
- envSet.reset(ra, lights, fog, modelClip);
- } else {
- envSet = new EnvironmentSet(ra, lights, fog, modelClip, this);
- }
- return (envSet);
+ private EnvironmentSet getEnvironmentSet(RenderAtom ra, LightRetained[] lights,
+ FogRetained fog, ModelClipRetained modelClip) {
+ EnvironmentSet envSet;
+
+ envSet = new EnvironmentSet(ra, lights, fog, modelClip, this);
+ return (envSet);
}
/**
@@ -4925,14 +4881,7 @@ System.out.println("......tb.soleUser= " +
* on the freelist.
*/
private ShaderBin getShaderBin(ShaderAppearanceRetained sApp) {
- ShaderBin shaderBin;
- if (shaderBinFreelist.size() > 0) {
- shaderBin = (ShaderBin)shaderBinFreelist.remove(shaderBinFreelist.size()-1);
- shaderBin.reset(sApp, this);
- } else {
- shaderBin = new ShaderBin( sApp, this);
- }
- return (shaderBin);
+ return new ShaderBin( sApp, this);
}
/**
@@ -4940,17 +4889,7 @@ System.out.println("......tb.soleUser= " +
* on the freelist.
*/
private AttributeBin getAttributeBin(AppearanceRetained app, RenderingAttributesRetained ra) {
- AttributeBin attrBin;
- if (attrBinFreelist.size() > 0) {
- attrBin = (AttributeBin)attrBinFreelist.remove(
- attrBinFreelist.size()-1);
- attrBin.reset(app, ra, this);
- } else {
-
-
- attrBin = new AttributeBin(app, ra, this);
- }
- return (attrBin);
+ return new AttributeBin(app, ra, this);
}
/**
@@ -4958,17 +4897,12 @@ System.out.println("......tb.soleUser= " +
* on the freelist.
*/
private LightBin getLightBin(int maxLights, BackgroundRetained bg, boolean inOpaque) {
- LightBin lightBin;
-
- if (lightBinFreelist.size() > 0) {
- lightBin = (LightBin)lightBinFreelist.remove(
- lightBinFreelist.size()-1);
- lightBin.reset(inOpaque);
- } else {
- lightBin = new LightBin(maxLights, this, inOpaque);
- }
- lightBin.geometryBackground = bg;
- return (lightBin);
+ LightBin lightBin;
+
+ lightBin = new LightBin(maxLights, this, inOpaque);
+
+ lightBin.geometryBackground = bg;
+ return (lightBin);
}
/**
@@ -4976,49 +4910,30 @@ System.out.println("......tb.soleUser= " +
* on the freelist.
*/
private TextureBin getTextureBin(TextureUnitStateRetained texUnitState[],
- AppearanceRetained app) {
- TextureBin textureBin;
-
- if (textureBinFreelist.size() > 0) {
- textureBin = (TextureBin)textureBinFreelist.remove(
- textureBinFreelist.size()-1);
- textureBin.reset(texUnitState, app);
- } else {
- textureBin = new TextureBin(texUnitState, app, this);
- }
-
- return (textureBin);
+ AppearanceRetained app) {
+ return new TextureBin(texUnitState, app, this);
}
/**
* This gets a new RenderMolecule. It creates one if there are none
* on the freelist.
*/
- private RenderMolecule getRenderMolecule(GeometryAtom ga,
- PolygonAttributesRetained polya,
- LineAttributesRetained linea,
- PointAttributesRetained pointa,
- MaterialRetained material,
- ColoringAttributesRetained cola,
- TransparencyAttributesRetained transa,
- RenderingAttributesRetained ra,
- TextureUnitStateRetained[] texUnits,
- Transform3D[] transform,
- int[] transformIndex) {
- RenderMolecule renderMolecule;
-
- if (renderMoleculeFreelist.size() > 0) {
- renderMolecule = (RenderMolecule)renderMoleculeFreelist.remove(
- renderMoleculeFreelist.size()-1);
- renderMolecule.reset(ga, polya, linea, pointa, material,
- cola, transa, ra, texUnits, transform, transformIndex);
- } else {
- renderMolecule = new RenderMolecule(ga, polya, linea, pointa,
- material, cola, transa, ra,
- texUnits,
- transform, transformIndex, this);
- }
- return (renderMolecule);
+ private RenderMolecule getRenderMolecule(GeometryAtom ga,
+ PolygonAttributesRetained polya,
+ LineAttributesRetained linea,
+ PointAttributesRetained pointa,
+ MaterialRetained material,
+ ColoringAttributesRetained cola,
+ TransparencyAttributesRetained transa,
+ RenderingAttributesRetained ra,
+ TextureUnitStateRetained[] texUnits,
+ Transform3D[] transform,
+ int[] transformIndex) {
+
+ return new RenderMolecule(ga, polya, linea, pointa,
+ material, cola, transa, ra,
+ texUnits,
+ transform, transformIndex, this);
}
@@ -5197,7 +5112,6 @@ System.out.println("......tb.soleUser= " +
// gotten from the freelist from one frame to another
canvases[i].lightBin = null;
}
- lightBinFreelist.add(lbin);
lbin.prev = null;
lbin.next = null;
}
@@ -5358,41 +5272,50 @@ System.out.println("......tb.soleUser= " +
* Sets the new background color.
*/
void setBackground(BackgroundRetained back) {
-
- boolean cvDirty = false;
- BackgroundRetained oldGeomBack = geometryBackground;
- geometryBackground = null;
-
- if (back != null) {
- background.initColor(back.color);
- background.initImageScaleMode(back.imageScaleMode);
- background.geometryBranch = back.geometryBranch;
+
+ boolean cvDirty = false;
+ BackgroundRetained oldGeomBack = geometryBackground;
+ geometryBackground = null;
+
+ if (back != null) {
+ background.initColor(back.color);
+ background.initImageScaleMode(back.imageScaleMode);
+ background.geometryBranch = back.geometryBranch;
if (background.geometryBranch != null) {
geometryBackground = back;
}
- if (background.image != null) {
- if (background.image.isByReference())
- removeNodeComponent(background.image);
- }
- if (back.image != null) {
- // May need to optimize later
- background.initImage((ImageComponent2D)back.image.source);
- if (back.image.isByReference()) {
- addNodeComponent(back.image);
- }
- } else {
- background.initImage(null);
- }
- if (oldGeomBack == null) {
- cvDirty = true;
- }
- } else {
- background.initColor(black);
- background.geometryBranch = null;
- background.initImage(null);
- if (oldGeomBack != null) {
- cvDirty = true;
- }
+ // Release resources associated with old BG and initialize new BG
+ // if the old and new BG images are different or if the
+ // reloadBgTexture flag is set.
+ if (background.image != back.image || reloadBgTexture) {
+ if (background.image != null) {
+ assert background.texture != null;
+ addTextureResourceFreeList(background.texture);
+ removeNodeComponent(background.image);
+ }
+ if (back.image != null) {
+ // May need to optimize later
+ background.initImage((ImageComponent2D)back.image.source);
+ addNodeComponent(back.image);
+ } else {
+ background.initImage(null);
+ }
+ }
+ if (oldGeomBack == null) {
+ cvDirty = true;
+ }
+ } else {
+ background.initColor(black);
+ background.geometryBranch = null;
+ if (background.image != null) {
+ assert background.texture != null;
+ addTextureResourceFreeList(background.texture);
+ removeNodeComponent(background.image);
+ }
+ background.initImage(null);
+ if (oldGeomBack != null) {
+ cvDirty = true;
+ }
}
// Need to reEvaluate View cache since doInfinite
@@ -6005,12 +5928,6 @@ System.out.println("......tb.soleUser= " +
nodeComponentList.clear();
orientedRAs.clear();
bhTreesArrList.clear();
- lightBinFreelist.clear();
- envSetFreelist.clear();
- attrBinFreelist.clear();
- shaderBinFreelist.clear();
- textureBinFreelist.clear();
- renderMoleculeFreelist.clear();
// clean up any messages that are queued up, since they are
// irrelevant
@@ -6142,7 +6059,6 @@ System.out.println("......tb.soleUser= " +
}
t.prev = null;
t.next = null;
- transparentInfoFreeList.add(t);
tb.parentTInfo = null;
}
else {
@@ -6168,7 +6084,6 @@ System.out.println("......tb.soleUser= " +
}
t.prev = null;
t.next = null;
- transparentInfoFreeList.add(t);
tb.parentTInfo = null;
}
@@ -6202,7 +6117,6 @@ System.out.println("......tb.soleUser= " +
}
t.prev = null;
t.next = null;
- transparentInfoFreeList.add(t);
nElements--;
r.parentTInfo[i] = null;
}
@@ -6261,15 +6175,7 @@ System.out.println("......tb.soleUser= " +
}
TransparentRenderingInfo getTransparentInfo() {
- TransparentRenderingInfo tinfo;
-
- if (transparentInfoFreeList.size() > 0) {
- tinfo = (TransparentRenderingInfo)transparentInfoFreeList.remove(transparentInfoFreeList.size()-1);
- } else {
- tinfo = new TransparentRenderingInfo();
- }
- return (tinfo);
-
+ return new TransparentRenderingInfo();
}
TransparentRenderingInfo computeDirtyAcrossTransparentBins(TextureBin tb, TransparentRenderingInfo startinfo) {
@@ -6370,7 +6276,6 @@ System.out.println("......tb.soleUser= " +
for (i = 0; i < size; i++) {
TextureBin tb = (TextureBin)allTransparentObjects.get(i);
- transparentInfoFreeList.add(tb.parentTInfo);
tb.parentTInfo = null;
RenderMolecule r = tb.transparentRMList;
// For each renderMolecule
@@ -6429,7 +6334,6 @@ System.out.println("......tb.soleUser= " +
if (r.parentTInfo[j] == null)
continue;
- transparentInfoFreeList.add(r.parentTInfo[j]);
r.parentTInfo[j] = null;
}
if (r.renderMolecule.textureBin.parentTInfo == null) {
@@ -6919,6 +6823,15 @@ System.out.println("......tb.soleUser= " +
renderAtoms.remove(renderAtoms.indexOf(ra));
removeARenderAtom(ra);
}
+
+ // This code segment is to handle the texture resource cleanup
+ // for Raster object.
+ GeometryAtom geomAtom = (GeometryAtom) nodes[n];
+ GeometryRetained geomRetained = geomAtom.geometryArray[0];
+ if ((geomRetained != null) &&
+ (geomRetained instanceof RasterRetained )) {
+ addTextureResourceFreeList(((RasterRetained)geomRetained).texture);
+ }
}
else if (nodes[n] instanceof AlternateAppearanceRetained) {
altAppearanceDirty = true;
@@ -6978,7 +6891,9 @@ System.out.println("......tb.soleUser= " +
}
- void freeAllDisplayListResources(Canvas3D cv) {
+ void freeAllDisplayListResources(Canvas3D cv, Context ctx) {
+
+ assert ctx != null;
int i;
int size = renderMoleculeList.size();
@@ -6989,7 +6904,7 @@ System.out.println("......tb.soleUser= " +
renderMoleculeList.toArray(false);
for (i = 0 ; i < size; i++) {
- rmArr[i].releaseAllPrimaryDisplayListResources(cv);
+ rmArr[i].releaseAllPrimaryDisplayListResources(cv, ctx);
}
}
@@ -7012,7 +6927,7 @@ System.out.println("......tb.soleUser= " +
// Canvas in the renderer. However, since the
// display lists will be recreated, it doesn't
// really matter.
- cv.freeDisplayList(cv.ctx, geo.dlistId);
+ cv.freeDisplayList(ctx, geo.dlistId);
geo.resourceCreationMask &= ~mask;
}
}
diff --git a/src/classes/share/javax/media/j3d/RenderMethod.java b/src/classes/share/javax/media/j3d/RenderMethod.java
index 8641375..a714cfd 100644
--- a/src/classes/share/javax/media/j3d/RenderMethod.java
+++ b/src/classes/share/javax/media/j3d/RenderMethod.java
@@ -22,6 +22,6 @@ interface RenderMethod {
/**
* The actual rendering code for this RenderMethod
*/
- abstract boolean render(RenderMolecule rm, Canvas3D cv, int pass,
+ abstract boolean render(RenderMolecule rm, Canvas3D cv,
RenderAtomListInfo ra, int dirtyBits);
}
diff --git a/src/classes/share/javax/media/j3d/RenderMolecule.java b/src/classes/share/javax/media/j3d/RenderMolecule.java
index 2bc58a6..a0c24b9 100644
--- a/src/classes/share/javax/media/j3d/RenderMolecule.java
+++ b/src/classes/share/javax/media/j3d/RenderMolecule.java
@@ -390,14 +390,16 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
geo = ga.geometryArray[k];
k++;
}
-
- if (ga.source.appearance != null) {
- soleUser = ((ga.source.appearance.changedFrequent & RM_COMPONENTS) != 0);
- }
- else {
- soleUser = false;
+
+ // Issue 249 - check for sole user only if property is set
+ soleUser = false;
+ if (VirtualUniverse.mc.allowSoleUser) {
+ if (ga.source.appearance != null) {
+ soleUser = ((ga.source.appearance.changedFrequent & RM_COMPONENTS) != 0);
+ }
}
- // Set the appearance only for soleUser case
+
+ // Set the appearance only for soleUser case
if (soleUser)
appHandle = ga.source.appearance;
else
@@ -674,8 +676,8 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
if (localeLocalToVworld == null) {
localeLocalToVworld = new Transform3D[2];
}
- localeLocalToVworld[0] = VirtualUniverse.mc.getTransform3D(null);
- localeLocalToVworld[1] = VirtualUniverse.mc.getTransform3D(null);
+ localeLocalToVworld[0] = new Transform3D();
+ localeLocalToVworld[1] = new Transform3D();
localeTranslation = new Vector3d();
ga.locale.hiRes.difference(renderBin.locale.hiRes, localeTranslation);
translate();
@@ -1072,16 +1074,9 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
rinfo.next.prev = rinfo.prev;
}
}
- // If this renderAtom has localTransform,
- // return transform to freelist
- if (primaryMoleculeType == RenderMolecule.TEXT3D_MOLECULE) {
- if (!rinfo.renderAtom.inRenderBin()) {
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, rinfo.localToVworld);
-
- }
- }
+
// If the molecule type is Raster, then add it to the lock list
- else if (primaryMoleculeType == RASTER) {
+ if (primaryMoleculeType == RASTER) {
RasterRetained geo = (RasterRetained)rinfo.geometry();
renderBin.removeGeometryFromLockList(geo);
if (geo.image != null)
@@ -1161,10 +1156,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
displayListId = 0;
displayListIdObj = null;
}
- // If the locale is different, return xform to freelist
if (locale != renderBin.locale) {
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D,
- localeLocalToVworld[0]);
localeLocalToVworld = null;
}
textureBin.removeRenderMolecule(this);
@@ -1297,18 +1289,16 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
((geo.vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0)) {
renderBin.addGeometryToLockList(geo);
// Add the geometry to the dirty list only if the geometry is by
- // refernce and there is color and we need to use alpha and its
- // not multiScreen
+ // refernce and there is color and we need to use alpha
+ // Issue 113 - ignore multiScreen
if ((( geo.vertexFormat & GeometryArray.BY_REFERENCE)!=0) &&
(geo.c4fAllocated == 0) &&
((geo.vertexFormat & GeometryArray.COLOR) != 0) &&
- useAlpha &&
- !renderBin.multiScreen) {
+ useAlpha) {
renderBin.addDirtyReferenceGeometry(geo);
}
}
}
-
}
addRAs = addRAs.nextAdd;
renderAtom.nextAdd = null;
@@ -1749,13 +1739,12 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
((geo.vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0)) {
renderBin.addGeometryToLockList(geo);
// Add the geometry to the dirty list only if the geometry is by
- // refernce and there is color and we need to use alpha and its
- // not multiScreen
+ // reference and there is color and we need to use alpha
+ // Issue 113 - ignore multiScreen
if ((( geo.vertexFormat & GeometryArray.BY_REFERENCE)!=0) &&
(geo.c4fAllocated == 0) &&
((geo.vertexFormat & GeometryArray.COLOR) != 0) &&
- useAlpha &&
- !renderBin.multiScreen) {
+ useAlpha) {
renderBin.addDirtyReferenceGeometry(geo);
}
}
@@ -1791,6 +1780,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
* Renders this RenderMolecule
*/
boolean render(Canvas3D cv, int pass, int dirtyBits) {
+ assert pass < 0;
boolean isVisible = isSwitchOn();
@@ -1847,24 +1837,16 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
modeSupportDL) {
if (primaryMoleculeType != SEPARATE_DLIST_PER_RINFO_MOLECULE) {
-
- if ((primaryRenderMethod != VirtualUniverse.mc.getDisplayListRenderMethod()) &&
- (pass == TextureBin.USE_DISPLAYLIST)) {
- pass = TextureBin.USE_VERTEXARRAY;
- }
- if (primaryRenderMethod.render(this, cv, pass, primaryRenderAtomList,dirtyBits))
+ if (primaryRenderMethod.render(this, cv, primaryRenderAtomList,dirtyBits))
isVisible = true;
}
else {
- if (renderBin.dlistRenderMethod.renderSeparateDlistPerRinfo(this, cv, pass,primaryRenderAtomList,dirtyBits))
+ if (renderBin.dlistRenderMethod.renderSeparateDlistPerRinfo(this, cv, primaryRenderAtomList,dirtyBits))
isVisible = true;
}
} else {
- if (pass == TextureBin.USE_DISPLAYLIST) {
- pass = TextureBin.USE_VERTEXARRAY;
- }
- if(cachedVertexArrayRenderMethod.render(this, cv, pass,
+ if(cachedVertexArrayRenderMethod.render(this, cv,
primaryRenderAtomList,
dirtyBits)) {
isVisible = true;
@@ -1875,10 +1857,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
else { // TEXT3D or ORIENTEDSHAPE3D
if (primaryRenderAtomList != null) {
- if (pass == TextureBin.USE_DISPLAYLIST) {
- pass = TextureBin.USE_VERTEXARRAY;
- }
- if(primaryRenderMethod.render(this, cv, pass, primaryRenderAtomList,
+ if(primaryRenderMethod.render(this, cv, primaryRenderAtomList,
dirtyBits)) {
isVisible = true;
}
@@ -1886,19 +1865,15 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
}
if (separateDlistRenderAtomList != null) {
- if (modeSupportDL) {
- if(renderBin.dlistRenderMethod.
- renderSeparateDlists(this, cv, pass,
- separateDlistRenderAtomList,
- dirtyBits)) {
- isVisible = true;
- }
+ if (modeSupportDL) {
+ if(renderBin.dlistRenderMethod.renderSeparateDlists(this, cv,
+ separateDlistRenderAtomList,
+ dirtyBits)) {
+ isVisible = true;
+ }
} else {
- if (pass == TextureBin.USE_DISPLAYLIST) {
- pass = TextureBin.USE_VERTEXARRAY;
- }
- if(cachedVertexArrayRenderMethod.render(this, cv, pass,
+ if(cachedVertexArrayRenderMethod.render(this, cv,
separateDlistRenderAtomList,
dirtyBits)) {
isVisible = true;
@@ -1910,10 +1885,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
// XXXX: In the case of independent primitives such as quads,
// it would still be better to call multi draw arrays
if (vertexArrayRenderAtomList != null) {
- if (pass == TextureBin.USE_DISPLAYLIST) {
- pass = TextureBin.USE_VERTEXARRAY;
- }
- if(cachedVertexArrayRenderMethod.render(this, cv, pass,
+ if(cachedVertexArrayRenderMethod.render(this, cv,
vertexArrayRenderAtomList,
dirtyBits)) {
isVisible = true;
@@ -2121,6 +2093,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
}
void transparentSortRender(Canvas3D cv, int pass, TransparentRenderingInfo tinfo) {
+ assert pass < 0;
Transform3D modelMatrix =
trans[localToVworldIndex[NodeRetained.LAST_LOCAL_TO_VWORLD]];
@@ -2169,12 +2142,12 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
// System.out.println("cachedVertexArrayRenderMethod = "+cachedVertexArrayRenderMethod);
// System.out.println("tinfo.rInfo = "+tinfo.rInfo);
if (modeSupportDL) {
- renderBin.dlistRenderMethod.renderSeparateDlistPerRinfo(this, cv, pass,
+ renderBin.dlistRenderMethod.renderSeparateDlistPerRinfo(this, cv,
tinfo.rInfo,
ALL_DIRTY_BITS);
}
else {
- cachedVertexArrayRenderMethod.render(this, cv, pass, tinfo.rInfo,ALL_DIRTY_BITS);
+ cachedVertexArrayRenderMethod.render(this, cv, tinfo.rInfo,ALL_DIRTY_BITS);
}
tinfo.rInfo.next = save;
}
@@ -2184,7 +2157,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
tinfo.rInfo.next = null;
// System.out.println("cachedVertexArrayRenderMethod = "+cachedVertexArrayRenderMethod);
// System.out.println("tinfo.rInfo = "+tinfo.rInfo);
- cachedVertexArrayRenderMethod.render(this, cv, pass, tinfo.rInfo,
+ cachedVertexArrayRenderMethod.render(this, cv, tinfo.rInfo,
ALL_DIRTY_BITS);
tinfo.rInfo.next = save;
}
@@ -2194,19 +2167,19 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
RenderAtomListInfo save= tinfo.rInfo.next;
tinfo.rInfo.next = null;
if (modeSupportDL) {
- renderBin.dlistRenderMethod.renderSeparateDlists(this, cv, pass,
+ renderBin.dlistRenderMethod.renderSeparateDlists(this, cv,
tinfo.rInfo,
ALL_DIRTY_BITS);
}
else {
- cachedVertexArrayRenderMethod.render(this, cv, pass, tinfo.rInfo,
+ cachedVertexArrayRenderMethod.render(this, cv, tinfo.rInfo,
ALL_DIRTY_BITS);
}
tinfo.rInfo.next = save;
}
else {
RenderAtomListInfo save= tinfo.rInfo.next;
- primaryRenderMethod.render(this, cv, pass, primaryRenderAtomList,
+ primaryRenderMethod.render(this, cv, primaryRenderAtomList,
ALL_DIRTY_BITS);
tinfo.rInfo.next = save;
}
@@ -2264,7 +2237,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
}
- void releaseAllPrimaryDisplayListResources(Canvas3D cv) {
+ void releaseAllPrimaryDisplayListResources(Canvas3D cv, Context ctx) {
if (primaryRenderAtomList != null) {
if (primaryMoleculeType == SEPARATE_DLIST_PER_RINFO_MOLECULE) {
RenderAtomListInfo ra = primaryRenderAtomList;
@@ -2272,14 +2245,14 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
while (ra != null) {
id = ra.renderAtom.dlistIds[ra.index];
if (id > 0) {
- cv.freeDisplayList(cv.ctx, id);
+ cv.freeDisplayList(ctx, id);
}
ra = ra.next;
}
}
else if (primaryMoleculeType == DLIST_MOLECULE) {
if (displayListId > 0) {
- cv.freeDisplayList(cv.ctx, displayListId);
+ cv.freeDisplayList(ctx, displayListId);
}
}
}
@@ -2985,13 +2958,6 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
void handleLocaleChange() {
if (locale == renderBin.locale) {
if (localToVworld != localeLocalToVworld) {
- if (localeTranslation != null) {
- // return to the freelist;
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D,
- localeLocalToVworld[0]);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D,
- localeLocalToVworld[1]);
- }
localeLocalToVworld = localToVworld;
localeTranslation = null;
}
@@ -3000,11 +2966,6 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
// Using the localToVworl then, go back to making a new copy
if (localeTranslation == null) {
localeLocalToVworld = new Transform3D[2];
- /*
- localeLocalToVworld[0] = VirtualUniverse.mc.getTransform3D(null);
- localeLocalToVworld[1] = VirtualUniverse.mc.getTransform3D(null);
- */
-
localeLocalToVworld[0] = new Transform3D();
localeLocalToVworld[1] = new Transform3D();
diff --git a/src/classes/share/javax/media/j3d/Renderer.java b/src/classes/share/javax/media/j3d/Renderer.java
index db0d8b3..3c73a7e 100644
--- a/src/classes/share/javax/media/j3d/Renderer.java
+++ b/src/classes/share/javax/media/j3d/Renderer.java
@@ -25,7 +25,7 @@ import java.util.*;
class Renderer extends J3dThread {
- int objectId = -1;
+
// This action causes this thread to wait
static final int WAIT = 0;
@@ -78,26 +78,26 @@ class Renderer extends J3dThread {
boolean sharedStereoZBuffer;
// This is the id for the underlying sharable graphics context
- long sharedCtx = 0;
+ Context sharedCtx = null;
// since the sharedCtx id can be the same as the previous one,
// we need to keep a time stamp to differentiate the contexts with the
// same id
long sharedCtxTimeStamp = 0;
- // display id - to free shared context
- long display;
- int window;
+ // display and drawable, used to free shared context
+ private long sharedCtxDisplay = 0;
+ private Drawable sharedCtxDrawable = null;
/**
* This is the id of the current rendering context
*/
- long currentCtx = -1;
+ Context currentCtx = null;
/**
- * This is the id of the current rendering window
+ * This is the id of the current rendering drawable
*/
- long currentWindow = 0;
+ Drawable currentDrawable = null;
// an unique bit to identify this renderer
int rendererBit = 0;
@@ -132,22 +132,21 @@ class Renderer extends J3dThread {
Screen3D onScreen;
Screen3D offScreen;
- // full screen anti-aliasing projection matrices
- double accumLeftProjMat[] = new double[16];
- double accumRightProjMat[] = new double[16];
- double accumInfLeftProjMat[] = new double[16];
- double accumInfRightProjMat[] = new double[16];
+ // full screen anti-aliasing projection matrices
+ Transform3D accumLeftProj = new Transform3D();
+ Transform3D accumRightProj = new Transform3D();
+ Transform3D accumInfLeftProj = new Transform3D();
+ Transform3D accumInfRightProj = new Transform3D();
// rendering messages
J3dMessage m[];
int nmesg = 0;
// List of contexts created
- ArrayList listOfCtxs = new ArrayList();
+ ArrayList<Context> listOfCtxs = new ArrayList<Context>();
// Parallel list of canvases
- ArrayList listOfCanvases = new ArrayList();
-
+ ArrayList<Canvas3D> listOfCanvases = new ArrayList<Canvas3D>();
boolean needToRebuildDisplayList = false;
boolean needToResendTextureDown = false;
@@ -161,8 +160,6 @@ class Renderer extends J3dThread {
// It is used when sharedCtx = true;
ArrayList textureIDResourceTable = new ArrayList(5);
- native void D3DCleanUp();
-
private synchronized int newInstanceNum() {
return (++numInstances);
}
@@ -215,112 +212,133 @@ class Renderer extends J3dThread {
opArg = ((Integer)args[0]).intValue();
try {
- if (opArg == SWAP) {
-
- Object [] swapArray = (Object[])args[2];
-
- view = (View)args[3];
-
- for (i=0; i<swapArray.length; i++) {
- cv = (Canvas3D) swapArray[i];
- if (!cv.isRunning) {
- continue;
- }
-
- doneSwap: try {
-
- if (!cv.validCanvas) {
- continue;
- }
-
- if (cv.active && (cv.ctx != 0) &&
- (cv.view != null) && (cv.imageReady)) {
- if (cv.useDoubleBuffer) {
- synchronized (cv.drawingSurfaceObject) {
- if (cv.validCtx) {
- if (VirtualUniverse.mc.doDsiRenderLock) {
- // Set doDsiLock flag for rendering based on system
- // property, If we force DSI lock for swap
- // buffer, we lose most of the parallelism that having
- // multiple renderers gives us.
-
- if (!cv.drawingSurfaceObject.renderLock()) {
- break doneSwap;
- }
- cv.makeCtxCurrent();
- cv.syncRender(cv.ctx, true);
- status = cv.swapBuffers(cv.ctx,
- cv.screen.display,
- cv.window);
- if (status != Canvas3D.NOCHANGE) {
- cv.resetRendering(status);
- }
- cv.drawingSurfaceObject.unLock();
- } else {
- cv.makeCtxCurrent();
-
- cv.syncRender(cv.ctx, true);
- status = cv.swapBuffers(cv.ctx,
- cv.screen.display,
- cv.window);
- if (status != Canvas3D.NOCHANGE) {
- cv.resetRendering(status);
- }
-
- }
- }
- }
- }
- cv.view.inCanvasCallback = true;
- try {
- cv.postSwap();
- } catch (RuntimeException e) {
- System.err.println("Exception occurred during Canvas3D callback:");
- e.printStackTrace();
- }
- // reset flag
- cv.imageReady = false;
- cv.view.inCanvasCallback = false;
- // Clear canvasDirty bit ONLY when postSwap() success
-
- // Set all dirty bits except environment set and lightbin
- // they are only set dirty if the last used light bin or
- // environment set values for this canvas change between
- // one frame and other
-
- if (!cv.ctxChanged) {
- cv.canvasDirty = (0xffff & ~(Canvas3D.LIGHTBIN_DIRTY |
- Canvas3D.LIGHTENABLES_DIRTY |
- Canvas3D.AMBIENTLIGHT_DIRTY |
- Canvas3D.MODELCLIP_DIRTY |
- Canvas3D.VIEW_MATRIX_DIRTY |
- Canvas3D.FOG_DIRTY));
- // Force reload of transform next frame
- cv.modelMatrix = null;
-
- // Force the cached renderAtom to null
- cv.ra = null;
- } else {
- cv.ctxChanged = false;
- }
- }
- } catch (NullPointerException ne) {
- //ne.printStackTrace();
- if (VirtualUniverse.mc.doDsiRenderLock) {
- cv.drawingSurfaceObject.unLock();
- }
- }
- }
-
- if (view != null) { // STOP_TIMER
- // incElapsedFrames() is delay until MC:updateMirroObject
- if (view.viewCache.getDoHeadTracking()) {
- VirtualUniverse.mc.sendRunMessage(view,
- J3dThread.RENDER_THREAD);
- }
- }
-
- } else if (opArg == REQUESTCLEANUP) {
+ if (opArg == SWAP) {
+
+ Object [] swapArray = (Object[])args[2];
+
+ view = (View)args[3];
+
+ for (i=0; i<swapArray.length; i++) {
+ cv = (Canvas3D) swapArray[i];
+ if (!cv.isRunning) {
+ continue;
+ }
+
+ doneSwap: try {
+
+ if (!cv.validCanvas) {
+ continue;
+ }
+
+ if (cv.active && (cv.ctx != null) &&
+ (cv.view != null) && (cv.imageReady)) {
+ if (cv.useDoubleBuffer) {
+ synchronized (cv.drawingSurfaceObject) {
+ if (cv.validCtx) {
+ if (VirtualUniverse.mc.doDsiRenderLock) {
+ // Set doDsiLock flag for rendering based on system
+ // property, If we force DSI lock for swap
+ // buffer, we lose most of the parallelism that having
+ // multiple renderers gives us.
+
+ if (!cv.drawingSurfaceObject.renderLock()) {
+ break doneSwap;
+ }
+ cv.makeCtxCurrent();
+ cv.syncRender(cv.ctx, true);
+ status = cv.swapBuffers(cv.ctx,
+ cv.screen.display,
+ cv.drawable);
+ if (status != Canvas3D.NOCHANGE) {
+ cv.resetRendering(status);
+ }
+ cv.drawingSurfaceObject.unLock();
+ } else {
+ cv.makeCtxCurrent();
+
+ cv.syncRender(cv.ctx, true);
+ status = cv.swapBuffers(cv.ctx,
+ cv.screen.display,
+ cv.drawable);
+ if (status != Canvas3D.NOCHANGE) {
+ cv.resetRendering(status);
+ }
+
+ }
+ }
+ }
+ }
+ cv.view.inCanvasCallback = true;
+ try {
+ cv.postSwap();
+ } catch (RuntimeException e) {
+ System.err.println("Exception occurred during Canvas3D callback:");
+ e.printStackTrace();
+ } catch (Error e) {
+ // Issue 264 - catch Error so Renderer doesn't die
+ System.err.println("Error occurred during Canvas3D callback:");
+ e.printStackTrace();
+ }
+ // reset flag
+ cv.imageReady = false;
+ cv.view.inCanvasCallback = false;
+ // Clear canvasDirty bit ONLY when postSwap() success
+
+ // Set all dirty bits except environment set and lightbin
+ // they are only set dirty if the last used light bin or
+ // environment set values for this canvas change between
+ // one frame and other
+
+ if (!cv.ctxChanged) {
+ cv.canvasDirty = (0xffff & ~(Canvas3D.LIGHTBIN_DIRTY |
+ Canvas3D.LIGHTENABLES_DIRTY |
+ Canvas3D.AMBIENTLIGHT_DIRTY |
+ Canvas3D.MODELCLIP_DIRTY |
+ Canvas3D.VIEW_MATRIX_DIRTY |
+ Canvas3D.FOG_DIRTY));
+ // Force reload of transform next frame
+ cv.modelMatrix = null;
+
+ // Force the cached renderAtom to null
+ cv.ra = null;
+ } else {
+ cv.ctxChanged = false;
+ }
+ }
+ } catch (NullPointerException ne) {
+ // Ignore NPE
+ if (VirtualUniverse.mc.doDsiRenderLock) {
+ cv.drawingSurfaceObject.unLock();
+ }
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+
+ if (VirtualUniverse.mc.doDsiRenderLock) {
+ cv.drawingSurfaceObject.unLock();
+ }
+
+ // Issue 260 : indicate fatal error and notify error listeners
+ cv.setFatalError();
+ RenderingError err =
+ new RenderingError(RenderingError.UNEXPECTED_RENDERING_ERROR,
+ J3dI18N.getString("Renderer0"));
+ err.setCanvas3D(cv);
+ err.setGraphicsDevice(cv.graphicsConfiguration.getDevice());
+ notifyErrorListeners(err);
+ }
+
+ cv.releaseCtx();
+ }
+
+ if (view != null) { // STOP_TIMER
+ // incElapsedFrames() is delay until MC:updateMirroObject
+ if (view.viewCache.getDoHeadTracking()) {
+ VirtualUniverse.mc.sendRunMessage(view,
+ J3dThread.RENDER_THREAD);
+ }
+ }
+
+ } else if (opArg == REQUESTCLEANUP) {
Integer mtype = (Integer) args[2];
if (mtype == MasterControl.REMOVEALLCTXS_CLEANUP) {
@@ -329,12 +347,12 @@ class Renderer extends J3dThread {
} else if (mtype == MasterControl.FREECONTEXT_CLEANUP) {
// from MasterControl freeContext(View v)
cv = (Canvas3D) args[1];
- removeCtx(cv, cv.screen.display, cv.window, cv.ctx,
+ removeCtx(cv, cv.screen.display, cv.drawable, cv.ctx,
true, true, false);
} else if (mtype == MasterControl.RESETCANVAS_CLEANUP) {
// from MasterControl RESET_CANVAS postRequest
cv = (Canvas3D) args[1];
- if (cv.ctx != 0) {
+ if (cv.ctx != null) {
cv.makeCtxCurrent();
}
cv.freeContextResources(cv.screen.renderer, true, cv.ctx);
@@ -344,22 +362,27 @@ class Renderer extends J3dThread {
Canvas3D c = (Canvas3D) obj[0];
removeCtx(c,
((Long) obj[1]).longValue(),
- ((Integer) obj[2]).intValue(),
- ((Long) obj[3]).longValue(),
+ (Drawable) obj[2],
+ (Context) obj[3],
false, !c.offScreen,
false);
}
return;
} else { // RENDER || REQUESTRENDER
-
int renderType;
nmesg = 0;
int totalMessages = 0;
if (opArg == RENDER) {
m = renderMessage;
- m[0] = VirtualUniverse.mc.getMessage();
- m[0].type = J3dMessage.RENDER_RETAINED;
+ m[0] = new J3dMessage();
+ // Issue 131: Set appropriate message type
+ if (((Canvas3D)args[1]).offScreen) {
+ m[0].type = J3dMessage.RENDER_OFFSCREEN;
+ }
+ else {
+ m[0].type = J3dMessage.RENDER_RETAINED;
+ }
m[0].incRefcount();
m[0].args[0] = args[1];
totalMessages = 1;
@@ -370,7 +393,7 @@ class Renderer extends J3dThread {
return;
}
}
-
+
doneRender: while (nmesg < totalMessages) {
@@ -383,20 +406,19 @@ class Renderer extends J3dThread {
Integer reqType = (Integer) m[nmesg].args[2];
Canvas3D c = (Canvas3D) secondArg;
if (reqType == MasterControl.SET_GRAPHICSCONFIG_FEATURES) {
- NativeConfigTemplate3D nct =
- GraphicsConfigTemplate3D.nativeTemplate;
+ try {
if (c.offScreen) {
// offScreen canvas neither supports
// double buffering nor stereo
c.doubleBufferAvailable = false;
c.stereoAvailable = false;
} else {
- c.doubleBufferAvailable = nct.hasDoubleBuffer(c);
- c.stereoAvailable = nct.hasStereo(c);
+ c.doubleBufferAvailable = c.hasDoubleBuffer();
+ c.stereoAvailable = c.hasStereo();
}
// Setup stencil related variables.
- c.actualStencilSize = nct.getStencilSize(c);
+ c.actualStencilSize = c.getStencilSize();
boolean userOwnsStencil = c.requestedStencilSize > 0;
c.userStencilAvailable =
@@ -404,35 +426,53 @@ class Renderer extends J3dThread {
c.systemStencilAvailable =
(!userOwnsStencil && (c.actualStencilSize > 0));
- /*
- System.out.println("Renderer :check for nct configuration");
- System.out.println("-- userStencilAvailable " +
- c.userStencilAvailable);
- System.out.println("-- systemStencilAvailable " +
- c.systemStencilAvailable);
- */
-
c.sceneAntialiasingMultiSamplesAvailable =
- nct.hasSceneAntialiasingMultisample(c);
+ c.hasSceneAntialiasingMultisample();
if (c.sceneAntialiasingMultiSamplesAvailable) {
c.sceneAntialiasingAvailable = true;
} else {
c.sceneAntialiasingAvailable =
- nct.hasSceneAntialiasingAccum(c);
+ c.hasSceneAntialiasingAccum();
}
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+
+ // Issue 260 : indicate fatal error and notify error listeners
+ c.setFatalError();
+ RenderingError err =
+ new RenderingError(RenderingError.GRAPHICS_CONFIG_ERROR,
+ J3dI18N.getString("Renderer1"));
+ err.setCanvas3D(c);
+ err.setGraphicsDevice(c.graphicsConfiguration.getDevice());
+ notifyErrorListeners(err);
+ }
GraphicsConfigTemplate3D.runMonitor(J3dThread.NOTIFY);
} else if (reqType == MasterControl.SET_QUERYPROPERTIES){
- c.createQueryContext();
+ try {
+ c.createQueryContext();
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+
+ // Issue 260 : indicate fatal error and notify error listeners
+ c.setFatalError();
+ RenderingError err =
+ new RenderingError(RenderingError.CONTEXT_CREATION_ERROR,
+ J3dI18N.getString("Renderer2"));
+ err.setCanvas3D(c);
+ err.setGraphicsDevice(c.graphicsConfiguration.getDevice());
+ notifyErrorListeners(err);
+ }
// currentCtx change after we create a new context
GraphicsConfigTemplate3D.runMonitor(J3dThread.NOTIFY);
- currentCtx = -1;
- currentWindow = 0;
+ currentCtx = null;
+ currentDrawable = null;
}
} else if (secondArg instanceof Integer) {
- // message from TextureRetained finalize() method
- // to free texture id
- freeTextureID(((Integer) secondArg).intValue(), (String)m[nmesg].args[2]);
+ // Issue 121 - This was formerly used as a message from
+ // the now-nonexistant TextureRetained finalize() method
+ // to free the texture id
+ throw new AssertionError();
} else if (secondArg instanceof GeometryArrayRetained) {
// message from GeometryArrayRetained
// clearLive() to free D3D array
@@ -441,20 +481,49 @@ class Renderer extends J3dThread {
GraphicsConfigTemplate3D gct =
(GraphicsConfigTemplate3D) secondArg;
Integer reqType = (Integer) m[nmesg].args[2];
- if (reqType == MasterControl.GETBESTCONFIG) {
- gct.testCfg =
- gct.nativeTemplate.getBestConfiguration(gct,
- (GraphicsConfiguration []) gct.testCfg);
+ if (reqType == MasterControl.GETBESTCONFIG) {
+ GraphicsConfiguration gcfg = null;
+ GraphicsConfiguration [] gcList = (GraphicsConfiguration []) gct.testCfg;
+ try {
+ gcfg = Pipeline.getPipeline().getBestConfiguration(gct, gcList);
+ } catch (NullPointerException npe) {
+ npe.printStackTrace();
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+
+ // Issue 260 : notify error listeners
+ RenderingError err =
+ new RenderingError(RenderingError.GRAPHICS_CONFIG_ERROR,
+ J3dI18N.getString("Renderer3"));
+ err.setGraphicsDevice(gcList[0].getDevice());
+ notifyErrorListeners(err);
+ }
+
+ gct.testCfg = gcfg;
} else if (reqType == MasterControl.ISCONFIGSUPPORT) {
- if (gct.nativeTemplate.isGraphicsConfigSupported(gct,
- (GraphicsConfiguration) gct.testCfg)) {
- gct.testCfg = Boolean.TRUE;
- } else {
- gct.testCfg = Boolean.FALSE;
- }
- }
+ boolean rval = false;
+ GraphicsConfiguration gc = (GraphicsConfiguration) gct.testCfg;
+ try {
+ if (Pipeline.getPipeline().isGraphicsConfigSupported(gct, gc)) {
+ rval = true;
+ }
+ } catch (NullPointerException npe) {
+ npe.printStackTrace();
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+
+ // Issue 260 : notify error listeners
+ RenderingError err =
+ new RenderingError(RenderingError.GRAPHICS_CONFIG_ERROR,
+ J3dI18N.getString("Renderer4"));
+ err.setGraphicsDevice(gc.getDevice());
+ notifyErrorListeners(err);
+ }
+
+ gct.testCfg = Boolean.valueOf(rval);
+ }
gct.runMonitor(J3dThread.NOTIFY);
- }
+ }
m[nmesg++].decRefcount();
continue;
@@ -467,28 +536,45 @@ class Renderer extends J3dThread {
if (renderType == J3dMessage.CREATE_OFFSCREENBUFFER) {
// Fix for issue 18.
// Fix for issue 20.
- canvas.window =
- canvas.createOffScreenBuffer(canvas.ctx,
- canvas.screen.display,
- canvas.vid,
- canvas.fbConfig,
- canvas.offScreenCanvasSize.width,
- canvas.offScreenCanvasSize.height);
+
+ canvas.drawable = null;
+ try {
+ canvas.drawable =
+ canvas.createOffScreenBuffer(canvas.ctx,
+ canvas.screen.display,
+ canvas.fbConfig,
+ canvas.offScreenCanvasSize.width,
+ canvas.offScreenCanvasSize.height);
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+ }
+
+ if (canvas.drawable == null) {
+ // Issue 260 : indicate fatal error and notify error listeners
+ canvas.setFatalError();
+ RenderingError err =
+ new RenderingError(RenderingError.OFF_SCREEN_BUFFER_ERROR,
+ J3dI18N.getString("Renderer5"));
+ err.setCanvas3D(canvas);
+ err.setGraphicsDevice(canvas.graphicsConfiguration.getDevice());
+ notifyErrorListeners(err);
+ }
+
canvas.offScreenBufferPending = false;
m[nmesg++].decRefcount();
continue;
}
else if (renderType == J3dMessage.DESTROY_CTX_AND_OFFSCREENBUFFER) {
- // Fix for issue 175.
- // destroy ctx.
- // Should be able to collaspe both call into one. Will do this in 1.5,
- // it is a little risky for 1.4 beta3.
- removeCtx(canvas, canvas.screen.display, canvas.window, canvas.ctx,
- false, !canvas.offScreen, false);
- // destroy offScreenBuffer.
- removeCtx(canvas, canvas.screen.display, canvas.window, 0,
- false, !canvas.offScreen, true);
-
+ Object[] obj = m[nmesg].args;
+
+ // Fix for issue 175: destroy ctx & off-screen buffer
+ // Fix for issue 340: get display, drawable & ctx from msg
+ removeCtx(canvas,
+ ((Long) obj[1]).longValue(),
+ (Drawable) obj[2],
+ (Context) obj[3],
+ false, !canvas.offScreen, true);
+
canvas.offScreenBufferPending = false;
m[nmesg++].decRefcount();
continue;
@@ -525,8 +611,13 @@ class Renderer extends J3dThread {
VirtualUniverse.mc.resendTexTimestamp++;
needToResendTextureDown = false;
}
-
- if (canvas.ctx != 0) {
+
+ if (canvas.isFatalError()) {
+ continue;
+ }
+
+ try {
+ if (canvas.ctx != null) {
// ctx may not construct until doClear();
canvas.beginScene();
}
@@ -583,17 +674,11 @@ class Renderer extends J3dThread {
case GraphicsContext3D.SET_MODEL_TRANSFORM:
t3d = (Transform3D)m[nmesg].args[2];
canvas.graphicsContext3D.doSetModelTransform(t3d);
- // return t3d to freelist. t3d was gotten from GraphicsContext3D
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D,
- t3d);
break;
case GraphicsContext3D.MULTIPLY_MODEL_TRANSFORM:
- t3d = (Transform3D)m[nmesg].args[2];
- canvas.graphicsContext3D.doMultiplyModelTransform(t3d);
- // return t3d to freelist. t3d was gotten from GraphicsContext3D
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D,
- t3d);
- break;
+ t3d = (Transform3D)m[nmesg].args[2];
+ canvas.graphicsContext3D.doMultiplyModelTransform(t3d);
+ break;
case GraphicsContext3D.SET_SOUND:
canvas.graphicsContext3D.doSetSound(
(Sound)m[nmesg].args[2],
@@ -643,6 +728,9 @@ class Renderer extends J3dThread {
((Point) ar[3]).y,
(ImageObserver) ar[4]);
break;
+ case GraphicsContext3D.DISPOSE2D:
+ canvas.graphics2D.doDispose();
+ break;
case GraphicsContext3D.SET_MODELCLIP:
canvas.graphicsContext3D.doSetModelClip(
(ModelClip)m[nmesg].args[2]);
@@ -651,30 +739,53 @@ class Renderer extends J3dThread {
break;
}
- if (canvas.ctx != 0) {
+ if (canvas.ctx != null) {
canvas.endScene();
}
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+
+ // Issue 260 : indicate fatal error and notify error listeners
+ canvas.setFatalError();
+ RenderingError err =
+ new RenderingError(RenderingError.CONTEXT_CREATION_ERROR,
+ J3dI18N.getString("Renderer6"));
+ err.setCanvas3D(canvas);
+ err.setGraphicsDevice(canvas.graphicsConfiguration.getDevice());
+ notifyErrorListeners(err);
+ }
+
m[nmesg++].decRefcount();
} else { // retained mode rendering
m[nmesg++].decRefcount();
+
+ if (canvas.isFatalError()) {
+ continue;
+ }
ImageComponent2DRetained offBufRetained = null;
if (renderType == J3dMessage.RENDER_OFFSCREEN) {
- if (canvas.window == 0 || !canvas.active) {
+ // Issue 131: set offScreenRendering flag here, since it
+ // otherwise won't be set for auto-off-screen rendering
+ // (which doesn't use renderOffScreenBuffer)
+ canvas.offScreenRendering = true;
+ if (canvas.drawable == null || !canvas.active) {
canvas.offScreenRendering = false;
continue;
} else {
offBufRetained = (ImageComponent2DRetained)
canvas.offScreenBuffer.retained;
- if (offBufRetained.isByReference()) {
- offBufRetained.geomLock.getLock();
- offBufRetained.evaluateExtensions(
- canvas.extensionsSupported);
- }
+ if (offBufRetained.isByReference()) {
+ offBufRetained.geomLock.getLock();
+ }
+
+ offBufRetained.evaluateExtensions(canvas);
+
}
+
} else if (!canvas.active) {
continue;
}
@@ -687,8 +798,6 @@ class Renderer extends J3dThread {
canvas.drawingSurfaceObject.getDrawingSurfaceObjectInfo();
}
- boolean background_image_update = false;
-
renderBin = canvas.view.renderBin;
// setup rendering context
@@ -698,8 +807,9 @@ class Renderer extends J3dThread {
if (canvas.useSharedCtx) {
- if (sharedCtx == 0) {
- display = canvas.screen.display;
+ if (sharedCtx == null) {
+ sharedCtxDisplay = canvas.screen.display;
+ sharedCtxDrawable = canvas.drawable;
// Always lock for context create
if (!canvas.drawingSurfaceObject.renderLock()) {
@@ -707,17 +817,35 @@ class Renderer extends J3dThread {
offBufRetained.isByReference()) {
offBufRetained.geomLock.unLock();
}
+ canvas.offScreenRendering = false;
break doneRender;
}
synchronized (VirtualUniverse.mc.contextCreationLock) {
- sharedCtx = canvas.createNewContext(0, true);
- if (sharedCtx == 0) {
+ sharedCtx = null;
+ try {
+ sharedCtx = canvas.createNewContext(null, true);
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+ }
+
+ if (sharedCtx == null) {
canvas.drawingSurfaceObject.unLock();
if ((offBufRetained != null) &&
offBufRetained.isByReference()) {
offBufRetained.geomLock.unLock();
}
+ canvas.offScreenRendering = false;
+
+ // Issue 260 : indicate fatal error and notify error listeners
+ canvas.setFatalError();
+ RenderingError err =
+ new RenderingError(RenderingError.CONTEXT_CREATION_ERROR,
+ J3dI18N.getString("Renderer7"));
+ err.setCanvas3D(canvas);
+ err.setGraphicsDevice(canvas.graphicsConfiguration.getDevice());
+ notifyErrorListeners(err);
+
break doneRender;
}
sharedCtxTimeStamp =
@@ -730,9 +858,7 @@ class Renderer extends J3dThread {
}
}
- if (canvas.ctx == 0) {
-
- display = canvas.screen.display;
+ if (canvas.ctx == null) {
// Always lock for context create
if (!canvas.drawingSurfaceObject.renderLock()) {
@@ -740,19 +866,36 @@ class Renderer extends J3dThread {
offBufRetained.isByReference()) {
offBufRetained.geomLock.unLock();
}
+ canvas.offScreenRendering = false;
break doneRender;
}
synchronized (VirtualUniverse.mc.contextCreationLock) {
- canvas.ctx = canvas.createNewContext(sharedCtx, false);
+ canvas.ctx = null;
+ try {
+ canvas.ctx = canvas.createNewContext(sharedCtx, false);
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+ }
- if (canvas.ctx == 0) {
+ if (canvas.ctx == null) {
canvas.drawingSurfaceObject.unLock();
if ((offBufRetained != null) &&
offBufRetained.isByReference()) {
offBufRetained.geomLock.unLock();
}
- break doneRender;
+ canvas.offScreenRendering = false;
+
+ // Issue 260 : indicate fatal error and notify error listeners
+ canvas.setFatalError();
+ RenderingError err =
+ new RenderingError(RenderingError.CONTEXT_CREATION_ERROR,
+ J3dI18N.getString("Renderer7"));
+ err.setCanvas3D(canvas);
+ err.setGraphicsDevice(canvas.graphicsConfiguration.getDevice());
+ notifyErrorListeners(err);
+
+ break doneRender;
}
if (canvas.graphics2D != null) {
@@ -761,13 +904,15 @@ class Renderer extends J3dThread {
canvas.ctxTimeStamp =
VirtualUniverse.mc.getContextTimeStamp();
- listOfCtxs.add(new Long(canvas.ctx));
+ listOfCtxs.add(canvas.ctx);
listOfCanvases.add(canvas);
if (renderBin.nodeComponentList.size() > 0) {
for (i = 0; i < renderBin.nodeComponentList.size(); i++) {
NodeComponentRetained nc = (NodeComponentRetained)renderBin.nodeComponentList.get(i);
- nc.evaluateExtensions(canvas.extensionsSupported);
+ if(nc instanceof ImageComponent2DRetained) {
+ ((ImageComponent2DRetained)nc).evaluateExtensions(canvas);
+ }
}
}
@@ -781,11 +926,6 @@ class Renderer extends J3dThread {
canvas.createTexUnitState();
}
- // Create the texture unit state map
- if (canvas.texUnitStateMap == null) {
- canvas.createTexUnitStateMap();
- }
-
canvas.resetImmediateRendering(Canvas3D.NOCHANGE);
canvas.drawingSurfaceObject.contextValidated();
@@ -808,6 +948,7 @@ class Renderer extends J3dThread {
offBufRetained.isByReference()) {
offBufRetained.geomLock.unLock();
}
+ canvas.offScreenRendering = false;
break doneRender;
}
@@ -822,13 +963,6 @@ class Renderer extends J3dThread {
canvas.freeResourcesInFreeList(canvas.ctx);
}
- // save the BACKGROUND_IMAGE_DIRTY before canvas.updateViewCache
- // clean it
- synchronized (canvas.dirtyMaskLock) {
- background_image_update =
- ((canvas.cvDirtyMask[Canvas3D.RENDERER_DIRTY_IDX] & Canvas3D.BACKGROUND_IMAGE_DIRTY) != 0);
- }
-
if (VirtualUniverse.mc.doDsiRenderLock) {
canvas.drawingSurfaceObject.unLock();
}
@@ -848,6 +982,7 @@ class Renderer extends J3dThread {
offBufRetained.isByReference()) {
offBufRetained.geomLock.unLock();
}
+ canvas.offScreenRendering = false;
break doneRender;
}
@@ -933,14 +1068,14 @@ class Renderer extends J3dThread {
canvas.sceneAntialiasingAvailable) {
if (!VirtualUniverse.mc.isD3D() &&
- ((canvas.extensionsSupported & Canvas3D.ARB_MULTISAMPLE) == 0) ||
+ ((canvas.extensionsSupported & Canvas3D.MULTISAMPLE) == 0) ||
!canvas.sceneAntialiasingMultiSamplesAvailable) {
doAccum = true;
num_accum_passes = NUM_ACCUMULATION_SAMPLES;
System.arraycopy(
cvCache.getLeftProjection().mat,
- 0, accumLeftProjMat, 0, 16);
+ 0, accumLeftProj.mat, 0, 16);
accumDxFactor = (
@@ -952,29 +1087,29 @@ class Renderer extends J3dThread {
canvas.canvasViewCache.getCanvasHeight())*canvas.view.fieldOfView;
- accumLeftX = accumLeftProjMat[3];
- accumLeftY = accumLeftProjMat[7];
+ accumLeftX = accumLeftProj.mat[3];
+ accumLeftY = accumLeftProj.mat[7];
if (useStereo) {
System.arraycopy(
cvCache.getRightProjection().mat,
- 0, accumRightProjMat, 0, 16);
- accumRightX = accumRightProjMat[3];
- accumRightY = accumRightProjMat[7];
+ 0, accumRightProj.mat, 0, 16);
+ accumRightX = accumRightProj.mat[3];
+ accumRightY = accumRightProj.mat[7];
}
if (renderBin.geometryBackground != null) {
System.arraycopy(
cvCache.getInfLeftProjection().mat,
- 0, accumInfLeftProjMat, 0, 16);
- accumInfLeftX = accumInfLeftProjMat[3];
- accumInfLeftY = accumInfLeftProjMat[7];
+ 0, accumInfLeftProj.mat, 0, 16);
+ accumInfLeftX = accumInfLeftProj.mat[3];
+ accumInfLeftY = accumInfLeftProj.mat[7];
if (useStereo) {
System.arraycopy(
cvCache.getInfRightProjection().mat,
- 0, accumInfRightProjMat, 0, 16);
- accumInfRightX = accumInfRightProjMat[3];
- accumInfRightY = accumInfRightProjMat[7];
+ 0, accumInfRightProj.mat, 0, 16);
+ accumInfRightX = accumInfRightProj.mat[3];
+ accumInfRightY = accumInfRightProj.mat[7];
}
}
} else {
@@ -1005,39 +1140,6 @@ class Renderer extends J3dThread {
Canvas3D.FIELD_ALL,
canvas.useDoubleBuffer);
- // Support DVR
- /*
- System.out.println("canvas.supportVideoResize() is " +
- canvas.supportVideoResize());
- */
- if(canvas.supportVideoResize()) {
- if(canvas.view.dvrResizeCompensation !=
- canvas.cachedDvrResizeCompensation) {
- /*
- System.out.println("Renderer : dvrResizeComp " +
- canvas.view.dvrResizeCompensation);
- */
- canvas.videoResizeCompensation(canvas.ctx,
- canvas.view.dvrResizeCompensation);
- canvas.cachedDvrResizeCompensation =
- canvas.view.dvrResizeCompensation;
-
- }
- if(canvas.view.dvrFactor != canvas.cachedDvrFactor) {
- /*
- System.out.println("Renderer : dvrFactor is " +
- canvas.view.dvrFactor);
- */
- canvas.videoResize(canvas.ctx,
- canvas.screen.display,
- canvas.window,
- canvas.view.dvrFactor);
- canvas.cachedDvrFactor = canvas.view.dvrFactor;
-
- }
-
- }
-
canvas.beginScene();
// this is if the background image resizes with the canvas
@@ -1049,41 +1151,9 @@ class Renderer extends J3dThread {
// and not in stereo mode
if (!doAccum && !sharedStereoZBuffer) {
BackgroundRetained bg = renderBin.background;
- if (!VirtualUniverse.mc.isBackgroundTexture) {
- canvas.clear(canvas.ctx,
- bg.color.x,
- bg.color.y,
- bg.color.z,
- winWidth,
- winHeight,
- bg.image,
- bg.imageScaleMode,
- (bg.image != null?
- bg.image.imageYdown[0]:null));
- } else {
- if ((bg.texImage != null) &&
- (objectId == -1)) {
- objectId = VirtualUniverse.mc.
- getTexture2DId();
- }
- canvas.textureclear(canvas.ctx,
- bg.xmax,
- bg.ymax,
- bg.color.x,
- bg.color.y,
- bg.color.z,
- winWidth,
- winHeight,
- objectId,
- bg.imageScaleMode,
- bg.texImage,
- background_image_update);
- }
-// canvas.clear(canvas.ctx,
-// bg.color.x,
-// bg.color.y,
-// bg.color.z,
-// bg.image);
+
+ canvas.clear(bg, winWidth, winHeight);
+
}
// handle preRender callback
@@ -1095,18 +1165,22 @@ class Renderer extends J3dThread {
try {
canvas.preRender();
} catch (RuntimeException e) {
- System.err.println("Exception occurred " +
- "during Canvas3D callback:");
+ System.err.println("Exception occurred during Canvas3D callback:");
e.printStackTrace();
+ } catch (Error e) {
+ // Issue 264 - catch Error so Renderer doesn't die
+ System.err.println("Error occurred during Canvas3D callback:");
+ e.printStackTrace();
}
canvas.view.inCanvasCallback = false;
-
+
if ((VirtualUniverse.mc.doDsiRenderLock) &&
(!canvas.drawingSurfaceObject.renderLock())) {
if ((offBufRetained != null) &&
offBufRetained.isByReference()) {
offBufRetained.geomLock.unLock();
}
+ canvas.offScreenRendering = false;
break doneRender;
}
@@ -1130,82 +1204,54 @@ class Renderer extends J3dThread {
accumDy = ACCUM_SAMPLES_Y[apass] *
accumDyFactor;
- accumLeftProjMat[3] = accumLeftX +
- accumLeftProjMat[0] * accumDx +
- accumLeftProjMat[1] * accumDy;
+ accumLeftProj.mat[3] = accumLeftX +
+ accumLeftProj.mat[0] * accumDx +
+ accumLeftProj.mat[1] * accumDy;
- accumLeftProjMat[7] = accumLeftY +
- accumLeftProjMat[4] * accumDx +
- accumLeftProjMat[5] * accumDy;
+ accumLeftProj.mat[7] = accumLeftY +
+ accumLeftProj.mat[4] * accumDx +
+ accumLeftProj.mat[5] * accumDy;
if (useStereo) {
- accumRightProjMat[3] = accumRightX +
- accumRightProjMat[0] * accumDx +
- accumRightProjMat[1] * accumDy;
+ accumRightProj.mat[3] = accumRightX +
+ accumRightProj.mat[0] * accumDx +
+ accumRightProj.mat[1] * accumDy;
- accumRightProjMat[7] = accumRightY +
- accumRightProjMat[4] * accumDx +
- accumRightProjMat[5] * accumDy;
+ accumRightProj.mat[7] = accumRightY +
+ accumRightProj.mat[4] * accumDx +
+ accumRightProj.mat[5] * accumDy;
}
if (renderBin.geometryBackground != null) {
- accumInfLeftProjMat[3] = accumInfLeftX +
- accumInfLeftProjMat[0] * accumDx +
- accumInfLeftProjMat[1] * accumDy;
+ accumInfLeftProj.mat[3] = accumInfLeftX +
+ accumInfLeftProj.mat[0] * accumDx +
+ accumInfLeftProj.mat[1] * accumDy;
- accumInfLeftProjMat[7] = accumInfLeftY +
- accumInfLeftProjMat[4] * accumDx +
- accumInfLeftProjMat[5] * accumDy;
+ accumInfLeftProj.mat[7] = accumInfLeftY +
+ accumInfLeftProj.mat[4] * accumDx +
+ accumInfLeftProj.mat[5] * accumDy;
if (useStereo) {
- accumInfRightProjMat[3] =
+ accumInfRightProj.mat[3] =
accumInfRightX +
- accumInfRightProjMat[0] * accumDx +
- accumInfRightProjMat[1] * accumDy;
+ accumInfRightProj.mat[0] * accumDx +
+ accumInfRightProj.mat[1] * accumDy;
- accumInfRightProjMat[7] =
+ accumInfRightProj.mat[7] =
accumInfRightY +
- accumInfRightProjMat[4] * accumDx +
- accumInfRightProjMat[5] * accumDy;
+ accumInfRightProj.mat[4] * accumDx +
+ accumInfRightProj.mat[5] * accumDy;
}
- }
+ }
}
// clear background for stereo and
// accumulation buffer cases
if (doAccum || sharedStereoZBuffer) {
BackgroundRetained bg = renderBin.background;
- if (!VirtualUniverse.mc.isBackgroundTexture) {
- canvas.clear(canvas.ctx,
- bg.color.x,
- bg.color.y,
- bg.color.z,
- winWidth,
- winHeight,
- bg.image,
- bg.imageScaleMode,
- (bg.image != null?bg.image.imageYdown[0]:null));
- }
- else {
- if ((bg.texImage != null) &&
- (objectId == -1)) {
- objectId = VirtualUniverse.mc.
- getTexture2DId();
- }
-
- canvas.textureclear(canvas.ctx,
- bg.xmax,
- bg.ymax,
- bg.color.x,
- bg.color.y,
- bg.color.z,
- winWidth,
- winHeight,
- objectId,
- bg.imageScaleMode,
- bg.texImage,
- background_image_update);
- }
+
+ canvas.clear(bg, winWidth, winHeight);
+
}
// render background geometry
@@ -1217,24 +1263,22 @@ class Renderer extends J3dThread {
cvCache.getInfLeftVpcToEc();
if (doAccum) {
canvas.setProjectionMatrix(
- canvas.ctx,
- accumInfLeftProjMat);
+ canvas.ctx, accumInfLeftProj);
} else {
canvas.setProjectionMatrix(
canvas.ctx,
- cvCache.getInfLeftProjection().mat);
+ cvCache.getInfLeftProjection());
}
} else {
canvas.vpcToEc =
cvCache.getInfRightVpcToEc();
if (doAccum) {
canvas.setProjectionMatrix(
- canvas.ctx,
- accumInfRightProjMat);
+ canvas.ctx, accumInfRightProj);
} else {
canvas.setProjectionMatrix(
canvas.ctx,
- cvCache.getInfRightProjection().mat);
+ cvCache.getInfRightProjection());
}
}
canvas.vworldToEc.mul(canvas.vpcToEc,
@@ -1248,20 +1292,19 @@ class Renderer extends J3dThread {
if (pass == 0) {
canvas.vpcToEc = cvCache.getLeftVpcToEc();
if (doAccum) {
- canvas.setProjectionMatrix(
- canvas.ctx, accumLeftProjMat);
+ canvas.setProjectionMatrix(canvas.ctx, accumLeftProj);
} else {
canvas.setProjectionMatrix(canvas.ctx,
- cvCache.getLeftProjection().mat);
+ cvCache.getLeftProjection());
}
} else {
canvas.vpcToEc = cvCache.getRightVpcToEc();
if (doAccum) {
canvas.setProjectionMatrix(
- canvas.ctx, accumRightProjMat);
+ canvas.ctx, accumRightProj);
} else {
canvas.setProjectionMatrix(canvas.ctx,
- cvCache.getRightProjection().mat);
+ cvCache.getRightProjection());
}
}
canvas.vworldToEc.mul(canvas.vpcToEc,
@@ -1295,9 +1338,12 @@ class Renderer extends J3dThread {
try {
canvas.renderField(stereo_mode);
} catch (RuntimeException e) {
- System.err.println("Exception occurred during " +
- "Canvas3D callback:");
- e.printStackTrace();
+ System.err.println("Exception occurred during Canvas3D callback:");
+ e.printStackTrace();
+ } catch (Error e) {
+ // Issue 264 - catch Error so Renderer doesn't die
+ System.err.println("Error occurred during Canvas3D callback:");
+ e.printStackTrace();
}
canvas.view.inCanvasCallback = false;
if ((VirtualUniverse.mc.doDsiRenderLock) &&
@@ -1306,6 +1352,7 @@ class Renderer extends J3dThread {
offBufRetained.isByReference()) {
offBufRetained.geomLock.unLock();
}
+ canvas.offScreenRendering = false;
break doneRender;
}
@@ -1340,8 +1387,11 @@ class Renderer extends J3dThread {
try {
canvas.postRender();
} catch (RuntimeException e) {
- System.err.println("Exception occurred during " +
- "Canvas3D callback:");
+ System.err.println("Exception occurred during Canvas3D callback:");
+ e.printStackTrace();
+ } catch (Error e) {
+ // Issue 264 - catch Error so Renderer doesn't die
+ System.err.println("Error occurred during Canvas3D callback:");
e.printStackTrace();
}
canvas.view.inCanvasCallback = false;
@@ -1351,6 +1401,7 @@ class Renderer extends J3dThread {
canvas.syncRender(canvas.ctx, true);
canvas.endOffScreenRendering();
+ canvas.offScreenRendering = false;
// do the postSwap for offscreen here
canvas.view.inCanvasCallback = true;
@@ -1359,16 +1410,20 @@ class Renderer extends J3dThread {
} catch (RuntimeException e) {
System.err.println("Exception occurred during Canvas 3D callback:");
e.printStackTrace();
+ } catch (Error e) {
+ // Issue 264 - catch Error so Renderer doesn't die
+ System.err.println("Error occurred during Canvas3D callback:");
+ e.printStackTrace();
}
if (offBufRetained.isByReference()) {
offBufRetained.geomLock.unLock();
}
- canvas.offScreenRendering = false;
canvas.view.inCanvasCallback = false;
- }
+ canvas.releaseCtx();
+ }
canvas.endScene();
@@ -1425,10 +1480,11 @@ class Renderer extends J3dThread {
Arrays.fill(m, 0, totalMessages, null);
}
}
- } catch (NullPointerException ne) {
+ } catch (NullPointerException ne) {
+ // Print NPE, but otherwise ignore it
ne.printStackTrace();
if (canvas != null) {
- if (canvas.ctx != 0) {
+ if (canvas.ctx != null) {
canvas.endScene();
}
// drawingSurfaceObject will safely ignore
@@ -1436,16 +1492,35 @@ class Renderer extends J3dThread {
canvas.drawingSurfaceObject.unLock();
}
- }
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+
+ if (canvas != null) {
+ if (canvas.ctx != null) {
+ canvas.endScene();
+ }
+ // drawingSurfaceObject will safely ignore
+ // this request if this is not lock before
+ canvas.drawingSurfaceObject.unLock();
+ }
+
+ // Issue 260 : indicate fatal error and notify error listeners
+ canvas.setFatalError();
+ RenderingError err =
+ new RenderingError(RenderingError.UNEXPECTED_RENDERING_ERROR,
+ J3dI18N.getString("Renderer8"));
+ err.setCanvas3D(canvas);
+ if (canvas != null) {
+ err.setGraphicsDevice(canvas.graphicsConfiguration.getDevice());
+ }
+ notifyErrorListeners(err);
+ }
}
// resource clean up
void shutdown() {
removeAllCtxs();
-
- if (VirtualUniverse.mc.isD3D()) {
- D3DCleanUp();
- }
+ Pipeline.getPipeline().cleanupRenderer();
}
void cleanup() {
@@ -1454,8 +1529,10 @@ class Renderer extends J3dThread {
rendererStructure = new RendererStructure();
bgVworldToVpc = new Transform3D();
numframes = 0.0f;
- sharedCtx = 0;
+ sharedCtx = null;
sharedCtxTimeStamp = 0;
+ sharedCtxDisplay = 0;
+ sharedCtxDrawable = null;
dirtyRenderMoleculeList.clear();
dirtyRenderAtomList.clear();
dirtyDlistPerRinfoList.clear();
@@ -1467,24 +1544,22 @@ class Renderer extends J3dThread {
nmesg = 0;
lasttime = 0;
currtime = 0;
- display = 0;
}
-
// This is only invoked from removeCtx()/removeAllCtxs()
// with drawingSurface already lock
- final void makeCtxCurrent(long sharedCtx, long display, int window) {
- if (sharedCtx != currentCtx || window != currentWindow) {
- Canvas3D.useCtx(sharedCtx, display, window);
+ final void makeCtxCurrent(Context sharedCtx, long display, Drawable drawable) {
+ if (sharedCtx != currentCtx || drawable != currentDrawable) {
+ Canvas3D.useCtx(sharedCtx, display, drawable);
/*
- if(!Canvas3D.useCtx(sharedCtx, display, window)) {
+ if(!Canvas3D.useCtx(sharedCtx, display, drawable)) {
Thread.dumpStack();
System.err.println("useCtx Fail");
}
*/
currentCtx = sharedCtx;
- currentWindow = window;
+ currentDrawable = drawable;
}
}
@@ -1492,67 +1567,65 @@ class Renderer extends J3dThread {
// Canvas3D postRequest() offScreen rendering since the
// user thread will not wait for it. Also we can just
// reuse it as Canvas3D did not destroy.
- private void removeCtx(Canvas3D cv, long display, int window, long ctx,
+ private void removeCtx(Canvas3D cv, long display, Drawable drawable, Context ctx,
boolean resetCtx, boolean freeBackground,
boolean destroyOffScreenBuffer) {
-
synchronized (VirtualUniverse.mc.contextCreationLock) {
- // Fix for issue 18.
- // Since we are now the renderer thread,
- // we can safely execute destroyOffScreenBuffer.
- if(destroyOffScreenBuffer) {
- cv.destroyOffScreenBuffer(ctx, display, cv.fbConfig, window);
- cv.offScreenBufferPending = false;
- }
-
- if (ctx != 0) {
- int idx = listOfCtxs.indexOf(new Long(ctx));
+ if (ctx != null) {
+ int idx = listOfCtxs.indexOf(ctx);
if (idx >= 0) {
listOfCtxs.remove(idx);
listOfCanvases.remove(idx);
- // display is always 0 under windows
- if ((MasterControl.isWin32 || (display != 0)) &&
- (window != 0) && cv.added) {
+ // Issue 326 : don't check display variable here
+ if ((drawable != null) && cv.added) {
// cv.ctx may reset to -1 here so we
// always use the ctx pass in.
if (cv.drawingSurfaceObject.renderLock()) {
// if it is the last one, free shared resources
- if (sharedCtx != 0) {
+ if (sharedCtx != null) {
if (listOfCtxs.isEmpty()) {
- makeCtxCurrent(sharedCtx, display, window);
+ makeCtxCurrent(sharedCtx, sharedCtxDisplay, sharedCtxDrawable);
freeResourcesInFreeList(null);
freeContextResources();
- Canvas3D.destroyContext(display, window, sharedCtx);
- currentCtx = -1;
- currentWindow = 0;
+ Canvas3D.destroyContext(sharedCtxDisplay, sharedCtxDrawable, sharedCtx);
+ currentCtx = null;
+ currentDrawable = null;
} else {
freeResourcesInFreeList(cv);
}
- cv.makeCtxCurrent(ctx, display, window);
+ cv.makeCtxCurrent(ctx, display, drawable);
} else {
- cv.makeCtxCurrent(ctx, display, window);
+ cv.makeCtxCurrent(ctx, display, drawable);
cv.freeResourcesInFreeList(ctx);
}
cv.freeContextResources(this, freeBackground, ctx);
- Canvas3D.destroyContext(display, window, ctx);
- currentCtx = -1;
- currentWindow = 0;
+ Canvas3D.destroyContext(display, drawable, ctx);
+ currentCtx = null;
+ currentDrawable = null;
cv.drawingSurfaceObject.unLock();
}
}
}
if (resetCtx) {
- cv.ctx = 0;
+ cv.ctx = null;
}
- if ((sharedCtx != 0) && listOfCtxs.isEmpty()) {
- sharedCtx = 0;
+ if ((sharedCtx != null) && listOfCtxs.isEmpty()) {
+ sharedCtx = null;
sharedCtxTimeStamp = 0;
}
cv.ctxTimeStamp = 0;
}
+
+ // Fix for issue 18.
+ // Since we are now the renderer thread,
+ // we can safely execute destroyOffScreenBuffer.
+ if(destroyOffScreenBuffer) {
+ cv.destroyOffScreenBuffer(ctx, display, cv.fbConfig, drawable);
+ cv.offScreenBufferPending = false;
+ }
}
}
@@ -1564,41 +1637,41 @@ class Renderer extends J3dThread {
for (int i=listOfCanvases.size()-1; i >=0; i--) {
cv = (Canvas3D) listOfCanvases.get(i);
- if ((cv.screen != null) && (cv.ctx != 0)) {
- if ((MasterControl.isWin32 || (display != 0)) &&
- (cv.window != 0) && cv.added) {
+ if ((cv.screen != null) && (cv.ctx != null)) {
+ // Issue 326 : don't check display variable here
+ if ((cv.drawable != null) && cv.added) {
if (cv.drawingSurfaceObject.renderLock()) {
// We need to free sharedCtx resource
// first before last non-sharedCtx to
// workaround Nvidia driver bug under Linux
// that crash on freeTexture ID:4685156
- if ((i == 0) && (sharedCtx != 0)) {
- makeCtxCurrent(sharedCtx, display, window);
+ if ((i == 0) && (sharedCtx != null)) {
+ makeCtxCurrent(sharedCtx, sharedCtxDisplay, sharedCtxDrawable);
freeResourcesInFreeList(null);
freeContextResources();
- Canvas3D.destroyContext(display, window, sharedCtx);
- currentCtx = -1;
- currentWindow = 0;
+ Canvas3D.destroyContext(sharedCtxDisplay, sharedCtxDrawable, sharedCtx);
+ currentCtx = null;
+ currentDrawable = null;
}
cv.makeCtxCurrent();
cv.freeResourcesInFreeList(cv.ctx);
cv.freeContextResources(this, true, cv.ctx);
Canvas3D.destroyContext(cv.screen.display,
- cv.window,
+ cv.drawable,
cv.ctx);
- currentCtx = -1;
- currentWindow = 0;
+ currentCtx = null;
+ currentDrawable = null;
cv.drawingSurfaceObject.unLock();
}
}
}
- cv.ctx = 0;
+ cv.ctx = null;
cv.ctxTimeStamp = 0;
}
- if (sharedCtx != 0) {
- sharedCtx = 0;
+ if (sharedCtx != null) {
+ sharedCtx = null;
sharedCtxTimeStamp = 0;
}
listOfCanvases.clear();
@@ -1606,49 +1679,6 @@ class Renderer extends J3dThread {
}
}
- void freeTextureID(int texId, String texture) {
- Canvas3D currentCanvas = null;
-
- // get the current canvas
- for (int i=listOfCtxs.size()-1; i >= 0; i--) {
- Canvas3D c = (Canvas3D) listOfCanvases.get(i);
- if (c.ctx == currentCtx) {
- currentCanvas = c;
- break;
- }
- }
-
- if (currentCanvas == null) {
- return;
- }
-
- synchronized (VirtualUniverse.mc.contextCreationLock) {
- if (sharedCtx != 0) {
- currentCanvas.makeCtxCurrent(sharedCtx);
- // OGL share context is used
- Canvas3D.freeTexture(sharedCtx, texId);
- } else {
- for (int i=listOfCtxs.size()-1; i >= 0; i--) {
- Canvas3D c = (Canvas3D) listOfCanvases.get(i);
- c.makeCtxCurrent();
- Canvas3D.freeTexture(c.ctx, texId);
- }
- }
- // restore current context
- currentCanvas.makeCtxCurrent();
- }
- // Issue 162: TEMPORARY FIX -- don't free the texture ID, since it will
- // be freed once per canvas / screen and will subsequently cause the ID
- // to be used for multiple textures.
-// if (texture.equals("2D")){
-// VirtualUniverse.mc.freeTexture2DId(texId);
-// }
-// else if(texture.equals("3D")){
-// VirtualUniverse.mc.freeTexture3DId(texId);
-// }
- }
-
-
// handle free resource in the FreeList
void freeResourcesInFreeList(Canvas3D cv) {
Iterator it;
@@ -1684,7 +1714,18 @@ class Renderer extends J3dThread {
textureIDResourceTable.size() +
" val = " + val);
} else {
- textureIDResourceTable.set(val, null);
+ Object obj = textureIDResourceTable.get(val);
+ if (obj instanceof TextureRetained) {
+ TextureRetained tex = (TextureRetained) obj;
+ synchronized (tex.resourceLock) {
+ tex.resourceCreationMask &= ~rendererBit;
+ if (tex.resourceCreationMask == 0) {
+ tex.freeTextureId(val);
+ }
+ }
+ }
+
+ textureIDResourceTable.set(val, null);
}
Canvas3D.freeTexture(sharedCtx, val);
}
@@ -1711,7 +1752,6 @@ class Renderer extends J3dThread {
void freeContextResources() {
Object obj;
TextureRetained tex;
- DetailTextureImage detailTex;
for (int id = textureIDResourceTable.size()-1; id > 0; id--) {
obj = textureIDResourceTable.get(id);
@@ -1727,17 +1767,44 @@ class Renderer extends J3dThread {
tex.freeTextureId(id);
}
}
- } else if (obj instanceof DetailTextureImage) {
- detailTex = (DetailTextureImage) obj;
- detailTex.freeDetailTextureId(id, rendererBit);
}
-
}
textureIDResourceTable.clear();
// displayList is free in Canvas.freeContextResources()
}
+
+ /**
+ * Send a message to the notification thread, which will call the
+ * shader error listeners.
+ */
+ static void notifyErrorListeners(RenderingError err) {
+ J3dNotification notification = new J3dNotification();
+ notification.type = J3dNotification.RENDERING_ERROR;
+ notification.universe = null;//cv.view.universe;
+ notification.args[0] = err;
+ VirtualUniverse.mc.sendNotification(notification);
+ }
-}
+ // Default rendering error listener class
+ private static RenderingErrorListener defaultErrorListener = null;
+ synchronized static RenderingErrorListener getDefaultErrorListener() {
+ if (defaultErrorListener == null) {
+ defaultErrorListener = new DefaultErrorListener();
+ }
+
+ return defaultErrorListener;
+ }
+
+ static class DefaultErrorListener implements RenderingErrorListener {
+ public void errorOccurred(RenderingError error) {
+ System.err.println();
+ System.err.println("DefaultRenderingErrorListener.errorOccurred:");
+ error.printVerbose();
+ System.exit(1);
+ }
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/RenderingAttributesRetained.java b/src/classes/share/javax/media/j3d/RenderingAttributesRetained.java
index 0558b83..c7c80a0 100644
--- a/src/classes/share/javax/media/j3d/RenderingAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/RenderingAttributesRetained.java
@@ -491,28 +491,13 @@ class RenderingAttributesRetained extends NodeComponentRetained {
* Updates the native context.
*/
- // TODO : Need to handle stencil operation on the native side -- Chien
- native void updateNative(long ctx,
- boolean depthBufferWriteEnableOverride,
- boolean depthBufferEnableOverride,
- boolean depthBufferEnable,
- boolean depthBufferWriteEnable,
- int depthTestFunction,
- float alphaTestValue, int alphaTestFunction,
- boolean ignoreVertexColors,
- boolean rasterOpEnable, int rasterOp,
- boolean userStencilAvailable, boolean stencilEnable,
- int stencilFailOp, int stencilZFailOp, int stencilZPassOp,
- int stencilFunction, int stencilReferenceValue,
- int stencilCompareMask, int stencilWriteMask );
-
/**
* Updates the native context.
*/
void updateNative(Canvas3D c3d,
boolean depthBufferWriteEnableOverride,
boolean depthBufferEnableOverride) {
- updateNative(c3d.ctx,
+ Pipeline.getPipeline().updateRenderingAttributes(c3d.ctx,
depthBufferWriteEnableOverride, depthBufferEnableOverride,
depthBufferEnable, depthBufferWriteEnable, depthTestFunction,
alphaTestValue, alphaTestFunction, ignoreVertexColors,
@@ -658,7 +643,7 @@ class RenderingAttributesRetained extends NodeComponentRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.RENDERINGATTRIBUTES_CHANGED;
createMessage.universe = null;
@@ -671,7 +656,7 @@ class RenderingAttributesRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
if (attrMask == VISIBLE)
createMessage.threads |= J3dThread.UPDATE_GEOMETRY;
diff --git a/src/classes/share/javax/media/j3d/RenderingError.java b/src/classes/share/javax/media/j3d/RenderingError.java
new file mode 100644
index 0000000..d86e834
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/RenderingError.java
@@ -0,0 +1,253 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.awt.GraphicsDevice;
+import java.io.PrintStream;
+
+/**
+ * RenderingError is a container object that holds the details of
+ * a runtime error that occurs in the Java 3D rendering system.
+ *
+ * @since Java 3D 1.5
+ */
+public class RenderingError extends Object {
+ private int errorCode = NO_ERROR;
+ private String errorMessage = null;
+ private String detailMessage = null;
+ private GraphicsDevice graphicsDevice = null;
+ private Canvas3D canvas = null;
+
+ /**
+ * Indicates that no error occurred.
+ */
+ public static final int NO_ERROR = 0;
+
+ /**
+ * Indicates that an unexpected rendering exception was caught by the
+ * Java 3D renderer thread.
+ */
+ public static final int UNEXPECTED_RENDERING_ERROR = 1;
+
+ /**
+ * Indicates that an error occurred while getting the best graphics
+ * configuration or while testing whether a given graphics config is
+ * supported.
+ */
+ public static final int GRAPHICS_CONFIG_ERROR = 2;
+
+ /**
+ * Indicates that an error occurred while creating an OpenGL or D3D
+ * graphics context. This can happen either when querying
+ * the Canvas3D properties or when rendering.
+ */
+ public static final int CONTEXT_CREATION_ERROR = 3;
+
+ /**
+ * Indicates a error in creating a rendering buffer for an off-screen
+ * Canvas3D.
+ */
+ public static final int OFF_SCREEN_BUFFER_ERROR = 4;
+
+
+ /**
+ * Constructs a new RenderingError object indicating no error. The
+ * error code is set to <code>NO_ERROR</code>. All other fields
+ * are initialized to null, including the error message.
+ */
+ public RenderingError() {
+ }
+
+ /**
+ * Constructs a new RenderingError object with the given error code
+ * and message. All other fields are initialized to null.
+ *
+ * @param errorCode the error code for this rendering error.
+ * @param errorMessage a short error message describing this
+ * rendering error.
+ */
+ public RenderingError(int errorCode, String errorMessage) {
+ this.errorCode = errorCode;
+ this.errorMessage = errorMessage;
+ }
+
+ /**
+ * Prints a verbose error report to System.err. This verbose
+ * output includes the error code, error message, detail message,
+ * and all relevant Java 3D objects.
+ */
+ public void printVerbose() {
+ printVerbose(System.err);
+ }
+
+ /**
+ * Prints a verbose error report to the specified PrintStream.
+ * This verbose output includes the error code, error message,
+ * detail message, and all relevant Java 3D objects.
+ *
+ * @param printStream the print stream on which to print the error
+ * report.
+ */
+ public void printVerbose(PrintStream printStream) {
+ printStream.println(this);
+ if (graphicsDevice != null) {
+ printStream.println("graphicsDevice = " + graphicsDevice);
+ }
+ if (canvas != null) {
+ printStream.println("canvas = " + canvas);
+ }
+
+ if (detailMessage != null) {
+ printStream.println();
+ printStream.println("Detail Message");
+ printStream.println("--------------");
+ printStream.println(detailMessage);
+ }
+ }
+
+ /**
+ * Sets the error code for this rendering error. This represents the
+ * type of error that occurred.
+ *
+ * @param errorCode the error code for this rendering error.
+ */
+ public void setErrorCode(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ /**
+ * Returns the error code for this rendering error.
+ *
+ * @return the error code.
+ */
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ /**
+ * Sets the error message for this rendering error. This is a short
+ * message describing the error, and is included as part of
+ * toString().
+ *
+ * @param errorMessage a short error message describing this
+ * rendering error.
+ */
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ /**
+ * Returns the error message for this rendering error.
+ *
+ * @return a short error message describing this rendering error.
+ */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * Sets the detail message for this rendering error. This is a more
+ * detailed error message that is not included as part of toString().
+ *
+ * @param detailMessage a detailed message describing this
+ * error in more detail.
+ */
+ public void setDetailMessage(String detailMessage) {
+ this.detailMessage = detailMessage;
+ }
+
+ /**
+ * Returns the detail message for this rendering error.
+ *
+ * @return the detail message for this rendering error.
+ */
+ public String getDetailMessage() {
+ return detailMessage;
+ }
+
+ /**
+ * Sets the graphics device associated with this rendering error.
+ *
+ * @param graphicsDevice the graphics device associated with this rendering error.
+ */
+ public void setGraphicsDevice(GraphicsDevice graphicsDevice) {
+ this.graphicsDevice = graphicsDevice;
+ }
+
+ /**
+ * Returns the graphics device associated with this rendering error.
+ *
+ * @return the graphics device associated with this rendering error.
+ */
+ public GraphicsDevice getGraphicsDevice() {
+ return this.graphicsDevice;
+ }
+
+ /**
+ * Sets the canvas associated with this rendering error.
+ *
+ * @param canvas the canvas associated with this rendering error.
+ */
+ public void setCanvas3D(Canvas3D canvas) {
+ this.canvas = canvas;
+ }
+
+ /**
+ * Returns the canvas associated with this rendering error.
+ *
+ * @return the canvas associated with this rendering error.
+ */
+ public Canvas3D getCanvas3D() {
+ return this.canvas;
+ }
+
+
+ /**
+ * Returns a short string that describes this rendering error. The
+ * string is composed of the textual description of the errorCode,
+ * a ": ", and the errorMessage field. If the errorMessage is
+ * null then the ": " and the errorMessage are omitted.
+ *
+ * @return a string representation of this rendering error.
+ */
+ public String toString() {
+ // Concatenate string representation of error code with error message
+ String errorCodeStr;
+ switch (errorCode) {
+ case NO_ERROR:
+ errorCodeStr = "NO_ERROR";
+ break;
+ case UNEXPECTED_RENDERING_ERROR:
+ errorCodeStr = "UNEXPECTED_RENDERING_ERROR";
+ break;
+ case GRAPHICS_CONFIG_ERROR:
+ errorCodeStr = "GRAPHICS_CONFIG_ERROR";
+ break;
+ case CONTEXT_CREATION_ERROR:
+ errorCodeStr = "CONTEXT_CREATION_ERROR";
+ break;
+ case OFF_SCREEN_BUFFER_ERROR:
+ errorCodeStr = "OFF_SCREEN_BUFFER_ERROR";
+ break;
+
+ default:
+ errorCodeStr = "UNKNOWN ERROR CODE (" + errorCode + ")";
+ }
+
+ if (errorMessage == null) {
+ return errorCodeStr;
+ }
+
+ return errorCodeStr + ": " + errorMessage;
+ }
+}
diff --git a/src/classes/share/javax/media/j3d/RenderingErrorListener.java b/src/classes/share/javax/media/j3d/RenderingErrorListener.java
new file mode 100644
index 0000000..b621775
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/RenderingErrorListener.java
@@ -0,0 +1,29 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Listener interface for monitoring Java 3D rendering errors.
+ *
+ * @see VirtualUniverse#addRenderingErrorListener
+ *
+ * @since Java 3D 1.5
+ */
+public interface RenderingErrorListener {
+ /**
+ * Invoked when an error occurs in the Java 3D rendering system.
+ *
+ * @param error object that contains the details of the error.
+ */
+ public void errorOccurred(RenderingError error);
+}
diff --git a/src/classes/share/javax/media/j3d/Screen3D.java b/src/classes/share/javax/media/j3d/Screen3D.java
index 6633b99..017947b 100644
--- a/src/classes/share/javax/media/j3d/Screen3D.java
+++ b/src/classes/share/javax/media/j3d/Screen3D.java
@@ -97,8 +97,10 @@ public class Screen3D extends Object {
// an off-screen Canvas3D or with one or more on-screen Canvas3Ds
boolean offScreen;
- // The display connection (X11 only) and the screen ID
+ // The display connection (native OGL pipeline on X11 only)
long display;
+
+ // Screen number
int screen;
// The width and height of the screen in meters.
@@ -353,18 +355,14 @@ public class Screen3D extends Object {
* associated with an off-screen Canvas3D
*/
Screen3D(GraphicsConfiguration graphicsConfiguration, boolean offScreen) {
- NativeScreenInfo nativeScreenInfo;
-
this.offScreen = offScreen;
this.graphicsDevice = graphicsConfiguration.getDevice();
screenViewCache = new ScreenViewCache(this);
- nativeScreenInfo = new NativeScreenInfo(graphicsDevice);
- // Get the display from the native code (X11 only) and the
- // screen ID
- display = nativeScreenInfo.getDisplay();
- screen = nativeScreenInfo.getScreen();
+ // Get the display handle and the screen number from the Pipeline
+ display = Pipeline.getPipeline().getDisplay();
+ screen = Pipeline.getPipeline().getScreen(graphicsDevice);
if (debug)
System.out.println("Screen3D: display " + display +
diff --git a/src/classes/share/javax/media/j3d/SetLiveState.java b/src/classes/share/javax/media/j3d/SetLiveState.java
index bffd18f..d7b0000 100644
--- a/src/classes/share/javax/media/j3d/SetLiveState.java
+++ b/src/classes/share/javax/media/j3d/SetLiveState.java
@@ -248,5 +248,10 @@ class SetLiveState extends Object {
//transformTargetThreads = 0;
hashkeyIndex = null;
+
+ // Fix for issue 75
+ parentBranchGroupPaths = null;
+ branchGroupPaths = null;
+ orderedPaths = null;
}
}
diff --git a/src/classes/share/javax/media/j3d/ShaderAppearanceRetained.java b/src/classes/share/javax/media/j3d/ShaderAppearanceRetained.java
index 9815827..b5dc6f9 100644
--- a/src/classes/share/javax/media/j3d/ShaderAppearanceRetained.java
+++ b/src/classes/share/javax/media/j3d/ShaderAppearanceRetained.java
@@ -281,7 +281,7 @@ class ShaderAppearanceRetained extends AppearanceRetained {
ArrayList gaList = Shape3DRetained.getGeomAtomsList(mirror.users, univList);
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.SHADER_APPEARANCE_CHANGED;
createMessage.universe = null;
@@ -294,7 +294,7 @@ class ShaderAppearanceRetained extends AppearanceRetained {
//System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.SHADER_APPEARANCE_CHANGED;
@@ -328,8 +328,20 @@ class ShaderAppearanceRetained extends AppearanceRetained {
return flag;
}
+ // Issue 209 - implement the compile method
+ // Simply pass along to the NodeComponents
+ void compile(CompileState compState) {
+ super.compile(compState);
+
+ if (shaderProgram != null) {
+ shaderProgram.compile(compState);
+ }
+
+ if (shaderAttributeSet != null) {
+ shaderAttributeSet.compile(compState);
+ }
+ }
-
boolean isOpaque(int geoType) {
if (!super.isOpaque(geoType)) {
diff --git a/src/classes/share/javax/media/j3d/ShaderAttrLoc.java b/src/classes/share/javax/media/j3d/ShaderAttrLoc.java
new file mode 100644
index 0000000..f7c5a88
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttrLoc.java
@@ -0,0 +1,22 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Tagging interface for shader attribute location objects. The rendering
+ * pipelines will define concrete classes that implement this interface. All
+ * code that uses the tagged objects will be in the pipelines.
+ */
+interface ShaderAttrLoc {
+ // No methods or constants defined at this time
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeObjectRetained.java b/src/classes/share/javax/media/j3d/ShaderAttributeObjectRetained.java
index 7d5ede7..efd4bc3 100644
--- a/src/classes/share/javax/media/j3d/ShaderAttributeObjectRetained.java
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeObjectRetained.java
@@ -125,7 +125,7 @@ abstract class ShaderAttributeObjectRetained extends ShaderAttributeRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.SHADER_ATTRIBUTE_CHANGED;
createMessage.universe = null;
@@ -138,7 +138,7 @@ abstract class ShaderAttributeObjectRetained extends ShaderAttributeRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.SHADER_ATTRIBUTE_CHANGED;
@@ -283,4 +283,24 @@ abstract class ShaderAttributeObjectRetained extends ShaderAttributeRetained {
this.classType = classType;
}
+
+ // Issue 320 : Override base class method so we can force changedFrequent
+ // to be set whenever the capability is writable, regardless of whether
+ // it is frequently writable. We must do this because the ShaderBin doesn't
+ // support updating shader attributes when changedFrequent is 0.
+ void setFrequencyChangeMask(int bit, int mask) {
+ if (source.getCapability(bit)) {
+ changedFrequent |= mask;
+ } else if (!source.isLive()) {
+ // Record the freq->infreq change only for non-live node components
+ changedFrequent &= ~mask;
+ }
+ }
+
+ void handleFrequencyChange(int bit) {
+ if (bit == ShaderAttributeObject.ALLOW_VALUE_WRITE) {
+ setFrequencyChangeMask(bit, 0x1);
+ }
+ }
+
}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeSetRetained.java b/src/classes/share/javax/media/j3d/ShaderAttributeSetRetained.java
index 88952d9..ce03357 100644
--- a/src/classes/share/javax/media/j3d/ShaderAttributeSetRetained.java
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeSetRetained.java
@@ -319,7 +319,7 @@ class ShaderAttributeSetRetained extends NodeComponentRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.SHADER_ATTRIBUTE_SET_CHANGED;
createMessage.universe = null;
@@ -332,7 +332,7 @@ class ShaderAttributeSetRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.SHADER_ATTRIBUTE_SET_CHANGED;
@@ -351,4 +351,24 @@ class ShaderAttributeSetRetained extends NodeComponentRetained {
}
+
+ // Issue 320 : Override base class method so we can force changedFrequent
+ // to be set whenever the capability is writable, regardless of whether
+ // it is frequently writable. We must do this because the ShaderBin doesn't
+ // support updating shader attributes when changedFrequent is 0.
+ void setFrequencyChangeMask(int bit, int mask) {
+ if (source.getCapability(bit)) {
+ changedFrequent |= mask;
+ } else if (!source.isLive()) {
+ // Record the freq->infreq change only for non-live node components
+ changedFrequent &= ~mask;
+ }
+ }
+
+ void handleFrequencyChange(int bit) {
+ if (bit == ShaderAttributeSet.ALLOW_ATTRIBUTES_WRITE) {
+ setFrequencyChangeMask(bit, 0x1);
+ }
+ }
+
}
diff --git a/src/classes/share/javax/media/j3d/ShaderBin.java b/src/classes/share/javax/media/j3d/ShaderBin.java
index 83ca00f..056b9f4 100644
--- a/src/classes/share/javax/media/j3d/ShaderBin.java
+++ b/src/classes/share/javax/media/j3d/ShaderBin.java
@@ -270,8 +270,6 @@ class ShaderBin implements ObjectUpdate {
t.clear();
- renderBin.textureBinFreelist.add(t);
-
if (textureBinList == null && addTextureBins.size() == 0 ) {
// Note: Removal of this shaderBin as a user of the rendering
// atttrs is done during removeRenderAtom() in RenderMolecule.java
diff --git a/src/classes/share/javax/media/j3d/ShaderId.java b/src/classes/share/javax/media/j3d/ShaderId.java
new file mode 100644
index 0000000..f5ca3c7
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderId.java
@@ -0,0 +1,22 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Tagging interface for shader objects. The rendering pipelines
+ * will define concrete classes that implement this interface. All code that
+ * uses the tagged objects will be in the pipelines.
+ */
+interface ShaderId {
+ // No methods or constants defined at this time
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderProgramId.java b/src/classes/share/javax/media/j3d/ShaderProgramId.java
new file mode 100644
index 0000000..b3dd88c
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderProgramId.java
@@ -0,0 +1,22 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Tagging interface for shader program objects. The rendering pipelines
+ * will define concrete classes that implement this interface. All code that
+ * uses the tagged objects will be in the pipelines.
+ */
+interface ShaderProgramId {
+ // No methods or constants defined at this time
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderProgramRetained.java b/src/classes/share/javax/media/j3d/ShaderProgramRetained.java
index 6d926bf..9524d4b 100644
--- a/src/classes/share/javax/media/j3d/ShaderProgramRetained.java
+++ b/src/classes/share/javax/media/j3d/ShaderProgramRetained.java
@@ -195,176 +195,176 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
}
return shads;
}
- }
-
+ }
+
/**
* Method to create the native shader.
*/
- abstract ShaderError createShader(long ctx, ShaderRetained shader, long[] shaderIdArr);
+ abstract ShaderError createShader(Context ctx, ShaderRetained shader, ShaderId[] shaderIdArr);
/**
* Method to destroy the native shader.
*/
- abstract ShaderError destroyShader(long ctx, long shaderId);
+ abstract ShaderError destroyShader(Context ctx, ShaderId shaderId);
/**
* Method to compile the native shader.
*/
- abstract ShaderError compileShader(long ctx, long shaderId, String source);
+ abstract ShaderError compileShader(Context ctx, ShaderId shaderId, String source);
/**
* Method to create the native shader program.
*/
- abstract ShaderError createShaderProgram(long ctx, long[] shaderProgramIdArr);
+ abstract ShaderError createShaderProgram(Context ctx, ShaderProgramId[] shaderProgramIdArr);
/**
* Method to destroy the native shader program.
*/
- abstract ShaderError destroyShaderProgram(long ctx, long shaderProgramId);
+ abstract ShaderError destroyShaderProgram(Context ctx, ShaderProgramId shaderProgramId);
/**
* Method to link the native shader program.
*/
- abstract ShaderError linkShaderProgram(long ctx, long shaderProgramId, long[] shaderIds);
+ abstract ShaderError linkShaderProgram(Context ctx, ShaderProgramId shaderProgramId, ShaderId[] shaderIds);
/**
* Method to bind a vertex attribute name to the specified index.
*/
- abstract ShaderError bindVertexAttrName(long ctx, long shaderProgramId, String attrName, int attrIndex);
+ abstract ShaderError bindVertexAttrName(Context ctx, ShaderProgramId shaderProgramId, String attrName, int attrIndex);
/**
* Method to lookup a list of (uniform) shader attribute names and return
* information about the attributes.
*/
- abstract void lookupShaderAttrNames(long ctx, long shaderProgramId, String[] attrNames, AttrNameInfo[] attrNameInfoArr);
+ abstract void lookupShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId, String[] attrNames, AttrNameInfo[] attrNameInfoArr);
/*
* Method to lookup a list of vertex attribute names.
*/
- abstract void lookupVertexAttrNames(long ctx, long shaderProgramId, String[] attrNames, boolean[] errArr);
+ abstract void lookupVertexAttrNames(Context ctx, ShaderProgramId shaderProgramId, String[] attrNames, boolean[] errArr);
/**
* Method to use the native shader program.
*/
- abstract ShaderError enableShaderProgram(long ctx, long shaderProgramId);
+ abstract ShaderError enableShaderProgram(Context ctx, ShaderProgramId shaderProgramId);
/**
* Method to disable the native shader program.
*/
- abstract ShaderError disableShaderProgram(long ctx);
+ abstract ShaderError disableShaderProgram(Context ctx);
// ShaderAttributeValue methods
- abstract ShaderError setUniform1i(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform1i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int value);
- abstract ShaderError setUniform1f(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform1f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
float value);
- abstract ShaderError setUniform2i(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform2i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int[] value);
- abstract ShaderError setUniform2f(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform2f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
float[] value);
- abstract ShaderError setUniform3i(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform3i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int[] value);
- abstract ShaderError setUniform3f(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
float[] value);
- abstract ShaderError setUniform4i(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform4i(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int[] value);
- abstract ShaderError setUniform4f(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
float[] value);
- abstract ShaderError setUniformMatrix3f(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniformMatrix3f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
float[] value);
- abstract ShaderError setUniformMatrix4f(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniformMatrix4f(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
float[] value);
// ShaderAttributeArray methods
- abstract ShaderError setUniform1iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform1iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int numElements,
int[] value);
- abstract ShaderError setUniform1fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform1fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
- abstract ShaderError setUniform2iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform2iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int numElements,
int[] value);
- abstract ShaderError setUniform2fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform2fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
- abstract ShaderError setUniform3iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform3iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int numElements,
int[] value);
- abstract ShaderError setUniform3fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
- abstract ShaderError setUniform4iArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform4iArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int numElements,
int[] value);
- abstract ShaderError setUniform4fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniform4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
- abstract ShaderError setUniformMatrix3fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniformMatrix3fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
- abstract ShaderError setUniformMatrix4fArray(long ctx,
- long shaderProgramId,
- long uniformLocation,
+ abstract ShaderError setUniformMatrix4fArray(Context ctx,
+ ShaderProgramId shaderProgramId,
+ ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
@@ -505,9 +505,9 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
private ShaderError createShaderProgram(Canvas3D cv, int cvRdrIndex) {
// Create shaderProgram resources if it has not been done.
synchronized(resourceLock) {
- assert(shaderProgramData[cvRdrIndex].getShaderProgramId() == 0);
+ assert shaderProgramData[cvRdrIndex].getShaderProgramId() == null;
- long[] spIdArr = new long[1];
+ ShaderProgramId[] spIdArr = new ShaderProgramId[1];
ShaderError err = createShaderProgram(cv.ctx, spIdArr);
if(err != null) {
return err;
@@ -524,7 +524,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
private ShaderError linkShaderProgram(Canvas3D cv, int cvRdrIndex,
ShaderRetained[] shaders) {
synchronized(resourceLock) {
- long[] shaderIds = new long[shaders.length];
+ ShaderId[] shaderIds = new ShaderId[shaders.length];
for(int i=0; i<shaders.length; i++) {
synchronized(shaders[i]) {
shaderIds[i] = shaders[i].shaderIds[cvRdrIndex];
@@ -547,7 +547,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
private ShaderError bindVertexAttrName(Canvas3D cv, int cvRdrIndex, String attrName, int attrIndex) {
assert(attrName != null);
synchronized(resourceLock) {
- long shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
+ ShaderProgramId shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
// System.err.println("attrName = " + attrName);
ShaderError err = bindVertexAttrName(cv.ctx, shaderProgramId, attrName, attrIndex);
if (err != null) {
@@ -559,7 +559,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
private void lookupVertexAttrNames(Canvas3D cv, int cvRdrIndex, String[] attrNames) {
synchronized(resourceLock) {
- long shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
+ ShaderProgramId shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
boolean[] errArr = new boolean[attrNames.length];
lookupVertexAttrNames(cv.ctx, shaderProgramId, attrNames, errArr);
@@ -580,7 +580,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
private void lookupShaderAttrNames(Canvas3D cv, int cvRdrIndex, String[] attrNames) {
synchronized(resourceLock) {
- long shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
+ ShaderProgramId shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
AttrNameInfo[] attrNameInfoArr = new AttrNameInfo[attrNames.length];
lookupShaderAttrNames(cv.ctx, shaderProgramId, attrNames, attrNameInfoArr);
@@ -588,8 +588,8 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
for (int i = 0; i < attrNames.length; i++) {
shaderProgramData[cvRdrIndex].setAttrNameInfo(attrNames[i], attrNameInfoArr[i]);
- // Report non-fatal error if location is invalid (-1)
- if (attrNameInfoArr[i].getLocation() == -1) {
+ // Report non-fatal error if location is invalid
+ if (attrNameInfoArr[i].getLocation() == null) {
String errMsg = "Attribute name lookup failed: " + attrNames[i];
ShaderError err = new ShaderError(ShaderError.SHADER_ATTRIBUTE_LOOKUP_ERROR, errMsg);
err.setShaderProgram((ShaderProgram)this.source);
@@ -619,11 +619,11 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
synchronized(shader.resourceLock) {
if(shader.shaderIds == null){
// We rely on Java to initial the array elements to 0 or false;
- shader.shaderIds = new long[cvRdrIndex+1];
+ shader.shaderIds = new ShaderId[cvRdrIndex+1];
shader.compiled = new boolean[cvRdrIndex+1];
} else if( shader.shaderIds.length <= cvRdrIndex) {
// We rely on Java to initial the array elements to 0 or false;
- long[] tempSIds = new long[cvRdrIndex+1];
+ ShaderId[] tempSIds = new ShaderId[cvRdrIndex+1];
boolean[] tempCompiled = new boolean[cvRdrIndex+1];
System.arraycopy(shader.shaderIds, 0,
@@ -637,12 +637,12 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
shader.compiled = tempCompiled;
}
- if(shader.shaderIds[cvRdrIndex] != 0) {
+ if(shader.shaderIds[cvRdrIndex] != null) {
// We have already created the shaderId for this Canvas.
return null;
}
- long[] shaderIdArr = new long[1];
+ ShaderId[] shaderIdArr = new ShaderId[1];
ShaderError err = createShader(cv.ctx, shader, shaderIdArr);
if(err != null) {
return err;
@@ -722,15 +722,15 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
return;
}
- // Nothing to do if the shaderId is 0
- if (shader.shaderIds[cvRdrIndex] == 0) {
+ // Nothing to do if the shaderId is null
+ if (shader.shaderIds[cvRdrIndex] == null) {
return;
}
- // Destroy the native resource and set the ID to 0 for this canvas/renderer
+ // Destroy the native resource and set the ID to null for this canvas/renderer
// Ignore any possible shader error, because there is no meaningful way to report it
destroyShader(cv.ctx, shader.shaderIds[cvRdrIndex]);
- shader.shaderIds[cvRdrIndex] = 0;
+ shader.shaderIds[cvRdrIndex] = null;
}
}
@@ -756,13 +756,13 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
// return;
// }
- long shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
- // Nothing to do if the shaderProgramId is 0
- if (shaderProgramId == 0) {
+ ShaderProgramId shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
+ // Nothing to do if the shaderProgramId is null
+ if (shaderProgramId == null) {
return;
}
- // Destroy the native resource, set the ID to 0 for this canvas/renderer,
+ // Destroy the native resource, set the ID to null for this canvas/renderer,
// and clear the bit in the resourceCreationMask
// Ignore any possible shader error, because there is no meaningful way to report it
destroyShaderProgram(cv.ctx, shaderProgramId);
@@ -779,7 +779,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
void updateNative(Canvas3D cv, boolean enable) {
// System.out.println("ShaderProgramRetained.updateNative : ");
- final boolean useSharedCtx = cv.useSharedCtx && cv.screen.renderer.sharedCtx != 0;
+ final boolean useSharedCtx = cv.useSharedCtx && cv.screen.renderer.sharedCtx != null;
final int cvRdrIndex = useSharedCtx ? cv.screen.renderer.rendererId : cv.canvasId;
// Create ShaderProgramData object for this canvas/renderer if it doesn't already exist
@@ -806,7 +806,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
}
boolean loadShaderProgram = false; // flag indicating whether to reload all shaderProgram states
- if (getShaderProgramData(cvRdrIndex).getShaderProgramId() == 0) {
+ if (getShaderProgramData(cvRdrIndex).getShaderProgramId() == null) {
loadShaderProgram = true;
}
@@ -927,8 +927,8 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
/**
* Update native value for ShaderAttributeValue class
*/
- ShaderError setUniformAttrValue(long ctx, long shaderProgramId, long loc,
- ShaderAttributeValueRetained sav) {
+ ShaderError setUniformAttrValue(Context ctx, ShaderProgramId shaderProgramId,
+ ShaderAttrLoc loc, ShaderAttributeValueRetained sav) {
switch (sav.getClassType()) {
case ShaderAttributeObjectRetained.TYPE_INTEGER:
@@ -981,8 +981,8 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
/**
* Update native value for ShaderAttributeArray class
*/
- ShaderError setUniformAttrArray(long ctx, long shaderProgramId, long loc,
- ShaderAttributeArrayRetained saa) {
+ ShaderError setUniformAttrArray(Context ctx, ShaderProgramId shaderProgramId,
+ ShaderAttrLoc loc, ShaderAttributeArrayRetained saa) {
switch (saa.getClassType()) {
case ShaderAttributeObjectRetained.TYPE_INTEGER:
@@ -1035,7 +1035,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
void setShaderAttributes(Canvas3D cv, ShaderAttributeSetRetained attributeSet) {
- final boolean useSharedCtx = cv.useSharedCtx && cv.screen.renderer.sharedCtx != 0;
+ final boolean useSharedCtx = cv.useSharedCtx && cv.screen.renderer.sharedCtx != null;
final int cvRdrIndex = useSharedCtx ? cv.screen.renderer.rendererId : cv.canvasId;
ShaderProgramData spData = getShaderProgramData(cvRdrIndex);
@@ -1044,7 +1044,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
return;
}
- long shaderProgramId = spData.getShaderProgramId();
+ ShaderProgramId shaderProgramId = spData.getShaderProgramId();
Iterator attrs = attributeSet.getAttrs().values().iterator();
while (attrs.hasNext()) {
@@ -1060,8 +1060,8 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
String errMsg = "Attribute name not set in ShaderProgram: " + saRetained.getAttributeName(); // TODO: I18N
err = new ShaderError(ShaderError.SHADER_ATTRIBUTE_NAME_NOT_SET_ERROR, errMsg);
} else {
- long loc = attrNameInfo.getLocation();
- if (loc != -1) {
+ ShaderAttrLoc loc = attrNameInfo.getLocation();
+ if (loc != null) {
if (saRetained instanceof ShaderAttributeValueRetained) {
ShaderAttributeValueRetained savRetained = (ShaderAttributeValueRetained)saRetained;
if (attrNameInfo.isArray() ||
@@ -1111,7 +1111,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
class ShaderProgramData extends Object {
// shaderProgramId use by native code.
- private long shaderProgramId = 0;
+ private ShaderProgramId shaderProgramId = null;
// linked flag for native.
private boolean linked = false;
@@ -1124,16 +1124,16 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
}
void reset() {
- shaderProgramId = 0;
+ shaderProgramId = null;
linked = false;
attrNameInfoMap.clear();
}
- void setShaderProgramId(long shaderProgramId) {
+ void setShaderProgramId(ShaderProgramId shaderProgramId) {
this.shaderProgramId = shaderProgramId;
}
- long getShaderProgramId() {
+ ShaderProgramId getShaderProgramId() {
return this.shaderProgramId;
}
@@ -1159,11 +1159,11 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
// Data associated with an attribute name
class AttrNameInfo {
- void setLocation(long loc) {
+ void setLocation(ShaderAttrLoc loc) {
this.loc = loc;
}
- long getLocation() {
+ ShaderAttrLoc getLocation() {
return loc;
}
@@ -1184,7 +1184,7 @@ abstract class ShaderProgramRetained extends NodeComponentRetained {
}
// Location of attribute name in linked shader program
- private long loc;
+ private ShaderAttrLoc loc;
// boolean indicating whether the attribute is an array
private boolean isArray;
diff --git a/src/classes/share/javax/media/j3d/ShaderRetained.java b/src/classes/share/javax/media/j3d/ShaderRetained.java
index 9965dba..213456f 100644
--- a/src/classes/share/javax/media/j3d/ShaderRetained.java
+++ b/src/classes/share/javax/media/j3d/ShaderRetained.java
@@ -26,7 +26,7 @@ abstract class ShaderRetained extends NodeComponentRetained {
int shaderType;
// shaderId use by native code. One per Canvas.
- long[] shaderIds;
+ ShaderId[] shaderIds;
boolean[] compiled;
// Flag indicating whether a COMPILE_ERROR has occurred for this shader
diff --git a/src/classes/share/javax/media/j3d/Shape3DRetained.java b/src/classes/share/javax/media/j3d/Shape3DRetained.java
index 61e56b3..d051281 100644
--- a/src/classes/share/javax/media/j3d/Shape3DRetained.java
+++ b/src/classes/share/javax/media/j3d/Shape3DRetained.java
@@ -191,7 +191,7 @@ class Shape3DRetained extends LeafRetained {
if (source.isLive()) {
// Notify Geometry Structure to check for collision
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.COLLISION_BOUND_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM;
message.universe = universe;
@@ -221,7 +221,7 @@ class Shape3DRetained extends LeafRetained {
super.setBounds(bounds);
if (source.isLive() && !boundsAutoCompute) {
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.REGION_BOUND_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM |
J3dThread.UPDATE_GEOMETRY |
@@ -531,7 +531,7 @@ class Shape3DRetained extends LeafRetained {
size = 1;
J3dMessage[] createMessage = new J3dMessage[size];
// Send a message
- createMessage[0] = VirtualUniverse.mc.getMessage();
+ createMessage[0] = new J3dMessage();
createMessage[0].threads = targetThreads;
createMessage[0].type = J3dMessage.SHAPE3D_CHANGED;
createMessage[0].universe = universe;
@@ -551,7 +551,7 @@ class Shape3DRetained extends LeafRetained {
createMessage[0].args[3] = obj;
createMessage[0].args[4] = getGeomAtomsArray(mirrorShape3D);
if(visibleIsDirty) {
- createMessage[1] = VirtualUniverse.mc.getMessage();
+ createMessage[1] = new J3dMessage();
createMessage[1].threads = J3dThread.UPDATE_GEOMETRY;
createMessage[1].type = J3dMessage.SHAPE3D_CHANGED;
createMessage[1].universe = universe;
@@ -584,7 +584,7 @@ class Shape3DRetained extends LeafRetained {
if (((Shape3D)this.source).isLive()) {
// Send a message
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.SHAPE3D_CHANGED;
createMessage.universe = universe;
@@ -1922,7 +1922,7 @@ class Shape3DRetained extends LeafRetained {
}
- J3dMessage changeMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage changeMessage = new J3dMessage();
changeMessage.type = J3dMessage.SHAPE3D_CHANGED;
// Who to send this message to ?
changeMessage.threads = J3dThread.UPDATE_RENDER |
@@ -2002,7 +2002,7 @@ class Shape3DRetained extends LeafRetained {
}
super.setBoundsAutoCompute(autoCompute);
if (source.isLive()) {
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.BOUNDS_AUTO_COMPUTE_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM |
J3dThread.UPDATE_GEOMETRY |
@@ -2023,7 +2023,7 @@ class Shape3DRetained extends LeafRetained {
getCombineBounds((BoundingBox)localBounds);
synchronized(mirrorShape3D) {
if (source.isLive()) {
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.BOUNDS_AUTO_COMPUTE_CHANGED;
message.threads = J3dThread.UPDATE_TRANSFORM |
J3dThread.UPDATE_GEOMETRY |
@@ -2252,7 +2252,7 @@ class Shape3DRetained extends LeafRetained {
// send a Shape GEOMETRY_CHANGED message for all geometry atoms
- J3dMessage changeMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage changeMessage = new J3dMessage();
changeMessage.type = J3dMessage.SHAPE3D_CHANGED;
changeMessage.threads = J3dThread.UPDATE_RENDER |
J3dThread.UPDATE_TRANSFORM |
@@ -2714,14 +2714,6 @@ class Shape3DRetained extends LeafRetained {
}
- static Point3d getPoint3d() {
- return (Point3d)FreeListManager.getObject(FreeListManager.POINT3D);
- }
-
- static void freePoint3d(Point3d p) {
- FreeListManager.freeObject(FreeListManager.POINT3D, p);
- }
-
void handleFrequencyChange(int bit) {
int mask = 0;
if (bit == Shape3D.ALLOW_GEOMETRY_WRITE) {
diff --git a/src/classes/share/javax/media/j3d/SoundRetained.java b/src/classes/share/javax/media/j3d/SoundRetained.java
index d0898ff..38a8515 100644
--- a/src/classes/share/javax/media/j3d/SoundRetained.java
+++ b/src/classes/share/javax/media/j3d/SoundRetained.java
@@ -215,7 +215,7 @@ abstract class SoundRetained extends LeafRetained
*/
void dispatchAttribChange(int dirtyBit, Object argument) {
// Send message including a integer argument
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_SOUND |
J3dThread.SOUND_SCHEDULER;
createMessage.type = J3dMessage.SOUND_ATTRIB_CHANGED;
@@ -238,7 +238,7 @@ abstract class SoundRetained extends LeafRetained
*/
void dispatchStateChange(int dirtyBit, Object argument) {
// Send message including a integer argument
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_SOUND |
J3dThread.SOUND_SCHEDULER;
createMessage.type = J3dMessage.SOUND_STATE_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/SoundScheduler.java b/src/classes/share/javax/media/j3d/SoundScheduler.java
index b9ef720..59bc12a 100644
--- a/src/classes/share/javax/media/j3d/SoundScheduler.java
+++ b/src/classes/share/javax/media/j3d/SoundScheduler.java
@@ -270,6 +270,12 @@ class SoundScheduler extends J3dStructure {
"during Sound rendering:");
e.printStackTrace();
}
+ catch (Error e) {
+ // Issue 264 - catch Error
+ System.err.println("Error occurred " +
+ "during Sound rendering:");
+ e.printStackTrace();
+ }
// what if the user/app makes no change to scenegraph?
// must still re-render after retest for sound complete
@@ -789,6 +795,12 @@ class SoundScheduler extends J3dStructure {
"during sound deactivation:");
e.printStackTrace();
}
+ catch (Error e) {
+ // Issue 264 - catch Error
+ System.err.println("Error occurred " +
+ "during sound deactivation:");
+ e.printStackTrace();
+ }
updateThread.active = false;
}
}
diff --git a/src/classes/share/javax/media/j3d/SoundscapeRetained.java b/src/classes/share/javax/media/j3d/SoundscapeRetained.java
index 72ba4b5..53d8471 100644
--- a/src/classes/share/javax/media/j3d/SoundscapeRetained.java
+++ b/src/classes/share/javax/media/j3d/SoundscapeRetained.java
@@ -56,7 +56,7 @@ class SoundscapeRetained extends LeafRetained
void dispatchMessage(int dirtyBit, Object argument) {
// Send message including a integer argument
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.type = J3dMessage.SOUNDSCAPE_CHANGED;
createMessage.universe = universe;
diff --git a/src/classes/share/javax/media/j3d/SpotLightRetained.java b/src/classes/share/javax/media/j3d/SpotLightRetained.java
index 6609fc0..20f41e3 100644
--- a/src/classes/share/javax/media/j3d/SpotLightRetained.java
+++ b/src/classes/share/javax/media/j3d/SpotLightRetained.java
@@ -183,22 +183,16 @@ class SpotLightRetained extends PointLightRetained {
* transformed position, spread angle, concentration,
* and its transformed position.
*/
- native void updateLight(long ctx,
- int lightSlot, float red, float green,
- float blue, float ax, float ay, float az,
- float px, float py, float pz, float spreadAngle,
- float concentration, float dx, float dy,
- float dz);
-
- void update(long ctx, int lightSlot, double scale) {
+ void update(Context ctx, int lightSlot, double scale) {
validateAttenuationInEc(scale);
- updateLight(ctx, lightSlot, color.x, color.y, color.z,
- attenuation.x, linearAttenuationInEc,
- quadraticAttenuationInEc,
- xformPosition.x, xformPosition.y,
- xformPosition.z, spreadAngle, concentration,
- xformDirection.x, xformDirection.y,
- xformDirection.z);
+ Pipeline.getPipeline().updateSpotLight(ctx,
+ lightSlot, color.x, color.y, color.z,
+ attenuation.x, linearAttenuationInEc,
+ quadraticAttenuationInEc,
+ xformPosition.x, xformPosition.y,
+ xformPosition.z, spreadAngle, concentration,
+ xformDirection.x, xformDirection.y,
+ xformDirection.z);
}
@@ -264,40 +258,6 @@ class SpotLightRetained extends PointLightRetained {
}
- /*
- // This update function, and its native counterpart,
- // updates a spot light. This includes its color, attenuation,
- // transformed position, spread angle, concentration,
- // and its transformed position.
- native void updateLight(int lightSlot, float red, float green,
- float blue, float ax, float ay, float az,
- float px, float py, float pz, float spreadAngle,
- float concentration, float dx, float dy,
- float dz);
- void update(int lightSlot, double scale) {
- updateLight(lightSlot, color.x, color.y, color.z,
- attenuation.x, linearAttenuationInEc,
- quadraticAttenuationInEc,
- xformPosition.x, xformPosition.y,
- xformPosition.z, spreadAngle, concentration,
- xformDirection.x, xformDirection.y,
- xformDirection.z);
- }
-
- synchronized void update(LightRetained l, boolean clear) {
- SpotLightRetained sl = (SpotLightRetained)l;
- super.update(sl, clear);
-
- l.sgLight.getLocalToVworld(trans, l.key);
- trans.transform(direction, sl.xformDirection);
- sl.xformDirection.normalize();
- trans.transform(position, sl.xformPosition);
- sl.spreadAngle = spreadAngle;
- sl.concentration = concentration;
- }
- */
-
-
// Clones only the retained side, internal use only
protected Object clone() {
SpotLightRetained sr = (SpotLightRetained)super.clone();
@@ -318,7 +278,7 @@ class SpotLightRetained extends PointLightRetained {
}
final void sendMessage(int attrMask, Object attr) {
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = targetThreads;
createMessage.universe = universe;
createMessage.type = J3dMessage.LIGHT_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/SwitchRetained.java b/src/classes/share/javax/media/j3d/SwitchRetained.java
index 21b0640..cc3ad37 100644
--- a/src/classes/share/javax/media/j3d/SwitchRetained.java
+++ b/src/classes/share/javax/media/j3d/SwitchRetained.java
@@ -194,7 +194,7 @@ class SwitchRetained extends GroupRetained implements TargetsInterface
if (threads > 0) {
- m = VirtualUniverse.mc.getMessage();
+ m = new J3dMessage();
m.type = J3dMessage.SWITCH_CHANGED;
m.universe = universe;
m.threads = threads;
diff --git a/src/classes/share/javax/media/j3d/TexCoordGenerationRetained.java b/src/classes/share/javax/media/j3d/TexCoordGenerationRetained.java
index 408c30f..3a5089d 100644
--- a/src/classes/share/javax/media/j3d/TexCoordGenerationRetained.java
+++ b/src/classes/share/javax/media/j3d/TexCoordGenerationRetained.java
@@ -255,20 +255,6 @@ class TexCoordGenerationRetained extends NodeComponentRetained {
}
}
- /**
- * These two methods update the native context,
- * trans contains eyeTovworld transform in d3d
- * trans contains vworldToEye transform in ogl
- */
- native void updateNative(long ctx,
- boolean enable, int genMode, int format,
- float planeSx, float planeSy, float planeSz, float planeSw,
- float planeTx, float planeTy, float planeTz, float planeTw,
- float planeRx, float planeRy, float planeRz, float planeRw,
- float planeQx, float planeQy, float planeQz, float planeQw,
- double[] trans);
-
-
void updateNative(Canvas3D cv) {
int gMode = genMode;
Transform3D trans = null;
@@ -282,22 +268,17 @@ class TexCoordGenerationRetained extends NodeComponentRetained {
if (VirtualUniverse.mc.isD3D() &&
(gMode == TexCoordGeneration.EYE_LINEAR)) {
- trans = VirtualUniverse.mc.getTransform3D(cv.vworldToEc);
+ trans = new Transform3D(cv.vworldToEc);
trans.invert();
m = trans;
}
- updateNative(cv.ctx,
+ Pipeline.getPipeline().updateTexCoordGeneration(cv.ctx,
enable, gMode, format, planeS.x, planeS.y, planeS.z,
planeS.w, planeT.x, planeT.y, planeT.z, planeT.w,
planeR.x, planeR.y, planeR.z, planeR.w,
planeQ.x, planeQ.y, planeQ.z, planeQ.w,
m.mat);
-
- if (trans != null) {
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D,
- trans);
- }
}
/**
@@ -379,7 +360,7 @@ class TexCoordGenerationRetained extends NodeComponentRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.TEXCOORDGENERATION_CHANGED;
createMessage.universe = null;
@@ -392,7 +373,7 @@ class TexCoordGenerationRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.TEXCOORDGENERATION_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/Text3DRenderMethod.java b/src/classes/share/javax/media/j3d/Text3DRenderMethod.java
index 2416f32..c4d304d 100644
--- a/src/classes/share/javax/media/j3d/Text3DRenderMethod.java
+++ b/src/classes/share/javax/media/j3d/Text3DRenderMethod.java
@@ -22,8 +22,9 @@ class Text3DRenderMethod implements RenderMethod {
/**
* The actual rendering code for this RenderMethod
*/
- public boolean render(RenderMolecule rm, Canvas3D cv, int pass,
+ public boolean render(RenderMolecule rm, Canvas3D cv,
RenderAtomListInfo ra, int dirtyBits) {
+
boolean isNonUniformScale;
Transform3D trans = null;
@@ -33,7 +34,7 @@ class Text3DRenderMethod implements RenderMethod {
rm.textureBin.attributeBin.ignoreVertexColors, cv.ctx);
if (rm.doInfinite) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
while (ra != null) {
trans = ra.infLocalToVworld;
isNonUniformScale = !trans.isCongruent();
@@ -42,10 +43,8 @@ class Text3DRenderMethod implements RenderMethod {
ra.geometry().execute(cv, ra.renderAtom, isNonUniformScale,
(rm.useAlpha && ra.geometry().noAlpha),
rm.alpha,
- rm.renderBin.multiScreen,
cv.screen.screen,
- rm.textureBin.attributeBin.ignoreVertexColors,
- pass);
+ rm.textureBin.attributeBin.ignoreVertexColors);
ra = ra.next;
}
return true;
@@ -55,7 +54,7 @@ class Text3DRenderMethod implements RenderMethod {
while (ra != null) {
if (cv.ra == ra.renderAtom) {
if (cv.raIsVisible) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
trans = ra.localToVworld;
isNonUniformScale = !trans.isCongruent();
@@ -63,18 +62,16 @@ class Text3DRenderMethod implements RenderMethod {
ra.geometry().execute(cv, ra.renderAtom, isNonUniformScale,
(rm.useAlpha && ra.geometry().noAlpha),
rm.alpha,
- rm.renderBin.multiScreen,
cv.screen.screen,
rm.textureBin.attributeBin.
- ignoreVertexColors,
- pass);
+ ignoreVertexColors);
isVisible = true;
}
}
else {
if (!VirtualUniverse.mc.viewFrustumCulling ||
ra.renderAtom.localeVwcBounds.intersect(cv.viewFrustum)) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
cv.raIsVisible = true;
trans = ra.localToVworld;
isNonUniformScale = !trans.isCongruent();
@@ -83,11 +80,9 @@ class Text3DRenderMethod implements RenderMethod {
ra.geometry().execute(cv, ra.renderAtom, isNonUniformScale,
(rm.useAlpha && ra.geometry().noAlpha),
rm.alpha,
- rm.renderBin.multiScreen,
cv.screen.screen,
rm.textureBin.attributeBin.
- ignoreVertexColors,
- pass);
+ ignoreVertexColors);
isVisible = true;
}
else {
diff --git a/src/classes/share/javax/media/j3d/Text3DRetained.java b/src/classes/share/javax/media/j3d/Text3DRetained.java
index 56483ac..36ad3c0 100644
--- a/src/classes/share/javax/media/j3d/Text3DRetained.java
+++ b/src/classes/share/javax/media/j3d/Text3DRetained.java
@@ -458,7 +458,7 @@ class Text3DRetained extends GeometryRetained {
numMessages = universeList.size();
m = new J3dMessage[numMessages];
for (i=0; i<numMessages; i++) {
- m[i] = VirtualUniverse.mc.getMessage();
+ m[i] = new J3dMessage();
m[i].type = J3dMessage.TEXT3D_DATA_CHANGED;
m[i].threads = targetThreads;
shapeList = (ArrayList)userLists.get(i);
@@ -637,7 +637,7 @@ class Text3DRetained extends GeometryRetained {
numMessages = universeList.size();
m = new J3dMessage[numMessages];
for (i=0; i<numMessages; i++) {
- m[i] = VirtualUniverse.mc.getMessage();
+ m[i] = new J3dMessage();
m[i].type = J3dMessage.TEXT3D_TRANSFORM_CHANGED;
m[i].threads = targetThreads;
shapeList = (ArrayList)userLists.get(i);
@@ -709,7 +709,7 @@ class Text3DRetained extends GeometryRetained {
charTransforms = new Transform3D[numChars];
for (i=0; i<numChars; i++) {
- charTransforms[i] = VirtualUniverse.mc.getTransform3D(null);
+ charTransforms[i] = new Transform3D();
}
if (numChars != 0) {
@@ -880,7 +880,7 @@ class Text3DRetained extends GeometryRetained {
}
boolean intersect(Point3d[] pnts) {
- Transform3D tempT3D = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D tempT3D = new Transform3D();
GeometryArrayRetained ga;
boolean isIntersect = false;
Point3d transPnts[] = new Point3d[pnts.length];
@@ -901,7 +901,6 @@ class Text3DRetained extends GeometryRetained {
}
}
}
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, tempT3D);
return isIntersect;
}
@@ -940,21 +939,19 @@ class Text3DRetained extends GeometryRetained {
void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
- boolean updateAlpha, float alpha, boolean multiScreen,
+ boolean updateAlpha, float alpha,
int screen,
- boolean ignoreVertexColors, int pass) {
+ boolean ignoreVertexColors) {
- Transform3D trans = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D trans = new Transform3D();
for (int i = 0; i < geometryList.length; i++) {
trans.set(drawTransform);
trans.mul(charTransforms[i]);
cv.setModelViewMatrix(cv.ctx, vpcToEc.mat, trans);
geometryList[i].execute(cv, ra, isNonUniformScale, updateAlpha, alpha,
- multiScreen, screen, ignoreVertexColors,
- pass);
+ screen, ignoreVertexColors);
}
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, trans);
}
int getClassType() {
diff --git a/src/classes/share/javax/media/j3d/Texture.java b/src/classes/share/javax/media/j3d/Texture.java
index 52e6cd5..2ac1fce 100644
--- a/src/classes/share/javax/media/j3d/Texture.java
+++ b/src/classes/share/javax/media/j3d/Texture.java
@@ -28,10 +28,11 @@ import java.util.Hashtable;
* boundary color is used when the boundaryModeS and boundaryModeT
* parameters are set to CLAMP or CLAMP_TO_BOUNDARY and if the texture
* boundary is not specified. </LI><P>
- * <LI>Boundary Width - the texture boundary width. If the texture boundary
- * width is > 0, then all images for all mipmap levels will include boundary
- * texels. The actual texture image for level 0, for example, will be of
- * dimension (width + 2*boundaryWidth) * (height + 2*boundaryWidth).
+ * <LI>Boundary Width - the texture boundary width, which must be 0 or 1.
+ * If the texture boundary
+ * width is 1, then all images for all mipmap levels will include a border.
+ * The actual texture image for level 0, for example, will be of
+ * dimension (width + 2*boundaryWidth) * (height + 2*boundaryWidth).
* The boundary texels will be used when linear filtering is to be applied.
* </LI><p>
* <LI>Boundary ModeS and Boundary ModeT - the boundary mode for the
@@ -549,7 +550,7 @@ public abstract class Texture extends NodeComponent {
ALLOW_SHARPEN_TEXTURE_READ,
ALLOW_SIZE_READ
};
-
+
/**
* Constructs a Texture object with default parameters.
* The default values are as follows:
@@ -610,6 +611,9 @@ public abstract class Texture extends NodeComponent {
int width,
int height) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
if ((mipMapMode != BASE_LEVEL) && (mipMapMode != MULTI_LEVEL_MIPMAP))
throw new IllegalArgumentException(J3dI18N.getString("Texture0"));
@@ -619,19 +623,32 @@ public abstract class Texture extends NodeComponent {
throw new IllegalArgumentException(J3dI18N.getString("Texture1"));
}
- // set default read capabilities
- setDefaultReadCapabilities(readCapabilities);
+ if (width < 1) {
+ throw new IllegalArgumentException(J3dI18N.getString("Texture46"));
+ }
- int widPower = getPowerOf2(width);
- if (widPower == -1)
- throw new IllegalArgumentException(J3dI18N.getString("Texture2"));
+ if (height < 1) {
+ throw new IllegalArgumentException(J3dI18N.getString("Texture47"));
+ }
- int heiPower = getPowerOf2(height);
- if (heiPower == -1)
- throw new IllegalArgumentException(J3dI18N.getString("Texture3"));
+ int widthLevels;
+ int heightLevels;
- ((TextureRetained)this.retained).initialize(format, width, widPower,
- height, heiPower, mipMapMode, 0);
+ if (VirtualUniverse.mc.enforcePowerOfTwo) {
+ widthLevels = getPowerOf2(width);
+ if (widthLevels == -1)
+ throw new IllegalArgumentException(J3dI18N.getString("Texture2"));
+
+ heightLevels = getPowerOf2(height);
+ if (heightLevels == -1)
+ throw new IllegalArgumentException(J3dI18N.getString("Texture3"));
+ } else {
+ widthLevels = getLevelsNPOT(width);
+ heightLevels = getLevelsNPOT(height);
+ }
+
+ ((TextureRetained)this.retained).initialize(format, width, widthLevels,
+ height, heightLevels, mipMapMode, 0);
}
/**
@@ -653,10 +670,10 @@ public abstract class Texture extends NodeComponent {
* does not include the width of the boundary.
* @param height height of image at level 0. Must be power of 2. This
* does not include the width of the boundary.
- * @param boundaryWidth width of the boundary.
+ * @param boundaryWidth width of the boundary, which must be 0 or 1.
* @exception IllegalArgumentException if width or height are not a
* power of 2, if an invalid format or mipMapMode is specified, or
- * if the boundaryWidth < 0
+ * if the boundaryWidth is &lt; 0 or &gt; 1
*
* @since Java 3D 1.3
*/
@@ -666,6 +683,9 @@ public abstract class Texture extends NodeComponent {
int height,
int boundaryWidth) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
if ((mipMapMode != BASE_LEVEL) && (mipMapMode != MULTI_LEVEL_MIPMAP))
throw new IllegalArgumentException(J3dI18N.getString("Texture0"));
@@ -675,22 +695,35 @@ public abstract class Texture extends NodeComponent {
throw new IllegalArgumentException(J3dI18N.getString("Texture1"));
}
- // set default read capabilities
- setDefaultReadCapabilities(readCapabilities);
+ if (width < 1) {
+ throw new IllegalArgumentException(J3dI18N.getString("Texture46"));
+ }
+
+ if (height < 1) {
+ throw new IllegalArgumentException(J3dI18N.getString("Texture47"));
+ }
- int widPower = getPowerOf2(width);
- if (widPower == -1)
- throw new IllegalArgumentException(J3dI18N.getString("Texture2"));
+ int widthLevels;
+ int heightLevels;
- int heiPower = getPowerOf2(height);
- if (heiPower == -1)
- throw new IllegalArgumentException(J3dI18N.getString("Texture3"));
+ if (VirtualUniverse.mc.enforcePowerOfTwo) {
+ widthLevels = getPowerOf2(width);
+ if (widthLevels == -1)
+ throw new IllegalArgumentException(J3dI18N.getString("Texture2"));
- if (boundaryWidth < 0)
+ heightLevels = getPowerOf2(height);
+ if (heightLevels == -1)
+ throw new IllegalArgumentException(J3dI18N.getString("Texture3"));
+ } else {
+ widthLevels = getLevelsNPOT(width);
+ heightLevels = getLevelsNPOT(height);
+ }
+
+ if (boundaryWidth < 0 || boundaryWidth > 1)
throw new IllegalArgumentException(J3dI18N.getString("Texture30"));
- ((TextureRetained)this.retained).initialize(format, width, widPower,
- height, heiPower, mipMapMode, boundaryWidth);
+ ((TextureRetained)this.retained).initialize(format, width, widthLevels,
+ height, heightLevels, mipMapMode, boundaryWidth);
}
/**
@@ -869,26 +902,45 @@ public abstract class Texture extends NodeComponent {
}
/**
- * Sets the image for a specified mipmap level.
+ * Sets the image for a specified mipmap level. Note that the image size
+ * must be the correct size for the specified mipmap level. The image size
+ * of the base level image, that is level 0, must be the same size
+ * in each dimension (width, height, depth) as this
+ * texture, excluding the border, if any.
+ * Each successive mipmap level must be 1/2 the size of the previous level,
+ * such that <code>size[n]&nbsp;=&nbsp;floor(size[n-1]/2)</code>, exluding
+ * the border.
+ *
* @param level mipmap level to set: 0 is the base level
* @param image ImageComponent object containing the texture image
* for the specified mipmap level
+ *
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @exception IllegalArgumentException if an ImageComponent3D is
- * used in a Texture2D object; if an ImageComponent2D is used in a
- * Texture3D object; or if this object is part of a live
- * scene graph and the image being set at this level is not the
- * same size (width, height, depth) as the old image at this
- * level.
+ * used in a Texture2D object or if an ImageComponent2D is used in a
+ * Texture3D object.
+ *
+ * @exception IllegalArgumentException if the image being set at this
+ * level is not the correct size for this level.
+ *
+ * @exception IllegalSharingException if this Texture is live and
+ * the specified image is being used by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalSharingException if this Texture is
+ * being used by an immediate mode context and
+ * the specified image is being used by a Canvas3D as an off-screen buffer.
*/
public void setImage(int level, ImageComponent image) {
if (isLiveOrCompiled()) {
if(!this.getCapability(ALLOW_IMAGE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Texture15"));
}
-
+
+ // Do illegal sharing check
+ validateImageIllegalSharing(image);
+
if (isLive())
((TextureRetained)this.retained).setImage(level, image);
else
@@ -913,20 +965,38 @@ public abstract class Texture extends NodeComponent {
}
/**
- * Sets the array of images for all mipmap levels.
+ * Sets the array of images for all mipmap levels. Note that the image size
+ * of the base level image, <code>images[0]</code>, must be the same size
+ * in each dimension (width, height, depth) as this
+ * texture, excluding the border, if any.
+ * Each successive mipmap level must be 1/2 the size of the previous level,
+ * such that <code>size[n]&nbsp;=&nbsp;floor(size[n-1]/2)</code>, exluding
+ * the border.
+ *
* @param images array of ImageComponent objects
* containing the texture images for all mipmap levels
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @exception IllegalArgumentException if an ImageComponent3D is
- * used in a Texture2D object; if an ImageComponent2D is used in a
- * Texture3D object; if <code>images.length</code> is not equal to
- * the total number of mipmap levels; or if this object is part of
- * a live scene graph and the size of each dimension (width,
- * height, depth) of the image at a given level in the
- * <code>images</code> array is not half the dimension of the
- * previous level.
+ * used in a Texture2D object or if an ImageComponent2D is used in a
+ * Texture3D object.
+ *
+ * @exception IllegalArgumentException if <code>images.length</code> is
+ * not equal to the total number of mipmap levels.
+ *
+ * @exception IllegalArgumentException if the size of each dimension
+ * of the image at a given level in the
+ * <code>images</code> array is not the correct size.
+ *
+ * @exception IllegalSharingException if this Texture is live and
+ * any of the specified images are being used by a Canvas3D as an
+ * off-screen buffer.
+ *
+ * @exception IllegalSharingException if this Texture is
+ * being used by an immediate mode context and
+ * any of the specified images are being used by a Canvas3D as an
+ * off-screen buffer.
*
* @since Java 3D 1.2
*/
@@ -936,6 +1006,11 @@ public abstract class Texture extends NodeComponent {
throw new CapabilityNotSetException(J3dI18N.getString("Texture15"));
}
+ // Do illegal sharing check
+ for(int i=0; i<images.length; i++) {
+ validateImageIllegalSharing(images[i]);
+ }
+
if (images == null)
throw new IllegalArgumentException(J3dI18N.getString("Texture20"));
@@ -1132,6 +1207,18 @@ public abstract class Texture extends NodeComponent {
//Can't reach here because we have already checked for 0
return -1;
}
+
+ // returns number of levels using NPOT rules for mipmap generation
+ // which say that each level should be floor(size/2) of previous level
+ static int getLevelsNPOT(int num) {
+ int tmp, levels = 0;
+ tmp = num;
+ while (tmp > 1) {
+ tmp = tmp / 2;
+ levels++;
+ }
+ return levels;
+ }
/**
* Sets the texture boundary color for this texture object. The
@@ -1771,4 +1858,5 @@ public abstract class Texture extends NodeComponent {
}
return false;
}
+
}
diff --git a/src/classes/share/javax/media/j3d/Texture2D.java b/src/classes/share/javax/media/j3d/Texture2D.java
index 766a396..ca20be6 100644
--- a/src/classes/share/javax/media/j3d/Texture2D.java
+++ b/src/classes/share/javax/media/j3d/Texture2D.java
@@ -11,68 +11,20 @@
*/
package javax.media.j3d;
-import javax.vecmath.*;
+import javax.vecmath.*;
/**
* Texture2D is a subclass of Texture class. It extends Texture
* class by adding a constructor and a mutator method for
* setting a 2D texture image.
- * <P>
- * Each Texture2D object has the following properties:<P>
- * <UL>
- * <LI>Magnification filter - the magnification filter function.
- * Used when the pixel being rendered maps to an area less than or
- * equal to one texel. In addition to the magnification filter functions
- * defined in the base Texture class, the following values are
- * supported:</LI><P>
- * <UL>
- * <LI>LINEAR_DETAIL - performs linear sampling in both the base level
- * texture image and the detail texture image, and combines the two
- * texture values according to the detail texture mode.</LI><P>
- * <LI>LINEAR_DETAIL_RGB - performs linear detail for the rgb
- * components only. The alpha component is computed using BASE_LEVEL_LINEAR
- * filter.</LI><P>
- * <LI>LINEAR_DETAIL_ALPHA - performs linear detail for the alpha
- * component only. The rgb components are computed using BASE_LEVEL_LINEAR
- * filter.</LI><P>
- * </UL>
- * <LI>Detail Texture Image - Detail texture image to be used when the texture
- * magnification filter mode specifies LINEAR_DETAIL, LINEAR_DETAIL_ALPHA, or
- * LINEAR_DETAIL_RGB; if the detail texture images is null, then
- * the texture magnification filter mode will fall back to BASE_LEVEL_LINEAR.
- * </LI><P>
- * <LI>Detail Texture Mode - specifies how the texture image is combined
- * with the detail image. The detail texture modes are as follows: </LI><P>
- * <UL>
- * <LI>DETAIL_ADD</LI><P>
- * <UL>
- * T' = T<sub>texture</sub> + DetailFunc(LOD) * (2 * T<sub>detail</sub> - 1)<P>
- * </UL>
- * <LI>DETAIL_MODULATE</LI><P>
- * <UL>
- * T' = T<sub>texture</sub> * (1 + DetailFunc(LOD) * (2 * T<sub>detail</sub> - 1))<P>
- * </UL>
- * </UL>
- * where T<sub>texture</sub> is the texture value computed from the base level
- * texture image, and T<sub>detail</sub> is the texture value computed from the
- * detail texture image.<P>
- * <LI>Detail Texture Function - specifies the function of level-of-detail
- * used in combining the detail texture with the base level texture of this object.</LI><P>
- * <LI>Detail Texture Level - specifies the number of levels that
- * separate the base level image of this texture object and the detail
- * texture image. This value is used in the linear filter
- * calculation of the detail texture image. Note, detail texture will only
- * be applied to the level 0 of the texture image. Hence, for detail texture
- * to work, base level has to be set to 0.</LI><P>
- * </UL>
- *
- * @see Canvas3D#queryProperties
*/
public class Texture2D extends Texture {
/**
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
* Specifies that this Texture object allows reading its detail
* texture information (e.g., detail texture image, detail texture mode,
* detail texture function, detail texture function points count,
@@ -84,6 +36,8 @@ public class Texture2D extends Texture {
ALLOW_DETAIL_TEXTURE_READ = CapabilityBits.TEXTURE2D_ALLOW_DETAIL_TEXTURE_READ;
/**
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
* Performs linear sampling in both the base level
* texture image and the detail texture image, and combines the two
* texture values according to the detail texture mode.
@@ -94,6 +48,8 @@ public class Texture2D extends Texture {
public static final int LINEAR_DETAIL = 6;
/**
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
* Performs linear detail for the rgb
* components only. The alpha component is computed using
* BASE_LEVEL_LINEAR filter.
@@ -104,6 +60,8 @@ public class Texture2D extends Texture {
public static final int LINEAR_DETAIL_RGB = 7;
/**
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
* Performs linear detail for the alpha
* component only. The rgb components are computed using
* BASE_LEVEL_LINEAR filter.
@@ -114,6 +72,8 @@ public class Texture2D extends Texture {
public static final int LINEAR_DETAIL_ALPHA = 8;
/**
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
* Adds the detail texture image to the level 0 image of this texture
* object
*
@@ -123,6 +83,8 @@ public class Texture2D extends Texture {
public static final int DETAIL_ADD = 0;
/**
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
* Modulates the detail texture image with the level 0 image of this
* texture object
*
@@ -167,10 +129,10 @@ public class Texture2D extends Texture {
* BASE_LEVEL, MULTI_LEVEL_MIPMAP.
* @param format data format of Textures saved in this object.
* One of INTENSITY, LUMINANCE, ALPHA, LUMINANCE_ALPHA, RGB, RGBA.
- * @param width width of image at level 0. Must be power of 2.
- * @param height height of image at level 0. Must be power of 2.
+ * @param width width of image at level 0. Must be greater than 0
+ * @param height height of image at level 0. Must be greater than 0
* @exception IllegalArgumentException if width or height are NOT
- * power of 2 OR invalid format/mipmapMode is specified.
+ * greater than 0 OR invalid format/mipmapMode is specified.
*/
public Texture2D(
int mipMapMode,
@@ -200,14 +162,14 @@ public class Texture2D extends Texture {
* BASE_LEVEL, MULTI_LEVEL_MIPMAP
* @param format data format of Textures saved in this object.
* One of INTENSITY, LUMINANCE, ALPHA, LUMINANCE_ALPHA, RGB, RGBA
- * @param width width of image at level 0. Must be power of 2. This
+ * @param width width of image at level 0. Must be greater than 0. This
* does not include the width of the boundary.
- * @param height height of image at level 0. Must be power of 2. This
+ * @param height height of image at level 0. Must be greater than 0. This
* does not include the width of the boundary.
- * @param boundaryWidth width of the boundary.
- * @exception IllegalArgumentException if width or height are not a
- * power of 2, if an invalid format or mipMapMode is specified, or
- * if the boundaryWidth < 0
+ * @param boundaryWidth width of the boundary, which must be 0 or 1.
+ * @exception IllegalArgumentException if width or height are not greater
+ * than 0, if an invalid format or mipMapMode is specified, or
+ * if the boundaryWidth is &lt; 0 or &gt; 1
*
* @since Java 3D 1.3
*/
@@ -271,7 +233,9 @@ public class Texture2D extends Texture {
}
/**
- * Sets the detail texture image for this texture object.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
+ *
* @param detailTexture ImageComponent2D object containing the
* detail texture image.
* @exception RestrictedAccessException if the method is called
@@ -286,7 +250,9 @@ public class Texture2D extends Texture {
}
/**
- * Retrieves the detail texture image for this texture object.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
+ *
* @return ImageComponent2D object containing the detail texture image.
*
* @exception CapabilityNotSetException if appropriate capability is
@@ -305,7 +271,9 @@ public class Texture2D extends Texture {
}
/**
- * Sets the detail texture mode for this texture object.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
+ *
* @param mode detail texture mode. One of: DETAIL_ADD or DETAIL_MODULATE
*
* @exception IllegalArgumentException if
@@ -327,7 +295,9 @@ public class Texture2D extends Texture {
}
/**
- * Retrieves the detail texture mode for this texture object.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
+ *
* @return the detail texture mode.
*
* @exception CapabilityNotSetException if appropriate capability is
@@ -346,7 +316,9 @@ public class Texture2D extends Texture {
}
/**
- * Sets the detail texture level for this texture object.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
+ *
* @param level the detail texture level.
*
* @exception IllegalArgumentException if <code>level</code> < 0
@@ -366,7 +338,9 @@ public class Texture2D extends Texture {
}
/**
- * Retrieves the detail texture level for this texture object.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
+ *
* @return the detail texture level.
*
* @exception CapabilityNotSetException if appropriate capability is
@@ -385,7 +359,9 @@ public class Texture2D extends Texture {
}
/**
- * sets the detail texture LOD function for this texture object.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
+ *
* @param lod array containing the level-of-detail values.
* @param pts array containing the function values for the corresponding
* level-of-detail values.
@@ -409,9 +385,8 @@ public class Texture2D extends Texture {
}
/**
- * sets the detail texture LOD function for this texture object.
- * The Point2f x,y values are defined as follows: x is the lod value,
- * y is the corresponding function value.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
*
* @param pts array of Point2f containing the lod as well as the
* corresponding function value.
@@ -428,8 +403,8 @@ public class Texture2D extends Texture {
}
/**
- * Gets the number of points in the detail texture LOD function for this
- * texture object.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
*
* @return the number of points in the detail texture LOD function.
*
@@ -449,9 +424,8 @@ public class Texture2D extends Texture {
}
/**
- * Copies the array of detail texture LOD function points into the
- * specified arrays. The arrays must be large enough to hold all the
- * points.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
*
* @param lod the array to receive the level-of-detail values.
* @param pts the array to receive the function values for the
@@ -473,10 +447,8 @@ public class Texture2D extends Texture {
}
/**
- * Copies the array of detail texture LOD function points including
- * the lod values and the corresponding function values into the
- * specified array. The array must be large enough to hold all the points.
- * The individual array elements must be allocated by the caller as well.
+ * @deprecated As of Java 3D 1.5 the optional detail texture feature is no
+ * longer supported.
*
* @param pts the array to receive the detail texture LOD function points
*
diff --git a/src/classes/share/javax/media/j3d/Texture2DRetained.java b/src/classes/share/javax/media/j3d/Texture2DRetained.java
index 991c6ee..4957680 100644
--- a/src/classes/share/javax/media/j3d/Texture2DRetained.java
+++ b/src/classes/share/javax/media/j3d/Texture2DRetained.java
@@ -22,17 +22,18 @@ import javax.vecmath.*;
*/
class Texture2DRetained extends TextureRetained {
+ // Note : There is hardly any HW vendor supports detail Image.
+ // Detail Image operation is simply no-op in 1.5.
+
// currently detail image is only applicable to 2D texture
-
// detail texture info
-
- int detailTextureId = -1;
- ImageComponent2DRetained detailImage = null;
- DetailTextureImage detailTexture = null;
- int detailTextureMode = Texture2D.DETAIL_MODULATE;
- int detailTextureLevel = 2;
- int numDetailTextureFuncPts = 0;
- float detailTextureFuncPts[] = null; // array of pairs of floats
+
+ // These members are unused except for public set and get methods.
+ private ImageComponent2DRetained detailImage = null;
+ private int detailTextureMode = Texture2D.DETAIL_MODULATE;
+ private int detailTextureLevel = 2;
+ private int numDetailTextureFuncPts = 0;
+ private float detailTextureFuncPts[] = null; // array of pairs of floats
// first value for LOD
// second value for the fcn value
@@ -44,7 +45,6 @@ class Texture2DRetained extends TextureRetained {
detailImage = null;
} else {
detailImage = (ImageComponent2DRetained)image.retained;
- detailImage.setTextureRef();
}
}
@@ -184,174 +184,6 @@ class Texture2DRetained extends TextureRetained {
return detailTextureFuncPts;
}
- synchronized void initMirrorObject() {
-
- super.initMirrorObject();
-
- Texture2DRetained mirrorTexture = (Texture2DRetained)mirror;
-
- // detail texture info
- mirrorTexture.detailImage = detailImage;
- mirrorTexture.detailTextureMode = detailTextureMode;
- mirrorTexture.detailTextureLevel = detailTextureLevel;
- mirrorTexture.detailTexture = null;
- mirrorTexture.numDetailTextureFuncPts = numDetailTextureFuncPts;
-
- if (detailTextureFuncPts == null) {
- mirrorTexture.detailTextureFuncPts = null;
- } else {
- if ((mirrorTexture.detailTextureFuncPts == null) ||
- (mirrorTexture.detailTextureFuncPts.length !=
- detailTextureFuncPts.length)) {
- mirrorTexture.detailTextureFuncPts =
- new float[detailTextureFuncPts.length];
- }
- for (int i = 0; i < detailTextureFuncPts.length; i++) {
- mirrorTexture.detailTextureFuncPts[i] =
- detailTextureFuncPts[i];
- }
-
- // add detail texture to the user list of the image
- // only if detail texture is to be used
- if ((mirrorTexture.detailImage != null) &&
- (mirrorTexture.magFilter >= Texture2D.LINEAR_DETAIL) &&
- (mirrorTexture.magFilter <= Texture2D.LINEAR_DETAIL_ALPHA)) {
- mirrorTexture.detailImage.addUser(mirrorTexture);
- }
- }
- }
-
- void clearLive(int refCount) {
- super.clearLive(refCount);
-
- // remove detail texture from the user list of the image
- if ((detailImage != null) &&
- (magFilter >= Texture2D.LINEAR_DETAIL) &&
- (magFilter <= Texture2D.LINEAR_DETAIL_ALPHA)) {
- detailImage.removeUser(mirror);
- }
- }
-
- // overload the incTextureBinRefCount method to take care
- // of detail texture ref as well
- // This method is called from RenderBin when a new TextureBin
- // is created. And all the referenced textures in that TextureBin
- // will be notified to increment the TextureBin reference count.
-
- void incTextureBinRefCount(TextureBin tb) {
- super.incTextureBinRefCount(tb);
-
- // increment detail texture ref count
-
- if ((detailImage != null) &&
- (magFilter >= Texture2D.LINEAR_DETAIL) &&
- (magFilter <= Texture2D.LINEAR_DETAIL_ALPHA)) {
- if (detailTexture == null) {
- detailTexture = detailImage.getDetailTexture();
- }
-
- detailTexture.incTextureBinRefCount(format, tb);
- }
- }
-
- // This method is called from AttributeBin when a TextureBin
- // is to be removed. And all the referenced textures in that TextureBin
- // will be notified to decrement the TextureBin reference count.
- // And if detail texture exists, we need to decrement the
- // TextureBin reference count of the detail texture as well.
-
- void decTextureBinRefCount(TextureBin tb) {
- super.decTextureBinRefCount(tb);
-
- // decrement detail texture ref count
-
- if (detailTexture != null) {
- detailTexture.decTextureBinRefCount(format, tb);
- }
- }
-
-
- native void bindDetailTexture(long ctx, int objectId);
-
- native void updateTextureImage(long ctx,
- int numLevels,
- int level,
- int internalFormat, int format,
- int width, int height,
- int boundaryWidth, byte[] imageYup);
-
- native void updateTextureSubImage(long ctx,
- int level, int xoffset, int yoffset,
- int internalFormat,int format,
- int imgXOffset, int imgYOffset,
- int tilew,
- int width, int height,
- byte[] image);
-
- native void updateDetailTextureParameters(long ctx,
- int detailTextureMode,
- int detailTextureLevel,
- int nPts, float[] pts);
- // wrapper to the native call
-
- void updateTextureImage(Canvas3D cv, int face,
- int numLevels, int level,
- int format, int storedFormat,
- int width, int height,
- int boundaryWidth,
- byte[] data) {
-
- updateTextureImage(cv.ctx, numLevels, level, format,
- storedFormat, width, height,
- boundaryWidth, data);
- }
-
-
-
- // wrapper to the native call
-
- void updateTextureSubImage(Canvas3D cv, int face, int level,
- int xoffset, int yoffset, int format,
- int storedFormat, int imgXOffset,
- int imgYOffset, int tileWidth,
- int width, int height, byte[] data) {
-
- updateTextureSubImage(cv.ctx, level, xoffset, yoffset, format,
- storedFormat, imgXOffset, imgYOffset,
- tileWidth, width, height, data);
- }
-
-
- void updateNative(Canvas3D cv) {
-
- // update mipmap texture
-
- super.updateNative(cv);
-
-
- // update detail texture if exists
-
- if (detailTexture != null) {
- detailTexture.updateNative(cv, format);
- }
- }
-
-
- // update texture parameters
-
- void updateTextureFields(Canvas3D cv) {
-
- super.updateTextureFields(cv);
-
- // update detail texture parameters if applicable
-
- if (detailTexture != null) {
-
- updateDetailTextureParameters(cv.ctx, detailTextureMode,
- detailTextureLevel, numDetailTextureFuncPts,
- detailTextureFuncPts);
- }
- }
}
diff --git a/src/classes/share/javax/media/j3d/Texture3D.java b/src/classes/share/javax/media/j3d/Texture3D.java
index 69f007d..024a2d8 100644
--- a/src/classes/share/javax/media/j3d/Texture3D.java
+++ b/src/classes/share/javax/media/j3d/Texture3D.java
@@ -24,6 +24,8 @@ package javax.media.j3d;
public class Texture3D extends Texture {
+ // TODO KCR : NPOT
+
/**
* Constructs a Texture3D object with default parameters.
* The default values are as follows:
@@ -62,10 +64,20 @@ public class Texture3D extends Texture {
int depth) {
super(mipmapMode, format, width, height);
- int depthPower = getPowerOf2(depth);
- if (depthPower == -1)
- throw new IllegalArgumentException(J3dI18N.getString("Texture3D1"));
+ int depthLevels = -1;
+ if (VirtualUniverse.mc.enforcePowerOfTwo) {
+ depthLevels = getPowerOf2(depth);
+ if (depthLevels == -1)
+ throw new IllegalArgumentException(J3dI18N.getString("Texture3D1"));
+
+ } else {
+ depthLevels = getLevelsNPOT(depth);
+ }
+
+ // TODO : Need to verify whether this is a bug. Why depthLevels isn't
+ // use to determine maxMipMapLevels ? See also Texture.java
+
((Texture3DRetained)this.retained).setDepth(depth);
}
@@ -83,10 +95,10 @@ public class Texture3D extends Texture {
* @param width width of image at level 0. Must be power of 2.
* @param height height of image at level 0. Must be power of 2.
* @param depth depth of image at level 0. Must be power of 2.
- * @param boundaryWidth width of the boundary.
+ * @param boundaryWidth width of the boundary, which must be 0 or 1.
* @exception IllegalArgumentException if width or height are NOT
* power of 2 OR invalid format/mipmapMode is specified, or
- * if the boundaryWidth < 0
+ * if the boundaryWidth is &lt; 0 or &gt; 1
*
* @since Java 3D 1.3
*/
@@ -98,10 +110,22 @@ public class Texture3D extends Texture {
int boundaryWidth) {
super(mipmapMode, format, width, height, boundaryWidth);
- int depthPower = getPowerOf2(depth);
- if (depthPower == -1)
- throw new IllegalArgumentException(J3dI18N.getString("Texture3D1"));
-
+ int depthLevels = -1;
+
+ if (VirtualUniverse.mc.enforcePowerOfTwo) {
+ depthLevels = getPowerOf2(depth);
+
+ if (depthLevels == -1)
+ throw new IllegalArgumentException(J3dI18N.getString("Texture3D1"));
+ }
+ else {
+ depthLevels = getLevelsNPOT(depth);
+
+ }
+
+ // TODO : Need to verify whether this is a bug. Why depthLevels isn't
+ // use to determine maxMipMapLevels ? See also Texture.java
+
((Texture3DRetained)this.retained).setDepth(depth);
}
diff --git a/src/classes/share/javax/media/j3d/Texture3DRetained.java b/src/classes/share/javax/media/j3d/Texture3DRetained.java
index 6128325..5e4f667 100644
--- a/src/classes/share/javax/media/j3d/Texture3DRetained.java
+++ b/src/classes/share/javax/media/j3d/Texture3DRetained.java
@@ -57,42 +57,84 @@ class Texture3DRetained extends TextureRetained {
/**
* This method updates the native context.
*/
- native void bindTexture(long ctx, int objectId, boolean enable);
+ void bindTexture(Context ctx, int objectId, boolean enable) {
+ Pipeline.getPipeline().bindTexture3D(ctx, objectId, enable);
+ }
- native void updateTextureBoundary(long ctx,
- int boundaryModeS, int boundaryModeT,
- int boundaryModeR, float boundaryRed,
- float boundaryGreen, float boundaryBlue,
- float boundaryAlpha);
-
- native void updateTextureFilterModes(long ctx,
- int minFilter, int magFilter);
+ void updateTextureBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ int boundaryModeR, float boundaryRed,
+ float boundaryGreen, float boundaryBlue,
+ float boundaryAlpha) {
- native void updateTextureSharpenFunc(long ctx,
- int numSharpenTextureFuncPts,
- float[] sharpenTextureFuncPts);
+ Pipeline.getPipeline().updateTexture3DBoundary(ctx,
+ boundaryModeS, boundaryModeT, boundaryModeR,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+ }
- native void updateTextureFilter4Func(long ctx,
- int numFilter4FuncPts,
- float[] filter4FuncPts);
+ void updateTextureFilterModes(Context ctx,
+ int minFilter, int magFilter) {
- native void updateTextureAnisotropicFilter(long ctx, float degree);
+ Pipeline.getPipeline().updateTexture3DFilterModes(ctx,
+ minFilter, magFilter);
+ }
+ void updateTextureSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
+
+ Pipeline.getPipeline().updateTexture3DSharpenFunc(ctx,
+ numSharpenTextureFuncPts, sharpenTextureFuncPts);
+ }
- native void updateTextureImage(long ctx, int numLevels, int level,
- int format, int internalFormat, int width,
- int height, int depth,
- int boundaryWidth, byte[] imageYup);
+ void updateTextureFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+
+ Pipeline.getPipeline().updateTexture3DFilter4Func(ctx,
+ numFilter4FuncPts, filter4FuncPts);
+ }
+
+ void updateTextureAnisotropicFilter(Context ctx, float degree) {
+ Pipeline.getPipeline().updateTexture3DAnisotropicFilter(ctx, degree);
+ }
- native void updateTextureSubImage(long ctx, int level,
- int xoffset, int yoffset, int zoffset,
- int internalFormat, int format,
- int imgXoffset, int imgYoffset, int imgZoffset,
- int tilew, int tileh,
- int width, int height, int depth,
- byte[] imageYup);
+ // Wrapper around the native call for 3D textures
+ void updateTextureImage(Canvas3D cv,
+ int face, int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height, int depth,
+ int boundaryWidth, int imageDataType,
+ Object imageData) {
+
+ Pipeline.getPipeline().updateTexture3DImage(cv.ctx,
+ numLevels, level,
+ textureFormat, imageFormat,
+ width, height, depth,
+ boundaryWidth, imageDataType, imageData);
+ }
+
+ // Wrapper around the native call for 3D textures
+ void updateTextureSubImage(Canvas3D cv,
+ int face, int level,
+ int xoffset, int yoffset, int zoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset, int imgZOffset,
+ int tilew, int tileh, int width, int height, int depth,
+ int imageDataType, Object imageData) {
+
+ Pipeline.getPipeline().updateTexture3DSubImage(cv.ctx,
+ level, xoffset, yoffset, zoffset,
+ textureFormat, imageFormat,
+ imgXOffset, imgYOffset, imgZOffset,
+ tilew, tileh, width, height, depth,
+ imageDataType, imageData);
+ }
+
+
// get an ID for Texture3D
int getTextureId() {
@@ -116,18 +158,36 @@ class Texture3DRetained extends TextureRetained {
// mipmapping when level 0 is not the base level
void updateTextureDimensions(Canvas3D cv) {
- updateTextureImage(cv.ctx, maxLevels, 0,
- format, ImageComponentRetained.BYTE_RGBA,
- width, height, depth, boundaryWidth, null);
+ if(images[0][0] != null) {
+ updateTextureImage(cv, maxLevels, 0, 0,
+ format, images[0][0].getImageFormatTypeIntValue(false),
+ width, height, depth, boundaryWidth,
+ images[0][0].getImageDataTypeIntValue(), null);
+ }
}
void updateTextureBoundary(Canvas3D cv) {
- updateTextureBoundary(cv.ctx,
- boundaryModeS, boundaryModeT, boundaryModeR,
- boundaryColor.x, boundaryColor.y,
- boundaryColor.z, boundaryColor.w);
-
+ updateTextureBoundary(cv.ctx,
+ boundaryModeS, boundaryModeT, boundaryModeR,
+ boundaryColor.x, boundaryColor.y,
+ boundaryColor.z, boundaryColor.w);
+ }
+
+ void updateTextureLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+
+ Pipeline.getPipeline().updateTexture3DLodRange(ctx, baseLevel, maximumLevel,
+ minimumLod, maximumLod);
+ }
+
+ void updateTextureLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ) {
+
+ Pipeline.getPipeline().updateTexture3DLodOffset(ctx,
+ lodOffsetX, lodOffsetY, lodOffsetZ);
}
void reloadTextureImage(Canvas3D cv, int face, int level,
@@ -139,13 +199,16 @@ class Texture3DRetained extends TextureRetained {
" h= " + image.height + " d= " + depth +
" numLevels= " + numLevels);
*/
-
-
- updateTextureImage(cv.ctx, numLevels, level, format,
- image.storedYupFormat,
- image.width, image.height, depth,
- boundaryWidth, image.imageYup);
-
+
+ // Texture3D does not need to support Raster
+ ImageComponentRetained.ImageData imageData = image.getImageData(false);
+
+ updateTextureImage(cv,
+ 0, numLevels, level, format,
+ image.getImageFormatTypeIntValue(false),
+ image.width, image.height, depth,
+ boundaryWidth, image.getImageDataTypeIntValue(),
+ imageData.get());
}
void reloadTextureSubImage(Canvas3D cv, int level, int face,
@@ -157,43 +220,18 @@ class Texture3DRetained extends TextureRetained {
width = info.width,
height = info.height;
- int xoffset = x - image.minX;
- int yoffset = y - image.minY;
-
- updateTextureSubImage(cv.ctx, level, xoffset, yoffset, z,
- format, image.storedYupFormat,
- xoffset, yoffset, z,
- image.width, image.height,
- width, height, 1, image.imageYup);
- }
-
-
-
- protected void finalize() {
-
- if (objectId > 0) {
- // memory not yet free
- // send a message to the request renderer
- synchronized (VirtualUniverse.mc.contextCreationLock) {
- boolean found = false;
-
- for (Enumeration e = Screen3D.deviceRendererMap.elements();
- e.hasMoreElements(); ) {
- Renderer rdr = (Renderer) e.nextElement();
- J3dMessage renderMessage = VirtualUniverse.mc.getMessage();
- renderMessage.threads = J3dThread.RENDER_THREAD;
- renderMessage.type = J3dMessage.RENDER_IMMEDIATE;
- renderMessage.universe = null;
- renderMessage.view = null;
- renderMessage.args[0] = null;
- renderMessage.args[1] = new Integer(objectId);
- renderMessage.args[2] = "3D";
- rdr.rendererStructure.addMessage(renderMessage);
- }
- objectId = -1;
- }
- VirtualUniverse.mc.setWorkForRequestRenderer();
- }
+ int xoffset = x;
+ int yoffset = y;
+ // Texture3D does not need to support Raster
+ ImageComponentRetained.ImageData imageData = image.getImageData(false);
+
+ updateTextureSubImage(cv,
+ 0, level, xoffset, yoffset, z,
+ format, image.getImageFormatTypeIntValue(false),
+ xoffset, yoffset, z,
+ image.width, image.height,
+ width, height, 1, image.getImageDataTypeIntValue(),
+ imageData.get());
}
}
diff --git a/src/classes/share/javax/media/j3d/TextureAttributesRetained.java b/src/classes/share/javax/media/j3d/TextureAttributesRetained.java
index 3b58d95..aaba553 100644
--- a/src/classes/share/javax/media/j3d/TextureAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/TextureAttributesRetained.java
@@ -220,8 +220,7 @@ class TextureAttributesRetained extends NodeComponentRetained {
*/
final void setTextureTransform(Transform3D transform) {
this.transform.set(transform);
- sendMessage(TRANSFORM_CHANGED,
- VirtualUniverse.mc.getTransform3D(transform), null);
+ sendMessage(TRANSFORM_CHANGED, new Transform3D(transform), null);
}
@@ -498,39 +497,6 @@ class TextureAttributesRetained extends NodeComponentRetained {
return combineAlphaScale;
}
- // These methods update the native context.
- native void updateNative(long ctx,
- double[] transform, boolean isIdentity, int textureMode,
- int perspCorrectionMode, float red,
- float green, float blue, float alpha,
- int textureFormat);
-
- native void updateNativeRegisterCombiners(long ctx,
- double[] transform, boolean isIdentity, int textureMode,
- int perspCorrectionMode, float red,
- float green, float blue, float alpha,
- int textureFormat,
- int combineRgbMode, int combineAlphaMode,
- int[] combineRgbSrc, int[] combineAlphaSrc,
- int[] combineRgbFcn, int[] combineAlphaFcn,
- int combineRgbScale, int combineAlphaScale);
-
- native void updateTextureColorTableNative(long ctx, int numComponents,
- int colorTableSize,
- int[] colorTable);
-
- native void updateCombinerNative(long ctx,
- int combineRgbMode, int combineAlphaMode,
- int[] combineRgbSrc, int[] combineAlphaSrc,
- int[] combineRgbFcn, int[] combineAlphaFcn,
- int combineRgbScale, int combineAlphaScale);
-
- // NOTE: the following native methods are not used any more, since
- // we no longer do simulated multi-pass by default
- // (and with shaders, this won't work anyway)
-// native void restoreBlend1Pass(long ctx);
-// native void updateBlend2Pass(long ctx);
-
void updateNative(Canvas3D cv, boolean simulate, int textureFormat) {
//System.out.println("TextureAttributes/updateNative: simulate= " + simulate + " " + this);
@@ -548,14 +514,14 @@ class TextureAttributesRetained extends NodeComponentRetained {
if (VirtualUniverse.mc.useCombiners &&
(cv.textureExtendedFeatures &
Canvas3D.TEXTURE_REGISTER_COMBINERS) != 0) {
- updateNativeRegisterCombiners(cv.ctx,
- transform.mat, isIdentity, textureMode, perspCorrectionMode,
- textureBlendColor.x, textureBlendColor.y,
- textureBlendColor.z, textureBlendColor.w,
- textureFormat, combineRgbMode, combineAlphaMode,
- combineRgbSrc, combineAlphaSrc,
- combineRgbFcn, combineAlphaFcn,
- combineRgbScale, combineAlphaScale);
+ Pipeline.getPipeline().updateRegisterCombiners(cv.ctx,
+ transform.mat, isIdentity, textureMode, perspCorrectionMode,
+ textureBlendColor.x, textureBlendColor.y,
+ textureBlendColor.z, textureBlendColor.w,
+ textureFormat, combineRgbMode, combineAlphaMode,
+ combineRgbSrc, combineAlphaSrc,
+ combineRgbFcn, combineAlphaFcn,
+ combineRgbScale, combineAlphaScale);
} else {
if (textureMode == TextureAttributes.COMBINE) {
@@ -567,11 +533,12 @@ class TextureAttributesRetained extends NodeComponentRetained {
int _combineRgbMode = combineRgbMode;
int _combineAlphaMode = combineAlphaMode;
- updateNative(cv.ctx, transform.mat, isIdentity, textureMode,
- perspCorrectionMode,
- textureBlendColor.x, textureBlendColor.y,
- textureBlendColor.z, textureBlendColor.w,
- textureFormat);
+ Pipeline.getPipeline().updateTextureAttributes(cv.ctx,
+ transform.mat, isIdentity, textureMode,
+ perspCorrectionMode,
+ textureBlendColor.x, textureBlendColor.y,
+ textureBlendColor.z, textureBlendColor.w,
+ textureFormat);
if (((combineRgbMode == TextureAttributes.COMBINE_DOT3) &&
@@ -600,30 +567,32 @@ class TextureAttributesRetained extends NodeComponentRetained {
_combineAlphaMode = TextureAttributes.COMBINE_REPLACE;
}
- updateCombinerNative(cv.ctx,
- _combineRgbMode, _combineAlphaMode,
- combineRgbSrc, combineAlphaSrc,
- combineRgbFcn, combineAlphaFcn,
- combineRgbScale, combineAlphaScale);
+ Pipeline.getPipeline().updateCombiner(cv.ctx,
+ _combineRgbMode, _combineAlphaMode,
+ combineRgbSrc, combineAlphaSrc,
+ combineRgbFcn, combineAlphaFcn,
+ combineRgbScale, combineAlphaScale);
} else {
// Texture COMBINE is not supported by the underlying
// layer, fallback to REPLACE
- updateNative(cv.ctx, transform.mat, isIdentity,
- TextureAttributes.REPLACE,
- perspCorrectionMode,
- textureBlendColor.x, textureBlendColor.y,
- textureBlendColor.z, textureBlendColor.w,
- textureFormat);
+ Pipeline.getPipeline().updateTextureAttributes(cv.ctx,
+ transform.mat, isIdentity,
+ TextureAttributes.REPLACE,
+ perspCorrectionMode,
+ textureBlendColor.x, textureBlendColor.y,
+ textureBlendColor.z, textureBlendColor.w,
+ textureFormat);
}
} else {
- updateNative(cv.ctx, transform.mat, isIdentity, textureMode,
- perspCorrectionMode,
- textureBlendColor.x, textureBlendColor.y,
- textureBlendColor.z, textureBlendColor.w,
- textureFormat);
+ Pipeline.getPipeline().updateTextureAttributes(cv.ctx,
+ transform.mat, isIdentity, textureMode,
+ perspCorrectionMode,
+ textureBlendColor.x, textureBlendColor.y,
+ textureBlendColor.z, textureBlendColor.w,
+ textureFormat);
}
}
@@ -631,7 +600,7 @@ class TextureAttributesRetained extends NodeComponentRetained {
if (((cv.textureExtendedFeatures & Canvas3D.TEXTURE_COLOR_TABLE)
!= 0) && textureColorTable != null) {
- updateTextureColorTableNative(cv.ctx,
+ Pipeline.getPipeline().updateTextureColorTable(cv.ctx,
numTextureColorTableComponents,
textureColorTableSize, textureColorTable);
}
@@ -639,15 +608,16 @@ class TextureAttributesRetained extends NodeComponentRetained {
// we are in the multi-pass mode,
// in this case, set the texture Mode to replace and use
// blending to simulate the original textureMode
- updateNative(cv.ctx, transform.mat, isIdentity, TextureAttributes.REPLACE,
- perspCorrectionMode,
- textureBlendColor.x, textureBlendColor.y,
- textureBlendColor.z, textureBlendColor.w, textureFormat);
+ Pipeline.getPipeline().updateTextureAttributes(cv.ctx,
+ transform.mat, isIdentity, TextureAttributes.REPLACE,
+ perspCorrectionMode,
+ textureBlendColor.x, textureBlendColor.y,
+ textureBlendColor.z, textureBlendColor.w, textureFormat);
if (((cv.textureExtendedFeatures & Canvas3D.TEXTURE_COLOR_TABLE)
!= 0) && textureColorTable != null) {
- updateTextureColorTableNative(cv.ctx, numTextureColorTableComponents,
+ Pipeline.getPipeline().updateTextureColorTable(cv.ctx, numTextureColorTableComponents,
textureColorTableSize, textureColorTable);
}
@@ -727,8 +697,6 @@ class TextureAttributesRetained extends NodeComponentRetained {
if ((component & TRANSFORM_CHANGED) != 0) {
mirrorTa.transform.set((Transform3D)value);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D,
- (Transform3D)value);
}
else if ((component & MODE_CHANGED) != 0) {
mirrorTa.textureMode = ((Integer)value).intValue();
@@ -969,7 +937,7 @@ class TextureAttributesRetained extends NodeComponentRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.TEXTUREATTRIBUTES_CHANGED;
createMessage.universe = null;
@@ -983,7 +951,7 @@ class TextureAttributesRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.TEXTUREATTRIBUTES_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/TextureBin.java b/src/classes/share/javax/media/j3d/TextureBin.java
index 9a004bc..75c5229 100644
--- a/src/classes/share/javax/media/j3d/TextureBin.java
+++ b/src/classes/share/javax/media/j3d/TextureBin.java
@@ -152,21 +152,27 @@ class TextureBin extends Object implements ObjectUpdate {
transparentRMList = null;
numEditingRenderMolecules = 0;
+ // Issue 249 - check for sole user only if property is set
// determine if this appearance is a sole user of this
// TextureBin
- if ((app != null) &&
- (app.changedFrequent &
- (AppearanceRetained.TEXTURE |
- AppearanceRetained.TEXCOORD_GEN |
- AppearanceRetained.TEXTURE_ATTR |
- AppearanceRetained.TEXTURE_UNIT_STATE)) != 0) {
- tbFlag |= TextureBin.SOLE_USER;
- this.app = app;
+ tbFlag &= ~TextureBin.SOLE_USER;
+ if (VirtualUniverse.mc.allowSoleUser) {
+ if ((app != null) &&
+ (app.changedFrequent &
+ (AppearanceRetained.TEXTURE |
+ AppearanceRetained.TEXCOORD_GEN |
+ AppearanceRetained.TEXTURE_ATTR |
+ AppearanceRetained.TEXTURE_UNIT_STATE)) != 0) {
+ tbFlag |= TextureBin.SOLE_USER;
- } else {
- tbFlag &= ~TextureBin.SOLE_USER;
- this.app = null;
+ }
}
+
+ if ((tbFlag & TextureBin.SOLE_USER) != 0) {
+ this.app = app;
+ } else {
+ this.app = null;
+ }
resetTextureState(state);
@@ -1015,7 +1021,6 @@ class TextureBin extends Object implements ObjectUpdate {
r.prev = null;
r.next = null;
- renderBin.renderMoleculeFreelist.add(r);
found = true;
}
}
@@ -1082,14 +1087,14 @@ class TextureBin extends Object implements ObjectUpdate {
texUnitState = null;
}
}
-
+
/**
* This method is called to update the state for this
* TextureBin. This is only applicable in the single-pass case.
* Multi-pass render will have to take care of its own
* state update.
*/
- void updateAttributes(Canvas3D cv, int pass) {
+ void updateAttributes(Canvas3D cv) {
boolean dirty = ((cv.canvasDirty & (Canvas3D.TEXTUREBIN_DIRTY|
Canvas3D.TEXTUREATTRIBUTES_DIRTY)) != 0);
@@ -1112,11 +1117,11 @@ class TextureBin extends Object implements ObjectUpdate {
useShaders ? cv.maxTextureImageUnits : cv.maxTextureUnits;
// If the number of active texture units is greater than the number of
- // supported units, and we don't allow simulated multi-texture, then we
+ // supported units, then we
// need to set a flag indicating that the texture units are invalid.
boolean disableTexture = false;
- if (pass < 0 && numActiveTexUnit > availableTextureUnits) {
+ if (numActiveTexUnit > availableTextureUnits) {
disableTexture = true;
// System.err.println("*** TextureBin : number of texture units exceeded");
}
@@ -1148,7 +1153,7 @@ class TextureBin extends Object implements ObjectUpdate {
}
cv.setLastActiveTexUnit(-1);
}
- } else if (pass < 0) {
+ } else {
int j = 0;
@@ -1194,28 +1199,10 @@ class TextureBin extends Object implements ObjectUpdate {
}
cv.setLastActiveTexUnit(lastActiveTexUnitIdx);
- // tell the underlying library the texture unit mapping
-
- if ((pass == USE_DISPLAYLIST) &&
- (cv.numActiveTexUnit > 0)) {
- cv.updateTexUnitStateMap();
- }
// set the active texture unit back to 0
cv.activeTextureUnit(cv.ctx, 0);
- } else {
- // update the last active texture unit state
- if (dirty || cv.texUnitState[0].mirror == null ||
- cv.texUnitState[0].mirror !=
- texUnitState[lastActiveTexUnitIndex].mirror) {
- texUnitState[lastActiveTexUnitIndex].updateNative(
- -1, cv, false, false);
- cv.texUnitState[0].mirror =
- texUnitState[lastActiveTexUnitIndex].mirror;
-
- cv.setLastActiveTexUnit(0);
- }
}
cv.canvasDirty &= ~Canvas3D.TEXTUREBIN_DIRTY;
}
@@ -1256,20 +1243,7 @@ class TextureBin extends Object implements ObjectUpdate {
}
}
- // If shaders are not being used, and if allowSimulatedMultiTexture
- // property is set, then we will use simulated (multi-pass)
- // multi-texture when the requested number of texture units exceeds
- // the available number of texture units
- boolean useShaders = (shaderBin.shaderProgram != null);
- int availableTextureUnits =
- useShaders ? cv.maxTextureImageUnits : cv.maxTextureUnits;
-
- if (!useShaders && (numActiveTexUnit > availableTextureUnits) &&
- VirtualUniverse.mc.allowSimulatedMultiTexture) {
- multiPassRender(cv, rlist);
- } else {
- renderList(cv, USE_DISPLAYLIST, rlist);
- }
+ renderList(cv, USE_DISPLAYLIST, rlist);
}
@@ -1277,6 +1251,7 @@ class TextureBin extends Object implements ObjectUpdate {
* render a render list
*/
void renderList(Canvas3D cv, int pass, Object rlist) {
+ assert pass < 0;
if (rlist instanceof RenderMolecule) {
renderList(cv, pass, (RenderMolecule) rlist);
@@ -1290,6 +1265,7 @@ class TextureBin extends Object implements ObjectUpdate {
* render list of RenderMolecule
*/
void renderList(Canvas3D cv, int pass, RenderMolecule rlist) {
+ assert pass < 0;
// bit mask of all attr fields that are equivalent across
// renderMolecules thro. ORing of invisible RMs.
@@ -1323,6 +1299,7 @@ class TextureBin extends Object implements ObjectUpdate {
* render sorted transparent list
*/
void renderList(Canvas3D cv, int pass, TransparentRenderingInfo tinfo) {
+ assert pass < 0;
RenderMolecule rm = tinfo.rm;
if (rm.isSwitchOn()) {
@@ -1331,87 +1308,6 @@ class TextureBin extends Object implements ObjectUpdate {
}
-
- /**
- * multi rendering pass to simulate multiple texture units
- */
- private void multiPassRender(Canvas3D cv, Object rlist) {
-
- assert VirtualUniverse.mc.allowSimulatedMultiTexture;
-
- boolean startToSimulate = false;
- boolean isFogEnabled = false;
-
- // No lazy download of texture for multi-pass,
- // update the texture states here now
-
- // update the environment state
-
- // no need to update the texture state in updateAttributes(), the state
- // will be explicitly updated in the multi-pass
- cv.setStateIsUpdated(Canvas3D.TEXTUREBIN_BIT);
- cv.textureBin = this;
- cv.canvasDirty &= ~Canvas3D.TEXTUREBIN_DIRTY;
- cv.updateEnvState();
-
-
- // first reset those texture units that are currently enabled
-
- if (cv.multiTexAccelerated) {
- int activeTexUnit = cv.getNumActiveTexUnit();
- for (int i = 0; i < activeTexUnit; i++) {
- cv.resetTexture(cv.ctx, i);
- }
- // set the active texture unit back to 0
- cv.activeTextureUnit(cv.ctx, 0);
- }
-
- // only texture unit 0 will be used in multi-pass case
- cv.setNumActiveTexUnit(1);
- cv.setLastActiveTexUnit(0);
-
- // first check if there is fog in the path
- // if there is, then turn off fog now and turn it back on
- // for the last pass only
- isFogEnabled = (environmentSet.fog != null);
-
- TextureUnitStateRetained tus;
-
- for (int i = 0; i < texUnitState.length; i++) {
- tus = texUnitState[i];
-
- if (tus != null && tus.isTextureEnabled()) {
-
-
- // update the canvas texture unit state cache
- cv.texUnitState[0].mirror = tus.mirror;
-
- tus.updateNative(-1, cv, false, startToSimulate);
-
- if (!startToSimulate) {
- startToSimulate = true;
- if (isFogEnabled) {
- cv.setFogEnableFlag(cv.ctx, false);
- }
- }
-
- // turn on fog again in the last pass
-
- if (i == lastActiveTexUnitIndex && isFogEnabled) {
- cv.setFogEnableFlag(cv.ctx, true);
- }
- renderList(cv, i, rlist);
- }
- }
-
- // adjust the depth test back to what it was
- // and adjust the blend func to what it was
- if (startToSimulate) {
- cv.setStateToUpdate(Canvas3D.TRANSPARENCY_BIT);
- }
- }
-
-
void changeLists(RenderMolecule r) {
RenderMolecule renderMoleculeList, rmlist = null, head;
HashMap allMap = null;
@@ -1680,5 +1576,3 @@ class TextureBin extends Object implements ObjectUpdate {
numEditingRenderMolecules++;
}
}
-
-
diff --git a/src/classes/share/javax/media/j3d/TextureCubeMap.java b/src/classes/share/javax/media/j3d/TextureCubeMap.java
index 9c6f608..f3facec 100644
--- a/src/classes/share/javax/media/j3d/TextureCubeMap.java
+++ b/src/classes/share/javax/media/j3d/TextureCubeMap.java
@@ -44,6 +44,8 @@ import javax.vecmath.*;
*/
public class TextureCubeMap extends Texture {
+ // TODO KCR : NPOT
+
/**
* Specifies the face of the cube that is pierced by the positive x axis
*/
@@ -123,7 +125,7 @@ public class TextureCubeMap extends Texture {
* @param format data format of Textures saved in this object.
* One of INTENSITY, LUMINANCE, ALPHA, LUMINANCE_ALPHA, RGB, RGBA.
* @param width width of image at level 0. Must be power of 2.
- * @param boundaryWidth width of the boundary.
+ * @param boundaryWidth width of the boundary, which must be 0 or 1.
*
* @exception IllegalArgumentException if width is NOT
* power of 2 OR invalid format/mipmapMode is specified.
@@ -157,6 +159,12 @@ public class TextureCubeMap extends Texture {
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalSharingException if this TextureCubeMap is live and
+ * the specified image is being used by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalSharingException if this TextureCubeMap is
+ * being used by an immediate mode context and
+ * the specified image is being used by a Canvas3D as an off-screen buffer.
*/
public void setImage(int level, int face, ImageComponent2D image) {
if (isLiveOrCompiled()) {
@@ -164,7 +172,9 @@ public class TextureCubeMap extends Texture {
throw new CapabilityNotSetException(
J3dI18N.getString("TextureCubeMap1"));
}
-
+
+ validateImageIllegalSharing(image);
+
if (isLive())
((TextureCubeMapRetained)this.retained).setImage(level, face, image);
else
@@ -190,6 +200,14 @@ public class TextureCubeMap extends Texture {
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
+ * @exception IllegalSharingException if this TextureCubeMap is live and
+ * any of the specified images are being used by a Canvas3D as an
+ * off-screen buffer.
+ *
+ * @exception IllegalSharingException if this TextureCubeMap is
+ * being used by an immediate mode context and
+ * any of the specified images are being used by a Canvas3D as an
+ * off-screen buffer.
*/
public void setImages(int face, ImageComponent2D[] images) {
if (isLiveOrCompiled()) {
@@ -198,6 +216,11 @@ public class TextureCubeMap extends Texture {
J3dI18N.getString("TextureCubeMap1"));
}
+ // Do illegal sharing check
+ for(int i=0; i<images.length; i++) {
+ validateImageIllegalSharing(images[i]);
+ }
+
if (isLive())
((TextureCubeMapRetained)this.retained).setImages(face, images);
else
diff --git a/src/classes/share/javax/media/j3d/TextureCubeMapRetained.java b/src/classes/share/javax/media/j3d/TextureCubeMapRetained.java
index b79f5a0..f5e683c 100644
--- a/src/classes/share/javax/media/j3d/TextureCubeMapRetained.java
+++ b/src/classes/share/javax/media/j3d/TextureCubeMapRetained.java
@@ -41,6 +41,10 @@ class TextureCubeMapRetained extends TextureRetained {
* Sets a specified mipmap level for a particular face of the cubemap.
*/
void initImage(int level, int face, ImageComponent image) {
+
+ // Issue 172 : call checkImageSize even for non-live setImage calls
+ checkImageSize(level, image);
+
if (this.images == null) {
throw new IllegalArgumentException(
J3dI18N.getString("TextureRetained0"));
@@ -70,8 +74,10 @@ class TextureCubeMapRetained extends TextureRetained {
}
}
- ((ImageComponent2DRetained)image.retained).setTextureRef();
-
+ /* Don't think this is needed. --- Chien.
+ ((ImageComponent2DRetained)image.retained).setTextureRef();
+ */
+
if (image != null) {
this.images[face][level] = (ImageComponentRetained)image.retained;
} else {
@@ -81,8 +87,6 @@ class TextureCubeMapRetained extends TextureRetained {
final void setImage(int level, int face, ImageComponent image) {
- checkImageSize(level, image);
-
initImage(level, face, image);
Object arg[] = new Object[3];
@@ -98,12 +102,12 @@ class TextureCubeMapRetained extends TextureRetained {
if (image != null && level < maxLevels) {
ImageComponentRetained img= (ImageComponentRetained)image.retained;
if (img.isByReference()) {
- if (img.bImage[0] == null) {
+ if (img.getRefImage(0) == null) {
enable = false;
}
}
else {
- if (img.imageYup == null) {
+ if (img.getImageData(isUseAsRaster()).get() == null) {
enable = false;
}
}
@@ -126,14 +130,8 @@ class TextureCubeMapRetained extends TextureRetained {
final void setImages(int face, ImageComponent[] images) {
int i;
- ImageComponentRetained[] imagesRet =
- new ImageComponentRetained[images.length];
- for (i = 0; i < images.length; i++) {
- imagesRet[i] = (ImageComponentRetained)images[i].retained;
- }
- checkSizes(imagesRet);
- initImages(face, images);
+ initImages(face, images);
ImageComponent [] imgs = new ImageComponent[images.length];
for (i = 0; i < images.length; i++) {
@@ -154,12 +152,12 @@ class TextureCubeMapRetained extends TextureRetained {
if (images[i] != null) {
ImageComponentRetained img= (ImageComponentRetained)images[i].retained;
if (img.isByReference()) {
- if (img.bImage[0] == null) {
+ if (img.getRefImage(0) == null) {
enable = false;
}
}
else {
- if (img.imageYup == null) {
+ if (img.getImageData(isUseAsRaster()).get() == null) {
enable = false;
}
}
@@ -221,42 +219,64 @@ class TextureCubeMapRetained extends TextureRetained {
}
- native void bindTexture(long ctx, int objectId, boolean enable);
+ void bindTexture(Context ctx, int objectId, boolean enable) {
+ Pipeline.getPipeline().bindTextureCubeMap(ctx, objectId, enable);
+ }
- native void updateTextureFilterModes(long ctx, int minFilter,
- int magFilter);
+ void updateTextureBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha) {
- native void updateTextureBoundary(long ctx,
- int boundaryModeS, int boundaryModeT,
- float boundaryRed, float boundaryGreen,
- float boundaryBlue, float boundaryAlpha);
+ Pipeline.getPipeline().updateTextureCubeMapBoundary(ctx,
+ boundaryModeS, boundaryModeT,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+ }
- native void updateTextureSharpenFunc(long ctx,
- int numSharpenTextureFuncPts,
- float[] sharpenTextureFuncPts);
+ void updateTextureFilterModes(Context ctx,
+ int minFilter, int magFilter) {
- native void updateTextureFilter4Func(long ctx,
- int numFilter4FuncPts,
- float[] filter4FuncPts);
+ Pipeline.getPipeline().updateTextureCubeMapFilterModes(ctx,
+ minFilter, magFilter);
+ }
- native void updateTextureAnisotropicFilter(long ctx, float degree);
+ void updateTextureSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
- native void updateTextureImage(long ctx,
- int face,
- int numLevels,
- int level,
- int internalFormat, int format,
- int width, int height,
- int boundaryWidth, byte[] imageYup);
+ Pipeline.getPipeline().updateTextureCubeMapSharpenFunc(ctx,
+ numSharpenTextureFuncPts, sharpenTextureFuncPts);
+ }
- native void updateTextureSubImage(long ctx, int face,
- int level, int xoffset, int yoffset,
- int internalFormat,int format,
- int imgXOffset, int imgYOffset,
- int tilew,
- int width, int height,
- byte[] image);
-
+ void updateTextureFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
+
+ Pipeline.getPipeline().updateTextureCubeMapFilter4Func(ctx,
+ numFilter4FuncPts, filter4FuncPts);
+ }
+
+ void updateTextureAnisotropicFilter(Context ctx, float degree) {
+ Pipeline.getPipeline().updateTextureCubeMapAnisotropicFilter(ctx, degree);
+ }
+
+
+ void updateTextureLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+
+ Pipeline.getPipeline().updateTextureCubeMapLodRange(ctx, baseLevel, maximumLevel,
+ minimumLod, maximumLod);
+ }
+
+ void updateTextureLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ) {
+
+ Pipeline.getPipeline().updateTextureCubeMapLodOffset(ctx,
+ lodOffsetX, lodOffsetY, lodOffsetZ);
+ }
/**
@@ -264,38 +284,52 @@ class TextureCubeMapRetained extends TextureRetained {
* mipmapping when level 0 is not the base level
*/
void updateTextureDimensions(Canvas3D cv) {
- for (int i = 0; i < 6; i++) {
- updateTextureImage(cv.ctx, i, maxLevels, 0,
- format, ImageComponentRetained.BYTE_RGBA,
- width, height, boundaryWidth, null);
- }
+ if(images[0][0] != null) {
+ // All faces should have the same image format and type.
+ int imageFormat = images[0][0].getImageFormatTypeIntValue(false);
+ int imageType = images[0][0].getImageDataTypeIntValue();
+
+ for (int i = 0; i < 6; i++) {
+ updateTextureImage(cv, i, maxLevels, 0,
+ format, imageFormat,
+ width, height, boundaryWidth,
+ imageType, null);
+ }
+ }
}
// This is just a wrapper of the native method.
-
- void updateTextureImage(Canvas3D cv, int face, int numLevels, int level,
- int format, int storedFormat,
- int width, int height,
- int boundaryWidth, byte[] data) {
-
- updateTextureImage(cv.ctx, face, numLevels, level, format,
- storedFormat, width, height,
- boundaryWidth, data);
+ void updateTextureImage(Canvas3D cv,
+ int face, int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth, int imageDataType,
+ Object imageData) {
+
+ Pipeline.getPipeline().updateTextureCubeMapImage(cv.ctx,
+ face, numLevels, level,
+ textureFormat, imageFormat,
+ width, height,
+ boundaryWidth, imageDataType, imageData);
}
-
// This is just a wrapper of the native method.
+ void updateTextureSubImage(Canvas3D cv,
+ int face, int level,
+ int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int imageDataType, Object imageData) {
+
+ Pipeline.getPipeline().updateTextureCubeMapSubImage(cv.ctx,
+ face, level, xoffset, yoffset,
+ textureFormat, imageFormat,
+ imgXOffset, imgYOffset,
+ tilew, width, height,
+ imageDataType, imageData);
- void updateTextureSubImage(Canvas3D cv, int face, int level,
- int xoffset, int yoffset, int format,
- int storedFormat, int imgXOffset,
- int imgYOffset, int tileWidth,
- int width, int height, byte[] data) {
-
- updateTextureSubImage(cv.ctx, face, level, xoffset, yoffset, format,
- storedFormat, imgXOffset, imgYOffset,
- tileWidth, width, height, data);
}
}
diff --git a/src/classes/share/javax/media/j3d/TextureRetained.java b/src/classes/share/javax/media/j3d/TextureRetained.java
index bfeef5a..ec4de75 100644
--- a/src/classes/share/javax/media/j3d/TextureRetained.java
+++ b/src/classes/share/javax/media/j3d/TextureRetained.java
@@ -12,10 +12,10 @@
package javax.media.j3d;
-import java.awt.image.BufferedImage;
import java.util.*;
import javax.vecmath.*;
import java.awt.image.DataBufferByte;
+import java.awt.image.RenderedImage;
/**
* The Texture object is a component object of an Appearance object
@@ -85,6 +85,7 @@ abstract class TextureRetained extends NodeComponentRetained {
float maximumLod = 1000.0f;
Point3f lodOffset = null;
+ private boolean useAsRaster = false; // true if used by Raster or Background.
// Texture mapping enable switch
// This enable is derived from the user specified enable
@@ -163,8 +164,8 @@ abstract class TextureRetained extends NodeComponentRetained {
Object resourceLock = new Object();
- void initialize(int format, int width, int widPower,
- int height, int heiPower, int mipmapMode,
+ void initialize(int format, int width, int widLevels,
+ int height, int heiLevels, int mipmapMode,
int boundaryWidth) {
this.mipmapMode = mipmapMode;
@@ -176,10 +177,10 @@ abstract class TextureRetained extends NodeComponentRetained {
// determine the maximum number of mipmap levels that can be
// defined from the specified dimension
- if (widPower > heiPower) {
- maxMipMapLevels = widPower + 1;
+ if (widLevels > heiLevels) {
+ maxMipMapLevels = widLevels + 1;
} else {
- maxMipMapLevels = heiPower + 1;
+ maxMipMapLevels = heiLevels + 1;
}
@@ -331,6 +332,10 @@ abstract class TextureRetained extends NodeComponentRetained {
* power of 2 OR invalid format/mipmapMode is specified.
*/
void initImage(int level, ImageComponent image) {
+
+ // Issue 172 : call checkImageSize even for non-live setImage calls
+ checkImageSize(level, image);
+
if (this.images == null) {
throw new IllegalArgumentException(J3dI18N.getString("TextureRetained0"));
}
@@ -359,12 +364,6 @@ abstract class TextureRetained extends NodeComponentRetained {
}
}
- if (this instanceof Texture2DRetained) {
- ((ImageComponent2DRetained)image.retained).setTextureRef();
- } else {
- ((ImageComponent3DRetained)image.retained).setTextureRef();
- }
-
if (image != null) {
this.images[0][level] = (ImageComponentRetained)image.retained;
@@ -375,17 +374,21 @@ abstract class TextureRetained extends NodeComponentRetained {
final void checkImageSize(int level, ImageComponent image) {
if (image != null) {
- int imgHeight = ((ImageComponentRetained)image.retained).height;
int imgWidth = ((ImageComponentRetained)image.retained).width;
- int i, tmp = 1;
- // calculate tmp = 2**level
- for (i=0; i < level; i++,tmp *= 2);
+ int imgHeight = ((ImageComponentRetained)image.retained).height;
+
+ int wdh = width;
+ int hgt = height;
+ for (int i = 0; i < level; i++) {
+ wdh >>= 1;
+ hgt >>= 1;
+ }
- int hgt = height/tmp, wdh = width / tmp;
- if (hgt < 1) hgt = 1;
if (wdh < 1) wdh = 1;
+ if (hgt < 1) hgt = 1;
- if ((hgt != imgHeight) || (wdh != imgWidth)) {
+ if ((wdh != (imgWidth - 2*boundaryWidth)) ||
+ (hgt != (imgHeight - 2*boundaryWidth))) {
throw new IllegalArgumentException(
J3dI18N.getString("TextureRetained1"));
}
@@ -393,36 +396,31 @@ abstract class TextureRetained extends NodeComponentRetained {
}
final void checkSizes(ImageComponentRetained images[]) {
- // check that the image at each level is w/2 h/2 of the image at the
- // previous level
+ // Issue 172 : this method is now redundant
+
+ // Assertion check that the image at each level is the correct size
+ // This shouldn't be needed since we already should have checked the
+ // size at each level, and verified that all levels are set.
if (images != null) {
-
- // only need to check if there is more than 1 level
- if (images.length > 1) {
- int compareW = images[0].width/2;
- int compareH = images[0].height/2;
- int w, h;
- for (int i = 1; i < images.length; i++) {
- w = images[i].width;
- h = images[i].height;
- if (compareW < 1) compareW = 1;
- if (compareH < 1) compareH = 1;
- if ((w != compareW) && (h != compareH)) {
- throw new IllegalArgumentException(
- J3dI18N.getString("TextureRetained1"));
- }
- compareW = w/2;
- compareH = h/2;
- }
- }
- }
+ int hgt = height;
+ int wdh = width;
+ for (int level = 0; level < images.length; level++) {
+ int imgWidth = images[level].width;
+ int imgHeight = images[level].height;
+
+ assert (wdh == (imgWidth - 2*boundaryWidth)) &&
+ (hgt == (imgHeight - 2*boundaryWidth));
+
+ wdh /= 2;
+ hgt /= 2;
+ if (wdh < 1) wdh = 1;
+ if (hgt < 1) hgt = 1;
+ }
+ }
}
final void setImage(int level, ImageComponent image) {
-
- checkImageSize(level, image);
-
- initImage(level, image);
+ initImage(level, image);
Object arg[] = new Object[3];
arg[0] = new Integer(level);
@@ -438,12 +436,12 @@ abstract class TextureRetained extends NodeComponentRetained {
if (image != null && level >= baseLevel && level <= maximumLevel) {
ImageComponentRetained img= (ImageComponentRetained)image.retained;
if (img.isByReference()) {
- if (img.bImage[0] == null) {
+ if (img.getRefImage(0) == null) {
enable = false;
}
}
else {
- if (img.imageYup == null) {
+ if (img.getImageData(isUseAsRaster()).get() == null) {
enable = false;
}
}
@@ -466,14 +464,8 @@ abstract class TextureRetained extends NodeComponentRetained {
final void setImages(ImageComponent[] images) {
int i;
- ImageComponentRetained[] imagesRet =
- new ImageComponentRetained[images.length];
- for (i = 0; i < images.length; i++) {
- imagesRet[i] = (ImageComponentRetained)images[i].retained;
- }
- checkSizes(imagesRet);
- initImages(images);
+ initImages(images);
ImageComponent [] imgs = new ImageComponent[images.length];
for (i = 0; i < images.length; i++) {
@@ -496,12 +488,12 @@ abstract class TextureRetained extends NodeComponentRetained {
ImageComponentRetained img=
(ImageComponentRetained)images[i].retained;
if (img.isByReference()) {
- if (img.bImage[0] == null) {
+ if (img.getRefImage(0) == null) {
enable = false;
}
}
else {
- if (img.imageYup == null) {
+ if (img.getImageData(isUseAsRaster()).get() == null) {
enable = false;
}
}
@@ -629,11 +621,11 @@ abstract class TextureRetained extends NodeComponentRetained {
for (int j = 0; j < numFaces && enable; j++) {
for (int i = baseLevel; i <= maximumLevel && enable; i++) {
if (images[j][i].isByReference()) {
- if (images[j][i].bImage[0] == null) {
+ if (images[j][i].getRefImage(0) == null) {
enable = false;
}
} else {
- if (images[j][i].imageYup == null) {
+ if (images[j][i].getImageData(isUseAsRaster()).get() == null) {
enable = false;
}
}
@@ -936,13 +928,6 @@ abstract class TextureRetained extends NodeComponentRetained {
void setLive(boolean backgroundGroup, int refCount) {
- // check the sizes of the images
- if (images != null) {
- for (int j = 0; j < numFaces; j++) {
- checkSizes(images[j]);
- }
- }
-
// This line should be assigned before calling doSetLive, so that
// the mirror object's enable is assigned correctly!
enable = userSpecifiedEnable;
@@ -967,8 +952,16 @@ abstract class TextureRetained extends NodeComponentRetained {
}
}
+ // Issue 172 : assertion check the sizes of the images after we have
+ // checked for all mipmap levels being set
+ if (images != null) {
+ for (int j = 0; j < numFaces; j++) {
+ checkSizes(images[j]);
+ }
+ }
+
// Send a message to Rendering Attr stucture to update the resourceMask
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.TEXTURE_CHANGED;
createMessage.args[0] = this;
@@ -984,11 +977,11 @@ abstract class TextureRetained extends NodeComponentRetained {
for (int j = 0; j < numFaces && enable; j++) {
for (int i = baseLevel; i <= maximumLevel && enable; i++){
if (images[j][i].isByReference()) {
- if (images[j][i].bImage[0] == null) {
+ if (images[j][i].getRefImage(0) == null) {
enable = false;
}
} else {
- if (images[j][i].imageYup == null) {
+ if (images[j][i].getImageData(isUseAsRaster()).get() == null) {
enable = false;
}
}
@@ -1017,52 +1010,69 @@ abstract class TextureRetained extends NodeComponentRetained {
}
}
- // Simply pass along to the NodeComponents
- /**
- * This method updates the native context. The implementation for 2D
- * texture mapping happens here. Texture3D implements its own version
- * of this.
+ /*
+ * The following methods update the native context.
+ * The implementation for Texture2D happens here.
+ * Texture3D and TextureCubeMap implement their own versions.
*/
- native void bindTexture(long ctx, int objectId, boolean enable);
- native void updateTextureFilterModes(long ctx,
- int minFilter, int magFilter);
+ void bindTexture(Context ctx, int objectId, boolean enable) {
+ Pipeline.getPipeline().bindTexture2D(ctx, objectId, enable);
+ }
- native void updateTextureLodRange(long ctx,
- int baseLevel, int maximumLevel,
- float minimumLod, float maximumLod);
+ void updateTextureBoundary(Context ctx,
+ int boundaryModeS, int boundaryModeT,
+ float boundaryRed, float boundaryGreen,
+ float boundaryBlue, float boundaryAlpha) {
- native void updateTextureLodOffset(long ctx,
- float lodOffsetX, float lodOffsetY,
- float lodOffsetZ);
+ Pipeline.getPipeline().updateTexture2DBoundary(ctx,
+ boundaryModeS, boundaryModeT,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+ }
+ void updateTextureFilterModes(Context ctx,
+ int minFilter, int magFilter) {
- native void updateTextureBoundary(long ctx,
- int boundaryModeS, int boundaryModeT,
- float boundaryRed, float boundaryGreen,
- float boundaryBlue, float boundaryAlpha);
+ Pipeline.getPipeline().updateTexture2DFilterModes(ctx,
+ minFilter, magFilter);
+ }
- native void updateTextureSharpenFunc(long ctx,
- int numSharpenTextureFuncPts,
- float[] sharpenTextureFuncPts);
+ void updateTextureSharpenFunc(Context ctx,
+ int numSharpenTextureFuncPts,
+ float[] sharpenTextureFuncPts) {
- native void updateTextureFilter4Func(long ctx,
- int numFilter4FuncPts,
- float[] filter4FuncPts);
+ Pipeline.getPipeline().updateTexture2DSharpenFunc(ctx,
+ numSharpenTextureFuncPts, sharpenTextureFuncPts);
+ }
- native void updateTextureAnisotropicFilter(long ctx, float degree);
+ void updateTextureFilter4Func(Context ctx,
+ int numFilter4FuncPts,
+ float[] filter4FuncPts) {
- native void updateTextureImage(long ctx,
- int numLevels, int level,
- int format, int storedFormat,
- int width, int height,
- int boundaryWidth, byte[] data);
+ Pipeline.getPipeline().updateTexture2DFilter4Func(ctx,
+ numFilter4FuncPts, filter4FuncPts);
+ }
- native void updateTextureSubImage(long ctx, int level,
- int xoffset, int yoffset, int format,
- int storedFormat, int imgXOffset,
- int imgYOffset, int tileWidth,
- int width, int height, byte[] data);
+ void updateTextureAnisotropicFilter(Context ctx, float degree) {
+ Pipeline.getPipeline().updateTexture2DAnisotropicFilter(ctx, degree);
+ }
+
+ void updateTextureLodRange(Context ctx,
+ int baseLevel, int maximumLevel,
+ float minimumLod, float maximumLod) {
+
+ Pipeline.getPipeline().updateTexture2DLodRange(ctx, baseLevel, maximumLevel,
+ minimumLod, maximumLod);
+ }
+
+ void updateTextureLodOffset(Context ctx,
+ float lodOffsetX, float lodOffsetY,
+ float lodOffsetZ) {
+
+ Pipeline.getPipeline().updateTexture2DLodOffset(ctx,
+ lodOffsetX, lodOffsetY, lodOffsetZ);
+ }
// get an ID for Texture 2D
@@ -1100,23 +1110,26 @@ abstract class TextureRetained extends NodeComponentRetained {
* mipmapping when level 0 is not the base level
*/
void updateTextureDimensions(Canvas3D cv) {
- updateTextureImage(cv.ctx, maxLevels, 0,
- format, ImageComponentRetained.BYTE_RGBA,
- width, height, boundaryWidth, null);
+ if(images[0][0] != null) {
+ updateTextureImage(cv, 0, maxLevels, 0,
+ format, images[0][0].getImageFormatTypeIntValue(false),
+ width, height, boundaryWidth,
+ images[0][0].getImageDataTypeIntValue(), null);
+ }
}
-
+
void updateTextureLOD(Canvas3D cv) {
if ((cv.textureExtendedFeatures & Canvas3D.TEXTURE_LOD_RANGE) != 0 ) {
- updateTextureLodRange(cv.ctx, baseLevel, maximumLevel,
- minimumLod, maximumLod);
+ updateTextureLodRange(cv.ctx, baseLevel, maximumLevel,
+ minimumLod, maximumLod);
}
- if ((lodOffset != null) &&
- ((cv.textureExtendedFeatures & Canvas3D.TEXTURE_LOD_OFFSET) != 0)) {
- updateTextureLodOffset(cv.ctx,
- lodOffset.x, lodOffset.y, lodOffset.z);
+ if ((lodOffset != null) &&
+ ((cv.textureExtendedFeatures & Canvas3D.TEXTURE_LOD_OFFSET) != 0)) {
+ updateTextureLodOffset(cv.ctx,
+ lodOffset.x, lodOffset.y, lodOffset.z);
}
}
@@ -1218,38 +1231,40 @@ abstract class TextureRetained extends NodeComponentRetained {
}
-
- // wrapper of the native call
-
- void updateTextureImage(Canvas3D cv, int face,
- int numLevels, int level,
- int format, int storedFormat,
- int width, int height,
- int boundaryWidth, byte[] data) {
-
- updateTextureImage(cv.ctx, maxLevels, level,
- format, storedFormat,
- width, height, boundaryWidth, data);
- }
-
-
-
- // wrapper of the native call
-
- void updateTextureSubImage(Canvas3D cv, int face, int level,
- int xoffset, int yoffset, int format,
- int storedFormat, int imgXOffset,
- int imgYOffset, int tileWidth,
- int width, int height, byte[] data) {
-
- updateTextureSubImage(cv.ctx, level,
- xoffset, yoffset, format,
- storedFormat, imgXOffset,
- imgYOffset, tileWidth,
- width, height, data);
+ // Wrapper around the native call for 2D textures; overridden for
+ // Texture3D and TextureCureMap
+ void updateTextureImage(Canvas3D cv,
+ int face, int numLevels, int level,
+ int textureFormat, int imageFormat,
+ int width, int height,
+ int boundaryWidth,
+ int imageDataType, Object data) {
+
+ Pipeline.getPipeline().updateTexture2DImage(cv.ctx,
+ numLevels, level,
+ textureFormat, imageFormat,
+ width, height, boundaryWidth,
+ imageDataType, data);
+ }
+
+ // Wrapper around the native call for 2D textures; overridden for
+ // Texture3D and TextureCureMap
+ void updateTextureSubImage(Canvas3D cv,
+ int face, int level,
+ int xoffset, int yoffset,
+ int textureFormat, int imageFormat,
+ int imgXOffset, int imgYOffset,
+ int tilew, int width, int height,
+ int imageDataType, Object data) {
+
+ Pipeline.getPipeline().updateTexture2DSubImage(cv.ctx,
+ level, xoffset, yoffset,
+ textureFormat, imageFormat,
+ imgXOffset, imgYOffset,
+ tilew, width, height,
+ imageDataType, data);
}
-
-
+
/**
* reloadTextureImage is used to load a particular level of image
@@ -1257,33 +1272,31 @@ abstract class TextureRetained extends NodeComponentRetained {
* BufferedImage
*/
void reloadTextureImage(Canvas3D cv, int face, int level,
- ImageComponentRetained image, int numLevels) {
-
- //System.out.println("Texture.reloadTextureImage: face= " + face + " level= " + level);
-
- //System.out.println("...image = "+image+" image.storedFormat = "+image.storedYupFormat+" image.imageYup = "+image.imageYup+" texture - "+this);
-
- //System.out.println("....imageYupAllocated= " + image.imageYupAllocated);
-
- updateTextureImage(cv, face, numLevels, level, format,
- image.storedYupFormat,
- image.width, image.height,
- boundaryWidth, image.imageYup);
-
- // Now take care of the RenderedImage case. Note, if image
- // is a RenderedImage, then imageYup will be null
-
- if (image.imageYupClass == ImageComponentRetained.RENDERED_IMAGE) {
-
- // System.out.println("==========. subImage");
+ ImageComponentRetained image, int numLevels) {
+
+ boolean useAsRaster = isUseAsRaster();
+ ImageComponentRetained.ImageData imageData = image.getImageData(useAsRaster);
+
+ updateTextureImage(cv,
+ face, numLevels, level,
+ format, image.getImageFormatTypeIntValue(useAsRaster),
+ imageData.getWidth(), imageData.getHeight(),
+ boundaryWidth, image.getImageDataTypeIntValue(),
+ imageData.get());
+
+ // Now take care of the RenderedImage (byRef and yUp) case. Note, if image
+ // is a RenderedImage ( byRef and yUp), then imageData will be null
+
+ if (imageData == null) {
+ // System.out.println("==========. subImage");
// Download all the tiles for this texture
int xoffset = 0, yoffset = 0;
int tmpw = image.width;
int tmph = image.height;
- int endXTile = image.minTileX * image.tilew + image.tileGridXOffset+image.tilew;
- int endYTile = image.minTileY * image.tileh + image.tileGridYOffset+image.tileh;
- int curw = (endXTile - image.minX);
- int curh = (endYTile - image.minY);
+ int endXTile = image.tilew;
+ int endYTile = image.tileh;
+ int curw = endXTile;
+ int curh = endYTile;
if (tmpw < curw) {
curw = tmpw;
@@ -1296,23 +1309,23 @@ abstract class TextureRetained extends NodeComponentRetained {
int startw = curw;
int imageXOffset = image.tilew - curw;
int imageYOffset = image.tileh - curh;
- for (int m = image.minTileY; m < image.minTileY+image.numYTiles; m++) {
+ for (int m = 0; m < image.numYTiles; m++) {
xoffset = 0;
tmpw = width;
curw = startw;
imageXOffset = image.tilew - curw;
- for (int n = image.minTileX;
- n < image.minTileX+image.numXTiles; n++) {
+ for (int n = 0; n < image.numXTiles; n++) {
java.awt.image.Raster ras;
- ras = image.bImage[0].getTile(n,m);
- byte[] tmpImage = ((DataBufferByte)ras.getDataBuffer()).getData();
- updateTextureSubImage(cv, face,
- level, xoffset, yoffset, format,
- image.storedYupFormat,
- imageXOffset, imageYOffset,
- image.tilew,
- curw, curh,
- tmpImage);
+ ras = ((RenderedImage)image.getRefImage(0)).getTile(n,m);
+ byte[] data = ((DataBufferByte)ras.getDataBuffer()).getData();
+ updateTextureSubImage(cv, face,
+ level, xoffset, yoffset, format,
+ image.getImageFormatTypeIntValue(false),
+ imageXOffset, imageYOffset,
+ image.tilew,
+ curw, curh,
+ ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY,
+ (Object) data);
xoffset += curw;
imageXOffset = 0;
tmpw -= curw;
@@ -1354,57 +1367,43 @@ abstract class TextureRetained extends NodeComponentRetained {
// " width= " + width + " height= " + height +
// " format= " + format);
-
- if (image.imageYupClass == ImageComponentRetained.BUFFERED_IMAGE) {
-
- int xoffset = x - image.minX;
- int yoffset = y - image.minY;
-
- byte[] imageData;
- if (image.imageYupAllocated) {
- imageData = image.imageYup;
- yoffset = image.height - yoffset - height;
-
- } else {
- // Fix issue 132
- imageData = ((DataBufferByte)
- ((BufferedImage)image.bImage[0]).getRaster().getDataBuffer()).getData();
-
- // based on the yUp flag in the associated ImageComponent,
- // adjust the yoffset
-
- if (!image.yUp) {
- yoffset = image.height - yoffset - height;
- }
- }
-
- updateTextureSubImage(cv, face, level,
- xoffset, yoffset,
- format, image.storedYupFormat,
- xoffset, yoffset,
- image.width, width, height, imageData);
- } else {
+ ImageComponentRetained.ImageData imageData = image.getImageData(isUseAsRaster());
+ if(imageData != null) {
+ int xoffset = x;
+ int yoffset = y;
+
+ // TODO Check this logic : If !yUp adjust yoffset --- Chien
+ if (!image.yUp) {
+ yoffset = image.height - yoffset - height;
+ }
+
+ updateTextureSubImage(cv, face, level,
+ xoffset, yoffset,
+ format, image.getImageFormatTypeIntValue(false),
+ xoffset, yoffset,
+ image.width, width, height,
+ image.getImageDataTypeIntValue(),
+ imageData.get());
+
+ } else {
// System.out.println("RenderedImage subImage update");
-
// determine the first tile of the image
float mt;
- int xoff = image.tileGridXOffset;
- int yoff = image.tileGridYOffset;
int minTileX, minTileY;
- int rx = x + image.minX; // x offset in RenderedImage
- int ry = y + image.minY; // y offset in RenderedImage
+ int rx = x;
+ int ry = y;
- mt = (float)(rx - xoff) / (float)image.tilew;
+ mt = (float)(rx) / (float)image.tilew;
if (mt < 0) {
minTileX = (int)(mt - 1);
} else {
minTileX = (int)mt;
}
- mt = (float)(ry - yoff) / (float)image.tileh;
+ mt = (float)(ry) / (float)image.tileh;
if (mt < 0) {
minTileY = (int)(mt - 1);
} else {
@@ -1413,8 +1412,8 @@ abstract class TextureRetained extends NodeComponentRetained {
// determine the pixel offset of the upper-left corner of the
// first tile
- int startXTile = minTileX * image.tilew + xoff;
- int startYTile = minTileY * image.tilew + yoff;
+ int startXTile = minTileX * image.tilew;
+ int startYTile = minTileY * image.tilew;
// image dimension in the first tile
@@ -1466,7 +1465,6 @@ abstract class TextureRetained extends NodeComponentRetained {
}
java.awt.image.Raster ras;
- byte[] imageData;
int textureX = x; // x offset in the texture
int textureY = y; // y offset in the texture
@@ -1480,14 +1478,16 @@ abstract class TextureRetained extends NodeComponentRetained {
for (int xTile = minTileX; xTile < minTileX + numXTiles;
xTile++) {
- ras = image.bImage[0].getTile(xTile, yTile);
- imageData = ((DataBufferByte)ras.getDataBuffer()).getData();
-
- updateTextureSubImage(cv, face, level,
- textureX, textureY,
- format, image.storedYupFormat,
- imgX, imgY, image.tilew, curw, curh, imageData);
+ ras = ((RenderedImage)image.getRefImage(0)).getTile(xTile, yTile);
+ byte[] data = ((DataBufferByte)ras.getDataBuffer()).getData();
+ updateTextureSubImage(cv, face, level,
+ textureX, textureY,
+ format, image.getImageFormatTypeIntValue(false),
+ imgX, imgY,
+ image.tilew, curw, curh,
+ ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY,
+ (Object)data);
// move to the next tile in x direction
@@ -1690,7 +1690,7 @@ abstract class TextureRetained extends NodeComponentRetained {
return;
}
- if (cv.useSharedCtx && cv.screen.renderer.sharedCtx != 0) {
+ if (cv.useSharedCtx && cv.screen.renderer.sharedCtx != null) {
if ((resourceCreationMask & cv.screen.renderer.rendererBit) == 0) {
reloadTexture = true;
@@ -1845,7 +1845,7 @@ abstract class TextureRetained extends NodeComponentRetained {
width,
height,
boundaryWidth);
- mirror = (Texture2DRetained)tex.retained;;
+ mirror = (Texture2DRetained)tex.retained;
}
((TextureRetained)mirror).objectId = -1;
@@ -1950,9 +1950,9 @@ abstract class TextureRetained extends NodeComponentRetained {
images[j][0].addUser(mirrorTexture);
}
- for (int i = 1; i < mirrorTexture.maxLevels; i++) {
- mirrorTexture.images[j][i] = createNextLevelImage(
- (mirrorTexture.images[j][i-1]));
+ for (int i = 1; i < mirrorTexture.maxLevels; i++) {
+ mirrorTexture.images[j][i] =
+ mirrorTexture.images[j][i-1].createNextLevelMipMapImage();
}
}
}
@@ -1995,7 +1995,6 @@ abstract class TextureRetained extends NodeComponentRetained {
if (info.updateMask == 0) {
// this update info is done, remove it
// from the update list
- VirtualUniverse.mc.addFreeImageUpdateInfo(info);
imageUpdateInfo[k][i].remove(j);
}
}
@@ -2025,8 +2024,7 @@ abstract class TextureRetained extends NodeComponentRetained {
imageUpdateInfo[face][level] = new ArrayList();
}
- //info = mirrorTa.getFreeImageUpdateInfo();
- info = VirtualUniverse.mc.getFreeImageUpdateInfo();
+ info = new ImageComponentUpdateInfo();
if (arg == null) {
@@ -2045,8 +2043,6 @@ abstract class TextureRetained extends NodeComponentRetained {
if (info.entireImage) {
// the entire image update supercedes all the subimage update;
// hence, remove all the existing updates from the list
- VirtualUniverse.mc.addFreeImageUpdateInfo(
- imageUpdateInfo[face][level]);
imageUpdateInfo[face][level].clear();
// reset the update prune mask for this level
@@ -2308,8 +2304,6 @@ abstract class TextureRetained extends NodeComponentRetained {
for (int face = 0; face < numFaces; face++) {
for (int level = 0; level < maxLevels; level++) {
if (imageUpdateInfo[face][level] != null) {
- VirtualUniverse.mc.addFreeImageUpdateInfo(
- imageUpdateInfo[face][level]);
imageUpdateInfo[face][level].clear();
}
}
@@ -2358,110 +2352,6 @@ abstract class TextureRetained extends NodeComponentRetained {
resourceCreationMask = 0x0;
}
- final ImageComponentRetained createNextLevelImage(
- ImageComponentRetained oImage) {
-
- int xScale, yScale, nWidth, nHeight;
- ImageComponentRetained nImage = null;
-
- if (oImage.width > 1) {
- nWidth = oImage.width >> 1;
- xScale = 2;
- } else {
- nWidth = 1;
- xScale = 1;
- }
- if (oImage.height > 1) {
- nHeight = oImage.height >> 1;
- yScale = 2;
- } else {
- nHeight = 1;
- yScale = 1;
- }
-
- int bytesPerPixel = oImage.bytesPerYupPixelStored;
-
- if (oImage instanceof ImageComponent2DRetained) {
-
- nImage = new ImageComponent2DRetained();
- nImage.processParams(oImage.format, nWidth, nHeight, 1);
- nImage.imageYup = new byte[nWidth * nHeight * bytesPerPixel];
- nImage.storedYupFormat = nImage.internalFormat;
- nImage.bytesPerYupPixelStored = bytesPerPixel;
- scaleImage(nWidth, nHeight, xScale, yScale, oImage.width, 0, 0,
- bytesPerPixel, nImage.imageYup, oImage.imageYup);
-
- } else { //oImage instanceof ImageComponent3DRetained
-
- int depth = ((ImageComponent3DRetained)oImage).depth;
- nImage = new ImageComponent3DRetained();
- nImage.processParams(oImage.format, nWidth, nHeight, depth);
- nImage.imageYup = new byte[nWidth * nHeight * bytesPerPixel];
- nImage.storedYupFormat = nImage.internalFormat;
- nImage.bytesPerYupPixelStored = bytesPerPixel;
-
- for (int i = 0; i < depth; i++) {
- scaleImage(nWidth, nHeight, xScale, yScale, oImage.width,
- i * nWidth * nHeight * bytesPerPixel,
- i * oImage.width * oImage.height * bytesPerPixel,
- bytesPerPixel, nImage.imageYup, oImage.imageYup);
- }
- }
- return nImage;
- }
-
- final void scaleImage(int nWidth, int nHeight, int xScale, int yScale,
- int oWidth, int nStart, int oStart, int bytesPerPixel,
- byte[] nData, byte[] oData) {
-
- int nOffset = 0;
- int oOffset = 0;
- int oLineIncr = bytesPerPixel * oWidth;
- int oPixelIncr = bytesPerPixel << 1;
-
- if (yScale == 1) {
- for (int x = 0; x < nWidth; x++) {
- for (int k = 0; k < bytesPerPixel; k++) {
- nData[nStart + nOffset + k] = (byte)
- (((int)(oData[oStart + oOffset + k] & 0xff) +
- (int)(oData[oStart + oOffset + k
- + bytesPerPixel] & 0xff) + 1) >> 1);
- }
- nOffset += bytesPerPixel;
- oOffset += oPixelIncr;
- }
- } else if (xScale == 1) {
- for (int y = 0; y < nHeight; y++) {
- for (int k = 0; k < bytesPerPixel; k++) {
- nData[nStart + nOffset + k] = (byte)
- (((int)(oData[oStart + oOffset + k] & 0xff) +
- (int)(oData[oStart + oOffset + k
- + oLineIncr] & 0xff) + 1) >> 1);
- }
- nOffset += bytesPerPixel;
- oOffset += oLineIncr;
- }
- } else {
- for (int y = 0; y < nHeight; y++) {
- for (int x = 0; x < nWidth; x++) {
- for (int k = 0; k < bytesPerPixel; k++) {
- nData[nStart + nOffset + k] = (byte)
- (((int)(oData[oStart + oOffset + k] & 0xff) +
- (int)(oData[oStart + oOffset + k
- + bytesPerPixel] & 0xff) +
- (int)(oData[oStart + oOffset + k
- + oLineIncr] & 0xff) +
- (int)(oData[oStart + oOffset + k + oLineIncr +
- + bytesPerPixel] & 0xff) + 2) >> 2);
- }
- nOffset += bytesPerPixel;
- oOffset += oPixelIncr;
- }
- oOffset += oLineIncr;
- }
- }
- }
-
void incTextureBinRefCount(TextureBin tb) {
ImageComponentRetained image;
@@ -2523,7 +2413,7 @@ abstract class TextureRetained extends NodeComponentRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.TEXTURE_CHANGED;
createMessage.universe = null;
@@ -2535,7 +2425,7 @@ abstract class TextureRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.TEXTURE_CHANGED;
@@ -2554,35 +2444,6 @@ abstract class TextureRetained extends NodeComponentRetained {
}
- protected void finalize() {
-
- if (objectId > 0) {
- // memory not yet free
- // send a message to the request renderer
- synchronized (VirtualUniverse.mc.contextCreationLock) {
- boolean found = false;
-
- for (Enumeration e = Screen3D.deviceRendererMap.elements();
- e.hasMoreElements(); ) {
- Renderer rdr = (Renderer) e.nextElement();
- J3dMessage renderMessage = VirtualUniverse.mc.getMessage();
- renderMessage.threads = J3dThread.RENDER_THREAD;
- renderMessage.type = J3dMessage.RENDER_IMMEDIATE;
- renderMessage.universe = null;
- renderMessage.view = null;
- renderMessage.args[0] = null;
- renderMessage.args[1] = new Integer(objectId);
- renderMessage.args[2] = "2D";
- rdr.rendererStructure.addMessage(renderMessage);
- }
- objectId = -1;
- }
-
- VirtualUniverse.mc.setWorkForRequestRenderer();
- }
-
- }
-
void handleFrequencyChange(int bit) {
switch (bit) {
case Texture.ALLOW_ENABLE_WRITE:
@@ -2594,5 +2455,13 @@ abstract class TextureRetained extends NodeComponentRetained {
break;
}
}
-}
+
+ void setUseAsRaster(boolean useAsRaster) {
+ this.useAsRaster = useAsRaster;
+ }
+
+ boolean isUseAsRaster() {
+ return this.useAsRaster;
+ }
+}
diff --git a/src/classes/share/javax/media/j3d/TextureUnitState.java b/src/classes/share/javax/media/j3d/TextureUnitState.java
index ced1e88..162a301 100644
--- a/src/classes/share/javax/media/j3d/TextureUnitState.java
+++ b/src/classes/share/javax/media/j3d/TextureUnitState.java
@@ -126,6 +126,15 @@ public class TextureUnitState extends NodeComponent {
* texture attributes
* @param texCoordGeneration object that specifies the texture coordinate
* generation parameters
+ *
+ * @exception IllegalSharingException if this TextureUnitState is live and
+ * the specified texture refers to an ImageComponent2D that is being used
+ * by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalSharingException if this TextureUnitState is
+ * being used by an immediate mode context and
+ * the specified texture refers to an ImageComponent2D that is being used
+ * by a Canvas3D as an off-screen buffer.
*/
public void set(Texture texture,
TextureAttributes textureAttributes,
@@ -135,6 +144,17 @@ public class TextureUnitState extends NodeComponent {
if (!this.getCapability(ALLOW_STATE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("TextureUnitState0"));
+ // Do illegal sharing check
+ if(texture != null) {
+ TextureRetained texRetained = (TextureRetained)texture.retained;
+ ImageComponent[] images = texRetained.getImages();
+ if(images != null) {
+ for(int i=0; i<images.length; i++) {
+ validateImageIllegalSharing(images[i]);
+ }
+ }
+ }
+
((TextureUnitStateRetained)this.retained).setTextureUnitState(
texture, textureAttributes, texCoordGeneration);
}
@@ -143,16 +163,38 @@ public class TextureUnitState extends NodeComponent {
* Sets the texture object to the specified object.
* Setting it to null disables texture mapping for the
* texture unit corresponding to this TextureUnitState object.
+ *
* @param texture object that specifies the desired texture
* map and texture parameters
+ *
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalSharingException if this TextureUnitState is live and
+ * the specified texture refers to an ImageComponent2D that is being used
+ * by a Canvas3D as an off-screen buffer.
+ *
+ * @exception IllegalSharingException if this TextureUnitState is
+ * being used by an immediate mode context and
+ * the specified texture refers to an ImageComponent2D that is being used
+ * by a Canvas3D as an off-screen buffer.
*/
public void setTexture(Texture texture) {
if (isLiveOrCompiled())
if (!this.getCapability(ALLOW_STATE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("TextureUnitState0"));
+ // Do illegal sharing check
+ if(texture != null) {
+ TextureRetained texRetained = (TextureRetained)texture.retained;
+ ImageComponent[] images = texRetained.getImages();
+ if(images != null) {
+ for(int i=0; i<images.length; i++) {
+ validateImageIllegalSharing(images[i]);
+ }
+ }
+ }
+
((TextureUnitStateRetained)this.retained).setTexture(texture);
}
diff --git a/src/classes/share/javax/media/j3d/TextureUnitStateRetained.java b/src/classes/share/javax/media/j3d/TextureUnitStateRetained.java
index ffadb2a..ccc87c8 100644
--- a/src/classes/share/javax/media/j3d/TextureUnitStateRetained.java
+++ b/src/classes/share/javax/media/j3d/TextureUnitStateRetained.java
@@ -142,8 +142,6 @@ class TextureUnitStateRetained extends NodeComponentRetained {
return (texGen == null ? null : (TexCoordGeneration)texGen.source);
}
- native void updateTextureUnitState(long ctx, int unitIndex, boolean enableFlag);
-
void updateNative(int unitIndex, Canvas3D cv,
boolean reload, boolean simulate) {
@@ -176,7 +174,7 @@ class TextureUnitStateRetained extends NodeComponentRetained {
return;
} else {
- updateTextureUnitState(cv.ctx, unitIndex, true);
+ Pipeline.getPipeline().updateTextureUnitState(cv.ctx, unitIndex, true);
}
// reload is needed in a multi-texture case to bind the
@@ -499,9 +497,8 @@ class TextureUnitStateRetained extends NodeComponentRetained {
((texGen == null) || (texGen.isStatic())));
}
- /*
+ // Issue 209 - enable this method (was previously commented out)
// Simply pass along to the NodeComponent
-
void compile (CompileState compState) {
setCompiled();
@@ -512,7 +509,6 @@ class TextureUnitStateRetained extends NodeComponentRetained {
if (texGen != null)
texGen.compile(compState);
}
- */
boolean equals(TextureUnitStateRetained ts) {
return ((ts == this) ||
@@ -557,7 +553,7 @@ class TextureUnitStateRetained extends NodeComponentRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.TEXTURE_UNIT_STATE_CHANGED;
createMessage.universe = null;
@@ -569,7 +565,7 @@ class TextureUnitStateRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.TEXTURE_UNIT_STATE_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/TimerThread.java b/src/classes/share/javax/media/j3d/TimerThread.java
index c3dd474..657e900 100644
--- a/src/classes/share/javax/media/j3d/TimerThread.java
+++ b/src/classes/share/javax/media/j3d/TimerThread.java
@@ -38,8 +38,9 @@ class TimerThread extends Thread {
private WakeupOnElapsedTime soundSchedCond =
new WakeupOnElapsedTime(120000); // every 2 minutes
- private boolean running = true;
- private volatile boolean waiting = false;
+ private volatile boolean running = true;
+ private boolean waiting = false;
+ private boolean ready = false;
TimerThread(ThreadGroup t) {
super(t, "J3D-TimerThread");
@@ -119,20 +120,27 @@ class TimerThread extends Thread {
synchronized void runMonitor(int action, long waitTime) {
switch (action) {
case WAIT:
- try {
- if (running) {
- waiting = true;
- if (waitTime < 0) {
- wait();
- } else {
- wait(waitTime);
- }
- }
- } catch (InterruptedException e) {}
- waiting = false;
- break;
+ // Issue 308 - wait unless ready flag already set
+ // Note that we can't loop since we need to be able to timeout
+ // after "waitTime" msec
+ if (running && !ready) {
+ waiting = true;
+ try {
+ if (waitTime < 0) {
+ wait();
+ } else {
+ wait(waitTime);
+ }
+ } catch (InterruptedException e) {}
+ waiting = false;
+ }
+ ready = false;
+ break;
case NOTIFY:
- notify();
+ ready = true;
+ if (waiting) {
+ notify();
+ }
break;
case STOP:
running = false;
diff --git a/src/classes/share/javax/media/j3d/Transform3D.java b/src/classes/share/javax/media/j3d/Transform3D.java
index 386c03d..e36672a 100644
--- a/src/classes/share/javax/media/j3d/Transform3D.java
+++ b/src/classes/share/javax/media/j3d/Transform3D.java
@@ -117,6 +117,8 @@ public class Transform3D {
private static final int ROTSCALESVD_DIRTY = SCALE_BIT |
ROTATION_BIT |
SVD_BIT;
+ private static final int ALL_DIRTY = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+
private int dirtyBits;
boolean autoNormalize = false; // Don't auto normalize by default
@@ -541,6 +543,27 @@ public class Transform3D {
return this.autoNormalize;
}
+ /**
+ * Transforms the point parameter with this transform and
+ * places the result into pointOut. The fourth element of the
+ * point input paramter is assumed to be one.
+ * @param point the input point to be transformed
+ * @param pointOut the transformed point
+ */
+ void transform(Point3d point, Point4d pointOut) {
+
+ pointOut.x = mat[0]*point.x + mat[1]*point.y +
+ mat[2]*point.z + mat[3];
+ pointOut.y = mat[4]*point.x + mat[5]*point.y +
+ mat[6]*point.z + mat[7];
+ pointOut.z = mat[8]*point.x + mat[9]*point.y +
+ mat[10]*point.z + mat[11];
+ pointOut.w = mat[12]*point.x + mat[13]*point.y +
+ mat[14]*point.z + mat[15];
+ }
+
+
+
private static final boolean almostZero(double a) {
return ((a < EPSILON_ABSOLUTE) && (a > -EPSILON_ABSOLUTE));
}
@@ -576,17 +599,6 @@ public class Transform3D {
}
}
- // Fix for Issue 167 -- don't classify matrices with Infinity or NaN values
- // as affine
- private final boolean isInfOrNaN() {
- for (int i = 0; i < 16; i++) {
- if (Double.isNaN(mat[i]) || Double.isInfinite(mat[i])) {
- return true;
- }
- }
- return false;
- }
-
private final void classifyAffine() {
if (!isInfOrNaN() &&
almostZero(mat[12]) &&
@@ -774,7 +786,7 @@ public class Transform3D {
mat[i] += t1.mat[i];
}
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -792,7 +804,7 @@ public class Transform3D {
mat[i] = t1.mat[i] + t2.mat[i];
}
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -810,7 +822,7 @@ public class Transform3D {
mat[i] -= t1.mat[i];
}
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -829,7 +841,7 @@ public class Transform3D {
mat[i] = t1.mat[i] - t2.mat[i];
}
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -868,7 +880,7 @@ public class Transform3D {
mat[14] = mat[11];
mat[11] = temp;
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -900,7 +912,7 @@ public class Transform3D {
mat[14] = t1.mat[11];
mat[15] = t1.mat[15];
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -940,6 +952,11 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(q1)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
dirtyBits = CLASSIFY_BIT | SCALE_BIT | ROTATION_BIT;
type = RIGID | CONGRUENT | AFFINE | ORTHO;
@@ -974,6 +991,12 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(q1)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
dirtyBits = CLASSIFY_BIT | SCALE_BIT | ROTATION_BIT;
type = RIGID | CONGRUENT | AFFINE | ORTHO;
}
@@ -1002,11 +1025,8 @@ public class Transform3D {
mat[9] = m1.m21*scales[1];
mat[10]= m1.m22*scales[2];
- // only affine bit is preserved
- // SCALE_BIT is clear in the above computeScales() so
- // there is no need to set it dirty again.
- dirtyBits |= (RIGID_BIT | CONGRUENT_BIT| ORTHO_BIT|
- CLASSIFY_BIT | ROTSCALESVD_DIRTY);
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
// the matrix pass in may not normalize
@@ -1038,8 +1058,8 @@ public class Transform3D {
mat[9] = m1.m21*scales[1];
mat[10]= m1.m22*scales[2];
- dirtyBits |= (RIGID_BIT | CONGRUENT_BIT| ORTHO_BIT|
- CLASSIFY_BIT | ROTSCALESVD_DIRTY);
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -1072,7 +1092,13 @@ public class Transform3D {
mat[6] = (2.0*(q1.y*q1.z - q1.w*q1.x))*scales[2];
mat[10] = (1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y)*scales[2];
- dirtyBits |= CLASSIFY_BIT | ROTATION_BIT;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(q1)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
+ dirtyBits |= CLASSIFY_BIT | ROTATION_BIT;
dirtyBits &= ~ORTHO_BIT;
type |= ORTHO;
type &= ~(ORTHOGONAL|IDENTITY|SCALE|TRANSLATION|SCALE|ZERO);
@@ -1104,10 +1130,16 @@ public class Transform3D {
mat[6] = (2.0*(q1.y*q1.z - q1.w*q1.x))*scales[2];
mat[10] = (1.0 - 2.0*q1.x*q1.x - 2.0*q1.y*q1.y)*scales[2];
- dirtyBits |= CLASSIFY_BIT | ROTATION_BIT;
- dirtyBits &= ~ORTHO_BIT;
- type |= ORTHO;
- type &= ~(ORTHOGONAL|IDENTITY|SCALE|TRANSLATION|SCALE|ZERO);
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(q1)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
+ dirtyBits |= CLASSIFY_BIT | ROTATION_BIT;
+ dirtyBits &= ~ORTHO_BIT;
+ type |= ORTHO;
+ type &= ~(ORTHOGONAL|IDENTITY|SCALE|TRANSLATION|SCALE|ZERO);
}
@@ -1157,7 +1189,13 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
- type = CONGRUENT | AFFINE | RIGID | ORTHO;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(a1)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
+ type = CONGRUENT | AFFINE | RIGID | ORTHO;
dirtyBits = CLASSIFY_BIT | ROTATION_BIT | SCALE_BIT;
}
}
@@ -1209,6 +1247,12 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(a1)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
type = CONGRUENT | AFFINE | RIGID | ORTHO;
dirtyBits = CLASSIFY_BIT | ROTATION_BIT | SCALE_BIT;
}
@@ -1267,6 +1311,11 @@ public class Transform3D {
mat[10] = (t * az * az + cosTheta)*scales[2];
}
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(a1)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
// Rigid remain rigid, congruent remain congruent after
// set rotation
@@ -1329,6 +1378,11 @@ public class Transform3D {
mat[10] = (t * az * az + cosTheta)*scales[2];
}
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(a1)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
// Rigid remain rigid, congruent remain congruent after
// set rotation
@@ -1369,6 +1423,12 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(angle)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
type = CONGRUENT | AFFINE | RIGID | ORTHO;
dirtyBits = CLASSIFY_BIT | ROTATION_BIT | SCALE_BIT;
}
@@ -1403,6 +1463,12 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(angle)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
type = CONGRUENT | AFFINE | RIGID | ORTHO;
dirtyBits = CLASSIFY_BIT | ROTATION_BIT | SCALE_BIT;
}
@@ -1438,6 +1504,12 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(angle)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
type = CONGRUENT | AFFINE | RIGID | ORTHO;
dirtyBits = CLASSIFY_BIT | ROTATION_BIT | SCALE_BIT;
}
@@ -1455,6 +1527,12 @@ public class Transform3D {
mat[8] = 0.0; mat[9] = 0.0; mat[10] = 1.0; mat[11] = trans.z;
mat[12] = 0.0; mat[13] = 0.0; mat[14] = 0.0; mat[15] = 1.0;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(trans)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
type = CONGRUENT | AFFINE | RIGID | ORTHO;
dirtyBits = CLASSIFY_BIT | ROTATION_BIT | SCALE_BIT;
}
@@ -1471,6 +1549,11 @@ public class Transform3D {
mat[8] = 0.0; mat[9] = 0.0; mat[10] = 1.0; mat[11] = trans.z;
mat[12] = 0.0; mat[13] = 0.0; mat[14] = 0.0; mat[15] = 1.0;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(trans)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
type = CONGRUENT | AFFINE | RIGID | ORTHO;
dirtyBits = CLASSIFY_BIT | ROTATION_BIT | SCALE_BIT;
@@ -1498,6 +1581,12 @@ public class Transform3D {
mat[9] = rot[7]*scale;
mat[10] = rot[8]*scale;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(scale)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
dirtyBits |= (CLASSIFY_BIT | RIGID_BIT | CONGRUENT_BIT | SVD_BIT);
dirtyBits &= ~SCALE_BIT;
}
@@ -1528,6 +1617,13 @@ public class Transform3D {
mat[8] = rot[6]*scale.x;
mat[9] = rot[7]*scale.y;
mat[10] = rot[8]*scale.z;
+
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(scale)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
dirtyBits |= (CLASSIFY_BIT | RIGID_BIT | CONGRUENT_BIT | SVD_BIT);
dirtyBits &= ~SCALE_BIT;
}
@@ -1568,9 +1664,8 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
- type = AFFINE | ORTHO;
- dirtyBits = CLASSIFY_BIT | CONGRUENT_BIT | RIGID_BIT |
- ROTATION_BIT;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
}
/**
@@ -1583,6 +1678,13 @@ public class Transform3D {
mat[3] = trans.x;
mat[7] = trans.y;
mat[11] = trans.z;
+
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(trans)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
// Only preserve CONGRUENT, RIGID, ORTHO
type &= ~(ORTHOGONAL|IDENTITY|SCALE|TRANSLATION|SCALE|ZERO);
dirtyBits |= CLASSIFY_BIT;
@@ -1599,6 +1701,13 @@ public class Transform3D {
mat[3] = trans.x;
mat[7] = trans.y;
mat[11] = trans.z;
+
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(trans)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
type &= ~(ORTHOGONAL|IDENTITY|SCALE|TRANSLATION|SCALE|ZERO);
dirtyBits |= CLASSIFY_BIT;
}
@@ -1636,8 +1745,9 @@ public class Transform3D {
mat[13] = 0.0;
mat[14] = 0.0;
mat[15] = 1.0;
- type = CONGRUENT | AFFINE | ORTHO;
- dirtyBits = CLASSIFY_BIT | ROTATION_BIT | RIGID_BIT;
+
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
}
/**
@@ -1673,8 +1783,8 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
- type = CONGRUENT | AFFINE | ORTHO;
- dirtyBits = CLASSIFY_BIT | ROTATION_BIT| RIGID_BIT;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
}
/**
@@ -1710,8 +1820,8 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
- type = CONGRUENT | AFFINE | ORTHO;
- dirtyBits = CLASSIFY_BIT | ROTATION_BIT | RIGID_BIT;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
}
/**
@@ -1742,9 +1852,8 @@ public class Transform3D {
mat[14]=0.0;
mat[15]=1.0;
- type = AFFINE;
- dirtyBits = ORTHO_BIT | CONGRUENT_BIT | RIGID_BIT |
- CLASSIFY_BIT | ROTSCALESVD_DIRTY;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
// input matrix may not normalize
@@ -1780,9 +1889,8 @@ public class Transform3D {
mat[14]=0.0;
mat[15]=1.0;
- type = AFFINE;
- dirtyBits = ORTHO_BIT | CONGRUENT_BIT | RIGID_BIT |
- CLASSIFY_BIT | ROTSCALESVD_DIRTY;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -1817,9 +1925,8 @@ public class Transform3D {
mat[14]=0.0;
mat[15]=1.0;
- type = AFFINE;
- dirtyBits = ORTHO_BIT | CONGRUENT_BIT | RIGID_BIT |
- CLASSIFY_BIT | ROTSCALESVD_DIRTY;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -1849,7 +1956,7 @@ public class Transform3D {
}
}
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -1920,7 +2027,7 @@ public class Transform3D {
mat[14] = matrix[14];
mat[15] = matrix[15];
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -1952,7 +2059,7 @@ public class Transform3D {
mat[14] = matrix[14];
mat[15] = matrix[15];
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -1984,7 +2091,7 @@ public class Transform3D {
mat[14] = m1.m32;
mat[15] = m1.m33;
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -2016,7 +2123,7 @@ public class Transform3D {
mat[14] = m1.m32;
mat[15] = m1.m33;
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -2049,9 +2156,8 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
- type = AFFINE;
- dirtyBits = ORTHO_BIT | CONGRUENT_BIT | RIGID_BIT |
- CLASSIFY_BIT | ROTSCALESVD_DIRTY;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -2084,9 +2190,8 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
- type = AFFINE;
- dirtyBits = ORTHO_BIT | CONGRUENT_BIT | RIGID_BIT |
- CLASSIFY_BIT | ROTSCALESVD_DIRTY;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -2139,6 +2244,12 @@ public class Transform3D {
mat[14] = 0.0;
mat[15] = 1.0;
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(euler)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
+
type = AFFINE | CONGRUENT | RIGID | ORTHO;
dirtyBits = CLASSIFY_BIT | SCALE_BIT | ROTATION_BIT;
}
@@ -2968,7 +3079,7 @@ public class Transform3D {
luBacksubstitution(tmp, row_perm, this.mat);
type = 0;
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
}
@@ -3314,6 +3425,12 @@ public class Transform3D {
scales = new double[3];
scales[0] = scales[1] = scales[2] = scale;
+
+ // Issue 253: set all dirty bits if input is infinity or NaN
+ if (isInfOrNaN(x) || isInfOrNaN(y) || isInfOrNaN(z) || isInfOrNaN(scale)) {
+ dirtyBits = ALL_DIRTY;
+ return;
+ }
type = AFFINE | CONGRUENT | ORTHO;
dirtyBits = CLASSIFY_BIT | ROTATION_BIT | RIGID_BIT;
@@ -3329,7 +3446,7 @@ public class Transform3D {
for (int i=0 ; i<16 ; i++) {
mat[i] *= scalar;
}
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
}
/**
@@ -3342,7 +3459,7 @@ public class Transform3D {
for (int i=0 ; i<16 ; i++) {
mat[i] = t1.mat[i] * scalar;
}
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -3465,7 +3582,7 @@ public class Transform3D {
dirtyBits = ORTHO_BIT | CONGRUENT_BIT | RIGID_BIT |
CLASSIFY_BIT | ROTSCALESVD_DIRTY;
} else {
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
}
}
@@ -3668,7 +3785,7 @@ public class Transform3D {
dirtyBits = ORTHO_BIT | CONGRUENT_BIT | RIGID_BIT |
CLASSIFY_BIT | ROTSCALESVD_DIRTY;
} else {
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
}
}
@@ -3683,11 +3800,10 @@ public class Transform3D {
* @param t1 the matrix whose inverse is computed.
*/
public final void mulInverse(Transform3D t1) {
- Transform3D t2 = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D t2 = new Transform3D();
t2.autoNormalize = false;
t2.invert(t1);
this.mul(t2);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t2);
}
@@ -3698,11 +3814,10 @@ public class Transform3D {
* @param t2 the transform whose inverse is computed.
*/
public final void mulInverse(Transform3D t1, Transform3D t2) {
- Transform3D t3 = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D t3 = new Transform3D();
t3.autoNormalize = false;
t3.invert(t2);
this.mul(t1,t3);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t3);
}
/**
@@ -3712,11 +3827,10 @@ public class Transform3D {
* @param t2 the transform whose transpose is computed
*/
public final void mulTransposeRight(Transform3D t1, Transform3D t2) {
- Transform3D t3 = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D t3 = new Transform3D();
t3.autoNormalize = false;
t3.transpose(t2);
mul(t1, t3);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t3);
}
@@ -3727,11 +3841,10 @@ public class Transform3D {
* @param t2 the transform on the right hand side of the multiplication
*/
public final void mulTransposeLeft(Transform3D t1, Transform3D t2){
- Transform3D t3 = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D t3 = new Transform3D();
t3.autoNormalize = false;
t3.transpose(t1);
mul(t3, t2);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t3);
}
@@ -3743,15 +3856,13 @@ public class Transform3D {
* @param t2 the transform on the right hand side of the multiplication
*/
public final void mulTransposeBoth(Transform3D t1, Transform3D t2) {
- Transform3D t3 = VirtualUniverse.mc.getTransform3D(null);
- Transform3D t4 = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D t3 = new Transform3D();
+ Transform3D t4 = new Transform3D();
t3.autoNormalize = false;
t4.autoNormalize = false;
t3.transpose(t1);
t4.transpose(t2);
mul(t3, t4);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t3);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t4);
}
@@ -3765,6 +3876,10 @@ public class Transform3D {
* Note that the scale of the matrix is not altered by this method.
*/
public final void normalize() {
+ // Issue 253: Unable to normalize matrices with infinity or NaN
+ if (!isAffine() && isInfOrNaN()) {
+ return;
+ }
if ((dirtyBits & (ROTATION_BIT|SVD_BIT)) != 0) {
computeScaleRotation(true);
@@ -3813,6 +3928,11 @@ public class Transform3D {
* Note that the scale of the matrix is not altered by this method.
*/
public final void normalizeCP() {
+ // Issue 253: Unable to normalize matrices with infinity or NaN
+ if (!isAffine() && isInfOrNaN()) {
+ return;
+ }
+
if ((dirtyBits & SCALE_BIT) != 0) {
computeScales(false);
}
@@ -4189,9 +4309,9 @@ public class Transform3D {
mat[4] = m1.m10; mat[5] = m1.m11; mat[6] = m1.m12;
mat[8] = m1.m20; mat[9] = m1.m21; mat[10] = m1.m22;
- // keep affine bit
- dirtyBits |= (RIGID_BIT | CONGRUENT_BIT | ORTHO_BIT |
- CLASSIFY_BIT | ROTSCALESVD_DIRTY);
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
+
if (autoNormalize) {
normalize();
}
@@ -4208,9 +4328,10 @@ public class Transform3D {
mat[4] = m1.m10; mat[5] = m1.m11; mat[6] = m1.m12;
mat[8] = m1.m20; mat[9] = m1.m21; mat[10] = m1.m22;
- dirtyBits |= (RIGID_BIT | CONGRUENT_BIT | ORTHO_BIT |
- CLASSIFY_BIT | ROTSCALESVD_DIRTY);
- if (autoNormalize) {
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
+
+ if (autoNormalize) {
normalize();
}
}
@@ -4227,7 +4348,7 @@ public class Transform3D {
mat[i] = s*t1.mat[i] + t2.mat[i];
}
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -4246,7 +4367,7 @@ public class Transform3D {
mat[i] = s*mat[i] + t1.mat[i];
}
- dirtyBits = CLASSIFY_ALL_DIRTY | ROTSCALESVD_DIRTY;
+ dirtyBits = ALL_DIRTY;
if (autoNormalize) {
normalize();
@@ -4354,8 +4475,8 @@ public class Transform3D {
mat[12] = mat[13] = mat[14] = 0;
mat[15] = 1;
- type = AFFINE | CONGRUENT | RIGID | ORTHO;
- dirtyBits = CLASSIFY_BIT | ROTSCALESVD_DIRTY;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
}
@@ -4407,7 +4528,8 @@ public class Transform3D {
// Matrix is a projection transform
type = 0;
- dirtyBits = CLASSIFY_BIT | ROTSCALESVD_DIRTY;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
}
@@ -4454,7 +4576,8 @@ public class Transform3D {
// Matrix is a projection transform
type = 0;
- dirtyBits = CLASSIFY_BIT | ROTSCALESVD_DIRTY;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
}
@@ -4497,10 +4620,9 @@ public class Transform3D {
mat[1] = mat[2] = mat[4] = mat[6] = mat[8] =
mat[9] = mat[12] = mat[13] = mat[14] = 0;
mat[15] = 1;
- // Matrix is a projection transform
- type = AFFINE;
- dirtyBits = CLASSIFY_BIT | ROTSCALESVD_DIRTY | CONGRUENT_BIT |
- RIGID_BIT | ORTHO_BIT;
+
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
}
/**
@@ -5641,18 +5763,72 @@ public class Transform3D {
t.mat[9] = rot[7];
t.mat[10] = rot[8];
- t.type = ORTHOGONAL | RIGID | CONGRUENT| AFFINE | ORTHO;
- if ((dirtyBits & SVD_BIT) != 0) {
- t.dirtyBits = CLASSIFY_BIT | ROTSCALESVD_DIRTY;
- } else {
- t.dirtyBits = CLASSIFY_BIT | ROTATION_BIT | SCALE_BIT;
- }
+ // Issue 253: set all dirty bits
+ t.dirtyBits = ALL_DIRTY;
}
// somehow CanvasViewCache will directly modify mat[]
// instead of calling ortho(). So we need to reset dirty bit
final void setOrthoDirtyBit() {
- dirtyBits = CLASSIFY_BIT | ROTSCALESVD_DIRTY;
+ // Issue 253: set all dirty bits
+ dirtyBits = ALL_DIRTY;
type = 0;
}
+
+ // Fix for Issue 167 -- don't classify matrices with Infinity or NaN values
+ // as affine
+ private final boolean isInfOrNaN() {
+ for (int i = 0; i < 16; i++) {
+ if (Double.isNaN(mat[i]) || Double.isInfinite(mat[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Fix for Issue 253
+ // Methods to check input parameters for Infinity or NaN values
+ private final boolean isInfOrNaN(Quat4f q) {
+ return (Float.isNaN(q.x) || Float.isInfinite(q.x) ||
+ Float.isNaN(q.y) || Float.isInfinite(q.y) ||
+ Float.isNaN(q.z) || Float.isInfinite(q.z) ||
+ Float.isNaN(q.w) || Float.isInfinite(q.w));
+ }
+
+ private boolean isInfOrNaN(Quat4d q) {
+ return (Double.isNaN(q.x) || Double.isInfinite(q.x) ||
+ Double.isNaN(q.y) || Double.isInfinite(q.y) ||
+ Double.isNaN(q.z) || Double.isInfinite(q.z) ||
+ Double.isNaN(q.w) || Double.isInfinite(q.w));
+ }
+
+ private boolean isInfOrNaN(AxisAngle4f a) {
+ return (Float.isNaN(a.x) || Float.isInfinite(a.x) ||
+ Float.isNaN(a.y) || Float.isInfinite(a.y) ||
+ Float.isNaN(a.z) || Float.isInfinite(a.z) ||
+ Float.isNaN(a.angle) || Float.isInfinite(a.angle));
+ }
+
+ private boolean isInfOrNaN(AxisAngle4d a) {
+ return (Double.isNaN(a.x) || Double.isInfinite(a.x) ||
+ Double.isNaN(a.y) || Double.isInfinite(a.y) ||
+ Double.isNaN(a.z) || Double.isInfinite(a.z) ||
+ Double.isNaN(a.angle) || Double.isInfinite(a.angle));
+ }
+
+ private boolean isInfOrNaN(double val) {
+ return Double.isNaN(val) || Double.isInfinite(val);
+ }
+
+ private boolean isInfOrNaN(Vector3f v) {
+ return (Float.isNaN(v.x) || Float.isInfinite(v.x) ||
+ Float.isNaN(v.y) || Float.isInfinite(v.y) ||
+ Float.isNaN(v.z) || Float.isInfinite(v.z));
+ }
+
+ private boolean isInfOrNaN(Vector3d v) {
+ return (Double.isNaN(v.x) || Double.isInfinite(v.x) ||
+ Double.isNaN(v.y) || Double.isInfinite(v.y) ||
+ Double.isNaN(v.z) || Double.isInfinite(v.z));
+ }
}
diff --git a/src/classes/share/javax/media/j3d/TransformGroup.java b/src/classes/share/javax/media/j3d/TransformGroup.java
index 9290c03..6bf078c 100644
--- a/src/classes/share/javax/media/j3d/TransformGroup.java
+++ b/src/classes/share/javax/media/j3d/TransformGroup.java
@@ -182,9 +182,8 @@ public class TransformGroup extends Group {
void duplicateAttributes(Node originalNode, boolean forceDuplicate) {
super.duplicateAttributes(originalNode, forceDuplicate);
- Transform3D t = VirtualUniverse.mc.getTransform3D(null);
+ Transform3D t = new Transform3D();
((TransformGroupRetained) originalNode.retained).getTransform(t);
((TransformGroupRetained) retained).setTransform(t);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t);
}
}
diff --git a/src/classes/share/javax/media/j3d/TransformGroupRetained.java b/src/classes/share/javax/media/j3d/TransformGroupRetained.java
index 7ede29f..bca8aa4 100644
--- a/src/classes/share/javax/media/j3d/TransformGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/TransformGroupRetained.java
@@ -117,13 +117,13 @@ class TransformGroupRetained extends GroupRetained implements TargetsInterface
// this writeable transformGroup has a static transform
// merged into this node
- trans = VirtualUniverse.mc.getTransform3D(staticTransform.transform);
+ trans = new Transform3D(staticTransform.transform);
trans.mul(t1);
transform.setWithLock(trans);
} else {
- trans = VirtualUniverse.mc.getTransform3D(t1);
+ trans = new Transform3D(t1);
transform.setWithLock(t1);
}
@@ -137,7 +137,7 @@ class TransformGroupRetained extends GroupRetained implements TargetsInterface
throw new BadTransformException(J3dI18N.getString("ViewPlatformRetained0"));
}
- tchangeMessage = VirtualUniverse.mc.getMessage();
+ tchangeMessage = new J3dMessage();
tchangeMessage.type = J3dMessage.TRANSFORM_CHANGED;
tchangeMessage.threads = targetThreads;
tchangeMessage.args[1] = this;
@@ -534,7 +534,7 @@ class TransformGroupRetained extends GroupRetained implements TargetsInterface
// This is needed b/c super.setlive is called after inSharedGroup check.
inSharedGroup = s.inSharedGroup;
- trans = VirtualUniverse.mc.getTransform3D(null);
+ trans = new Transform3D();
transform.getWithLock(trans);
currentTransform.set(trans);
diff --git a/src/classes/share/javax/media/j3d/TransformStructure.java b/src/classes/share/javax/media/j3d/TransformStructure.java
index 5c16942..8320a6c 100644
--- a/src/classes/share/javax/media/j3d/TransformStructure.java
+++ b/src/classes/share/javax/media/j3d/TransformStructure.java
@@ -216,8 +216,6 @@ class TransformStructure extends J3dStructure implements ObjectUpdate {
for (i=0; i<tSize; i++) {
tg = tgs[i];
tg.currentTransform.set(t3ds[i]);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D,
- t3ds[i]);
synchronized(tg) { // synchronized with tg.set/clearLive
if(tg.perPathData != null) {
diff --git a/src/classes/share/javax/media/j3d/TransparencyAttributesRetained.java b/src/classes/share/javax/media/j3d/TransparencyAttributesRetained.java
index beb2ad7..8c4b6fd 100644
--- a/src/classes/share/javax/media/j3d/TransparencyAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/TransparencyAttributesRetained.java
@@ -215,22 +215,11 @@ class TransparencyAttributesRetained extends NodeComponentRetained {
}
}
- /**
- * These two native methods update the native context.
- */
- native void updateNative(long ctx,
- float alpha, int geometryType,
- int polygonMode,
- boolean lineAA, boolean pointAA,
- int transparencyMode,
- int srcBlendFunction,
- int dstBlendFunction);
-
- void updateNative(long ctx,
+ void updateNative(Context ctx,
float alpha, int geometryType, int polygonMode,
boolean lineAA,
boolean pointAA) {
- updateNative(ctx, alpha, geometryType, polygonMode,
+ Pipeline.getPipeline().updateTransparencyAttributes(ctx, alpha, geometryType, polygonMode,
lineAA, pointAA, transparencyMode,
srcBlendFunction, dstBlendFunction);
}
@@ -292,7 +281,7 @@ class TransparencyAttributesRetained extends NodeComponentRetained {
// Send to rendering attribute structure, regardless of
// whether there are users or not (alternate appearance case ..)
- J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
createMessage.type = J3dMessage.TRANSPARENCYATTRIBUTES_CHANGED;
createMessage.universe = null;
@@ -305,7 +294,7 @@ class TransparencyAttributesRetained extends NodeComponentRetained {
// System.out.println("univList.size is " + univList.size());
for(int i=0; i<univList.size(); i++) {
- createMessage = VirtualUniverse.mc.getMessage();
+ createMessage = new J3dMessage();
createMessage.threads = J3dThread.UPDATE_RENDER;
createMessage.type = J3dMessage.TRANSPARENCYATTRIBUTES_CHANGED;
diff --git a/src/classes/share/javax/media/j3d/TriangleArrayRetained.java b/src/classes/share/javax/media/j3d/TriangleArrayRetained.java
index 9969788..d64221d 100644
--- a/src/classes/share/javax/media/j3d/TriangleArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/TriangleArrayRetained.java
@@ -414,12 +414,12 @@ class TriangleArrayRetained extends GeometryArrayRetained {
int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
initialVertexIndex : initialCoordIndex);
- Point3d pnt0 = getPoint3d();
- Point3d pnt1 = getPoint3d();
- Point3d pnt2 = getPoint3d();
- Vector3d vec = getVector3d();
- Vector3d normal = getVector3d();
- Vector3d tmpvec = getVector3d();
+ Point3d pnt0 = new Point3d();
+ Point3d pnt1 = new Point3d();
+ Point3d pnt2 = new Point3d();
+ Vector3d vec = new Vector3d();
+ Vector3d normal = new Vector3d();
+ Vector3d tmpvec = new Vector3d();
double area;
double totalarea = 0;
@@ -463,12 +463,6 @@ class TriangleArrayRetained extends GeometryArrayRetained {
centroid.y *= area;
centroid.z *= area;
}
- freeVector3d(tmpvec);
- freeVector3d(vec);
- freeVector3d(normal);
- freePoint3d(pnt0);
- freePoint3d(pnt1);
- freePoint3d(pnt2);
}
int getClassType() {
diff --git a/src/classes/share/javax/media/j3d/TriangleFanArrayRetained.java b/src/classes/share/javax/media/j3d/TriangleFanArrayRetained.java
index e7035a6..7e24f77 100644
--- a/src/classes/share/javax/media/j3d/TriangleFanArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/TriangleFanArrayRetained.java
@@ -509,12 +509,12 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
// From Graphics Gems IV (pg5) and Graphics Gems II, Pg170
void computeCentroid() {
- Vector3d vec = getVector3d();
- Vector3d normal = getVector3d();
- Vector3d tmpvec = getVector3d();
- Point3d pnt0 = getPoint3d();
- Point3d pnt1 = getPoint3d();
- Point3d pnt2 = getPoint3d();
+ Vector3d vec = new Vector3d();
+ Vector3d normal = new Vector3d();
+ Vector3d tmpvec = new Vector3d();
+ Point3d pnt0 = new Point3d();
+ Point3d pnt1 = new Point3d();
+ Point3d pnt2 = new Point3d();
double area, totalarea = 0;
int end, replaceIndex, j, i = 0;
centroid.x = 0;
@@ -569,12 +569,6 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
centroid.y *= area;
centroid.z *= area;
}
- freeVector3d(tmpvec);
- freeVector3d(vec);
- freeVector3d(normal);
- freePoint3d(pnt0);
- freePoint3d(pnt1);
- freePoint3d(pnt2);
}
int getClassType() {
diff --git a/src/classes/share/javax/media/j3d/TriangleStripArrayRetained.java b/src/classes/share/javax/media/j3d/TriangleStripArrayRetained.java
index 8d06972..54347df 100644
--- a/src/classes/share/javax/media/j3d/TriangleStripArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/TriangleStripArrayRetained.java
@@ -527,12 +527,12 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
// From Graphics Gems IV (pg5) and Graphics Gems II, Pg170
void computeCentroid() {
- Point3d pnt0 = getPoint3d();
- Point3d pnt1 = getPoint3d();
- Point3d pnt2 = getPoint3d();
- Vector3d vec = getVector3d();
- Vector3d normal = getVector3d();
- Vector3d tmpvec = getVector3d();
+ Point3d pnt0 = new Point3d();
+ Point3d pnt1 = new Point3d();
+ Point3d pnt2 = new Point3d();
+ Vector3d vec = new Vector3d();
+ Vector3d normal = new Vector3d();
+ Vector3d tmpvec = new Vector3d();
double area, totalarea = 0;
int end, replaceIndex, j, i = 0;
@@ -594,13 +594,6 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
centroid.y *= area;
centroid.z *= area;
}
-
- freeVector3d(tmpvec);
- freeVector3d(vec);
- freeVector3d(normal);
- freePoint3d(pnt0);
- freePoint3d(pnt1);
- freePoint3d(pnt2);
}
diff --git a/src/classes/share/javax/media/j3d/VertexArrayRenderMethod.java b/src/classes/share/javax/media/j3d/VertexArrayRenderMethod.java
index c5ac846..a7c0bb0 100644
--- a/src/classes/share/javax/media/j3d/VertexArrayRenderMethod.java
+++ b/src/classes/share/javax/media/j3d/VertexArrayRenderMethod.java
@@ -20,18 +20,18 @@ package javax.media.j3d;
class VertexArrayRenderMethod implements RenderMethod {
- public boolean render(RenderMolecule rm, Canvas3D cv, int pass,
+ public boolean render(RenderMolecule rm, Canvas3D cv,
RenderAtomListInfo ra, int dirtyBits) {
-
+
GeometryArrayRetained geo = (GeometryArrayRetained)ra.geometry();
geo.setVertexFormat((rm.useAlpha && ((geo.vertexFormat &
GeometryArray.COLOR) != 0)),
rm.textureBin.attributeBin.ignoreVertexColors, cv.ctx);
if (rm.doInfinite) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
while (ra != null) {
- renderGeo(ra, rm, pass, cv);
+ renderGeo(ra, rm, cv);
ra = ra.next;
}
return true;
@@ -41,17 +41,17 @@ class VertexArrayRenderMethod implements RenderMethod {
while (ra != null) {
if (cv.ra == ra.renderAtom) {
if (cv.raIsVisible) {
- cv.updateState(pass, dirtyBits);
- renderGeo(ra, rm, pass, cv);
+ cv.updateState(dirtyBits);
+ renderGeo(ra, rm, cv);
isVisible = true;
}
}
else {
if (!VirtualUniverse.mc.viewFrustumCulling ||
ra.renderAtom.localeVwcBounds.intersect(cv.viewFrustum)) {
- cv.updateState(pass, dirtyBits);
+ cv.updateState(dirtyBits);
cv.raIsVisible = true;
- renderGeo(ra, rm, pass, cv);
+ renderGeo(ra, rm, cv);
isVisible = true;
}
else {
@@ -69,7 +69,7 @@ class VertexArrayRenderMethod implements RenderMethod {
return isVisible;
}
- void renderGeo(RenderAtomListInfo ra, RenderMolecule rm, int pass, Canvas3D cv) {
+ void renderGeo(RenderAtomListInfo ra, RenderMolecule rm, Canvas3D cv) {
GeometryArrayRetained geo;
boolean useAlpha;
@@ -81,9 +81,7 @@ class VertexArrayRenderMethod implements RenderMethod {
geo.execute(cv, ra.renderAtom, rm.isNonUniformScale,
(useAlpha && ((geo.vertexFormat & GeometryArray.COLOR) != 0)) ,
rm.alpha,
- rm.renderBin.multiScreen,
cv.screen.screen,
- rm.textureBin.attributeBin.ignoreVertexColors,
- pass);
+ rm.textureBin.attributeBin.ignoreVertexColors);
}
}
diff --git a/src/classes/share/javax/media/j3d/View.java b/src/classes/share/javax/media/j3d/View.java
index 9cc2300..a447cf2 100644
--- a/src/classes/share/javax/media/j3d/View.java
+++ b/src/classes/share/javax/media/j3d/View.java
@@ -13,15 +13,13 @@
package javax.media.j3d;
import javax.vecmath.*;
-import java.lang.Math;
import java.util.Vector;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Iterator;
import java.util.Enumeration;
import java.awt.*;
-import java.awt.event.*;
-import com.sun.j3d.utils.universe.*; // Needed for Support of DVR.
+import com.sun.j3d.utils.universe.Viewer; // Needed for Support of DVR.
/**
* The View object contains all parameters needed in rendering a
@@ -166,12 +164,13 @@ import com.sun.j3d.utils.universe.*; // Needed for Support of DVR.
* <LI>VIRTUAL_EYE - specifies that the associated distance is from
* the eye and in units of virtual distance.</LI><P>
* <LI>PHYSICAL_EYE - specifies that the associated distance is from
- * the eye and in units of physical distance (in meters).</LI><P>
+ * the eye and in units of physical distance (in meters).
+ * This is the default policy for both front and back clipping.</LI><P>
* <LI>VIRTUAL_SCREEN - specifies that the associated distance is
* from the screen and in units of virtual distance. </LI><P>
* <LI>PHYSICAL_SCREEN - specifies that the associated distance is
* from the screen and in units of physical distance (in meters).
- * This is the default policy for both front and back clipping.</LI><P>
+ * </LI><P>
* </UL>
* <LI>Visibility policy - specifies how visible and invisible objects
* are drawn. There are three visibility policies:</LI><P>
@@ -491,6 +490,7 @@ public class View extends Object {
* from the eye in meters.
* Policy for interpreting clip plane distances.
* Used in specifying the policy in frontClipPolicy and backClipPolicy.
+ * This is the default policy for both front and back clipping.
* @see #setFrontClipPolicy
* @see #setBackClipPolicy
*/
@@ -722,8 +722,8 @@ public class View extends Object {
// Support dynamic video resize -- DVR.
Viewer viewer = null; // Cached the associate viewer of this view.
boolean firstTime = true;
- float dvrFactor = 1.0f;
- boolean dvrResizeCompensation = true;
+// float dvrFactor = 1.0f;
+// boolean dvrResizeCompensation = true;
// User adjustable minimum frame cycle time
long minFrameCycleTime;
@@ -982,7 +982,6 @@ public class View extends Object {
private Canvas3D[][] cachedCanvasList;
private Canvas3D[] cachedCanvases;
- private Canvas3D[] cachedOffScreenCanvases;
private Screen3D[] cachedScreens;
private int longestScreenList = 0;
private boolean canvasesDirty = true;
@@ -1912,7 +1911,7 @@ public class View extends Object {
if (activeStatus && isRunning) {
- J3dMessage vpMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage vpMessage = new J3dMessage();
vpMessage.universe = universe;
vpMessage.view = this;
vpMessage.type = J3dMessage.UPDATE_VIEW;
@@ -1973,7 +1972,7 @@ public class View extends Object {
transparencySortingPolicy = policy;
if (activeStatus && isRunning) {
- J3dMessage vpMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage vpMessage = new J3dMessage();
vpMessage.universe = universe;
vpMessage.view = this;
vpMessage.type = J3dMessage.UPDATE_VIEW;
@@ -2416,22 +2415,14 @@ public class View extends Object {
synchronized (canvasList) {
ArrayList cv;
int len = canvases.size();
- int numOffScreenCanvases = 0;
Canvas3D newCachedCanvases[] = new Canvas3D[len];
for (int i=0; i < len; i++) {
newCachedCanvases[i] = (Canvas3D) canvases.get(i);
- if (newCachedCanvases[i].offScreen)
- numOffScreenCanvases++;
}
// Do this in one instruction so there is no need to
// synchronized getCanvases()
- if (numOffScreenCanvases > 0) {
- cachedOffScreenCanvases = new Canvas3D[numOffScreenCanvases];
- numOffScreenCanvases = 0;
- }
-
cachedCanvases = newCachedCanvases;
len = 0;
longestScreenList = 0;
@@ -2444,13 +2435,6 @@ public class View extends Object {
cachedCanvasList[i][j] = (Canvas3D) cv.get(j);
}
- if (cachedCanvasList[i][0].offScreen) {
- for (int j = 0; j < len; j++) {
- cachedOffScreenCanvases[numOffScreenCanvases++]=
- cachedCanvasList[i][j];
- }
- }
-
if (len > longestScreenList) {
longestScreenList = len;
}
@@ -2491,10 +2475,6 @@ public class View extends Object {
return cachedCanvases;
}
- Canvas3D[] getOffScreenCanvases() {
- return cachedOffScreenCanvases;
- }
-
// assume getCanvasList is called before
Screen3D[] getScreens() {
return cachedScreens;
@@ -3089,7 +3069,10 @@ public class View extends Object {
final void updateViewCache() {
- // DVR support
+ // TODO KCR : remove obsolete DVR code (but make sure we don't end
+ // up with a leak in the Viewer Map object).
+
+ // DVR support
// This is a back door in j3d to provide DVR support.
// A better place to put this code segment is in
// ViewCache.snapshot(). Since it consists of some
@@ -3104,24 +3087,24 @@ public class View extends Object {
firstTime = false;
}
- if(viewer != null) {
- if(viewer.isDvrEnabled()) {
- dvrFactor = viewer.getDvrFactor();
- dvrResizeCompensation =
- viewer.getDvrResizeCompensationEnable();
- /*
- System.out.println("View : dvrFactor is " + dvrFactor);
- System.out.println("View : dvrResizeCompensation is " +
- dvrResizeCompensation);
- */
- }
- else {
- // Reset back to default.
- dvrFactor = 1.0f;
- dvrResizeCompensation = true;
-
- }
- }
+// if(viewer != null) {
+// if(viewer.isDvrEnabled()) {
+// dvrFactor = viewer.getDvrFactor();
+// dvrResizeCompensation =
+// viewer.getDvrResizeCompensationEnable();
+// /*
+// System.out.println("View : dvrFactor is " + dvrFactor);
+// System.out.println("View : dvrResizeCompensation is " +
+// dvrResizeCompensation);
+// */
+// }
+// else {
+// // Reset back to default.
+// dvrFactor = 1.0f;
+// dvrResizeCompensation = true;
+//
+// }
+// }
// End of back door -- DVR.
synchronized(this) {
@@ -3286,7 +3269,7 @@ public class View extends Object {
soundScheduler.reset();
}
- J3dMessage vpMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage vpMessage = new J3dMessage();
vpMessage.universe = universe;
vpMessage.view = this;
vpMessage.type = J3dMessage.UPDATE_VIEW;
@@ -3325,7 +3308,7 @@ public class View extends Object {
}
- J3dMessage vpMessage = VirtualUniverse.mc.getMessage();
+ J3dMessage vpMessage = new J3dMessage();
vpMessage.universe = universe;
vpMessage.view = this;
vpMessage.type = J3dMessage.UPDATE_VIEW;
diff --git a/src/classes/share/javax/media/j3d/ViewPlatformRetained.java b/src/classes/share/javax/media/j3d/ViewPlatformRetained.java
index d80341b..b9756e4 100644
--- a/src/classes/share/javax/media/j3d/ViewPlatformRetained.java
+++ b/src/classes/share/javax/media/j3d/ViewPlatformRetained.java
@@ -141,7 +141,7 @@ class ViewPlatformRetained extends LeafRetained {
}
// Notify behavior scheduler & RenderBin
if (source.isLive()) {
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.UPDATE_VIEWPLATFORM;
message.threads = J3dThread.UPDATE_RENDER|J3dThread.UPDATE_BEHAVIOR;
message.universe = universe;
@@ -184,7 +184,7 @@ class ViewPlatformRetained extends LeafRetained {
Transform3D getVworldToVpc() {
if (vworldToVpc == null)
- vworldToVpc = VirtualUniverse.mc.getTransform3D(null);
+ vworldToVpc = new Transform3D();
vworldToVpc.set(getCurrentLocalToVworld(null));
vworldToVpc.invert();
return vworldToVpc;
@@ -197,10 +197,6 @@ class ViewPlatformRetained extends LeafRetained {
void evaluateViewPlatformTransform() {
- if (vworldToVpc != null) {
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D,
- vworldToVpc);
- }
// clear cache so that next time getVworldToVpc() can recompute
vworldToVpc = null;
}
diff --git a/src/classes/share/javax/media/j3d/ViewSpecificGroupRetained.java b/src/classes/share/javax/media/j3d/ViewSpecificGroupRetained.java
index 113e4d8..5f6b963 100644
--- a/src/classes/share/javax/media/j3d/ViewSpecificGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/ViewSpecificGroupRetained.java
@@ -78,7 +78,7 @@ class ViewSpecificGroupRetained extends GroupRetained {
objAry[3] = super.processViewSpecificInfo(ADD_VIEW,
(HashKey)key, view,
addVsgList, addKeyList, addLeafList);
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
@@ -120,7 +120,7 @@ class ViewSpecificGroupRetained extends GroupRetained {
}
*/
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
@@ -184,7 +184,7 @@ class ViewSpecificGroupRetained extends GroupRetained {
objAry[3] = super.processViewSpecificInfo(ADD_VIEW, (HashKey)key,
view, addVsgList, addKeyList, addLeafList);
}
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
@@ -230,7 +230,7 @@ class ViewSpecificGroupRetained extends GroupRetained {
objAry[3] = super.processViewSpecificInfo(ADD_VIEW, (HashKey)tempKey,
view, addVsgList, addKeyList, addLeafList);
}
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
@@ -337,7 +337,7 @@ class ViewSpecificGroupRetained extends GroupRetained {
objAry[3] = super.processViewSpecificInfo(ADD_VIEW,
(HashKey)key, view,
addVsgList, addKeyList, addLeafList);
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
@@ -379,7 +379,7 @@ class ViewSpecificGroupRetained extends GroupRetained {
}
*/
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
@@ -427,7 +427,7 @@ class ViewSpecificGroupRetained extends GroupRetained {
removeVsgList, removeKeyList, removeLeafList);
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
@@ -468,7 +468,7 @@ class ViewSpecificGroupRetained extends GroupRetained {
System.out.println("n = "+n+" keyValue = "+removeKeyList.get(n));
}
*/
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.VIEWSPECIFICGROUP_CHANGED;
message.threads = (J3dThread.UPDATE_RENDERING_ENVIRONMENT|
J3dThread.UPDATE_RENDER |
diff --git a/src/classes/share/javax/media/j3d/VirtualUniverse.java b/src/classes/share/javax/media/j3d/VirtualUniverse.java
index a38302c..dcedfcb 100644
--- a/src/classes/share/javax/media/j3d/VirtualUniverse.java
+++ b/src/classes/share/javax/media/j3d/VirtualUniverse.java
@@ -163,13 +163,20 @@ public class VirtualUniverse extends Object {
boolean isSceneGraphLock = false;
private Object waitLock = new Object();
-
- private HashSet structureChangeListenerSet = null;
- private HashSet shaderErrorListenerSet = null;
+ // Set of scene graph structure change listeners
+ private HashSet<GraphStructureChangeListener> structureChangeListenerSet = null;
+
+ // Set of shader error listeners
+ private HashSet<ShaderErrorListener> shaderErrorListenerSet = null;
private ShaderErrorListener defaultShaderErrorListener =
ShaderProgram.getDefaultErrorListener();
+ // Set of rendering error listeners
+ private static HashSet<RenderingErrorListener> renderingErrorListenerSet = null;
+ private static RenderingErrorListener defaultRenderingErrorListener =
+ Renderer.getDefaultErrorListener();
+
/**
* Constructs a new VirtualUniverse.
*/
@@ -255,24 +262,8 @@ public class VirtualUniverse extends Object {
// Print out debugging information for debug builds
if(VersionInfo.isDebug) {
System.err.println("Java 3D system initialized");
- System.err.print(" graphics library = ");
- switch (mc.getRenderingAPI()) {
- case MasterControl.RENDER_OPENGL_SOLARIS:
- System.err.println("Solaris OpenGL");
- break;
- case MasterControl.RENDER_OPENGL_LINUX:
- System.err.println("Linux OpenGL");
- break;
- case MasterControl.RENDER_OPENGL_WIN32:
- System.err.print("Windows OpenGL");
- break;
- case MasterControl.RENDER_DIRECT3D:
- System.err.println("Windows Direct3D");
- break;
- default:
- System.err.println("UNKNOWN");
- break;
- }
+ System.err.println(" rendering pipeline = " +
+ Pipeline.getPipeline().getPipelineName());
System.err.println();
}
}
@@ -439,6 +430,10 @@ public class VirtualUniverse extends Object {
* <td>String</td>
* </tr>
* <tr>
+ * <td><code>j3d.pipeline</code></td>
+ * <td>String</td>
+ * </tr>
+ * <tr>
* <td><code>j3d.renderer</code></td>
* <td>String</td>
* </tr>
@@ -514,10 +509,20 @@ public class VirtualUniverse extends Object {
* <p>
*
* <li>
+ * <code>j3d.pipeline</code>
+ * <ul>
+ * String that specifies the Java 3D rendering pipeline. This could
+ * be one of: "NATIVE_OGL", "NATIVE_D3D", or "JOGL". Others could be
+ * added in the future.
+ * </ul>
+ * </li>
+ * <p>
+ *
+ * <li>
* <code>j3d.renderer</code>
* <ul>
- * String that specifies the Java 3D rendering library. This could
- * be one of: "OpenGL" or "DirectX".
+ * String that specifies the underlying rendering library. This could
+ * be one of: "OpenGL" or "DirectX". Others could be added in the future.
* </ul>
* </li>
* <p>
@@ -549,7 +554,10 @@ public class VirtualUniverse extends Object {
values.add(VersionInfo.getSpecificationVendor());
keys.add("j3d.renderer");
- values.add(mc.isD3D() ? "DirectX" : "OpenGL");
+ values.add(Pipeline.getPipeline().getRendererName());
+
+ keys.add("j3d.pipeline");
+ values.add(Pipeline.getPipeline().getPipelineName());
// Now Create read-only properties object
properties =
@@ -1058,9 +1066,9 @@ public class VirtualUniverse extends Object {
}
synchronized(structureChangeListenerSet) {
- Iterator it = structureChangeListenerSet.iterator();
+ Iterator<GraphStructureChangeListener> it = structureChangeListenerSet.iterator();
while(it.hasNext()) {
- GraphStructureChangeListener listener = (GraphStructureChangeListener)it.next();
+ GraphStructureChangeListener listener = it.next();
try {
if (add) {
listener.branchGroupAdded(parent, child);
@@ -1072,6 +1080,11 @@ public class VirtualUniverse extends Object {
System.err.println("Exception occurred in GraphStructureChangeListener:");
e.printStackTrace();
}
+ catch (Error e) {
+ // Issue 264 - catch Error
+ System.err.println("Error occurred in GraphStructureChangeListener:");
+ e.printStackTrace();
+ }
}
}
}
@@ -1086,9 +1099,9 @@ public class VirtualUniverse extends Object {
}
synchronized(structureChangeListenerSet) {
- Iterator it = structureChangeListenerSet.iterator();
+ Iterator<GraphStructureChangeListener> it = structureChangeListenerSet.iterator();
while(it.hasNext()) {
- GraphStructureChangeListener listener = (GraphStructureChangeListener)it.next();
+ GraphStructureChangeListener listener = it.next();
try {
listener.branchGroupMoved(oldParent, newParent, child);
}
@@ -1096,6 +1109,11 @@ public class VirtualUniverse extends Object {
System.err.println("Exception occurred in GraphStructureChangeListener:");
e.printStackTrace();
}
+ catch (Error e) {
+ // Issue 264 - catch Error
+ System.err.println("Error occurred in GraphStructureChangeListener:");
+ e.printStackTrace();
+ }
}
}
}
@@ -1163,9 +1181,9 @@ public class VirtualUniverse extends Object {
// Notify all error listeners in the set
if (shaderErrorListenerSet != null) {
synchronized(shaderErrorListenerSet) {
- Iterator it = shaderErrorListenerSet.iterator();
+ Iterator<ShaderErrorListener> it = shaderErrorListenerSet.iterator();
while(it.hasNext()) {
- ShaderErrorListener listener = (ShaderErrorListener)it.next();
+ ShaderErrorListener listener = it.next();
try {
listener.errorOccurred(error);
}
@@ -1173,15 +1191,108 @@ public class VirtualUniverse extends Object {
System.err.println("Exception occurred in ShaderErrorListener:");
e.printStackTrace();
}
+ catch (Error e) {
+ // Issue 264 - catch Error
+ System.err.println("Error occurred in ShaderErrorListener:");
+ e.printStackTrace();
+ }
errorReported = true;
}
}
}
- // Notify the default error listener if the set is null or empty
- if (!errorReported) {
- defaultShaderErrorListener.errorOccurred(error);
+ // Notify the default error listener if the set is null or empty
+ if (!errorReported) {
+ defaultShaderErrorListener.errorOccurred(error);
+ }
+ }
+
+
+ // Issue 260 : rendering error listeners.
+
+ /**
+ * Adds the specified RenderingErrorListener to the set of listeners
+ * that will be notified when a rendering error is detected.
+ * If the specifed listener is null no action is taken and no exception
+ * is thrown.
+ * If a rendering error occurs, the listeners will be called
+ * asynchronously from a separate notification thread. If the set
+ * of listeners is empty, a default listener is notified. The
+ * default listener prints the error information to System.err and
+ * then calls System.exit().
+ *
+ * @param listener the listener to add to the set.
+ *
+ * @since Java 3D 1.5
+ */
+ public static void addRenderingErrorListener(RenderingErrorListener listener) {
+ if (listener == null) {
+ return;
+ }
+
+ if (renderingErrorListenerSet == null) {
+ renderingErrorListenerSet = new HashSet();
+ }
+
+ synchronized(renderingErrorListenerSet) {
+ renderingErrorListenerSet.add(listener);
+ }
+ }
+
+ /**
+ * Removes the specified RenderingErrorListener from the set of
+ * listeners. This method performs no function, nor does it throw
+ * an exception if the specified listener is not currently in the
+ * set or is null.
+ *
+ * @param listener the listener to remove from the set.
+ *
+ * @since Java 3D 1.5
+ */
+ public static void removeRenderingErrorListener(RenderingErrorListener listener) {
+ if (renderingErrorListenerSet == null) {
+ return;
}
+
+ synchronized(renderingErrorListenerSet) {
+ renderingErrorListenerSet.remove(listener);
+ }
+ }
+
+ /**
+ * Notifies all listeners of a rendering error. If no listeners exist,
+ * a default listener is notified.
+ */
+ static void notifyRenderingErrorListeners(RenderingError error) {
+ boolean errorReported = false;
+
+ // Notify all error listeners in the set
+ if (renderingErrorListenerSet != null) {
+ synchronized(renderingErrorListenerSet) {
+ Iterator<RenderingErrorListener> it = renderingErrorListenerSet.iterator();
+ while(it.hasNext()) {
+ RenderingErrorListener listener = it.next();
+ try {
+ listener.errorOccurred(error);
+ }
+ catch (RuntimeException e) {
+ System.err.println("Exception occurred in RenderingErrorListener:");
+ e.printStackTrace();
+ }
+ catch (Error e) {
+ // Issue 264 - catch Error
+ System.err.println("Error occurred in RenderingErrorListener:");
+ e.printStackTrace();
+ }
+ errorReported = true;
+ }
+ }
+ }
+
+ // Notify the default error listener if the set is null or empty
+ if (!errorReported) {
+ defaultRenderingErrorListener.errorOccurred(error);
+ }
}
}
diff --git a/src/classes/share/javax/media/j3d/WakeupCondition.java b/src/classes/share/javax/media/j3d/WakeupCondition.java
index d0491dd..f419376 100644
--- a/src/classes/share/javax/media/j3d/WakeupCondition.java
+++ b/src/classes/share/javax/media/j3d/WakeupCondition.java
@@ -91,7 +91,7 @@ public abstract class WakeupCondition extends Object {
if (!conditionMet) {
conditionMet = true;
- J3dMessage message = VirtualUniverse.mc.getMessage();
+ J3dMessage message = new J3dMessage();
message.type = J3dMessage.COND_MET;
message.threads = J3dThread.UPDATE_BEHAVIOR;
message.universe = behav.universe;
diff --git a/src/classes/solaris/javax/media/j3d/J3dGraphicsConfig.java b/src/classes/solaris/javax/media/j3d/J3dGraphicsConfig.java
deleted file mode 100644
index c242a77..0000000
--- a/src/classes/solaris/javax/media/j3d/J3dGraphicsConfig.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-package javax.media.j3d;
-
-import sun.awt.*;
-import java.awt.*;
-
-class J3dGraphicsConfig {
-
- static native boolean isValidVisualID(long display, int vid);
-
- J3dGraphicsConfig(GraphicsDevice gd, int pixelFormat) {
- // a dummy class which this constructor should
- // never invoke under Solaris
- }
-
- static boolean isValidPixelFormat(GraphicsConfiguration gc) {
- return isValidVisualID(NativeScreenInfo.getStaticDisplay(),
- ((X11GraphicsConfig) gc).getVisual());
- }
-
- static boolean isValidConfig(GraphicsConfiguration gc) {
- // Check to see if a valid FBConfig pointer has been cached.
- Object fbConfigObject = Canvas3D.fbConfigTable.get(gc);
- return ((fbConfigObject != null) &&
- (fbConfigObject instanceof GraphicsConfigInfo));
- }
-
-
-}
diff --git a/src/classes/solaris/javax/media/j3d/NativeWSInfo.java b/src/classes/solaris/javax/media/j3d/NativeWSInfo.java
deleted file mode 100644
index 2e0da2a..0000000
--- a/src/classes/solaris/javax/media/j3d/NativeWSInfo.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-package javax.media.j3d;
-
-import java.awt.*;
-import java.awt.event.*;
-import sun.awt.*;
-import java.lang.reflect.Method;
-
-class NativeWSInfo {
-
- //X11DrawingSurface xds;
- Object xds;
-
- void getCanvasWSParameters(Canvas3D canvas) {
- try {
- Class x11DSclass = Class.forName("sun.awt.X11DrawingSurface");
- Method getDrawable = x11DSclass.getDeclaredMethod("getDrawable", null );
- Method getVisualID = x11DSclass.getDeclaredMethod("getVisualID", null );
-
- //canvas.window = xds.getDrawable();
- //canvas.vid = xds.getVisualID();
-
- canvas.window = ((Integer)getDrawable.invoke( xds, null )).intValue();
- canvas.vid = ((Integer)getVisualID.invoke( xds, null )).intValue();
- } catch( Exception e ) {
- e.printStackTrace();
- }
- }
-
- void getWSDrawingSurface( Object dsi) {
- try {
- //xds = (X11DrawingSurface)dsi.getSurface();
- Class drawingSurfaceInfoClass = Class.forName("sun.awt.DrawingSurfaceInfo");
- Method getSurface = drawingSurfaceInfoClass.getDeclaredMethod( "getSurface", null);
-
- //xds = dsi.getSurface();
- xds = getSurface.invoke( dsi, null );
- } catch( Exception e ) {
- e.printStackTrace();
- }
- }
-
- int getCanvasVid(GraphicsConfiguration gcfg) {
- return (((X11GraphicsConfig)gcfg).getVisual());
- }
-}
-
diff --git a/src/classes/win32/javax/media/j3d/J3dGraphicsConfig.java b/src/classes/win32/javax/media/j3d/J3dGraphicsConfig.java
deleted file mode 100644
index 72340e5..0000000
--- a/src/classes/win32/javax/media/j3d/J3dGraphicsConfig.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-package javax.media.j3d;
-
-import sun.awt.Win32GraphicsConfig;
-import java.awt.*;
-
-class J3dGraphicsConfig extends Win32GraphicsConfig {
-
- private int pixelFormat;
-
- J3dGraphicsConfig(GraphicsDevice gd, int pixelFormat)
- {
- super(gd, pixelFormat);
- this.pixelFormat = pixelFormat;
- }
-
- static boolean isValidPixelFormat(GraphicsConfiguration gc) {
- return (gc instanceof J3dGraphicsConfig);
- }
-
- static boolean isValidConfig(GraphicsConfiguration gc) {
- return isValidPixelFormat(gc);
- }
-
- int getPixelFormat() {
- return pixelFormat;
- }
-
-
-}
diff --git a/src/classes/win32/javax/media/j3d/NativeConfigTemplate3D.java b/src/classes/win32/javax/media/j3d/NativeConfigTemplate3D.java
index 7253c5a..c198e31 100644
--- a/src/classes/win32/javax/media/j3d/NativeConfigTemplate3D.java
+++ b/src/classes/win32/javax/media/j3d/NativeConfigTemplate3D.java
@@ -44,7 +44,7 @@ class NativeConfigTemplate3D {
choosePixelFormat(long ctx, int screen, int[] attrList, long[] pFormatInfo);
// Native method to free an PixelFormatInfo struct. This is static since it
- // may need to be called to clean up the Canvas3D fbConfigTable after the
+ // may need to be called to clean up the Canvas3D graphicsConfigTable after the
// NativeConfigTemplate3D has been disposed of.
static native void freePixelFormatInfo(long pFormatInfo);
@@ -91,8 +91,8 @@ class NativeConfigTemplate3D {
attrList[STENCIL_SIZE] = template.getStencilSize();
// System.out.println("NativeConfigTemplate3D : getStencilSize " +
// attrList[STENCIL_SIZE]);
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
- int screen = nativeScreenInfo.getScreen();
+
+ int screen = NativeScreenInfo.getScreen(gd);
long[] pFormatInfo = new long[1];
@@ -118,17 +118,15 @@ class NativeConfigTemplate3D {
// Fix to issue 104 --
// Pass in 0 for pixel format to the AWT.
// ATI driver will lockup pixelFormat, if it is passed to AWT.
- GraphicsConfiguration gc1 = new J3dGraphicsConfig(gd, 0);
-
- // We need to cache the offScreen pixelformat that glXChoosePixelFormat()
- // returns, since this is not cached with J3dGraphicsConfig and there
- // are no public constructors to allow us to extend it.
- synchronized (Canvas3D.fbConfigTable) {
- if (Canvas3D.fbConfigTable.get(gc1) == null) {
- GraphicsConfigInfo gcInfo = new GraphicsConfigInfo();
- gcInfo.setFBConfig(pFormatInfo[0]);
- gcInfo.setRequestedStencilSize(attrList[STENCIL_SIZE]);
- Canvas3D.fbConfigTable.put(gc1, gcInfo);
+ GraphicsConfiguration gc1 = Win32GraphicsConfig.getConfig(gd, 0);
+
+ // We need to cache the GraphicsTemplate3D and the private
+ // pixel format info.
+ synchronized (Canvas3D.graphicsConfigTable) {
+ if (Canvas3D.graphicsConfigTable.get(gc1) == null) {
+ GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(template);
+ gcInfo.setPrivateData(new Long(pFormatInfo[0]));
+ Canvas3D.graphicsConfigTable.put(gc1, gcInfo);
} else {
freePixelFormatInfo(pFormatInfo[0]);
}
@@ -174,8 +172,7 @@ class NativeConfigTemplate3D {
// System.out.println("NativeConfigTemplate3D : getStencilSize " +
// attrList[STENCIL_SIZE]);
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
- int screen = nativeScreenInfo.getScreen();
+ int screen = NativeScreenInfo.getScreen(gd);
long[] pFormatInfo = new long[1];
@@ -220,8 +217,7 @@ class NativeConfigTemplate3D {
Win32GraphicsDevice gd =
(Win32GraphicsDevice)((Win32GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
- int screen = nativeScreenInfo.getScreen();
+ int screen = NativeScreenInfo.getScreen(gd);
/* Fix to issue 77 */
return isSceneAntialiasingMultisampleAvailable(c3d.fbConfig, c3d.offScreen, screen);
}
diff --git a/src/classes/win32/javax/media/j3d/NativeScreenInfo.java b/src/classes/win32/javax/media/j3d/NativeScreenInfo.java
index 2156b8f..9652b7a 100644
--- a/src/classes/win32/javax/media/j3d/NativeScreenInfo.java
+++ b/src/classes/win32/javax/media/j3d/NativeScreenInfo.java
@@ -16,18 +16,20 @@ import java.awt.GraphicsDevice;
import sun.awt.Win32GraphicsDevice;
class NativeScreenInfo {
- private int display = 0;
- private int screen = 0;
-
+ private static final long display = 0; // unused for Win32
private static boolean wglARBChecked = false;
private static boolean isWglARB;
- private native static boolean queryWglARB();
+ private static native boolean queryWglARB();
+
+ private NativeScreenInfo() {
+ throw new AssertionError("constructor should never be called");
+ }
// This method will return true if wglGetExtensionsStringARB is supported,
// else return false
- synchronized static boolean isWglARB() {
+ static synchronized boolean isWglARB() {
if (!wglARBChecked) {
// Query for wglGetExtensionsStringARB support.
@@ -37,21 +39,14 @@ class NativeScreenInfo {
return isWglARB;
}
- NativeScreenInfo(GraphicsDevice graphicsDevice) {
- // Get the screen number
- screen = ((sun.awt.Win32GraphicsDevice)graphicsDevice).getScreen();
- display = screen;
- }
-
- int getDisplay() {
+ static long getDisplay() {
return display;
}
- int getScreen() {
- return screen;
+ static int getScreen(GraphicsDevice graphicsDevice) {
+ return ((Win32GraphicsDevice)graphicsDevice).getScreen();
}
-
// Ensure that the native libraries are loaded
static {
VirtualUniverse.loadLibraries();
diff --git a/src/classes/win32/javax/media/j3d/NativeWSInfo.java b/src/classes/win32/javax/media/j3d/NativeWSInfo.java
deleted file mode 100644
index aca9c26..0000000
--- a/src/classes/win32/javax/media/j3d/NativeWSInfo.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-package javax.media.j3d;
-
-import java.awt.*;
-import java.awt.event.*;
-import sun.awt.*;
-import java.lang.reflect.Method;
-
-class NativeWSInfo {
-
- //Win32DrawingSurface wds;
- Object wds;
-
- void getCanvasWSParameters(Canvas3D canvas) {
- //canvas.window = wds.getHDC();
- try {
- Class win32DSclass = Class.forName("sun.awt.Win32DrawingSurface");
- Method getHDC = win32DSclass.getDeclaredMethod("getHDC", null );
-
- canvas.window = ((Integer)getHDC.invoke( wds, null )).intValue();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- void getWSDrawingSurface(Object dsi) {
- //wds = (Win32DrawingSurface)dsi.getSurface();
- int hwnd =0;
-
- try {
- Class drawingSurfaceInfoClass = Class.forName("sun.awt.DrawingSurfaceInfo");
- Method getSurface = drawingSurfaceInfoClass.getDeclaredMethod( "getSurface", null);
-
- wds = getSurface.invoke( dsi, null );
-
- Class win32DSclass = Class.forName("sun.awt.Win32DrawingSurface");
- Method getHWnd = win32DSclass.getDeclaredMethod("getHWnd", null );
- hwnd = ((Integer)getHWnd.invoke( wds, null )).intValue();
- } catch( Exception e ) {
- e.printStackTrace();
- }
-
- // note: dsi lock is called from the caller of this method
- // Workaround for bug 4169320
- //dsi.lock();
- //subclass(wds.getHWnd());
- subclass(hwnd);
- //dsi.unlock();
- }
-
- // Used in workaround for bug 4169320: Resizing a Java 3D canvas
- // on Win95 crashes the application
- private native void subclass(int hWnd);
-
- int getCanvasVid(GraphicsConfiguration gcfg) {
- return ((J3dGraphicsConfig) gcfg).getPixelFormat();
- }
-}
diff --git a/src/classes/solaris/javax/media/j3d/NativeConfigTemplate3D.java b/src/classes/x11/javax/media/j3d/NativeConfigTemplate3D.java
index 6f116cf..cbd3713 100644
--- a/src/classes/solaris/javax/media/j3d/NativeConfigTemplate3D.java
+++ b/src/classes/x11/javax/media/j3d/NativeConfigTemplate3D.java
@@ -44,8 +44,8 @@ class NativeConfigTemplate3D {
int[] attrList, long[] fbConfig);
// Native method to free an GLXFBConfig struct. This is static since it
- // may need to be called to clean up the Canvas3D fbConfigTable after the
- // NativeConfigTemplate3D has been disposed of.
+ // may need to be called to clean up the Canvas3D graphicsConfigTable
+ // after the NativeConfigTemplate3D has been disposed of.
static native void freeFBConfig(long fbConfig);
// Native methods to return whether a particular attribute is available
@@ -58,9 +58,8 @@ class NativeConfigTemplate3D {
/*
* Chooses the best FBConfig for Java 3D apps.
*/
- GraphicsConfiguration
- getBestConfiguration(GraphicsConfigTemplate3D template,
- GraphicsConfiguration[] gc) {
+ GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate3D template,
+ GraphicsConfiguration[] gc) {
X11GraphicsDevice gd =
(X11GraphicsDevice)((X11GraphicsConfig)gc[0]).getDevice();
@@ -69,10 +68,8 @@ class NativeConfigTemplate3D {
return null;
}
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
-
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
+ long display = NativeScreenInfo.getDisplay();
+ int screen = NativeScreenInfo.getScreen(gd);
if (debug) {
System.out.println(" NativeConfigTemplate3D: using device " + gd);
@@ -125,34 +122,42 @@ class NativeConfigTemplate3D {
if (visID == 0 || fbConfig[0] == 0) {
return null; // no valid visual was found
- }
+ }
// search list of graphics configurations for config
// with matching visualId
- GraphicsConfiguration gc1 = null;
- for (int i = 0; i < gc.length; i++)
+ X11GraphicsConfig gc0 = null;
+ for (int i = 0; i < gc.length; i++) {
if (((X11GraphicsConfig)gc[i]).getVisual() == visID) {
- gc1 = gc[i];
+ gc0 = (X11GraphicsConfig)gc[i];
break;
}
-
- // To support disabling Solaris OpenGL Xinerama mode, we need to cache
- // the pointer to the actual GLXFBConfig that glXChooseFBConfig()
- // returns, since this is not cached with X11GraphicsConfig and there
- // are no public constructors to allow us to extend it.
- synchronized (Canvas3D.fbConfigTable) {
- if (Canvas3D.fbConfigTable.get(gc1) == null) {
- GraphicsConfigInfo gcInfo = new GraphicsConfigInfo();
- gcInfo.setFBConfig(fbConfig[0]);
- gcInfo.setRequestedStencilSize(attrList[STENCIL_SIZE]);
- Canvas3D.fbConfigTable.put(gc1, gcInfo);
+ }
+
+ // Just return if we didn't find a match
+ if (gc0 == null) {
+ return null;
+ }
+
+ // Create a new GraphicsConfig object based on the one we found
+ X11GraphicsConfig gc1 =
+ X11GraphicsConfig.getConfig(gd, gc0.getVisual(),
+ gc0.getDepth(), gc0.getColormap(), false);
+
+ // We need to cache the GraphicsTemplate3D and the private
+ // fbconfig info.
+ synchronized (Canvas3D.graphicsConfigTable) {
+ if (Canvas3D.graphicsConfigTable.get(gc1) == null) {
+ GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(template);
+ gcInfo.setPrivateData(new Long(fbConfig[0]));
+ Canvas3D.graphicsConfigTable.put(gc1, gcInfo);
} else {
freeFBConfig(fbConfig[0]);
}
}
return gc1;
}
-
+
/*
* Determine if a given GraphicsConfiguration object can be used
* by Java 3D.
@@ -167,10 +172,8 @@ class NativeConfigTemplate3D {
return false;
}
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
-
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
+ long display = NativeScreenInfo.getDisplay();
+ int screen = NativeScreenInfo.getScreen(gd);
int[] attrList; // holds the list of attributes to be tramslated
// for glxChooseVisual call
@@ -206,10 +209,9 @@ class NativeConfigTemplate3D {
X11GraphicsDevice gd =
(X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
+ long display = NativeScreenInfo.getDisplay();
+ int screen = NativeScreenInfo.getScreen(gd);
int vid = ((X11GraphicsConfig)gc).getVisual();
return isStereoAvailable(display, screen, vid);
@@ -221,10 +223,9 @@ class NativeConfigTemplate3D {
X11GraphicsDevice gd =
(X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
+ long display = NativeScreenInfo.getDisplay();
+ int screen = NativeScreenInfo.getScreen(gd);
int vid = ((X11GraphicsConfig)gc).getVisual();
return getStencilSize(display, screen, vid);
@@ -236,10 +237,9 @@ class NativeConfigTemplate3D {
X11GraphicsDevice gd =
(X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
+ long display = NativeScreenInfo.getDisplay();
+ int screen = NativeScreenInfo.getScreen(gd);
int vid = ((X11GraphicsConfig)gc).getVisual();
return isDoubleBufferAvailable(display, screen, vid);
@@ -251,10 +251,9 @@ class NativeConfigTemplate3D {
X11GraphicsDevice gd =
(X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
+ long display = NativeScreenInfo.getDisplay();
+ int screen = NativeScreenInfo.getScreen(gd);
int vid = ((X11GraphicsConfig)gc).getVisual();
return isSceneAntialiasingAccumAvailable(display, screen, vid);
@@ -267,10 +266,9 @@ class NativeConfigTemplate3D {
X11GraphicsDevice gd =
(X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice();
- NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd);
- long display = nativeScreenInfo.getDisplay();
- int screen = nativeScreenInfo.getScreen();
+ long display = NativeScreenInfo.getDisplay();
+ int screen = NativeScreenInfo.getScreen(gd);
int vid = ((X11GraphicsConfig)gc).getVisual();
return isSceneAntialiasingMultisampleAvailable(display, screen, vid);
diff --git a/src/classes/solaris/javax/media/j3d/NativeScreenInfo.java b/src/classes/x11/javax/media/j3d/NativeScreenInfo.java
index c84e8fe..85d2d3c 100644
--- a/src/classes/solaris/javax/media/j3d/NativeScreenInfo.java
+++ b/src/classes/x11/javax/media/j3d/NativeScreenInfo.java
@@ -16,54 +16,50 @@ import java.awt.GraphicsDevice;
import sun.awt.X11GraphicsDevice;
class NativeScreenInfo {
- private int screen;
private static long display = 0;
private static boolean glxChecked = false;
private static boolean isGLX13;
- private native static long openDisplay();
- private native static int getDefaultScreen(long display);
- private native static boolean queryGLX13(long display);
+ private static native long openDisplay();
+ private static native boolean queryGLX13(long display);
+
+ private NativeScreenInfo() {
+ throw new AssertionError("constructor should never be called");
+ }
// Fix for issue 20.
// This method will return true if glx version is 1.3 or higher,
// else return false.
- synchronized static boolean isGLX13() {
+ static synchronized boolean isGLX13() {
if (!glxChecked) {
// Open a new static display connection if one is not already opened.
getStaticDisplay();
- // Query for glx1.3 support.
- isGLX13 = queryGLX13(display);
+
+ // Query for glx1.3 support.
+ isGLX13 = queryGLX13(getDisplay());
glxChecked = true;
}
return isGLX13;
}
- synchronized static long getStaticDisplay() {
+ private static synchronized long getStaticDisplay() {
if (display == 0) {
display = openDisplay();
}
return display;
}
- NativeScreenInfo(GraphicsDevice graphicsDevice) {
+ static long getDisplay() {
// Open a new static display connection if one is not already opened
- getStaticDisplay();
-
- // Get the screen number
- screen = ((X11GraphicsDevice)graphicsDevice).getScreen();
+ return getStaticDisplay();
}
- long getDisplay() {
- return display;
- }
-
- int getScreen() {
- return screen;
+ static int getScreen(GraphicsDevice graphicsDevice) {
+ // Get the screen number
+ return ((X11GraphicsDevice)graphicsDevice).getScreen();
}
-
// Ensure that the native libraries are loaded
static {
VirtualUniverse.loadLibraries();