aboutsummaryrefslogtreecommitdiffstats
path: root/src/native
diff options
context:
space:
mode:
authorKevin Rushforth <[email protected]>2004-06-09 04:25:41 +0000
committerKevin Rushforth <[email protected]>2004-06-09 04:25:41 +0000
commit343b658c32a6473c545187c1e276ee5d06c2686a (patch)
treead2606538b7db1c3553c53a79ccccb2ed5b5e4e2 /src/native
parent06cebb1e576da6f7222f999ab059dcfa3d8edd39 (diff)
Initial creation of j3d-core-utils sources in CVS repository
git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@7 ba19aa83-45c5-6ac9-afd3-db810772062c
Diffstat (limited to 'src/native')
-rw-r--r--src/native/build.xml367
-rw-r--r--src/native/d3d/Attributes.cpp3014
-rw-r--r--src/native/d3d/Canvas3D.cpp1029
-rw-r--r--src/native/d3d/CompressedGeometryRetained.cpp39
-rw-r--r--src/native/d3d/D3dCtx.cpp1793
-rw-r--r--src/native/d3d/D3dCtx.hpp325
-rw-r--r--src/native/d3d/D3dDeviceInfo.cpp204
-rw-r--r--src/native/d3d/D3dDeviceInfo.hpp85
-rw-r--r--src/native/d3d/D3dDisplayList.cpp330
-rw-r--r--src/native/d3d/D3dDisplayList.hpp38
-rw-r--r--src/native/d3d/D3dDriverInfo.cpp320
-rw-r--r--src/native/d3d/D3dDriverInfo.hpp61
-rw-r--r--src/native/d3d/D3dImageComponent.cpp171
-rw-r--r--src/native/d3d/D3dImageComponent.hpp52
-rw-r--r--src/native/d3d/D3dUtil.cpp11666
-rw-r--r--src/native/d3d/D3dUtil.hpp310
-rw-r--r--src/native/d3d/D3dVertexBuffer.cpp259
-rw-r--r--src/native/d3d/D3dVertexBuffer.hpp127
-rw-r--r--src/native/d3d/GeometryArrayRetained.cpp5254
-rw-r--r--src/native/d3d/GraphicsContext3D.cpp150
-rw-r--r--src/native/d3d/Lights.cpp155
-rw-r--r--src/native/d3d/NativeAPIInfo.c23
-rw-r--r--src/native/d3d/NativeConfigTemplate3D.cpp140
-rw-r--r--src/native/d3d/NativeWSInfo.cpp92
-rw-r--r--src/native/d3d/RasterRetained.cpp255
-rw-r--r--src/native/d3d/StdAfx.h54
-rw-r--r--src/native/d3d/build-windows-i586-gcc.xml17
-rw-r--r--src/native/d3d/build-windows-i586-vc.xml63
-rw-r--r--src/native/ogl/Attributes.c3505
-rw-r--r--src/native/ogl/Canvas3D.c3388
-rw-r--r--src/native/ogl/CompressedGeometryRetained.c70
-rw-r--r--src/native/ogl/DrawingSurfaceObjectAWT.c268
-rw-r--r--src/native/ogl/GeometryArrayRetained.c3599
-rw-r--r--src/native/ogl/GraphicsContext3D.c171
-rw-r--r--src/native/ogl/Lights.c168
-rw-r--r--src/native/ogl/MasterControl.c261
-rw-r--r--src/native/ogl/NativeAPIInfo.c38
-rw-r--r--src/native/ogl/NativeConfigTemplate3D.c1277
-rw-r--r--src/native/ogl/NativeScreenInfo.c65
-rw-r--r--src/native/ogl/NativeWSInfo.c78
-rw-r--r--src/native/ogl/RasterRetained.c392
-rw-r--r--src/native/ogl/build-linux-i586.xml56
-rw-r--r--src/native/ogl/build-solaris-sparc-forte.xml81
-rw-r--r--src/native/ogl/build-solaris-sparc-gcc.xml81
-rw-r--r--src/native/ogl/build-windows-i586-gcc.xml64
-rw-r--r--src/native/ogl/build-windows-i586-vc.xml62
-rw-r--r--src/native/ogl/gl_1_2.h191
-rw-r--r--src/native/ogl/gldefs.h645
-rw-r--r--src/native/ogl/glext.h3063
-rw-r--r--src/native/ogl/panoramiXext.h102
-rw-r--r--src/native/share/build-linux-i586.xml54
-rw-r--r--src/native/share/build-solaris-sparc-forte.xml79
-rw-r--r--src/native/share/build-solaris-sparc-gcc.xml79
-rw-r--r--src/native/share/build-windows-i586-gcc.xml63
-rw-r--r--src/native/share/build-windows-i586-vc.xml62
55 files changed, 44355 insertions, 0 deletions
diff --git a/src/native/build.xml b/src/native/build.xml
new file mode 100644
index 0000000..f2ca9a1
--- /dev/null
+++ b/src/native/build.xml
@@ -0,0 +1,367 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native files -->
+<project name="Java 3D" default="compile-opt">
+
+ <target name="nativeSetup-debug-solaris" if="isSolarisOnSparc">
+ <property name="bldFlag" value="g"/>
+ <property name="coreLibDependency" value="lib/sparc/libj3dcore-ogl.so"/>
+ <property name="coreUtilsLibDependency" value="lib/sparc/libj3dutils.so"/>
+ </target>
+
+ <target name="nativeSetup-debug-linux" if="isLinuxOnX86">
+ <property name="bldFlag" value="g"/>
+ <property name="coreLibDependency" value="lib/i386/libj3dcore-ogl.so"/>
+ <property name="coreUtilsLibDependency" value="lib/i386/libj3dutils.so"/>
+ </target>
+
+ <target name="nativeSetup-debug-win32" if="isWindowsOnX86">
+ <property name="bldFlag"
+ value="-DWIN32 -DDEBUG -D_WINDOWS"/>
+ <property name="coreLibDependency" value="bin/j3dcore-${build.rend}.dll"/>
+ <property name="coreUtilsLibDependency" value="bin/j3dutils.dll"/>
+ </target>
+
+
+ <target name="nativeSetup-debug" depends="nativeSetup-debug-solaris, nativeSetup-debug-linux, nativeSetup-debug-win32">
+ <property name="bldType" value="debug"/>
+ <property name="javahCoreSrc"
+ location="${src}/classes/share/javax/media/j3d"/>
+ <property name="javahCoreTarget"
+ location="${build}/${platform}/${bldType}/native/javah/j3dcore"/>
+ <property name="javahUtilsSrc"
+ location="${core_utils_src}/classes/share/com/sun/j3d/utils/timer"/>
+ <property name="javahUtilsTarget"
+ location="${build}/${platform}/${bldType}/native/javah/j3dutils"/>
+ </target>
+
+ <target name="nativeSetup-opt-solaris" if="isSolarisOnSparc">
+ <property name="bldFlag" value="O"/>
+ <property name="coreLibDependency" value="lib/sparc/libj3dcore-ogl.so"/>
+ <property name="coreUtilsLibDependency" value="lib/sparc/libj3dutils.so"/>
+ </target>
+
+ <target name="nativeSetup-opt-linux" if="isLinuxOnX86">
+ <property name="bldFlag" value="O"/>
+ <property name="coreLibDependency" value="lib/i386/libj3dcore-ogl.so"/>
+ <property name="coreUtilsLibDependency" value="lib/i386/libj3dutils.so"/>
+ </target>
+
+ <target name="nativeSetup-opt-win32" if="isWindowsOnX86">
+ <property name="bldFlag"
+ value="-DWIN32 -DNDEBUG -D_WINDOWS"/>
+ <property name="coreLibDependency" value="bin/j3dcore-${build.rend}.dll"/>
+ <property name="coreUtilsLibDependency" value="bin/j3dutils.dll"/>
+ </target>
+
+ <target name="nativeSetup-opt" depends="nativeSetup-opt-solaris, nativeSetup-opt-linux, nativeSetup-opt-win32">
+ <property name="bldType" value="opt"/>
+ <property name="javahCoreSrc"
+ location="${src}/classes/share/javax/media/j3d"/>
+ <property name="javahCoreTarget"
+ location="${build}/${platform}/${bldType}/native/javah/j3dcore"/>
+ <property name="javahUtilsSrc"
+ location="${core_utils_src}/classes/share/com/sun/j3d/utils/timer"/>
+ <property name="javahUtilsTarget"
+ location="${build}/${platform}/${bldType}/native/javah/j3dutils"/>
+ </target>
+
+ <target name="dependencyCheck">
+
+ <!-- ==== source/target out-of-date checking for JNI header files ==== -->
+ <condition property="javahBuild.notRequired">
+ <and>
+ <uptodate
+ srcfile="${javahCoreSrc}/Background.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_Background.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/Canvas3D.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_Canvas3D.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/ColoringAttributes.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_ColoringAttributes.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/ColoringAttributesRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_ColoringAttributesRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/CompressedGeometryRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_CompressedGeometryRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/DepthComponentRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_DepthComponentRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/DetailTextureImage.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_DetailTextureImage.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/DirectionalLightRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_DirectionalLightRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/DisplayListRenderMethod.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_DisplayListRenderMethod.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/DrawingSurfaceObjectAWT.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_DrawingSurfaceObjectAWT.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/ExponentialFogRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_ExponentialFogRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/GeometryArray.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_GeometryArray.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/GeometryArrayRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_GeometryArrayRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/GeometryRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_GeometryRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/GraphicsContext3D.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_GraphicsContext3D.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/ImageComponent.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_ImageComponent.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/ImageComponent2DRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_ImageComponent2DRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/ImageComponentRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_ImageComponentRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/IndexedGeometryArrayRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_IndexedGeometryArrayRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/LineAttributes.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_LineAttributes.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/LineAttributesRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_LineAttributesRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/LinearFogRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_LinearFogRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/MasterControl.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_MasterControl.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/Material.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_Material.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/MaterialRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_MaterialRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/ModelClipRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_ModelClipRetained.h"/>
+ <uptodate
+ srcfile="${src}/classes/${ostype}/javax/media/j3d/NativeConfigTemplate3D.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_NativeConfigTemplate3D.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/NodeRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_NodeRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/PointAttributesRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_PointAttributesRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/PointLightRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_PointLightRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/PolygonAttributes.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_PolygonAttributes.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/PolygonAttributesRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_PolygonAttributesRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/Raster.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_Raster.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/RasterRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_RasterRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/RenderMolecule.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_RenderMolecule.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/Renderer.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_Renderer.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/RenderingAttributes.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_RenderingAttributes.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/RenderingAttributesRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_RenderingAttributesRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/SpotLightRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_SpotLightRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/TexCoordGeneration.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_TexCoordGeneration.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/TexCoordGenerationRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_TexCoordGenerationRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/Texture.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_Texture.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/Texture2D.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_Texture2D.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/Texture2DRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_Texture2DRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/Texture3DRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_Texture3DRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/TextureAttributes.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_TextureAttributes.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/TextureAttributesRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_TextureAttributesRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/TextureCubeMapRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_TextureCubeMapRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/TextureRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_TextureRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/TextureUnitStateRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_TextureUnitStateRetained.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/TransparencyAttributes.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_TransparencyAttributes.h"/>
+ <uptodate
+ srcfile="${javahCoreSrc}/TransparencyAttributesRetained.java"
+ targetfile="${javahCoreTarget}/javax_media_j3d_TransparencyAttributesRetained.h"/>
+ <uptodate
+ srcfile="${javahUtilsSrc}/J3DTimer.java"
+ targetfile="${javahUtilsTarget}/com_sun_j3d_utils_timer_J3DTimer.h"/>
+ </and>
+ </condition>
+ <echo message="javahBuild.notRequired = ${javahBuild.notRequired}"/>
+
+ <!-- ==== source/target out-of-date checking for JNI header files ==== -->
+ <!-- ==== and obj files ==== -->
+ <condition property="nativeOGLBuild.notRequired">
+ <and>
+ <istrue value="${javahBuild.notRequired}"/>
+ <uptodate>
+ <srcfiles dir= "${src}/native/${build.rend}" includes="*.c,*.h,*.cpp,*.hpp"/>
+ <mapper type="merge" from="*.c,*.h,*.cpp,*.hpp"
+ to="${build}/${platform}/${bldType}/${coreLibDependency}"/>
+ </uptodate>
+ <uptodate>
+ <srcfiles dir= "${core_utils_src}/native/share" includes="*.c,*.h,*.cpp,*.hpp"/>
+ <mapper type="merge" from="*.c,*.h,*.cpp,*.hpp"
+ to="${build}/${platform}/${bldType}/${coreUtilsLibDependency}"/>
+ </uptodate>
+ </and>
+ </condition>
+ <echo message="nativeOGLBuild.notRequired = ${nativeOGLBuild.notRequired}"/>
+ </target>
+
+ <target name="genJavah" unless="javahBuild.notRequired">
+
+ <!-- Create the build directory structure used for JNI header -->
+ <mkdir dir="${javahCoreTarget}"/>
+ <mkdir dir="${javahUtilsTarget}"/>
+
+ <!-- Generate JNI headers from ${build}/${platform}/${bldType}/classes -->
+ <!-- into ${javahCoreTarget} -->
+ <javah destdir="${javahCoreTarget}" force="yes">
+ <classpath>
+ <pathelement path="${build}/${platform}/${bldType}/classes"/>
+ </classpath>
+
+ <class name="javax.media.j3d.Background"/>
+ <class name="javax.media.j3d.Canvas3D"/>
+ <class name="javax.media.j3d.ColoringAttributes"/>
+ <class name="javax.media.j3d.ColoringAttributesRetained"/>
+ <class name="javax.media.j3d.CompressedGeometryRetained"/>
+ <class name="javax.media.j3d.DepthComponentRetained"/>
+ <class name="javax.media.j3d.DetailTextureImage"/>
+ <class name="javax.media.j3d.DirectionalLightRetained"/>
+ <class name="javax.media.j3d.DisplayListRenderMethod"/>
+ <class name="javax.media.j3d.DrawingSurfaceObjectAWT"/>
+ <class name="javax.media.j3d.ExponentialFogRetained"/>
+ <class name="javax.media.j3d.GeometryArray"/>
+ <class name="javax.media.j3d.GeometryArrayRetained"/>
+ <class name="javax.media.j3d.GeometryRetained"/>
+ <class name="javax.media.j3d.GraphicsContext3D"/>
+ <class name="javax.media.j3d.ImageComponent"/>
+ <class name="javax.media.j3d.ImageComponent2DRetained"/>
+ <class name="javax.media.j3d.ImageComponentRetained"/>
+ <class name="javax.media.j3d.IndexedGeometryArrayRetained"/>
+ <class name="javax.media.j3d.LineAttributes"/>
+ <class name="javax.media.j3d.LineAttributesRetained"/>
+ <class name="javax.media.j3d.LinearFogRetained"/>
+ <class name="javax.media.j3d.MasterControl"/>
+ <class name="javax.media.j3d.Material"/>
+ <class name="javax.media.j3d.MaterialRetained"/>
+ <class name="javax.media.j3d.ModelClipRetained"/>
+ <class name="javax.media.j3d.NativeConfigTemplate3D"/>
+ <class name="javax.media.j3d.NodeRetained"/>
+ <class name="javax.media.j3d.PointAttributesRetained"/>
+ <class name="javax.media.j3d.PointLightRetained"/>
+ <class name="javax.media.j3d.PolygonAttributes"/>
+ <class name="javax.media.j3d.PolygonAttributesRetained"/>
+ <class name="javax.media.j3d.Raster"/>
+ <class name="javax.media.j3d.RasterRetained"/>
+ <class name="javax.media.j3d.RenderMolecule"/>
+ <class name="javax.media.j3d.Renderer"/>
+ <class name="javax.media.j3d.RenderingAttributes"/>
+ <class name="javax.media.j3d.RenderingAttributesRetained"/>
+ <class name="javax.media.j3d.SpotLightRetained"/>
+ <class name="javax.media.j3d.TexCoordGeneration"/>
+ <class name="javax.media.j3d.TexCoordGenerationRetained"/>
+ <class name="javax.media.j3d.Texture"/>
+ <class name="javax.media.j3d.Texture2D"/>
+ <class name="javax.media.j3d.Texture2DRetained"/>
+ <class name="javax.media.j3d.Texture3DRetained"/>
+ <class name="javax.media.j3d.TextureAttributes"/>
+ <class name="javax.media.j3d.TextureAttributesRetained"/>
+ <class name="javax.media.j3d.TextureCubeMapRetained"/>
+ <class name="javax.media.j3d.TextureRetained"/>
+ <class name="javax.media.j3d.TextureUnitStateRetained"/>
+ <class name="javax.media.j3d.TransparencyAttributes"/>
+ <class name="javax.media.j3d.TransparencyAttributesRetained"/>
+
+ </javah>
+
+ <!-- Generate JNI headers from ${build}/${platform}/${bldType}/classes -->
+ <!-- into ${javahUtilsTarget} -->
+ <javah destdir="${javahUtilsTarget}" force="yes">
+ <classpath>
+ <pathelement path="${build}/${platform}/${bldType}/classes"/>
+ </classpath>
+ <class name="com.sun.j3d.utils.timer.J3DTimer"/>
+ </javah>
+
+ </target>
+
+ <target name="compile-debug" depends="nativeSetup-debug, dependencyCheck, genJavah" unless="nativeOGLBuild.notRequired">
+ <ant antfile="build-${platform}.xml" dir="${build.rend}" target="compile"/>
+ <ant antfile="build-${platform}.xml" dir="share" target="compile"/>
+ </target>
+
+ <target name="compile-opt" depends="nativeSetup-opt, dependencyCheck, genJavah"
+ unless="nativeOGLBuild.notRequired">
+ <ant antfile="build-${platform}.xml" dir="${build.rend}" target="compile"/>
+ <ant antfile="build-${platform}.xml" dir="share" target="compile"/>
+ </target>
+
+ <target name="dist">
+ <ant antfile="build-${platform}.xml" dir="${build.rend}" target="dist"/>
+ <ant antfile="build-${platform}.xml" dir="share" target="dist"/>
+ </target>
+
+</project>
+
diff --git a/src/native/d3d/Attributes.cpp b/src/native/d3d/Attributes.cpp
new file mode 100644
index 0000000..7798226
--- /dev/null
+++ b/src/native/d3d/Attributes.cpp
@@ -0,0 +1,3014 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+
+const DWORD blendFunctionTable[] =
+{
+ D3DBLEND_ZERO, D3DBLEND_ONE,
+ D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA,
+ D3DBLEND_DESTCOLOR, D3DBLEND_SRCCOLOR,
+ D3DBLEND_INVSRCCOLOR, D3DBLEND_SRCCOLOR
+};
+
+const DWORD combineFunctionTable[] =
+{
+ D3DTOP_SELECTARG1, D3DTOP_SELECTARG1, D3DTOP_SELECTARG1, D3DTOP_SELECTARG1,
+ D3DTOP_MODULATE, D3DTOP_MODULATE2X, D3DTOP_MODULATE2X, D3DTOP_MODULATE4X,
+ D3DTOP_ADD, D3DTOP_ADD, D3DTOP_ADD, D3DTOP_ADD,
+ D3DTOP_ADDSIGNED, D3DTOP_ADDSIGNED2X, D3DTOP_ADDSIGNED2X, D3DTOP_ADDSIGNED2X,
+ D3DTOP_SUBTRACT, D3DTOP_SUBTRACT, D3DTOP_SUBTRACT, D3DTOP_SUBTRACT,
+ D3DTOP_LERP, D3DTOP_LERP, D3DTOP_LERP, D3DTOP_LERP,
+ D3DTOP_DOTPRODUCT3, D3DTOP_DOTPRODUCT3, D3DTOP_DOTPRODUCT3, D3DTOP_DOTPRODUCT3
+};
+
+// Assume COMBINE_OBJECT_COLOR = 0
+// COMBINE_TEXTURE_COLOR = 1
+// COMBINE_CONSTANT_COLOR = 2
+// COMBINE_PREVIOUS_TEXTURE_UNIT_STATE = 3
+//
+// COMBINE_SRC_COLOR = 0
+// COMBINE_ONE_MINUS_SRC_COLOR = 1
+// COMBINE_SRC_ALPHA = 2
+// COMBINE_ONE_MINUS_SRC_ALPHA = 3
+//
+const DWORD combineSourceTable[] =
+{
+ D3DTA_DIFFUSE,
+ D3DTA_DIFFUSE | D3DTA_COMPLEMENT,
+ D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE,
+ D3DTA_DIFFUSE | D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE,
+ D3DTA_TEXTURE,
+ D3DTA_TEXTURE | D3DTA_COMPLEMENT,
+ D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE,
+ D3DTA_TEXTURE | D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE,
+ D3DTA_TFACTOR,
+ D3DTA_TFACTOR | D3DTA_COMPLEMENT,
+ D3DTA_TFACTOR | D3DTA_ALPHAREPLICATE,
+ D3DTA_TFACTOR | D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE,
+ D3DTA_CURRENT,
+ D3DTA_CURRENT | D3DTA_COMPLEMENT,
+ D3DTA_CURRENT | D3DTA_ALPHAREPLICATE,
+ D3DTA_CURRENT | D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE
+};
+
+// Assume TEXTURE_COORDINATE_2 = 0
+// TEXTURE_COORDINATE_3 = 1;
+// TEXTURE_COORDINATE_4 = 2;
+const int coordFormatTable[] = {2, 3, 4};
+
+BOOL isLineWidthMessOutput = false;
+BOOL isBackFaceMessOutput = false;
+BOOL isLinePatternMessOutput = false;
+BOOL isTexBorderMessOutput = false;
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_LinearFogRetained_update(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat red,
+ jfloat green,
+ jfloat blue,
+ jdouble fdist,
+ jdouble bdist)
+{
+ GetDevice();
+
+ float fstart = (float) fdist;
+ float fend = (float) bdist;
+
+ device->SetRenderState(d3dCtx->deviceInfo->fogMode,
+ D3DFOG_LINEAR);
+ device->SetRenderState(D3DRS_FOGCOLOR,
+ D3DCOLOR_COLORVALUE(red, green, blue, 0));
+
+ device->SetRenderState(D3DRS_FOGSTART,
+ *((LPDWORD) (&fstart)));
+ device->SetRenderState(D3DRS_FOGEND,
+ *((LPDWORD) (&fend)));
+ device->SetRenderState(D3DRS_FOGENABLE, TRUE);
+
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_ExponentialFogRetained_update(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat red,
+ jfloat green,
+ jfloat blue,
+ jfloat density)
+{
+ GetDevice();
+
+ float d = (float) density;
+
+ device->SetRenderState(d3dCtx->deviceInfo->fogMode,
+ D3DFOG_EXP);
+ device->SetRenderState(D3DRS_FOGCOLOR,
+ D3DCOLOR_COLORVALUE(red, green, blue, 0));
+ device->SetRenderState(D3DRS_FOGDENSITY,
+ *((LPDWORD) (&d)));
+ device->SetRenderState(D3DRS_FOGENABLE, TRUE);
+
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_ModelClipRetained_update(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint planeNum,
+ jboolean enableFlag,
+ jdouble A,
+ jdouble B,
+ jdouble C,
+ jdouble D)
+{
+ DWORD status;
+ float clip[4];
+
+ GetDevice();
+
+ clip[0] = -A;
+ clip[1] = -B;
+ clip[2] = -C;
+ clip[3] = -D;
+
+ device->GetRenderState(D3DRS_CLIPPLANEENABLE, &status);
+
+ if (enableFlag) {
+ device->SetClipPlane(planeNum, clip);
+ device->SetRenderState(D3DRS_CLIPPLANEENABLE,
+ status | (1 << planeNum));
+ } else {
+ device->SetRenderState(D3DRS_CLIPPLANEENABLE,
+ status & ~(1 << planeNum));
+ }
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setModelViewMatrix(
+ JNIEnv * env,
+ jobject obj,
+ jlong ctx,
+ jdoubleArray viewMatrix,
+ jdoubleArray modelMatrix)
+{
+ D3DXMATRIX d3dMatrix;
+
+ GetDevice();
+
+
+ jdouble *matrix = reinterpret_cast<jdouble*>(
+ env->GetPrimitiveArrayCritical(modelMatrix, NULL));
+
+ CopyTranspose(d3dMatrix, matrix);
+
+ env->ReleasePrimitiveArrayCritical(modelMatrix, matrix, 0);
+
+
+ device->SetTransform(D3DTS_WORLD,&d3dMatrix);
+
+ matrix = reinterpret_cast<jdouble*>(
+ env->GetPrimitiveArrayCritical(viewMatrix, NULL));
+ CopyTranspose(d3dMatrix, matrix);
+
+ env->ReleasePrimitiveArrayCritical(viewMatrix, matrix, 0);
+
+ // Because we negate the third row in projection matrix to
+ // make ._34 = 1. Here we negate the third column of View
+ // matrix to compensate it.
+ d3dMatrix._13 = -d3dMatrix._13;
+ d3dMatrix._23 = -d3dMatrix._23;
+ d3dMatrix._33 = -d3dMatrix._33;
+ d3dMatrix._43 = -d3dMatrix._43;
+
+ device->SetTransform(D3DTS_VIEW, &d3dMatrix);
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setProjectionMatrix(
+ JNIEnv * env,
+ jobject obj,
+ jlong ctx,
+ jdoubleArray projMatrix)
+{
+
+ GetDevice();
+
+ jdouble *s = reinterpret_cast<jdouble*>(
+ env->GetPrimitiveArrayCritical(projMatrix, NULL));
+
+ /*
+ * There are five steps we need to do in order that this
+ * matrix is useful by D3D
+ *
+ * (1) We need to transpose the matrix since in Java3D v' = M*v
+ * but in Direct3D v' = v*N where N is the transpose of M
+ *
+ * (2) Invert the Z value in clipping coordinates because OpenGL
+ * uses left-handed clipping coordinates, while Java3D defines
+ * right-handed coordinates everywhere. i.e. do the following
+ * after the transpose
+ *
+ * d3dMatrix._13 *= -1;
+ * d3dMatrix._23 *= -1;
+ * d3dMatrix._33 *= -1;
+ * d3dMatrix._43 *= -1;
+ *
+ * (3) In Direct3D, the z-depths range is [0,1] instead of
+ * OGL [-1, 1], so we need to multiple it by
+ *
+ * [1 0 0 0]
+ * R = [0 1 0 0]
+ * [0 0 0.5 0]
+ * [0 0 0.5 1]
+ *
+ * after the transpose and negate. i.e. N*R
+ *
+ * (4) We want w-friendly perspective matrix, i.e., d3dMatrix._34 = 1
+ * We do this first by divide the whole matrix by
+ * 1/d3dMatrix._34 Since d3dMatrix._34 is always negative as
+ * input from Java3D. Now d3dMatrix._34 = -1
+ *
+ * (5) To make d3dMatrix._34 = 1, we negate the third row of it.
+ * Because of this, we need to negate the third column in
+ * View matrix to compensate this.
+ *
+ * All of the above operation is combined together in this
+ * implementation for optimization.
+ */
+ D3DXMATRIX m;
+
+ if (s[14] != 0) {
+ // Perspective projection
+ // s[14] is always < 0
+ float ratio = -1/s[14];
+ m._12= m._13 = m._14 = m._21 = m._23 =
+ m._24 = m._41 = m._42 = m._44 = 0;
+ m._11 = s[0]*ratio;
+ m._22 = s[5]*ratio;
+ m._31 = -s[2]*ratio;
+ m._32 = -s[6]*ratio;
+ m._33 = -(s[14]-s[10])*ratio/2;
+ m._43 = -s[11]*ratio/2;
+ m._34 = 1;
+ } else {
+ // parallel projection
+ m._12 = m._13 = m._14 = m._21 = m._23 =
+ m._24 = m._31 = m._32 = m._34 = 0;
+ m._11 = s[0];
+ m._22 = s[5];
+ m._33 = s[10]/2;
+ m._41 = s[3];
+ m._42 = s[7];
+ m._43 = (s[15]-s[11])/2;
+ m._44 = s[15];
+ }
+
+ env->ReleasePrimitiveArrayCritical(projMatrix, s, 0);
+ device->SetTransform(D3DTS_PROJECTION, &m);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setViewport(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint x,
+ jint y,
+ jint width,
+ jint height)
+{
+ GetDevice();
+
+ if (d3dCtx->bFullScreen) {
+ width = d3dCtx->devmode.dmPelsWidth;
+ height = d3dCtx->devmode.dmPelsHeight;
+ }
+ D3DVIEWPORT8 vp = {x, y, width, height, 0.0f, 1.0f};
+
+ device->SetViewport(&vp);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setSceneAmbient(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat red,
+ jfloat green,
+ jfloat blue)
+{
+ GetDevice();
+ /*
+ Clamp(red);
+ Clamp(green);
+ Clamp(blue);
+ */
+ device->SetRenderState(D3DRS_AMBIENT,
+ D3DCOLOR_COLORVALUE(red, green, blue, 0));
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setLightEnables(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jlong enable_mask,
+ jint nlights)
+{
+ GetDevice();
+
+#pragma warning(disable:4244) // loss of data from __int64 to int
+
+ for (int i=nlights-1; i>=0; i--) {
+ device->LightEnable(i, enable_mask & (1<<i));
+ }
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setLightingEnable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jboolean lightingOn)
+{
+ GetDevice();
+
+ d3dCtx->isLightEnable = lightingOn;
+ device->SetRenderState(D3DRS_LIGHTING, lightingOn);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_disableFog(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+ device->SetRenderState(D3DRS_FOGENABLE, false);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_disableModelClip(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+ device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetRenderingAttributes(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jboolean db_write_enable_override,
+ jboolean db_enable_override)
+{
+ GetDevice();
+
+ if (!db_write_enable_override) {
+ d3dCtx->zWriteEnable = TRUE;
+ device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+ }
+
+ if (!db_enable_override) {
+ d3dCtx->zEnable = TRUE;
+ device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
+ }
+
+ device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
+ device->SetRenderState(D3DRS_ALPHAREF, 0);
+
+ /* setRasterOp(d3dCtx, R2_COPYPEN); */
+
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_RenderingAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jboolean db_write_enable_override,
+ jboolean db_enable_override,
+ jboolean db_enable,
+ jboolean db_write_enable,
+ jfloat at_value,
+ jint at_func,
+ jboolean ignoreVertexColors,
+ jboolean rasterOpEnable,
+ jint rasterOp)
+{
+
+ GetDevice();
+
+ DWORD alpha = (DWORD) (at_value * 255 + 0.5f);
+
+ if (!db_enable_override) {
+ if (db_enable) {
+ d3dCtx->zEnable = TRUE;
+ device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
+ } else {
+ d3dCtx->zEnable = FALSE;
+ device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
+ }
+ }
+
+ if (!db_write_enable_override) {
+ d3dCtx->zWriteEnable = db_write_enable;
+ device->SetRenderState(D3DRS_ZWRITEENABLE, db_write_enable);
+ }
+
+ if (at_func == javax_media_j3d_RenderingAttributes_ALWAYS) {
+ device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+ } else {
+ device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
+ device->SetRenderState(D3DRS_ALPHAREF, alpha);
+ }
+
+ switch (at_func) {
+ case javax_media_j3d_RenderingAttributes_ALWAYS:
+ device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
+ break;
+ case javax_media_j3d_RenderingAttributes_NEVER:
+ device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NEVER);
+ break;
+ case javax_media_j3d_RenderingAttributes_EQUAL:
+ device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_EQUAL);
+ break;
+ case javax_media_j3d_RenderingAttributes_NOT_EQUAL:
+ device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL);
+ break;
+ case javax_media_j3d_RenderingAttributes_LESS:
+ device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESS);
+ break;
+ case javax_media_j3d_RenderingAttributes_LESS_OR_EQUAL:
+ device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESSEQUAL);
+ break;
+ case javax_media_j3d_RenderingAttributes_GREATER:
+ device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
+ break;
+ case javax_media_j3d_RenderingAttributes_GREATER_OR_EQUAL:
+ device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
+ break;
+ }
+
+
+
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetPolygonAttributes(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+ // D3D vertex order is reverse of OGL
+ d3dCtx->cullMode = D3DCULL_CW;
+ d3dCtx->fillMode = D3DFILL_SOLID;
+ device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
+ d3dCtx->twoSideLightingEnable = false;
+ device->SetRenderState(D3DRS_ZBIAS, 0);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_PolygonAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint polygonMode,
+ jint cullFace,
+ jboolean backFaceNormalFlip,
+ jfloat polygonOffset,
+ jfloat polygonOffsetFactor)
+{
+
+ GetDevice();
+
+ jfloat zbias = polygonOffset + polygonOffsetFactor;
+ DWORD zbias_w = 0;
+ /*
+ * DirectX support Z-bias from 0 to 16 only and the
+ * direction is opposite to OGL. If we pass negative
+ * Z-bias the polygon will not render at all.
+ * So we map -ve polygon offset to positive value
+ * and +ve offset to 0. (i.e. we don't support positive
+ * polygon offset)
+ */
+ if (zbias <= -1) {
+ zbias_w = max(-zbias/50, 1);
+
+ if (zbias_w > 16) {
+ zbias_w = 16;
+ }
+ }
+
+ device->SetRenderState(D3DRS_ZBIAS, zbias_w);
+
+ if (cullFace == javax_media_j3d_PolygonAttributes_CULL_NONE) {
+ d3dCtx->cullMode = D3DCULL_NONE;
+ device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ } else {
+ if (cullFace == javax_media_j3d_PolygonAttributes_CULL_BACK) {
+ d3dCtx->cullMode = D3DCULL_CW;
+ device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
+ } else {
+ d3dCtx->cullMode = D3DCULL_CCW;
+ device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
+ }
+ }
+
+ if (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_POINT) {
+ d3dCtx->fillMode = D3DFILL_POINT;
+ device->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT);
+ } else if (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_LINE) {
+ d3dCtx->fillMode = D3DFILL_WIREFRAME;
+ device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
+ } else {
+ d3dCtx->fillMode = D3DFILL_SOLID;
+ device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ }
+
+ /*
+ if (debug && !isBackFaceMessOutput &&
+ (backFaceNormalFlip) && (cullFace != javax_media_j3d_PolygonAttributes_CULL_BACK)) {
+ isBackFaceMessOutput = true;
+ printf("BackFaceNormalFlip is not support !\n");
+ }
+ */
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetLineAttributes(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+
+ // D3D don't support Line width
+ // glLineWidth(1);
+
+ D3DLINEPATTERN pattern;
+ pattern.wRepeatFactor = 0;
+ pattern.wLinePattern = 0;
+ device->SetRenderState(D3DRS_LINEPATTERN,
+ *((LPDWORD) (&pattern)));
+
+
+}
+
+
+// Note that some graphics card don't support it.
+// In this case use RGB Emulation.
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_LineAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat lineWidth,
+ jint linePattern,
+ jint linePatternMask,
+ jint linePatternScaleFactor,
+ jboolean lineAntialiasing)
+{
+ GetDevice();
+
+ D3DLINEPATTERN pattern;
+
+ /*
+ if (lineWidth > 1) {
+ if (debug && !isLineWidthMessOutput) {
+ isLineWidthMessOutput = true;
+ printf("Line width > 1 not support !\n");
+ }
+ }
+ */
+ // glLineWidth(lineWidth);
+
+ if (linePattern == javax_media_j3d_LineAttributes_PATTERN_SOLID) {
+ pattern.wRepeatFactor = 0;
+ pattern.wLinePattern = 0;
+
+ } else {
+ /*
+ if (!d3dCtx->deviceInfo->linePatternSupport) {
+ if (debug && !isLinePatternMessOutput) {
+ printf("Device not support line pattern !\n");
+ isLinePatternMessOutput = false;
+ }
+ }
+ */
+ if (linePattern == javax_media_j3d_LineAttributes_PATTERN_DASH) { // dashed lines
+ pattern.wRepeatFactor = 1;
+ pattern.wLinePattern = 0x00ff;
+ } else if (linePattern == javax_media_j3d_LineAttributes_PATTERN_DOT) { // dotted lines
+ pattern.wRepeatFactor = 1;
+ pattern.wLinePattern = 0x0101;
+ } else if (linePattern == javax_media_j3d_LineAttributes_PATTERN_DASH_DOT) { // dash-dotted lines
+ pattern.wRepeatFactor = 1;
+ pattern.wLinePattern = 0x087f;
+ } else if (linePattern == javax_media_j3d_LineAttributes_PATTERN_USER_DEFINED) { // user-defined mask
+ pattern.wRepeatFactor = linePatternScaleFactor;
+ pattern.wLinePattern = (WORD) linePatternMask;
+ }
+ }
+
+ device->SetRenderState(D3DRS_LINEPATTERN,
+ *((LPDWORD) (&pattern)));
+
+ /*
+ if (lineAntialiasing == JNI_TRUE) {
+ glEnable (GL_LINE_SMOOTH);
+ } else {
+ glDisable (GL_LINE_SMOOTH);
+ }
+ */
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetPointAttributes(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+
+ if (d3dCtx->pointSize != 1.0f) {
+ d3dCtx->pointSize = 1.0f;
+ device->SetRenderState(D3DRS_POINTSIZE, *((LPDWORD) &d3dCtx->pointSize));
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_PointAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat pointSize,
+ jboolean pointAntialiasing)
+{
+ // point Antialiasing not support by D3D
+ GetDevice();
+
+ if (pointSize < 1.0f) {
+ // We don't want to set pointSize unnecessary and
+ // trigger the software vertex processing mode in
+ // D3DVertexBuffer if possible. It is an error
+ // to set pointSize to zero under OGL.
+ pointSize = 1.0f;
+ }
+
+ if (d3dCtx->pointSize != pointSize) {
+ device->SetRenderState(D3DRS_POINTSIZE, *((LPDWORD)
+ &pointSize));
+ d3dCtx->pointSize = pointSize;
+ }
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetTexCoordGeneration(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+
+ int tus = d3dCtx->texUnitStage;
+
+ if (tus >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+
+ d3dCtx->texGenMode[tus] = TEX_GEN_NONE;
+
+ if (d3dCtx->texTransformSet[tus]) {
+ device->SetTransform((D3DTRANSFORMSTATETYPE)
+ (D3DTS_TEXTURE0 + tus),
+ &(d3dCtx->texTransform[tus]));
+ }
+
+ device->SetTextureStageState(tus,
+ D3DTSS_TEXCOORDINDEX,
+ D3DTSS_TCI_PASSTHRU);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TexCoordGenerationRetained_updateNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jboolean enable,
+ jint genMode,
+ jint format,
+ jfloat planeSx,
+ jfloat planeSy,
+ jfloat planeSz,
+ jfloat planeSw,
+ jfloat planeTx,
+ jfloat planeTy,
+ jfloat planeTz,
+ jfloat planeTw,
+ jfloat planeRx,
+ jfloat planeRy,
+ jfloat planeRz,
+ jfloat planeRw,
+ jfloat planeQx,
+ jfloat planeQy,
+ jfloat planeQz,
+ jfloat planeQw,
+ jdoubleArray eyeToVworld)
+{
+
+ D3DXMATRIX m;
+ jdouble *mv;
+ GetDevice();
+
+ int tus = d3dCtx->texUnitStage;
+
+
+ if (tus >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+
+ if (!enable) {
+ device->SetTextureStageState(tus,
+ D3DTSS_TEXCOORDINDEX,
+ D3DTSS_TCI_PASSTHRU);
+ d3dCtx->texGenMode[tus] = TEX_GEN_NONE;
+ return;
+ }
+
+ d3dCtx->texCoordFormat[tus] = coordFormatTable[format];
+
+// printf("TexCoordGenerationRetained_updateNative texStage %d set Mode %d, format %d, texTransformSet %d\n", tus, genMode, format, d3dCtx->texTransformSet[tus]);
+
+ switch (genMode) {
+ case javax_media_j3d_TexCoordGeneration_EYE_LINEAR:
+ // Generated Coordinate = p1'*x + p2'*y + p3'*z + p4'*w;
+ // where (p1', p2', p3', p4') = (p1 p2 p3 p4)*eyeToVworld
+ mv = (jdouble * ) env->GetPrimitiveArrayCritical(eyeToVworld, 0);
+ m._11 = planeSx*mv[0] + planeSy*mv[4] + planeSz*mv[8] + planeSw*mv[12];
+ m._21 = planeSx*mv[1] + planeSy*mv[5] + planeSz*mv[9] + planeSw*mv[13];
+ m._31 = planeSx*mv[2] + planeSy*mv[6] + planeSz*mv[10] + planeSw*mv[14];
+ m._41 = planeSx*mv[3] + planeSy*mv[7] + planeSz*mv[11] + planeSw*mv[15];
+ m._12 = planeTx*mv[0] + planeTy*mv[4] + planeTz*mv[8] + planeTw*mv[12];
+ m._22 = planeTx*mv[1] + planeTy*mv[5] + planeTz*mv[9] + planeTw*mv[13];
+ m._32 = planeTx*mv[2] + planeTy*mv[6] + planeTz*mv[10] + planeTw*mv[14];
+ m._42 = planeTx*mv[3] + planeTy*mv[7] + planeTz*mv[11] + planeTw*mv[15];
+
+
+ if (format >= javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) {
+ m._13 = planeRx*mv[0] + planeRy*mv[4] + planeRz*mv[8] + planeRw*mv[12];
+ m._23 = planeRx*mv[1] + planeRy*mv[5] + planeRz*mv[9] + planeRw*mv[13];
+ m._33 = planeRx*mv[2] + planeRy*mv[6] + planeRz*mv[10] + planeRw*mv[14];
+ m._43 = planeRx*mv[3] + planeRy*mv[7] + planeRz*mv[11] + planeRw*mv[15];
+
+ if (format >= javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) {
+ m._14 = planeQx*mv[0] + planeQy*mv[4] + planeQz*mv[8] + planeQw*mv[12];
+ m._24 = planeQx*mv[1] + planeQy*mv[5] + planeQz*mv[9] + planeQw*mv[13];
+ m._34 = planeQx*mv[2] + planeQy*mv[6] + planeQz*mv[10] + planeQw*mv[14];
+ m._44 = planeQx*mv[3] + planeQy*mv[7] + planeQz*mv[11] + planeQw*mv[15];
+ } else {
+ m._14 = 0;
+ m._24 = 0;
+ m._34 = 0;
+ m._44 = 0;
+ }
+ } else {
+ m._13 = 0;
+ m._23 = 0;
+ m._33 = 0;
+ m._43 = 0;
+ m._14 = 0;
+ m._24 = 0;
+ m._34 = 0;
+ m._44 = 0;
+ }
+
+ env->ReleasePrimitiveArrayCritical(eyeToVworld, mv, 0);
+
+ if (d3dCtx->texTransformSet[tus]) {
+ device->MultiplyTransform((D3DTRANSFORMSTATETYPE)
+ (D3DTS_TEXTURE0 + tus) , &m);
+ } else {
+ device->SetTransform((D3DTRANSFORMSTATETYPE)
+ (D3DTS_TEXTURE0 + tus), &m);
+ d3dCtx->texTransformSet[tus] = true;
+ }
+ d3dCtx->texGenMode[tus] = TEX_EYE_LINEAR;
+
+ break;
+
+ case javax_media_j3d_TexCoordGeneration_SPHERE_MAP:
+ /*
+ The matrix has to scale and translate the texture coordinates
+ Since in sphere map Tx = Nx/2 + 0.5, Ty = Ny/2 + 0.5
+ */
+ m._11 = 0.5f; m._12 = 0.0f; m._13 = 0.0f; m._14 = 0.0f;
+ m._21 = 0.0f; m._22 = 0.5f; m._23 = 0.0f; m._24 = 0.0f;
+ m._31 = 0.0f; m._32 = 0.0f; m._33 = 1.0f; m._34 = 0.0f;
+ m._41 = 0.5f; m._42 = 0.5f; m._43 = 0.0f; m._44 = 1.0f;
+
+ if (d3dCtx->texTransformSet[tus]) {
+ // If texture transform already set, multiple by this
+ // matrix.
+ device->MultiplyTransform((D3DTRANSFORMSTATETYPE)
+ (D3DTS_TEXTURE0 + tus) , &m);
+ } else {
+ device->SetTransform((D3DTRANSFORMSTATETYPE)
+ (D3DTS_TEXTURE0 + tus), &m);
+ d3dCtx->texTransformSet[tus] = true;
+ }
+
+ d3dCtx->texGenMode[tus] = TEX_SPHERE_MAP;
+ break;
+ case javax_media_j3d_TexCoordGeneration_OBJECT_LINEAR:
+ // OBJECT_LINEAR not support by D3D, we'll do it ourselve.
+ d3dCtx->planeS[tus][0] = planeSx;
+ d3dCtx->planeS[tus][1] = planeSy;
+ d3dCtx->planeS[tus][2] = planeSz;
+ d3dCtx->planeS[tus][3] = planeSw;
+ d3dCtx->planeT[tus][0] = planeTx;
+ d3dCtx->planeT[tus][1] = planeTy;
+ d3dCtx->planeT[tus][2] = planeTz;
+ d3dCtx->planeT[tus][3] = planeTw;
+ d3dCtx->planeR[tus][0] = planeRx;
+ d3dCtx->planeR[tus][1] = planeRy;
+ d3dCtx->planeR[tus][2] = planeRz;
+ d3dCtx->planeR[tus][3] = planeRw;
+ d3dCtx->planeQ[tus][0] = planeQx;
+ d3dCtx->planeQ[tus][1] = planeQy;
+ d3dCtx->planeQ[tus][2] = planeQz;
+ d3dCtx->planeQ[tus][3] = planeQw;
+ d3dCtx->texGenMode[tus] = TEX_OBJ_LINEAR;
+ break;
+ case javax_media_j3d_TexCoordGeneration_NORMAL_MAP:
+ d3dCtx->texGenMode[tus] = TEX_NORMAL_MAP;
+ break;
+ case javax_media_j3d_TexCoordGeneration_REFLECTION_MAP:
+ d3dCtx->texGenMode[tus] = TEX_REFLECT_MAP;
+ break;
+ default:
+ printf("Unknown TexCoordinate Generation mode %d\n", genMode);
+ }
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetTextureAttributes(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+
+ int tus = d3dCtx->texUnitStage;
+
+ if (tus >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+
+ if (d3dCtx->texTransformSet[tus]) {
+ d3dCtx->texTransformSet[tus] = false;
+ device->SetTransform((D3DTRANSFORMSTATETYPE)
+ (D3DTS_TEXTURE0 + tus),
+ &identityMatrix);
+ }
+
+ // perspCorrectionMode always turn on in DX8.0 if device support
+
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jdoubleArray transform, jboolean isIdentityT,
+ jint textureMode,
+ jint perspCorrectionMode,
+ jfloat textureBlendColorRed,
+ jfloat textureBlendColorGreen,
+ jfloat textureBlendColorBlue,
+ jfloat textureBlendColorAlpha,
+ jint format)
+{
+
+ D3DCOLOR textureBlendColor;
+ BOOL alphaDisable = FALSE;
+
+ GetDevice();
+
+ int tus = d3dCtx->texUnitStage;
+
+ if (tus >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+
+ // perspCorrectionMode always turn on in DX8.0 if device support
+
+ if (isIdentityT) {
+ d3dCtx->texTransformSet[tus] = false;
+ device->SetTransform((D3DTRANSFORMSTATETYPE)
+ (D3DTS_TEXTURE0 + tus),
+ &identityMatrix);
+ } else {
+ D3DXMATRIX *m = &(d3dCtx->texTransform[tus]);
+ jdouble *mx_ptr = reinterpret_cast<jdouble *>(
+ env->GetPrimitiveArrayCritical(transform, NULL));
+ CopyTranspose((*m), mx_ptr);
+
+ env->ReleasePrimitiveArrayCritical(transform, mx_ptr, 0);
+ /*
+ printf("set Tex Transform \n");
+ printf("%f, %f, %f, %f\n", (*m)._11, (*m)._12, (*m)._13, (*m)._14);
+ printf("%f, %f, %f, %f\n", (*m)._21, (*m)._22, (*m)._23, (*m)._24);
+ printf("%f, %f, %f, %f\n", (*m)._31, (*m)._23, (*m)._33, (*m)._34);
+ printf("%f, %f, %f, %f\n", (*m)._41, (*m)._42, (*m)._43, (*m)._44);
+ */
+ d3dCtx->texTransformSet[tus] = true;
+ d3dCtx->texTranslateSet[tus] = false;
+ device->SetTransform((D3DTRANSFORMSTATETYPE)
+ (D3DTS_TEXTURE0 + tus), m);
+ }
+
+ /* set texture environment mode */
+
+ switch (textureMode) {
+ case javax_media_j3d_TextureAttributes_MODULATE:
+ switch (format) {
+ case J3D_RGBA:
+ case INTENSITY:
+ case LUMINANCE_ALPHA:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_MODULATE);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG2, D3DTA_CURRENT);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG2, D3DTA_CURRENT);
+ break;
+ case J3D_RGB:
+ case LUMINANCE:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_MODULATE);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG2, D3DTA_CURRENT);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+ break;
+ case ALPHA:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_CURRENT);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG2, D3DTA_CURRENT);
+ break;
+ default:
+ printf("Format %d not support\n", format);
+ }
+ break;
+ case javax_media_j3d_TextureAttributes_DECAL:
+ switch (format) {
+ case J3D_RGBA:
+ case INTENSITY:
+ case LUMINANCE_ALPHA:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG2, D3DTA_CURRENT);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+ break;
+ case J3D_RGB:
+ case LUMINANCE:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+ break;
+ case ALPHA:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_CURRENT);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ break;
+ default:
+ printf("Format %d not support\n", format);
+ }
+ break;
+ case javax_media_j3d_TextureAttributes_BLEND:
+ // Two pass is needed for this mode, the first pass
+ // will
+
+ textureBlendColor = D3DCOLOR_COLORVALUE(textureBlendColorRed,
+ textureBlendColorGreen,
+ textureBlendColorBlue,
+ textureBlendColorAlpha);
+
+ device->SetRenderState(D3DRS_TEXTUREFACTOR,
+ *((LPDWORD) &textureBlendColor));
+
+ switch (format) {
+ case ALPHA:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_CURRENT);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG2, D3DTA_CURRENT);
+ break;
+ case INTENSITY:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_CURRENT);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG2, D3DTA_TFACTOR);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_BLENDTEXTUREALPHA);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG1, D3DTA_CURRENT);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
+ break;
+ case J3D_RGB:
+ case LUMINANCE:
+ device->SetTextureStageState(0,
+ D3DTSS_ALPHAOP,
+ D3DTOP_DISABLE);
+ alphaDisable = TRUE;
+ // fallthrough
+ case J3D_RGBA:
+ case LUMINANCE_ALPHA:
+
+ if (!d3dCtx->deviceInfo->texLerpSupport) {
+ // Use two pass, first pass will enable specular and
+ // compute Cf*(1 - Ct), second pass will disable specular and
+ // comptue Cc*Ct. Note that multi-texturing is disable
+ // in this case, so stage 0 is always use.
+ device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ device->SetTextureStageState(0, D3DTSS_COLORARG1,
+ D3DTA_TEXTURE|D3DTA_COMPLEMENT);
+ device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
+
+ if (!alphaDisable) {
+ device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
+ }
+ } else {
+ device->SetTextureStageState(tus, D3DTSS_COLOROP, D3DTOP_LERP);
+ device->SetTextureStageState(tus, D3DTSS_COLORARG0, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+ device->SetTextureStageState(tus, D3DTSS_COLORARG2, D3DTA_CURRENT);
+
+ if (!alphaDisable) {
+ device->SetTextureStageState(tus, D3DTSS_ALPHAOP, D3DTOP_LERP);
+ device->SetTextureStageState(tus, D3DTSS_ALPHAARG0, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
+ device->SetTextureStageState(tus, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
+ }
+ }
+ break;
+ default:
+ printf("Format %d not support\n", format);
+ }
+
+
+ break;
+ case javax_media_j3d_TextureAttributes_REPLACE:
+ switch (format) {
+ case J3D_RGBA:
+ case INTENSITY:
+ case LUMINANCE_ALPHA:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ break;
+ case J3D_RGB:
+ case LUMINANCE:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+ break;
+ case ALPHA:
+ device->SetTextureStageState(tus,
+ D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_COLORARG1, D3DTA_CURRENT);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(tus,
+ D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ break;
+ default:
+ printf("Format %d not support\n", format);
+ }
+ break;
+ default:
+ // TEXTURE COMBINER case
+ break;
+ }
+}
+
+
+// This procedure is invoked after Blend2Pass to restore the original value
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureAttributesRetained_restoreBlend1Pass(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+
+ device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ device->SetTextureStageState(0, D3DTSS_COLORARG1,
+ D3DTA_TEXTURE|D3DTA_COMPLEMENT);
+ device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
+
+ device->SetRenderState(D3DRS_SRCBLEND,
+ d3dCtx->srcBlendFunc);
+ device->SetRenderState(D3DRS_DESTBLEND,
+ d3dCtx->dstBlendFunc);
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE,
+ d3dCtx->blendEnable);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateBlend2Pass(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+ device->GetRenderState(D3DRS_SRCBLEND,
+ &d3dCtx->srcBlendFunc);
+ device->GetRenderState(D3DRS_DESTBLEND,
+ &d3dCtx->dstBlendFunc);
+ device->GetRenderState(D3DRS_ALPHABLENDENABLE,
+ &d3dCtx->blendEnable);
+
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateCombinerNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint combineRgbMode,
+ jint combineAlphaMode,
+ jintArray combineRgbSrc,
+ jintArray combineAlphaSrc,
+ jintArray combineRgbFcn,
+ jintArray combineAlphaFcn,
+ jint combineRgbScale,
+ jint combineAlphaScale)
+{
+
+ GetDevice();
+
+ DWORD ts = d3dCtx->texUnitStage;
+
+ jint *rgbSrc = (jint *) env->GetPrimitiveArrayCritical(combineRgbSrc, NULL);
+ jint *alphaSrc = (jint *) env->GetPrimitiveArrayCritical(combineAlphaSrc, NULL);
+ jint *rgbFcn = (jint *) env->GetPrimitiveArrayCritical(combineRgbFcn, NULL);
+ jint *alphaFcn = (jint *) env->GetPrimitiveArrayCritical(combineAlphaFcn, NULL);
+
+
+ device->SetTextureStageState(ts, D3DTSS_COLOROP,
+ combineFunctionTable[(combineRgbMode << 2) + combineRgbScale]);
+
+ if (combineRgbMode != javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE) {
+ device->SetTextureStageState(ts, D3DTSS_COLORARG1,
+ combineSourceTable[(rgbSrc[0] << 2) + rgbFcn[0]]);
+ if (combineRgbMode != javax_media_j3d_TextureAttributes_COMBINE_REPLACE) {
+ device->SetTextureStageState(ts, D3DTSS_COLORARG2,
+ combineSourceTable[(rgbSrc[1] << 2) + rgbFcn[1]]);
+ }
+ } else {
+ device->SetTextureStageState(ts, D3DTSS_COLORARG1,
+ combineSourceTable[(rgbSrc[2] << 2) + rgbFcn[2]]);
+ device->SetTextureStageState(ts, D3DTSS_COLORARG2,
+ combineSourceTable[(rgbSrc[0] << 2) + rgbFcn[0]]);
+ device->SetTextureStageState(ts, D3DTSS_COLORARG0,
+ combineSourceTable[(rgbSrc[1] << 2) + rgbFcn[1]]);
+ }
+
+ device->SetTextureStageState(ts, D3DTSS_ALPHAOP,
+ combineFunctionTable[(combineAlphaMode << 2) + combineAlphaScale]);
+
+ if (combineAlphaMode != javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE) {
+ device->SetTextureStageState(ts, D3DTSS_ALPHAARG1,
+ combineSourceTable[(alphaSrc[0] << 2) + alphaFcn[0]]);
+ if (combineAlphaMode != javax_media_j3d_TextureAttributes_COMBINE_REPLACE) {
+ device->SetTextureStageState(ts, D3DTSS_ALPHAARG2,
+ combineSourceTable[(alphaSrc[1] << 2) + alphaFcn[1]]);
+ }
+ } else {
+ device->SetTextureStageState(ts, D3DTSS_ALPHAARG0,
+ combineSourceTable[(alphaSrc[2] << 2) + alphaFcn[2]]);
+ device->SetTextureStageState(ts, D3DTSS_ALPHAARG1,
+ combineSourceTable[(alphaSrc[0] << 2) + alphaFcn[0]]);
+ device->SetTextureStageState(ts, D3DTSS_ALPHAARG2,
+ combineSourceTable[(alphaSrc[1] << 2) + alphaFcn[1]]);
+ }
+
+ env->ReleasePrimitiveArrayCritical(combineRgbSrc, rgbSrc, 0);
+ env->ReleasePrimitiveArrayCritical(combineAlphaSrc, alphaSrc, 0);
+ env->ReleasePrimitiveArrayCritical(combineRgbFcn, rgbFcn, 0);
+ env->ReleasePrimitiveArrayCritical(combineAlphaFcn, alphaFcn, 0);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateTextureColorTableNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint numComponents,
+ jint colorTableSize,
+ jintArray textureColorTable)
+{
+ // Not support by D3D
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_updateMaterial(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat colorRed,
+ jfloat colorGreen,
+ jfloat colorBlue,
+ jfloat transparency)
+{
+ GetDevice();
+
+ d3dCtx->currentColor_r = colorRed;
+ d3dCtx->currentColor_g = colorGreen;
+ d3dCtx->currentColor_b = colorBlue;
+ d3dCtx->currentColor_a = transparency;
+
+ d3dCtx->isLightEnable = false;
+ device->SetRenderState(D3DRS_LIGHTING, false);
+ if (d3dCtx->resetColorTarget) {
+ device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE,
+ D3DMCS_COLOR1);
+ device->SetRenderState(D3DRS_SPECULARMATERIALSOURCE,
+ D3DMCS_MATERIAL);
+ device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE,
+ D3DMCS_MATERIAL);
+ device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE,
+ D3DMCS_MATERIAL);
+ d3dCtx->resetColorTarget = false;
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_MaterialRetained_updateNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat colorRed,
+ jfloat colorGreen,
+ jfloat colorBlue,
+ jfloat transparency,
+ jfloat aRed,
+ jfloat aGreen,
+ jfloat aBlue,
+ jfloat eRed,
+ jfloat eGreen,
+ jfloat eBlue,
+ jfloat dRed,
+ jfloat dGreen,
+ jfloat dBlue,
+ jfloat sRed,
+ jfloat sGreen,
+ jfloat sBlue,
+ jfloat shininess,
+ jint colorTarget,
+ jboolean lightEnable)
+{
+ D3DMATERIAL8 material;
+
+ GetDevice();
+
+ switch (colorTarget) {
+ case javax_media_j3d_Material_DIFFUSE:
+ device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE,
+ D3DMCS_COLOR1);
+ break;
+ case javax_media_j3d_Material_SPECULAR:
+ device->SetRenderState(D3DRS_SPECULARMATERIALSOURCE,
+ D3DMCS_COLOR1);
+ d3dCtx->resetColorTarget = true;
+ break;
+ case javax_media_j3d_Material_AMBIENT:
+ device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE,
+ D3DMCS_COLOR1);
+ d3dCtx->resetColorTarget = true;
+ break;
+ case javax_media_j3d_Material_AMBIENT_AND_DIFFUSE:
+ device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE,
+ D3DMCS_COLOR1);
+ device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE,
+ D3DMCS_COLOR1);
+ d3dCtx->resetColorTarget = true;
+ break;
+ case javax_media_j3d_Material_EMISSIVE:
+ device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE,
+ D3DMCS_COLOR1);
+ d3dCtx->resetColorTarget = true;
+ break;
+ default:
+ printf("Material updateNative: Uknown colorTarget %d\n", colorTarget);
+ }
+
+ material.Power = shininess;
+
+ CopyColor(material.Emissive, eRed, eGreen, eBlue, 1.0f);
+ CopyColor(material.Ambient, aRed, aGreen, aBlue, 1.0f);
+ CopyColor(material.Specular, sRed, sGreen, sBlue, 1.0f);
+
+ d3dCtx->currentColor_a = transparency;
+
+ if (lightEnable) {
+ d3dCtx->currentColor_r = dRed;
+ d3dCtx->currentColor_g = dGreen;
+ d3dCtx->currentColor_b = dBlue;
+
+ CopyColor(material.Diffuse, dRed, dGreen, dBlue,
+ transparency);
+
+ } else {
+ d3dCtx->currentColor_r = colorRed;
+ d3dCtx->currentColor_g = colorGreen;
+ d3dCtx->currentColor_b = colorBlue;
+
+ CopyColor(material.Diffuse, colorRed, colorGreen,
+ colorBlue, transparency);
+ }
+
+
+ d3dCtx->isLightEnable = lightEnable;
+ device->SetRenderState(D3DRS_LIGHTING, lightEnable);
+ device->SetMaterial(&material);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetTransparency(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint geometryType,
+ jint polygonMode,
+ jboolean lineAA,
+ jboolean pointAA)
+{
+ GetDevice();
+
+ // Line/Point Antialiasing not support
+
+ /*
+ if (((((geometryType & LINE) != 0) || polygonMode == POLYGON_LINE)
+ && lineAA == JNI_TRUE) ||
+ ((((geometryType & _POINT) != 0) || polygonMode == POLYGON_POINT)
+ && pointAA == JNI_TRUE)) {
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ } else {
+ */
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ // }
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TransparencyAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject tr,
+ jlong ctx,
+ jfloat transparency,
+ jint geometryType,
+ jint polygonMode,
+ jboolean lineAA,
+ jboolean pointAA,
+ jint transparencyMode,
+ jint srcBlendFunction,
+ jint dstBlendFunction)
+{
+
+ GetDevice();
+
+ // No screen door transparency in D3D, use BLENDED
+ // Don't know how to use STIPPLEDALPHA either.
+ /*
+ if (transparencyMode != TRANS_SCREEN_DOOR) {
+ device->SetRenderState(D3DRS_STIPPLEDALPHA, FALSE);
+ } else {
+ device->SetRenderState(D3DRS_STIPPLEDALPHA, TRUE);
+ }
+ */
+
+ if (transparencyMode < javax_media_j3d_TransparencyAttributes_NONE) {
+ /*
+ ((((geometryType & LINE) != 0) || polygonMode == POLYGON_LINE)
+ && lineAA == JNI_TRUE) ||
+ ((((geometryType & _POINT) != 0) || polygonMode == POLYGON_POINT)
+ && pointAA == JNI_TRUE)) {
+ */
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ device->SetRenderState(D3DRS_SRCBLEND,
+ blendFunctionTable[srcBlendFunction]);
+ device->SetRenderState(D3DRS_DESTBLEND,
+ blendFunctionTable[dstBlendFunction]);
+ } else {
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ }
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetColoringAttributes(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat colorRed,
+ jfloat colorGreen,
+ jfloat colorBlue,
+ jfloat transparency,
+ jboolean lightEnable)
+{
+
+ GetDevice();
+
+ if (!lightEnable) {
+ d3dCtx->currentColor_r = colorRed;
+ d3dCtx->currentColor_g = colorGreen;
+ d3dCtx->currentColor_b = colorBlue;
+ d3dCtx->currentColor_a = transparency;
+ }
+ device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
+ // No line smooth in D3D
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_ColoringAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat dRed,
+ jfloat dGreen,
+ jfloat dBlue,
+ jfloat colorRed,
+ jfloat colorGreen,
+ jfloat colorBlue,
+ jfloat transparency,
+ jboolean lightEnable,
+ jint shadeModel)
+{
+
+ GetDevice();
+
+ d3dCtx->currentColor_a = transparency;
+ if (lightEnable) {
+ d3dCtx->currentColor_r = dRed;
+ d3dCtx->currentColor_g = dGreen;
+ d3dCtx->currentColor_b = dBlue;
+ } else {
+ d3dCtx->currentColor_r = colorRed;
+ d3dCtx->currentColor_g = colorGreen;
+ d3dCtx->currentColor_b = colorBlue;
+ }
+
+
+ if (shadeModel == javax_media_j3d_ColoringAttributes_SHADE_FLAT) {
+ device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
+ } else {
+ device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
+ }
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetTextureNative(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint texUnitIndex)
+{
+ GetDevice();
+
+ if (texUnitIndex < 0) {
+ texUnitIndex = 0;
+ }
+
+ d3dCtx->texUnitStage = texUnitIndex;
+
+ if (texUnitIndex >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+ device->SetTexture(texUnitIndex, NULL);
+ d3dCtx->bindTextureId[texUnitIndex] = -1;
+
+ if (d3dCtx->texTransformSet[texUnitIndex]) {
+ d3dCtx->texTransformSet[texUnitIndex] = false;
+ device->SetTransform((D3DTRANSFORMSTATETYPE)
+ (D3DTS_TEXTURE0 + texUnitIndex),
+ &identityMatrix);
+ }
+ d3dCtx->texGenMode[texUnitIndex] = TEX_GEN_NONE;
+ device->SetTextureStageState(texUnitIndex,
+ D3DTSS_TEXCOORDINDEX,
+ D3DTSS_TCI_PASSTHRU);
+ device->SetTextureStageState(texUnitIndex,
+ D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(texUnitIndex,
+ D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(texUnitIndex,
+ D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(texUnitIndex,
+ D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_bindTexture(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint objectId,
+ jboolean enable)
+{
+ GetDevice();
+
+ if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+
+ if (!enable) {
+ device->SetTexture(d3dCtx->texUnitStage, NULL);
+ d3dCtx->bindTextureId[d3dCtx->texUnitStage] = -1;
+ } else {
+ if (d3dCtx->bindTextureId[d3dCtx->texUnitStage] == objectId) {
+ return;
+ }
+
+ if (objectId >= d3dCtx->textureTableLen) {
+ DWORD i;
+ DWORD len = max(objectId+1, d3dCtx->textureTableLen << 1);
+ LPDIRECT3DTEXTURE8 *newTable = (LPDIRECT3DTEXTURE8 *)
+ malloc(sizeof(LPDIRECT3DTEXTURE8) * len);
+
+ if (newTable == NULL) {
+ printf("Not enough memory to alloc texture table of size %d.\n", len);
+ return;
+ }
+ for (i=0; i < d3dCtx->textureTableLen; i++) {
+ newTable[i] = d3dCtx->textureTable[i];
+ }
+ for (i=d3dCtx->textureTableLen; i < len; i++) {
+ newTable[i] = NULL;
+ }
+ d3dCtx->textureTableLen = len;
+ SafeFree(d3dCtx->textureTable);
+ d3dCtx->textureTable = newTable;
+ }
+
+ d3dCtx->bindTextureId[d3dCtx->texUnitStage] = objectId;
+ if (d3dCtx->textureTable[objectId] != NULL) {
+ device->SetTexture(d3dCtx->texUnitStage,
+ d3dCtx->textureTable[objectId]);
+ }
+ // else we will bind this in updateTextureImage
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureFilterModes(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint minFilter,
+ jint magFilter)
+{
+ GetDevice();
+
+
+ if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+
+ d3dCtx->texLinearMode = false;
+
+ /* set texture min filter */
+ switch (minFilter) {
+ case javax_media_j3d_Texture_FASTEST:
+ case javax_media_j3d_Texture_BASE_LEVEL_POINT:
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MINFILTER, D3DTEXF_POINT);
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MIPFILTER, D3DTEXF_POINT);
+ break;
+ case javax_media_j3d_Texture_BASE_LEVEL_LINEAR:
+ d3dCtx->texLinearMode = true;
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MINFILTER, D3DTEXF_LINEAR);
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MIPFILTER, D3DTEXF_POINT);
+ break;
+ case javax_media_j3d_Texture_MULTI_LEVEL_POINT:
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MINFILTER, D3DTEXF_POINT);
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
+ break;
+ case javax_media_j3d_Texture_NICEST:
+ case javax_media_j3d_Texture_MULTI_LEVEL_LINEAR:
+ d3dCtx->texLinearMode = true;
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MINFILTER, D3DTEXF_LINEAR);
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
+ break;
+ }
+
+ /* set texture mag filter */
+ switch (magFilter) {
+ case javax_media_j3d_Texture_FASTEST:
+ case javax_media_j3d_Texture_BASE_LEVEL_POINT:
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MAGFILTER, D3DTEXF_POINT);
+ break;
+ case javax_media_j3d_Texture_NICEST:
+ case javax_media_j3d_Texture_BASE_LEVEL_LINEAR:
+ d3dCtx->texLinearMode = true;
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
+ break;
+ }
+
+ return;
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureLodRange(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint baseLevel,
+ jint maximumLevel,
+ jfloat minimumLod,
+ jfloat maximumLod)
+{
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureLodOffset(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jfloat lodOffsetS,
+ jfloat lodOffsetT,
+ jfloat lodOffsetR)
+{
+ /* not supported */
+}
+
+void updateTextureBoundary(JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint boundaryModeS,
+ jint boundaryModeT,
+ jint boundaryModeR,
+ jfloat boundaryRed,
+ jfloat boundaryGreen,
+ jfloat boundaryBlue,
+ jfloat boundaryAlpha)
+{
+ GetDevice();
+
+
+ if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+
+ /* set texture wrap parameter */
+ BOOL useBorderMode = FALSE;
+
+ // D3D ignored border color in CLAMP mode.
+ // Instead D3D use Border color in D3DTADDRESS_BORDER only.
+ // So we approximate the effect by using D3DTADDRESS_BORDER
+ // mode if linear filtering mode is used.
+
+ switch (boundaryModeS) {
+ case javax_media_j3d_Texture_WRAP:
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_ADDRESSU,
+ D3DTADDRESS_WRAP);
+ break;
+ case javax_media_j3d_Texture_CLAMP:
+ if (!d3dCtx->texLinearMode || !d3dCtx->deviceInfo->texBorderModeSupport) {
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_ADDRESSU,
+ D3DTADDRESS_CLAMP);
+ } else {
+ useBorderMode = TRUE;
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_ADDRESSU,
+ D3DTADDRESS_BORDER);
+ }
+ break;
+ }
+
+ switch (boundaryModeT) {
+ case javax_media_j3d_Texture_WRAP:
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_ADDRESSV,
+ D3DTADDRESS_WRAP);
+ break;
+ case javax_media_j3d_Texture_CLAMP:
+ if (!d3dCtx->texLinearMode || !d3dCtx->deviceInfo->texBorderModeSupport) {
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_ADDRESSV,
+ D3DTADDRESS_CLAMP);
+ } else {
+ useBorderMode = TRUE;
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_ADDRESSV,
+ D3DTADDRESS_BORDER);
+ }
+ break;
+ }
+
+ if (boundaryModeR >= 0) {
+ switch (boundaryModeR) {
+ case javax_media_j3d_Texture_WRAP:
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_ADDRESSW,
+ D3DTADDRESS_WRAP);
+ break;
+ case javax_media_j3d_Texture_CLAMP:
+ if (!d3dCtx->texLinearMode || !d3dCtx->deviceInfo->texBorderModeSupport) {
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_ADDRESSW,
+ D3DTADDRESS_CLAMP);
+ } else {
+ useBorderMode = TRUE;
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_ADDRESSW,
+ D3DTADDRESS_BORDER);
+ }
+ break;
+ }
+ }
+
+ if (useBorderMode) {
+ D3DCOLOR color = D3DCOLOR_COLORVALUE(boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_BORDERCOLOR,
+ *((DWORD *) &color));
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureBoundary(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint boundaryModeS,
+ jint boundaryModeT,
+ jfloat boundaryRed,
+ jfloat boundaryGreen,
+ jfloat boundaryBlue,
+ jfloat boundaryAlpha)
+{
+ updateTextureBoundary(env, texture, ctx, boundaryModeS,
+ boundaryModeT, -1,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureSharpenFunc(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint numPts,
+ jfloatArray pts)
+{
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureFilter4Func(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint numPts,
+ jfloatArray pts)
+{
+}
+
+
+void updateTextureAnisotropicFilter(
+ jlong ctx,
+ jfloat degree)
+{
+ GetDevice();
+
+ if (degree > 1) {
+ DWORD deg = degree + 0.5f; // round float to int
+ // This will overwrite the previous setting in
+ // updateTextureFilterModes()
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MINFILTER,
+ D3DTEXF_ANISOTROPIC);
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MAGFILTER,
+ D3DTEXF_ANISOTROPIC);
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MIPFILTER,
+ D3DTEXF_ANISOTROPIC);
+
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MAXANISOTROPY, deg);
+ } else {
+ // updateTextureFilterModes() will always invoke before
+ // updateTextureAnisotropicFilter() to set Filter mode
+ // correctly.
+ device->SetTextureStageState(d3dCtx->texUnitStage,
+ D3DTSS_MAXANISOTROPY, 1);
+ }
+
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureAnisotropicFilter(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jfloat degree)
+{
+ updateTextureAnisotropicFilter(ctx, degree);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureAnisotropicFilter(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jfloat degree)
+{
+ GetCtx();
+
+ if (d3dCtx->deviceInfo->maxTextureDepth > 0) {
+ updateTextureAnisotropicFilter(ctx, degree);
+ }
+
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureAnisotropicFilter(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jfloat degree)
+{
+ updateTextureAnisotropicFilter(ctx, degree);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureSubImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint level,
+ jint xoffset,
+ jint yoffset,
+ jint internalFormat,
+ jint storedFormat,
+ jint imgXOffset,
+ jint imgYOffset,
+ jint tilew,
+ jint width,
+ jint height,
+ jbyteArray image)
+{
+ GetDevice();
+
+ if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+
+ INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage];
+
+ if ((currBindTex < 1) ||
+ (currBindTex >= d3dCtx->textureTableLen)) {
+ if (debug) {
+ printf("Internal Error : UpdateTextureSubImage bind texture ID %d, textureTableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->textureTableLen, d3dCtx->texUnitStage);
+ }
+ return;
+ }
+
+ LPDIRECT3DTEXTURE8 surf = d3dCtx->textureTable[currBindTex];
+
+ if ((surf == NULL) ||
+ ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap))) {
+ return;
+ }
+
+ // update Image data
+ if (storedFormat != FORMAT_USHORT_GRAY) {
+ jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(image, NULL);
+ copyDataToSurface(storedFormat, internalFormat, xoffset, yoffset,
+ imgXOffset, imgYOffset,
+ width, height, tilew, byteData,
+ surf, level);
+ env->ReleasePrimitiveArrayCritical(image, byteData, 0);
+
+ } else {
+ jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(image, NULL);
+ copyDataToSurface(storedFormat, internalFormat, xoffset, yoffset,
+ imgXOffset, imgYOffset,
+ width, height, tilew, shortData,
+ surf, level);
+ env->ReleasePrimitiveArrayCritical(image, shortData, 0);
+ }
+
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint numLevels,
+ jint level,
+ jint internalFormat,
+ jint format,
+ jint width,
+ jint height,
+ jint boundaryWidth,
+ jbyteArray imageYup)
+{
+ GetDevice();
+
+
+
+ if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) {
+ if (debug) {
+ printf("Internal Error: texUnitState %d, bindTextureIDLen %d\n",
+ d3dCtx->texUnitStage, d3dCtx->bindTextureIdLen);
+ }
+ return;
+ }
+
+
+ INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage];
+
+ if ((currBindTex < 1) ||
+ (currBindTex >= d3dCtx->textureTableLen)) {
+ if (debug) {
+ printf("Internal Error : UpdateTextureImage bind texture ID %d, textureTableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->textureTableLen, d3dCtx->texUnitStage);
+ }
+ return;
+ }
+
+ LPDIRECT3DTEXTURE8 surf = d3dCtx->textureTable[currBindTex];
+
+ if (level == 0) {
+ if (surf != NULL) {
+ // see if no. of mipmap level change
+
+ if (surf->GetLevelCount() != numLevels) {
+ d3dCtx->freeResource(surf);
+ d3dCtx->textureTable[currBindTex] = NULL;
+ surf = NULL;
+ }
+ }
+
+ if (surf == NULL) {
+ // Need to create surface
+ surf = createTextureSurface(d3dCtx, numLevels, internalFormat,
+ width, height);
+
+ if (surf == NULL) {
+ return;
+ }
+
+ d3dCtx->textureTable[currBindTex] = surf;
+ }
+ } else {
+ if (surf == NULL) {
+ return;
+ }
+ }
+
+ if ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap)) {
+ if (debug) {
+ printf("mipmap not support\n");
+ }
+ return;
+ }
+
+ // update Image data
+ if (imageYup != NULL) {
+ if (format != FORMAT_USHORT_GRAY) {
+ jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(imageYup, NULL);
+ copyDataToSurface(format, internalFormat, 0, 0, 0, 0,
+ width, height, width, byteData,
+ surf, level);
+ env->ReleasePrimitiveArrayCritical(imageYup, byteData, 0);
+
+ } else {
+ jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(imageYup, NULL);
+ copyDataToSurface(format, internalFormat, 0, 0, 0, 0,
+ width, height, width, shortData,
+ surf, level);
+ env->ReleasePrimitiveArrayCritical(imageYup, shortData, 0);
+ }
+ }
+
+
+ device->SetTexture(d3dCtx->texUnitStage, surf);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture2DRetained_bindTexture(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint objectId,
+ jboolean enable)
+{
+ Java_javax_media_j3d_TextureRetained_bindTexture(env, texture,
+ ctx, objectId, enable);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture2DRetained_updateTextureSubImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint level,
+ jint xoffset,
+ jint yoffset,
+ jint internalFormat,
+ jint storedFormat,
+ jint imgXOffset,
+ jint imgYOffset,
+ jint tilew,
+ jint width,
+ jint height,
+ jbyteArray image)
+{
+ Java_javax_media_j3d_TextureRetained_updateTextureSubImage(
+ env, texture, ctx, level, xoffset, yoffset, internalFormat,
+ storedFormat, imgXOffset, imgYOffset, tilew, width, height, image);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture2DRetained_updateTextureImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint numLevels,
+ jint level,
+ jint internalFormat,
+ jint format,
+ jint width,
+ jint height,
+ jint boundaryWidth,
+ jbyteArray imageYup)
+{
+ Java_javax_media_j3d_TextureRetained_updateTextureImage(env, texture,
+ ctx, numLevels, level, internalFormat, format,
+ width, height, boundaryWidth, imageYup);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture2DRetained_updateDetailTextureParameters(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint detailTextureMode,
+ jint detailTextureLevel,
+ jint numPts,
+ jfloatArray funcPts)
+{
+ // Not support
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_bindTexture(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint objectId,
+ jboolean enable)
+{
+ GetDevice();
+
+ if ((d3dCtx->deviceInfo->maxTextureDepth <= 0) ||
+ (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen)) {
+ return;
+ }
+
+ if (!enable) {
+ device->SetTexture(d3dCtx->texUnitStage, NULL);
+ d3dCtx->bindTextureId[d3dCtx->texUnitStage] = -1;
+ } else {
+ if (d3dCtx->bindTextureId[d3dCtx->texUnitStage] == objectId) {
+ return;
+ }
+ if (objectId >= d3dCtx->volumeTableLen) {
+ DWORD i;
+ DWORD len = max(objectId+1, d3dCtx->volumeTableLen << 1);
+ LPDIRECT3DVOLUMETEXTURE8 *newTable = (LPDIRECT3DVOLUMETEXTURE8 *)
+ malloc(sizeof(LPDIRECT3DVOLUMETEXTURE8) * len);
+
+ if (newTable == NULL) {
+ printf("Not enough memory to alloc volume texture table of size %d.\n", len);
+ return;
+ }
+ for (i=0; i < d3dCtx->volumeTableLen; i++) {
+ newTable[i] = d3dCtx->volumeTable[i];
+ }
+ for (i=d3dCtx->volumeTableLen; i < len; i++) {
+ newTable[i] = NULL;
+ }
+ d3dCtx->volumeTableLen = len;
+ SafeFree(d3dCtx->volumeTable);
+ d3dCtx->volumeTable = newTable;
+ }
+
+ d3dCtx->bindTextureId[d3dCtx->texUnitStage] = objectId;
+ if (d3dCtx->volumeTable[objectId] != NULL) {
+ device->SetTexture(d3dCtx->texUnitStage,
+ d3dCtx->volumeTable[objectId]);
+ }
+ // else we will bind this in updateTextureImage
+ }
+
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureFilterModes(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint minFilter,
+ jint magFilter)
+{
+ GetCtx();
+
+ if (d3dCtx->deviceInfo->maxTextureDepth > 0) {
+ Java_javax_media_j3d_TextureRetained_updateTextureFilterModes(
+ env, texture, ctx, minFilter, magFilter);
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureLodRange(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint baseLevel,
+ jint maximumLevel,
+ jfloat minimumLod,
+ jfloat maximumLod)
+{
+ // Not support
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureLodOffset(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jfloat lodOffsetS,
+ jfloat lodOffsetT,
+ jfloat lodOffsetR)
+{
+ /* not supported */
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureBoundary(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint boundaryModeS,
+ jint boundaryModeT,
+ jint boundaryModeR,
+ jfloat boundaryRed,
+ jfloat boundaryGreen,
+ jfloat boundaryBlue,
+ jfloat boundaryAlpha)
+{
+
+ GetCtx();
+
+ if (d3dCtx->deviceInfo->maxTextureDepth > 0) {
+
+ updateTextureBoundary(
+ env, texture, ctx,
+ boundaryModeS,
+ boundaryModeT,
+ boundaryModeR,
+ boundaryRed,
+ boundaryGreen,
+ boundaryBlue,
+ boundaryAlpha);
+ }
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint numLevels,
+ jint level,
+ jint internalFormat,
+ jint format,
+ jint width,
+ jint height,
+ jint depth,
+ jint boundaryWidth,
+ jbyteArray imageYup)
+{
+
+ GetDevice();
+
+ if (d3dCtx->deviceInfo->maxTextureDepth <= 0) {
+ return;
+ }
+
+ if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) {
+ if (debug) {
+ printf("Internal Error: texUnitState %d, bindTextureIDLen %d\n",
+ d3dCtx->texUnitStage, d3dCtx->bindTextureIdLen);
+ }
+ return;
+ }
+
+
+ INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage];
+
+ if ((currBindTex < 1) ||
+ (currBindTex >= d3dCtx->volumeTableLen)) {
+ if (debug) {
+ printf("Internal Error : UpdateTexture3DImage bind texture ID %d, volumeTableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->volumeTableLen, d3dCtx->texUnitStage);
+ }
+ return;
+ }
+
+ LPDIRECT3DVOLUMETEXTURE8 surf = d3dCtx->volumeTable[currBindTex];
+
+ if (level == 0) {
+ if (surf != NULL) {
+ // see if no. of mipmap level change
+
+ if (surf->GetLevelCount() != numLevels) {
+ d3dCtx->freeResource(surf);
+ d3dCtx->volumeTable[currBindTex] = NULL;
+ surf = NULL;
+ }
+ }
+
+ if (surf == NULL) {
+ surf = createVolumeTexture(d3dCtx, numLevels, internalFormat,
+ width, height, depth);
+ if (surf == NULL) {
+ return;
+ }
+
+ d3dCtx->volumeTable[currBindTex] = surf;
+ }
+ } else {
+ if (surf == NULL) {
+ return;
+ }
+ }
+
+ if ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap)) {
+ if (debug) {
+ printf("mipmap not support\n");
+ }
+ return;
+ }
+
+ // update Image data
+ if (imageYup != NULL) {
+ if (format != FORMAT_USHORT_GRAY) {
+ jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(imageYup, NULL);
+ copyDataToVolume(format, internalFormat, 0, 0, 0, 0, 0, 0,
+ width, height, depth, width, height, byteData,
+ surf, level);
+ env->ReleasePrimitiveArrayCritical(imageYup, byteData, 0);
+
+ } else {
+ jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(imageYup, NULL);
+ copyDataToVolume(format, internalFormat, 0, 0, 0, 0, 0, 0,
+ width, height, depth, width, height, shortData,
+ surf, level);
+ env->ReleasePrimitiveArrayCritical(imageYup, shortData, 0);
+ }
+ }
+ device->SetTexture(d3dCtx->texUnitStage, surf);
+
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureSubImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint level,
+ jint xoffset,
+ jint yoffset,
+ jint zoffset,
+ jint internalFormat,
+ jint storedFormat,
+ jint imgXOffset,
+ jint imgYOffset,
+ jint imgZOffset,
+ jint tilew,
+ jint tileh,
+ jint width,
+ jint height,
+ jint depth,
+ jbyteArray image)
+{
+ GetDevice();
+
+ if ((d3dCtx->deviceInfo->maxTextureDepth <= 0) ||
+ (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen)) {
+ return;
+ }
+
+ INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage];
+
+ if ((currBindTex < 1) ||
+ (currBindTex >= d3dCtx->volumeTableLen)) {
+ if (debug) {
+ printf("Internal Error : UpdateTexture3DSubImage bind texture ID %d, volumeableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->volumeTableLen, d3dCtx->texUnitStage);
+ }
+ return;
+ }
+
+ LPDIRECT3DVOLUMETEXTURE8 surf = d3dCtx->volumeTable[currBindTex];
+
+ if ((surf == NULL) ||
+ ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap))) {
+ return;
+ }
+
+ // update Image data
+ if (storedFormat != FORMAT_USHORT_GRAY) {
+ jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(image, NULL);
+ copyDataToVolume(storedFormat, internalFormat, xoffset,
+ yoffset, zoffset, imgXOffset, imgYOffset,
+ imgZOffset, width, height, depth,
+ tilew, tileh, byteData,
+ surf, level);
+ env->ReleasePrimitiveArrayCritical(image, byteData, 0);
+
+ } else {
+ jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(image, NULL);
+ copyDataToVolume(storedFormat, internalFormat, xoffset,
+ yoffset, zoffset,
+ imgXOffset, imgYOffset, imgZOffset,
+ width, height, depth, tilew, tileh, shortData,
+ surf, level);
+ env->ReleasePrimitiveArrayCritical(image, shortData, 0);
+ }
+
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_bindTexture(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint objectId,
+ jboolean enable)
+{
+ GetDevice();
+
+ if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+
+ if (!enable) {
+ device->SetTexture(d3dCtx->texUnitStage, NULL);
+ d3dCtx->bindTextureId[d3dCtx->texUnitStage] = -1;
+ } else {
+
+ if (d3dCtx->bindTextureId[d3dCtx->texUnitStage] == objectId) {
+ return;
+ }
+
+ if (objectId >= d3dCtx->cubeMapTableLen) {
+ DWORD i;
+ DWORD len = max(objectId+1, d3dCtx->cubeMapTableLen << 1);
+ LPDIRECT3DCUBETEXTURE8 *newTable = (LPDIRECT3DCUBETEXTURE8 *)
+ malloc(sizeof(LPDIRECT3DCUBETEXTURE8) * len);
+
+ if (newTable == NULL) {
+ printf("Not enough memory to alloc cubeMap table of size %d.\n", len);
+ return;
+ }
+ for (i=0; i < d3dCtx->cubeMapTableLen; i++) {
+ newTable[i] = d3dCtx->cubeMapTable[i];
+ }
+ for (i=d3dCtx->cubeMapTableLen; i < len; i++) {
+ newTable[i] = NULL;
+ }
+ d3dCtx->cubeMapTableLen = len;
+ SafeFree(d3dCtx->cubeMapTable);
+ d3dCtx->cubeMapTable = newTable;
+ }
+
+ d3dCtx->bindTextureId[d3dCtx->texUnitStage] = objectId;
+ if (d3dCtx->cubeMapTable[objectId] != NULL) {
+ device->SetTexture(d3dCtx->texUnitStage,
+ d3dCtx->cubeMapTable[objectId]);
+ }
+ // else we will bind this in updateTextureImage
+ }
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureFilterModes(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint minFilter,
+ jint magFilter)
+{
+ Java_javax_media_j3d_TextureRetained_updateTextureFilterModes(env,
+ texture, ctx, minFilter, magFilter);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureLodRange(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint baseLevel,
+ jint maximumLevel,
+ jfloat minimumLod,
+ jfloat maximumLod)
+{
+ // not support
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureLodOffset(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jfloat lodOffsetS,
+ jfloat lodOffsetT,
+ jfloat lodOffsetR)
+{
+ /* not supported */
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureBoundary(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint boundaryModeS,
+ jint boundaryModeT,
+ jfloat boundaryRed,
+ jfloat boundaryGreen,
+ jfloat boundaryBlue,
+ jfloat boundaryAlpha)
+{
+ updateTextureBoundary(env, texture, ctx, boundaryModeS,
+ boundaryModeT, -1, boundaryRed,
+ boundaryGreen, boundaryBlue,
+ boundaryAlpha);
+
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureSubImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint face,
+ jint level,
+ jint xoffset,
+ jint yoffset,
+ jint internalFormat,
+ jint storedFormat,
+ jint imgXOffset,
+ jint imgYOffset,
+ jint tilew,
+ jint width,
+ jint height,
+ jbyteArray image)
+{
+ GetDevice();
+
+ if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) {
+ return;
+ }
+
+ INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage];
+
+ if ((currBindTex < 1) ||
+ (currBindTex >= d3dCtx->cubeMapTableLen)) {
+ if (debug) {
+ printf("Internal Error : UpdateCubeMapSubImage bind texture ID %d, cubeMapTableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->cubeMapTableLen, d3dCtx->texUnitStage);
+ }
+ return;
+ }
+
+ LPDIRECT3DCUBETEXTURE8 surf = d3dCtx->cubeMapTable[currBindTex];
+
+ if ((surf == NULL) ||
+ ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap))) {
+ return;
+ }
+
+ // update Image data
+ if (storedFormat != FORMAT_USHORT_GRAY) {
+ jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(image, NULL);
+ copyDataToCubeMap(storedFormat, internalFormat,
+ xoffset, yoffset,
+ imgXOffset, imgYOffset,
+ width, height,
+ tilew, byteData,
+ surf, level, face);
+ env->ReleasePrimitiveArrayCritical(image, byteData, 0);
+
+ } else {
+ jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(image, NULL);
+ copyDataToCubeMap(storedFormat, internalFormat,
+ xoffset, yoffset,
+ imgXOffset, imgYOffset,
+ width, height,
+ tilew, shortData,
+ surf, level, face);
+ env->ReleasePrimitiveArrayCritical(image, shortData, 0);
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint face,
+ jint numLevels,
+ jint level,
+ jint internalFormat,
+ jint format,
+ jint width,
+ jint height,
+ jint boundaryWidth,
+ jbyteArray imageYup)
+{
+ GetDevice();
+
+ if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) {
+ if (debug) {
+ printf("Internal Error: texUnitState %d, bindTextureIDLen %d\n",
+ d3dCtx->texUnitStage, d3dCtx->bindTextureIdLen);
+ }
+ return;
+ }
+
+
+ INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage];
+
+ if ((currBindTex < 1) ||
+ (currBindTex >= d3dCtx->cubeMapTableLen)) {
+ if (debug) {
+ printf("Internal Error : UpdateCubeMapImage bind texture ID %d, cubeMapTableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->cubeMapTableLen, d3dCtx->texUnitStage);
+ }
+ return;
+ }
+
+ LPDIRECT3DCUBETEXTURE8 surf = d3dCtx->cubeMapTable[currBindTex];
+
+ if (level == 0) {
+ if (surf != NULL) {
+ // see if no. of mipmap level change
+
+ if (surf->GetLevelCount() != numLevels) {
+ d3dCtx->freeResource(surf);
+ d3dCtx->cubeMapTable[currBindTex] = NULL;
+ surf = NULL;
+ }
+ }
+
+ if (surf == NULL) {
+ // Need to create surface
+ surf = createCubeMapTexture(d3dCtx, numLevels, internalFormat,
+ width, height);
+ if (surf == NULL) {
+ return;
+ }
+
+ d3dCtx->cubeMapTable[currBindTex] = surf;
+ }
+ } else {
+ if (surf == NULL) {
+ return;
+ }
+ }
+
+ if ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap)) {
+ if (debug) {
+ printf("mipmap not support\n");
+ }
+ return;
+ }
+
+ // update Image data
+ if (imageYup != NULL) {
+ if (format != FORMAT_USHORT_GRAY) {
+ jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(imageYup, NULL);
+ copyDataToCubeMap(format, internalFormat, 0, 0, 0, 0,
+ width, height, width, byteData,
+ surf, level, face);
+ env->ReleasePrimitiveArrayCritical(imageYup, byteData, 0);
+
+ } else {
+ jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(imageYup, NULL);
+ copyDataToCubeMap(format, internalFormat, 0, 0, 0, 0,
+ width, height, width, shortData,
+ surf, level, face);
+ env->ReleasePrimitiveArrayCritical(imageYup, shortData, 0);
+ }
+ }
+
+ device->SetTexture(d3dCtx->texUnitStage, surf);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_DetailTextureImage_bindTexture(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint objectId)
+{
+ // NOT SUPPORTED
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_DetailTextureImage_updateTextureImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint numLevels,
+ jint level,
+ jint internalFormat,
+ jint format,
+ jint width,
+ jint height,
+ jint boundaryWidth,
+ jbyteArray imageYup)
+{
+ // NOT SUPPORTED
+}
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_Canvas3D_decal1stChildSetup(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice2();
+
+ device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
+ device->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 1.0, 0);
+ device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+ device->SetRenderState(D3DRS_STENCILREF, 0x1);
+ device->SetRenderState(D3DRS_STENCILMASK, 0x1);
+ device->SetRenderState(D3DRS_STENCILFAIL,
+ D3DSTENCILOP_KEEP);
+ device->SetRenderState(D3DRS_STENCILZFAIL,
+ D3DSTENCILOP_KEEP);
+ device->SetRenderState(D3DRS_STENCILPASS,
+ D3DSTENCILOP_REPLACE);
+ return d3dCtx->zEnable;
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_decalNthChildSetup(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+
+{
+ GetDevice();
+
+ d3dCtx->zEnable = FALSE;
+ device->SetRenderState(D3DRS_ZENABLE, FALSE);
+ device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
+ device->SetRenderState(D3DRS_STENCILREF, 0x1);
+ device->SetRenderState(D3DRS_STENCILMASK, 0x1);
+ device->SetRenderState(D3DRS_STENCILFAIL,
+ D3DSTENCILOP_KEEP);
+ device->SetRenderState(D3DRS_STENCILZFAIL,
+ D3DSTENCILOP_KEEP);
+ device->SetRenderState(D3DRS_STENCILPASS,
+ D3DSTENCILOP_KEEP);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_decalReset(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jboolean depthBufferEnable)
+{
+ GetDevice();
+
+ device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+
+ if (depthBufferEnable) {
+ d3dCtx->zEnable = TRUE;
+ device->SetRenderState(D3DRS_ZENABLE, TRUE);
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_ctxUpdateEyeLightingEnable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jboolean localEyeLightingEnable)
+{
+ GetDevice();
+ device->SetRenderState(D3DRS_LOCALVIEWER, localEyeLightingEnable);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_activeTextureUnit(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint index)
+{
+ GetDevice();
+ // If this index is greater than max support stage,
+ // then subsequence texture operation will ignore.
+ if (index < 0) {
+ index = 0;
+ }
+
+ d3dCtx->texUnitStage = index;
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureUnitStateRetained_updateTextureUnitState(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint index,
+ jboolean enable)
+{
+ GetDevice();
+ // If this index is greater than max support stage,
+ // then subsequence texture operation will ignore.
+ if (index <= 0) {
+ index = 0;
+ }
+
+ d3dCtx->texUnitStage = index;
+
+ if (!enable && (index < d3dCtx->bindTextureIdLen)) {
+ device->SetTexture(index, NULL);
+ d3dCtx->bindTextureId[index] = -1;
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setDepthFunc(
+ JNIEnv * env,
+ jobject obj,
+ jlong ctx,
+ jint func)
+{
+ GetDevice();
+
+ if (func == javax_media_j3d_RenderingAttributesRetained_LESS) {
+ device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);
+ } else if (func ==
+ javax_media_j3d_RenderingAttributesRetained_LEQUAL) {
+ device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+ }
+
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setBlendColor(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat colorRed,
+ jfloat colorGreen,
+ jfloat colorBlue,
+ jfloat colorAlpha)
+{
+ // Not support in D3D
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setBlendFunc(
+ JNIEnv * env,
+ jobject obj,
+ jlong ctx,
+ jint srcBlendFunction,
+ jint dstBlendFunction)
+{
+ GetDevice();
+
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ device->SetRenderState(D3DRS_SRCBLEND,
+ blendFunctionTable[srcBlendFunction]);
+ device->SetRenderState(D3DRS_DESTBLEND,
+ blendFunctionTable[dstBlendFunction]);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setFogEnableFlag(
+ JNIEnv * env,
+ jobject obj,
+ jlong ctx,
+ jboolean enable)
+{
+ GetDevice();
+
+ device->SetRenderState(D3DRS_FOGENABLE, enable);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_updateSeparateSpecularColorEnable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jboolean enable)
+{
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_updateTexUnitStateMap(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint numActiveTexUnit,
+ jintArray texUnitStateMapArray)
+{
+ if ((texUnitStateMapArray != NULL) && (numActiveTexUnit > 0)) {
+ GetDevice();
+
+ jint* texUnitStateMap = (jint *) env->GetPrimitiveArrayCritical(
+ texUnitStateMapArray, NULL);
+ int genMode;
+ int ts;
+ for (int i = 0; i < numActiveTexUnit; i++) {
+ genMode = setTextureStage(d3dCtx, device, i, texUnitStateMap[i]);
+ if (genMode != TEX_GEN_AUTO) {
+ ts = d3dCtx->texStride[i];
+ if (ts == 0) {
+ /*
+ In multiTexture case when no tex defined in non object
+ linear mode.
+ */
+ ts = d3dCtx->texCoordFormat[i];
+ }
+ } else {
+ ts = d3dCtx->texCoordFormat[i];
+ }
+ setTexTransformStageFlag(d3dCtx, device, i, ts, genMode);
+ }
+
+ env->ReleasePrimitiveArrayCritical(texUnitStateMapArray,
+ texUnitStateMap, 0);
+ }
+}
diff --git a/src/native/d3d/Canvas3D.cpp b/src/native/d3d/Canvas3D.cpp
new file mode 100644
index 0000000..c262335
--- /dev/null
+++ b/src/native/d3d/Canvas3D.cpp
@@ -0,0 +1,1029 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setDrawActive(
+ JNIEnv *env,
+ jobject obj,
+ jint fd)
+{
+ // This function is only used for Solaris OpenGL
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_widSync(
+ JNIEnv *env,
+ jobject obj,
+ jint fd,
+ jint numWindows)
+{
+ // This function is only used for Solaris OpenGL
+}
+
+
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_Canvas3D_useSharedCtx(
+ JNIEnv *env,
+ jobject obj)
+{
+ return JNI_FALSE;
+}
+
+
+
+extern "C" JNIEXPORT
+jlong JNICALL Java_javax_media_j3d_Canvas3D_createContext(
+ JNIEnv *env,
+ jobject obj,
+ jlong display,
+ jint window,
+ jint vid,
+ jlong visInfo,
+ jlong sharedCtx,
+ jboolean isSharedCtx,
+ jboolean offScreen)
+{
+ HWND hwnd = WindowFromDC(reinterpret_cast<HDC>(window));
+
+ lock();
+ D3dCtx* ctx = new D3dCtx(env, obj, hwnd, offScreen, vid);
+ if (ctx == NULL) {
+ printf("%s", getErrorMessage(OUTOFMEMORY));
+ unlock();
+ return 0;
+ }
+
+ if (offScreen) {
+
+ jclass cls = (jclass) env->GetObjectClass(obj);
+ jfieldID fieldId = env->GetFieldID(cls,
+ "offScreenCanvasSize",
+ "Ljava/awt/Dimension;");
+ jobject dimObj = env->GetObjectField(obj, fieldId);
+ if (dimObj == NULL) {
+ // user invoke queryProperties()
+ ctx->offScreenWidth = 1;
+ ctx->offScreenHeight = 1;
+ } else {
+ cls = (jclass) env->GetObjectClass(dimObj);
+ fieldId = env->GetFieldID(cls, "width", "I");
+ ctx->offScreenWidth = env->GetIntField(dimObj, fieldId);
+ fieldId = env->GetFieldID(cls, "height", "I");
+ ctx->offScreenHeight = env->GetIntField(dimObj, fieldId);
+ }
+ }
+
+ if (!ctx->initialize(env, obj)) {
+ delete ctx;
+ unlock();
+ return 0;
+ }
+ d3dCtxList.push_back(ctx);
+
+ unlock();
+ return reinterpret_cast<jlong>(ctx);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext(
+ JNIEnv *env,
+ jobject obj,
+ jlong display,
+ jint window,
+ jint vid,
+ jboolean offScreen,
+ jint width,
+ jint height)
+{
+ HWND hwnd = WindowFromDC(reinterpret_cast<HDC>(window));
+
+ lock();
+ // always use offscreen for property since it
+ // makes no difference in D3D and this will also
+ // instruct initialize() to use offScreenWidth/Height
+ // instead of current window width/height to create
+ // context.
+
+ D3dCtx* ctx = new D3dCtx(env, obj, hwnd, true, vid);
+ if (ctx == NULL) {
+ printf("%s", getErrorMessage(OUTOFMEMORY));
+ unlock();
+ return;
+ }
+
+ ctx->offScreenWidth = width;
+ ctx->offScreenHeight = height;
+
+ ctx->initialize(env, obj);
+ delete ctx;
+ unlock();
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_useCtx(
+ JNIEnv *env,
+ jclass cl,
+ jlong ctx,
+ jlong display,
+ jint window)
+{
+ // D3D doesn't have notation of current context
+}
+
+
+extern "C" JNIEXPORT
+jint JNICALL Java_javax_media_j3d_Canvas3D_getNumCtxLights(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice2();
+
+ int nlight = d3dCtx->deviceInfo->maxActiveLights;
+ if (nlight <= 0) {
+ // In emulation & referene mode, D3D return -1
+ // work around by setting 8.
+ nlight = 8;
+ }
+ return nlight;
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_composite(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint px,
+ jint py,
+ jint minX,
+ jint minY,
+ jint maxX,
+ jint maxY,
+ jint rasWidth,
+ jbyteArray imageYdown,
+ jint winWidth,
+ jint winHeight)
+
+{
+ GetDevice();
+
+ // However we use the following texturemapping function instead
+ // so this will not invoke.
+ if (d3dCtx->backSurface == NULL) {
+ device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO,
+ &d3dCtx->backSurface);
+ }
+ jbyte *byteData = (jbyte *) (env->GetPrimitiveArrayCritical(
+ imageYdown, NULL));
+ compositeDataToSurface(px, py,
+ minX, minY, maxX-minX, maxY-minY,
+ rasWidth,
+ byteData, d3dCtx->backSurface);
+ env->ReleasePrimitiveArrayCritical(imageYdown, byteData, 0);
+}
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_Canvas3D_initTexturemapping(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint texWidth,
+ jint texHeight,
+ jint objectId)
+{
+ GetCtx2();
+
+
+ if ((objectId >= 0) &&
+ (objectId < d3dCtx->textureTableLen) &&
+ (d3dCtx->textureTable[objectId] != NULL)) {
+ // delete the previous texture reference
+ // when canvas resize
+ Java_javax_media_j3d_Canvas3D_freeTexture(env,
+ NULL,
+ ctx,
+ objectId);
+ }
+
+ Java_javax_media_j3d_TextureRetained_bindTexture(
+ env, texture, ctx, objectId, TRUE);
+
+ Java_javax_media_j3d_TextureRetained_updateTextureImage(
+ env, texture, ctx, 1, 0, J3D_RGBA, 0, texWidth, texHeight, 0, NULL);
+
+ return (d3dCtx->textureTable[objectId] != NULL);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_texturemapping(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctx,
+ jint px,
+ jint py,
+ jint minX,
+ jint minY,
+ jint maxX,
+ jint maxY,
+ jint texWidth,
+ jint texHeight,
+ jint rasWidth,
+ jint format,
+ jint objectId,
+ jbyteArray imageYdown,
+ jint winWidth,
+ jint winHeight)
+{
+ GetDevice();
+
+ Java_javax_media_j3d_TextureRetained_bindTexture(
+ env, texture, ctx, objectId, TRUE);
+
+
+ Java_javax_media_j3d_Texture2DRetained_updateTextureSubImage(
+ env, texture, ctx, 0, minX, minY, J3D_RGBA, format,
+ minX, minY, rasWidth, maxX-minX, maxY-minY, imageYdown);
+
+ LPDIRECT3DTEXTURE8 surf = d3dCtx->textureTable[objectId];
+
+ if (surf == NULL) {
+ if (debug) {
+ printf("[Java 3D] Fail to apply texture in J3DGraphics2D !\n");
+ }
+ return;
+ }
+
+ D3DTLVERTEX screenCoord;
+ DWORD zcmpfunc;
+
+ screenCoord.sx = (px + minX) - 0.5f;
+ screenCoord.sy = (py + minY) - 0.5f;
+
+ // sz can be any number since we will disable z buffer
+ // However rhw can't be 0, otherwise texture will not shown
+ screenCoord.sz = 0.999f;
+ screenCoord.rhw = 1;
+
+ DWORD blendEnable;
+ DWORD srcBlend;
+ DWORD dstBlend;
+
+ // disable z buffer
+ device->GetRenderState(D3DRS_ZFUNC, &zcmpfunc);
+ device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
+
+ device->GetRenderState(D3DRS_ALPHABLENDENABLE, &blendEnable);
+ device->GetRenderState(D3DRS_SRCBLEND, &srcBlend);
+ device->GetRenderState(D3DRS_DESTBLEND, &dstBlend);
+
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+
+ drawTextureRect(d3dCtx, device, surf, screenCoord,
+ minX, minY, maxX, maxY,
+ maxX - minX, maxY - minY, false);
+
+ Java_javax_media_j3d_TextureRetained_bindTexture(
+ env, texture, ctx, objectId, FALSE);
+
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, blendEnable);
+ device->SetRenderState(D3DRS_SRCBLEND, srcBlend);
+ device->SetRenderState(D3DRS_DESTBLEND, dstBlend);
+ device->SetRenderState(D3DRS_ZFUNC, zcmpfunc);
+ device->SetRenderState(D3DRS_ZWRITEENABLE,
+ d3dCtx->zWriteEnable);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_clear(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat r,
+ jfloat g,
+ jfloat b,
+ jint winWidth,
+ jint winHeight,
+ jobject pa2d,
+ jint imageScaleMode,
+ jbyteArray pixels_obj)
+{
+
+ GetDevice();
+
+ /* Java 3D always clears the Z-buffer */
+
+ if (!d3dCtx->zWriteEnable) {
+ device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+ }
+
+ device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
+ D3DCOLOR_COLORVALUE(r, g, b, 1.0f), 1.0, 0);
+
+ if (pa2d) {
+ jclass pa2d_class = env->GetObjectClass(pa2d);
+ /*
+ jfieldID id = env->GetFieldID(pa2d_class, "surfaceDirty", "I");
+ if (env->GetIntField(pa2d, id) == NOTLIVE) {
+ return;
+ }
+ */
+ // It is possible that (1) Another user thread will free this
+ // image. (2) Another Renderer thread in case of multiple screen
+ // will invoke clear() at the same time.
+ lockBackground();
+
+
+ jfieldID id = env->GetFieldID(pa2d_class, "hashId", "I");
+ int hashCode = env->GetIntField(pa2d, id);
+
+ D3dImageComponent *d3dImage =
+ D3dImageComponent::find(&BackgroundImageList, d3dCtx, hashCode);
+
+ id = env->GetFieldID(pa2d_class, "width", "I");
+ int width = env->GetIntField(pa2d, id);
+ id = env->GetFieldID(pa2d_class, "height", "I");
+ int height = env->GetIntField(pa2d, id);
+
+ LPDIRECT3DTEXTURE8 surf;
+
+ if ((d3dImage == NULL) || (d3dImage->surf == NULL)) {
+ surf = createSurfaceFromImage(env, pa2d, ctx,
+ width, height, pixels_obj);
+ if (surf == NULL) {
+ if (d3dImage != NULL) {
+ D3dImageComponent::remove(&BackgroundImageList, d3dImage);
+ }
+ unlockBackground();
+ return;
+ }
+
+ if (d3dImage == NULL) {
+ d3dImage =
+ D3dImageComponent::add(&BackgroundImageList, d3dCtx, hashCode, surf);
+ } else {
+ // need to add this one because the new imageDirtyFlag may
+ // cause d3dImage->surf set to NULL
+ d3dImage->surf = surf;
+ }
+ }
+
+
+ D3DTLVERTEX screenCoord;
+ DWORD zcmpfunc;
+ boolean texModeRepeat;
+ int scaleWidth, scaleHeight;
+ float sw, sh;
+
+ // sz can be any number since we already disable z buffer
+ // However rhw can't be 0, otherwise texture will not shown
+ screenCoord.sz = 0.999f;
+ screenCoord.rhw = 1;
+
+ // disable z buffer
+ device->GetRenderState(D3DRS_ZFUNC, &zcmpfunc);
+ device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
+
+ switch (imageScaleMode){
+ case javax_media_j3d_Background_SCALE_NONE:
+ screenCoord.sx = -0.5f;
+ screenCoord.sy = -0.5f;
+ scaleWidth = width;
+ scaleHeight = height;
+ texModeRepeat = FALSE;
+ break;
+ case javax_media_j3d_Background_SCALE_FIT_MIN:
+ screenCoord.sx = -0.5f;
+ screenCoord.sy = -0.5f;
+ sw = winWidth/(float) width;
+ sh = winHeight/(float) height;
+ if (sw >= sh) {
+ scaleWidth = width*sh;
+ scaleHeight = winHeight;
+ } else {
+ scaleWidth = winWidth;
+ scaleHeight = height*sw;
+ }
+ texModeRepeat = FALSE;
+ break;
+ case javax_media_j3d_Background_SCALE_FIT_MAX:
+ screenCoord.sx = -0.5f;
+ screenCoord.sy = -0.5f;
+ sw = winWidth/(float) width;
+ sh = winHeight/(float) height;
+ if (sw >= sh) {
+ scaleWidth = winWidth;
+ scaleHeight = height*sw;
+ } else {
+ scaleWidth = width*sh;
+ scaleHeight = winHeight;
+ }
+ texModeRepeat = FALSE;
+ break;
+ case javax_media_j3d_Background_SCALE_FIT_ALL:
+ screenCoord.sx = -0.5f;
+ screenCoord.sy = -0.5f;
+ scaleWidth = winWidth;
+ scaleHeight = winHeight;
+ texModeRepeat = FALSE;
+ break;
+ case javax_media_j3d_Background_SCALE_REPEAT:
+ screenCoord.sx = -0.5f;
+ screenCoord.sy = -0.5f;
+ scaleWidth = winWidth;
+ scaleHeight = winHeight;
+ texModeRepeat = TRUE;
+ break;
+ case javax_media_j3d_Background_SCALE_NONE_CENTER:
+ screenCoord.sx = (winWidth - width)/2.0f - 0.5f;
+ screenCoord.sy = (winHeight - height)/2.0f -0.5f;
+ scaleWidth = width;
+ scaleHeight = height;
+ texModeRepeat = FALSE;
+ break;
+ default:
+ printf("Unknown Background scale mode %d\n", imageScaleMode);
+ }
+
+ drawTextureRect(d3dCtx, device, d3dImage->surf,
+ screenCoord, 0, 0, width, height,
+ scaleWidth, scaleHeight, texModeRepeat);
+
+ device->SetRenderState(D3DRS_ZFUNC, zcmpfunc);
+ device->SetRenderState(D3DRS_ZWRITEENABLE,
+ d3dCtx->zWriteEnable);
+ unlockBackground();
+ } else {
+ if (!d3dCtx->zWriteEnable) {
+ device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ }
+ }
+
+
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setRenderMode(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint mode,
+ jboolean dbEnable)
+{
+ // D3D v8.0 doesn't support stereo
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_clearAccum(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ // D3D use full-scene antialiasing capbilities in device
+ // instead of accumulation buffer (which it didn't support)
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_accum(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat value)
+{
+ // D3D use full-scene antialiasing capbilities in device
+ // instead of accumulation buffer (which didn't support)
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_accumReturn(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ // D3D use full-scene antialiasing capbilities in device
+ // instead of accumulation buffer (which it didn't support)
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setDepthBufferWriteEnable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jboolean mode)
+{
+ GetDevice();
+
+ d3dCtx->zWriteEnable = mode;
+ device->SetRenderState(D3DRS_ZWRITEENABLE, mode);
+}
+
+
+VOID freePointerList()
+{
+ if (useFreePointerList0) {
+ if (freePointerList1.size() > 0) {
+ lockSurfaceList();
+ for (void **p = freePointerList1.begin();
+ p != freePointerList1.end(); ++p) {
+ delete (*p);
+ }
+
+ freePointerList1.clear();
+ unlockSurfaceList();
+ }
+ useFreePointerList0 = false;
+ } else {
+ if (freePointerList0.size() > 0) {
+ lockSurfaceList();
+ for (void **p = freePointerList0.begin();
+ p != freePointerList0.end(); ++p) {
+ delete (*p);
+ }
+
+ freePointerList0.clear();
+ unlockSurfaceList();
+ }
+ useFreePointerList0 = true;
+
+ }
+}
+
+
+extern "C" JNIEXPORT
+jint JNICALL Java_javax_media_j3d_Canvas3D_swapBuffers(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jlong display,
+ jint win)
+{
+ GetDevice2();
+
+ int retCode = NOCHANGE;
+
+ HRESULT hr = device->Present(NULL, NULL, NULL, NULL);
+
+ if (FAILED(hr)) {
+ hr = device->TestCooperativeLevel();
+ if (D3DERR_DEVICELOST == hr) {
+ return NOCHANGE;
+ }
+ if (D3DERR_DEVICENOTRESET == hr) {
+ if (debug) {
+ printf("Buffer swap error %s, try Reset() the surface... \n",
+ DXGetErrorString8(hr));
+ }
+ retCode = d3dCtx->resetSurface(env, obj);
+ GetDevice2();
+ hr = device->Present(NULL, NULL, NULL, NULL);
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Buffer swap error %s \n",
+ DXGetErrorString8(hr));
+ }
+ }
+ }
+
+ }
+
+ d3dCtx->freeList();
+ freePointerList();
+ return retCode;
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_syncRender(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jboolean waitFlag)
+{
+ // do nothing since D3D always wait in Blt
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_newDisplayList(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint id)
+{
+ GetCtx();
+
+ if (id <= 0) {
+ if (debug) {
+ printf("In Canvas3D.newDisplayList id pass in = %d !\n", id);
+ }
+ return;
+ }
+
+ if (id >= d3dCtx->dlTableSize) {
+ int newSize = d3dCtx->dlTableSize << 1;
+ if (id >= newSize) {
+ newSize = id+1;
+ }
+ int i=0;
+ LPD3DDISPLAYLIST *newTable = new LPD3DDISPLAYLIST[newSize];
+
+ if (newTable == NULL) {
+ printf("%s", getErrorMessage(OUTOFMEMORY));
+ exit(1);
+ }
+ // entry 0 is not used
+ newTable[0] = NULL;
+ while (++i < d3dCtx->dlTableSize) {
+ newTable[i] = d3dCtx->displayListTable[i];
+ }
+ while (i < newSize) {
+ newTable[i++] = NULL;
+ }
+ d3dCtx->dlTableSize = newSize;
+ SafeDelete(d3dCtx->displayListTable);
+ d3dCtx->displayListTable = newTable;
+ }
+
+ if (d3dCtx->displayListTable[id] != NULL) {
+ SafeDelete(d3dCtx->displayListTable[id]);
+ }
+ d3dCtx->displayListTable[id] = new D3dDisplayList();
+ if (d3dCtx->displayListTable[id] == NULL) {
+ printf("%s", getErrorMessage(OUTOFMEMORY));
+ exit(1);
+ }
+ d3dCtx->currDisplayListID = id;
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_endDisplayList(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+ d3dCtx->displayListTable[d3dCtx->currDisplayListID]->optimize(d3dCtx);
+ d3dCtx->currDisplayListID = 0;
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_callDisplayList(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint id,
+ jboolean isNonUniformScale)
+{
+ GetDevice();
+
+ // TODO: Remove this two safe checks when release
+ // d3dCtx->displayListTable[id]->render(d3dCtx);
+
+
+ if ((id <= 0) || (id >= d3dCtx->dlTableSize)) {
+ if (debug) {
+ if (id <= 0) {
+ printf("[Java 3D] Invalid Display List ID %d is invoked !\n", id);
+ } else {
+ printf("[Java 3D] Display List ID %d not yet initialize !\n", id);
+ }
+ }
+ return;
+ }
+
+ LPD3DDISPLAYLIST dl = d3dCtx->displayListTable[id];
+
+ if (dl == NULL) {
+ if (debug) {
+ printf("[Java 3D] Display List ID %d not yet initialize !\n", id);
+ }
+ return;
+ }
+ dl->render(d3dCtx);
+
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_freeDisplayList(
+ JNIEnv *env,
+ jclass cl,
+ jlong ctx,
+ jint id)
+{
+ GetCtx();
+
+ if ((id < 0) || (id >= d3dCtx->dlTableSize)) {
+ if (debug) {
+ printf("[Java 3D] FreeDisplayList, id %d not within table range %d!\n", id,
+ d3dCtx->dlTableSize);
+ }
+ return;
+ }
+
+ SafeDelete(d3dCtx->displayListTable[id]);
+}
+
+
+/*
+ Native function to delete OGL texture object after j3d texture object
+ has been deleted by java garbage collector.
+ */
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_freeTexture(
+ JNIEnv *env,
+ jclass cls,
+ jlong ctx,
+ jint id)
+{
+ GetDevice();
+
+ for (int i=0; i < d3dCtx->bindTextureIdLen; i++) {
+ if (d3dCtx->bindTextureId[i] == id) {
+ device->SetTexture(i, NULL);
+ d3dCtx->bindTextureId[i] = -1;
+ }
+ }
+
+ if ((id >= d3dCtx->textureTableLen) || (id < 1)) {
+ if (debug) {
+ printf("Internal Error : freeTexture ID %d, textureTableLen %d \n",
+ id, d3dCtx->textureTableLen);
+ }
+ return;
+ }
+
+ d3dCtx->freeResource(d3dCtx->textureTable[id]);
+ d3dCtx->textureTable[id] = NULL;
+}
+
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_Canvas3D_isTexture3DAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ return JNI_FALSE;
+}
+
+
+extern "C" JNIEXPORT
+jint JNICALL Java_javax_media_j3d_Canvas3D_getTextureColorTableSize(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ // Not support by D3D
+ return 0;
+}
+
+
+extern "C" JNIEXPORT
+jint JNICALL Java_javax_media_j3d_Canvas3D_getTextureUnitCount(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetCtx2();
+ return d3dCtx->deviceInfo->maxTextureUnitStageSupport;
+}
+
+
+extern "C" JNIEXPORT
+jint JNICALL Java_javax_media_j3d_Canvas3D_createOffScreenBuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jlong display,
+ jint vid,
+ jint width,
+ jint height)
+{
+
+
+ if (ctx == 0) {
+ // createContext() will be invoked later in Renderer
+ return 1;
+ } else {
+ GetCtx2();
+ d3dCtx->d3dPresent.BackBufferWidth = width;
+ d3dCtx->d3dPresent.BackBufferHeight = height;
+ return SUCCEEDED(d3dCtx->resetSurface(env, obj));
+ }
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_destroyContext(
+ JNIEnv *env,
+ jclass cl,
+ jlong display,
+ jint window,
+ jlong ctx)
+{
+ GetDevice();
+
+ lock();
+ d3dCtxList.erase(find(d3dCtxList.begin(), d3dCtxList.end(), d3dCtx));
+ delete d3dCtx;
+ unlock();
+
+ Java_javax_media_j3d_Renderer_D3DCleanUp(env, cl);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jlong display,
+ jint window)
+{
+ // do nothing, since the old buffer will destory
+ // in createOffScreenBuffer
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_readOffScreenBuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint format,
+ jint width,
+ jint height)
+{
+ GetDevice();
+
+ if (format == FORMAT_USHORT_GRAY) {
+ printf("[Java 3D] readOffScreenBuffer not support FORMAT_USHORT_GRAY\n");
+ return;
+ }
+
+ if (d3dCtx->backSurface == NULL) {
+ HRESULT hr = device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO,
+ &d3dCtx->backSurface);
+ if (FAILED(hr)) {
+ printf("[Java 3D] GetBackBuffer fail %s\n",
+ DXGetErrorString8(hr));
+ return;
+ }
+ }
+
+ jclass cv_class = env->GetObjectClass(obj);
+
+ jfieldID byteData_field = env->GetFieldID(cv_class, "byteBuffer", "[B");
+ jbyteArray byteData_array = (jbyteArray) env->GetObjectField(obj, byteData_field);
+ jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(
+ byteData_array, NULL);
+
+ copyDataFromSurface(format, 0, 0, width, height, byteData,
+ d3dCtx->backSurface);
+
+ env->ReleasePrimitiveArrayCritical(byteData_array, byteData, 0);
+ return;
+}
+
+
+extern "C" JNIEXPORT
+jint JNICALL Java_javax_media_j3d_Canvas3D_resizeD3DCanvas(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ int status;
+
+ GetCtx2();
+ lock();
+ status = d3dCtx->resize(env, obj);
+ unlock();
+
+ return status;
+}
+
+
+extern "C" JNIEXPORT
+jint JNICALL Java_javax_media_j3d_Canvas3D_toggleFullScreenMode(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ int status;
+
+ GetCtx2();
+ lock();
+ status = d3dCtx->toggleMode(!d3dCtx->bFullScreen, env, obj);
+ unlock();
+ if (status == RECREATEDFAIL) {
+ return RECREATEDDRAW;
+ }
+ return status;
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setFullSceneAntialiasing(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jboolean enable)
+{
+ GetDevice();
+
+ if (!implicitMultisample) {
+ device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, enable);
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Renderer_D3DCleanUp(
+ JNIEnv *env,
+ jobject obj)
+{
+ lock();
+ if (d3dCtxList.empty()) {
+ D3dDriverInfo::release();
+ }
+ unlock();
+
+ // Need to call it two times to free both list0 and list1
+ freePointerList();
+ freePointerList();
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_ImageComponent2DRetained_freeD3DSurface(
+ JNIEnv *env,
+ jobject image,
+ jint hashCode)
+
+{
+
+ lockImage();
+ D3dImageComponent::remove(&RasterList, hashCode);
+ unlockImage();
+ lockBackground();
+ D3dImageComponent::remove(&BackgroundImageList, hashCode);
+ unlockBackground();
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_beginScene(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+ device->BeginScene();
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_endScene(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx)
+{
+ GetDevice();
+ device->EndScene();
+}
+
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_Canvas3D_validGraphicsMode(
+ JNIEnv *env,
+ jobject obj)
+{
+ DEVMODE devMode;
+
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);
+ return (devMode.dmBitsPerPel > 8);
+}
+
diff --git a/src/native/d3d/CompressedGeometryRetained.cpp b/src/native/d3d/CompressedGeometryRetained.cpp
new file mode 100644
index 0000000..413b33d
--- /dev/null
+++ b/src/native/d3d/CompressedGeometryRetained.cpp
@@ -0,0 +1,39 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_CompressedGeometryRetained_execute
+ (JNIEnv *env, jobject obj, jlong ctx, jint version, jint bufferType,
+ jint bufferContents, jint renderFlags, jint offset, jint size,
+ jbyteArray geometry)
+{
+ // Not support by D3D, problem should not call this.
+ printf("Error: CompressedGeometryRetained execute should not invoke by D3D");
+}
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_CompressedGeometryRetained_decompressByRef
+ (JNIEnv *env, jobject obj, jlong ctx)
+{
+ // Not support by D3D
+ return JNI_FALSE ;
+}
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_CompressedGeometryRetained_decompressHW
+ (JNIEnv *env, jobject obj, jlong ctx, jint majorVersion, jint minorVersion)
+{
+ // Not support by D3D
+ return JNI_FALSE ;
+}
diff --git a/src/native/d3d/D3dCtx.cpp b/src/native/d3d/D3dCtx.cpp
new file mode 100644
index 0000000..9072a3f
--- /dev/null
+++ b/src/native/d3d/D3dCtx.cpp
@@ -0,0 +1,1793 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "Stdafx.h"
+
+D3dCtxVector d3dCtxList;
+
+/*
+ * Use the following code to initialize ctx property :
+ *
+ * D3dCtx ctx* = new D3dCtx(env, obj, hwnd, offScreen, vid);
+ * if (ctx->initialize(env, obj)) {
+ * delete ctx;
+ * }
+ * d3dCtxList.push_back(ctx);
+ *
+ *
+ * When ctx remove :
+ *
+ * d3dCtxList.erase(find(d3dCtxList.begin(), d3dCtxList.end(), ctx);
+ * delete ctx;
+ *
+ */
+
+const D3DXMATRIX identityMatrix = D3DXMATRIX(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+
+D3dCtx::D3dCtx(JNIEnv* env, jobject obj, HWND _hwnd, BOOL _offScreen,
+ jint vid)
+{
+ int i;
+
+ monitor = NULL;
+ hwnd = _hwnd;
+ pD3D = NULL;
+ pDevice = NULL;
+ offScreen = _offScreen;
+ offScreenWidth = 0;
+ offScreenHeight = 0;
+
+ driverInfo = NULL;
+ deviceInfo = NULL;
+
+ depthStencilSurface = NULL;
+ frontSurface = NULL;
+ backSurface = NULL;
+ resetColorTarget = false;
+ forceResize = false;
+ inToggle = false;
+ useFreeList0 = true;
+ reIndexifyTable = NULL;
+
+ // set default RenderingState variable
+ cullMode = D3DCULL_CW;
+ fillMode = D3DFILL_SOLID;
+ zWriteEnable = TRUE;
+ zEnable = TRUE;
+
+ // this is the pixelFormat return from NativeConfigTemplate.
+ minZDepth = vid & 0x3fffffff;
+ if (vid & 0x80000000) {
+ antialiasing = REQUIRED;
+ } else if (vid & 0x40000000) {
+ antialiasing = PREFERRED;
+ } else {
+ antialiasing = UNNECESSARY;
+ }
+
+ setFullScreenFromProperty(env);
+
+ if (offScreen) {
+ // disable fullscreen mode for offscreen
+ bFullScreen = false;
+ bFullScreenRequired = false;
+ }
+
+ dlTableSize = DISPLAYLIST_INITSIZE;
+ displayListTable = new LPD3DDISPLAYLIST[dlTableSize];
+ if (displayListTable == NULL) {
+ error(OUTOFMEMORY);
+ exit(1);
+ }
+ for (i=0; i < dlTableSize; i++) {
+ displayListTable[i] = NULL;
+ }
+
+ currDisplayListID = 0;
+ quadIndexBuffer = NULL;
+ quadIndexBufferSize = 0;
+ lineModeIndexBuffer = NULL;
+
+ srcVertexBuffer = NULL;
+ dstVertexBuffer = NULL;
+
+
+ multiTextureSupport = false;
+ texUnitStage = 0;
+ twoSideLightingEnable = false;
+ bindTextureId = NULL;
+ bindTextureIdLen = 0;
+
+ textureTable = (LPDIRECT3DTEXTURE8 *) malloc(
+ sizeof(LPDIRECT3DTEXTURE8) * TEXTURETABLESIZE);
+
+ if (textureTable == NULL) {
+ error(OUTOFMEMORY);
+ exit(1);
+ }
+ ZeroMemory(textureTable, sizeof(LPDIRECT3DTEXTURE8)*TEXTURETABLESIZE);
+ textureTableLen = TEXTURETABLESIZE;
+
+ bindTextureId = NULL;
+
+ volumeTable = (LPDIRECT3DVOLUMETEXTURE8 *) malloc(
+ sizeof(LPDIRECT3DVOLUMETEXTURE8) * TEXTURETABLESIZE);
+
+ if (volumeTable == NULL) {
+ error(OUTOFMEMORY);
+ exit(1);
+ }
+ ZeroMemory(volumeTable, sizeof(LPDIRECT3DVOLUMETEXTURE8)*TEXTURETABLESIZE);
+ volumeTableLen = TEXTURETABLESIZE;
+
+
+ cubeMapTable = (LPDIRECT3DCUBETEXTURE8 *) malloc(
+ sizeof(LPDIRECT3DCUBETEXTURE8) * TEXTURETABLESIZE);
+
+ if (cubeMapTable == NULL) {
+ error(OUTOFMEMORY);
+ exit(1);
+ }
+ ZeroMemory(cubeMapTable, sizeof(LPDIRECT3DCUBETEXTURE8)*TEXTURETABLESIZE);
+ cubeMapTableLen = TEXTURETABLESIZE;
+
+
+ if (hwnd == 0) {
+ // Offscreen rendering
+ hwnd = GetDesktopWindow();
+ topHwnd = hwnd;
+ } else {
+ topHwnd = getTopWindow(hwnd);
+ }
+
+ if (d3dDriverList == NULL) {
+
+ // keep trying to initialize even though
+ // last time it fail.
+ D3dDriverInfo::initialize(env);
+ }
+
+ if (d3dDriverList == NULL) {
+ /*
+ * This happen when either
+ * (1) D3D v8.0 not install or
+ * (2) Not enough memory or
+ * (3) No adapter found in the system.
+ */
+ SafeRelease(pD3D);
+ return;
+ }
+
+ pD3D = Direct3DCreate8( D3D_SDK_VERSION );
+
+ if (pD3D == NULL) {
+ error(D3DNOTFOUND);
+ return;
+ }
+ // find current monitor handle before
+ // get current display mode
+ monitor = findMonitor();
+
+ // check current display mode
+ enumDisplayMode(&devmode);
+
+ if (devmode.dmBitsPerPel < 16) {
+ // tell user switch to at least 16 bit color next time
+ warning(NEEDSWITCHMODE);
+ }
+
+ // find the adapter for this
+ setDriverInfo();
+
+ GetWindowRect(topHwnd, &savedTopRect);
+ winStyle = GetWindowLong(topHwnd, GWL_STYLE);
+
+ for (i=0; i < 4; i++) {
+ rasterRect[i].sx = 0;
+ rasterRect[i].sy = 0;
+ rasterRect[i].sz = 0;
+ rasterRect[i].rhw = 0;
+ }
+
+ rasterRect[0].tu = 0;
+ rasterRect[0].tv = 1;
+ rasterRect[1].tu = 0;
+ rasterRect[1].tv = 0;
+ rasterRect[2].tu = 1;
+ rasterRect[2].tv = 1;
+ rasterRect[3].tu = 1;
+ rasterRect[3].tv = 0;
+
+ // initialize Ambient Material
+ ambientMaterial.Power = 0;
+ CopyColor(ambientMaterial.Emissive, 0, 0, 0, 1.0f);
+ CopyColor(ambientMaterial.Diffuse, 0, 0, 0, 1.0f);
+ CopyColor(ambientMaterial.Ambient, 1.0f, 1.0f, 1.0f, 1.0f);
+ CopyColor(ambientMaterial.Specular, 0, 0, 0, 1.0f);
+ GetWindowRect(hwnd, &windowRect);
+}
+
+D3dCtx::~D3dCtx()
+{
+ release();
+ SafeRelease(pD3D);
+}
+
+VOID D3dCtx::releaseTexture()
+{
+
+ for (int i=0; i < bindTextureIdLen; i++) {
+ if (bindTextureId[i] > 0) {
+ pDevice->SetTexture(i, NULL);
+ }
+ }
+
+ lockSurfaceList();
+ if (textureTable != NULL) {
+ // free all textures
+ for (int i=0; i < textureTableLen; i++) {
+ SafeRelease(textureTable[i]);
+ }
+ SafeFree(textureTable);
+ }
+
+ if (volumeTable != NULL) {
+ for (int i=0; i < volumeTableLen; i++) {
+ SafeRelease(volumeTable[i]);
+ }
+ SafeFree(volumeTable);
+
+ }
+
+
+ if (cubeMapTable != NULL) {
+ for (int i=0; i < cubeMapTableLen; i++) {
+ SafeRelease(cubeMapTable[i]);
+ }
+ SafeFree(cubeMapTable);
+
+ }
+
+ textureTableLen = 0;
+ volumeTableLen = 0;
+ cubeMapTableLen = 0;
+ unlockSurfaceList();
+
+ lockImage();
+ D3dImageComponent::remove(&RasterList, this);
+ unlockImage();
+
+ lockBackground();
+ D3dImageComponent::remove(&BackgroundImageList, this);
+ unlockBackground();
+
+ // free list0
+ freeList();
+ // free list1
+ freeList();
+}
+
+VOID D3dCtx::setViewport()
+{
+ int renderWidth = getWidth();
+ int renderHeight = getHeight();
+ HRESULT hr;
+ D3DVIEWPORT8 vp = {0, 0, renderWidth, renderHeight, 0.0f, 1.0f};
+
+ hr = pDevice->SetViewport( &vp );
+
+ if (FAILED(hr)) {
+ // Use the previous Viewport if fail
+ error(VIEWPORTFAIL, hr);
+ }
+}
+
+VOID D3dCtx::releaseVB()
+{
+
+ if (displayListTable != NULL) {
+ // entry 0 is not used
+ for (int i=1; i < dlTableSize; i++) {
+ SafeDelete(displayListTable[i]);
+ }
+ SafeFree(displayListTable);
+ dlTableSize = 0;
+ }
+
+
+ lockGeometry();
+
+ D3dVertexBuffer *p = vertexBufferTable.next;
+ D3dVertexBuffer *q, **r;
+ D3dVertexBufferVector *vbVector;
+ boolean found = false;
+
+ while (p != NULL) {
+ vbVector = p->vbVector;
+ if (vbVector != NULL) {
+ for (r = vbVector->begin(); r != vbVector->end(); ++r) {
+ if (*r == p) {
+ vbVector->erase(r);
+ found = true;
+ break;
+ }
+ }
+ }
+ q = p;
+ p = p->next;
+ delete q;
+ }
+
+ vertexBufferTable.next = NULL;
+
+ freeVBList0.clear();
+ freeVBList1.clear();
+
+ unlockGeometry();
+
+}
+
+VOID D3dCtx::release()
+{
+ D3dImageComponent::removeAll(&BackgroundImageList);
+ D3dImageComponent::removeAll(&RasterList);
+ releaseTexture();
+ SafeFree(bindTextureId);
+ bindTextureIdLen = 0;
+
+
+ SafeRelease(srcVertexBuffer);
+ SafeRelease(dstVertexBuffer);
+ SafeRelease(quadIndexBuffer);
+ SafeRelease(lineModeIndexBuffer);
+ quadIndexBufferSize = 0;
+ releaseVB();
+
+ // trying to free VertexBuffer
+ // This will crash the driver if Indices/StreamSource
+ // Not set before.
+ // pDevice->SetIndices(NULL, 0);
+ // pDevice->SetStreamSource(0, NULL, 0);
+ SafeRelease(depthStencilSurface);
+ SafeRelease(frontSurface);
+ SafeRelease(backSurface);
+
+ SafeRelease(pDevice);
+ currDisplayListID = 0;
+ multiTextureSupport = false;
+ texUnitStage = 0;
+ twoSideLightingEnable = false;
+ freePointerList();
+ freePointerList();
+}
+
+
+
+/*
+ * Application should delete ctx when this function return false.
+ */
+BOOL D3dCtx::initialize(JNIEnv *env, jobject obj)
+{
+ HRESULT hr;
+ // int oldWidth, oldHeight;
+ // BOOL needBiggerRenderSurface = false;
+
+ // It is possible that last time Emulation mode is used.
+ // If this is the case we will try Hardware mode first.
+ deviceInfo = setDeviceInfo(driverInfo, &bFullScreen, minZDepth);
+
+ if ((pD3D == NULL) || (driverInfo == NULL)) {
+ return false;
+ }
+ /*
+ if (offScreenWidth > driverInfo->desktopMode.Width) {
+ if (debug) {
+ printf("OffScreen width cannot greater than %d\n",
+ driverInfo->desktopMode.Width);
+ }
+ oldWidth = offScreenWidth;
+ offScreenWidth = driverInfo->desktopMode.Width;
+ needBiggerRenderSurface = true;
+
+ }
+
+ if (offScreenHeight > driverInfo->desktopMode.Height) {
+ if (debug) {
+ printf("OffScreen Height cannot greater than %d\n",
+ driverInfo->desktopMode.Height);
+ }
+ oldHeight = offScreenHeight;
+ offScreenHeight = driverInfo->desktopMode.Height;
+ needBiggerRenderSurface = true;
+ }
+ */
+
+ if (!bFullScreen) {
+ getScreenRect(hwnd, &savedClientRect);
+ CopyMemory(&screenRect, &savedClientRect, sizeof (RECT));
+ }
+
+ dwBehavior = findBehavior();
+
+ if (debug) {
+ printf("Use %s, ", driverInfo->adapterIdentifier.Description);
+
+ if (deviceInfo->isHardwareTnL &&
+ (dwBehavior == D3DCREATE_SOFTWARE_VERTEXPROCESSING)) {
+ // user select non-TnL device
+ printf("Hardware Rasterizer\n");
+ } else {
+ printf("%s \n", deviceInfo->deviceName);
+ }
+ }
+
+ setPresentParams(env, obj);
+
+ if (debug) {
+ printf("\nCreate device :\n");
+ printInfo(&d3dPresent);
+ }
+
+
+ if ((d3dPresent.BackBufferWidth <= 0) ||
+ (d3dPresent.BackBufferHeight <= 0)) {
+ if (debug) {
+ printf("D3D: Can't create device of buffer size %dx%d\n",
+ d3dPresent.BackBufferWidth,
+ d3dPresent.BackBufferHeight);
+ }
+ return false;
+ }
+
+ hr = pD3D->CreateDevice(driverInfo->iAdapter,
+ deviceInfo->deviceType,
+ topHwnd,
+ dwBehavior,
+ &d3dPresent,
+ &pDevice);
+
+ if (FAILED(hr) && (requiredDeviceID < 0)) {
+ if (deviceInfo->deviceType != D3DDEVTYPE_REF) {
+ // switch to reference mode
+ warning(CREATEDEVICEFAIL, hr);
+ deviceInfo = driverInfo->d3dDeviceList[DEVICE_REF];
+ dwBehavior = findBehavior();
+ deviceInfo->findDepthStencilFormat(minZDepth);
+ d3dPresent.AutoDepthStencilFormat =
+ deviceInfo->depthStencilFormat;
+ if (deviceInfo->depthStencilFormat == D3DFMT_UNKNOWN) {
+ // should not happen since reference mode will
+ // support all depth stencil format
+ error(DEPTHSTENCILNOTFOUND);
+ return false;
+ }
+ if (debug) {
+ printf("Fallback to create reference device :\n");
+ printInfo(&d3dPresent);
+ }
+
+ hr = pD3D->CreateDevice(driverInfo->iAdapter,
+ deviceInfo->deviceType,
+ topHwnd,
+ dwBehavior,
+ &d3dPresent,
+ &pDevice);
+ }
+ }
+
+ /*
+ if (offScreen && needBiggerRenderSurface) {
+ IDirect3DSurface8 *pRenderTarget;
+ IDirect3DSurface8 *pStencilDepthTarget;
+
+ hr = pDevice->CreateRenderTarget(oldWidth,
+ oldHeight,
+ driverInfo->desktopMode.Format,
+ D3DMULTISAMPLE_NONE,
+ true,
+ &pRenderTarget);
+
+ if (FAILED(hr)) {
+ printf("Fail to CreateRenderTarget %s\n", DXGetErrorString8(hr));
+ } else {
+ hr = pDevice->CreateDepthStencilSurface(oldWidth,
+ oldHeight,
+ deviceInfo->depthStencilFormat,
+ D3DMULTISAMPLE_NONE,
+ &pStencilDepthTarget);
+ if (FAILED(hr)) {
+ printf("Fail to CreateDepthStencilSurface %s\n", DXGetErrorString8(hr));
+ pRenderTarget->Release();
+ } else {
+ hr = pDevice->SetRenderTarget(pRenderTarget,
+ pStencilDepthTarget);
+ if (FAILED(hr)) {
+ printf("Fail to SetRenderTarget %s\n", DXGetErrorString8(hr));
+ pRenderTarget->Release();
+ pStencilDepthTarget->Release();
+ } else {
+ printf("Successfully set bigger buffer\n");
+ }
+ }
+ }
+ }
+ */
+
+
+ setWindowMode();
+
+ if (FAILED(hr)) {
+ release();
+ if (!inToggle) {
+ error(CREATEREFDEVICEFAIL, hr);
+ } else {
+ warning(CREATEREFDEVICEFAIL, hr);
+ }
+ return false;
+ }
+
+ if (deviceInfo != NULL) {
+ bindTextureIdLen = deviceInfo->maxTextureUnitStageSupport;
+ } else {
+ bindTextureIdLen = 1;
+ }
+
+ jclass canvasCls = env->GetObjectClass(obj);
+ jfieldID id = env->GetFieldID(canvasCls, "numTexCoordSupported", "I");
+ env->SetIntField(obj, id, TEXSTAGESUPPORT);
+
+ if (bindTextureIdLen > 1) {
+ if (bindTextureIdLen > TEXSTAGESUPPORT) {
+ // D3D only support max. 8 stages.
+ bindTextureIdLen = TEXSTAGESUPPORT;
+ }
+ multiTextureSupport = true;
+ id = env->GetFieldID(canvasCls, "multiTexAccelerated", "Z");
+ env->SetBooleanField(obj, id, JNI_TRUE);
+ id = env->GetFieldID(canvasCls, "numTexUnitSupported", "I");
+ env->SetIntField(obj, id, bindTextureIdLen);
+ } else {
+ bindTextureIdLen = 1;
+ }
+
+ bindTextureId = (INT *) malloc(sizeof(INT) * bindTextureIdLen);
+ if (bindTextureId == NULL) {
+ release();
+ error(OUTOFMEMORY);
+ return false;
+ }
+
+ setViewport();
+ setDefaultAttributes();
+
+ createVertexBuffer();
+
+ if (debug && (deviceInfo != NULL)) {
+ if (multiTextureSupport) {
+ printf("Max Texture Unit Stage support : %d \n",
+ deviceInfo->maxTextureBlendStages);
+
+ printf("Max Simultaneous Texture unit support : %d \n",
+ deviceInfo->maxSimultaneousTextures);
+ } else {
+ printf("MultiTexture support : false\n");
+ }
+ }
+ return true;
+}
+
+// canvas size change, get new back buffer
+INT D3dCtx::resize(JNIEnv *env, jobject obj)
+{
+ int retValue;
+
+ if ((pDevice == NULL) || bFullScreen) {
+ return false; // not yet ready when startup
+ }
+
+ if (forceResize) {
+ // ignore first resize request after screen toggle
+ forceResize = false;
+ return NOCHANGE;
+ }
+ // we don't want resize to do twice but when window toggle
+ // between fullscreen and window mode, the move event will got
+ // first. Thus it will get size correctly without doing resize.
+
+ BOOL moveRequest;
+
+
+ GetWindowRect(hwnd, &windowRect);
+
+ if ((windowRect.right == screenRect.right) &&
+ (windowRect.left == screenRect.left) &&
+ (windowRect.bottom == screenRect.bottom) &&
+ (windowRect.top == screenRect.top)) {
+ return NOCHANGE;
+ }
+
+ if (((windowRect.left - windowRect.right)
+ == (screenRect.left - screenRect.right)) &&
+ ((windowRect.bottom - windowRect.top)
+ == (screenRect.bottom - screenRect.top))) {
+ moveRequest = true;
+ } else {
+ moveRequest = false;
+ }
+
+
+ HMONITOR oldMonitor = monitor;
+ monitor = findMonitor();
+
+ getScreenRect(hwnd, &screenRect);
+
+ if (monitor != oldMonitor) {
+ enumDisplayMode(&devmode);
+ setDriverInfo();
+ release();
+ initialize(env, obj);
+ return RECREATEDDRAW;
+ }
+
+ if (!moveRequest) {
+
+ retValue = resetSurface(env, obj);
+ if (retValue != RECREATEDFAIL) {
+ return retValue;
+ } else {
+ return RECREATEDDRAW;
+ }
+ }
+ return NOCHANGE;
+}
+
+
+INT D3dCtx::toggleMode(BOOL _bFullScreen, JNIEnv *env, jobject obj)
+{
+ INT retValue;
+
+ if ((pDevice == NULL) ||
+ (!_bFullScreen &&
+ !deviceInfo->canRenderWindowed)) {
+ // driver did not support window mode
+ return NOCHANGE;
+ }
+
+ int onScreenCount = 0;
+
+ for (D3dCtx **p = d3dCtxList.begin(); p != d3dCtxList.end(); p++) {
+ if (!(*p)->offScreen &&
+ // (monitor == (*p)->monitor) &&
+ (++onScreenCount > 1)) {
+ // don't toggle if there are more than one onScreen ctx exists
+ // in the same screen
+ return false;
+ }
+ }
+
+
+ inToggle = true;
+ bFullScreen = _bFullScreen;
+
+ retValue = resetSurface(env, obj);
+
+ if (retValue != RECREATEDFAIL) {
+ forceResize = true;
+ } else {
+ // Switch back to window mode if fall to toggle fullscreen
+ // and vice versa
+ bFullScreen = !bFullScreen;
+ release();
+ if (initialize(env, obj)) {
+ retValue = RECREATEDDRAW;
+ forceResize = true;
+ } else {
+ retValue = RECREATEDFAIL;
+ }
+ }
+ if (retValue != RECREATEDFAIL) {
+ setViewport();
+ }
+
+ inToggle = false;
+ return retValue;
+}
+
+VOID D3dCtx::setPresentParams(JNIEnv *env, jobject obj)
+{
+ setCanvasProperty(env, obj);
+
+ d3dPresent.AutoDepthStencilFormat = deviceInfo->depthStencilFormat;
+ d3dPresent.EnableAutoDepthStencil = true;
+
+ if ((antialiasing != UNNECESSARY) &&
+ deviceInfo->supportAntialiasing()) {
+ d3dPresent.MultiSampleType = deviceInfo->getBestMultiSampleType();
+ } else {
+ d3dPresent.MultiSampleType = D3DMULTISAMPLE_NONE;
+ }
+ d3dPresent.BackBufferCount = 1;
+ d3dPresent.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
+
+ // We can't use Discard, otherwise readRaster will fail as
+ // content of backbuffer will discard after swap unless
+ // we always call readRaster() just before swap.
+ // However in this way we can't use multisample effect
+
+
+ if (bFullScreen) {
+ GetWindowRect(topHwnd, &savedTopRect);
+ GetWindowRect(hwnd, &savedClientRect);
+
+ d3dPresent.Windowed = false;
+ d3dPresent.hDeviceWindow = topHwnd;
+
+ if ((antialiasing != UNNECESSARY) &&
+ deviceInfo->supportAntialiasing()) {
+ d3dPresent.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ } else {
+ d3dPresent.SwapEffect = D3DSWAPEFFECT_FLIP;
+ }
+ d3dPresent.BackBufferWidth = driverInfo->desktopMode.Width;
+ d3dPresent.BackBufferHeight = driverInfo->desktopMode.Height;
+ d3dPresent.BackBufferFormat = driverInfo->desktopMode.Format;
+ d3dPresent.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
+ d3dPresent.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+
+ } else {
+ d3dPresent.Windowed = true;
+ d3dPresent.hDeviceWindow = hwnd;
+
+ if ((antialiasing != UNNECESSARY) &&
+ deviceInfo->supportAntialiasing()) {
+ d3dPresent.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ } else {
+ d3dPresent.SwapEffect = D3DSWAPEFFECT_COPY;
+ }
+ d3dPresent.BackBufferWidth = getWidth();
+ d3dPresent.BackBufferHeight = getHeight();
+ d3dPresent.BackBufferFormat = driverInfo->desktopMode.Format;
+ d3dPresent.FullScreen_RefreshRateInHz = 0;
+ d3dPresent.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
+
+ }
+
+}
+
+INT D3dCtx::resetSurface(JNIEnv *env, jobject obj)
+{
+ D3dDeviceInfo* oldDevice = deviceInfo;
+ HRESULT hr;
+
+
+ deviceInfo = setDeviceInfo(driverInfo, &bFullScreen, minZDepth);
+
+ if (deviceInfo == NULL) {
+ return NOCHANGE;
+ }
+ if (deviceInfo != oldDevice) {
+ // we fall back to Reference mode last time,
+ // try to see if we can run in hardware mode after
+ // the surface size change.
+ release();
+ if (initialize(env, obj)) {
+ return RECREATEDDRAW;
+ } else {
+ return RECREATEDFAIL;
+ }
+ } else {
+ setPresentParams(env, obj);
+ if (debug) {
+ printf("\nReset Device :\n");
+ printInfo(&d3dPresent);
+ }
+
+ // Must release any non default pool surface, otherwise
+ // Reset() will fail
+ SafeRelease(depthStencilSurface);
+ SafeRelease(frontSurface);
+ SafeRelease(backSurface);
+
+ releaseVB();
+ SafeRelease(lineModeIndexBuffer);
+ quadIndexBufferSize = 0;
+
+ hr = pDevice->Reset(&d3dPresent);
+ if (FAILED(hr)) {
+ warning(RESETFAIL, hr);
+ // try to recreate Surface, if still fail, try Reference mode
+ release();
+ if (initialize(env, obj)) {
+ return RECREATEDDRAW;
+ } else {
+ return RECREATEDFAIL;
+ }
+ } else {
+ setWindowMode();
+ setDefaultAttributes();
+ return RESETSURFACE;
+ }
+ }
+
+ return NOCHANGE;
+}
+
+
+VOID D3dCtx::error(int idx)
+{
+ error(getErrorMessage(idx));
+}
+
+VOID D3dCtx::error(int idx, HRESULT hr)
+{
+ error(getErrorMessage(idx), hr);
+}
+
+
+VOID D3dCtx::warning(int idx)
+{
+ printf("%s\n", getErrorMessage(idx));
+}
+
+VOID D3dCtx::warning(int idx, HRESULT hr)
+{
+ printf("%s - %s\n", getErrorMessage(idx), DXGetErrorString8(hr));
+}
+
+
+VOID D3dCtx::error(char *s)
+{
+ showError(hwnd, s, bFullScreen);
+}
+
+VOID D3dCtx::error(char *s, HRESULT hr)
+{
+ char message[400];
+ sprintf(message, "%s - %s", s, DXGetErrorString8(hr));
+ showError(hwnd, message, bFullScreen);
+}
+
+
+VOID D3dCtx::d3dWarning(int idx)
+{
+ printf("%s\n", getErrorMessage(idx));
+}
+
+VOID D3dCtx::d3dWarning(int idx, HRESULT hr)
+{
+ printf("%s - %s\n",
+ getErrorMessage(idx), DXGetErrorString8(hr));
+
+}
+
+VOID D3dCtx::d3dError(char *s)
+{
+ showError(GetDesktopWindow(), s, false);
+}
+
+
+VOID D3dCtx::d3dError(int idx)
+{
+ d3dError(getErrorMessage(idx));
+}
+
+
+// Only display message box for the first error, since
+// Java3D will continue to invoke createContext() when it fail
+VOID D3dCtx::showError(HWND hwnd, char *s, BOOL bFullScreen)
+{
+ if (firstError) {
+ firstError = false;
+ if (bFullScreen) {
+ // In full screen mode, we can't see message box
+ printf("[Java 3D] %s\n", s);
+ exit(1);
+ } else {
+ MessageBox(hwnd, s, "Java 3D", MB_OK|MB_ICONERROR);
+ }
+ }
+}
+
+
+DWORD D3dCtx::getWidth()
+{
+ if (!offScreen) {
+ return screenRect.right - screenRect.left;
+ } else {
+ return offScreenWidth;
+ }
+
+}
+
+
+DWORD D3dCtx::getHeight()
+{
+ if (!offScreen) {
+ return screenRect.bottom - screenRect.top;
+ } else {
+ return offScreenHeight;
+ }
+
+}
+
+D3dDeviceInfo* D3dCtx::selectDevice(int deviceID,
+ D3dDriverInfo *driverInfo,
+ BOOL *bFullScreen,
+ int minZDepth)
+{
+ D3dDeviceInfo *pDevice;
+
+ for (int i=0; i < numDeviceTypes; i++) {
+ pDevice = driverInfo->d3dDeviceList[i];
+ if ((((deviceID == DEVICE_HAL) || (deviceID == DEVICE_HAL_TnL)) &&
+ (pDevice->deviceType == D3DDEVTYPE_HAL)) ||
+ (deviceID == DEVICE_REF) &&
+ (pDevice->deviceType == D3DDEVTYPE_REF)) {
+ if ((*bFullScreen && !pDevice->fullscreenCompatible) ||
+ (!*bFullScreen && !pDevice->desktopCompatible)) {
+ if (pDevice->deviceType == D3DDEVTYPE_HAL) {
+ d3dError(HALDEVICENOTFOUND);
+ } else {
+ // should not happen, REF device always support
+ d3dError(DEVICENOTFOUND);
+ }
+ exit(1);
+ }
+ if (pDevice->maxZBufferDepthSize == 0) {
+ if (pDevice->deviceType == D3DDEVTYPE_HAL) {
+ d3dError(HALNOTCOMPATIBLE);
+ } else {
+ // should not happen, REF device always support
+ d3dError(DEVICENOTFOUND);
+ }
+ exit(1);
+ }
+ if (pDevice->deviceType == D3DDEVTYPE_HAL) {
+ if ((deviceID == DEVICE_HAL_TnL) &&
+ !pDevice->isHardwareTnL) {
+ d3dError(TNLHALDEVICENOTFOUND);
+ exit(1);
+ }
+ }
+ pDevice->findDepthStencilFormat(minZDepth);
+ if (pDevice->depthStencilFormat == D3DFMT_UNKNOWN) {
+ d3dError(DEPTHSTENCILNOTFOUND);
+ exit(1);
+ }
+ return pDevice;
+ }
+ }
+
+
+ // should not happen
+ d3dError(DEVICENOTFOUND);
+ exit(1);
+}
+
+
+
+D3dDeviceInfo* D3dCtx::selectBestDevice(D3dDriverInfo *driverInfo,
+ BOOL *bFullScreen, int minZDepth)
+{
+ D3dDeviceInfo *pDevice;
+ D3dDeviceInfo *bestDevice = NULL;
+ int i;
+
+ for (i=0; i < numDeviceTypes; i++) {
+ pDevice = driverInfo->d3dDeviceList[i];
+ if (pDevice->maxZBufferDepthSize > 0) {
+ pDevice->findDepthStencilFormat(minZDepth);
+
+ if (pDevice->depthStencilFormat == D3DFMT_UNKNOWN) {
+ if (pDevice->deviceType == D3DDEVTYPE_REF) {
+ d3dError(DEPTHSTENCILNOTFOUND);
+ return NULL;
+ } else {
+ continue;
+ }
+ }
+ if (*bFullScreen) {
+ if (pDevice->fullscreenCompatible) {
+ bestDevice = pDevice;
+ break;
+ }
+ } else {
+ if (pDevice->canRenderWindowed) {
+ if (pDevice->desktopCompatible) {
+ bestDevice = pDevice;
+ break;
+ }
+ } else {
+ if (pDevice->fullscreenCompatible) {
+ // switch to fullscreen mode
+ *bFullScreen = true;
+ bestDevice = pDevice;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (bestDevice == NULL) {
+ // should not happen
+ d3dError(DEVICENOTFOUND);
+ return NULL;
+ }
+
+ // TODO: suggest another display mode for user
+ /*
+ if (bestDevice->deviceType == D3DDEVTYPE_REF) {
+ // Recomend other display mode that support
+ // hardware accerated rendering if any.
+ int numModes = pD3D->GetAdapterModeCount(driverInfo->iAdapter);
+ D3DDISPLAYMODE dmode;
+
+ for (i=0; i < numModes; i++) {
+ pD3D->EnumAdapterModes(pDriverInfo->iAdapter, i, &dmode);
+ if ((dmode.Width < 640) || (dmode.Height < 400)) {
+ // filter out low resolution modes
+ continue;
+ }
+ }
+ ....
+ }
+ */
+ return bestDevice;
+}
+
+
+VOID D3dCtx::setDeviceFromProperty(JNIEnv *env)
+{
+
+ jclass systemClass = env->FindClass( "javax/media/j3d/MasterControl" );
+
+ if ( systemClass != NULL )
+ {
+ jmethodID method = env->GetStaticMethodID(
+ systemClass, "getProperty",
+ "(Ljava/lang/String;)Ljava/lang/String;" );
+ if ( method != NULL )
+ {
+ jstring name = env->NewStringUTF( "j3d.d3ddevice" );
+ jstring property = reinterpret_cast<jstring>(
+ env->CallStaticObjectMethod(
+ systemClass, method, name ));
+ jboolean isCopy;
+
+ if ( property != NULL )
+ {
+ const char* chars = env->GetStringUTFChars(
+ property, &isCopy );
+ if ( chars != 0 )
+ {
+ if (stricmp(chars, "reference") == 0) {
+ // There is no emulation device anymore in v8.0
+ requiredDeviceID = DEVICE_REF;
+ } else if (stricmp(chars, "hardware") == 0) {
+ requiredDeviceID = DEVICE_HAL;
+ } else if (stricmp(chars, "TnLhardware") == 0) {
+ requiredDeviceID = DEVICE_HAL_TnL;
+ } else {
+ d3dError(UNKNOWNDEVICE);
+ exit(1);
+ }
+ env->ReleaseStringUTFChars( property, chars );
+ }
+ }
+ name = env->NewStringUTF( "j3d.d3ddriver" );
+ property = reinterpret_cast<jstring>(
+ env->CallStaticObjectMethod(
+ systemClass, method, name ));
+ if ( property != NULL )
+ {
+ const char* chars = env->GetStringUTFChars(
+ property, &isCopy);
+ if ( chars != 0 )
+ {
+ // atoi() return 0, our default value, on error.
+ requiredDriverID = atoi(chars);
+ }
+ }
+ }
+ }
+}
+
+VOID D3dCtx::setFullScreenFromProperty(JNIEnv *env)
+{
+
+ jclass systemClass = env->FindClass( "javax/media/j3d/MasterControl" );
+
+ bFullScreenRequired = false;
+ bFullScreen = false;
+
+ if ( systemClass != NULL )
+ {
+ jmethodID method = env->GetStaticMethodID(
+ systemClass, "getProperty",
+ "(Ljava/lang/String;)Ljava/lang/String;" );
+ if ( method != NULL )
+ {
+ jstring name = env->NewStringUTF( "j3d.fullscreen" );
+ jstring property = reinterpret_cast<jstring>(
+ env->CallStaticObjectMethod(
+ systemClass, method, name ));
+ if ( property != NULL )
+ {
+ jboolean isCopy;
+ const char * chars = env->GetStringUTFChars(
+ property, &isCopy );
+ if ( chars != 0 )
+ {
+ if ( stricmp( chars, "required" ) == 0 ) {
+ bFullScreenRequired = true;
+ bFullScreen = true;
+ } else if ( stricmp( chars, "preferred" ) == 0 ) {
+ bFullScreen = true;
+ }
+ // "UNNECESSARY" is the default
+ env->ReleaseStringUTFChars( property, chars );
+ }
+ }
+ }
+ }
+
+}
+
+VOID D3dCtx::setVBLimitProperty(JNIEnv *env)
+{
+ jclass systemClass = env->FindClass( "javax/media/j3d/MasterControl" );
+
+ if ( systemClass != NULL )
+ {
+ jmethodID method = env->GetStaticMethodID(
+ systemClass, "getProperty",
+ "(Ljava/lang/String;)Ljava/lang/String;" );
+ if ( method != NULL )
+ {
+ jstring name = env->NewStringUTF( "j3d.vertexbufferlimit" );
+ jstring property = reinterpret_cast<jstring>(
+ env->CallStaticObjectMethod(
+ systemClass, method, name ));
+ if ( property != NULL )
+ {
+ jboolean isCopy;
+ const char * chars = env->GetStringUTFChars(
+ property, &isCopy );
+ if ( chars != 0 )
+ {
+ long vbLimit = atol(chars);
+ env->ReleaseStringUTFChars( property, chars );
+ if (vbLimit >= 6) {
+ // Has to be at least 6 since for Quad the
+ // limit reset to 2*vbLimit/3 >= 4
+ printf("Java 3D: VertexBuffer limit set to %ld\n", vbLimit);
+ vertexBufferMaxVertexLimit = vbLimit;
+ } else {
+ printf("Java 3D: VertexBuffer limit should be an integer >= 6 !\n");
+ }
+
+ }
+ }
+ }
+ }
+}
+
+VOID D3dCtx::setDebugProperty(JNIEnv *env)
+{
+ jclass systemClass = env->FindClass( "javax/media/j3d/MasterControl" );
+
+ debug = false;
+
+ if ( systemClass != NULL )
+ {
+ jmethodID method = env->GetStaticMethodID(
+ systemClass, "getProperty",
+ "(Ljava/lang/String;)Ljava/lang/String;" );
+ if ( method != NULL )
+ {
+ jstring name = env->NewStringUTF( "j3d.debug" );
+ jstring property = reinterpret_cast<jstring>(
+ env->CallStaticObjectMethod(
+ systemClass, method, name ));
+ if ( property != NULL )
+ {
+ jboolean isCopy;
+ const char * chars = env->GetStringUTFChars(
+ property, &isCopy );
+ if ( chars != 0 )
+ {
+ if ( stricmp( chars, "true" ) == 0 ) {
+ debug = true;
+ } else {
+ debug = false;
+ }
+ // "UNNECESSARY" is the default
+ env->ReleaseStringUTFChars( property, chars );
+ }
+ }
+ }
+ }
+}
+
+VOID D3dCtx::setImplicitMultisamplingProperty(JNIEnv *env)
+{
+ jclass cls = env->FindClass("javax/media/j3d/VirtualUniverse");
+
+ if (cls == NULL) {
+ implicitMultisample = false;
+ return;
+ }
+
+ jfieldID fieldID = env->GetStaticFieldID(cls, "mc", "Ljavax/media/j3d/MasterControl;");
+
+ if (fieldID == NULL) {
+ implicitMultisample = false;
+ return;
+ }
+
+ jobject obj = env->GetStaticObjectField(cls, fieldID);
+
+ if (obj == NULL) {
+ implicitMultisample = false;
+ return;
+ }
+
+ cls = env->FindClass("javax/media/j3d/MasterControl");
+
+ if (cls == NULL) {
+ implicitMultisample = false;
+ return;
+ }
+
+ fieldID = env->GetFieldID(cls, "implicitAntialiasing", "Z");
+
+ if (fieldID == NULL ) {
+ implicitMultisample = false;
+ return;
+ }
+
+ implicitMultisample = env->GetBooleanField(obj, fieldID);
+ return;
+}
+
+
+// Callback to notify Canvas3D which mode it is currently running
+VOID D3dCtx::setCanvasProperty(JNIEnv *env, jobject obj)
+{
+ int mask = javax_media_j3d_Canvas3D_EXT_ABGR |
+ javax_media_j3d_Canvas3D_EXT_BGR;
+
+ if ((deviceInfo->depthStencilFormat == D3DFMT_D24S8) ||
+ (deviceInfo->depthStencilFormat == D3DFMT_D24X4S4)) {
+ // The other format D3DFMT_D15S1 with 1 bit
+ // stencil buffer has no use for Decal group so it
+ // is ignored.
+ mask |= javax_media_j3d_Canvas3D_STENCIL_BUFFER;
+ }
+
+ jclass canvasCls = env->GetObjectClass(obj);
+ jfieldID id = env->GetFieldID(canvasCls, "fullScreenMode", "Z");
+ env->SetBooleanField(obj, id, bFullScreen);
+ id = env->GetFieldID(canvasCls, "fullscreenWidth", "I");
+ env->SetIntField(obj, id, driverInfo->desktopMode.Width);
+ id = env->GetFieldID(canvasCls, "fullscreenHeight", "I");
+ env->SetIntField(obj, id, driverInfo->desktopMode.Height);
+
+ id = env->GetFieldID(canvasCls, "textureExtendedFeatures", "I");
+ env->SetIntField(obj, id, deviceInfo->getTextureFeaturesMask());
+
+ id = env->GetFieldID(canvasCls, "extensionsSupported", "I");
+ env->SetIntField(obj, id, mask);
+
+
+ id = env->GetFieldID(canvasCls, "nativeGraphicsVersion", "Ljava/lang/String;");
+ char *version = "DirectX 8.0 or above";
+ env->SetObjectField(obj, id, env->NewStringUTF(version));
+
+ float degree = deviceInfo->maxAnisotropy;
+ id = env->GetFieldID(canvasCls, "anisotropicDegreeMax", "F");
+ env->SetFloatField(obj, id, degree);
+
+ id = env->GetFieldID(canvasCls, "textureWidthMax", "I");
+ env->SetIntField(obj, id, deviceInfo->maxTextureWidth);
+
+ id = env->GetFieldID(canvasCls, "textureHeightMax", "I");
+ env->SetIntField(obj, id, deviceInfo->maxTextureHeight);
+}
+
+VOID D3dCtx::createVertexBuffer()
+{
+ if (srcVertexBuffer != NULL) {
+ // Each pDevice has its own vertex buffer,
+ // so if different pDevice create vertex buffer has to
+ // recreate again.
+ srcVertexBuffer->Release();
+ }
+
+ if (dstVertexBuffer != NULL) {
+ dstVertexBuffer->Release();
+ }
+
+ HRESULT hr =
+ pDevice->CreateVertexBuffer(sizeof(D3DVERTEX),
+ D3DUSAGE_DONOTCLIP|
+ D3DUSAGE_WRITEONLY|
+ D3DUSAGE_SOFTWAREPROCESSING,
+ D3DFVF_XYZ,
+ D3DPOOL_MANAGED,
+ &srcVertexBuffer);
+
+ if (FAILED(hr)) {
+ error(CREATEVERTEXBUFFER, hr);
+ }
+
+ hr = pDevice->CreateVertexBuffer(sizeof(D3DTLVERTEX),
+ D3DUSAGE_DONOTCLIP|
+ D3DUSAGE_SOFTWAREPROCESSING,
+ D3DFVF_XYZRHW|D3DFVF_TEX1,
+ D3DPOOL_MANAGED,
+ &dstVertexBuffer);
+ if (FAILED(hr)) {
+ error(CREATEVERTEXBUFFER, hr);
+ }
+}
+
+
+VOID D3dCtx::transform(D3DVERTEX *worldCoord, D3DTLVERTEX *screenCoord) {
+ D3DVERTEX *pv;
+ D3DTLVERTEX *tlpv;
+ HRESULT hr;
+
+ if (srcVertexBuffer != NULL) {
+ // Need to disable Texture state, otherwise
+ // ProcessVertices() will fail with debug message :
+ //
+ // "Number of output texture coordintes and their format should
+ // be the same in the destination vertex buffer and as
+ // computed for current D3D settings."
+ //
+ // when multiple texture is used.
+ DWORD texState;
+ // save original texture state
+ pDevice->GetTextureStageState(0, D3DTSS_COLOROP, &texState);
+ // disable texture processing
+ pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
+
+ if (!softwareVertexProcessing) {
+ // ProcessVertices() only work in software vertex
+ // processing mode
+ pDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING,
+ TRUE);
+ }
+
+ pDevice->SetRenderState(D3DRS_CLIPPING, FALSE);
+ hr = srcVertexBuffer->Lock(0, 0, (BYTE **)&pv, 0);
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Fail to lock buffer %s\n", DXGetErrorString8(hr));
+ }
+ } else {
+ pv[0].x = worldCoord->x;
+ pv[0].y = worldCoord->y;
+ pv[0].z = worldCoord->z;
+
+ srcVertexBuffer->Unlock();
+ pDevice->SetStreamSource(0, srcVertexBuffer,
+ sizeof(D3DVERTEX));
+ pDevice->SetVertexShader(D3DFVF_XYZ);
+ hr = pDevice->ProcessVertices(0, 0, 1,
+ dstVertexBuffer, 0);
+
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Fail to processVertices %s\n", DXGetErrorString8(hr));
+ }
+ } else {
+ hr = dstVertexBuffer->Lock(0, 0, (BYTE **)&tlpv, D3DLOCK_READONLY);
+ if (SUCCEEDED(hr)) {
+ screenCoord->sx = tlpv[0].sx;
+ screenCoord->sy = tlpv[0].sy;
+ screenCoord->sz = tlpv[0].sz;
+ screenCoord->rhw = tlpv[0].rhw;
+ dstVertexBuffer->Unlock();
+ } else {
+ if (debug) {
+ error("Fail to lock surface in transform", hr);
+ }
+ }
+ }
+ }
+ pDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
+ if (!softwareVertexProcessing) {
+ pDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING,
+ FALSE);
+ }
+ // restore original texture state
+ pDevice->SetTextureStageState(0, D3DTSS_COLOROP, texState);
+ }
+}
+
+
+
+VOID D3dCtx::getScreenRect(HWND hwnd, RECT *rect) {
+
+ GetWindowRect(hwnd, rect);
+
+ if ((deviceInfo->isHardware) &&
+ (numDriver > 1)) {
+
+ MONITORINFO info;
+ HMONITOR hMonitor = driverInfo->hMonitor;
+
+ info.cbSize = sizeof(MONITORINFO);
+ if (hMonitor == NULL) {
+ hMonitor = MonitorFromWindow(hwnd,
+ MONITOR_DEFAULTTONEAREST);
+ }
+ GetMonitorInfo(hMonitor, &info);
+ monitorLeft = info.rcMonitor.left;
+ monitorTop = info.rcMonitor.top;
+ rect->left -= monitorLeft;
+ rect->right -= monitorLeft;
+ rect->top -= monitorTop;
+ rect->bottom -= monitorTop;
+ } else {
+ monitorLeft = 0;
+ monitorTop = 0;
+ }
+}
+
+/*
+ * Search the monitor that this window competely enclosed.
+ * Return NULL if this window intersect several monitor
+ */
+
+HMONITOR D3dCtx::findMonitor()
+{
+
+ if ((osvi.dwMajorVersion < 4) ||
+ (numDriver < 2)) {
+ return NULL;
+ }
+
+ RECT rect;
+ MONITORINFO info;
+ HMONITOR hmonitor = MonitorFromWindow(hwnd,
+ MONITOR_DEFAULTTONEAREST);
+ info.cbSize = sizeof(MONITORINFO);
+ GetMonitorInfo(hmonitor, &info);
+ GetWindowRect(hwnd, &rect);
+
+ if ((info.rcMonitor.left <= rect.left) &&
+ (info.rcMonitor.right >= rect.right) &&
+ (info.rcMonitor.top <= rect.top) &&
+ (info.rcMonitor.bottom >= rect.bottom)) {
+ if (info.dwFlags & MONITORINFOF_PRIMARY) {
+ // Pass NULL is same as passing the guid of the
+ // first monitor. This can avoid recreate when
+ // window drag between screen borders from first
+ // screen.
+ return NULL;
+ } else {
+ return hmonitor;
+ }
+ }
+ return NULL;
+}
+
+
+D3dDeviceInfo* D3dCtx::setDeviceInfo(D3dDriverInfo *driverInfo,
+ BOOL *bFullScreen,
+ int minZDepth)
+{
+ if (requiredDeviceID >= 0) {
+ return selectDevice(requiredDeviceID, driverInfo,
+ bFullScreen, minZDepth);
+ } else {
+ return selectBestDevice(driverInfo, bFullScreen,
+ minZDepth);
+ }
+}
+
+// Find the adapter that this window belongs to
+// and set driverInfo to this
+VOID D3dCtx::setDriverInfo()
+{
+ D3dDriverInfo *newDriver = NULL;
+
+ if (requiredDriverID <= 0) {
+ if ((numDriver < 2) ||
+ (monitor == NULL) ||
+ (osvi.dwMajorVersion < 4)) {
+ // windows 95 don't support multiple monitors
+ // Use Primary display driver
+ newDriver = d3dDriverList[0];
+ } else {
+ for (int i=0; i < numDriver; i++) {
+ if (d3dDriverList[i]->hMonitor == monitor) {
+ newDriver = d3dDriverList[i];
+ break;
+ }
+ }
+ }
+ } else {
+ if (requiredDriverID > numDriver) {
+ requiredDriverID = numDriver;
+ }
+ newDriver = d3dDriverList[requiredDriverID-1];
+ }
+
+ driverInfo = newDriver;
+}
+
+
+VOID D3dCtx::setDefaultAttributes()
+{
+
+ pDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING,
+ softwareVertexProcessing);
+
+ pDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE,
+ D3DMCS_MATERIAL);
+ pDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE,
+ D3DMCS_MATERIAL);
+ pDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);
+ // Default specular is FALSE
+ pDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
+ // Texture & CULL mode default value for D3D is different from OGL
+
+ pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
+
+ // Default in D3D is D3DCMP_LESSEQUAL, OGL is D3DCMP_LESS
+
+ // Set Range based fog
+ pDevice->SetRenderState(D3DRS_RANGEFOGENABLE,
+ deviceInfo->rangeFogEnable);
+
+ // disable antialiasing (default is true in D3D)
+ if (!implicitMultisample) {
+ pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
+ }
+
+ pointSize = 1;
+ cullMode = D3DCULL_CW;
+ fillMode = D3DFILL_SOLID;
+ zWriteEnable = TRUE;
+ zEnable = TRUE;
+
+ if ((pDevice != NULL) && (bindTextureId != NULL)) {
+ for (int i=0; i < bindTextureIdLen; i++) {
+ pDevice->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ pDevice->SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ pDevice->SetTextureStageState(i, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ pDevice->SetTextureStageState(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ pDevice->SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
+ pDevice->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
+ bindTextureId[i] = -1;
+ }
+ }
+
+
+ for (int i=0; i < TEXSTAGESUPPORT; i++) {
+ texGenMode[i] = TEX_GEN_NONE;
+ texTransformSet[i] = false;
+ texCoordFormat[i] = 2;
+ texTransform[i] = identityMatrix;
+ texStride[i] = 0;
+ texTranslateSet[i] = false;
+ }
+}
+
+VOID D3dCtx::enumDisplayMode(DEVMODE* dmode)
+{
+
+ MONITORINFOEX mi;
+
+ if (monitor == NULL) {
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, dmode );
+ } else {
+ mi.cbSize = sizeof(MONITORINFOEX);
+ GetMonitorInfo(monitor, (MONITORINFOEX *) &mi);
+ dmode->dmSize = sizeof(DEVMODE);
+ EnumDisplaySettings( mi.szDevice, ENUM_CURRENT_SETTINGS, dmode);
+ }
+}
+
+DWORD D3dCtx::findBehavior()
+{
+ if (deviceInfo->isHardwareTnL &&
+ ((requiredDeviceID < 0) || (requiredDeviceID == DEVICE_HAL_TnL))) {
+ softwareVertexProcessing = FALSE;
+ return D3DCREATE_MIXED_VERTEXPROCESSING;
+ } else {
+ softwareVertexProcessing = TRUE;
+ return D3DCREATE_SOFTWARE_VERTEXPROCESSING;
+ }
+}
+
+VOID D3dCtx::printInfo(D3DPRESENT_PARAMETERS *d3dPresent)
+{
+
+ if (d3dPresent->Windowed) {
+ printf("Window ");
+ } else {
+ printf("FullScreen ");
+ }
+
+ printf("%dx%d %s, handle=%x, %s, %s, %s\n",
+ d3dPresent->BackBufferWidth,
+ d3dPresent->BackBufferHeight,
+ getPixelFormatName(d3dPresent->BackBufferFormat),
+ d3dPresent->hDeviceWindow,
+ getMultiSampleName(d3dPresent->MultiSampleType),
+ getSwapEffectName(d3dPresent->SwapEffect),
+ getPixelFormatName(d3dPresent->AutoDepthStencilFormat));
+}
+
+VOID D3dCtx::setWindowMode()
+{
+ if (inToggle) {
+ if (!bFullScreen) {
+ SetWindowLong(topHwnd, GWL_STYLE, winStyle);
+ SetWindowPos(topHwnd, HWND_NOTOPMOST, savedTopRect.left, savedTopRect.top,
+ savedTopRect.right - savedTopRect.left,
+ savedTopRect.bottom - savedTopRect.top,
+ SWP_SHOWWINDOW);
+ } else {
+ SetWindowLong(topHwnd, GWL_STYLE,
+ WS_POPUP|WS_SYSMENU|WS_VISIBLE);
+ }
+ }
+
+}
+
+VOID D3dCtx::setAmbientLightMaterial()
+{
+ // We need to set a constant per vertex color
+ // There is no way in D3D to do this. It is workaround
+ // by adding Ambient light and set Ambient Material
+ // color temporary
+ pDevice->GetLight(0, &savedLight);
+ pDevice->GetMaterial(&savedMaterial);
+ pDevice->GetLightEnable(0, &savedLightEnable);
+
+ CopyColor(ambientMaterial.Ambient,
+ currentColor_r,
+ currentColor_g,
+ currentColor_b,
+ currentColor_a);
+
+
+ // This is what the specification say it should set
+ ambientMaterial.Specular.a = currentColor_a;
+
+ // This is what we found after testing - spec. is not correct
+ ambientMaterial.Diffuse.a = currentColor_a;
+
+ pDevice->SetLight(0, &ambientLight);
+ pDevice->SetMaterial(&ambientMaterial);
+ pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
+ pDevice->LightEnable(0, TRUE);
+}
+
+VOID D3dCtx::restoreDefaultLightMaterial()
+{
+ // restore original values after setAmbientLightMaterial()
+ pDevice->SetLight(0, &savedLight);
+ pDevice->SetMaterial(&savedMaterial);
+ pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
+ pDevice->LightEnable(0, savedLightEnable);
+}
+
+VOID D3dCtx::freeVBList(D3dVertexBufferVector *v)
+{
+ LPD3DVERTEXBUFFER *p, r;
+
+ lockGeometry();
+
+ for (p = v->begin(); p != v->end(); ++p) {
+ // Remove itself from current ctx vertexBufferTable list
+ r = (*p)->next;
+ if (r != NULL) {
+ r->previous = (*p)->previous;
+ }
+ (*p)->previous->next = r;
+ // Now we can free current VB
+ delete (*p);
+ }
+ v->clear();
+ unlockGeometry();
+}
+
+
+VOID D3dCtx::freeResourceList(LPDIRECT3DRESOURCE8Vector *v)
+{
+ LPDIRECT3DRESOURCE8 *s;
+
+ lockSurfaceList();
+ for (s = v->begin(); s != v->end(); ++s) {
+ (*s)->Release();
+ }
+ v->clear();
+ unlockSurfaceList();
+}
+
+VOID D3dCtx::freeList()
+{
+ if (useFreeList0) {
+ if (freeResourceList1.size() > 0) {
+ freeResourceList(&freeResourceList1);
+ }
+ if (freeVBList1.size() > 0) {
+ freeVBList(&freeVBList1);
+ }
+ useFreeList0 = false;
+ } else {
+ if (freeResourceList0.size() > 0) {
+ freeResourceList(&freeResourceList0);
+ }
+ if (freeVBList0.size() > 0) {
+ freeVBList(&freeVBList0);
+ }
+ useFreeList0 = true;
+ }
+}
+
+VOID D3dCtx::freeVB(LPD3DVERTEXBUFFER vb)
+{
+ if (vb != NULL) {
+ lockSurfaceList();
+ if (useFreeList0) {
+ freeVBList0.push_back(vb);
+ } else {
+ freeVBList1.push_back(vb);
+ }
+ unlockSurfaceList();
+ }
+}
+
+
+VOID D3dCtx::freeResource(LPDIRECT3DRESOURCE8 res)
+{
+ if (res != NULL) {
+ lockSurfaceList();
+ if (useFreeList0) {
+ freeResourceList0.push_back(res);
+ } else {
+ freeResourceList1.push_back(res);
+ }
+ unlockSurfaceList();
+ }
+}
+
+BOOL D3dCtx::createFrontBuffer()
+{
+ HRESULT hr;
+
+ hr = pDevice->CreateImageSurface(driverInfo->desktopMode.Width,
+ driverInfo->desktopMode.Height,
+ D3DFMT_A8R8G8B8,
+ &frontSurface);
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("[Java3D] Fail to CreateImageSurface %s\n",
+ DXGetErrorString8(hr));
+ }
+ frontSurface = NULL;
+ return false;
+ }
+ return true;
+}
+
+
+
diff --git a/src/native/d3d/D3dCtx.hpp b/src/native/d3d/D3dCtx.hpp
new file mode 100644
index 0000000..83added
--- /dev/null
+++ b/src/native/d3d/D3dCtx.hpp
@@ -0,0 +1,325 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#if !defined(D3DCTX_H)
+#define D3DCTX_H
+
+
+#include "StdAfx.h"
+#include "D3dVertexBuffer.hpp"
+#include "D3dDisplayList.hpp"
+
+#define TEXTURETABLESIZE 8
+#define TEXSTAGESUPPORT 8
+#define DISPLAYLIST_INITSIZE 8
+#define NOCHANGE 0
+#define RESETSURFACE 1
+#define RECREATEDDRAW 2
+#define RECREATEDFAIL -1
+
+
+// Use in texCoordPosition[]
+// Must be negative number
+#define TEX_GEN_NONE 0
+#define TEX_EYE_LINEAR -1
+#define TEX_SPHERE_MAP -2
+#define TEX_NORMAL_MAP -3
+#define TEX_REFLECT_MAP -4
+#define TEX_OBJ_LINEAR -5
+#define TEX_GEN_INVALID -6
+#define TEX_GEN_AUTO -7
+
+typedef struct _D3DVERTEX {
+ float x, y, z;
+} D3DVERTEX;
+
+typedef struct _D3DTLVERTEX {
+ float sx, sy, sz, rhw;
+ float tu, tv;
+} D3DTLVERTEX;
+
+typedef vector<LPDIRECT3DRESOURCE8> LPDIRECT3DRESOURCE8Vector;
+typedef vector<LPDIRECT3DVERTEXBUFFER8> LPDIRECT3DVERTEXBUFFER8Vector;
+
+class D3dCtx {
+public:
+
+ HWND hwnd; // window handle
+ HWND topHwnd; // Top window handle
+ D3dDriverInfo *driverInfo; // Driver use
+ D3dDeviceInfo *deviceInfo; // Device use
+
+ LPDIRECT3D8 pD3D; // Direct3D interface
+ LPDIRECT3DDEVICE8 pDevice; // Instance of D3D Device
+
+ LPDIRECT3DSURFACE8 depthStencilSurface;
+
+ // This is used for readRaster and offscreen rendering
+ // Only allocate the memory area if necessary
+ LPDIRECT3DSURFACE8 frontSurface;
+
+ LPDIRECT3DSURFACE8 backSurface;
+
+ // Parameters use for CreateDevice()
+ D3DPRESENT_PARAMETERS d3dPresent;
+ DWORD dwBehavior;
+
+ BOOL offScreen; // true if it is offScreen rendering
+ // in this case only backSurface is used
+ DWORD offScreenWidth;
+ DWORD offScreenHeight;
+
+ BOOL bFullScreen; // true if in full screen mode
+ BOOL bFullScreenRequired; // true if must run in full
+ // screen mode or die
+ BOOL inToggle; // in toggle fullscreen/window mode
+ RECT screenRect; // coordinate of window relative to
+ // the whole desktop in multiple monitor
+ RECT windowRect; // coordinate of window relative to
+ // the current monitor desktop only
+ INT minZDepth; // min Z depth set in NativeConfigTemplate
+
+ DEVMODE devmode; // current display mode
+ DWORD antialiasing; // PREFERRED, REQUIRED or UNNECESSARY
+
+
+ // Store current color as in OGL glColor()
+ float currentColor_r;
+ float currentColor_g;
+ float currentColor_b;
+ float currentColor_a;
+
+ // Two side light is used. Note that D3D don't support two side
+ // lighting.
+ BOOL twoSideLightingEnable;
+
+ // True if lighting is currently enable
+ // Save the current RenderingState to avoid GetRenderState()
+ // call during Rendering.
+ BOOL isLightEnable;
+ DWORD cullMode;
+ DWORD fillMode;
+ DWORD softwareVertexProcessing;
+ DWORD zWriteEnable;
+ DWORD zEnable;
+
+ // Ambient material used when coloring Attributes
+ D3DMATERIAL8 ambientMaterial;
+
+ // temporary variables for ambient light setting
+ D3DLIGHT8 savedLight;
+ D3DMATERIAL8 savedMaterial;
+ BOOL savedLightEnable;
+
+ // temporary variables used for building VertexBuffer
+ LPD3DVERTEXBUFFER pVB; // point to the current VB being update
+ DWORD texSetUsed;
+ DWORD texStride[TEXSTAGESUPPORT];
+
+ // true when in toggle mode
+ BOOL forceResize;
+
+ // Texture related variables
+ INT *bindTextureId;
+ DWORD bindTextureIdLen;
+
+ LPDIRECT3DTEXTURE8 *textureTable;
+ DWORD textureTableLen;
+
+ // Volume Texture related variables
+ // Since 2d & 3d texture ID can't be the same from Java3D.
+ // We don't need bindVolumeId
+ LPDIRECT3DVOLUMETEXTURE8 *volumeTable;
+ DWORD volumeTableLen;
+
+ // Texture Cube Mapping related variables
+ LPDIRECT3DCUBETEXTURE8 *cubeMapTable;
+ DWORD cubeMapTableLen;
+
+ // true if hardware support MultiTexture
+ BOOL multiTextureSupport;
+
+ // handle to monitor that this ctx belongs to. This is equal to
+ // NULL if this window is a primary display screen or it covers
+ // more than one screen.
+ HMONITOR monitor;
+
+ // D3D don't have concept of current texture unit stage,
+ // instead, the texture unit stage is pass in as argument
+ // for all texture call.
+ INT texUnitStage;
+
+ // true if linear filtering is to be used
+ BOOL texLinearMode;
+
+
+ // This is used temporary to store the blend function
+ // when two pass texture is used to simulate BLEND mode
+ DWORD srcBlendFunc;
+ DWORD dstBlendFunc;
+ DWORD blendEnable;
+
+
+ // This is used for to transform vertex
+ // from world to screen coordinate
+ LPDIRECT3DVERTEXBUFFER8 srcVertexBuffer;
+ LPDIRECT3DVERTEXBUFFER8 dstVertexBuffer;
+
+ // For Rect of texture map in Raster write
+ D3DTLVERTEX rasterRect[4];
+
+ // Set automatic Texture coordinate generation type
+ // TEX_xxx_xxx as defined in GeometryArrayRetained.cpp
+ INT texGenMode[TEXSTAGESUPPORT];
+
+ // Whether TEXTURE_COORDINATE_2/3/4 is used in this state
+ INT texCoordFormat[TEXSTAGESUPPORT];
+
+ // Whether texture transform matrix is set in this state or not
+ BOOL texTransformSet[TEXSTAGESUPPORT];
+
+ // Remember the last Texture Transform pass down, since
+ // TexCoordGen may destroy it in some mode so we have to
+ // restore it later manually.
+ D3DXMATRIX texTransform[TEXSTAGESUPPORT];
+
+ // True if we copy m._41, m._42 elment to m._31, m._32
+ // as a workaround that 2D texture translation did not work.
+ BOOL texTranslateSet[TEXSTAGESUPPORT];
+
+ float planeS[TEXSTAGESUPPORT][4];
+ float planeT[TEXSTAGESUPPORT][4];
+ float planeR[TEXSTAGESUPPORT][4];
+ float planeQ[TEXSTAGESUPPORT][4];
+
+ // Display List ID (start from 1) => VertexBuffer pointer table
+ LPD3DDISPLAYLIST *displayListTable;
+ int dlTableSize;
+
+ // For immediate mode rendering, we save the vertexBuffer pointer
+ // in variable pVertexBuffer of GeometryArrayRetained to reuse it.
+ D3dVertexBuffer vertexBufferTable;
+
+ int currDisplayListID;
+
+ // True if colorTarget need to reset
+ BOOL resetColorTarget;
+
+ // Use for QuadArray
+ LPDIRECT3DINDEXBUFFER8 quadIndexBuffer;
+ DWORD quadIndexBufferSize;
+
+ // Use for Quad Polygon Line mode
+ LPDIRECT3DINDEXBUFFER8 lineModeIndexBuffer;
+
+ // Use temporary for reindexing
+ DWORD *reIndexifyTable;
+
+ // True if Direcct Draw context is being destroy and recreate
+ // again during resize/toggle
+ BOOL recreateDDraw;
+
+ // Screen coordinate of current monitor in use
+ // When hardware accleerated mode is used. For Emulation mode
+ // they are always zero;
+ INT monitorLeft;
+ INT monitorTop;
+ float pointSize;
+
+ // Use to free resource surface in swap()
+ BOOL useFreeList0;
+ LPDIRECT3DRESOURCE8Vector freeResourceList0;
+ LPDIRECT3DRESOURCE8Vector freeResourceList1;
+ D3dVertexBufferVector freeVBList0;
+ D3dVertexBufferVector freeVBList1;
+
+ D3dCtx(JNIEnv *env, jobject obj, HWND hwnd, BOOL offScreen, jint vid);
+ ~D3dCtx();
+
+ BOOL initialize(JNIEnv *env, jobject obj);
+ INT resize(JNIEnv *env, jobject obj);
+ VOID error(char *s, HRESULT hr);
+ VOID error(int idx, HRESULT hr);
+ VOID error(int idx);
+ VOID error(char *s);
+ VOID warning(int idx, HRESULT hr);
+ VOID warning(int idx);
+
+ static VOID d3dError(int idx);
+ static VOID d3dError(char *s);
+ static VOID d3dWarning(int idx, HRESULT hr);
+ static VOID d3dWarning(int idx);
+
+ INT toggleMode(BOOL fullScreen, JNIEnv *env, jobject obj);
+ DWORD getWidth();
+ DWORD getHeight();
+
+ VOID release();
+ VOID releaseTexture();
+ VOID releaseVB();
+ VOID setViewport();
+ VOID transform(D3DVERTEX *worldCoord, D3DTLVERTEX *screenCoord);
+ VOID getScreenRect(HWND hwnd, RECT *rect);
+ HMONITOR findMonitor();
+ VOID setDriverInfo();
+ static D3dDeviceInfo* setDeviceInfo(D3dDriverInfo *driverInfo,
+ BOOL *bFullScreen,
+ int minZDepth);
+ DWORD findBehavior();
+ VOID setPresentParams();
+ INT resetSurface(JNIEnv *env, jobject obj);
+ VOID setPresentParams(JNIEnv *env, jobject obj);
+ VOID setAmbientLightMaterial();
+ VOID restoreDefaultLightMaterial();
+ VOID freeResource(LPDIRECT3DRESOURCE8 surf);
+ VOID freeVB(LPD3DVERTEXBUFFER vb);
+
+ VOID freeList();
+ VOID freeResourceList(LPDIRECT3DRESOURCE8Vector *v);
+ VOID freeVBList(D3dVertexBufferVector *v);
+ BOOL createFrontBuffer();
+
+ static D3dDeviceInfo* selectDevice(int deviceID,
+ D3dDriverInfo *driverInfo,
+ BOOL *bFullScreen,
+ int minZDepth);
+ static D3dDeviceInfo* selectBestDevice(D3dDriverInfo *driverInfo,
+ BOOL *bFullScreen,
+ int minZDepth);
+ static VOID setDeviceFromProperty(JNIEnv *env);
+ static VOID setDebugProperty(JNIEnv *env);
+ static VOID setVBLimitProperty(JNIEnv *env);
+ static VOID setImplicitMultisamplingProperty(JNIEnv *env);
+
+private:
+
+ RECT savedTopRect; // for toggle between fullscreen mode
+ RECT savedClientRect;
+ DWORD winStyle;
+
+ VOID createVertexBuffer();
+
+ VOID setCanvasProperty(JNIEnv *env, jobject obj);
+ VOID setFullScreenFromProperty(JNIEnv *env);
+ VOID enumDisplayMode(DEVMODE *devmode);
+
+ static VOID printWarningMessage(D3dDeviceInfo *deviceInfo);
+ static VOID showError(HWND hwnd, char *s, BOOL bFullScreen);
+ VOID setDefaultAttributes();
+ VOID printInfo(D3DPRESENT_PARAMETERS *d3dPresent);
+ VOID setWindowMode();
+};
+
+typedef vector<D3dCtx *> D3dCtxVector;
+extern D3dCtxVector d3dCtxList;
+const extern D3DXMATRIX identityMatrix;
+#endif
diff --git a/src/native/d3d/D3dDeviceInfo.cpp b/src/native/d3d/D3dDeviceInfo.cpp
new file mode 100644
index 0000000..4a12167
--- /dev/null
+++ b/src/native/d3d/D3dDeviceInfo.cpp
@@ -0,0 +1,204 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "Stdafx.h"
+
+// return true if device is capable of hardware accelerated
+
+D3dDeviceInfo::D3dDeviceInfo()
+{
+}
+
+D3dDeviceInfo::~D3dDeviceInfo()
+{
+}
+
+VOID D3dDeviceInfo::setCaps(D3DCAPS8 *d3dCaps) {
+
+ if (deviceType == D3DDEVTYPE_HAL) {
+ isHardware = true;
+ isHardwareTnL = (d3dCaps->DevCaps &
+ D3DDEVCAPS_HWTRANSFORMANDLIGHT);
+ } else {
+ isHardware = false;
+ isHardwareTnL = false;
+ }
+ maxTextureBlendStages = d3dCaps->MaxTextureBlendStages;
+ maxSimultaneousTextures = d3dCaps->MaxSimultaneousTextures;
+ maxTextureUnitStageSupport = min(maxTextureBlendStages,
+ maxSimultaneousTextures);
+ supportMipmap = ((d3dCaps->TextureCaps &
+ D3DPTEXTURECAPS_MIPMAP) != 0);
+ texturePow2Only = ((d3dCaps->TextureCaps &
+ D3DPTEXTURECAPS_POW2) != 0);
+ textureSquareOnly = ((d3dCaps->TextureCaps &
+ D3DPTEXTURECAPS_SQUAREONLY) != 0);
+ linePatternSupport = ((d3dCaps->PrimitiveMiscCaps &
+ D3DPMISCCAPS_LINEPATTERNREP) != 0);
+ texBorderModeSupport = ((d3dCaps->TextureAddressCaps &
+ D3DPTADDRESSCAPS_BORDER) != 0);
+ texLerpSupport = ((d3dCaps->TextureOpCaps &
+ D3DTEXOPCAPS_LERP) != 0);
+ canRenderWindowed = ((d3dCaps->Caps2 &
+ D3DCAPS2_CANRENDERWINDOWED) != 0);
+ maxPrimitiveCount = d3dCaps->MaxPrimitiveCount;
+ maxVertexIndex = min(vertexBufferMaxVertexLimit,
+ d3dCaps->MaxVertexIndex);
+ maxTextureHeight = d3dCaps->MaxTextureHeight;
+ maxTextureWidth = d3dCaps->MaxTextureWidth;
+ maxTextureDepth = d3dCaps->MaxVolumeExtent;
+
+ maxActiveLights = d3dCaps->MaxActiveLights;
+ maxPointSize = d3dCaps->MaxPointSize;
+ maxAnisotropy = d3dCaps->MaxAnisotropy;
+
+ maxVertexCount[GEO_TYPE_QUAD_SET] = min(vertexBufferMaxVertexLimit,
+ maxPrimitiveCount << 1);
+
+ // Since index is used, we need to make sure than index range
+ // is also support.
+ maxVertexCount[GEO_TYPE_QUAD_SET] = min(maxVertexCount[GEO_TYPE_QUAD_SET],
+ maxVertexIndex);
+
+ maxVertexCount[GEO_TYPE_TRI_SET] = min(vertexBufferMaxVertexLimit,
+ maxPrimitiveCount*3);
+ maxVertexCount[GEO_TYPE_POINT_SET] = min(vertexBufferMaxVertexLimit,
+ maxPrimitiveCount);
+ maxVertexCount[GEO_TYPE_LINE_SET] = min(vertexBufferMaxVertexLimit,
+ maxPrimitiveCount << 1);
+ maxVertexCount[GEO_TYPE_TRI_STRIP_SET] = min(vertexBufferMaxVertexLimit,
+ maxPrimitiveCount + 2);
+ maxVertexCount[GEO_TYPE_TRI_FAN_SET] = min(vertexBufferMaxVertexLimit,
+ maxPrimitiveCount + 2);
+ maxVertexCount[GEO_TYPE_LINE_STRIP_SET] = min(vertexBufferMaxVertexLimit,
+ maxPrimitiveCount +1);
+ maxVertexCount[GEO_TYPE_INDEXED_QUAD_SET] = maxVertexCount[GEO_TYPE_QUAD_SET];
+ maxVertexCount[GEO_TYPE_INDEXED_TRI_SET] = maxVertexCount[GEO_TYPE_TRI_SET];
+ maxVertexCount[GEO_TYPE_INDEXED_POINT_SET] = maxVertexCount[GEO_TYPE_POINT_SET];
+ maxVertexCount[GEO_TYPE_INDEXED_LINE_SET] = maxVertexCount[GEO_TYPE_LINE_SET];
+ maxVertexCount[GEO_TYPE_INDEXED_TRI_STRIP_SET] = maxVertexCount[GEO_TYPE_TRI_STRIP_SET];
+ maxVertexCount[GEO_TYPE_INDEXED_TRI_FAN_SET] = maxVertexCount[GEO_TYPE_TRI_FAN_SET];
+ maxVertexCount[GEO_TYPE_INDEXED_LINE_STRIP_SET] = maxVertexCount[GEO_TYPE_LINE_STRIP_SET];
+
+
+ if (((d3dCaps->RasterCaps & D3DPRASTERCAPS_FOGTABLE) != 0) &&
+ ((d3dCaps->RasterCaps & D3DPRASTERCAPS_WFOG) != 0)) {
+ // use pixel w-fog
+ fogMode = D3DRS_FOGTABLEMODE;
+ rangeFogEnable = false;
+ } else if (((d3dCaps->RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0) &&
+ ((d3dCaps->RasterCaps & D3DPRASTERCAPS_FOGRANGE) != 0)) {
+ // use vertex range based fog
+ fogMode = D3DRS_FOGVERTEXMODE;
+ rangeFogEnable = true;
+ } else if ((d3dCaps->RasterCaps & D3DPRASTERCAPS_FOGTABLE) != 0) {
+ // use pixel z-fog
+ fogMode = D3DRS_FOGTABLEMODE;
+ rangeFogEnable = false;
+ } else if (D3DPRASTERCAPS_FOGVERTEX) {
+ // use vertex z-fog
+ fogMode = D3DRS_FOGVERTEXMODE;
+ rangeFogEnable = false;
+ } else {
+ if (debug) {
+ printf("[Java 3D] Fog not support in this device !\n");
+ }
+ }
+
+
+ texMask = 0;
+
+ if ((d3dCaps->TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) &&
+ (maxTextureDepth > 0)) {
+ texMask |= javax_media_j3d_Canvas3D_TEXTURE_3D;
+ }
+
+ if (d3dCaps->TextureCaps & D3DPTEXTURECAPS_CUBEMAP) {
+ texMask |= javax_media_j3d_Canvas3D_TEXTURE_CUBE_MAP;
+ }
+
+ if (maxTextureUnitStageSupport > 1) {
+ texMask |= javax_media_j3d_Canvas3D_TEXTURE_MULTI_TEXTURE;
+ }
+
+ if (d3dCaps->TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) {
+ texMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE_DOT3;
+ }
+
+ if (d3dCaps->TextureOpCaps & D3DTEXOPCAPS_SUBTRACT) {
+ texMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE_SUBTRACT;
+ }
+
+ if (d3dCaps->TextureOpCaps & D3DTEXOPCAPS_LERP) {
+ texMask |= (javax_media_j3d_Canvas3D_TEXTURE_LERP|
+ javax_media_j3d_Canvas3D_TEXTURE_COMBINE);
+ } else if (d3dCaps->TextureOpCaps &
+ (D3DTEXOPCAPS_DOTPRODUCT3|D3DTEXOPCAPS_SUBTRACT|
+ D3DTEXOPCAPS_MODULATE|D3DTEXOPCAPS_ADD|
+ D3DTEXOPCAPS_ADDSIGNED)) {
+ texMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE;
+ }
+
+
+ if (maxAnisotropy > 1) {
+ texMask |= javax_media_j3d_Canvas3D_TEXTURE_ANISOTROPIC_FILTER;
+ }
+}
+
+BOOL D3dDeviceInfo::supportAntialiasing() {
+ return (multiSampleSupport != 0);
+}
+
+
+void D3dDeviceInfo::findDepthStencilFormat(int minZDepth)
+{
+ depthStencilFormat = D3DFMT_UNKNOWN;
+ for (int i=0; i < D3DDEPTHFORMATSIZE; i++) {
+ if (depthFormatSupport[i]) {
+ // prefer one with stencil buffer, follow by D3DFMT_D16_LOCKABLE,
+ if (d3dDepthTable[i] >= minZDepth) {
+ depthStencilFormat = (D3DFORMAT) d3dDepthFormat[i];
+ break;
+ }
+ }
+ }
+}
+
+
+D3DMULTISAMPLE_TYPE D3dDeviceInfo::getBestMultiSampleType()
+{
+ DWORD bitmask = 0;
+ UINT i;
+
+ // start with 4, if none found, try 3 and 2
+ for (i=4; i < 16; i++) {
+ bitmask = (1 << i);
+ if (multiSampleSupport & bitmask) {
+ return (D3DMULTISAMPLE_TYPE) i;
+ }
+ }
+
+ for (i=3; i >= 2; i--) {
+ bitmask = (1 << i);
+ if (multiSampleSupport & bitmask) {
+ return (D3DMULTISAMPLE_TYPE) i;
+ }
+ }
+
+ // Should not happen
+ return D3DMULTISAMPLE_NONE;
+}
+
+int D3dDeviceInfo::getTextureFeaturesMask()
+{
+ return texMask;
+}
diff --git a/src/native/d3d/D3dDeviceInfo.hpp b/src/native/d3d/D3dDeviceInfo.hpp
new file mode 100644
index 0000000..7701261
--- /dev/null
+++ b/src/native/d3d/D3dDeviceInfo.hpp
@@ -0,0 +1,85 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#if !defined(D3DDEVICEINFO_H)
+#define D3DDEVICEINFO_H
+
+#include "StdAfx.h"
+
+extern UINT vertexBufferMaxVertexLimit;
+
+#define D3DDEPTHFORMATSIZE 6
+
+class D3dDeviceInfo {
+public:
+ // Hardware Rasterizer
+ // Transform & Light Hardware Rasterizer
+ // Reference Rasterizer
+ char deviceName[40]; // One of above name
+ D3DDEVTYPE deviceType; // D3DDEVTYPE_HAL or D3DDEVTYPE_REF
+ BOOL desktopCompatible; // Can render in desktop mode
+ BOOL fullscreenCompatible; // Can render in fullscreen mode
+ // using current desktop mode setting
+
+ // each bitmask correspond to the support of
+ // D3DMULTISAMPLE_i_SAMPLES type, i = 2...16
+ DWORD multiSampleSupport;
+
+ // TRUE when d3dDepthFormat[i] support
+ BOOL depthFormatSupport[D3DDEPTHFORMATSIZE];
+
+ // depth format select
+ D3DFORMAT depthStencilFormat;
+
+ // max z buffer depth support
+ UINT maxZBufferDepthSize;
+
+ // Max vetex count support for each primitive
+ DWORD maxVertexCount[GEO_TYPE_INDEXED_LINE_STRIP_SET+1];
+
+ BOOL isHardware;
+ BOOL isHardwareTnL;
+ BOOL canRenderWindowed;
+ BOOL supportMipmap;
+ BOOL texturePow2Only;
+ BOOL textureSquareOnly;
+ BOOL linePatternSupport;
+ BOOL texBorderModeSupport;
+ BOOL texLerpSupport;
+ DWORD maxTextureUnitStageSupport;
+ DWORD maxTextureBlendStages;
+ DWORD maxSimultaneousTextures;
+ DWORD maxTextureWidth;
+ DWORD maxTextureHeight;
+ DWORD maxTextureDepth;
+ DWORD maxPrimitiveCount;
+ DWORD maxVertexIndex;
+ DWORD maxActiveLights;
+ DWORD maxPointSize;
+ DWORD rangeFogEnable;
+ D3DRENDERSTATETYPE fogMode;
+ int texMask;
+ int maxAnisotropy;
+
+ D3dDeviceInfo();
+ ~D3dDeviceInfo();
+
+ // set capabilities of this device
+ VOID setCaps(D3DCAPS8 *d3dCaps);
+ BOOL supportAntialiasing();
+ D3DMULTISAMPLE_TYPE getBestMultiSampleType();
+ int getTextureFeaturesMask();
+ void findDepthStencilFormat(int minZDepth);
+};
+
+#endif
+
diff --git a/src/native/d3d/D3dDisplayList.cpp b/src/native/d3d/D3dDisplayList.cpp
new file mode 100644
index 0000000..f2de71e
--- /dev/null
+++ b/src/native/d3d/D3dDisplayList.cpp
@@ -0,0 +1,330 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+#include "D3dDisplayList.hpp"
+
+D3dDisplayList::D3dDisplayList()
+{
+}
+
+D3dDisplayList::~D3dDisplayList()
+{
+ for (D3dVertexBuffer **p = vBufferVec.begin();
+ p != vBufferVec.end(); p++) {
+ SafeDelete(*p);
+ }
+ vBufferVec.empty();
+}
+
+VOID D3dDisplayList::render(D3dCtx *d3dCtx)
+{
+ for (D3dVertexBuffer **p = vBufferVec.begin();
+ p != vBufferVec.end(); p++) {
+ (*p)->render(d3dCtx);
+ }
+}
+
+VOID D3dDisplayList::add(LPD3DVERTEXBUFFER vbuffer)
+{
+ vBufferVec.push_back(vbuffer);
+}
+
+
+BOOL D3dDisplayList::isQuad(LPD3DVERTEXBUFFER p)
+{
+ return (!p->isIndexPrimitive && (p->indexBuffer != NULL));
+}
+
+VOID D3dDisplayList::optimize(D3dCtx *d3dCtx)
+{
+
+ D3dVertexBufferVector vCloneBufferVec;
+ D3dVertexBuffer **r = vBufferVec.begin();
+
+ for (; r != vBufferVec.end(); r++) {
+ vCloneBufferVec.push_back(*r);
+
+ }
+
+ vBufferVec.erase(vBufferVec.begin(), vBufferVec.end());
+
+ D3dVertexBuffer **vbegin = vCloneBufferVec.begin();
+ D3dVertexBuffer **vend = vCloneBufferVec.end();
+ D3dVertexBuffer **q = vbegin;
+ D3dVertexBuffer **p;
+ int primitiveType, vcounts, climit;
+ int indexCounts = 0;
+ BOOL merge;
+ LPD3DVERTEXBUFFER mergedVB;
+ BOOL isPointFlagUsed;
+ DWORD vertexFormat;
+ BOOL isIndexPrimitive;
+ BOOL quadFlag;
+
+ while (q != vend) {
+ primitiveType = (*q)->primitiveType;
+ climit = (*q)->maxVertexLimit;
+ vcounts = (*q)->vcount;
+ isPointFlagUsed = (*q)->isPointFlagUsed;
+ vertexFormat = (*q)->vertexFormat;
+ isIndexPrimitive = (*q)->isIndexPrimitive;
+ quadFlag = isQuad(*q);
+
+ if ((*q)->indexBuffer != NULL) {
+ indexCounts = (*q)->indexCount;
+ }
+ merge = false;
+ p = q + 1;
+
+ while (p != vend) {
+ if (((*p)->primitiveType == primitiveType) &&
+ ((*p)->vertexFormat == vertexFormat) &&
+ ((*p)->isIndexPrimitive == isIndexPrimitive) &&
+ (isQuad(*p) == quadFlag) &&
+ ((*p)->isPointFlagUsed == isPointFlagUsed) &&
+ // This means Mutliple VBs already use
+ ((*p)->totalVertexCount == (*p)->vcount)) {
+ vcounts += (*p)->totalVertexCount;
+ if ((*p)->indexBuffer != NULL) {
+ indexCounts += (*p)->totalIndexCount;
+ }
+ if ((vcounts > climit) || (indexCounts > climit)) {
+ break;
+ }
+ p++;
+ merge = true;
+ } else {
+ break;
+ }
+ }
+
+ if (merge) {
+ mergedVB = createMergedVB(d3dCtx, q, p, vcounts, indexCounts);
+ if (mergedVB != NULL) {
+ for (r = q; r != p; r++) {
+ SafeDelete(*r);
+ }
+ vBufferVec.push_back(mergedVB);
+ } else {
+ for (r = q; r != p; r++) {
+ vBufferVec.push_back(*r);
+ }
+ }
+ } else {
+ vBufferVec.push_back(*q);
+ }
+ q = p;
+ }
+
+ vCloneBufferVec.erase(vCloneBufferVec.begin(), vCloneBufferVec.end());
+}
+
+
+
+LPD3DVERTEXBUFFER D3dDisplayList::createMergedVB(D3dCtx *d3dCtx,
+ D3dVertexBuffer **vstart,
+ D3dVertexBuffer **vend,
+ DWORD vcount,
+ DWORD indexCount)
+{
+ LPDIRECT3DDEVICE8 device = d3dCtx->pDevice;
+ D3dVertexBuffer **r;
+ UINT i;
+ HRESULT hr;
+ LPD3DVERTEXBUFFER vb = new D3dVertexBuffer();
+
+ vb->primitiveType = (*vstart)->primitiveType;
+ vb->isIndexPrimitive = (*vstart)->isIndexPrimitive;
+ vb->isPointFlagUsed = (*vstart)->isPointFlagUsed;
+ vb->vertexFormat = (*vstart)->vertexFormat;
+ vb->stride = (*vstart)->stride;
+ vb->ctx = (*vstart)->ctx;
+ vb->vcount = vb->totalVertexCount = vcount;
+ vb->indexCount = vb->totalIndexCount = indexCount;
+ vb->maxVertexLimit = (*vstart)->maxVertexLimit;
+
+ if (!vb->isPointFlagUsed) {
+ hr = device->CreateVertexBuffer(vb->stride*vcount,
+ D3DUSAGE_WRITEONLY,
+ vb->vertexFormat,
+ D3DPOOL_DEFAULT,
+ &vb->buffer);
+ } else {
+ hr = device->CreateVertexBuffer(vb->stride*vcount,
+ D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS,
+ vb->vertexFormat,
+ D3DPOOL_DEFAULT,
+ &vb->buffer);
+ }
+
+ if (FAILED(hr)) {
+ return NULL;
+ }
+
+ BYTE *bdst = NULL;
+ WORD *wdst = NULL;
+ UINT *idst = NULL;
+
+ hr = vb->buffer->Lock(0, 0, (BYTE**) &bdst, 0);
+ if (FAILED(hr)) {
+ SafeRelease(vb->buffer);
+ return NULL;
+ }
+
+ if (indexCount > 0) {
+ if (indexCount <= 0xffff) {
+ hr = device->CreateIndexBuffer(indexCount*sizeof(WORD),
+ D3DUSAGE_WRITEONLY,
+ D3DFMT_INDEX16,
+ D3DPOOL_DEFAULT,
+ &vb->indexBuffer);
+
+ } else {
+ hr = device->CreateIndexBuffer(indexCount*sizeof(UINT),
+ D3DUSAGE_WRITEONLY,
+ D3DFMT_INDEX32,
+ D3DPOOL_DEFAULT,
+ &vb->indexBuffer);
+ }
+ if (FAILED(hr)) {
+ vb->buffer->Unlock();
+ SafeRelease(vb->buffer);
+ return NULL;
+ }
+ if (indexCount <= 0xffff) {
+ hr = vb->indexBuffer->Lock(0, 0, (BYTE**) &wdst, 0);
+ } else {
+ hr = vb->indexBuffer->Lock(0, 0, (BYTE**) &idst, 0);
+ }
+ if (FAILED(hr)) {
+ vb->buffer->Unlock();
+ SafeRelease(vb->buffer);
+ SafeRelease(vb->indexBuffer);
+ return NULL;
+ }
+ }
+
+ BYTE *bsrc = NULL;
+ WORD *wsrc = NULL;
+ UINT *isrc = NULL;
+ UINT offset = 0;
+ DWORD len;
+ BOOL stripType = true;
+
+ if ((vb->primitiveType == D3DPT_POINTLIST) ||
+ (vb->primitiveType == D3DPT_LINELIST) ||
+ (vb->primitiveType == D3DPT_TRIANGLELIST)) {
+ vb->numVertices = new USHORT[1];
+ if (indexCount <= 0) {
+ vb->numVertices[0] = vcount;
+ } else {
+ vb->numVertices[0] = indexCount;
+ }
+ vb->numVerticesLen = 1;
+ vb->stripLen = 1;
+ stripType = false;
+ }
+
+ for (r = vstart; r != vend; r++) {
+ hr = (*r)->buffer->Lock(0, 0, (BYTE **) &bsrc, 0);
+
+ if (FAILED(hr)) {
+ vb->buffer->Unlock();
+ if (indexCount > 0) {
+ vb->indexBuffer->Unlock();
+ }
+ SafeRelease(vb->buffer);
+ SafeRelease(vb->indexBuffer);
+ return NULL;
+ }
+
+ if (indexCount > 0) {
+ if (indexCount <= 0xffff) {
+ hr = (*r)->indexBuffer->Lock(0, 0, (BYTE**) &wsrc, 0);
+ } else {
+ hr = (*r)->indexBuffer->Lock(0, 0, (BYTE**) &isrc, 0);
+ }
+ if (FAILED(hr)) {
+ (*r)->buffer->Unlock();
+ vb->buffer->Unlock();
+ SafeRelease(vb->buffer);
+ SafeRelease(vb->indexBuffer);
+ return NULL;
+ }
+ }
+ len = (*r)->vcount*(*r)->stride;
+ CopyMemory(bdst, bsrc, len);
+ if (stripType) {
+ vb->appendStrides((*r)->stripLen, (*r)->numVertices);
+ }
+ if (indexCount > 0) {
+ if (wdst != NULL) {
+ if (wsrc != NULL) {
+ for (i=0; i < (*r)->indexCount; i++) {
+ *wdst++ = offset + *wsrc++;
+ }
+ } else {
+ // should not happen
+ printf("[Java3D] Error in merging index vertex buffer\n");
+ }
+
+ } else {
+ if (wsrc != NULL) {
+ for (i=0; i < (*r)->indexCount; i++) {
+ *idst++ = offset + *wsrc++;
+ }
+ } else {
+ for (i=0; i < (*r)->indexCount; i++) {
+ *idst++ = offset + *isrc++;
+ }
+ }
+ }
+ offset += (*r)->vcount;
+ }
+ bdst += len;
+ (*r)->buffer->Unlock();
+ if (indexCount > 0) {
+ (*r)->indexBuffer->Unlock();
+ wsrc = NULL;
+ isrc = NULL;
+ }
+ }
+
+
+ vb->buffer->Unlock();
+ if (indexCount > 0) {
+ vb->indexBuffer->Unlock();
+ }
+
+ if (vb->isIndexPrimitive && (indexCount <= 0)) {
+ // QUAD is used, adjust size of index
+ createQuadIndices(d3dCtx, vcount);
+ }
+
+ for (i=0; i < D3DDP_MAXTEXCOORD; i++) {
+ vb->texCoordPosition[i] = -9999;
+ }
+
+
+ if (debug) {
+ int n = 0;
+ for (r = vstart; r != vend; r++) {
+ n++;
+ }
+ printf("Merge %d VB with primitiveType %d, vcount %d, indexCount %d\n",
+ n, vb->primitiveType, vcount, indexCount);
+ }
+ return vb;
+
+}
+
diff --git a/src/native/d3d/D3dDisplayList.hpp b/src/native/d3d/D3dDisplayList.hpp
new file mode 100644
index 0000000..f8323c6
--- /dev/null
+++ b/src/native/d3d/D3dDisplayList.hpp
@@ -0,0 +1,38 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#if !defined(D3DDISPLAYLIST_H)
+#define D3DDISPLAYLIST_H
+
+#include "StdAfx.h"
+#include "D3dVertexBuffer.hpp"
+
+
+class D3dDisplayList {
+public:
+ D3dDisplayList();
+ ~D3dDisplayList();
+ VOID add(LPD3DVERTEXBUFFER vBuffer);
+ VOID render(D3dCtx *d3dCtx);
+ VOID optimize(D3dCtx *d3dCtx);
+ BOOL isQuad(LPD3DVERTEXBUFFER p);
+ LPD3DVERTEXBUFFER createMergedVB(D3dCtx *d3dCtx,
+ D3dVertexBuffer **p,
+ D3dVertexBuffer **q,
+ DWORD vcount,
+ DWORD indexCount);
+
+private:
+ D3dVertexBufferVector vBufferVec;
+};
+typedef D3dDisplayList* LPD3DDISPLAYLIST;
+#endif
diff --git a/src/native/d3d/D3dDriverInfo.cpp b/src/native/d3d/D3dDriverInfo.cpp
new file mode 100644
index 0000000..81acdf7
--- /dev/null
+++ b/src/native/d3d/D3dDriverInfo.cpp
@@ -0,0 +1,320 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "Stdafx.h"
+
+
+const DWORD numDeviceTypes = 2;
+const D3DDEVTYPE deviceTypes[2] = { D3DDEVTYPE_HAL, D3DDEVTYPE_REF };
+D3dDriverInfo **d3dDriverList = NULL;
+int numDriver = 0; // size of above array list
+
+int requiredDeviceID = -1; // must use this Device or die
+
+// If this number is greater than zero, J3D must use the
+// adapter index in the order of GetAdapterIdentifier() starting from one.
+// Otherwise, the first driver found with monitor matching the display
+// driver is used.
+int requiredDriverID = -1;
+OSVERSIONINFO osvi;
+
+// There is bug in Nvidia driver which prevent VB too big
+// in TnL hardware vertex processing mode.
+// When the index is greater than 65535, the nvidia driver will
+// consider it to be N % 65535. However it works fine in
+// hardware vertex processing mode.
+UINT vertexBufferMaxVertexLimit = 65535;
+
+// True to disable setting D3DRS_MULTISAMPLEANTIALIAS
+// Rendering state.
+BOOL implicitMultisample;
+
+D3DFORMAT d3dDepthFormat[D3DDEPTHFORMATSIZE] = {D3DFMT_D15S1,
+ D3DFMT_D24S8,
+ D3DFMT_D24X4S4,
+ D3DFMT_D16_LOCKABLE,
+ D3DFMT_D16,
+ D3DFMT_D32};
+
+// This should match the depth bit in the above array
+int d3dDepthTable[D3DDEPTHFORMATSIZE] = {15, 24, 24, 16, 16, 32};
+D3DLIGHT8 ambientLight;
+
+D3dDriverInfo::D3dDriverInfo()
+{
+ for (int i=0; i < numDeviceTypes; i++) {
+ d3dDeviceList[i] = new D3dDeviceInfo();
+ }
+}
+
+D3dDriverInfo::~D3dDriverInfo()
+{
+ for (int i=0; i < numDeviceTypes; i++) {
+ SafeDelete(d3dDeviceList[i]);
+ }
+}
+
+VOID computeRGBDepth(D3dDriverInfo *pDriver)
+{
+ switch (pDriver->desktopMode.Format) {
+ case D3DFMT_R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ pDriver->redDepth = pDriver->greenDepth =
+ pDriver->blueDepth = 8;
+ break;
+ case D3DFMT_R5G6B5:
+ pDriver->redDepth = pDriver->blueDepth = 5;
+ pDriver->greenDepth = 6;
+ break;
+ case D3DFMT_X1R5G5B5:
+ case D3DFMT_A1R5G5B5:
+ pDriver->redDepth = pDriver->blueDepth =
+ pDriver->greenDepth = 5;
+ break;
+ case D3DFMT_A4R4G4B4:
+ case D3DFMT_X4R4G4B4:
+ pDriver->redDepth = pDriver->blueDepth =
+ pDriver->greenDepth = 4;
+ break;
+ case D3DFMT_R3G3B2:
+ case D3DFMT_A8R3G3B2:
+ pDriver->redDepth = pDriver->greenDepth = 3;
+ pDriver->blueDepth = 2;
+ default: // 8 color indexed or less
+ pDriver->redDepth = pDriver->blueDepth =
+ pDriver->greenDepth = 0;
+ }
+
+}
+
+VOID buildDriverList(LPDIRECT3D8 pD3D)
+{
+ numDriver = pD3D->GetAdapterCount();
+
+ if (numDriver <= 0) {
+ // keep d3dDriverList = NULL for checking later
+ D3dCtx::d3dError(DRIVERNOTFOUND);
+ return;
+ }
+
+ d3dDriverList = new LPD3dDriverInfo[numDriver];
+
+ if (d3dDriverList == NULL) {
+ D3dCtx::d3dError(OUTOFMEMORY);
+ return;
+ }
+
+ D3dDriverInfo *pDriver;
+
+ for (int i = 0; i < numDriver; i++ )
+ {
+ pDriver = new D3dDriverInfo();
+ d3dDriverList[i] = pDriver;
+ pD3D->GetAdapterIdentifier(i, D3DENUM_NO_WHQL_LEVEL,
+ &pDriver->adapterIdentifier);
+ pD3D->GetAdapterDisplayMode(i, &pDriver->desktopMode);
+ computeRGBDepth(pDriver);
+ pDriver->hMonitor = pD3D->GetAdapterMonitor(i);
+ pDriver->iAdapter = i;
+
+ for (int j = 0; j < numDeviceTypes; j++ )
+ {
+ D3DCAPS8 d3dCaps;
+ D3dDeviceInfo* pDevice = pDriver->d3dDeviceList[j];
+ pDevice->deviceType = deviceTypes[j];
+ pD3D->GetDeviceCaps(i, deviceTypes[j], &d3dCaps);
+ pDevice->setCaps(&d3dCaps);
+ pDevice->desktopCompatible =
+ SUCCEEDED(pD3D->CheckDeviceType(i, deviceTypes[j],
+ pDriver->desktopMode.Format,
+ pDriver->desktopMode.Format,
+ TRUE));
+ pDevice->fullscreenCompatible =
+ SUCCEEDED(pD3D->CheckDeviceType(i,deviceTypes[j],
+ pDriver->desktopMode.Format,
+ pDriver->desktopMode.Format,
+ FALSE));
+ pDevice->maxZBufferDepthSize = 0;
+
+ if (pDevice->isHardwareTnL) {
+ strcpy(pDevice->deviceName, "Transform & Light Hardware Rasterizer");
+ } else if (pDevice->isHardware) {
+ strcpy(pDevice->deviceName, "Hardware Rasterizer");
+ } else {
+ strcpy(pDevice->deviceName, "Reference Rasterizer");
+ }
+
+ for (int k=0; k < D3DDEPTHFORMATSIZE; k++) {
+ pDevice->depthFormatSupport[k] =
+ SUCCEEDED(pD3D->CheckDeviceFormat(i, deviceTypes[j],
+ pDriver->desktopMode.Format,
+ D3DUSAGE_DEPTHSTENCIL,
+ D3DRTYPE_SURFACE,
+ d3dDepthFormat[k]))
+ &&
+ SUCCEEDED(pD3D->CheckDepthStencilMatch(i, deviceTypes[j],
+ pDriver->desktopMode.Format,
+ pDriver->desktopMode.Format,
+ d3dDepthFormat[k]));
+ if (pDevice->depthFormatSupport[k]) {
+ if (d3dDepthTable[k] > pDevice->maxZBufferDepthSize) {
+ pDevice->maxZBufferDepthSize = d3dDepthTable[k];
+ }
+ }
+ }
+
+ DWORD bitmask = 1 << 2;
+ pDevice->multiSampleSupport = 0;
+ for (int mtype = D3DMULTISAMPLE_2_SAMPLES;
+ mtype <= D3DMULTISAMPLE_16_SAMPLES; mtype++) {
+ // consider desktop mode only for multisampling
+ if (SUCCEEDED(pD3D->CheckDeviceMultiSampleType(i, deviceTypes[j],
+ pDriver->desktopMode.Format,
+ TRUE,
+ (D3DMULTISAMPLE_TYPE) mtype))) {
+ pDevice->multiSampleSupport |= bitmask;
+ }
+ bitmask <<= 1;
+ }
+ }
+ }
+}
+
+
+
+// Cleanup when no more ctx exists
+VOID D3dDriverInfo::release()
+{
+ for (int i = 0; i < numDriver; i++ ) {
+ SafeDelete(d3dDriverList[i]);
+ }
+ SafeDelete(d3dDriverList);
+ numDriver = 0;
+}
+
+VOID printInfo()
+{
+ printf("Java 3D 1.3.2, Windows version is %d.%d ",
+ osvi.dwMajorVersion, osvi.dwMinorVersion);
+
+ printf("Build: %d, ", LOWORD(osvi.dwBuildNumber));
+
+ switch(osvi.dwPlatformId) {
+ case VER_PLATFORM_WIN32s:
+ printf("Windows3.1");
+ break;
+ case VER_PLATFORM_WIN32_WINDOWS:
+ printf("Windows 95/98");
+ break;
+ case VER_PLATFORM_WIN32_NT:
+ printf("Windows NT");
+ break;
+ }
+
+ printf(" %s", osvi.szCSDVersion);
+
+ D3dDriverInfo *pDriver;
+ for (int i=0; i < numDriver; i++) {
+ pDriver = d3dDriverList[i];
+ D3DADAPTER_IDENTIFIER8 *id = &pDriver->adapterIdentifier;
+ D3DDISPLAYMODE *dm = &pDriver->desktopMode;
+ printf("\n[Display Driver] %s, %s, Product %d\n",
+ id->Driver, id->Description,
+ HIWORD(id->DriverVersion.HighPart));
+ printf(" Version %d.%d, Build %d, VendorId %d\n",
+ LOWORD(id->DriverVersion.HighPart),
+ HIWORD(id->DriverVersion.LowPart),
+ LOWORD(id->DriverVersion.LowPart));
+ printf(" DeviceId 0x%x, SubSysId 0x%x, Revision 0x%d\n",
+ id->VendorId, id->DeviceId,
+ id->SubSysId, id->Revision);
+ printf(" [Desktop Mode] %dx%d ",
+ dm->Width, dm->Height);
+
+ if (dm->RefreshRate != 0) {
+ printf("%d MHz", dm->RefreshRate);
+ }
+ printf(", %s\n", getPixelFormatName(dm->Format));
+
+ for (int j=0; j < numDeviceTypes; j++) {
+ D3dDeviceInfo *pDevice = pDriver->d3dDeviceList[j];
+ printf("\t[Device] %s ", pDevice->deviceName);
+ if (pDevice->multiSampleSupport) {
+ printf("(AA)");
+ }
+ printf("\n");
+ }
+ }
+ printf("\n");
+}
+
+
+// Construct the D3dDriverList by enumerate all the drivers
+VOID D3dDriverInfo::initialize(JNIEnv *env)
+{
+ HINSTANCE hD3D8DLL = LoadLibrary( "D3D8.DLL" );
+
+ // Simply see if D3D8.dll exists.
+ if ( hD3D8DLL == NULL )
+ {
+ D3dCtx::d3dError(D3DNOTFOUND);
+ return;
+ }
+ FreeLibrary(hD3D8DLL);
+
+
+ LPDIRECT3D8 pD3D = Direct3DCreate8( D3D_SDK_VERSION );
+
+ if (pD3D == NULL) {
+ D3dCtx::d3dError(D3DNOTFOUND);
+ return;
+ }
+
+ // must appear before buildDriverList in order to
+ // set VertexBufferLimit correctly in D3dDeviceInfo
+ D3dCtx::setVBLimitProperty(env);
+
+ buildDriverList(pD3D);
+
+ SafeRelease(pD3D);
+
+ D3dCtx::setDebugProperty(env);
+
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osvi);
+
+ if (debug) {
+ printInfo();
+ }
+
+ // compute requiredGUID
+ D3dCtx::setDeviceFromProperty(env);
+
+ D3dCtx::setImplicitMultisamplingProperty(env);
+
+ RasterList.init();
+ BackgroundImageList.init();
+
+ // Setup Global constant Ambient light
+ ambientLight.Type = D3DLIGHT_DIRECTIONAL;
+ ambientLight.Direction.x = 0;
+ ambientLight.Direction.y = 0;
+ ambientLight.Direction.z = 1;
+ CopyColor(ambientLight.Diffuse, 0, 0, 0, 1.0f);
+ CopyColor(ambientLight.Ambient, 1.0f, 1.0f, 1.0f, 1.0f);
+ CopyColor(ambientLight.Specular, 0, 0, 0, 1.0f);
+}
+
+
+
+
diff --git a/src/native/d3d/D3dDriverInfo.hpp b/src/native/d3d/D3dDriverInfo.hpp
new file mode 100644
index 0000000..f907a99
--- /dev/null
+++ b/src/native/d3d/D3dDriverInfo.hpp
@@ -0,0 +1,61 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#if !defined(D3DDRIVERINFO_H)
+#define D3DDRIVERINFO_H
+
+#include "StdAfx.h"
+
+
+#define DEVICE_HAL 0
+#define DEVICE_REF 1
+#define DEVICE_HAL_TnL 2
+
+extern D3DFORMAT d3dDepthFormat[D3DDEPTHFORMATSIZE];
+extern int d3dDepthTable[D3DDEPTHFORMATSIZE];
+
+class D3dDriverInfo {
+public:
+ // DDraw Driver info
+ D3DADAPTER_IDENTIFIER8 adapterIdentifier;
+ // Desktop display mode for this adapter
+ D3DDISPLAYMODE desktopMode;
+ // monitor handle for this adapter
+ HMONITOR hMonitor;
+
+ // Index position in the adapter list
+ UINT iAdapter;
+
+ // Support devices : HAL or REF
+ D3dDeviceInfo* d3dDeviceList[2];
+
+ // Use for NativeConfigTemplate to
+ // determine the min. config support
+ UINT redDepth, greenDepth, blueDepth;
+
+ D3dDriverInfo();
+ ~D3dDriverInfo();
+
+ static VOID initialize(JNIEnv *env);
+ static VOID release();
+};
+
+typedef D3dDriverInfo* LPD3dDriverInfo;
+extern int numDriver; // size of above array list
+extern D3dDriverInfo **d3dDriverList;
+extern const DWORD numDeviceTypes;
+extern const D3DDEVTYPE deviceTypes[2];
+extern int requiredDeviceID; // force to use HAL/REF or exit
+extern int requiredDriverID; // force to use specific adapte
+extern D3DLIGHT8 ambientLight; // constant ambient light
+extern BOOL implicitMultisample;
+#endif
diff --git a/src/native/d3d/D3dImageComponent.cpp b/src/native/d3d/D3dImageComponent.cpp
new file mode 100644
index 0000000..e857f5f
--- /dev/null
+++ b/src/native/d3d/D3dImageComponent.cpp
@@ -0,0 +1,171 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+D3dImageComponent::D3dImageComponent()
+{
+ init();
+}
+
+
+D3dImageComponent::D3dImageComponent(D3dCtx *_ctx,
+ int _hashCode,
+ LPDIRECT3DTEXTURE8 _surf)
+{
+ ctx = _ctx;
+ hashCode = _hashCode;
+ surf = _surf;
+ next = NULL;
+}
+
+D3dImageComponent::~D3dImageComponent()
+{
+ if ((ctx != NULL) && (surf != NULL)) {
+ ctx->freeResource(surf);
+ }
+}
+
+VOID D3dImageComponent::init()
+{
+ next = NULL;
+ surf = NULL;
+ hashCode = 0;
+ ctx = NULL;
+}
+
+D3dImageComponent* D3dImageComponent::add(D3dImageComponent *list,
+ D3dCtx *ctx,
+ int hashCode,
+ LPDIRECT3DTEXTURE8 surf)
+{
+ D3dImageComponent *p = list->next;
+
+ D3dImageComponent *ic = new D3dImageComponent(ctx, hashCode, surf);
+
+ if (ic == NULL) {
+ return NULL;
+ }
+ list->next = ic;
+ ic->next = p;
+ return ic;
+}
+
+D3dImageComponent* D3dImageComponent::find(D3dImageComponent *list,
+ D3dCtx *ctx,
+ int hashCode)
+{
+ // skip the first dummy node
+ D3dImageComponent *p = list->next;
+ while (p != NULL) {
+ if ((p->ctx == ctx) &&
+ (p->hashCode == hashCode)) {
+ return p;
+ }
+ p = p->next;
+ }
+ return NULL;
+}
+
+
+VOID D3dImageComponent::remove(D3dImageComponent *list,
+ D3dCtx *ctx, int hashCode)
+{
+ // skip the first dummy node
+ D3dImageComponent *p = list->next;
+ D3dImageComponent *q = list;
+
+ while (p != NULL) {
+ if ((p->ctx == ctx) &&
+ (p->hashCode == hashCode)) {
+ q->next = p->next;
+ delete p;
+ break;
+ }
+ q = p;
+ p = p->next;
+
+ }
+}
+
+
+VOID D3dImageComponent::remove(D3dImageComponent *list,
+ int hashCode)
+{
+ // skip the first dummy node
+ D3dImageComponent *p = list->next;
+ D3dImageComponent *q = list;
+
+ while (p != NULL) {
+ if (p->hashCode == hashCode) {
+ q->next = p->next;
+ delete p;
+ // continue for image in another ctx
+ p = q->next;
+ } else {
+ q = p;
+ p = p->next;
+ }
+ }
+}
+
+VOID D3dImageComponent::remove(D3dImageComponent *list,
+ D3dCtx *ctx)
+{
+ // skip the first dummy node
+ D3dImageComponent *p = list->next;
+ D3dImageComponent *q = list;
+
+ while (p != NULL) {
+ if (p->ctx == ctx) {
+ q->next = p->next;
+ delete p;
+ p = q->next;
+ // continue for other images
+ } else {
+ q = p;
+ p = p->next;
+ }
+ }
+}
+
+VOID D3dImageComponent::remove(D3dImageComponent *list,
+ D3dImageComponent *ic)
+{
+ // skip the first dummy node
+ D3dImageComponent *p = list->next;
+ D3dImageComponent *q = list;
+
+ while (p != NULL) {
+ if (p == ic) {
+ q->next = p->next;
+ delete p;
+ break;
+ }
+ q = p;
+ p = p->next;
+ }
+}
+
+VOID D3dImageComponent::removeAll(D3dImageComponent *list)
+{
+ // skip the first dummy node
+ D3dImageComponent *q, *p = list->next;
+
+ list->next = NULL;
+
+ while (p != NULL) {
+ q = p->next;
+ delete p;
+ p = q;
+ }
+}
diff --git a/src/native/d3d/D3dImageComponent.hpp b/src/native/d3d/D3dImageComponent.hpp
new file mode 100644
index 0000000..659f907
--- /dev/null
+++ b/src/native/d3d/D3dImageComponent.hpp
@@ -0,0 +1,52 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#if !defined(D3DIMAGECOMPONENT_H)
+#define D3DIMAGECOMPONENT_H
+
+#include "StdAfx.h"
+
+class D3dImageComponent {
+public:
+
+ LPDIRECT3DTEXTURE8 surf;
+ D3dCtx *ctx;
+ int hashCode;
+ D3dImageComponent *next;
+
+ D3dImageComponent();
+
+ D3dImageComponent(D3dCtx *ctx, int hashCode,
+ LPDIRECT3DTEXTURE8 surf);
+
+ ~D3dImageComponent();
+
+ VOID init();
+
+ static D3dImageComponent* find(D3dImageComponent *list,
+ D3dCtx *ctx, int hashCode);
+
+ static D3dImageComponent* add(D3dImageComponent *list,
+ D3dCtx *ctx, int hashCode,
+ LPDIRECT3DTEXTURE8 surf);
+
+ static VOID remove(D3dImageComponent *list, D3dCtx *ctx, int hashCode);
+ static VOID remove(D3dImageComponent *list, D3dCtx *ctx);
+ static VOID remove(D3dImageComponent *list, int hashCode);
+ static VOID remove(D3dImageComponent *list, D3dImageComponent *ic);
+ static VOID removeAll(D3dImageComponent *list);
+};
+
+extern D3dImageComponent RasterList;
+extern D3dImageComponent BackgroundImageList;
+
+#endif
diff --git a/src/native/d3d/D3dUtil.cpp b/src/native/d3d/D3dUtil.cpp
new file mode 100644
index 0000000..643b809
--- /dev/null
+++ b/src/native/d3d/D3dUtil.cpp
@@ -0,0 +1,11666 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+HANDLE hSema = CreateSemaphore(NULL, 1, 1, "Java3d_Ctx");
+HANDLE imageSema = CreateSemaphore(NULL, 1, 1,
+ "Java3d_ImageComponent2DLock");
+HANDLE backgroundSema = CreateSemaphore(NULL, 1, 1,
+ "Java3d_ImageBackgroundLock");
+HANDLE geometrySema = CreateSemaphore(NULL, 1, 1,
+ "Java3d_GeometryArrayLock");
+HANDLE surfaceListSema = CreateSemaphore(NULL, 1, 1, "Java3d_SurfaceListLock");
+
+BOOL firstError = true;
+BOOL firstWarning = true;
+BOOL debug;
+
+
+vector<void *> freePointerList0;
+vector<void *> freePointerList1;
+BOOL useFreePointerList0 = true;
+
+char *D3dErrorMessage[] = {
+ "Can't found 3D Driver !",
+ "Current display driver did not support renderer inside window. Now switch to full screen mode...",
+ "DirectX 8.0 or above is required for this version of Java3D.",
+ "Your graphics card did not support >= 16 bit color mode which Java 3D required.",
+ "Please switch your display mode to at least 16 bit color depth.",
+ "No compatible device found, please switch to other display mode and try again !",
+ "Fail to create hardware D3D Device, switch to use reference rasterizer.",
+ "Fail to create reference rasterizer 3D Device.",
+ "Fail to set Viewport",
+ "Fail to get attach back buffer",
+ "256 color mode not support !",
+ "Out of memory !",
+ "Unknown 3D device specified in property j3d.d3ddevice, please use either \"reference\" or \"hardware\".",
+ "Graphics card did not support Hardware acceleration",
+ "Graphics card did not support Transform and light hardware acceleration",
+ "No Stencil buffer found in current display mode. DecalGroup may not work correctly.",
+ "Can't found a valid texture format, please try to use reference mode",
+ "Fail to create offscreen image for background",
+ "Fail to create Vertex Buffer",
+ "Fail to Reset() D3D device, try Recreate device again.",
+ "No compatible depth buffer found in your system, please switch to other display mode or try reference rasterizer.",
+ "Depth buffer with the required bit depth is not support, please try the default.",
+ "Fail to lock Vertex Buffer",
+ "Fail to create Vertex Buffer",
+ "Fail to create Index Buffer",
+ "Fail to lock Index Buffer"
+};
+
+D3DTRANSFORMSTATETYPE transformState[] = {
+ D3DTS_TEXTURE0,
+ D3DTS_TEXTURE1,
+ D3DTS_TEXTURE2,
+ D3DTS_TEXTURE3,
+ D3DTS_TEXTURE4,
+ D3DTS_TEXTURE5,
+ D3DTS_TEXTURE6,
+ D3DTS_TEXTURE7};
+
+#define D3DFORMATTABLESIZE 40
+
+D3DFORMAT d3dFormatTable[] = {
+ D3DFMT_UNKNOWN,
+ D3DFMT_R8G8B8,
+ D3DFMT_A8R8G8B8,
+ D3DFMT_X8R8G8B8,
+ D3DFMT_R5G6B5,
+ D3DFMT_X1R5G5B5,
+ D3DFMT_A1R5G5B5,
+ D3DFMT_A4R4G4B4,
+ D3DFMT_R3G3B2,
+ D3DFMT_A8,
+ D3DFMT_A8R3G3B2,
+ D3DFMT_X4R4G4B4,
+ D3DFMT_A8P8,
+ D3DFMT_P8,
+ D3DFMT_L8,
+ D3DFMT_A8L8,
+ D3DFMT_A4L4,
+ D3DFMT_V8U8,
+ D3DFMT_L6V5U5,
+ D3DFMT_X8L8V8U8,
+ D3DFMT_Q8W8V8U8,
+ D3DFMT_V16U16,
+ D3DFMT_W11V11U10,
+ D3DFMT_UYVY,
+ D3DFMT_YUY2,
+ D3DFMT_DXT1,
+ D3DFMT_DXT2,
+ D3DFMT_DXT3,
+ D3DFMT_DXT4,
+ D3DFMT_DXT5,
+ D3DFMT_D16_LOCKABLE,
+ D3DFMT_D32,
+ D3DFMT_D15S1,
+ D3DFMT_D24S8,
+ D3DFMT_D16,
+ D3DFMT_D24X8,
+ D3DFMT_D24X4S4,
+ D3DFMT_VERTEXDATA,
+ D3DFMT_INDEX16,
+ D3DFMT_INDEX32
+};
+
+char *d3dFormatTableChar[] = {
+ "D3DFMT_UNKNOWN",
+ "D3DFMT_R8G8B8",
+ "D3DFMT_A8R8G8B8",
+ "D3DFMT_X8R8G8B8",
+ "D3DFMT_R5G6B5",
+ "D3DFMT_X1R5G5B5",
+ "D3DFMT_A1R5G5B5",
+ "D3DFMT_A4R4G4B4",
+ "D3DFMT_R3G3B2",
+ "D3DFMT_A8",
+ "D3DFMT_A8R3G3B2",
+ "D3DFMT_X4R4G4B4",
+ "D3DFMT_A8P8",
+ "D3DFMT_P8",
+ "D3DFMT_L8",
+ "D3DFMT_A8L8",
+ "D3DFMT_A4L4",
+ "D3DFMT_V8U8",
+ "D3DFMT_L6V5U5",
+ "D3DFMT_X8L8V8U8",
+ "D3DFMT_Q8W8V8U8",
+ "D3DFMT_V16U16",
+ "D3DFMT_W11V11U10",
+ "D3DFMT_UYVY",
+ "D3DFMT_YUY2",
+ "D3DFMT_DXT1",
+ "D3DFMT_DXT2",
+ "D3DFMT_DXT3",
+ "D3DFMT_DXT4",
+ "D3DFMT_DXT5",
+ "D3DFMT_D16_LOCKABLE",
+ "D3DFMT_D32",
+ "D3DFMT_D15S1",
+ "D3DFMT_D24S8",
+ "D3DFMT_D16",
+ "D3DFMT_D24X8",
+ "D3DFMT_D24X4S4",
+ "D3DFMT_VERTEXDATA",
+ "D3DFMT_INDEX16",
+ "D3DFMT_INDEX32"
+};
+
+char* multipleSampleTypeTable[] = {
+ "D3DMULTISAMPLE_NONE",
+ "D3DMULTISAMPLE_UNKNOWN"
+ "D3DMULTISAMPLE_2_SAMPLES",
+ "D3DMULTISAMPLE_3_SAMPLES",
+ "D3DMULTISAMPLE_4_SAMPLES",
+ "D3DMULTISAMPLE_5_SAMPLES",
+ "D3DMULTISAMPLE_6_SAMPLES",
+ "D3DMULTISAMPLE_7_SAMPLES",
+ "D3DMULTISAMPLE_8_SAMPLES",
+ "D3DMULTISAMPLE_9_SAMPLES",
+ "D3DMULTISAMPLE_10_SAMPLES",
+ "D3DMULTISAMPLE_11_SAMPLES",
+ "D3DMULTISAMPLE_12_SAMPLES",
+ "D3DMULTISAMPLE_13_SAMPLES",
+ "D3DMULTISAMPLE_14_SAMPLES",
+ "D3DMULTISAMPLE_15_SAMPLES",
+ "D3DMULTISAMPLE_16_SAMPLES",
+};
+
+char* swapEffectTable[] = {
+ "D3DSWAPEFFECT_UNKNOWN",
+ "D3DSWAPEFFECT_DISCARD",
+ "D3DSWAPEFFECT_FLIP",
+ "D3DSWAPEFFECT_COPY",
+ "D3DSWAPEFFECT_COPY_VSYNC"
+};
+
+
+// mapping from java enum to d3d enum
+
+D3DCUBEMAP_FACES textureCubeMapFace[] = {
+ D3DCUBEMAP_FACE_POSITIVE_X,
+ D3DCUBEMAP_FACE_NEGATIVE_X,
+ D3DCUBEMAP_FACE_POSITIVE_Y,
+ D3DCUBEMAP_FACE_NEGATIVE_Y,
+ D3DCUBEMAP_FACE_NEGATIVE_Z,
+ D3DCUBEMAP_FACE_POSITIVE_Z,
+};
+
+typedef struct _PIXELFORMAT {
+ DWORD dwRGBBitCount;
+ DWORD dwRBitMask;
+ DWORD dwGBitMask;
+ DWORD dwBBitMask;
+ DWORD dwRGBAlphaBitMask;
+ BOOL noAlpha;
+} PIXELFORMAT;
+
+
+typedef struct _DEPTHPIXELFORMAT {
+ DWORD dwZBufferBitDepth;
+ DWORD dwZBitMask;
+} DEPTHPIXELFORMAT;
+
+
+char *getSwapEffectName(D3DSWAPEFFECT swapEffect)
+{
+ int t = (int) swapEffect;
+ if ((t < 0) || (t > 4)) {
+ return swapEffectTable[0];
+ }
+ return swapEffectTable[t];
+}
+
+char *getMultiSampleName(D3DMULTISAMPLE_TYPE mtype)
+{
+ int t = (int) mtype;
+ if ((t < 0) || (t > 16)) {
+ // UNKNOWN
+ return multipleSampleTypeTable[1];
+ }
+ return multipleSampleTypeTable[t];
+}
+
+char* getPixelFormatName(D3DFORMAT f)
+{
+ for (int i=0; i < D3DFORMATTABLESIZE; i++) {
+ if (f == d3dFormatTable[i]) {
+ return d3dFormatTableChar[i];
+ }
+ }
+ // should not happen
+ return d3dFormatTableChar[0];
+}
+
+// If there is a new D3DFORMAT, just add it here and
+// our copy procedures can handle any format specific
+// as bit mask.
+VOID computePixelFormat(PIXELFORMAT *ddpf, D3DFORMAT format)
+{
+ switch (format) {
+ case D3DFMT_R8G8B8:
+ ddpf->dwRGBBitCount = 24;
+ ddpf->dwRGBAlphaBitMask = 0;
+ ddpf->dwRBitMask = 0x00ff0000;
+ ddpf->dwGBitMask = 0x0000ff00;
+ ddpf->dwBBitMask = 0x000000ff;
+ ddpf->noAlpha = true;
+ break;
+ case D3DFMT_A8R8G8B8:
+ ddpf->dwRGBBitCount = 32;
+ ddpf->dwRGBAlphaBitMask = 0xff000000;
+ ddpf->dwRBitMask = 0x00ff0000;
+ ddpf->dwGBitMask = 0x0000ff00;
+ ddpf->dwBBitMask = 0x000000ff;
+ ddpf->noAlpha = false;
+ break;
+ case D3DFMT_X8R8G8B8:
+ ddpf->dwRGBBitCount = 32;
+ ddpf->dwRGBAlphaBitMask = 0;
+ ddpf->dwRBitMask = 0x00ff0000;
+ ddpf->dwGBitMask = 0x0000ff00;
+ ddpf->dwBBitMask = 0x000000ff;
+ ddpf->noAlpha = true;
+ break;
+ case D3DFMT_R5G6B5:
+ ddpf->dwRGBBitCount = 16;
+ ddpf->dwRGBAlphaBitMask = 0;
+ ddpf->dwRBitMask = 0xf800;
+ ddpf->dwGBitMask = 0x07e0;
+ ddpf->dwBBitMask = 0x001f;
+ ddpf->noAlpha = true;
+ break;
+ case D3DFMT_X1R5G5B5:
+ ddpf->dwRGBBitCount = 16;
+ ddpf->dwRGBAlphaBitMask = 0;
+ ddpf->dwRBitMask = 0x7c00;
+ ddpf->dwGBitMask = 0x03e0;
+ ddpf->dwBBitMask = 0x001f;
+ ddpf->noAlpha = true;
+ break;
+ case D3DFMT_A1R5G5B5:
+ ddpf->dwRGBBitCount = 16;
+ ddpf->dwRGBAlphaBitMask = 0x8000;
+ ddpf->dwRBitMask = 0x7c00;
+ ddpf->dwGBitMask = 0x03e0;
+ ddpf->dwBBitMask = 0x001f;
+ ddpf->noAlpha = false;
+ break;
+ case D3DFMT_A4R4G4B4:
+ ddpf->dwRGBBitCount = 16;
+ ddpf->dwRGBAlphaBitMask = 0xf000;
+ ddpf->dwRBitMask = 0x0f00;
+ ddpf->dwGBitMask = 0x00f0;
+ ddpf->dwBBitMask = 0x000f;
+ ddpf->noAlpha = false;
+ break;
+ case D3DFMT_X4R4G4B4:
+ ddpf->dwRGBBitCount = 16;
+ ddpf->dwRGBAlphaBitMask = 0;
+ ddpf->dwRBitMask = 0x0f00;
+ ddpf->dwGBitMask = 0x00f0;
+ ddpf->dwBBitMask = 0x000f;
+ ddpf->noAlpha = true;
+ break;
+ case D3DFMT_R3G3B2:
+ ddpf->dwRGBBitCount = 8;
+ ddpf->dwRGBAlphaBitMask = 0;
+ ddpf->dwRBitMask = 0xe0;
+ ddpf->dwGBitMask = 0x1c;
+ ddpf->dwBBitMask = 0x03;
+ ddpf->noAlpha = true;
+ break;
+ case D3DFMT_A8R3G3B2:
+ ddpf->dwRGBBitCount = 16;
+ ddpf->dwRGBAlphaBitMask = 0xff00;
+ ddpf->dwRBitMask = 0x00e0;
+ ddpf->dwGBitMask = 0x001c;
+ ddpf->dwBBitMask = 0x0003;
+ ddpf->noAlpha = false;
+ break;
+ case D3DFMT_A8:
+ ddpf->dwRGBBitCount = 8;
+ ddpf->dwRGBAlphaBitMask = 0xff;
+ ddpf->dwRBitMask = 0;
+ ddpf->dwGBitMask = 0;
+ ddpf->dwBBitMask = 0;
+ ddpf->noAlpha = false;
+ break;
+ case D3DFMT_L8:
+ ddpf->dwRGBBitCount = 8;
+ ddpf->dwRGBAlphaBitMask = 0;
+ ddpf->dwRBitMask = 0xff;
+ ddpf->dwGBitMask = 0;
+ ddpf->dwBBitMask = 0;
+ ddpf->noAlpha = true;
+ break;
+ case D3DFMT_A8L8:
+ ddpf->dwRGBBitCount = 16;
+ ddpf->dwRGBAlphaBitMask = 0xff00;
+ ddpf->dwRBitMask = 0x00ff;
+ ddpf->dwGBitMask = 0;
+ ddpf->dwBBitMask = 0;
+ ddpf->noAlpha = false;
+ break;
+ case D3DFMT_A4L4:
+ ddpf->dwRGBBitCount = 8;
+ ddpf->dwRGBAlphaBitMask = 0xf0;
+ ddpf->dwRBitMask = 0x0f;
+ ddpf->dwGBitMask = 0;
+ ddpf->dwBBitMask = 0;
+ ddpf->noAlpha = false;
+ break;
+ default:
+ printf("Unsupport format %d\n ", format);
+ ddpf->dwRGBBitCount = 8;
+ ddpf->dwRGBAlphaBitMask = 0;
+ ddpf->dwRBitMask = 0;
+ ddpf->dwGBitMask = 0;
+ ddpf->dwBBitMask = 0;
+ ddpf->noAlpha = true;
+ break;
+ }
+
+}
+
+
+/*
+ * Right now only format D3DFMT_D16_LOCKABLE
+ * is lockable by application. So can't use
+ * with stencil buffer (in DecalGroup) together
+ */
+VOID computeDepthPixelFormat(DEPTHPIXELFORMAT *ddpf,
+ D3DFORMAT format)
+{
+ switch (format) {
+ case D3DFMT_D16_LOCKABLE:
+ case D3DFMT_D16:
+ ddpf->dwZBufferBitDepth = 16;
+ ddpf->dwZBitMask = 0xffff;
+ break;
+ case D3DFMT_D15S1:
+ ddpf->dwZBufferBitDepth = 16;
+ ddpf->dwZBitMask = 0xfffe;
+ break;
+ case D3DFMT_D32:
+ ddpf->dwZBufferBitDepth = 32;
+ ddpf->dwZBitMask = 0xffffffff;
+ break;
+ case D3DFMT_D24S8:
+ case D3DFMT_D24X8:
+ case D3DFMT_D24X4S4:
+ ddpf->dwZBufferBitDepth = 32;
+ ddpf->dwZBitMask = 0xffffff00;
+ break;
+ default:
+ printf("Unknown depth buffer format %d\n", format);
+ }
+}
+
+
+/*
+ * Set the correct D3DTSS_TEXTURETRANSFORMFLAGS
+ */
+void setTexTransformStageFlag(D3dCtx* d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ int tus, int ts, int genMode)
+{
+ /*
+ * In case of automatic texture generation, disable
+ * texture unit transform stage will cause crash in
+ * reference device mode.
+ */
+ if ((!d3dCtx->texTransformSet[tus]) &&
+ (d3dCtx->texGenMode == TEX_GEN_NONE)) {
+ device->SetTextureStageState(tus,
+ D3DTSS_TEXTURETRANSFORMFLAGS,
+ D3DTTFF_DISABLE);
+ } else {
+ D3DXMATRIX *m;
+
+ switch (ts) {
+ case 2:
+ // Adjust for 2D texture transform in D3D
+ // 1 0 0 0
+ // 0 1 0 0
+ // du dv 0 0
+ // 0 0 0 0
+ //
+
+ /*
+ *
+ * The texture transform matrix is funky. With COUNT=2
+ * and texture coordinates coming from the vertices, you
+ * can't use the stock transformation matrix functions to
+ * generate the matrix without adjusting it before setting
+ * the transform. Basically in the case of COUNT=2 with
+ * texcoords coming from the vertices, the pipeline uses
+ * the upper 3x3 submatrix of the 4x4 matrix as the
+ * transformation. So if you were expecting the (u,v)
+ * translation elements to be on the 4th row, these won't
+ * be applied properly in this case.
+ *
+ * What's funky is that if you were using COUNT=2 and
+ * texture coordinates coming in automatically, then it
+ * wants the translation in the 4th row. I can't decide
+ * yet if this is a poor specification that results in
+ * this matrix weirdness, or if its a bug in the runtime.
+ */
+ if ((genMode != TEX_GEN_AUTO) &&
+ !d3dCtx->texTranslateSet[tus]) {
+ m = &d3dCtx->texTransform[tus];
+ (*m)._31 = (*m)._41;
+ (*m)._32 = (*m)._42;
+ device->SetTransform((D3DTRANSFORMSTATETYPE)
+ (D3DTS_TEXTURE0 + tus), m);
+ d3dCtx->texTranslateSet[tus] = true;
+ }
+
+ device->SetTextureStageState(tus,
+ D3DTSS_TEXTURETRANSFORMFLAGS,
+ D3DTTFF_COUNT2);
+ break;
+ case 3:
+ device->SetTextureStageState(tus,
+ D3DTSS_TEXTURETRANSFORMFLAGS,
+ D3DTTFF_COUNT3);
+ break;
+ case 4:
+ if (d3dCtx->texGenMode[tus] == TEX_OBJ_LINEAR) {
+ // The texture transform matrix is funky that only the
+ // upper 3x3 matrix is used if we are not using
+ // automatic texture generation. In case of Object
+ // Linear we are need to workaround by doing our
+ // own texture transform when generate texture
+ // coordinate.
+ device->SetTextureStageState(tus,
+ D3DTSS_TEXTURETRANSFORMFLAGS,
+ D3DTTFF_DISABLE);
+ } else {
+ device->SetTextureStageState(tus,
+ D3DTSS_TEXTURETRANSFORMFLAGS,
+ D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
+ }
+ break;
+ default:
+ printf("ERROR texCoordFormat, stage %d, format %d\n",
+ tus, ts);
+ }
+ }
+
+}
+
+/*
+ * Set the corresponding D3D texture coordinate
+ * mapping mode.
+ */
+inline int setTextureStage(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ int mapTexStage,
+ jint texStage)
+{
+ DWORD mode = 0;
+ int genMode = d3dCtx->texGenMode[mapTexStage];
+
+ // printf("Set TexStage mapTexStage = %d, texStage = %d, genMode = %d\n",
+ // mapTexStage, texStage, genMode);
+
+ switch (genMode) {
+ case TEX_GEN_NONE:
+ case TEX_OBJ_LINEAR:
+ case TEX_GEN_INVALID:
+ // optimize for general case
+ device->SetTextureStageState(mapTexStage,
+ D3DTSS_TEXCOORDINDEX,
+ texStage);
+ return genMode;
+ case TEX_EYE_LINEAR:
+ mode = D3DTSS_TCI_CAMERASPACEPOSITION;
+ break;
+ case TEX_SPHERE_MAP:
+ mode = D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR;
+ break;
+ case TEX_NORMAL_MAP:
+ mode = D3DTSS_TCI_CAMERASPACENORMAL;
+ break;
+ case TEX_REFLECT_MAP:
+ mode = D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR;
+ break;
+ default:
+ // should not happen
+ printf("Unknown TexCoordGenMode %d\n", genMode);
+ break;
+ }
+ // Need to OR texStage for Wrapping mode even though
+ // there is no texture coordinate defined in that texStage in VB.
+ // This also clear the texStage previously set.
+ device->SetTextureStageState(mapTexStage,
+ D3DTSS_TEXCOORDINDEX,
+ mode | texStage);
+
+ return TEX_GEN_AUTO;
+}
+
+
+void getTexWidthHeight(D3dDeviceInfo *deviceInfo,
+ jint* width, jint *height)
+{
+ int texWidth, texHeight;
+
+ texWidth = *width;
+ texHeight = *height;
+
+
+ // Found a texture bigger than width/height
+ if (deviceInfo->texturePow2Only) {
+ for (texWidth=1; *width > texWidth; texWidth <<= 1);
+ for (texHeight=1; *height > texHeight; texHeight <<= 1);
+ }
+
+
+ if (deviceInfo->textureSquareOnly) {
+ if (texWidth >= texHeight) {
+ texHeight = texWidth;
+ } else {
+ texWidth = texHeight;
+ }
+ }
+
+ // Check for maximum texture size support by hardware
+ if (texWidth > deviceInfo->maxTextureWidth) {
+ if (debug) {
+ printf("[Java 3D] Warning: Input texture width %d > maximum texture width %d hardware can support.\n", texWidth, deviceInfo->maxTextureWidth);
+ if (*width != texWidth) {
+ printf("Note that width is adjust from %d to %d to reflect texture limitation e.g. POW2, SQAUREONLY in hardware.\n", *width, texWidth);
+ }
+ }
+ texWidth = deviceInfo->maxTextureWidth;
+ }
+
+ if (texHeight > deviceInfo->maxTextureHeight) {
+ if (debug) {
+ printf("[Java 3D] Warning: Input texture height %d > maximum texture height %d hardware can support.\n", texHeight, deviceInfo->maxTextureHeight);
+ if (*height != texHeight) {
+ printf("Note that height is adjust from %d to %d to reflect texture limitation e.g. POW2, SQAUREONLY in hardware.\n", *height, texHeight);
+ }
+ }
+ texHeight = deviceInfo->maxTextureHeight;
+ }
+
+ *width = texWidth;
+ *height = texHeight;
+}
+
+D3DFORMAT getTexFormat(jint internalFormat) {
+
+ switch (internalFormat) {
+ case J3D_RGBA:
+ case INTENSITY:
+ return D3DFMT_A8R8G8B8;
+ case J3D_RGB:
+ return D3DFMT_R8G8B8;
+ case LUMINANCE_ALPHA:
+ return D3DFMT_A8L8;
+ case ALPHA:
+ return D3DFMT_A8;
+ case LUMINANCE:
+ return D3DFMT_L8;
+ default:
+ printf("CreateTextureSurface: Unknown internal Format %d \n", internalFormat);
+ return D3DFMT_UNKNOWN;
+ }
+
+}
+
+D3dCtx* findCtx(HWND hwnd)
+{
+ D3dCtx *ctx = NULL;
+
+ for (D3dCtx **p = d3dCtxList.begin(); p != d3dCtxList.end(); p++) {
+ if ((*p)->hwnd == hwnd) {
+ ctx = *p;
+ break;
+ }
+ }
+ return ctx;
+}
+
+
+inline VOID lock()
+{
+ if (hSema != NULL) {
+ WaitForSingleObject(hSema, INFINITE);
+ }
+}
+
+inline VOID unlock()
+{
+ if (hSema != NULL) {
+ ReleaseSemaphore(hSema, 1, NULL);
+ }
+}
+
+
+inline VOID lockSurfaceList()
+{
+ if (surfaceListSema != NULL) {
+ WaitForSingleObject(surfaceListSema, INFINITE);
+ }
+}
+
+inline VOID unlockSurfaceList()
+{
+ if (surfaceListSema != NULL) {
+ ReleaseSemaphore(surfaceListSema, 1, NULL);
+ }
+}
+
+inline VOID lockBackground()
+{
+ if (backgroundSema != NULL) {
+ WaitForSingleObject(backgroundSema, INFINITE);
+ }
+}
+
+inline VOID unlockBackground()
+{
+ if (backgroundSema != NULL) {
+ ReleaseSemaphore(backgroundSema, 1, NULL);
+ }
+}
+
+inline VOID lockImage()
+{
+ if (imageSema != NULL) {
+ WaitForSingleObject(imageSema, INFINITE);
+ }
+}
+
+inline VOID unlockImage()
+{
+ if (imageSema != NULL) {
+ ReleaseSemaphore(imageSema, 1, NULL);
+ }
+}
+
+
+
+inline VOID lockGeometry()
+{
+ if (geometrySema != NULL) {
+ WaitForSingleObject(geometrySema, INFINITE);
+ }
+}
+
+inline VOID unlockGeometry()
+{
+ if (geometrySema != NULL) {
+ ReleaseSemaphore(geometrySema, 1, NULL);
+ }
+}
+
+VOID freePointer(void * ptr)
+{
+ if (ptr != NULL) {
+ lockSurfaceList();
+ if (useFreePointerList0) {
+ freePointerList0.push_back(ptr);
+ } else {
+ freePointerList1.push_back(ptr);
+ }
+ unlockSurfaceList();
+ }
+}
+
+
+char *getErrorMessage(int idx)
+{
+ return D3dErrorMessage[idx];
+}
+
+
+
+HWND getTopWindow(HWND hwnd)
+{
+ HWND desktop = GetDesktopWindow();
+ HWND parent = GetParent(hwnd);
+
+ while ((parent != NULL) && (parent != desktop)) {
+ hwnd = parent;
+ parent = GetParent(hwnd);
+ }
+ return hwnd;
+}
+
+
+DWORD firstBit(DWORD mask)
+{
+ int i;
+
+ for (i=0; i < sizeof(DWORD)*8-1; i++) {
+ if ((mask & 0x01) > 0) {
+ return i;
+ }
+ mask >>= 1;
+ }
+
+ return i;
+}
+
+// create a DirectDraw Texture surface of specific width and height
+LPDIRECT3DTEXTURE8 createTextureSurface(D3dCtx *d3dCtx,
+ jint numLevels,
+ jint internalFormat,
+ jint width, jint height)
+{
+ LPDIRECT3DTEXTURE8 pTexture;
+ D3DFORMAT format;
+ HRESULT hr;
+
+ LPDIRECT3DDEVICE8 pDevice = d3dCtx->pDevice;
+ D3dDeviceInfo *deviceInfo = d3dCtx->deviceInfo;
+
+ if (!deviceInfo->supportMipmap) {
+ numLevels = 1;
+ }
+
+ getTexWidthHeight(deviceInfo, &width, &height);
+ format = getTexFormat(internalFormat);
+
+ // If format not support, the utility function will adjust the
+ // calling parameters automatically
+ hr = D3DXCreateTexture(d3dCtx->pDevice, width, height,
+ numLevels, 0, format, D3DPOOL_MANAGED,
+ &pTexture);
+
+ if (FAILED(hr)) {
+ printf("Fail to create texture surface %dx%d, format %d, level %d : %s\n",
+ width, height, format, numLevels, DXGetErrorString8(hr));
+ return NULL;
+ }
+
+ return pTexture;
+}
+
+
+
+// create a DirectDraw Texture surface of specific width and height
+LPDIRECT3DVOLUMETEXTURE8 createVolumeTexture(D3dCtx *d3dCtx,
+ jint numLevels,
+ jint internalFormat,
+ jint width,
+ jint height,
+ jint depth)
+{
+ LPDIRECT3DVOLUMETEXTURE8 pTexture;
+ int texWidth, texHeight, texDepth;
+ D3DFORMAT format;
+ HRESULT hr;
+
+ LPDIRECT3DDEVICE8 pDevice = d3dCtx->pDevice;
+ D3dDeviceInfo *deviceInfo = d3dCtx->deviceInfo;
+
+ texWidth = width;
+ texHeight = height;
+ texDepth = depth;
+
+
+ if (!deviceInfo->supportMipmap) {
+ numLevels = 1;
+ }
+
+
+ // Found a texture bigger than width/height
+ if (deviceInfo->texturePow2Only) {
+ for (texWidth=1; width > texWidth; texWidth <<= 1);
+ for (texHeight=1; height > texHeight; texHeight <<= 1);
+ for (texDepth=1; depth > texDepth; texDepth <<= 1);
+ }
+
+
+ if (deviceInfo->textureSquareOnly) {
+ if (texWidth >= texHeight) {
+ texHeight = texWidth;
+ } else {
+ texWidth = texHeight;
+ }
+ if (texDepth <= texWidth) {
+ texDepth = texWidth;
+ } else {
+ texWidth = texHeight = texDepth;
+ }
+ }
+
+ // Check for maximum texture size support by hardware
+ if (texWidth > deviceInfo->maxTextureWidth) {
+ if (debug) {
+ printf("[Java 3D] Warning: Input texture width %d > maximum texture width %d hardware can support.\n", texWidth, deviceInfo->maxTextureWidth);
+ if (width != texWidth) {
+ printf("Note that width is adjust from %d to %d to reflect texture limitation e.g. POW2, SQAUREONLY in hardware.\n", width, texWidth);
+ }
+ }
+ texWidth = deviceInfo->maxTextureWidth;
+ }
+
+ if (texHeight > deviceInfo->maxTextureHeight) {
+ if (debug) {
+ printf("[Java 3D] Warning: Input texture height %d > maximum texture height %d hardware can support.\n", texHeight, deviceInfo->maxTextureHeight);
+ if (height != texHeight) {
+ printf("Note that height is adjust from %d to %d to reflect texture limitation e.g. POW2, SQAUREONLY in hardware.\n", height, texHeight);
+ }
+ }
+ texHeight = deviceInfo->maxTextureHeight;
+ }
+
+ if (texDepth > deviceInfo->maxTextureDepth) {
+ if (debug) {
+ printf("[Java 3D] Warning: Input texture depth %d > maximum texture depth %d hardware can support.\n", texDepth, deviceInfo->maxTextureDepth);
+ if (depth != texDepth) {
+ printf("Note that depth is adjust from %d to %d to reflect texture limitation e.g. POW2, SQAUREONLY in hardware.\n", depth, texDepth);
+ }
+ }
+ texDepth = deviceInfo->maxTextureDepth;
+ }
+
+
+ format = getTexFormat(internalFormat);
+
+ // If format not support, the utility function will adjust the
+ // calling parameters automatically
+ hr = D3DXCreateVolumeTexture(d3dCtx->pDevice, texWidth, texHeight,
+ texDepth, numLevels, 0, format, D3DPOOL_MANAGED,
+ &pTexture);
+
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Fail to create volume texture %dx%dx%d, format %d, level %d : %s\n",
+ texWidth, texHeight, texDepth, format, numLevels,
+ DXGetErrorString8(hr));
+ }
+ return NULL;
+ }
+
+ return pTexture;
+}
+
+
+// copy data from DirectDraw surface to memory
+// and reverse the Y axis
+void copyDataFromSurface(jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint subWidth, jint subHeight,
+ jbyte *data,
+ LPDIRECT3DSURFACE8 surf)
+{
+ D3DSURFACE_DESC ddsd;
+ D3DLOCKED_RECT lockedRect;
+ PIXELFORMAT ddpf;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+
+ surf->GetDesc(&ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computePixelFormat(&ddpf, ddsd.Format);
+
+ if ((xoffset >= width) || (yoffset >= height)) {
+ return;
+ }
+
+ DWORD xlimit = min(xoffset + subWidth, width);
+ DWORD ylimit = min(yoffset + subHeight, height);
+
+ hr = surf->LockRect(&lockedRect, NULL, D3DLOCK_NOSYSLOCK|
+ D3DLOCK_READONLY);
+
+ if (FAILED(hr)) {
+ printf("Fail to lock surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+ unsigned char *src;
+ unsigned char *dst;
+ byte b1, b2, b3, b4;
+ DWORD mask, t;
+ DWORD dstPitch;
+
+ unsigned char *destRow = (unsigned char *) data;
+ unsigned char *srcRow = ((unsigned char *) lockedRect.pBits) +
+ xoffset*((int) ceil((float) ddpf.dwRGBBitCount/8.0)) +
+ (yoffset*lockedRect.Pitch);
+
+
+ if ((internalFormat == FORMAT_BYTE_RGBA) ||
+ (internalFormat == FORMAT_BYTE_RGB)) {
+ dstPitch = subWidth << 2;
+ destRow += (subHeight-1)*dstPitch;
+
+ if ((ddpf.dwRGBBitCount == 32) &&
+ (ddpf.dwRBitMask == 0xff0000) &&
+ (ddpf.dwGBitMask == 0xff00) &&
+ (ddpf.dwBBitMask == 0xff)) {
+ // Optimize for the most common case
+ if (ddpf.noAlpha) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ *dst++ = b3;
+ *dst++ = b2;
+ *dst++ = b1;
+ *src++;
+ *dst++ = (byte) 0xff;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ *dst++ = b3;
+ *dst++ = b2;
+ *dst++ = b1;
+ *dst++ = *src++;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ }
+ } else { // handle less common format
+ int rshift = firstBit(ddpf.dwRBitMask) +
+ countBits(ddpf.dwRBitMask) - 8;
+ int gshift = firstBit(ddpf.dwGBitMask) +
+ countBits(ddpf.dwGBitMask) - 8;
+ int bshift = firstBit(ddpf.dwBBitMask) +
+ countBits(ddpf.dwBBitMask) - 8;
+ int ashift = firstBit(ddpf.dwRGBAlphaBitMask) +
+ countBits(ddpf.dwRGBAlphaBitMask) - 8;
+
+ if ((ddpf.dwRGBBitCount <= 32) &&
+ (ddpf.dwRGBBitCount > 24)) {
+
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ b4 = *src++;
+ mask = ((b4 << 24) | (b3 << 16)| (b2 << 8) | b1);
+ if (rshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRBitMask) >>
+ rshift);
+ } else {
+ t = (mask & ddpf.dwRBitMask) << -rshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (bshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwBBitMask) >>
+ bshift);
+ } else {
+ t = (mask & ddpf.dwBBitMask) << -bshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (ddpf.noAlpha) {
+ *dst++ = (byte) 0xff;
+ } else {
+ if (ashift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else if ((ddpf.dwRGBBitCount <= 24) &&
+ (ddpf.dwRGBBitCount > 16)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ mask = ((b3 << 16) | (b2 << 8) | b1);
+ if (rshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRBitMask) >>
+ rshift);
+ } else {
+ t = (mask & ddpf.dwRBitMask) << -rshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) <<-gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (bshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwBBitMask) >>
+ bshift);
+ } else {
+ t = (mask & ddpf.dwBBitMask) << -bshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (ddpf.noAlpha) {
+ *dst++ = (byte) 0xff;
+ } else {
+ if (ashift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else if ((ddpf.dwRGBBitCount <= 16) &&
+ (ddpf.dwRGBBitCount > 8)) {
+
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ mask = ((b2 << 8) | b1);
+ if (rshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRBitMask) >>
+ rshift);
+ } else {
+ t = (mask & ddpf.dwRBitMask) << -rshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (bshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwBBitMask) >>
+ bshift);
+ } else {
+ t = (mask & ddpf.dwBBitMask) << -bshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+
+ if (ddpf.noAlpha) {
+ *dst++ = (byte) 0xff;
+ } else {
+ if (ashift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else if (ddpf.dwRGBBitCount <= 8) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ mask = *src++;
+ if (rshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRBitMask) >>
+ rshift);
+ } else {
+ t = (mask & ddpf.dwRBitMask) << -rshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (bshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwBBitMask) >>
+ bshift);
+ } else {
+ t = (mask & ddpf.dwBBitMask) << -bshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (ddpf.noAlpha) {
+ *dst++ = (byte) 0xff;
+ } else {
+ if (ashift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ }
+ }
+ } else if (internalFormat == FORMAT_BYTE_LA) {
+ int gshift = firstBit(ddpf.dwGBitMask) +
+ countBits(ddpf.dwGBitMask) - 8;
+ int ashift = firstBit(ddpf.dwRGBAlphaBitMask) +
+ countBits(ddpf.dwRGBAlphaBitMask) - 8;
+ dstPitch = subWidth << 1;
+ destRow += (subHeight-1)*dstPitch;
+
+ if ((ddpf.dwRGBBitCount == 32) &&
+ (ddpf.dwRBitMask == 0xff0000) &&
+ (ddpf.dwGBitMask == 0xff00) &&
+ (ddpf.dwBBitMask == 0xff)) {
+ // Optimize for the most common case
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ *dst++ = b2;
+ if (ddpf.noAlpha) {
+ *dst++ = (byte) 0xff;
+ *src++;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else { // handle less common format
+ int gshift = firstBit(ddpf.dwGBitMask) +
+ countBits(ddpf.dwGBitMask) - 8;
+ if ((ddpf.dwRGBBitCount <= 32) &&
+ (ddpf.dwRGBBitCount > 24)) {
+
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ b4 = *src++;
+ mask = ((b4 << 24) | (b3 << 16)| (b2 << 8) | b1);
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (ddpf.noAlpha) {
+ *dst++ = (byte) 0xff;
+ } else {
+ if (ashift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else if ((ddpf.dwRGBBitCount <= 24) &&
+ (ddpf.dwRGBBitCount > 16)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ mask = ((b3 << 16) | (b2 << 8) | b1);
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (ddpf.noAlpha) {
+ *dst++ = (byte) 0xff;
+ } else {
+ if (ashift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else if ((ddpf.dwRGBBitCount <= 16) &&
+ (ddpf.dwRGBBitCount > 8)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ mask = ((b2 << 8) | b1);
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (ddpf.noAlpha) {
+ *dst++ = (byte) 0xff;
+ } else {
+ if (ashift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else if (ddpf.dwRGBBitCount <= 8) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ mask = *src++;
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ if (ddpf.noAlpha) {
+ *dst++ = (byte) 0xff;
+ } else {
+ if (ashift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ }
+ }
+
+ } else if (internalFormat == FORMAT_BYTE_GRAY) {
+ int gshift = firstBit(ddpf.dwGBitMask) +
+ countBits(ddpf.dwGBitMask) - 8;
+ dstPitch = subWidth;
+ destRow += (subHeight-1)*dstPitch;
+
+ if ((ddpf.dwRGBBitCount == 32) &&
+ (ddpf.dwRBitMask == 0xff0000) &&
+ (ddpf.dwGBitMask == 0xff00) &&
+ (ddpf.dwBBitMask == 0xff)) {
+ // Optimize for the most common case
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ *dst++ = b2;
+ *src++;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else { // handle less common format
+ int gshift = firstBit(ddpf.dwGBitMask) +
+ countBits(ddpf.dwGBitMask) - 8;
+ if ((ddpf.dwRGBBitCount <= 32) &&
+ (ddpf.dwRGBBitCount > 24)) {
+
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ b4 = *src++;
+ mask = ((b4 << 24) | (b3 << 16)| (b2 << 8) | b1);
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else if ((ddpf.dwRGBBitCount <= 24) &&
+ (ddpf.dwRGBBitCount > 16)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ mask = ((b3 << 16) | (b2 << 8) | b1);
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else if ((ddpf.dwRGBBitCount <= 16) &&
+ (ddpf.dwRGBBitCount > 8)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ mask = ((b2 << 8) | b1);
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ } else if (ddpf.dwRGBBitCount <= 8) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ mask = *src++;
+ if (gshift >= 0) {
+ *dst++ = (byte) ((mask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ t = (mask & ddpf.dwGBitMask) << -gshift;
+ *dst++ = (t <= 0xff ? (byte) t : 0xff);
+ }
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= dstPitch;
+ }
+ }
+ }
+
+ } else {
+ // FORMAT_USHORT_GRAY
+ printf("[Java 3D] copyDataFromSurface: Format not support %d\n", internalFormat);
+ }
+
+
+ hr = surf->UnlockRect();
+ if (FAILED(hr)) {
+ printf("Fail to unlock surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+}
+
+
+void copyDataToSurfaceABGR(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD r, g, b, a, l;
+ const DWORD srcPitch = subWidth*4;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Optimize for most common case
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ a = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = a;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ a = (*src++) >> 4; // discard the lower 4 bit
+ b = (*src++) >> 4;
+ g = (*src++) >> 4;
+ r = (*src++) >> 4;
+ *dst++ = (g << 4) | b;
+ *dst++ = (a << 4) | r;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src += 3;
+ mask = a << ashift;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src += 3;
+ mask = a << ashift;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src += 3;
+ mask = (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src += 3;
+ *dst++ = (byte) (a << ashift);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+
+void copyDataToSurfaceBGR(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD r, g, b, l;
+ const DWORD srcPitch = subWidth*3;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Optimize for most common case
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = 0xff;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b = (*src++) >> 4;
+ g = (*src++) >> 4;
+ r = (*src++) >> 4;
+ *dst++ = (g << 4) | b;
+ *dst++ = 0xf0 | r;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) |ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ byte m1 = (byte) (ddpf->dwRGBAlphaBitMask & 0xff);
+ byte m2 = (byte) ((ddpf->dwRGBAlphaBitMask >> 8) & 0xff);
+ byte m3 = (byte) ((ddpf->dwRGBAlphaBitMask >> 16) & 0xff);
+ byte m4 = (byte) ((ddpf->dwRGBAlphaBitMask >> 24) & 0xff);
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst++ = m1;
+ *dst++ = m2;
+ *dst++ = m3;
+ *dst++ = m4;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst++ = m1;
+ *dst++ = m2;
+ *dst++ = m3;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst++ = m1;
+ *dst++ = m2;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst++ = m1;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+/*
+ * Same as copyDataToSurfaceRGBA()
+ * but the pixel is written in the destination buffer
+ * from right to left. This is used for CubeMapping.
+ */
+void copyDataToSurfaceRGBARev(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD r, g, b, a, l;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+ const DWORD srcPitch = subWidth*4;
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Most common case
+ // Note that format of destination is ARGB, which
+ // in PC format are BGRA, so we can't directly
+ // copy a row using CopyMemory()
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ r = *src++;
+ g = *src++;
+ b = *src++;
+ *dst-- = *src++;
+ *dst-- = r;
+ *dst-- = g;
+ *dst-- = b;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ r = (*src++) >> 4; // discard the lower 4 bit
+ g = (*src++) >> 4;
+ b = (*src++) >> 4;
+ a = (*src++) >> 4;
+ *dst-- = (a << 4) | r;
+ *dst-- = (g << 4) | b;
+
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit-1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) -1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += ((xlimit*3) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += ((xlimit*3) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit-1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ *dst-- = (byte) (a << ashift);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += ((xlimit*3)-1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit-1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+
+
+void copyDataToSurfaceABGRRev(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD r, g, b, a, l;
+ const DWORD srcPitch = subWidth*4;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Optimize for most common case
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ a = *src++;
+ b = *src++;
+ g = *src++;
+ r = *src++;
+ *dst-- = a;
+ *dst-- = r;
+ *dst-- = g;
+ *dst-- = b;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ a = (*src++) >> 4; // discard the lower 4 bit
+ b = (*src++) >> 4;
+ g = (*src++) >> 4;
+ r = (*src++) >> 4;
+ *dst-- = (a << 4) | r;
+ *dst-- = (g << 4) | b;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3-1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit-1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3-1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src += 3;
+ mask = a << ashift;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3-1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src += 3;
+ mask = a << ashift;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src += 3;
+ mask = (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xlimit;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ src += 3;
+ *dst-- = (byte) (a << ashift);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3-1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+
+}
+
+
+void copyDataToSurfaceBGRRev(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD r, g, b, l;
+ const DWORD srcPitch = subWidth*3;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Optimize for most common case
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b = *src++;
+ g = *src++;
+ r = *src++;
+ *dst-- = 0xff;
+ *dst-- = r;
+ *dst-- = g;
+ *dst-- = b;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b = (*src++) >> 4;
+ g = (*src++) >> 4;
+ r = (*src++) >> 4;
+ *dst-- = 0xf0 | r;
+ *dst-- = (g << 4) | b;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3-1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) |ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ byte m1 = (byte) (ddpf->dwRGBAlphaBitMask & 0xff);
+ byte m2 = (byte) ((ddpf->dwRGBAlphaBitMask >> 8) & 0xff);
+ byte m3 = (byte) ((ddpf->dwRGBAlphaBitMask >> 16) & 0xff);
+ byte m4 = (byte) ((ddpf->dwRGBAlphaBitMask >> 24) & 0xff);
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst-- = m4;
+ *dst-- = m3;
+ *dst-- = m2;
+ *dst-- = m1;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst-- = m3;
+ *dst-- = m2;
+ *dst-- = m1;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst-- = m2;
+ *dst-- = m1;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst-- = m1;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src += 3;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+
+void copyDataToSurfaceRGBRev(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD r, g, b, l;
+ const DWORD srcPitch = subWidth*3;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ destRow += ((xlimit << 2) - 1);
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Most common case
+ // Note that format of destination is ARGB, which
+ // in PC format are BGRA, so we can't directly
+ // copy a row using CopyMemory()
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ r = *src++;
+ g = *src++;
+ b = *src++;
+ *dst-- = (byte) 0xff;
+ *dst-- = r;
+ *dst-- = g;
+ *dst-- = b;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ r = (*src++) >> 4; // discard the lower 4 bit
+ g = (*src++) >> 4;
+ b = (*src++) >> 4;
+ *dst-- = 0xf0 | r;
+ *dst-- = (g << 4) | b;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ byte m1 = (byte) (ddpf->dwRGBAlphaBitMask & 0xff);
+ byte m2 = (byte) ((ddpf->dwRGBAlphaBitMask >> 8) & 0xff);
+ byte m3 = (byte) ((ddpf->dwRGBAlphaBitMask >> 16) & 0xff);
+ byte m4 = (byte) ((ddpf->dwRGBAlphaBitMask >> 24) & 0xff);
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst-- = m4;
+ *dst-- = m3;
+ *dst-- = m2;
+ *dst-- = m1;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3- 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst-- = m3;
+ *dst-- = m2;
+ *dst-- = m1;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst-- = m2;
+ *dst-- = m1;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst-- = m1;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+void copyDataToSurfaceLARev(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD a, r, g, b, l;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+ const DWORD srcPitch = subWidth*2;
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Most common case
+ // Note that format of destination is ARGB, which
+ // in PC format are BGRA, so we can't directly
+ // copy a row using CopyMemory()
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ *dst-- = *src++;
+ *dst-- = l;
+ *dst-- = l;
+ *dst-- = l;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = (*src++) >> 4; // discard the lower 4 bit
+ a = (*src++) >> 4;
+ *dst-- = (a << 4) | l;
+ *dst-- = (l << 4) | l;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ *dst-- = (byte) ((l << rshift) | (l << gshift) |
+ (l << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ *dst-- = (byte) (a << ashift);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+void copyDataToSurfaceGrayRev(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD a, r, g, b, l;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+ const DWORD srcPitch = subWidth;
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Most common case
+ // Note that format of destination is ARGB, which
+ // in PC format are BGRA, so we can't directly
+ // copy a row using CopyMemory()
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ *dst-- = 0xff;
+ *dst-- = l;
+ *dst-- = l;
+ *dst-- = l;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = (*src++) >> 4; // discard the lower 4 bit
+ *dst-- = 0xf0 | l;
+ *dst-- = (l << 4) | l;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ *dst-- = (byte) ((l << rshift) | (l << gshift) |
+ (l << bshift) | ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ *dst-- = (byte) (a << ashift);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+
+void copyDataToSurfaceGrayRev(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jshort *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD a, r, g, b, l;
+ DWORD srcPitch = subWidth << 1;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+
+
+ if (internalFormat == ALPHA) {
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ *dst-- = (byte) (a << ashift);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += ((xlimit << 2) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 24) & 0xff);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xlimit*3 - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 16) & 0xff);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += ((xlimit << 1) - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst-- = (byte) ((mask >> 8) & 0xff);
+ *dst-- = (byte) (mask & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += (xlimit - 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ *dst-- = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+
+
+/*
+ * Copy data to Texture memory surface *pRect
+ * with pitch = rectPitch
+ * Note that rectPitch >= surface width since
+ * D3D may allocate extra width in texture memory
+ * for other purpose or for alignment. Addional
+ * offset = (xoffset, yoffset) is added to copy
+ * data in texture memory.
+ *
+ * The source image has width = subWidth and
+ * pointer *data.
+ *
+ *
+ */
+void copyDataToSurfaceRGBA(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD r, g, b, a, l;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+ const DWORD srcPitch = subWidth*4;
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Most common case
+ // Note that format of destination is ARGB, which
+ // in PC format are BGRA, so we can't directly
+ // copy a row using CopyMemory()
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ r = *src++;
+ g = *src++;
+ b = *src++;
+ *dst++ = b;
+ *dst++ = g;
+ *dst++ = r;
+ *dst++ = *src++;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ r = (*src++) >> 4; // discard the lower 4 bit
+ g = (*src++) >> 4;
+ b = (*src++) >> 4;
+ a = (*src++) >> 4;
+ *dst++ = (g << 4) | b;
+ *dst++ = (a << 4) | r;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ *dst++ = (byte) (a << ashift);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+
+void copyDataToSurfaceRGB(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD r, g, b, l;
+ const DWORD srcPitch = subWidth*3;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ destRow += (xoffset << 2);
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Most common case
+ // Note that format of destination is ARGB, which
+ // in PC format are BGRA, so we can't directly
+ // copy a row using CopyMemory()
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ r = *src++;
+ g = *src++;
+ b = *src++;
+ *dst++ = b;
+ *dst++ = g;
+ *dst++ = r;
+ *dst++ = (byte) 0xff;
+
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ r = (*src++) >> 4; // discard the lower 4 bit
+ g = (*src++) >> 4;
+ b = (*src++) >> 4;
+ *dst++ = (g << 4) | b;
+ *dst++ = 0xf0 | r;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ r = (*src++) >> rDiscard;
+ } else {
+ r = (*src++) << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = (*src++) >> gDiscard;
+ } else {
+ g = (*src++) >> -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = (*src++) >> bDiscard;
+ } else {
+ b = (*src++) >> -bDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ byte m1 = (byte) (ddpf->dwRGBAlphaBitMask & 0xff);
+ byte m2 = (byte) ((ddpf->dwRGBAlphaBitMask >> 8) & 0xff);
+ byte m3 = (byte) ((ddpf->dwRGBAlphaBitMask >> 16) & 0xff);
+ byte m4 = (byte) ((ddpf->dwRGBAlphaBitMask >> 24) & 0xff);
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst++ = m1;
+ *dst++ = m2;
+ *dst++ = m3;
+ *dst++ = m4;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst++ = m1;
+ *dst++ = m2;
+ *dst++ = m3;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst++ = m1;
+ *dst++ = m2;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src += 3;
+ *dst++ = m1;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ src++;
+ src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+
+void copyDataToSurfaceLA(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD a, r, g, b, l;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+ const DWORD srcPitch = subWidth*2;
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Most common case
+ // Note that format of destination is ARGB, which
+ // in PC format are BGRA, so we can't directly
+ // copy a row using CopyMemory()
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ *dst++ = l;
+ *dst++ = l;
+ *dst++ = l;
+ *dst++ = *src++;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = (*src++) >> 4; // discard the lower 4 bit
+ a = (*src++) >> 4;
+ *dst++ = (l << 4) | l;
+ *dst++ = (a << 4) | l;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) >> -aDiscard;
+ }
+ *dst++ = (byte) ((l << rshift) | (l << gshift) |
+ (l << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ *dst++ = (byte) (a << ashift);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ src++;
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+void copyDataToSurfaceGray(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jbyte *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD a, r, g, b, l;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+ const DWORD srcPitch = subWidth;
+
+
+ if ((internalFormat == J3D_RGBA) ||
+ (internalFormat == J3D_RGB)) {
+ if ((ddpf->dwRGBBitCount == 32) &&
+ (ddpf->dwRBitMask == 0xff0000) &&
+ (ddpf->dwGBitMask == 0xff00) &&
+ (ddpf->dwBBitMask == 0xff)) {
+ // Most common case
+ // Note that format of destination is ARGB, which
+ // in PC format are BGRA, so we can't directly
+ // copy a row using CopyMemory()
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ *dst++ = l;
+ *dst++ = l;
+ *dst++ = l;
+ *dst++ = 0xff;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount == 16) &&
+ (ddpf->dwRBitMask == 0xf00) &&
+ (ddpf->dwGBitMask == 0xf0) &&
+ (ddpf->dwBBitMask == 0xf)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = (*src++) >> 4; // discard the lower 4 bit
+ *dst++ = (l << 4) | l;
+ *dst++ = 0xf0 | l;
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else { // handle less common (even weird) format
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ mask = (l << rshift) | (l << gshift) |
+ (l << bshift) | ddpf->dwRGBAlphaBitMask;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (rDiscard >= 0) {
+ l = (*src++) >> rDiscard;
+ } else {
+ l = (*src++) << -rDiscard;
+ }
+ *dst++ = (byte) ((l << rshift) | (l << gshift) |
+ (l << bshift) | ddpf->dwRGBAlphaBitMask);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ }
+ } else if (internalFormat == LUMINANCE_ALPHA) {
+
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if (internalFormat == ALPHA) {
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ *dst++ = (byte) (a << ashift);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+
+
+/*
+ * Copy data from memory to DirectDraw surface
+ *
+ * Source image with WIDTH = tilew, the subimage with
+ * dimension (subWidth, subHeight) is copy with
+ * offset = (imgXOffset, imgYOffset) from the start
+ * pointer *data.
+ *
+ * Destination frame buffer is copy with
+ * offset = (xoffset, yoffset)
+ *
+ */
+void copyDataToSurface(jint storedFormat,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint subWidth, jint subHeight,
+ jint tilew, jbyte *data,
+ LPDIRECT3DTEXTURE8 surf,
+ jint level)
+{
+ D3DSURFACE_DESC ddsd;
+ D3DLOCKED_RECT lockedRect;
+ PIXELFORMAT ddpf;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+ surf->GetLevelDesc(level, &ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computePixelFormat(&ddpf, ddsd.Format);
+
+ // It is possible when texture is not a power of 2 or
+ // square only texture is required in hardware. In these
+ // case the hardware memory buffer may smaller than the
+ // texture pass in.
+
+ if ((xoffset >= width) || (yoffset >= height)) {
+ return;
+ }
+
+ DWORD xlimit = min(xoffset + subWidth, width);
+ DWORD ylimit = min(yoffset + subHeight, height);
+
+ hr = surf->LockRect(level, &lockedRect, NULL, 0);
+
+
+ if (FAILED(hr)) {
+ printf("Fail to lock surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+ int offset = tilew*imgYOffset + imgXOffset;
+ switch (storedFormat) {
+ case FORMAT_BYTE_RGBA :
+ // This is the one we use when byReference = false
+ copyDataToSurfaceRGBA(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + (offset << 2),
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ break;
+ case FORMAT_BYTE_RGB:
+ copyDataToSurfaceRGB(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + 3*offset,
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ break;
+ case FORMAT_BYTE_ABGR:
+ copyDataToSurfaceABGR(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + (offset << 2),
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ break;
+ case FORMAT_BYTE_BGR:
+ copyDataToSurfaceBGR(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + 3*offset,
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ break;
+ case FORMAT_BYTE_LA:
+ copyDataToSurfaceLA(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + (offset << 1),
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ break;
+ case FORMAT_BYTE_GRAY:
+ copyDataToSurfaceGray(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + offset,
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ break;
+ default: // should not happen
+ printf("[Java 3D] StoredFormat %d, internalFormat %d not support !\n",
+ storedFormat, internalFormat);
+ }
+
+ hr = surf->UnlockRect(level);
+ if (FAILED(hr)) {
+ printf("Fail to unlock surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+}
+
+
+
+void copyDataToSurfaceGray(jint internalFormat,
+ PIXELFORMAT *ddpf,
+ unsigned char* pRect,
+ DWORD rectPitch,
+ jshort *data,
+ jint xoffset, jint yoffset,
+ DWORD xlimit, DWORD ylimit,
+ jint subWidth)
+{
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD a, r, g, b, l;
+ DWORD srcPitch = subWidth << 1;
+ unsigned char *srcRow = (unsigned char *) data;
+ unsigned char *destRow = pRect + rectPitch*yoffset;
+
+
+ if (internalFormat == ALPHA) {
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = a << ashift;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ mask = (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ if (aDiscard >= 0) {
+ a = (*src++) >> aDiscard;
+ } else {
+ a = (*src++) << -aDiscard;
+ }
+ *dst++ = (byte) (a << ashift);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else if ((internalFormat == LUMINANCE) ||
+ (internalFormat == INTENSITY)) {
+ int rDiscard = 8-countBits(ddpf->dwRBitMask);
+ int gDiscard = 8-countBits(ddpf->dwGBitMask);
+ int bDiscard = 8-countBits(ddpf->dwBBitMask);
+ int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask);
+ int rshift = firstBit(ddpf->dwRBitMask);
+ int gshift = firstBit(ddpf->dwGBitMask);
+ int bshift = firstBit(ddpf->dwBBitMask);
+ int ashift = firstBit(ddpf->dwRGBAlphaBitMask);
+ DWORD mask;
+
+
+ if ((ddpf->dwRGBBitCount <= 32) &&
+ (ddpf->dwRGBBitCount > 24)) {
+ destRow += (xoffset << 2);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 24) &&
+ (ddpf->dwRGBBitCount > 16)) {
+ destRow += (xoffset*3);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if ((ddpf->dwRGBBitCount <= 16) &&
+ (ddpf->dwRGBBitCount > 8)) {
+ destRow += (xoffset << 1);
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ mask = (r << rshift) | (g << gshift) |
+ (b << bshift) | (a << ashift);
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else if (ddpf->dwRGBBitCount <= 8) {
+ destRow += xoffset;
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *src++; // discard lower order byte
+ l = *src++;
+ if (rDiscard >= 0) {
+ r = l >> rDiscard;
+ } else {
+ r = l << -rDiscard;
+ }
+ if (gDiscard >= 0) {
+ g = l >> gDiscard;
+ } else {
+ g = l << -gDiscard;
+ }
+ if (bDiscard >= 0) {
+ b = l >> bDiscard;
+ } else {
+ b = l << -bDiscard;
+ }
+ if (aDiscard >= 0) {
+ a = l >> aDiscard;
+ } else {
+ a = l << -aDiscard;
+ }
+ *dst++ = (byte) ((r << rshift) |
+ (g << gshift) |
+ (b << bshift) |
+ (a << ashift));
+ }
+ srcRow += srcPitch;
+ destRow += rectPitch;
+ }
+ } else {
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf->dwRGBBitCount);
+ }
+ } else {
+ printf("Texture format %d not support.\n", internalFormat);
+ }
+}
+
+
+// copy the texture data to DirectDraw surface
+void copyDataToSurface(jint storedFormat,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint subWidth, jint subHeight,
+ jint tilew, jshort *data,
+ LPDIRECT3DTEXTURE8 surf,
+ jint level)
+{
+ D3DSURFACE_DESC ddsd;
+ D3DLOCKED_RECT lockedRect;
+ PIXELFORMAT ddpf;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+
+ surf->GetLevelDesc(level, &ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computePixelFormat(&ddpf, ddsd.Format);
+
+ if ((xoffset >= width) || (yoffset >= height)) {
+ return;
+ }
+ DWORD xlimit = min(xoffset + subWidth, width);
+ DWORD ylimit = min(yoffset + subHeight, height);
+
+ hr = surf->LockRect(level, &lockedRect, NULL, 0);
+
+ if (FAILED(hr)) {
+ printf("Fail to lock surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+ int offset = tilew*imgYOffset + imgXOffset;
+
+ copyDataToSurfaceGray(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + (offset << 1),
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+
+ hr = surf->UnlockRect(level);
+ if (FAILED(hr)) {
+ printf("Fail to unlock surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+}
+
+
+// copy data from DirectDraw depth surface to memory
+// and reverse the Y axis
+void copyDepthFromSurface(jint xoffset, jint yoffset,
+ jint subWidth, jint subHeight,
+ jint *data,
+ LPDIRECT3DSURFACE8 surf)
+{
+ D3DSURFACE_DESC ddsd;
+ DEPTHPIXELFORMAT ddpf;
+ D3DLOCKED_RECT lockedRect;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+ surf->GetDesc(&ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computeDepthPixelFormat(&ddpf, ddsd.Format);
+
+ if ((xoffset >= width) || (yoffset >= height)) {
+ return;
+ }
+
+ DWORD xlimit = min(xoffset + subWidth, width);
+ DWORD ylimit = min(yoffset + subHeight, height);
+
+ hr = surf->LockRect(&lockedRect, NULL, D3DLOCK_READONLY);
+
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr));
+ }
+ return;
+ }
+
+ DWORD b1, b2, b3, b4;
+ DWORD mask;
+ jint *destRow = data;
+ jint *dst;
+ unsigned char *src;
+ unsigned char *srcRow = ((unsigned char *) lockedRect.pBits) +
+ xoffset*((int) ceil((float) ddpf.dwZBufferBitDepth/8.0)) +
+ (yoffset*lockedRect.Pitch);
+
+ int zshift = firstBit(ddpf.dwZBitMask);
+
+ destRow += (subHeight-1)*subWidth;
+
+ if ((ddpf.dwZBufferBitDepth <= 32) &&
+ (ddpf.dwZBufferBitDepth > 24)) {
+
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ b4 = *src++;
+ mask = (b4 << 24) | (b3 << 16) |
+ (b2 << 8) | b1;
+ *dst++ = (mask & ddpf.dwZBitMask) >> zshift;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= subWidth;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 24) &&
+ (ddpf.dwZBufferBitDepth > 16)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ mask = (b3 << 16) | (b2 << 8) | b1;
+ *dst++ = (mask & ddpf.dwZBitMask) >> zshift;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= subWidth;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 16) &&
+ (ddpf.dwZBufferBitDepth > 8)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ mask = (b2 << 8) | b1;
+ *dst++ = (mask & ddpf.dwZBitMask) >> zshift;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= subWidth;
+ }
+ } else if (ddpf.dwZBufferBitDepth <= 8) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *dst++ = (*src++ & ddpf.dwZBitMask) >> zshift;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= subWidth;
+ }
+ } else {
+ // This is not support by D3D 8 either
+ printf("[Java 3D] %d bit Z buffer not support !\n",
+ ddpf.dwZBufferBitDepth);
+ }
+
+ hr = surf->UnlockRect();
+ if (FAILED(hr)) {
+ printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+}
+
+
+// copy data from DirectDraw depth surface to memory
+// and reverse the Y axis
+void copyDepthFromSurface(jint xoffset, jint yoffset,
+ jint subWidth, jint subHeight,
+ jfloat *data,
+ LPDIRECT3DSURFACE8 surf)
+{
+ D3DSURFACE_DESC ddsd;
+ DEPTHPIXELFORMAT ddpf;
+ D3DLOCKED_RECT lockedRect;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+
+ surf->GetDesc(&ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computeDepthPixelFormat(&ddpf, ddsd.Format);
+
+ if ((xoffset >= width) || (yoffset >= height)) {
+ return;
+ }
+
+ DWORD xlimit = min(xoffset + subWidth, width);
+ DWORD ylimit = min(yoffset + subHeight, height);
+
+ hr = surf->LockRect(&lockedRect, NULL, D3DLOCK_READONLY);
+
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr));
+ }
+ return;
+ }
+
+ DWORD b1, b2, b3, b4;
+ DWORD mask;
+ jfloat *destRow = data;
+ jfloat *dst;
+ unsigned char *src;
+ unsigned char *srcRow = ((unsigned char *) lockedRect.pBits) +
+ xoffset*((int) ceil((float) ddpf.dwZBufferBitDepth/8.0)) +
+ (yoffset*lockedRect.Pitch);
+
+ int zshift = firstBit(ddpf.dwZBitMask);
+ float maxdepth = 1 << ddpf.dwZBufferBitDepth;
+
+ destRow += (subHeight-1)*subWidth;
+
+ if ((ddpf.dwZBufferBitDepth <= 32) &&
+ (ddpf.dwZBufferBitDepth > 24)) {
+
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ b4 = *src++;
+ mask = (b4 << 24) | (b3 << 16) |
+ (b2 << 8) | b1;
+ *dst++ = (((mask & ddpf.dwZBitMask) >>
+ zshift))/ maxdepth;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= subWidth;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 24) &&
+ (ddpf.dwZBufferBitDepth > 16)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ b3 = *src++;
+ mask = (b3 << 16) | (b2 << 8) | b1;
+ *dst++ = ((mask & ddpf.dwZBitMask) >>
+ zshift)/ maxdepth;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= subWidth;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 16) &&
+ (ddpf.dwZBufferBitDepth > 8)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ b1 = *src++;
+ b2 = *src++;
+ mask = (b2 << 8) | b1;
+ *dst++ = ((mask & ddpf.dwZBitMask) >>
+ zshift)/ maxdepth;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= subWidth;
+ }
+ } else if (ddpf.dwZBufferBitDepth <= 8) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ *dst++ = ((*src++ & ddpf.dwZBitMask) >>
+ zshift)/ maxdepth;
+ }
+ srcRow += lockedRect.Pitch;
+ destRow -= subWidth;
+ }
+ } else {
+ // This is not support by D3D 8 either
+ printf("[Java 3D] %d bit Z buffer not support !\n",
+ ddpf.dwZBufferBitDepth);
+ }
+
+ hr = surf->UnlockRect();
+ if (FAILED(hr)) {
+ printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+}
+
+
+// copy data to DirectDraw depth surface from memory
+// and reverse the Y axis
+void copyDepthToSurfaceAlways(jint dst_xoffset, jint dst_yoffset,
+ jint src_xoffset, jint src_yoffset,
+ jint subWidth, jint subHeight,
+ jint src_width, jint src_height,
+ jint *data,
+ LPDIRECT3DSURFACE8 surf)
+{
+ D3DSURFACE_DESC ddsd;
+ DEPTHPIXELFORMAT ddpf;
+ D3DLOCKED_RECT lockedRect;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+
+ surf->GetDesc(&ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computeDepthPixelFormat(&ddpf, ddsd.Format);
+
+ if ((dst_xoffset >= width) || (dst_yoffset >= height)) {
+ return;
+ }
+
+ DWORD xlimit = min(dst_xoffset + subWidth, width);
+ DWORD ylimit = min(dst_yoffset + subHeight, height);
+
+ hr = surf->LockRect(&lockedRect, NULL, 0);
+
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr));
+ }
+ return;
+ }
+ jint *src;
+ jint *srcRow = data + src_xoffset +
+ (src_yoffset + subHeight-1)*src_width;
+ unsigned char *dst;
+ unsigned char *destRow = ((unsigned char *) lockedRect.pBits) +
+ dst_xoffset + dst_yoffset*lockedRect.Pitch;
+
+ int zshift = firstBit(ddpf.dwZBitMask);
+ DWORD mask;
+ int maxValue = ddpf.dwZBitMask >> zshift;
+
+
+ if ((ddpf.dwZBufferBitDepth <= 32) &&
+ (ddpf.dwZBufferBitDepth > 24)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ mask = *src++;
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 24) &&
+ (ddpf.dwZBufferBitDepth > 16)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ mask = *src++;
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 16) &&
+ (ddpf.dwZBufferBitDepth > 8)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ mask = *src++;
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if (ddpf.dwZBufferBitDepth <= 8) {
+ byte bmask = (byte) (ddpf.dwZBitMask & 0xff);
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ mask = *src++;
+ if (mask < maxValue) {
+ *dst++ = (byte) ((mask << zshift) & 0xff);
+ } else {
+ *dst++ = bmask;
+ }
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+
+ }
+
+ hr = surf->UnlockRect();
+ if (FAILED(hr)) {
+ printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+}
+
+
+// copy data to DirectDraw depth surface from memory
+// and reverse the Y axis
+void copyDepthToSurfaceAlways(jint dst_xoffset, jint dst_yoffset,
+ jint src_xoffset, jint src_yoffset,
+ jint subWidth, jint subHeight,
+ jint src_width, jint src_height,
+ jfloat *data,
+ LPDIRECT3DSURFACE8 surf)
+{
+ D3DSURFACE_DESC ddsd;
+ DEPTHPIXELFORMAT ddpf;
+ D3DLOCKED_RECT lockedRect;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+
+ surf->GetDesc(&ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computeDepthPixelFormat(&ddpf, ddsd.Format);
+
+
+ if ((dst_xoffset >= width) || (dst_yoffset >= height)) {
+ return;
+ }
+
+ DWORD xlimit = min(dst_xoffset + subWidth, width);
+ DWORD ylimit = min(dst_yoffset + subHeight, height);
+
+ hr = surf->LockRect(&lockedRect, NULL, 9);
+
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr));
+ }
+ return;
+ }
+ jfloat *src;
+ jfloat *srcRow = data + src_xoffset +
+ (src_yoffset + subHeight-1)*src_width;
+ unsigned char *dst;
+ unsigned char *destRow = ((unsigned char *) lockedRect.pBits) +
+ dst_xoffset + dst_yoffset*lockedRect.Pitch;
+
+ int zshift = firstBit(ddpf.dwZBitMask);
+ DWORD mask;
+ int maxValue = ddpf.dwZBitMask >> zshift;
+ float maxdepth = 1 << ddpf.dwZBufferBitDepth;
+
+ if ((ddpf.dwZBufferBitDepth <= 32) &&
+ (ddpf.dwZBufferBitDepth > 24)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ mask = (DWORD) (*src++)*maxdepth;
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 24) &&
+ (ddpf.dwZBufferBitDepth > 16)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ mask = (DWORD) (*src++)*maxdepth;
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 16) &&
+ (ddpf.dwZBufferBitDepth > 8)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ mask = (DWORD) (*src++)*maxdepth;
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if (ddpf.dwZBufferBitDepth <= 8) {
+ byte bmask = (byte) (ddpf.dwZBitMask & 0xff);
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ mask = (DWORD) (*src++)*maxdepth;
+ if (mask < maxValue) {
+ *dst++ = (byte) ((mask << zshift) & 0xff);
+ } else {
+ *dst++ = bmask;
+ }
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+
+ }
+
+ hr = surf->UnlockRect();
+ if (FAILED(hr)) {
+ printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+}
+
+// copy data to DirectDraw depth surface from memory
+// and reverse the Y axis with Z test D3DCMP_LESS
+void copyDepthToSurfaceCmp(jint dst_xoffset, jint dst_yoffset,
+ jint src_xoffset, jint src_yoffset,
+ jint subWidth, jint subHeight,
+ jint src_width, jint src_height,
+ jint *data,
+ LPDIRECT3DSURFACE8 surf)
+{
+ D3DSURFACE_DESC ddsd;
+ DEPTHPIXELFORMAT ddpf;
+ D3DLOCKED_RECT lockedRect;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+
+ surf->GetDesc(&ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computeDepthPixelFormat(&ddpf, ddsd.Format);
+
+
+ if ((dst_xoffset >= width) || (dst_yoffset >= height)) {
+ return;
+ }
+
+ DWORD xlimit = min(dst_xoffset + subWidth, width);
+ DWORD ylimit = min(dst_yoffset + subHeight, height);
+
+ hr = surf->LockRect(&lockedRect, NULL, 0);
+
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr));
+ }
+ return;
+ }
+
+ jint *src;
+ jint *srcRow = data + src_xoffset +
+ (src_yoffset + subHeight-1)*src_width;
+ unsigned char *dst;
+ unsigned char *destRow = ((unsigned char *) lockedRect.pBits) +
+ dst_xoffset + dst_yoffset*lockedRect.Pitch;
+
+
+ int zshift = firstBit(ddpf.dwZBitMask);
+ DWORD mask;
+ DWORD b1, b2, b3, b4;
+ DWORD zmask;
+ int maxValue = ddpf.dwZBitMask >> zshift;
+
+
+ if ((ddpf.dwZBufferBitDepth <= 32) &&
+ (ddpf.dwZBufferBitDepth > 24)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ b1 = *dst++;
+ b2 = *dst++;
+ b3 = *dst++;
+ b4 = *dst++;
+ zmask = (b4 << 24) | (b3 << 16) |
+ (b2 << 8) | b1;
+ zmask = (zmask & ddpf.dwZBitMask) >> zshift;
+ mask = *src++;
+ if (mask < zmask) {
+ // z depth test pass
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ dst -= 4;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 24) &&
+ (ddpf.dwZBufferBitDepth > 16)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ b1 = *dst++;
+ b2 = *dst++;
+ b3 = *dst++;
+ zmask = (b3 << 16) | (b2 << 8) | b1;
+ zmask = (zmask & ddpf.dwZBitMask) >> zshift;
+ mask = *src++;
+ if (mask < zmask) {
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ dst -= 3;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 16) &&
+ (ddpf.dwZBufferBitDepth > 8)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ b1 = *dst++;
+ b2 = *dst++;
+ zmask = (b2 << 8) | b1;
+ zmask = (zmask & ddpf.dwZBitMask) >> zshift;
+ mask = *src++;
+ if (mask < zmask) {
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ dst -= 2;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if (ddpf.dwZBufferBitDepth <= 8) {
+ byte bmask = (byte) (ddpf.dwZBitMask & 0xff);
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ zmask = (*dst++ & ddpf.dwZBitMask) >> zshift;
+ mask = *src++;
+ if (mask < zmask) {
+ dst--;
+ if (mask < maxValue) {
+ *dst++ = (byte) ((mask << zshift) & 0xff);
+ } else {
+ *dst++ = bmask;
+ }
+ }
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+
+ }
+
+ hr = surf->UnlockRect();
+ if (FAILED(hr)) {
+ printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+}
+
+
+// copy data to DirectDraw depth surface from memory
+// and reverse the Y axis with Z test D3DCMP_LESS
+void copyDepthToSurfaceCmp(jint dst_xoffset, jint dst_yoffset,
+ jint src_xoffset, jint src_yoffset,
+ jint subWidth, jint subHeight,
+ jint src_width, jint src_height,
+ jfloat *data,
+ LPDIRECT3DSURFACE8 surf)
+{
+ D3DSURFACE_DESC ddsd;
+ DEPTHPIXELFORMAT ddpf;
+ D3DLOCKED_RECT lockedRect;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+
+ surf->GetDesc(&ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computeDepthPixelFormat(&ddpf, ddsd.Format);
+
+
+ if ((dst_xoffset >= width) || (dst_yoffset >= height)) {
+ return;
+ }
+
+ DWORD xlimit = min(dst_xoffset + subWidth, width);
+ DWORD ylimit = min(dst_yoffset + subHeight, height);
+
+ hr = surf->LockRect(&lockedRect, NULL, 0);
+
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr));
+ }
+ return;
+ }
+ jfloat *src;
+ jfloat *srcRow = data + src_xoffset +
+ (src_yoffset + subHeight-1)*src_width;
+ unsigned char *dst;
+ unsigned char *destRow = ((unsigned char *) lockedRect.pBits) +
+ dst_xoffset + dst_yoffset*lockedRect.Pitch;
+
+ int zshift = firstBit(ddpf.dwZBitMask);
+ DWORD mask;
+ DWORD b1, b2, b3, b4;
+ DWORD zmask;
+ int maxValue = ddpf.dwZBitMask >> zshift;
+ float maxdepth = 1 << ddpf.dwZBufferBitDepth;
+
+ if ((ddpf.dwZBufferBitDepth <= 32) &&
+ (ddpf.dwZBufferBitDepth > 24)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ b1 = *dst++;
+ b2 = *dst++;
+ b3 = *dst++;
+ b4 = *dst++;
+ zmask = (b4 << 24) | (b3 << 16) |
+ (b2 << 8) | b1;
+ zmask = (zmask & ddpf.dwZBitMask) >> zshift;
+ mask = (DWORD) (*src++)*maxdepth;
+ if (mask < zmask) {
+ // z depth test pass
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ dst -= 4;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ }
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 24) &&
+ (ddpf.dwZBufferBitDepth > 16)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ b1 = *dst++;
+ b2 = *dst++;
+ b3 = *dst++;
+ zmask = (b3 << 16) | (b2 << 8) | b1;
+ zmask = (zmask & ddpf.dwZBitMask) >> zshift;
+ mask = (DWORD) (*src++)*maxdepth;
+ if (mask < zmask) {
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ dst -= 3;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ }
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if ((ddpf.dwZBufferBitDepth <= 16) &&
+ (ddpf.dwZBufferBitDepth > 8)) {
+
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ b1 = *dst++;
+ b2 = *dst++;
+ zmask = (b2 << 8) | b1;
+ zmask = (zmask & ddpf.dwZBitMask) >> zshift;
+ mask = (DWORD) (*src++)*maxdepth;
+ if (mask < zmask) {
+ if (mask < maxValue) {
+ mask = mask << zshift;
+ } else {
+ mask = ddpf.dwZBitMask;
+ }
+ dst -= 2;
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ }
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+ } else if (ddpf.dwZBufferBitDepth <= 8) {
+ byte bmask = (byte) (ddpf.dwZBitMask & 0xff);
+ for (int i=dst_yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=dst_xoffset; j < xlimit; j++) {
+ zmask = (*dst++ & ddpf.dwZBitMask) >> zshift;
+ mask = (DWORD) (*src++)*maxdepth;
+ if (mask < zmask) {
+ dst--;
+ if (mask < maxValue) {
+ *dst++ = (byte) ((mask << zshift) & 0xff);
+ } else {
+ *dst++ = bmask;
+ }
+ }
+ }
+ srcRow -= src_width;
+ destRow += lockedRect.Pitch;
+ }
+
+ }
+
+ hr = surf->UnlockRect();
+ if (FAILED(hr)) {
+ printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+}
+
+// copy data to DirectDraw depth surface from memory
+// and reverse the Y axis
+void copyDepthToSurface(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ jint dst_xoffset, jint dst_yoffset,
+ jint src_xoffset, jint src_yoffset,
+ jint subWidth, jint subHeight,
+ jint src_width, jint src_height,
+ jint *data,
+ LPDIRECT3DSURFACE8 surf)
+{
+
+ if (!d3dCtx->zWriteEnable) {
+ return;
+ }
+
+ if (!d3dCtx->zEnable) {
+ copyDepthToSurfaceAlways(dst_xoffset, dst_yoffset,
+ src_xoffset, src_yoffset,
+ subWidth, subHeight,
+ src_width, src_height,
+ data, surf);
+ } else {
+ // Currently ZFUNC must be D3DCMP_LESS
+ copyDepthToSurfaceCmp(dst_xoffset, dst_yoffset,
+ src_xoffset, src_yoffset,
+ subWidth, subHeight,
+ src_width, src_height,
+ data, surf);
+ }
+}
+
+
+// copy data to DirectDraw depth surface from memory
+// and reverse the Y axis
+void copyDepthToSurface(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ jint dst_xoffset, jint dst_yoffset,
+ jint src_xoffset, jint src_yoffset,
+ jint subWidth, jint subHeight,
+ jint src_width, jint src_height,
+ jfloat *data,
+ LPDIRECT3DSURFACE8 surf)
+{
+ if (!d3dCtx->zWriteEnable) {
+ return;
+ }
+
+ if (!d3dCtx->zEnable) {
+ copyDepthToSurfaceAlways(dst_xoffset, dst_yoffset,
+ src_xoffset, src_yoffset,
+ subWidth, subHeight,
+ src_width, src_height,
+ data, surf);
+ } else {
+ // Currently ZFUNC must be D3DCMP_LESS
+ copyDepthToSurfaceCmp(dst_xoffset, dst_yoffset,
+ src_xoffset, src_yoffset,
+ subWidth, subHeight,
+ src_width, src_height,
+ data, surf);
+ }
+}
+
+// composite data from memory to DirectDraw surface
+void compositeDataToSurface(jint px, jint py,
+ jint xoffset, jint yoffset,
+ jint subWidth, jint subHeight,
+ jint dataWidth,
+ jbyte *data,
+ LPDIRECT3DSURFACE8 surf)
+{
+ D3DSURFACE_DESC ddsd;
+ D3DLOCKED_RECT lockedRect;
+ PIXELFORMAT ddpf;
+
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+
+ surf->GetDesc(&ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computePixelFormat(&ddpf, ddsd.Format);
+
+ if ((xoffset >= width) || (yoffset >= height)) {
+ return;
+ }
+
+ DWORD xlimit = min(xoffset + subWidth, width);
+ DWORD ylimit = min(yoffset + subHeight, height);
+
+ hr = surf->LockRect(&lockedRect, NULL, 0);
+
+ if (FAILED(hr)) {
+ printf("Fail to lock rendering surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+ unsigned char *src;
+ unsigned char *dst;
+ DWORD r, g, b, a;
+ DWORD srcPitch;
+ int offset = (xoffset + yoffset*dataWidth) << 2;
+ unsigned char *srcRow = (unsigned char *) data + offset;
+ unsigned char *destRow = ((unsigned char *) lockedRect.pBits) +
+ ((px + xoffset) << 2) + (py + yoffset)*lockedRect.Pitch;
+ unsigned char a2;
+ float inv = 1.0f/255.0f;
+ ddpf.noAlpha = true;
+
+ if (ddpf.dwRGBAlphaBitMask != 0) {
+ ddpf.noAlpha = false;
+ }
+
+ srcPitch = dataWidth << 2;
+
+ if ((ddpf.dwRGBBitCount == 32) &&
+ (ddpf.dwRBitMask == 0xff0000) &&
+ (ddpf.dwGBitMask == 0xff00) &&
+ (ddpf.dwBBitMask == 0xff)) {
+ // Most common case
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ a = *src++;
+ b = *src++;
+ g = *src++;
+ r = *src++;
+
+ if (a != 0) {
+ if (a == 0xff) {
+ *dst++ = b;
+ *dst++ = g;
+ *dst++ = r;
+ *dst++ = 0xff;
+ } else {
+ a2 = 255-a;
+ *dst++ = (*dst * a2 + b * a)*inv;
+ *dst++ = (*dst * a2 + g * a)*inv;
+ *dst++ = (*dst * a2 + r * a)*inv;
+ if (ddpf.noAlpha) {
+ *dst++ = a;
+ } else {
+ *dst++ = (*dst * a2 + a * a)*inv;
+ }
+ }
+ } else {
+ dst += 4;
+ }
+ }
+ srcRow += srcPitch;
+ destRow += lockedRect.Pitch;
+ }
+ } else { // handle less common (even weird) format
+ int rshift = firstBit(ddpf.dwRBitMask) +
+ countBits(ddpf.dwRBitMask) - 8;
+ int gshift = firstBit(ddpf.dwGBitMask) +
+ countBits(ddpf.dwGBitMask) - 8;
+ int bshift = firstBit(ddpf.dwBBitMask) +
+ countBits(ddpf.dwBBitMask) - 8;
+ int ashift = firstBit(ddpf.dwRGBAlphaBitMask) +
+ countBits(ddpf.dwRGBAlphaBitMask) - 8;
+
+ DWORD mask, dmask;
+ DWORD dr, dg, db, da;
+
+ if ((ddpf.dwRGBBitCount <= 32) &&
+ (ddpf.dwRGBBitCount > 24)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ a = *src++;
+ b = *src++;
+ g = *src++;
+ r = *src++;
+
+ if (a != 0) {
+ if (a != 0xff) {
+ dmask = (*(dst+3) << 24) |
+ (*(dst+2) << 16) |
+ (*(dst+1) << 8) |
+ *dst;
+ if (rshift >= 0) {
+ dr = (byte) ((dmask & ddpf.dwRBitMask) >>
+ rshift);
+ } else {
+ dr = (byte) ((dmask & ddpf.dwRBitMask) <<
+ -rshift);
+ }
+ if (gshift >= 0) {
+ dg = (byte) ((dmask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ dg = (byte) ((dmask & ddpf.dwGBitMask) <<
+ -gshift);
+ }
+ if (bshift >= 0) {
+ db = (byte) ((dmask & ddpf.dwBBitMask) >>
+ bshift);
+ } else {
+ db = (byte) ((dmask & ddpf.dwBBitMask) <<
+ -bshift);
+ }
+ a2 = 255 - a;
+ if (!ddpf.noAlpha) {
+ if (ashift >= 0) {
+ da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) <<
+ -ashift);
+ }
+ a = (da * a2 + a * a)*inv;
+ }
+
+ g = (dg * a2 + g * a)*inv;
+ b = (db * a2 + b * a)*inv;
+ r = (dr * a2 + r * a)*inv;
+ }
+ if (rshift >= 0) {
+ mask = (r << rshift) & ddpf.dwRBitMask;
+ } else {
+ mask = (r >> -rshift) & ddpf.dwRBitMask;
+ }
+ if (gshift >= 0) {
+ mask |= (g << gshift) & ddpf.dwGBitMask;
+ } else {
+ mask |= (g >> -gshift) & ddpf.dwGBitMask;
+ }
+ if (bshift >= 0) {
+ mask |= (b << bshift) & ddpf.dwBBitMask;
+ } else {
+ mask |= (b >> -bshift) & ddpf.dwBBitMask;
+ }
+ if (!ddpf.noAlpha) {
+ if (ashift >= 0) {
+ mask |= (a << ashift) & ddpf.dwRGBAlphaBitMask;
+ } else {
+ mask |= (a >> -ashift) & ddpf.dwRGBAlphaBitMask;
+ }
+ }
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ *dst++ = (byte) ((mask >> 24) & 0xff);
+ } else {
+ dst += 4;
+ }
+ }
+ srcRow += srcPitch;
+ destRow += lockedRect.Pitch;
+ }
+ } else if ((ddpf.dwRGBBitCount <= 24) &&
+ (ddpf.dwRGBBitCount > 16)) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ a = *src++;
+ b = *src++;
+ g = *src++;
+ r = *src++;
+ if (a != 0) {
+ if (a != 0xff) {
+ dmask = (*(dst+2) << 16) |
+ (*(dst+1) << 8) |
+ *dst;
+ if (rshift >= 0) {
+ dr = (byte) ((dmask & ddpf.dwRBitMask) >>
+ rshift);
+ } else {
+ dr = (byte) ((dmask & ddpf.dwRBitMask) <<
+ -rshift);
+ }
+ if (gshift >= 0) {
+ dg = (byte) ((dmask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ dg = (byte) ((dmask & ddpf.dwGBitMask) <<
+ -gshift);
+ }
+ if (bshift >= 0) {
+ db = (byte) ((dmask & ddpf.dwBBitMask) >>
+ bshift);
+ } else {
+ db = (byte) ((dmask & ddpf.dwBBitMask) <<
+ -bshift);
+ }
+ a2 = 255 - a;
+ if (!ddpf.noAlpha) {
+ if (ashift >= 0) {
+ da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) <<
+ -ashift);
+ }
+ a = (da * a2 + a * a)*inv;
+ }
+ g = (dg * a2 + g * a)*inv;
+ b = (db * a2 + b * a)*inv;
+ r = (dr * a2 + r * a)*inv;
+ }
+ if (rshift >= 0) {
+ mask = (r << rshift) & ddpf.dwRBitMask;
+ } else {
+ mask = (r >> -rshift) & ddpf.dwRBitMask;
+ }
+ if (gshift >= 0) {
+ mask |= (g << gshift) & ddpf.dwGBitMask;
+ } else {
+ mask |= (g >> -gshift) & ddpf.dwGBitMask;
+ }
+ if (bshift >= 0) {
+ mask |= (b << bshift) & ddpf.dwBBitMask;
+ } else {
+ mask |= (b >> -bshift) & ddpf.dwBBitMask;
+ }
+ if (!ddpf.noAlpha) {
+ if (ashift >= 0) {
+ mask |= (a << ashift) & ddpf.dwRGBAlphaBitMask;
+ } else {
+ mask |= (a >> -ashift) & ddpf.dwRGBAlphaBitMask;
+ }
+ }
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ *dst++ = (byte) ((mask >> 16) & 0xff);
+ } else {
+ dst += 3;
+ }
+ }
+ srcRow += srcPitch;
+ destRow += lockedRect.Pitch;
+ }
+ } else if ((ddpf.dwRGBBitCount <= 16) &&
+ (ddpf.dwRGBBitCount > 8)) {
+
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ a = *src++;
+ b = *src++;
+ g = *src++;
+ r = *src++;
+
+ if (a != 0) {
+ if (a != 0xff) {
+ dmask = (*(dst+1) << 8) | *dst;
+
+ if (rshift >= 0) {
+ dr = (byte) ((dmask & ddpf.dwRBitMask) >>
+ rshift);
+ } else {
+ dr = (byte) ((dmask & ddpf.dwRBitMask) <<
+ -rshift);
+ }
+ if (gshift >= 0) {
+ dg = (byte) ((dmask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ dg = (byte) ((dmask & ddpf.dwGBitMask) <<
+ -gshift);
+ }
+ if (bshift >= 0) {
+ db = (byte) ((dmask & ddpf.dwBBitMask) >>
+ bshift);
+ } else {
+ db = (byte) ((dmask & ddpf.dwBBitMask) <<
+ -bshift);
+ }
+ a2 = 255 - a;
+
+ if (!ddpf.noAlpha) {
+ if (ashift >= 0) {
+ da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) <<
+ -ashift);
+ }
+ a = (da * a2 + a * a)*inv;
+ }
+
+ g = (dg * a2 + g * a)*inv;
+ b = (db * a2 + b * a)*inv;
+ r = (dr * a2 + r * a)*inv;
+ }
+
+ if (rshift >= 0) {
+ mask = (r << rshift) & ddpf.dwRBitMask;
+ } else {
+ mask = (r >> -rshift) & ddpf.dwRBitMask;
+ }
+ if (gshift >= 0) {
+ mask |= ((g << gshift) & ddpf.dwGBitMask);
+ } else {
+ mask |= ((g >> -gshift) & ddpf.dwGBitMask);
+ }
+ if (bshift >= 0) {
+ mask |= ((b << bshift) & ddpf.dwBBitMask);
+ } else {
+ mask |= ((b >> -bshift) & ddpf.dwBBitMask);
+ }
+ if (!ddpf.noAlpha) {
+ if (ashift >= 0) {
+ mask |= ((a << ashift) & ddpf.dwRGBAlphaBitMask);
+ } else {
+ mask |= ((a >> -ashift) & ddpf.dwRGBAlphaBitMask);
+ }
+ }
+
+ *dst++ = (byte) (mask & 0xff);
+ *dst++ = (byte) ((mask >> 8) & 0xff);
+ } else {
+ dst += 2;
+ }
+ }
+ srcRow += srcPitch;
+ destRow += lockedRect.Pitch;
+ }
+ } else if (ddpf.dwRGBBitCount <= 8) {
+ for (int i=yoffset; i < ylimit; i++) {
+ src = srcRow;
+ dst = destRow;
+ for (int j=xoffset; j < xlimit; j++) {
+ a = *src++;
+ b = *src++;
+ g = *src++;
+ r = *src++;
+ if (a != 0) {
+ if (a != 0xff) {
+ dmask = *dst;
+ if (rshift >= 0) {
+ dr = (byte) ((dmask & ddpf.dwRBitMask) >>
+ rshift);
+ } else {
+ dr = (byte) ((dmask & ddpf.dwRBitMask) <<
+ -rshift);
+ }
+ if (gshift >= 0) {
+ dg = (byte) ((dmask & ddpf.dwGBitMask) >>
+ gshift);
+ } else {
+ dg = (byte) ((dmask & ddpf.dwGBitMask) <<
+ -gshift);
+ }
+ if (bshift >= 0) {
+ db = (byte) ((dmask & ddpf.dwBBitMask) >>
+ bshift);
+ } else {
+ db = (byte) ((dmask & ddpf.dwBBitMask) <<
+ -bshift);
+ }
+ a2 = 255 - a;
+ if (!ddpf.noAlpha) {
+ if (ashift >= 0) {
+ da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) >>
+ ashift);
+ } else {
+ da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) <<
+ -ashift);
+ }
+ a = (da * a2 + a * a)*inv;
+ }
+
+ g = (dg * a2 + g * a)*inv;
+ b = (db * a2 + b * a)*inv;
+ r = (dr * a2 + r * a)*inv;
+ }
+ if (rshift >= 0) {
+ mask = (r << rshift) & ddpf.dwRBitMask;
+ } else {
+ mask = (r >> -rshift) & ddpf.dwRBitMask;
+ }
+ if (gshift >= 0) {
+ mask |= (g << gshift) & ddpf.dwGBitMask;
+ } else {
+ mask |= (g >> -gshift) & ddpf.dwGBitMask;
+ }
+ if (bshift >= 0) {
+ mask |= (b << bshift) & ddpf.dwBBitMask;
+ } else {
+ mask |= (b >> -bshift) & ddpf.dwBBitMask;
+ }
+ if (!ddpf.noAlpha) {
+ if (ashift >= 0) {
+ mask |= (a << ashift) & ddpf.dwRGBAlphaBitMask;
+ } else {
+ mask |= (a >> -ashift) & ddpf.dwRGBAlphaBitMask;
+ }
+ }
+ *dst++ = (byte) (mask & 0xff);
+ } else {
+ dst++;
+ }
+ }
+ srcRow += srcPitch;
+ destRow += lockedRect.Pitch;
+ }
+ } else {
+ // should not happen, RGBBitCount > 32. Even DirectX
+ // RGB mask can't address it.
+ printf("Texture memory with RGBBitCount = %d not support. \n",
+ ddpf.dwRGBBitCount);
+ }
+ }
+
+ hr = surf->UnlockRect();
+ if (FAILED(hr)) {
+ printf("Fail to unlock rendering surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+}
+
+
+void copyDataToVolume(jint storedFormat,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint zoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint imgZOffset,
+ jint subWidth, jint subHeight, jint subDepth,
+ jint tilew, jint tileh,
+ jbyte* data,
+ LPDIRECT3DVOLUMETEXTURE8 surf,
+ jint level)
+{
+
+ D3DVOLUME_DESC ddsd;
+ D3DLOCKED_BOX lockedBox;
+ PIXELFORMAT ddpf;
+ HRESULT hr;
+ UINT i;
+
+ if (surf == NULL) {
+ return;
+ }
+ surf->GetLevelDesc(level, &ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ DWORD depth = ddsd.Depth;
+ computePixelFormat(&ddpf, ddsd.Format);
+
+ // It is possible when texture is not a power of 2 or
+ // square only texture is required in hardware. In these
+ // case the hardware memory buffer may smaller than the
+ // texture pass in.
+
+ if ((xoffset >= width) ||
+ (yoffset >= height) ||
+ (zoffset >= depth)) {
+ return;
+ }
+
+ DWORD xlimit = min(xoffset + subWidth, width);
+ DWORD ylimit = min(yoffset + subHeight, height);
+ DWORD zlimit = min(zoffset + subDepth, depth);
+
+ hr = surf->LockBox(level, &lockedBox, NULL, 0);
+
+
+ if (FAILED(hr)) {
+ printf("Fail to lock volume: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+ int imgOffset = tilew*(tileh*imgZOffset + imgYOffset) + imgXOffset;
+ int srcSlicePitch = tilew*tileh;
+ unsigned char* p = (unsigned char *) lockedBox.pBits +
+ zoffset*lockedBox.SlicePitch;
+
+
+
+ switch (storedFormat) {
+ case FORMAT_BYTE_RGBA :
+ // This is the one we use when byReference = false
+ data += (imgOffset << 2);
+ srcSlicePitch <<= 2;
+
+ for (i = zoffset; i < zlimit; i++) {
+ copyDataToSurfaceRGBA(internalFormat, &ddpf,
+ p,
+ lockedBox.RowPitch,
+ data,
+ xoffset, yoffset,
+ xlimit, ylimit,
+ tilew);
+ p += lockedBox.SlicePitch;
+ data += srcSlicePitch;
+ }
+
+ break;
+ case FORMAT_BYTE_RGB:
+ data += (imgOffset*3);
+ srcSlicePitch *= 3;
+
+ for (i = zoffset; i < zlimit; i++) {
+ copyDataToSurfaceRGB(internalFormat, &ddpf,
+ p,
+ lockedBox.RowPitch,
+ data,
+ xoffset, yoffset,
+ xlimit, ylimit,
+ tilew);
+ p += lockedBox.SlicePitch;
+ data += srcSlicePitch;
+ }
+ break;
+ case FORMAT_BYTE_ABGR:
+ data += (imgOffset << 2);
+ srcSlicePitch <<= 2;
+
+ for (i = zoffset; i < zlimit; i++) {
+ copyDataToSurfaceABGR(internalFormat, &ddpf,
+ p,
+ lockedBox.RowPitch,
+ data,
+ xoffset, yoffset,
+ xlimit, ylimit,
+ tilew);
+ p += lockedBox.SlicePitch;
+ data += srcSlicePitch;
+ }
+ break;
+ case FORMAT_BYTE_BGR:
+ data += (imgOffset*3);
+ srcSlicePitch *= 3;
+
+ for (i = zoffset; i < zlimit; i++) {
+ copyDataToSurfaceBGR(internalFormat, &ddpf,
+ p,
+ lockedBox.RowPitch,
+ data,
+ xoffset, yoffset,
+ xlimit, ylimit,
+ tilew);
+ p += lockedBox.SlicePitch;
+ data += srcSlicePitch;
+ }
+ break;
+ case FORMAT_BYTE_LA:
+ data += (imgOffset << 1);
+ srcSlicePitch <<= 1;
+
+ for (i = zoffset; i < zlimit; i++) {
+ copyDataToSurfaceLA(internalFormat, &ddpf,
+ p,
+ lockedBox.RowPitch,
+ data,
+ xoffset, yoffset,
+ xlimit, ylimit,
+ tilew);
+ p += lockedBox.SlicePitch;
+ data += srcSlicePitch;
+ }
+ break;
+ case FORMAT_BYTE_GRAY:
+ data += imgOffset;
+
+ for (i = zoffset; i < zlimit; i++) {
+ copyDataToSurfaceGray(internalFormat, &ddpf,
+ p,
+ lockedBox.RowPitch,
+ data,
+ xoffset, yoffset,
+ xlimit, ylimit,
+ tilew);
+ p += lockedBox.SlicePitch;
+ data += srcSlicePitch;
+ }
+ break;
+ default: // should not happen
+ printf("[Java 3D] StoredFormat %d, internalFormat %d not support !\n",
+ storedFormat, internalFormat);
+ }
+
+ hr = surf->UnlockBox(level);
+ if (FAILED(hr)) {
+ printf("Fail to unlock volume: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+}
+
+
+void copyDataToVolume(jint storedFormat,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint zoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint imgZOffset,
+ jint subWidth, jint subHeight, jint subDepth,
+ jint tilew, jint tileh,
+ jshort* data,
+ LPDIRECT3DVOLUMETEXTURE8 surf,
+ jint level)
+{
+ D3DVOLUME_DESC ddsd;
+ D3DLOCKED_BOX lockedBox;
+ PIXELFORMAT ddpf;
+ HRESULT hr;
+ UINT i;
+
+ if (surf == NULL) {
+ return;
+ }
+
+ surf->GetLevelDesc(level, &ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ DWORD depth = ddsd.Depth;
+
+ computePixelFormat(&ddpf, ddsd.Format);
+
+
+ if ((xoffset >= width) ||
+ (yoffset >= height) ||
+ (zoffset >= depth)) {
+ return;
+ }
+
+
+ DWORD xlimit = min(xoffset + subWidth, width);
+ DWORD ylimit = min(yoffset + subHeight, height);
+ DWORD zlimit = min(zoffset + subDepth, depth);
+
+ hr = surf->LockBox(level, &lockedBox, NULL, 0);
+
+ if (FAILED(hr)) {
+ printf("Fail to lock volume: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+ int imgOffset = tilew*(tileh*imgZOffset + imgYOffset) + imgXOffset;
+ int srcSlicePitch = (tilew*tileh) << 1;
+ unsigned char* p = (unsigned char *) lockedBox.pBits +
+ zoffset*lockedBox.SlicePitch;
+
+ data += (imgOffset << 1);
+
+ for (i = zoffset; i < zlimit; i++) {
+ copyDataToSurfaceGray(internalFormat, &ddpf,
+ p,
+ lockedBox.RowPitch,
+ data,
+ xoffset, yoffset,
+ xlimit, ylimit,
+ tilew);
+ p += lockedBox.SlicePitch;
+ data += srcSlicePitch;
+ }
+
+ hr = surf->UnlockBox(level);
+ if (FAILED(hr)) {
+ printf("Fail to unlock volume: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+}
+
+
+LPDIRECT3DTEXTURE8 createSurfaceFromImage(JNIEnv *env,
+ jobject pa2d,
+ jlong ctx,
+ int width,
+ int height,
+ jbyteArray imageYdown)
+{
+ GetDevice2();
+
+ int internalFormat;
+ jclass pa2d_class = env->GetObjectClass(pa2d);
+
+ jfieldID id = env->GetFieldID(pa2d_class, "storedYdownFormat", "I");
+ int storedFormat = env->GetIntField(pa2d, id);
+
+ id = env->GetFieldID(pa2d_class, "internalFormat", "I");
+ internalFormat = env->GetIntField(pa2d, id);
+
+
+ switch (internalFormat) {
+ case FORMAT_BYTE_RGBA:
+ internalFormat = J3D_RGBA;
+ break;
+ case FORMAT_BYTE_RGB:
+ internalFormat = J3D_RGB;
+ break;
+ case FORMAT_BYTE_LA:
+ internalFormat = LUMINANCE_ALPHA;
+ break;
+ case FORMAT_BYTE_GRAY:
+ case FORMAT_USHORT_GRAY:
+ internalFormat = LUMINANCE;
+ break;
+ default:
+ printf("Format %d not support for Image Component\n", internalFormat);
+ return NULL;
+ }
+
+
+ LPDIRECT3DTEXTURE8 surf;
+
+ surf = createTextureSurface(d3dCtx, 1, internalFormat,
+ width, height);
+
+ if (surf == NULL) {
+ return NULL;
+ }
+
+ if (imageYdown != NULL) {
+ if (storedFormat != FORMAT_USHORT_GRAY) {
+ jbyte *byteData = (jbyte *) (env->GetPrimitiveArrayCritical(
+ imageYdown, NULL));
+ copyDataToSurface(storedFormat, internalFormat, 0, 0, 0, 0,
+ width, height, width, byteData, surf, 0);
+ env->ReleasePrimitiveArrayCritical(imageYdown, byteData, 0);
+
+ } else {
+ jshort *shortData = (jshort *)(env->GetPrimitiveArrayCritical(
+ imageYdown, NULL));
+ copyDataToSurface(storedFormat, internalFormat, 0, 0, 0, 0,
+ width, height, width, shortData, surf, 0);
+ env->ReleasePrimitiveArrayCritical(imageYdown, shortData, 0);
+ }
+ }
+ return surf;
+}
+
+VOID createLineModeIndexBuffer(D3dCtx *d3dCtx)
+{
+ HRESULT hr;
+ WORD *wptr;
+
+ hr = d3dCtx->pDevice->CreateIndexBuffer(6*sizeof(WORD),
+ D3DUSAGE_WRITEONLY,
+ D3DFMT_INDEX16,
+ D3DPOOL_DEFAULT,
+ &d3dCtx->lineModeIndexBuffer);
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(CREATEINDEXVBFAIL, hr);
+ return;
+ }
+
+
+ hr = d3dCtx->lineModeIndexBuffer->Lock(0, 0, (BYTE **) &wptr, 0);
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKINDEXVBFAIL, hr);
+ return;
+ }
+
+ *wptr++ = 0;
+ *wptr++ = 1;
+ *wptr++ = 2;
+ *wptr++ = 3;
+ *wptr++ = 0;
+ *wptr = 0; // not used
+ d3dCtx->lineModeIndexBuffer->Unlock();
+}
+
+// Return TRUE if index is adjust smaller
+BOOL createQuadIndices(D3dCtx *d3dCtx, int vcount)
+{
+ DWORD dwIndexCount = (vcount*3) >> 1;
+ WORD *q;
+ LPDIRECT3DDEVICE8 device = d3dCtx->pDevice;
+ HRESULT hr;
+ BOOL adjustIdx = FALSE;
+
+ if (dwIndexCount > d3dCtx->deviceInfo->maxVertexIndex) {
+ // We'll render the VB multiple times in this case
+ dwIndexCount = min(d3dCtx->deviceInfo->maxVertexIndex,
+ (d3dCtx->deviceInfo->maxPrimitiveCount << 1));
+ adjustIdx = TRUE;
+ }
+
+ if (dwIndexCount > d3dCtx->quadIndexBufferSize) {
+ d3dCtx->freeResource(d3dCtx->quadIndexBuffer);
+ hr = device->CreateIndexBuffer(dwIndexCount*sizeof(WORD),
+ D3DUSAGE_WRITEONLY,
+ D3DFMT_INDEX16,
+ D3DPOOL_MANAGED,
+ &d3dCtx->quadIndexBuffer);
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(CREATEINDEXVBFAIL, hr);
+ d3dCtx->quadIndexBufferSize = 0;
+ d3dCtx->quadIndexBuffer = NULL;
+ if (d3dCtx->quadIndexBufferSize > 0) {
+ // indices has successfully set before, we prevent
+ // setting this when indices did not set before.
+ // It is becasue there is a bug in Nvidia driver which
+ // will crash in this case.
+ device->SetIndices(NULL, 0);
+ }
+ return adjustIdx;
+ }
+
+ d3dCtx->quadIndexBufferSize = dwIndexCount;
+ hr = d3dCtx->quadIndexBuffer->Lock(0, 0, (BYTE **) &q, 0);
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKINDEXVBFAIL, hr);
+ if (d3dCtx->quadIndexBufferSize > 0) {
+ device->SetIndices(NULL, 0);
+ }
+ return adjustIdx;
+ }
+ int i = -1;
+ int j = 0;
+
+ while (j < dwIndexCount) {
+ q[j++] = ++i; // q[0] = 0
+ q[j++] = i+1; // q[1] = 1
+ q[j++] = i+2; // q[2] = 2
+ q[j++] = i++; // q[3] = 0
+ q[j++] = ++i; // q[4] = 2
+ q[j++] = ++i; // q[5] = 3
+ }
+
+ d3dCtx->quadIndexBuffer->Unlock();
+ }
+
+ return adjustIdx;
+}
+
+
+int getPrimitiveNum(int primitive, int vcount)
+{
+ switch (primitive) {
+ case D3DPT_TRIANGLESTRIP:
+ return vcount-2;
+ case D3DPT_TRIANGLEFAN:
+ return vcount-2;
+ case D3DPT_LINESTRIP:
+ return vcount - 1;
+ case D3DPT_LINELIST:
+ return vcount >> 1;
+ case D3DPT_TRIANGLELIST:
+ return vcount/3;
+ case D3DPT_POINTLIST:
+ return vcount;
+ default: // should not happen
+ printf("[Java 3D] Unknown primitive type %d\n", primitive);
+ }
+ return 0;
+}
+
+
+/*
+ * Note that tThe condition width == height always holds
+ * when this function is invoked.
+ */
+LPDIRECT3DCUBETEXTURE8 createCubeMapTexture(D3dCtx *d3dCtx,
+ jint numLevels,
+ jint internalFormat,
+ jint width,
+ jint height)
+{
+ LPDIRECT3DCUBETEXTURE8 pTexture;
+ D3DFORMAT format;
+ HRESULT hr;
+
+ LPDIRECT3DDEVICE8 pDevice = d3dCtx->pDevice;
+ D3dDeviceInfo *deviceInfo = d3dCtx->deviceInfo;
+
+ if (!deviceInfo->supportMipmap) {
+ numLevels = 1;
+ }
+
+ getTexWidthHeight(deviceInfo, &width, &height);
+ format = getTexFormat(internalFormat);
+
+ // If format not support, the utility function will adjust the
+ // calling parameters automatically
+ hr = D3DXCreateCubeTexture(d3dCtx->pDevice, width,
+ numLevels, 0, format, D3DPOOL_MANAGED,
+ &pTexture);
+
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("Fail to create cube texture surface %dx%d, format %d, level %d : %s\n",
+ width, height, format, numLevels, DXGetErrorString8(hr));
+ }
+ return NULL;
+ }
+
+ return pTexture;
+}
+
+
+void copyDataToCubeMap(jint storedFormat,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint subWidth, jint subHeight,
+ jint tilew,
+ jshort *data, LPDIRECT3DCUBETEXTURE8 surf,
+ jint level,
+ jint face)
+{
+ D3DSURFACE_DESC ddsd;
+ D3DLOCKED_RECT lockedRect;
+ PIXELFORMAT ddpf;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+
+ surf->GetLevelDesc(level, &ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computePixelFormat(&ddpf, ddsd.Format);
+
+ if ((xoffset >= width) || (yoffset >= height)) {
+ return;
+ }
+ DWORD xlimit = min(xoffset + subWidth, width);
+ DWORD ylimit = min(yoffset + subHeight, height);
+
+ hr = surf->LockRect(textureCubeMapFace[face], level,
+ &lockedRect, NULL, 0);
+
+ if (FAILED(hr)) {
+ printf("Fail to lock surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+ int offset = tilew*imgYOffset + imgXOffset;
+
+ if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) ||
+ (face == D3DCUBEMAP_FACE_POSITIVE_Y)) {
+ copyDataToSurfaceGray(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data +
+ ((offset+tilew*(ylimit-yoffset)) << 1),
+ xoffset, yoffset,
+ xlimit, ylimit, -tilew);
+ } else {
+ copyDataToSurfaceGrayRev(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + (offset << 1),
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ }
+
+ hr = surf->UnlockRect(textureCubeMapFace[face], level);
+ if (FAILED(hr)) {
+ printf("Fail to unlock surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+}
+
+
+void copyDataToCubeMap(jint storedFormat,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint subWidth, jint subHeight,
+ jint tilew,
+ jbyte* data,
+ LPDIRECT3DCUBETEXTURE8 surf,
+ jint level,
+ jint face)
+{
+ D3DSURFACE_DESC ddsd;
+ D3DLOCKED_RECT lockedRect;
+ PIXELFORMAT ddpf;
+ HRESULT hr;
+
+ if (surf == NULL) {
+ return;
+ }
+ surf->GetLevelDesc(level, &ddsd);
+ DWORD width = ddsd.Width;
+ DWORD height = ddsd.Height;
+ computePixelFormat(&ddpf, ddsd.Format);
+
+ // It is possible when texture is not a power of 2 or
+ // square only texture is required in hardware. In these
+ // case the hardware memory buffer may smaller than the
+ // texture pass in.
+
+ if ((xoffset >= width) || (yoffset >= height)) {
+ return;
+ }
+
+ DWORD xlimit = min(xoffset + subWidth, width);
+ DWORD ylimit = min(yoffset + subHeight, height);
+
+ hr = surf->LockRect(textureCubeMapFace[face],
+ level, &lockedRect, NULL, 0);
+
+
+ if (FAILED(hr)) {
+ printf("Fail to lock surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+ int offset = tilew*imgYOffset + imgXOffset;
+
+ switch (storedFormat) {
+ case FORMAT_BYTE_RGBA :
+ // This is the one we use when byReference = false
+ if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) ||
+ (face == D3DCUBEMAP_FACE_POSITIVE_Y)) {
+ // Copy the pixel from bottom to up and
+ // left to right in this case to match OGL definition
+ copyDataToSurfaceRGBA(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data +
+ ((offset + tilew*(ylimit-yoffset-1)) << 2),
+ xoffset, yoffset,
+ xlimit, ylimit, -tilew);
+ } else {
+ // Copy the pixel from up to bottom and
+ // right to left in this case to match OGL definition
+ copyDataToSurfaceRGBARev(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + (offset << 2),
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ }
+ break;
+ case FORMAT_BYTE_RGB:
+ if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) ||
+ (face == D3DCUBEMAP_FACE_POSITIVE_Y)) {
+ copyDataToSurfaceRGB(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data +
+ 3*(offset + tilew*(ylimit-yoffset-1)),
+ xoffset, yoffset,
+ xlimit, ylimit, -tilew);
+ } else {
+ copyDataToSurfaceRGBRev(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + 3*offset,
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ }
+ break;
+ case FORMAT_BYTE_ABGR:
+ if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) ||
+ (face == D3DCUBEMAP_FACE_POSITIVE_Y)) {
+ copyDataToSurfaceABGR(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data +
+ ((offset+tilew*(ylimit-yoffset-1)) << 2),
+ xoffset, yoffset,
+ xlimit, ylimit, -tilew);
+ } else {
+ copyDataToSurfaceABGRRev(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + (offset << 2),
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ }
+ break;
+ case FORMAT_BYTE_BGR:
+ if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) ||
+ (face == D3DCUBEMAP_FACE_POSITIVE_Y)) {
+ copyDataToSurfaceBGR(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data +
+ 3*(offset + tilew*(ylimit-yoffset-1)),
+ xoffset, yoffset,
+ xlimit, ylimit, -tilew);
+ } else {
+ copyDataToSurfaceBGRRev(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + 3*offset,
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ }
+ break;
+ case FORMAT_BYTE_LA:
+ if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) ||
+ (face == D3DCUBEMAP_FACE_POSITIVE_Y)) {
+ copyDataToSurfaceLA(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data +
+ ((offset+tilew*(ylimit-yoffset-1)) << 1),
+ xoffset, yoffset,
+ xlimit, ylimit, -tilew);
+ } else {
+ copyDataToSurfaceLARev(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + (offset << 1),
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ }
+ break;
+ case FORMAT_BYTE_GRAY:
+ if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) ||
+ (face == D3DCUBEMAP_FACE_POSITIVE_Y)) {
+ copyDataToSurfaceGray(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data +
+ offset + tilew*(ylimit-yoffset-1),
+ xoffset, yoffset,
+ xlimit, ylimit, -tilew);
+ } else {
+ copyDataToSurfaceGrayRev(internalFormat, &ddpf,
+ (unsigned char *) lockedRect.pBits,
+ lockedRect.Pitch,
+ data + offset,
+ xoffset, yoffset,
+ xlimit, ylimit, tilew);
+ }
+ break;
+ default: // should not happen
+ printf("[Java 3D] StoredFormat %d, internalFormat %d not support !\n",
+ storedFormat, internalFormat);
+ }
+
+ hr = surf->UnlockRect(textureCubeMapFace[face], level);
+ if (FAILED(hr)) {
+ printf("Fail to unlock surface: %s\n", DXGetErrorString8(hr));
+ return;
+ }
+}
+
+
+void drawTextureRect(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ LPDIRECT3DTEXTURE8 surf,
+ D3DTLVERTEX screenCoord,
+ int startx, int starty,
+ int endx, int endy,
+ int scaleWidth, int scaleHeight,
+ boolean texModeRepeat)
+{
+ LPDIRECT3DTEXTURE8 texture = NULL;
+ DWORD transflag, minstate, magstate, texcoordstate;
+ DWORD wrapU, wrapV;
+ DWORD colorOp, colorArg, alphaOp, alphaArg;
+ D3DMATRIX m;
+
+ int h = endy - starty;
+ int w = endx - startx;
+
+ device->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
+
+ device->GetTexture(0, (LPDIRECT3DBASETEXTURE8 *) &texture);
+
+ device->GetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS,
+ &transflag);
+ if (transflag != D3DTTFF_DISABLE) {
+ device->GetTransform(D3DTS_TEXTURE0, &m);
+ }
+
+ device->GetTextureStageState(0, D3DTSS_MINFILTER, &minstate);
+ device->GetTextureStageState(0, D3DTSS_MAGFILTER, &magstate);
+ device->GetTextureStageState(0, D3DTSS_TEXCOORDINDEX, &texcoordstate);
+ device->SetTexture(0, surf);
+ device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS,
+ D3DTTFF_DISABLE);
+
+ if ((w == scaleWidth) && (h == scaleHeight)) {
+ device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT);
+ device->SetTextureStageState(0, D3DTSS_MAGFILTER,
+ D3DTEXF_POINT);
+ } else {
+ device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
+ device->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
+ }
+ device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
+ device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+
+ device->GetTextureStageState(0, D3DTSS_COLOROP, &colorOp);
+ device->GetTextureStageState(0, D3DTSS_COLORARG1, &colorArg);
+ device->GetTextureStageState(0, D3DTSS_ALPHAOP, &alphaOp);
+ device->GetTextureStageState(0, D3DTSS_ALPHAARG1, &alphaArg);
+
+ device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ if (d3dCtx->fillMode != D3DFILL_SOLID) {
+ device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ }
+
+ D3DSURFACE_DESC ddsd;
+ surf->GetLevelDesc(0, &ddsd);
+
+
+ float tumax;
+ float tvmax;
+ float tumin = startx/(float) ddsd.Width;
+ float tvmin = starty/(float) ddsd.Height;
+ boolean multipleDraw;
+
+ if (texModeRepeat) {
+ if ((w == ddsd.Width) && (h == ddsd.Height)) {
+ // width & height match texture, so there is
+ // no need to draw multiple time
+ tumax = scaleWidth/(float) ddsd.Width;
+ tvmax = scaleHeight/(float) ddsd.Height;
+ device->GetTextureStageState(0, D3DTSS_ADDRESSU, &wrapU);
+ device->GetTextureStageState(0, D3DTSS_ADDRESSV, &wrapV);
+ device->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
+ device->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
+ multipleDraw = false;
+ } else {
+ tumax = endx/(float) ddsd.Width;
+ tvmax = endy/(float) ddsd.Height;
+ multipleDraw = true;
+ }
+ } else {
+ tumax = endx/(float) ddsd.Width;
+ tvmax = endy/(float) ddsd.Height;
+ multipleDraw = false;
+ }
+
+
+ d3dCtx->rasterRect[0].tu = tumin;
+ d3dCtx->rasterRect[0].tv = tvmax;
+ d3dCtx->rasterRect[1].tu = tumin;
+ d3dCtx->rasterRect[1].tv = tvmin;
+ d3dCtx->rasterRect[2].tu = tumax;
+ d3dCtx->rasterRect[2].tv = tvmax;
+ d3dCtx->rasterRect[3].tu = tumax;
+ d3dCtx->rasterRect[3].tv = tvmin;
+
+ d3dCtx->rasterRect[0].sx = screenCoord.sx;
+ d3dCtx->rasterRect[0].sz = screenCoord.sz;
+ d3dCtx->rasterRect[0].rhw = screenCoord.rhw;
+
+ d3dCtx->rasterRect[1].sx = screenCoord.sx;
+ d3dCtx->rasterRect[1].sy = screenCoord.sy;
+ d3dCtx->rasterRect[1].sz = screenCoord.sz;
+ d3dCtx->rasterRect[1].rhw = screenCoord.rhw;
+
+ d3dCtx->rasterRect[2].sz = screenCoord.sz;
+ d3dCtx->rasterRect[2].rhw = screenCoord.rhw;
+
+ d3dCtx->rasterRect[3].sy = screenCoord.sy;
+ d3dCtx->rasterRect[3].sz = screenCoord.sz;
+ d3dCtx->rasterRect[3].rhw = screenCoord.rhw;
+
+ if ((h > 0) && (w > 0)) {
+ device->SetVertexShader(D3DFVF_XYZRHW|D3DFVF_TEX1);
+ if (!multipleDraw) {
+ d3dCtx->rasterRect[0].sy = screenCoord.sy + scaleHeight;
+ d3dCtx->rasterRect[2].sx = screenCoord.sx + scaleWidth;
+ d3dCtx->rasterRect[2].sy = screenCoord.sy + scaleHeight;
+ d3dCtx->rasterRect[3].sx = screenCoord.sx + scaleWidth;
+ device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,
+ 2,
+ d3dCtx->rasterRect,
+ sizeof(D3DTLVERTEX));
+ } else {
+ d3dCtx->rasterRect[0].sy = screenCoord.sy + h;
+ d3dCtx->rasterRect[2].sx = screenCoord.sx + w;
+ d3dCtx->rasterRect[2].sy = screenCoord.sy + h;
+ d3dCtx->rasterRect[3].sx = screenCoord.sx + w;
+ for (int i=0; i < ceil(scaleHeight/((double) h)); i++) {
+ for (int j=0; j < ceil(scaleWidth/((double) w)); j++) {
+ device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,
+ 2,
+ d3dCtx->rasterRect,
+ sizeof(D3DTLVERTEX));
+ d3dCtx->rasterRect[0].sx += w;
+ d3dCtx->rasterRect[1].sx += w;
+ d3dCtx->rasterRect[2].sx += w;
+ d3dCtx->rasterRect[3].sx += w;
+ }
+ d3dCtx->rasterRect[0].sx = screenCoord.sx;
+ d3dCtx->rasterRect[1].sx = screenCoord.sx;
+ d3dCtx->rasterRect[2].sx = screenCoord.sx + w;
+ d3dCtx->rasterRect[3].sx = screenCoord.sx + w;
+ d3dCtx->rasterRect[0].sy += h;
+ d3dCtx->rasterRect[1].sy += h;
+ d3dCtx->rasterRect[2].sy += h;
+ d3dCtx->rasterRect[3].sy += h;
+ }
+
+ }
+ }
+
+ // restore original texture stage values
+ if (texture != NULL) {
+ device->SetTexture(0, texture);
+ texture->Release();
+ } else {
+ device->SetTexture(0, NULL);
+ }
+
+ device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS,
+ transflag);
+ if (transflag != D3DTTFF_DISABLE) {
+ device->SetTransform(D3DTS_TEXTURE0, &m);
+ }
+ if (d3dCtx->fillMode != D3DFILL_SOLID) {
+ device->SetRenderState(D3DRS_FILLMODE, d3dCtx->fillMode);
+ }
+ device->SetTextureStageState(0, D3DTSS_MINFILTER, minstate);
+ device->SetTextureStageState(0, D3DTSS_MAGFILTER, magstate);
+ device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, texcoordstate);
+
+ device->SetTextureStageState(0, D3DTSS_COLOROP, colorOp);
+ device->SetTextureStageState(0, D3DTSS_COLORARG1, colorArg);
+ device->SetTextureStageState(0, D3DTSS_ALPHAOP, alphaOp);
+ device->SetTextureStageState(0, D3DTSS_ALPHAARG1, alphaArg);
+
+ if (texModeRepeat && !multipleDraw) {
+ device->SetTextureStageState(0, D3DTSS_ADDRESSU, wrapU);
+ device->SetTextureStageState(0, D3DTSS_ADDRESSV, wrapV);
+ }
+ device->SetRenderState(D3DRS_CULLMODE, d3dCtx->cullMode);
+ device->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
+}
diff --git a/src/native/d3d/D3dUtil.hpp b/src/native/d3d/D3dUtil.hpp
new file mode 100644
index 0000000..1e09d6e
--- /dev/null
+++ b/src/native/d3d/D3dUtil.hpp
@@ -0,0 +1,310 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#if !defined(D3DUTIL_H)
+#define D3DUTIL_H
+
+#include "StdAfx.h"
+
+
+// Index to D3dErrorMessage
+#define DRIVERNOTFOUND 0
+#define CANNOTRENDERWINDOW 1
+#define D3DNOTFOUND 2
+#define CARDNOTSUPPORT 3
+#define NEEDSWITCHMODE 4
+#define DEVICENOTFOUND 5
+#define CREATEDEVICEFAIL 6
+#define CREATEREFDEVICEFAIL 7
+#define VIEWPORTFAIL 8
+#define GETBACKBUFFERFAIL 9
+#define COLORMODENOTSUPPORT 10
+#define OUTOFMEMORY 11
+#define UNKNOWNDEVICE 12
+#define HALDEVICENOTFOUND 13
+#define TNLHALDEVICENOTFOUND 14
+#define NOSTENCILBUFFER 15
+#define NOTEXTUREMEMORY 16
+#define OFFSCREENCREATEFAIL 17
+#define CREATEVERTEXBUFFER 18
+#define RESETFAIL 19
+#define HALNOTCOMPATIBLE 20
+#define DEPTHSTENCILNOTFOUND 21
+#define LOCKVBFAIL 22
+#define CREATEVBFAIL 23
+#define CREATEINDEXVBFAIL 24
+#define LOCKINDEXVBFAIL 25
+
+#define PI 3.14159265f
+
+// Same definition as in ImageComponent2DRetained
+#define CLEAN 0
+#define MODIFY 1
+#define NOTLIVE 2
+
+// If we want to synchrinized draw primitive, change the
+// following to D3DDP_WAIT
+#define DEFAULTMODE 0
+
+#define D3D_STEREO 1
+
+
+// Macro
+#define SafeRelease(p) if(p) {p->Release(); p = NULL;}
+#define SafeDelete(p) if(p) { delete p; p = NULL;}
+#define SafeFree(p) if(p) { free(p); p = NULL;}
+
+#define GetCtx() \
+ if (ctx == 0) return; \
+ D3dCtx *d3dCtx = reinterpret_cast<D3dCtx*>(ctx); \
+
+
+#define GetDevice() \
+ GetCtx() \
+ LPDIRECT3DDEVICE8 device = d3dCtx->pDevice; \
+ if (device == NULL) return;
+
+#define GetCtx2() \
+ if (ctx == 0) return 0;\
+ D3dCtx *d3dCtx = reinterpret_cast<D3dCtx*>(ctx); \
+
+
+#define GetDevice2() \
+ GetCtx2(); \
+ LPDIRECT3DDEVICE8 device = d3dCtx->pDevice; \
+ if (device == NULL) return 0;
+
+#define CopyColor(c, red, green, blue, alpha) \
+ (c).a = alpha; (c).r = red; (c).g = green; (c).b = blue;
+
+
+#define CopyTranspose(m, s) { \
+ (m)._11 = (s)[0]; (m)._12 = (s)[4]; (m)._13 = (s)[8]; (m)._14 = (s)[12]; \
+ (m)._21 = (s)[1]; (m)._22 = (s)[5]; (m)._23 = (s)[9]; (m)._24 = (s)[13]; \
+ (m)._31 = (s)[2]; (m)._32 = (s)[6]; (m)._33 = (s)[10]; (m)._34 = (s)[14]; \
+ (m)._41 = (s)[3]; (m)._42 = (s)[7]; (m)._43 = (s)[11]; (m)._44 = (s)[15]; }
+
+// Note that v should not be one of the reference in m
+#define MultiplyScaler(m, v) { \
+ (m)._11 *= v; (m)._12 *= v; (m)._13 *= v; (m)._14 *= v; \
+ (m)._21 *= v; (m)._22 *= v; (m)._23 *= v; (m)._24 *= v; \
+ (m)._31 *= v; (m)._32 *= v; (m)._33 *= v; (m)._34 *= v; \
+ (m)._41 *= v; (m)._42 *= v; (m)._43 *= v; (m)._44 *= v; }
+
+#define Clamp(c) \
+ if (c > 1.0f) { \
+ c = 1.0f; \
+ } else if (c < 0.0f) { \
+ c = 0.0f; \
+ }
+
+#define Magitude(x, y, z, w) sqrt((x)*(x) + (y)*(y) + (z)*(z) + (w)*(w));
+
+#define NORMALIZE(x, y, z, w) { \
+ float d; \
+ d = Magitude(x, y, z, w); \
+ (x) /= d; (y) /= d; (z) /= d; (w) /= d; }
+
+extern vector<void *> freePointerList0;
+extern vector<void *> freePointerList1;
+extern BOOL useFreePointerList0;
+
+extern HANDLE hSema; // handle to semaphore
+extern BOOL firstError;
+extern BOOL debug;
+
+// use for VertexBuffer
+extern OSVERSIONINFO osvi; // OS info
+
+extern D3dCtx* findCtx(HWND hwnd);
+extern VOID lock();
+extern VOID unlock();
+extern VOID lockImage();
+extern VOID unlockImage();
+extern VOID lockBackground();
+extern VOID unlockBackground();
+extern VOID lockGeometry();
+extern VOID unlockGeometry();
+extern VOID lockSurfaceList();
+extern VOID unlockSurfaceList();
+extern VOID freeSurface(LPDIRECT3DBASETEXTURE8 surf);
+extern VOID freePointer(void* surf);
+extern VOID freePointerList();
+extern VOID setWindowCallback(HWND topHwnd, HWND hwnd);
+extern char* getErrorMessage(int idx);
+extern HWND getTopWindow(HWND hwnd);
+
+extern LPDIRECT3DTEXTURE8 createTextureSurface(D3dCtx *d3dCtx,
+ jint numLevels,
+ jint internalFormat,
+ jint width,
+ jint height);
+
+
+extern LPDIRECT3DVOLUMETEXTURE8 createVolumeTexture(D3dCtx *d3dCtx,
+ jint numLevels,
+ jint internalFormat,
+ jint width,
+ jint height,
+ jint depth);
+
+
+extern LPDIRECT3DCUBETEXTURE8 createCubeMapTexture(D3dCtx *d3dCtx,
+ jint numLevels,
+ jint internalFormat,
+ jint width,
+ jint height);
+
+
+extern void copyDataToSurface(jint format,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint width, jint height, jint tilew,
+ jshort *data, LPDIRECT3DTEXTURE8 surf,
+ jint level);
+
+extern void copyDataToSurface(jint format,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint width, jint height, jint tilew,
+ jbyte* data,
+ LPDIRECT3DTEXTURE8 surf,
+ jint level);
+
+extern void copyDataToVolume(jint format,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint zoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint imgZOffset,
+ jint width, jint height, jint depth,
+ jint tilew, jint tileh,
+ jshort *data, LPDIRECT3DVOLUMETEXTURE8 surf,
+ jint level);
+
+
+extern void copyDataToVolume(jint format,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint zoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint imgZOffset,
+ jint width, jint height, jint depth,
+ jint tilew, jint tileh,
+ jbyte* data,
+ LPDIRECT3DVOLUMETEXTURE8 surf,
+ jint level);
+
+extern void copyDataToCubeMap(jint format,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint width, jint height,
+ jint tilew,
+ jshort *data, LPDIRECT3DCUBETEXTURE8 surf,
+ jint level,
+ jint face);
+
+
+extern void copyDataToCubeMap(jint format,
+ jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint imgXOffset, jint imgYOffset,
+ jint width, jint height,
+ jint tilew,
+ jbyte* data,
+ LPDIRECT3DCUBETEXTURE8 surf,
+ jint level,
+ jint face);
+
+
+extern void copyDepthFromSurface(jint xoffset, jint yoffset,
+ jint subWidth, jint subHeight,
+ jint *data,
+ LPDIRECT3DSURFACE8 surf);
+
+extern void copyDepthFromSurface(jint xoffset, jint yoffset,
+ jint subWidth, jint subHeight,
+ jfloat *data,
+ LPDIRECT3DSURFACE8 surf);
+
+extern void copyDepthToSurface(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ jint dst_xoffset, jint dst_yoffset,
+ jint src_xoffset, jint src_yoffset,
+ jint subWidth, jint subHeight,
+ jint src_width, jint src_height,
+ jint *data,
+ LPDIRECT3DSURFACE8 surf);
+
+extern void copyDepthToSurface(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ jint dst_xoffset, jint dst_yoffset,
+ jint src_xoffset, jint src_yoffset,
+ jint subWidth, jint subHeight,
+ jint src_width, jint src_height,
+ jfloat *data,
+ LPDIRECT3DSURFACE8 surf);
+
+extern void copyDataFromSurface(jint internalFormat,
+ jint xoffset, jint yoffset,
+ jint width, jint height,
+ jbyte *data, LPDIRECT3DSURFACE8 surf);
+
+void compositeDataToSurface(jint px, jint py,
+ jint xoffset, jint yoffset,
+ jint subWidth, jint subHeight,
+ jint dataWidth,
+ jbyte *data,
+ LPDIRECT3DSURFACE8 surf);
+
+// extern BOOL isIdentity(jdouble *matrix);
+
+extern void CopyTextureStage(LPDIRECT3DDEVICE8 device,
+ int fromLevel, int toLevel);
+
+
+extern LPDIRECT3DTEXTURE8 createSurfaceFromImage(JNIEnv *env,
+ jobject pa2d,
+ jlong ctx,
+ int width,
+ int height,
+ jbyteArray pixels);
+extern "C"
+DWORD countBits(DWORD mask); // Define in MasterControl.c
+
+extern BOOL createQuadIndices(D3dCtx *d3dCtx, int vcount);
+extern VOID createLineModeIndexBuffer(D3dCtx *d3dCtx);
+extern char *getPixelFormatName(D3DFORMAT format);
+extern char *getMultiSampleName(D3DMULTISAMPLE_TYPE mtype);
+extern char *getSwapEffectName(D3DSWAPEFFECT swapEffect);
+extern int getPrimitiveNum(int primitive, int vcount);
+extern int getMaxNumVertex(int primitive, int vcount);
+extern void drawTextureRect(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ LPDIRECT3DTEXTURE8 tex,
+ D3DTLVERTEX screenCoord,
+ int startx, int starty,
+ int endx, int endy,
+ int scaleWidth, int scaleHeight,
+ boolean texModeRepeat);
+extern int setTextureStage(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ int mapTexStage,
+ jint texStage);
+extern void setTexTransformStageFlag(D3dCtx* d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ int tus, int ts, int genMode);
+#endif
+
diff --git a/src/native/d3d/D3dVertexBuffer.cpp b/src/native/d3d/D3dVertexBuffer.cpp
new file mode 100644
index 0000000..e3cb8d1
--- /dev/null
+++ b/src/native/d3d/D3dVertexBuffer.cpp
@@ -0,0 +1,259 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+#include "D3dVertexBuffer.hpp"
+
+
+D3dVertexBuffer::D3dVertexBuffer()
+{
+ buffer = NULL;
+ indexBuffer = NULL;
+ numVertices = NULL;
+ numVerticesLen = 0;
+ isIndexPrimitive = FALSE;
+ nextVB = NULL;
+ stripLen = 0;
+ totalVertexCount = 0;
+ ctx = NULL;
+ next = NULL;
+ previous = NULL;
+ isPointFlagUsed = FALSE;
+ primitiveType = D3DPT_FORCE_DWORD;
+}
+
+D3dVertexBuffer::~D3dVertexBuffer()
+{
+ release();
+}
+
+VOID D3dVertexBuffer::release()
+{
+ SafeRelease(buffer);
+ SafeRelease(indexBuffer);
+ SafeDelete(numVertices);
+
+ numVerticesLen = 0;
+ isIndexPrimitive = FALSE;
+ isPointFlagUsed = FALSE;
+ stripLen = 0;
+ totalVertexCount = 0;
+ // recursively free the list
+ SafeDelete(nextVB);
+}
+
+
+
+VOID D3dVertexBuffer::render(D3dCtx *d3dCtx)
+{
+ D3DPRIMITIVETYPE oldPrimitiveType;
+ BOOL renderPoint = false;
+ BOOL restorePointSize = false;
+ float oldPointSize = 1.0f;
+
+ if ((buffer != NULL) && (numVertices != NULL)) {
+ // device is already check for NULL in callDisplayList
+ LPDIRECT3DDEVICE8 device = d3dCtx->pDevice;
+ BOOL setAmbientLight = false;
+
+ if (((vertexFormat & D3DFVF_DIFFUSE) == 0) &&
+ (!d3dCtx->isLightEnable)) {
+ setAmbientLight = true;
+ if (totalVertexCount > 0) {
+ // This is the first Node in the list
+ d3dCtx->setAmbientLightMaterial();
+ }
+ }
+
+ if ((d3dCtx->pointSize > 1) &&
+ ((d3dCtx->fillMode == D3DFILL_POINT) ||
+ (primitiveType == D3DPT_POINTLIST))) {
+ // Some driver may cull the point away if not
+ // set to CULL_NONE
+ if (!isPointFlagUsed) {
+ // restore point size to 1
+ if (debug) {
+ printf("VB render with pointSize %d without D3DPOINT flag set\n", d3dCtx->pointSize);
+ }
+ device->SetRenderState(D3DRS_POINTSIZE, *((LPDWORD)
+ &oldPointSize));
+ restorePointSize = true;
+ } else {
+ device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ // workaround for driver bug, otherwise you will
+ // see four corner points instead of one big point
+ // if fill mode is POINT
+ device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ if (d3dCtx->deviceInfo->maxPointSize < d3dCtx->pointSize) {
+ // Use software vertex processing mode
+ device->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING,
+ TRUE);
+ }
+ oldPrimitiveType = primitiveType;
+ // For Polygon D3DFill_POINT mode we need to
+ // temporary switch primitive to point list
+ primitiveType = D3DPT_POINTLIST;
+ renderPoint = true;
+ }
+ }
+
+ device->SetStreamSource(0, buffer, stride);
+ device->SetVertexShader(vertexFormat);
+
+ int startIdx=0;
+ int vc, i;
+
+ if (!isIndexPrimitive ||
+ ((indexBuffer == NULL) && renderPoint)) {
+ for (i = 0; i < stripLen; i++) {
+ vc = numVertices[i];
+ device->DrawPrimitive(primitiveType,
+ startIdx,
+ getPrimitiveNum(primitiveType,vc));
+ startIdx += vc;
+ }
+ } else {
+ if (indexBuffer != NULL) {
+ device->SetIndices(indexBuffer, 0);
+ for (i = 0; i < stripLen; i++) {
+ vc = numVertices[i];
+ device->DrawIndexedPrimitive(primitiveType,
+ 0,
+ vcount,
+ startIdx,
+ getPrimitiveNum(primitiveType, vc));
+ startIdx += vc;
+ }
+ } else {
+ if (d3dCtx->quadIndexBufferSize > 0) {
+ // Index is successfully set
+ device->SetIndices(d3dCtx->quadIndexBuffer, 0);
+ device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
+ 0,
+ numVertices[0],
+ 0,
+ numVertices[0] >> 1);
+ }
+ // Otherwise not enough memory when index buffer
+ // is created, so draw nothing.
+ }
+ }
+
+ if (setAmbientLight && (nextVB == NULL)) {
+ // This is the last Node in the list
+ d3dCtx->restoreDefaultLightMaterial();
+ }
+
+ if (renderPoint) {
+ device->SetRenderState(D3DRS_CULLMODE, d3dCtx->cullMode);
+ device->SetRenderState(D3DRS_FILLMODE, d3dCtx->fillMode);
+ device->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING,
+ d3dCtx->softwareVertexProcessing);
+ primitiveType = oldPrimitiveType;
+ } else if (restorePointSize) {
+ device->SetRenderState(D3DRS_POINTSIZE,
+ *((LPDWORD) &d3dCtx->pointSize));
+ }
+ }
+
+ if (nextVB != NULL) {
+ nextVB->render(d3dCtx);
+ }
+}
+
+
+VOID D3dVertexBuffer::addStride(int len)
+{
+ if (numVerticesLen <= stripLen) {
+ if (numVerticesLen == 0) {
+ numVertices = new USHORT[1];
+ if (numVertices == NULL) {
+ D3dCtx::d3dWarning(OUTOFMEMORY);
+ return;
+ }
+ numVerticesLen = 1;
+ } else {
+ int size = numVerticesLen << 1;
+ USHORT *p = new USHORT[size];
+ if (p == NULL) {
+ D3dCtx::d3dWarning(OUTOFMEMORY);
+ return;
+ }
+ CopyMemory(p, numVertices, numVerticesLen*sizeof(USHORT));
+ delete numVertices;
+ numVertices = p;
+ numVerticesLen = size;
+ }
+ }
+ numVertices[stripLen++] = len;
+}
+
+
+/*
+ * This is used by Strip GeometryArray
+ * Replace all previously define stripLen by this one.
+ */
+VOID D3dVertexBuffer::addStrides(jint len, jint* strips)
+{
+ int i = len;
+
+ if (numVerticesLen < len) {
+ if (numVertices) {
+ delete numVertices;
+ }
+ numVertices = new USHORT[len];
+ numVerticesLen = len;
+ }
+
+ USHORT *q = numVertices;
+
+ while (--i >= 0) {
+ *q++ = *strips++;
+ }
+ stripLen = len;
+}
+
+
+/*
+ * This is used by D3dDisplayList optimize()
+ * Append this one to the current strip define.
+ */
+VOID D3dVertexBuffer::appendStrides(jint len, USHORT* strips)
+{
+ int i;
+ USHORT *oldVertices;
+
+ if (numVerticesLen < stripLen + len) {
+ oldVertices = numVertices;
+ numVertices = new USHORT[len + stripLen];
+ numVerticesLen = len + stripLen;
+ }
+
+ USHORT *q = numVertices;
+ USHORT *p = oldVertices;
+
+ if (oldVertices != NULL) {
+ i = stripLen;
+ while (--i >= 0) {
+ *q++ = *p++;
+ }
+ delete oldVertices;
+ }
+
+ i = len;
+ while (--i >= 0) {
+ *q++ = *strips++;
+ }
+
+ stripLen = numVerticesLen;
+}
+
diff --git a/src/native/d3d/D3dVertexBuffer.hpp b/src/native/d3d/D3dVertexBuffer.hpp
new file mode 100644
index 0000000..e5633fa
--- /dev/null
+++ b/src/native/d3d/D3dVertexBuffer.hpp
@@ -0,0 +1,127 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#if !defined(D3DVERTEXBUFFER_H)
+#define D3DVERTEXBUFFER_H
+
+#include "StdAfx.h"
+
+class D3dCtx;
+
+class D3dVertexBuffer;
+
+typedef D3dVertexBuffer* LPD3DVERTEXBUFFER;
+typedef vector<LPD3DVERTEXBUFFER> D3dVertexBufferVector;
+
+
+class D3dVertexBuffer {
+public:
+
+ // Actual buffer memory to hold all the vertices
+ LPDIRECT3DVERTEXBUFFER8 buffer;
+
+ // Indexed buffer for rendering IndexedGeometry
+ LPDIRECT3DINDEXBUFFER8 indexBuffer;
+
+ // D3D type of this Vertex Buffer
+ D3DPRIMITIVETYPE primitiveType;
+
+ // Length of following numVertices array allocate
+ UINT numVerticesLen;
+
+ // Store the number of vertices for each strip
+ USHORT *numVertices;
+
+ // It true when QuadArray is used or
+ // indexGeometry is used.
+ BOOL isIndexPrimitive;
+
+ // If D3DUSAGE_POINTS flag is used to
+ // create this VertexBuffer
+ BOOL isPointFlagUsed;
+
+ // Flexible vertex format for this VB
+ DWORD vertexFormat;
+
+ // Stride of each vertex in the buffer
+ // compute from above vertexFormat
+ UINT stride;
+
+ // Number of strips used for StripGeometryArray
+ // For each strip i the number of vertex is
+ // numVertices[i]
+ UINT stripLen;
+
+ // Point to next overflow VB when size > VB limit
+ LPD3DVERTEXBUFFER nextVB;
+
+ // content that this buffer belongs, only the first node set this one.
+ D3dCtx *ctx;
+
+ // vcount is the number of vertex that this buffer
+ // can hold. vcount*stride is always equal to
+ // current VB size
+ UINT vcount;
+
+ // indexCount is the number of index that this buffer
+ // can hold. indexCount*indexSize is always equal to
+ // current index VB size.
+ UINT indexCount;
+
+ // Vertex count of all VBs link by nextVB,
+ // only the first node need to remember this info.
+ // The other overflow buffer always set it to zero.
+ DWORD totalVertexCount;
+
+ // Same as above, except for indexBuffer
+ DWORD totalIndexCount;
+
+ // This is a list of VB remember by D3dCtx
+ // so that it can release() all surface when canvas resize
+ // Only the header D3dVertexBuffer contains non-null entry
+ LPD3DVERTEXBUFFER next;
+ LPD3DVERTEXBUFFER previous;
+
+ // Pointer back to the GeometryArrayRetained pVertexBuffers
+ // This is used to remove itself from pVertexBuffers table
+ // when ctx destroy
+ D3dVertexBufferVector* vbVector;
+
+ // Last texture coordinate position =
+ // (i) textureCoordSetMap[pass] if executeVA()
+ // (ii) texCoordSetMapOffset[pass] if execute() or buildGA()
+ // (iii) TEX_EYE_LINEAR/TEX_SPHERE_MAP/TEX_OBJ_LINEAR/TEX_REFLECT_MAP
+ // if automatic texture generation is used
+ // This is used for VertexBuffer to know whether Texture
+ // coordinate need to copy or not in case texture unit swap
+ // or texture unit change from automatic texture generation
+ // to use coordinate index specifies by user.
+ int texCoordPosition[D3DDP_MAXTEXCOORD];
+
+ // Max vertex limit allow for this primitive type
+ // This is used for display list optimization without
+ // recompute it again.
+ int maxVertexLimit;
+
+ D3dVertexBuffer();
+ ~D3dVertexBuffer();
+
+ VOID release();
+ VOID render(D3dCtx *d3dCtx);
+ BOOL initializeNumVertices(int len);
+ VOID addStride(int len);
+ VOID addStrides(jint stripLen, jint *strips);
+ VOID appendStrides(jint stripLen, USHORT *strips);
+};
+
+
+#endif
diff --git a/src/native/d3d/GeometryArrayRetained.cpp b/src/native/d3d/GeometryArrayRetained.cpp
new file mode 100644
index 0000000..e8596d0
--- /dev/null
+++ b/src/native/d3d/GeometryArrayRetained.cpp
@@ -0,0 +1,5254 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+
+//#define VBDEBUG
+//#define TEXDEBUG
+
+#define getVertexFormat(texSize) \
+ (((texSize) << D3DFVF_TEXCOUNT_SHIFT) & D3DFVF_TEXCOUNT_MASK)
+
+/*
+ * This correspond to the constant in d3dtypes.h
+ * under D3D 7.0/8.0 header and may not portable :
+ * D3DFVF_TEXTUREFORMAT1 3
+ * D3DFVF_TEXTUREFORMAT2 0
+ * D3DFVF_TEXTUREFORMAT3 1
+ * D3DFVF_TEXTUREFORMAT4 2
+ */
+CONST static DWORD TexFormatSizeTable[5] = {0, 3, 0, 1, 2};
+static float defaultTexCoord[4] = {0, 0, 0, 0};
+
+typedef struct _D3DDRAWPRIMITIVESTRIDEDDATA
+{
+ DWORD positionStride;
+ jfloat *fpositionPtr;
+ jdouble *dpositionPtr;
+ DWORD normalStride;
+ jfloat *normalPtr;
+ DWORD diffuseStride;
+ jfloat *fdiffusePtr;
+ jbyte *bdiffusePtr;
+ jint *indexPtr;
+ jint initialIndexIndex;
+ DWORD textureCoordsStride[D3DDP_MAXTEXCOORD];
+ jfloat* textureCoordsPtr[D3DDP_MAXTEXCOORD];
+ jint texCoordPosition[D3DDP_MAXTEXCOORD];
+ boolean useAlpha;
+ boolean modulateAlpha;
+ jfloat alpha;
+} D3DDRAWPRIMITIVESTRIDEDDATA, *LPD3DDRAWPRIMITIVESTRIDEDDATA;
+
+
+void copyIndexVertexToVB(D3dCtx *d3dCtx,
+ D3DDRAWPRIMITIVESTRIDEDDATA* strideData,
+ DWORD indexCount,
+ jint cDirty,
+ BOOL insertStrideToVB,
+ BOOL expandQuadIndex)
+{
+ HRESULT hr;
+
+ if (cDirty & javax_media_j3d_GeometryArrayRetained_INDEX_CHANGED) {
+ jint *src = strideData->indexPtr + strideData->initialIndexIndex;
+ LPDIRECT3DINDEXBUFFER8 indexBuffer = d3dCtx->pVB->indexBuffer;
+ D3DINDEXBUFFER_DESC desc;
+ BYTE *bptr;
+
+ indexBuffer->GetDesc(&desc);
+ hr = indexBuffer->Lock(0, 0, &bptr, 0);
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKINDEXVBFAIL, hr);
+ return;
+ }
+
+ int i = indexCount;
+
+ if (desc.Format == D3DFMT_INDEX16) {
+ USHORT *dst = (USHORT *) bptr;
+
+ if (!expandQuadIndex) {
+ while (--i >= 0) {
+ *dst++ = *src++;
+ }
+ } else {
+ USHORT *endptr = dst + (USHORT) 3*indexCount/2;
+
+ while (dst < endptr) {
+ *dst++ = *src;
+ *dst++ = *(src+1);
+ *dst++ = *(src+2);
+ *dst++ = *src;
+ src++;
+ src++;
+ *dst++ = *src;
+ src++;
+ *dst++ = *src;
+ src++;
+ }
+ }
+ } else {
+ UINT *dst = (UINT *) bptr;
+
+ if (!expandQuadIndex) {
+ while (--i >= 0) {
+ *dst++ = *src++;
+ }
+ } else {
+ UINT *endptr = dst + (UINT) 3*indexCount/2;
+ while (dst < endptr) {
+ *dst++ = *src;
+ *dst++ = *(src+1);
+ *dst++ = *(src+2);
+ *dst++ = *src;
+ src++;
+ src++;
+ *dst++ = *src;
+ src++;
+ *dst++ = *src;
+ src++;
+ }
+
+ dst = (UINT *) bptr;
+ }
+ }
+
+ indexBuffer->Unlock();
+ }
+
+ if (insertStrideToVB) {
+ d3dCtx->pVB->addStride(d3dCtx->pVB->indexCount);
+ }
+}
+
+// This function copy the stride vertex data into Vertex Buffer
+// point by vbptr and update vbptr
+void copyVertexToVB(D3dCtx *d3dCtx,
+ D3DDRAWPRIMITIVESTRIDEDDATA* strideData,
+ DWORD vcount,
+ float **vbptr,
+ jint cDirty,
+ BOOL insertStrideToVB,
+ jdouble* xform,
+ jdouble* nxform)
+{
+ float *dst;
+ float *src;
+ double *dsrc;
+ DWORD i;
+ DWORD srcStride;
+ DWORD currStride;
+
+ DWORD dstStride = d3dCtx->pVB->stride >> 2;
+ DWORD vertexFormat = d3dCtx->pVB->vertexFormat;
+ float *endptr;
+
+ // Copy Position
+ if (cDirty & javax_media_j3d_GeometryArrayRetained_COORDINATE_CHANGED) {
+ dst = *vbptr;
+ // Before we call two times src++ in position and
+ // normal copy so we only need to add dstStride - 2
+ // at the end.
+ srcStride = strideData->positionStride - 2;
+ endptr = dst + vcount*dstStride;
+ dstStride -= 2;
+ src = strideData->fpositionPtr;
+
+ if (xform == NULL) {
+ if (src != NULL) {
+ while (dst < endptr) {
+ *dst++ = *src++; // pos x
+ *dst++ = *src++; // pos y
+ *dst = *src; // pos z
+ dst += dstStride;
+ src += srcStride;
+ }
+ } else {
+ // double is used for position coordinate in executeVA()
+ dsrc = strideData->dpositionPtr;
+ while (dst < endptr) {
+ *dst++ = *dsrc++; // pos x
+ *dst++ = *dsrc++; // pos y
+ *dst = *dsrc; // pos z
+ dst += dstStride;
+ dsrc += srcStride;
+ }
+ }
+ } else {
+ if (src != NULL) {
+ float x, y, z, w;
+ while (dst < endptr) {
+ x = *src++;
+ y = *src++;
+ z = *src; // pos z
+ w = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ *dst++ = (xform[0]*x + xform[1]*y + xform[2]*z + xform[3])*w;
+ *dst++ = (xform[4]*x + xform[5]*y + xform[6]*z + xform[7])*w;
+ *dst = (xform[8]*x + xform[9]*y + xform[10]*z + xform[11])*w;
+ dst += dstStride;
+ src += srcStride;
+ }
+ } else {
+ double x, y, z, w;
+ // double is used for position coordinate in executeVA()
+ dsrc = strideData->dpositionPtr;
+ while (dst < endptr) {
+ x = *src++;
+ y = *src++;
+ z = *src; // pos z
+ w = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ *dst++ = (xform[0]*x + xform[1]*y + xform[2]*z + xform[3])*w;
+ *dst++ = (xform[4]*x + xform[5]*y + xform[6]*z + xform[7])*w;
+ *dst = (xform[8]*x + xform[9]*y + xform[10]*z + xform[11])*w;
+ dst += dstStride;
+ dsrc += srcStride;
+ }
+ }
+
+ }
+ // restore value
+ dstStride += 2;
+ }
+
+ // Copy Normal
+ if (vertexFormat & D3DFVF_NORMAL) {
+ if (cDirty & javax_media_j3d_GeometryArrayRetained_NORMAL_CHANGED) {
+ dst = *vbptr + 3;
+ src = strideData->normalPtr;
+ srcStride = strideData->normalStride - 2;
+ endptr = dst + vcount*dstStride;
+ dstStride -= 2;
+ if (nxform == NULL) {
+ while (dst < endptr) {
+ *dst++ = *src++; // norm x
+ *dst++ = *src++; // norm y
+ *dst = *src; // norm z
+ dst += dstStride;
+ src += srcStride;
+ }
+ } else {
+ float nx, ny, nz, nw;
+ while (dst < endptr) {
+ nx = *src++;
+ ny = *src++;
+ nz = *src; // pos z
+ nw = 1/(nxform[12]*nx + nxform[13]*ny + nxform[14]*nz + nxform[15]);
+ *dst++ = (nxform[0]*nx + nxform[1]*ny + nxform[2]*nz + nxform[3])*nw;
+ *dst++ = (nxform[4]*nx + nxform[5]*ny + nxform[6]*nz + nxform[7])*nw;
+ *dst = (nxform[8]*nx + nxform[9]*ny + nxform[10]*nz + nxform[11])*nw;
+ dst += dstStride;
+ dsrc += srcStride;
+ }
+ }
+ // restore value
+ dstStride += 2;
+ }
+ // nx,ny,nz copy in addtion to x, y, z
+ currStride = 6;
+ } else {
+ // This is used to keep track of the offset
+ // from beginning of the current type copy.
+ currStride = 3; // x,y,z already copy
+ }
+
+ // Copy Diffuse Color (DWORD & float are of the same size)
+
+ if (vertexFormat & D3DFVF_DIFFUSE) {
+ if (cDirty & javax_media_j3d_GeometryArrayRetained_COLOR_CHANGED) {
+
+ DWORD* wdst = (DWORD *) *vbptr + currStride;
+ DWORD* wendptr = wdst + vcount*dstStride;
+
+ if (strideData->fdiffusePtr) {
+ float* wsrc = strideData->fdiffusePtr;
+ float r, g, b, a;
+ if ((d3dCtx->currDisplayListID <= 0) ||
+ !strideData->modulateAlpha) {
+ // execute() or executeVA()
+
+ if (strideData->useAlpha) {
+ srcStride = strideData->diffuseStride - 3;
+ while (wdst < wendptr) {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc++;
+ a = *wsrc;
+ *wdst = D3DCOLOR_COLORVALUE(r, g, b, a);
+ wdst += dstStride;
+ wsrc += srcStride;
+ }
+ } else {
+ srcStride = strideData->diffuseStride - 2;
+ while (wdst < wendptr) {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc;
+ *wdst = D3DCOLOR_COLORVALUE(r, g, b, 0);
+ wdst += dstStride;
+ wsrc += srcStride;
+ }
+ }
+ } else {
+ // buildGA() & modulateAlpha
+ float alpha = strideData->alpha;
+ if (strideData->useAlpha) {
+ srcStride = strideData->diffuseStride - 3;
+ while (wdst < wendptr) {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc++;
+ a = *wsrc * alpha;
+ *wdst = D3DCOLOR_COLORVALUE(r, g, b, a);
+ wdst += dstStride;
+ wsrc += srcStride;
+ }
+ } else {
+ srcStride = strideData->diffuseStride - 2;
+ while (wdst < wendptr) {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc;
+ *wdst = D3DCOLOR_COLORVALUE(r, g, b, alpha);
+ wdst += dstStride;
+ wsrc += srcStride;
+ }
+ }
+
+ }
+ } else { // byte color pointer
+ jbyte* wsrc = strideData->bdiffusePtr;
+ jbyte r, g, b, a;
+ if ((d3dCtx->currDisplayListID <= 0) ||
+ !strideData->modulateAlpha) {
+ // execute() or executeVA()
+
+ if (strideData->useAlpha) {
+ srcStride = strideData->diffuseStride - 3;
+ while (wdst < wendptr) {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc++;
+ a = *wsrc;
+ *wdst = D3DCOLOR_RGBA(r, g, b, a);
+ wdst += dstStride;
+ wsrc += srcStride;
+ }
+ } else {
+ srcStride = strideData->diffuseStride - 2;
+ while (wdst < wendptr) {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc;
+ *wdst = D3DCOLOR_RGBA(r, g, b, 0);
+ wdst += dstStride;
+ wsrc += srcStride;
+ }
+ }
+ } else {
+ // buildGA() & modeulateAlpha
+ // Currently buildGA() will not use byte color
+ // so this code should never execute.
+ jbyte alpha = (jbyte) 255*strideData->alpha;
+ if (strideData->useAlpha) {
+ srcStride = strideData->diffuseStride - 3;
+ while (wdst < wendptr) {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc++;
+ a = (jbyte)(((int)(*wsrc) & 0xff) * strideData->alpha);
+ *wdst = D3DCOLOR_RGBA(r, g, b, a);
+ wdst += dstStride;
+ wsrc += srcStride;
+ }
+ } else {
+ srcStride = strideData->diffuseStride - 2;
+ while (wdst < wendptr) {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc;
+ *wdst = D3DCOLOR_RGBA(r, g, b, alpha);
+ wdst += dstStride;
+ wsrc += srcStride;
+ }
+ }
+
+ }
+ }
+
+ }
+
+ currStride++; // additional one DWORD of color copy
+ }
+
+ // Copy Texture
+ int ts;
+ int texPos;
+ boolean invalidTexCoord;
+
+#ifdef TEXDEBUG
+ printf("In copyVertexToVB TexSet Used %d\n", d3dCtx->texSetUsed);
+#endif
+ for (i=0; i < d3dCtx->texSetUsed; i++) {
+ ts = d3dCtx->texStride[i];
+
+ // TODO: skip when ts = 0
+ if (ts == 0) {
+ continue;
+ }
+ texPos = strideData->texCoordPosition[i];
+
+ invalidTexCoord = ((texPos != d3dCtx->pVB->texCoordPosition[i]) ||
+ (texPos == TEX_OBJ_LINEAR));
+
+#ifdef TEXDEBUG
+ printf("%d texPos %d, invalidate Cached TexCoord %d, ts %d\n",i, texPos, invalidTexCoord, ts);
+#endif
+ if ((cDirty & javax_media_j3d_GeometryArrayRetained_TEXTURE_CHANGED) ||
+ invalidTexCoord) {
+
+ if (texPos >= 0) {
+ dst = *vbptr + currStride;
+ src = strideData->textureCoordsPtr[i];
+ endptr = dst + vcount*dstStride;
+#ifdef TEXDEBUG
+ printf("copy directly, ts %d\n", ts);
+#endif
+ if (ts == 2) {
+ dstStride--;
+ srcStride = strideData->textureCoordsStride[i] - 1;
+ while (dst < endptr) {
+ *dst++ = *src++; // tx
+ *dst = *src; // ty
+ dst += dstStride;
+ src += srcStride;
+ }
+ dstStride++;
+ } else if (ts == 3) {
+ dstStride -= 2;
+ srcStride = strideData->textureCoordsStride[i] - 2;
+ while (dst < endptr) {
+ *dst++ = *src++; // tx
+ *dst++ = *src++; // ty
+ *dst = *src; // tz
+ dst += dstStride;
+ src += srcStride;
+ }
+ dstStride += 2;
+ } else {
+ // ts == 4
+ dstStride -= 3;
+ srcStride = strideData->textureCoordsStride[i] - 3;
+ while (dst < endptr) {
+ *dst++ = *src++; // tx
+ *dst++ = *src++; // ty
+ *dst++ = *src++; // tz
+ *dst = *src; // tw
+ dst += dstStride;
+ src += srcStride;
+ }
+ dstStride += 3;
+ }
+
+ } else {
+ if (texPos == TEX_OBJ_LINEAR) {
+ // automatic texture generation for Object Linear
+ float *ps = d3dCtx->planeS[i];
+ float *pt = d3dCtx->planeT[i];
+ float *pr = d3dCtx->planeR[i];
+ float *pq = d3dCtx->planeQ[i];
+#ifdef TEXDEBUG
+ printf("gen obj linear tex, ts %d\n", ts);
+#endif
+ if (strideData->fpositionPtr) {
+ float x, y, z;
+ dst = *vbptr + currStride;
+ endptr = dst + vcount*dstStride;
+ src = strideData->fpositionPtr;
+ srcStride = strideData->positionStride - 2;
+ if (ts == 2) {
+ dstStride--;
+ if (xform == NULL) {
+ while (dst < endptr) {
+ x = *src++;
+ y = *src++;
+ z = *src;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ dst += dstStride;
+ src += srcStride;
+ }
+ } else {
+ float tx, ty, tz, tw;
+ while (dst < endptr) {
+ tx = *src++;
+ ty = *src++;
+ tz = *src;
+ tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw;
+ y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw;
+ z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ dst += dstStride;
+ src += srcStride;
+ }
+ }
+ dstStride++;
+ } else if (ts == 3) {
+ dstStride -= 2;
+ if (xform == NULL) {
+ while (dst < endptr) {
+ x = *src++;
+ y = *src++;
+ z = *src;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ *dst = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ dst += dstStride;
+ src += srcStride;
+ }
+ } else {
+ float tx, ty, tz, tw;
+ while (dst < endptr) {
+ tx = *src++;
+ ty = *src++;
+ tz = *src;
+ tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw;
+ y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw;
+ z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ *dst = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ dst += dstStride;
+ src += srcStride;
+ }
+ }
+
+ dstStride += 2;
+ } else {
+ // ts == 4
+ dstStride -= 3;
+
+ if (!d3dCtx->texTransformSet[i]) {
+ if (xform == NULL) {
+ while (dst < endptr) {
+ x = *src++;
+ y = *src++;
+ z = *src;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ *dst++ = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ *dst = pq[0]*x + pq[1]*y + pq[2]*z + pq[3];
+ dst += dstStride;
+ src += srcStride;
+ }
+ } else {
+ float tx, ty, tz, tw;
+ while (dst < endptr) {
+ tx = *src++;
+ ty = *src++;
+ tz = *src;
+ tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw;
+ y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw;
+ z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ *dst++ = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ *dst = pq[0]*x + pq[1]*y + pq[2]*z + pq[3];
+ dst += dstStride;
+ src += srcStride;
+ }
+ }
+ } else {
+ // do texture transform manually
+ D3DXMATRIX *m = &(d3dCtx->texTransform[i]);
+ double tx, ty, tz, tw;
+ if (xform == NULL) {
+ while (dst < endptr) {
+ x = *src++;
+ y = *src++;
+ z = *src;
+ tx = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ ty = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ tz = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ tw = pq[0]*x + pq[1]*y + pq[2]*z + pq[3];
+ *dst++ = (*m)._11*tx + (*m)._21*ty + (*m)._31*tz + (*m)._41*tw;
+ *dst++ = (*m)._12*tx + (*m)._22*ty + (*m)._32*tz + (*m)._42*tw;
+ *dst++ = (*m)._13*tx + (*m)._23*ty + (*m)._33*tz + (*m)._43*tw;
+ *dst = (*m)._14*tx + (*m)._24*ty + (*m)._34*tz + (*m)._44*tw;
+ dst += dstStride;
+ src += srcStride;
+ }
+ } else {
+ float tx, ty, tz, tw;
+ while (dst < endptr) {
+ tx = *src++;
+ ty = *src++;
+ tz = *src;
+ tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw;
+ y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw;
+ z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw;
+ tx = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ ty = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ tz = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ tw = pq[0]*x + pq[1]*y + pq[2]*z + pq[3];
+ *dst++ = (*m)._11*tx + (*m)._21*ty + (*m)._31*tz + (*m)._41*tw;
+ *dst++ = (*m)._12*tx + (*m)._22*ty + (*m)._32*tz + (*m)._42*tw;
+ *dst++ = (*m)._13*tx + (*m)._23*ty + (*m)._33*tz + (*m)._43*tw;
+ *dst = (*m)._14*tx + (*m)._24*ty + (*m)._34*tz + (*m)._44*tw;
+ dst += dstStride;
+ src += srcStride;
+ }
+ }
+ }
+ dstStride += 3;
+ }
+ } else {
+ // double type position pointer
+ double x, y, z;
+ dst = *vbptr + currStride;
+ endptr = dst + vcount*dstStride;
+ dsrc = strideData->dpositionPtr;
+ srcStride = strideData->positionStride - 2;
+ if (ts == 2) {
+ dstStride--;
+ if (xform == NULL) {
+ while (dst < endptr) {
+ x = *dsrc++;
+ y = *dsrc++;
+ z = *dsrc;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ dst += dstStride;
+ dsrc += srcStride;
+ }
+ } else {
+ double tx, ty, tz, tw;
+ while (dst < endptr) {
+ tx = *src++;
+ ty = *src++;
+ tz = *src;
+ tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw;
+ y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw;
+ z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ dst += dstStride;
+ src += srcStride;
+ }
+ }
+ dstStride++;
+ } else if (ts == 3) {
+ dstStride -= 2;
+ if (xform == NULL) {
+ while (dst < endptr) {
+ x = *dsrc++;
+ y = *dsrc++;
+ z = *dsrc;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ *dst = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ dst += dstStride;
+ dsrc += srcStride;
+ }
+ } else {
+ double tx, ty, tz, tw;
+ while (dst < endptr) {
+ tx = *src++;
+ ty = *src++;
+ tz = *src;
+ tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw;
+ y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw;
+ z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ *dst = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ dst += dstStride;
+ src += srcStride;
+ }
+ }
+ dstStride += 2;
+ } else {
+ // ts == 4
+ dstStride -= 3;
+ if (!d3dCtx->texTransformSet[i]) {
+ if (xform == NULL) {
+ while (dst < endptr) {
+ x = *dsrc++;
+ y = *dsrc++;
+ z = *dsrc;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ *dst++ = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ *dst = pq[0]*x + pq[1]*y + pq[2]*z + pq[3];
+ dst += dstStride;
+ dsrc += srcStride;
+ }
+ } else {
+ double tx, ty, tz, tw;
+ while (dst < endptr) {
+ tx = *src++;
+ ty = *src++;
+ tz = *src;
+ tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw;
+ y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw;
+ z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw;
+ *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ *dst++ = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ *dst = pq[0]*x + pq[1]*y + pq[2]*z + pq[3];
+ dst += dstStride;
+ src += srcStride;
+ }
+ }
+ } else {
+// do texture transform manually
+ D3DXMATRIX *m = &(d3dCtx->texTransform[i]);
+ double tx, ty, tz, tw;
+ if (xform == NULL) {
+ while (dst < endptr) {
+ x = *src++;
+ y = *src++;
+ z = *src;
+ tx = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ ty = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ tz = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ tw = pq[0]*x + pq[1]*y + pq[2]*z + pq[3];
+ *dst++ = ((*m)._11*tx + (*m)._21*ty + (*m)._31*tz + (*m)._41*tw);
+ *dst++ = ((*m)._12*tx + (*m)._22*ty + (*m)._32*tz + (*m)._42*tw);
+ *dst++ = ((*m)._13*tx + (*m)._23*ty + (*m)._33*tz + (*m)._43*tw);
+ *dst = (*m)._14*tx + (*m)._24*ty + (*m)._34*tz + (*m)._44*tw;
+ dst += dstStride;
+ src += srcStride;
+ }
+ } else {
+ float tx, ty, tz, tw;
+ while (dst < endptr) {
+ tx = *src++;
+ ty = *src++;
+ tz = *src;
+ tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw;
+ y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw;
+ z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw;
+ tx = ps[0]*x + ps[1]*y + ps[2]*z + ps[3];
+ ty = pt[0]*x + pt[1]*y + pt[2]*z + pt[3];
+ tz = pr[0]*x + pr[1]*y + pr[2]*z + pr[3];
+ tw = pq[0]*x + pq[1]*y + pq[2]*z + pq[3];
+ *dst++ = ((*m)._11*tx + (*m)._21*ty + (*m)._31*tz + (*m)._41*tw);
+ *dst++ = ((*m)._12*tx + (*m)._22*ty + (*m)._32*tz + (*m)._42*tw);
+ *dst++ = ((*m)._13*tx + (*m)._23*ty + (*m)._33*tz + (*m)._43*tw);
+ *dst = (*m)._14*tx + (*m)._24*ty + (*m)._34*tz + (*m)._44*tw;
+ dst += dstStride;
+ src += srcStride;
+ }
+ }
+ }
+ dstStride += 3;
+ }
+ }
+ } else if (texPos == TEX_GEN_INVALID) {
+ // application error, disable by setting texCoord to zero
+#ifdef TEXDEBUG
+ printf("app error, ts %d\n", ts);
+#endif
+ dst = *vbptr + currStride;
+ endptr = dst + vcount*dstStride;
+ if (ts == 2) {
+ dstStride--;
+ while (dst < endptr) {
+ *dst++ = 0;
+ *dst = 0;
+ dst += dstStride;
+ }
+ dstStride++;
+ } else if (ts == 3) {
+ dstStride -= 2;
+ while (dst < endptr) {
+ *dst++ = 0;
+ *dst++ = 0;
+ *dst = 0;
+ dst += dstStride;
+ }
+ dstStride += 2;
+ } else {
+ // ts == 4
+ dstStride -= 3;
+ while (dst < endptr) {
+ *dst++ = 0;
+ *dst++ = 0;
+ *dst++ = 0;
+ *dst = 0;
+ dst += dstStride;
+ }
+ dstStride += 3;
+ }
+ } else {
+ // Other automatic texture generation type handle
+ // by driver
+ //printf("TexStage %d, Tex gen by driver, texPos = %d\n", i, texPos);
+ }
+ }
+ }
+
+ currStride += ts;
+ }
+
+ if (insertStrideToVB) {
+ d3dCtx->pVB->addStride(vcount);
+ }
+
+ // Adjust VB pointer so that when this function is invoked
+ // again, it append to the VB correctly.
+ *vbptr += (vcount*dstStride);
+}
+
+
+void copyOneVertexToVB(D3dCtx *d3dCtx,
+ float **vbptr,
+ D3DDRAWPRIMITIVESTRIDEDDATA* strideData,
+ DWORD idx,
+ jint cDirty,
+ jdouble* xform,
+ jdouble* nxform)
+{
+ float *src;
+ float *dst = *vbptr;
+ DWORD vertexFormat = d3dCtx->pVB->vertexFormat;
+ float posX, posY, posZ;
+
+ // Copy Position
+
+ // if (cDirty & javax_media_j3d_GeometryArrayRetained_COORDINATE_CHANGED)
+ // Set the posX, posY, posZ anyway since TexGeneration will use it
+ // if dirty.
+
+ if (strideData->fpositionPtr != NULL) {
+ src = strideData->fpositionPtr +
+ idx*strideData->positionStride;
+
+ if (xform == NULL) {
+ posX = *src++; // pos x
+ posY = *src++; // pos y
+ posZ = *src; // pos z
+ } else {
+ float x, y, z, w;
+ x = *src++;
+ y = *src++;
+ z = *src;
+ w = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ posX = (xform[0]*x + xform[1]*y + xform[2]*z + xform[3])*w;
+ posY = (xform[4]*x + xform[5]*y + xform[6]*z + xform[7])*w;
+ posZ = (xform[8]*x + xform[9]*y + xform[10]*z + xform[11])*w;
+ }
+ } else {
+ // double is used for position coordinate in executeVA()
+ double *dsrc = strideData->dpositionPtr +
+ idx*strideData->positionStride;
+
+ if (xform == NULL) {
+ posX = (float) *dsrc++; // pos x
+ posY = (float) *dsrc++; // pos y
+ posZ = (float) *dsrc; // pos z
+ } else {
+ double x, y, z, w;
+ x = *dsrc++;
+ y = *dsrc++;
+ z = *dsrc;
+ w = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]);
+ posX = (float) (xform[0]*x + xform[1]*y + xform[2]*z + xform[3])*w;
+ posY = (float) (xform[4]*x + xform[5]*y + xform[6]*z + xform[7])*w;
+ posZ = (float) (xform[8]*x + xform[9]*y + xform[10]*z + xform[11])*w;
+ }
+ }
+ *dst++ = posX;
+ *dst++ = posY;
+ *dst++ = posZ;
+
+ // Copy Normal
+ if (vertexFormat & D3DFVF_NORMAL) {
+ if (cDirty & javax_media_j3d_GeometryArrayRetained_NORMAL_CHANGED) {
+ src = strideData->normalPtr +
+ idx*strideData->normalStride;
+ if (nxform == NULL) {
+ *dst++ = *src++; // norm x
+ *dst++ = *src++; // norm y
+ *dst++ = *src; // norm z
+ } else {
+ float nx, ny, nz, nw;
+ nx = *src++; // norm x
+ ny = *src++; // norm y
+ nz = *src; // norm z
+ nw = 1/(nxform[12]*nx + nxform[13]*ny + nxform[14]*nz + nxform[15]);
+ *dst++ = (nxform[0]*nx + nxform[1]*ny + nxform[2]*nz + nxform[3])*nw;
+ *dst++ = (nxform[4]*nx + nxform[5]*ny + nxform[6]*nz + nxform[7])*nw;
+ *dst = (nxform[8]*nx + nxform[9]*ny + nxform[10]*nz + nxform[11])*nw;
+ }
+ }
+ }
+
+
+ // Copy Diffuse Color (DWORD & float are of the same size)
+ if (vertexFormat & D3DFVF_DIFFUSE) {
+ if (cDirty & javax_media_j3d_GeometryArrayRetained_COLOR_CHANGED) {
+ DWORD* wdst = (DWORD *) dst;
+ if (strideData->fdiffusePtr) {
+ src = strideData->fdiffusePtr +
+ idx*strideData->diffuseStride;
+ float r, g, b, a;
+ if ((d3dCtx->currDisplayListID <= 0) ||
+ !strideData->modulateAlpha) {
+ // execute() or executeVA()
+ if (strideData->useAlpha) {
+ r = *src++;
+ g = *src++;
+ b = *src++;
+ a = *src;
+ } else {
+ r = *src++;
+ g = *src++;
+ b = *src;
+ a = 0;
+ }
+ } else {
+ // buildGA() & modeulateAlpha
+ if (strideData->useAlpha) {
+ r = *src++;
+ g = *src++;
+ b = *src++;
+ a = *src * strideData->alpha;
+ } else {
+ r = *src++;
+ g = *src++;
+ b = *src;
+ a = strideData->alpha;
+ }
+ }
+ *wdst = D3DCOLOR_COLORVALUE(r, g, b, a);
+ } else { // byte color pointer
+ jbyte* wsrc = strideData->bdiffusePtr +
+ idx*strideData->diffuseStride;
+ jbyte r, g, b, a;
+ if ((d3dCtx->currDisplayListID <= 0) ||
+ !strideData->modulateAlpha) {
+ // execute() or executeVA()
+ if (strideData->useAlpha) {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc++;
+ a = *wsrc;
+ } else {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc;
+ a = 0;
+ }
+ } else {
+ // buildGA() & modeulateAlpha
+ // Currently buildGA() will not use byte color
+ // so this code should never execute.
+ jbyte alpha = (jbyte) (255*strideData->alpha);
+ if (strideData->useAlpha) {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc++;
+ a = (jbyte)(((int)(*wsrc) & 0xff) * strideData->alpha);
+ } else {
+ r = *wsrc++;
+ g = *wsrc++;
+ b = *wsrc;
+ a = alpha;
+
+ }
+ }
+ *wdst = D3DCOLOR_RGBA(r, g, b, a);
+ }
+ }
+ dst++; // additional one DWORD of color copy
+ }
+
+
+ // Copy Texture
+ int ts;
+ int texPos;
+ boolean invalidTexCoord;
+
+ for (int i=0; i < d3dCtx->texSetUsed; i++) {
+ ts = d3dCtx->texStride[i];
+ if (ts == 0) {
+ continue;
+ }
+ texPos = strideData->texCoordPosition[i];
+
+ invalidTexCoord = ((texPos != d3dCtx->pVB->texCoordPosition[i]) ||
+ (texPos == TEX_OBJ_LINEAR));
+
+ if ((cDirty & javax_media_j3d_GeometryArrayRetained_TEXTURE_CHANGED) || invalidTexCoord) {
+ if (texPos >= 0) {
+ src = strideData->textureCoordsPtr[i] +
+ idx*strideData->textureCoordsStride[i];
+ *dst++ = *src++; // tx
+ *dst++ = *src++; // ty
+ if (ts >= 3) {
+ *dst++ = *src++; // tx
+ if (ts >= 4) {
+ *dst++ = *src; // tx
+ }
+ }
+ } else {
+ // automatic texture generation
+ if (texPos == TEX_OBJ_LINEAR) {
+ float *ps = d3dCtx->planeS[i];
+ float *pt = d3dCtx->planeT[i];
+ float *pr = d3dCtx->planeR[i];
+ float *pq = d3dCtx->planeQ[i];
+
+ if ((ts < 4) || (!d3dCtx->texTransformSet[i])) {
+ *dst++ = ps[0]*posX + ps[1]*posY + ps[2]*posZ + ps[3];
+ *dst++ = pt[0]*posX + pt[1]*posY + pt[2]*posZ + pt[3];
+ if (ts >= 3) {
+ *dst++ = pr[0]*posX + pr[1]*posY + pr[2]*posZ + pr[3];
+ if (ts >= 4) {
+ *dst++ = pq[0]*posX + pq[1]*posY + pq[2]*posZ + pq[3];
+ }
+ }
+ } else {
+ float tx, ty, tz, tw;
+ D3DXMATRIX *m = &(d3dCtx->texTransform[i]);
+ tx = ps[0]*posX + ps[1]*posY + ps[2]*posZ + ps[3];
+ ty = pt[0]*posX + pt[1]*posY + pt[2]*posZ + pt[3];
+ tz = pr[0]*posX + pr[1]*posY + pr[2]*posZ + pr[3];
+ tw = pq[0]*posX + pq[1]*posY + pq[2]*posZ + pq[3];
+ *dst++ = (*m)._11*tx + (*m)._21*ty + (*m)._31*tz + (*m)._41*tw;
+ *dst++ = (*m)._12*tx + (*m)._22*ty + (*m)._32*tz + (*m)._42*tw;
+ *dst++ = (*m)._13*tx + (*m)._23*ty + (*m)._33*tz + (*m)._43*tw;
+ *dst++ = (*m)._14*tx + (*m)._24*ty + (*m)._34*tz + (*m)._44*tw;
+ }
+ } else if (texPos == TEX_GEN_INVALID) {
+ // application error, disable by setting texCoord to zero
+ *dst++ = 0;
+ *dst++ = 0;
+ if (ts >= 3) {
+ *dst++ = 0;
+ if (ts >= 4) {
+ *dst++ = 0;
+ }
+ }
+ } else {
+ // should not happen
+ dst += ts;
+ }
+ }
+ } else {
+ dst += ts;
+ }
+ }
+
+ *vbptr = dst;
+}
+
+
+float* allocateVB(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ int vcount,
+ int maxVertexLimit,
+ jint *cdirty)
+{
+ LPD3DVERTEXBUFFER vb = d3dCtx->pVB->nextVB;
+ HRESULT hr;
+ float *ptr = NULL;
+
+
+ if (vcount > maxVertexLimit) {
+ vcount = maxVertexLimit;
+ }
+
+ if ((vb != NULL) && (vb->vcount < vcount)) {
+ delete vb;
+ d3dCtx->pVB->nextVB = NULL;
+ vb = NULL;
+ }
+
+ if (vb == NULL) {
+ vb = new D3dVertexBuffer();
+ if (vb == NULL) {
+ D3dCtx::d3dWarning(OUTOFMEMORY);
+ return NULL;
+ }
+
+ vb->stride = d3dCtx->pVB->stride;
+ vb->vertexFormat = d3dCtx->pVB->vertexFormat;
+ // Don't set totalVertexCount
+ vb->isIndexPrimitive = d3dCtx->pVB->isIndexPrimitive;
+ vb->primitiveType = d3dCtx->pVB->primitiveType;
+ vb->isPointFlagUsed = d3dCtx->pVB->isPointFlagUsed;
+ vb->vcount = vcount;
+ vb->maxVertexLimit = maxVertexLimit;
+
+#ifdef VBDEBUG
+ printf("Create secondary VertexBuffer of size %d, display list ID %d, pointFlag %d\n",
+ vb->vcount, d3dCtx->currDisplayListID, vb->isPointFlagUsed);
+#endif
+ if (!vb->isPointFlagUsed) {
+ hr = device->CreateVertexBuffer(vb->stride*vcount,
+ D3DUSAGE_WRITEONLY,
+ vb->vertexFormat,
+ D3DPOOL_DEFAULT,
+ &vb->buffer);
+ } else {
+ hr = device->CreateVertexBuffer(vb->stride*vcount,
+ D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS,
+ vb->vertexFormat,
+ D3DPOOL_DEFAULT,
+ &vb->buffer);
+ }
+ if (FAILED(hr)) {
+ vb->buffer = NULL;
+ delete vb;
+ D3dCtx::d3dWarning(CREATEVBFAIL, hr);
+ return NULL;
+ }
+ d3dCtx->pVB->nextVB = vb;
+ *cdirty = javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED;
+ }
+
+ hr = vb->buffer->Lock(0, 0, (BYTE**) &ptr, 0);
+
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKVBFAIL, hr);
+ delete vb;
+ d3dCtx->pVB->nextVB = NULL;
+ return NULL;
+ }
+
+ d3dCtx->pVB = vb;
+
+ vb->stripLen = 0;
+ return ptr;
+}
+
+
+
+BOOL createCopyVBVertex(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ D3DDRAWPRIMITIVESTRIDEDDATA *strideData,
+ int vcount, jint cDirty,
+ jdouble* xform,
+ jdouble* nxform)
+{
+ LPD3DVERTEXBUFFER vb = d3dCtx->pVB;
+ float *vbptr;
+
+
+ if (vb->stripLen > 0) {
+ // VertexBuffer already used, create a new one or used
+ // the next VB in the list
+ // maxVertexLimit is already check before, so we can
+ // pass vcount as maxVertexLimit
+ vbptr = allocateVB(d3dCtx, device, vcount, vcount, &cDirty);
+ if (vbptr == NULL) {
+ return FALSE;
+ }
+
+ } else {
+ // use the same VB
+ HRESULT hr;
+ hr = vb->buffer->Lock(0, 0, (BYTE**)&vbptr, 0);
+
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKVBFAIL, hr);
+ return FALSE;
+ }
+
+ }
+
+ copyVertexToVB(d3dCtx, strideData, vcount, &vbptr, cDirty, true,
+ xform, nxform);
+
+ d3dCtx->pVB->buffer->Unlock();
+ return TRUE;
+}
+
+
+/*
+ * Draw Primitive with vertexCount > D3DMAXNUMVERTICES.
+ * In this case we call the drawing routine multiple times.
+ */
+void splitVertexToMultipleVB(D3dCtx *d3dCtx,
+ LPD3DDRAWPRIMITIVESTRIDEDDATA strideData,
+ int vcount,
+ int maxVertexLimit,
+ jint cDirty,
+ jdouble* xform,
+ jdouble* nxform)
+{
+ int i, inc;
+ int min = 0;
+ int max = 0;
+ jfloat *oldfPosition;
+ double *olddPosition;
+ jfloat *oldNormal;
+ jfloat *oldfDiffuse;
+ jbyte *oldbDiffuse;
+ float* oldTexCoords[D3DDP_MAXTEXCOORD];
+ int vc;
+ int texSetUsed = d3dCtx->texSetUsed;
+ LPDIRECT3DDEVICE8 device = d3dCtx->pDevice;
+ jfloat fr, fg, fb, fa;
+ jbyte br, bg, bb, ba;
+ boolean success;
+
+ DWORD vertexFormat = d3dCtx->pVB->vertexFormat;
+
+ // save stride pointers since strip set may have
+ // multiple call to this procedure.
+ oldfPosition = strideData->fpositionPtr;
+ olddPosition = strideData->dpositionPtr;
+ oldNormal = strideData->normalPtr;
+ oldfDiffuse = strideData->fdiffusePtr;
+ oldbDiffuse = strideData->bdiffusePtr;
+
+ for (i=0; i < texSetUsed; i++) {
+ oldTexCoords[i] = strideData->textureCoordsPtr[i];
+ }
+
+
+
+ switch (d3dCtx->pVB->primitiveType) {
+ case D3DPT_TRIANGLEFAN:
+ {
+ // Copy the very first vertx and repeat the last vertex
+ jfloat fx, fy, fz, nx, ny, nz;
+ jdouble dx, dy, dz;
+ jfloat tx[D3DDP_MAXTEXCOORD];
+ jfloat ty[D3DDP_MAXTEXCOORD];
+ jfloat tz[D3DDP_MAXTEXCOORD];
+ jfloat tw[D3DDP_MAXTEXCOORD];
+ inc = maxVertexLimit - 2;
+
+ if (oldfPosition) {
+ fx = *oldfPosition;
+ fy = *(oldfPosition+1);
+ fz = *(oldfPosition+2);
+ } else {
+ // must be double, since this routine will
+ // not invoke when there is no position available
+ dx = *olddPosition;
+ dy = *(olddPosition+1);
+ dz = *(olddPosition+2);
+ }
+
+ if (oldNormal) {
+ nx = *oldNormal;
+ ny = *(oldNormal+1);
+ nz = *(oldNormal+2);
+ }
+ if (oldfDiffuse) {
+ fr = *oldfDiffuse;
+ fg = *(oldfDiffuse+1);
+ fb = *(oldfDiffuse+2);
+ if (strideData->useAlpha) {
+ fa = *(oldfDiffuse+3);
+ }
+ } else if (oldbDiffuse) {
+ br = *oldbDiffuse;
+ bg = *(oldbDiffuse+1);
+ bb = *(oldbDiffuse+2);
+ if (strideData->useAlpha) {
+ ba = *(oldbDiffuse+3);
+ }
+ }
+
+ for (i=0; i < texSetUsed; i++) {
+ tx[i] = *oldTexCoords[i];
+ ty[i] = *(oldTexCoords[i]+1);
+ if (d3dCtx->texStride[i] > 2) {
+ tz[i] = *(oldTexCoords[i]+2);
+ if (d3dCtx->texStride[i] > 3) {
+ tw[i] = *(oldTexCoords[i]+3);
+ }
+ }
+ }
+ while (true) {
+ vc = (vcount >= maxVertexLimit ? maxVertexLimit : vcount);
+
+ success = createCopyVBVertex(d3dCtx, device, strideData,
+ vc, cDirty, xform, nxform);
+ // restore old values
+ if (oldfPosition) {
+ *(strideData->fpositionPtr) = fx;
+ *(strideData->fpositionPtr+1) = fy;
+ *(strideData->fpositionPtr+2) = fz;
+ } else {
+ *(strideData->dpositionPtr) = dx;
+ *(strideData->dpositionPtr+1) = dy;
+ *(strideData->dpositionPtr+2) = dz;
+ }
+ if (oldNormal) {
+ *(strideData->normalPtr) = nx;
+ *(strideData->normalPtr+1) = ny;
+ *(strideData->normalPtr+2) = nz;
+ }
+ if (oldfDiffuse) {
+ *(strideData->fdiffusePtr) = fr;
+ *(strideData->fdiffusePtr+1) = fg;
+ *(strideData->fdiffusePtr+2) = fb;
+ if (strideData->useAlpha) {
+ *(strideData->fdiffusePtr+3) = fa;
+ }
+ } else if (oldbDiffuse) {
+ *(strideData->bdiffusePtr) = br;
+ *(strideData->bdiffusePtr+1) = bg;
+ *(strideData->bdiffusePtr+2) = bb;
+ if (strideData->useAlpha) {
+ *(strideData->bdiffusePtr+3) = ba;
+ }
+ }
+ for (i=0; i < texSetUsed; i++) {
+ *(strideData->textureCoordsPtr[i]) = tx[i];
+ *(strideData->textureCoordsPtr[i]+1) = ty[i];
+ if (d3dCtx->texStride[i] > 2) {
+ *(strideData->textureCoordsPtr[i]+2) = tz[i];
+ if (d3dCtx->texStride[i] > 3) {
+ *(strideData->textureCoordsPtr[i]+3) = tw[i];
+ }
+ }
+ }
+
+ vcount -= inc;
+ if (!success || (vcount <= 2)) {
+ break;
+ }
+
+ if (oldfPosition) {
+ strideData->fpositionPtr += strideData->positionStride*inc;
+ fx = *strideData->fpositionPtr;
+ *strideData->fpositionPtr = *oldfPosition;
+ fy = *(strideData->fpositionPtr+1);
+ *(strideData->fpositionPtr+1) = *(oldfPosition+1);
+ fz = *(strideData->fpositionPtr+2);
+ *(strideData->fpositionPtr+2) = *(oldfPosition+2);
+ } else {
+ strideData->dpositionPtr += strideData->positionStride*inc;
+ dx = *strideData->dpositionPtr;
+ *strideData->dpositionPtr = *olddPosition;
+ dy = *(strideData->dpositionPtr+1);
+ *(strideData->dpositionPtr+1) = *(olddPosition+1);
+ dz = *(strideData->dpositionPtr+2);
+ *(strideData->dpositionPtr+2) = *(olddPosition+2);
+ }
+
+
+ if (oldNormal) {
+ strideData->normalPtr += strideData->normalStride*inc;
+ nx = *strideData->normalPtr;
+ *strideData->normalPtr = *oldNormal;
+ ny = *(strideData->normalPtr+1);
+ *(strideData->normalPtr+1) = *(oldNormal+1);
+ nz = *(strideData->normalPtr+2);
+ *(strideData->normalPtr+2) = *(oldNormal+2);
+ }
+
+ if (oldfDiffuse) {
+ strideData->fdiffusePtr += strideData->diffuseStride*inc;
+ fr = *strideData->fdiffusePtr;
+ *strideData->fdiffusePtr = *oldfDiffuse;
+ fg = *(strideData->fdiffusePtr+1);
+ *(strideData->fdiffusePtr+1) = *(oldfDiffuse+1);
+ fb = *(strideData->fdiffusePtr+2);
+ *(strideData->fdiffusePtr+2) = *(oldfDiffuse+2);
+ if (strideData->useAlpha) {
+ fa = *(strideData->fdiffusePtr+3);
+ *(strideData->fdiffusePtr+3) = *(oldfDiffuse+3);
+ }
+ } else if (oldbDiffuse) {
+ strideData->bdiffusePtr += strideData->diffuseStride*inc;
+ br = *strideData->bdiffusePtr;
+ *strideData->bdiffusePtr = *oldbDiffuse;
+ bg = *(strideData->bdiffusePtr+1);
+ *(strideData->bdiffusePtr+1) = *(oldbDiffuse+1);
+ bb = *(strideData->bdiffusePtr+2);
+ *(strideData->bdiffusePtr+2) = *(oldbDiffuse+2);
+ if (strideData->useAlpha) {
+ ba = *(strideData->bdiffusePtr+3);
+ *(strideData->bdiffusePtr+3) = *(oldbDiffuse+3);
+ }
+ }
+
+ for (i=0; i < texSetUsed; i++) {
+ strideData->textureCoordsPtr[i] +=
+ strideData->textureCoordsStride[i]*inc;
+
+ tx[i] = *strideData->textureCoordsPtr[i];
+ ty[i] = *(strideData->textureCoordsPtr[i]+1);
+ *(strideData->textureCoordsPtr[i]) = *oldTexCoords[i];
+ *(strideData->textureCoordsPtr[i]+1) = *(oldTexCoords[i]+1);
+ if (d3dCtx->texStride[i] > 2) {
+ tz[i] = *(strideData->textureCoordsPtr[i]+2);
+ *(strideData->textureCoordsPtr[i]+2)
+ = *(oldTexCoords[i]+ 2);
+ if (d3dCtx->texStride[i] > 3) {
+ tw[i] = *(strideData->textureCoordsPtr[i]+3);
+ *(strideData->textureCoordsPtr[i]+3)
+ = *(oldTexCoords[i]+ 3);
+ }
+
+ }
+ }
+
+ }
+ break;
+ }
+ case D3DPT_POINTLIST:
+ if (max == 0) {
+ max = maxVertexLimit;
+ }
+ // fall through
+ case D3DPT_LINESTRIP:
+ if (max == 0) {
+ max = maxVertexLimit;
+ min = 1; // repeat the last vertex;
+ }
+ // fall through
+ case D3DPT_TRIANGLELIST:
+ if (max == 0) {
+ if (d3dCtx->pVB->isIndexPrimitive) {
+ // QuadArray
+ max = maxVertexLimit - (maxVertexLimit % 4);
+ } else {
+ max = maxVertexLimit - (maxVertexLimit % 3);
+ }
+ }
+ // fall through
+ case D3DPT_LINELIST:
+ if (max == 0) {
+ max = maxVertexLimit - (maxVertexLimit % 2);
+ }
+ // fall through
+ case D3DPT_TRIANGLESTRIP:
+ if (max == 0) {
+ max = maxVertexLimit - (maxVertexLimit % 4);
+ min = 2; // repeat the last two vertices
+ }
+ inc = max - min;
+
+ while (true) {
+ vc = (vcount >= max ? max : vcount);
+
+ if (!createCopyVBVertex(d3dCtx, device, strideData, vc,
+ cDirty, xform, nxform)) {
+ break;
+ }
+
+ vcount -= inc;
+ if (vcount <= min) {
+ break;
+ }
+ if (oldfPosition) {
+ strideData->fpositionPtr += strideData->positionStride*inc;
+ } else {
+ strideData->dpositionPtr += strideData->positionStride*inc;
+ }
+
+ if (oldNormal) {
+ strideData->normalPtr += strideData->normalStride*inc;
+ }
+ if (oldfDiffuse) {
+ strideData->fdiffusePtr += strideData->diffuseStride*inc;
+ } else if (oldbDiffuse) {
+ strideData->bdiffusePtr += strideData->diffuseStride*inc;
+ }
+ for (i=0; i < texSetUsed; i++) {
+ strideData->textureCoordsPtr[i] +=
+ strideData->textureCoordsStride[i]*inc;
+ }
+ }
+ break;
+ }
+
+ // Restore old pointers;
+ strideData->fpositionPtr = oldfPosition;
+ strideData->dpositionPtr = olddPosition;
+ strideData->normalPtr = oldNormal;
+ strideData->fdiffusePtr = oldfDiffuse;
+ strideData->bdiffusePtr = oldbDiffuse;
+
+ for (i=0; i < texSetUsed; i++) {
+ strideData->textureCoordsPtr[i] = oldTexCoords[i];
+ }
+}
+
+
+BOOL reIndexifyIndexVertexToVBs(D3dCtx *d3dCtx,
+ D3DDRAWPRIMITIVESTRIDEDDATA* strideData,
+ DWORD indexCount,
+ DWORD vcount,
+ jint cDirty,
+ BOOL expandQuadIndex,
+ DWORD maxVertexLimit,
+ jdouble* xform,
+ jdouble* nxform)
+{
+ LPD3DVERTEXBUFFER vb = d3dCtx->pVB;
+ HRESULT hr;
+ LPDIRECT3DDEVICE8 device = d3dCtx->pDevice;
+
+ int vbSize;
+
+ if (!expandQuadIndex) {
+ vbSize = indexCount;
+ } else {
+ vbSize = (3*indexCount) >> 1;
+ }
+
+ if (vb->stripLen > 0) {
+ // VertexBuffer already used, create a new one or used
+ // the next VB in the list
+ // maxVertexLimit is already check before, so we can
+ // pass indexCount as maxVertexLimit.
+ // The maximum vertex that can happens is equal
+ // to indexCount so we can just set vcount = indexCount
+ vb = vb->nextVB;
+ if ((vb != NULL) && (vb->vcount < vbSize)) {
+ delete vb;
+ d3dCtx->pVB->nextVB = NULL;
+ vb = NULL;
+ }
+
+ if (vb == NULL) {
+ vb = new D3dVertexBuffer();
+ if (vb == NULL) {
+ D3dCtx::d3dWarning(OUTOFMEMORY);
+ return false;
+ }
+
+ vb->stride = d3dCtx->pVB->stride;
+ vb->vertexFormat = d3dCtx->pVB->vertexFormat;
+ // Don't set totalVertexCount
+ vb->isIndexPrimitive = d3dCtx->pVB->isIndexPrimitive;
+ vb->primitiveType = d3dCtx->pVB->primitiveType;
+ vb->isPointFlagUsed = d3dCtx->pVB->isPointFlagUsed;
+ vb->vcount = vbSize;
+ vb->maxVertexLimit = maxVertexLimit;
+
+#ifdef VBDEBUG
+ printf("Create secondary VertexBuffer of size %d, display list ID %d, pointFlag %d\n",
+ vbSize, d3dCtx->currDisplayListID, vb->isPointFlagUsed);
+#endif
+
+ if (!vb->isPointFlagUsed) {
+ hr = device->CreateVertexBuffer(vb->stride*vbSize,
+ D3DUSAGE_WRITEONLY,
+ vb->vertexFormat,
+ D3DPOOL_DEFAULT,
+ &vb->buffer);
+ } else {
+ hr = device->CreateVertexBuffer(vb->stride*vbSize,
+ D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS,
+ vb->vertexFormat,
+ D3DPOOL_DEFAULT,
+ &vb->buffer);
+ vb->isPointFlagUsed = true;
+ }
+
+ if (FAILED(hr)) {
+ vb->buffer = NULL;
+ vb->release();
+ D3dCtx::d3dWarning(CREATEVBFAIL, hr);
+ return false;
+ }
+ d3dCtx->pVB->nextVB = vb;
+ cDirty = javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED;
+ }
+ }
+
+ if (vb->indexBuffer == NULL) {
+ // No need to set totalIndexCount
+ vb->indexCount = vbSize;
+
+ if (indexCount <= 0xffff) {
+ hr = device->CreateIndexBuffer(vbSize*sizeof(WORD),
+ D3DUSAGE_WRITEONLY,
+ D3DFMT_INDEX16,
+ D3DPOOL_DEFAULT,
+ &vb->indexBuffer);
+ } else {
+ hr = device->CreateIndexBuffer(vbSize*sizeof(UINT),
+ D3DUSAGE_WRITEONLY,
+ D3DFMT_INDEX32,
+ D3DPOOL_DEFAULT,
+ &vb->indexBuffer);
+ }
+
+ if (FAILED(hr)) {
+ vb->indexBuffer = NULL;
+ vb->release();
+ D3dCtx::d3dWarning(CREATEINDEXVBFAIL, hr);
+ return false;
+ }
+
+ cDirty |= javax_media_j3d_GeometryArrayRetained_INDEX_CHANGED;
+ }
+
+ float *vbptr;
+ // Note that DWORD (use for color) is of same size
+ // as float (use for vertex/normal)
+ hr = vb->buffer->Lock(0, 0, (BYTE**)&vbptr, 0);
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKVBFAIL, hr);
+ // recreate it next time
+ vb->release();
+ return false;
+ }
+
+ d3dCtx->pVB = vb;
+
+ // The current VB is not yet used.
+ vb->stripLen = 0;
+
+ if (cDirty) {
+ D3DINDEXBUFFER_DESC desc;
+ BYTE *bptr;
+
+ vb->indexBuffer->GetDesc(&desc);
+ hr = vb->indexBuffer->Lock(0, 0, &bptr, 0);
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKINDEXVBFAIL, hr);
+ vb->buffer->Unlock();
+ return false;
+ }
+
+ if (d3dCtx->reIndexifyTable == NULL) {
+ // vcount will not change during renderIndexGeometry
+ // and splitIndexVertex so it is safe not to check
+ // size of reIndexifyTable and recreate a bigger
+ // one.
+ d3dCtx->reIndexifyTable = new DWORD[vcount];
+ if (d3dCtx->reIndexifyTable == NULL) {
+ D3dCtx::d3dWarning(OUTOFMEMORY, hr);
+ vb->release();
+ return false;
+ }
+
+ }
+
+ ZeroMemory(d3dCtx->reIndexifyTable, sizeof(DWORD)*vcount);
+
+ DWORD i;
+ jint *idxPtr = strideData->indexPtr + strideData->initialIndexIndex;
+ USHORT firstEntry = *idxPtr;
+ DWORD *table = d3dCtx->reIndexifyTable;
+
+ if (desc.Format == D3DFMT_INDEX16) {
+ USHORT *dst = (USHORT *) bptr;
+ USHORT newIdx, prevIdx = -1, count = 0;
+ USHORT idx[3], vc = 0;
+
+ for (i=0; i < indexCount; i++) {
+ newIdx = table[*idxPtr];
+ if ((newIdx == 0) && (*idxPtr != firstEntry)) {
+ newIdx = ++count;
+ table[*idxPtr] = newIdx;
+ }
+ if (!expandQuadIndex) {
+ *dst++ = newIdx;
+ } else {
+ if (vc < 3) {
+ idx[vc++] = newIdx;
+ } else {
+ // vc = 3
+ *dst++ = idx[0];
+ *dst++ = idx[1];
+ *dst++ = idx[2];
+ *dst++ = idx[0];
+ *dst++ = idx[2];
+ *dst++ = newIdx;
+ vc = 0;
+ }
+ }
+ if (newIdx != prevIdx) {
+ copyOneVertexToVB(d3dCtx, &vbptr, strideData,
+ *idxPtr++, cDirty, xform, nxform);
+ prevIdx = newIdx;
+ } else {
+ idxPtr++;
+ }
+
+ }
+ } else {
+ DWORD *dst = (DWORD *) bptr;
+ DWORD newIdx, prevIdx = -1, count = 0;
+ DWORD idx[3], vc = 0;
+
+ for (i=0; i < indexCount; i++) {
+ newIdx = table[*idxPtr];
+ if ((newIdx == 0) && (*idxPtr != firstEntry)) {
+ newIdx = ++count;
+ table[*idxPtr] = newIdx;
+ }
+ if (!expandQuadIndex) {
+ *dst++ = newIdx;
+ } else {
+ if (vc < 3) {
+ idx[vc++] = newIdx;
+ } else {
+ // vc = 3
+ *dst++ = idx[0];
+ *dst++ = idx[1];
+ *dst++ = idx[2];
+ *dst++ = idx[0];
+ *dst++ = idx[2];
+ *dst++ = newIdx;
+ vc = 0;
+ }
+ }
+ if (newIdx != prevIdx) {
+ copyOneVertexToVB(d3dCtx, &vbptr, strideData,
+ *idxPtr++, cDirty, xform, nxform);
+ prevIdx = newIdx;
+ } else {
+ idxPtr++;
+ }
+ }
+ }
+ }
+
+
+ vb->addStride(vbSize);
+ vb->indexBuffer->Unlock();
+ vb->buffer->Unlock();
+ return true;
+}
+
+
+void splitIndexVertexToMultipleVB(D3dCtx *d3dCtx,
+ LPD3DDRAWPRIMITIVESTRIDEDDATA strideData,
+ int indexCount,
+ int vertexCount,
+ int maxVertexLimit,
+ jint cDirty,
+ BOOL expandQuadIndex,
+ jdouble* xform,
+ jdouble* nxform)
+{
+ int vc;
+ BOOL success;
+ int inc;
+ int min = 0;
+ int max = 0;
+ int initialIdxIdx = strideData->initialIndexIndex;
+
+
+ switch (d3dCtx->pVB->primitiveType) {
+ case D3DPT_TRIANGLEFAN:
+ {
+ jint firstIdx = strideData->indexPtr[initialIdxIdx];
+ jint prevIdx = firstIdx;
+
+ inc = maxVertexLimit - 2;
+
+ while (true) {
+ vc = (indexCount >= maxVertexLimit ? maxVertexLimit : indexCount);
+ success = reIndexifyIndexVertexToVBs(d3dCtx,
+ strideData,
+ vc,
+ vertexCount,
+ cDirty,
+ expandQuadIndex,
+ maxVertexLimit,
+ xform, nxform);
+ // restore index
+ strideData->indexPtr[strideData->initialIndexIndex] = prevIdx;
+ indexCount -= inc;
+
+ if (!success || (indexCount <= 2)) {
+ break;
+ }
+ // repeat the last index
+ strideData->initialIndexIndex += (vc - 2);
+ // replace by first index
+ prevIdx = strideData->indexPtr[strideData->initialIndexIndex];
+ strideData->indexPtr[strideData->initialIndexIndex] = firstIdx;
+ }
+ }
+ break;
+ case D3DPT_POINTLIST:
+ if (max == 0) {
+ max = maxVertexLimit;
+ }
+ // fall through
+ case D3DPT_LINESTRIP:
+ if (max == 0) {
+ max = maxVertexLimit;
+ min = 1; // repeat the last vertex;
+ }
+ // fall through
+ case D3DPT_TRIANGLELIST:
+ if (max == 0) {
+ if (expandQuadIndex) {
+ // QuadArray
+ max = maxVertexLimit - (maxVertexLimit % 4);
+ } else {
+ max = maxVertexLimit - (maxVertexLimit % 3);
+ }
+ }
+ // fall through
+ case D3DPT_LINELIST:
+ if (max == 0) {
+ max = maxVertexLimit - (maxVertexLimit % 2);
+ }
+ // fall through
+ case D3DPT_TRIANGLESTRIP:
+ if (max == 0) {
+ max = maxVertexLimit - (maxVertexLimit % 4);
+ min = 2; // repeat the last two vertices
+ }
+ inc = max - min;
+
+ while (true) {
+ vc = (indexCount >= max ? max : indexCount);
+
+ if (!reIndexifyIndexVertexToVBs(d3dCtx,
+ strideData,
+ vc,
+ vertexCount,
+ cDirty,
+ expandQuadIndex,
+ maxVertexLimit,
+ xform, nxform)) {
+ break;
+ }
+
+ indexCount -= inc;
+ if (indexCount <= min) {
+ break;
+ }
+ strideData->initialIndexIndex += inc;
+ }
+ }
+ strideData->initialIndexIndex = initialIdxIdx;
+}
+
+// This is used by quad polygon line mode
+void DrawPolygonLine(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ DWORD vertexFormat,
+ D3DDRAWPRIMITIVESTRIDEDDATA *strideData)
+{
+ HRESULT hr;
+ float *vbptr;
+
+ hr = d3dCtx->pVB->buffer->Lock(0, 0, (BYTE**) &vbptr, 0 );
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKVBFAIL, hr);
+ return;
+ }
+ // DisplayList will not use in this case, so xform = nxform = NULL
+ copyVertexToVB(d3dCtx, strideData, 4, &vbptr,
+ javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED, true,
+ NULL, NULL);
+ d3dCtx->pVB->buffer->Unlock();
+ device->SetStreamSource(0, d3dCtx->pVB->buffer,
+ d3dCtx->pVB->stride);
+ device->SetIndices(d3dCtx->lineModeIndexBuffer, 0);
+ device->SetVertexShader(vertexFormat);
+
+ device->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0, 4, 0, 4);
+}
+
+
+// This is used by indexed quad polygon line mode
+void DrawIndexPolygonLine(D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ DWORD vertexFormat,
+ D3DDRAWPRIMITIVESTRIDEDDATA *strideData,
+ jint idx0, jint idx1, jint idx2, jint idx3)
+{
+ HRESULT hr;
+ float *vbptr;
+
+ hr = d3dCtx->pVB->buffer->Lock(0, 0, (BYTE**) &vbptr, 0 );
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKVBFAIL, hr);
+ return;
+ }
+
+ copyOneVertexToVB(d3dCtx, &vbptr, strideData, idx0,
+ javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED,
+ NULL, NULL);
+ copyOneVertexToVB(d3dCtx, &vbptr, strideData, idx1,
+ javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED,
+ NULL, NULL);
+ copyOneVertexToVB(d3dCtx, &vbptr, strideData, idx2,
+ javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED,
+ NULL, NULL);
+ copyOneVertexToVB(d3dCtx, &vbptr, strideData, idx3,
+ javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED,
+ NULL, NULL);
+
+ d3dCtx->pVB->buffer->Unlock();
+ device->SetStreamSource(0, d3dCtx->pVB->buffer,
+ d3dCtx->pVB->stride);
+ device->SetVertexShader(vertexFormat);
+ device->SetIndices(d3dCtx->lineModeIndexBuffer, 0);
+
+ device->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0, 4, 0, 4);
+}
+
+
+void renderGeometry(JNIEnv *env,
+ D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ jobject geo,
+ jint geo_type,
+ D3DDRAWPRIMITIVESTRIDEDDATA *strideData,
+ DWORD vertexFormat,
+ jint vcount,
+ jdouble* xform,
+ jdouble* nxform,
+ jint cDirty)
+{
+ D3DPRIMITIVETYPE d3dRenderType;
+ BOOL renderTypeSet = false;
+ int i, j, genMode;
+ LPD3DVERTEXBUFFER vb = NULL;
+ D3dVertexBufferVector *vbVector;
+ float *vbptr;
+
+#ifdef VBDEBUG
+ BOOL createNew = false;
+#endif
+
+ if (vcount <= 0) {
+ return;
+ }
+
+ jclass geoClass = env->GetObjectClass(geo);
+ DWORD maxVertexLimit = d3dCtx->deviceInfo->maxVertexCount[geo_type];
+ DWORD texSetUsed = d3dCtx->texSetUsed;
+ HRESULT hr;
+ BOOL needPointFlag = (geo_type == GEO_TYPE_POINT_SET) ||
+ ((geo_type != GEO_TYPE_LINE_STRIP_SET) &&
+ (geo_type != GEO_TYPE_LINE_SET) &&
+ (d3dCtx->fillMode == D3DFILL_POINT));
+
+ BOOL buildDL = (d3dCtx->currDisplayListID > 0);
+
+ lockGeometry();
+
+ if (!buildDL) {
+ jfieldID fieldID = env->GetFieldID(geoClass, "pVertexBuffers", "J");
+ jobject cloneSource = NULL;
+
+ vbVector = reinterpret_cast<D3dVertexBufferVector *>
+ (env->GetLongField(geo, fieldID));
+
+ if (vbVector == NULL) {
+ // It is possible this is the mirrorGeometry
+ // from cloneNonIndexGeometry()
+ jfieldID fieldID2 = env->GetFieldID(geoClass,
+ "cloneSourceArray",
+ "Ljavax/media/j3d/IndexedGeometryArrayRetained;");
+ cloneSource = env->GetObjectField(geo, fieldID2);
+
+ if (cloneSource != NULL) {
+ jclass cloneClass = env->GetObjectClass(cloneSource);
+ fieldID = env->GetFieldID(cloneClass, "pVertexBuffers", "J");
+
+ vbVector = reinterpret_cast<D3dVertexBufferVector *>
+ (env->GetLongField(cloneSource, fieldID));
+ }
+
+ }
+
+
+ // This is the first time rendering is invoked on the
+ // first GeometryArray
+ if (vbVector == NULL) {
+ vbVector = new D3dVertexBufferVector();
+ if (vbVector == NULL) {
+ D3dCtx::d3dWarning(OUTOFMEMORY);
+ unlockGeometry();
+ return;
+ }
+ if (cloneSource == NULL) {
+ env->SetLongField(geo, fieldID,
+ reinterpret_cast<long>(vbVector));
+ } else {
+ env->SetLongField(cloneSource, fieldID,
+ reinterpret_cast<long>(vbVector));
+ }
+
+ } else {
+ // Found the vb in the list of vbVector
+ for (LPD3DVERTEXBUFFER *s = vbVector->begin();
+ s != vbVector->end(); ++s) {
+ if ((*s)->ctx == d3dCtx) {
+ vb = *s;
+ break;
+ }
+ }
+ }
+ }
+
+ if (vb == NULL) {
+ // This is the first time rendering is invoked
+ // using this ctx
+ vb = new D3dVertexBuffer();
+
+ if (vb == NULL) {
+ D3dCtx::d3dWarning(OUTOFMEMORY);
+ unlockGeometry();
+ return;
+ }
+ vb->ctx = d3dCtx;
+ vb->maxVertexLimit = maxVertexLimit;
+
+ if (!buildDL) {
+ vb->vbVector = vbVector;
+
+ // add it to the GeometryArray pVertexBuffers list
+ vbVector->push_back(vb);
+
+ // add it to the ctx lists
+ vb->next = d3dCtx->vertexBufferTable.next;
+ vb->previous = &(d3dCtx->vertexBufferTable);
+ d3dCtx->vertexBufferTable.next = vb;
+ if (vb->next != NULL) {
+ vb->next->previous = vb;
+ }
+ }
+ }
+
+ if ((vb->buffer != NULL) &&
+ ((vb->vertexFormat != vertexFormat) ||
+ (vb->totalVertexCount < vcount) ||
+ (cDirty &
+ javax_media_j3d_GeometryArrayRetained_STRIPCOUNT_CHANGED) ||
+ (!vb->isPointFlagUsed && needPointFlag))) {
+ // immediate release VB and reconstruct a new one
+ vb->release();
+ }
+
+ if (vb->buffer == NULL) {
+ vb->stride = D3DXGetFVFVertexSize(vertexFormat);
+ vb->vertexFormat = vertexFormat;
+ vb->totalVertexCount = vcount;
+ vb->vcount = (vcount >= maxVertexLimit ? maxVertexLimit : vcount);
+#ifdef VBDEBUG
+ printf("Create primary VertexBuffer of size %d, display list ID %d, pointFlag %d\n",
+ vb->vcount, d3dCtx->currDisplayListID, needPointFlag);
+#endif
+ if (!needPointFlag) {
+ hr = device->CreateVertexBuffer(vb->stride*vb->vcount,
+ D3DUSAGE_WRITEONLY,
+ vertexFormat,
+ D3DPOOL_DEFAULT,
+ &vb->buffer);
+ } else {
+ hr = device->CreateVertexBuffer(vb->stride*vb->vcount,
+ D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS,
+ vertexFormat,
+ D3DPOOL_DEFAULT,
+ &vb->buffer);
+ vb->isPointFlagUsed = true;
+ }
+
+ if (FAILED(hr)) {
+ vb->buffer = NULL;
+ D3dCtx::d3dWarning(CREATEVBFAIL, hr);
+ unlockGeometry();
+ return;
+ }
+#ifdef VBDEBUG
+ createNew = true;
+#endif
+ cDirty = javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED;
+ }
+
+ unlockGeometry();
+
+ if (buildDL) {
+ // In display list mode, add it to the displayList ID table
+ d3dCtx->displayListTable[d3dCtx->currDisplayListID]->add(vb);
+ } else {
+
+ if (vb->primitiveType == D3DPT_FORCE_DWORD) {
+ // This happens when previous frame use Quad Line
+ // so buffer not yet initialize
+ cDirty = javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED;
+ }
+
+ if (!cDirty &&
+ ((geo_type != GEO_TYPE_QUAD_SET) ||
+ (d3dCtx->fillMode != D3DFILL_WIREFRAME))) {
+ for (i=0; i < d3dCtx->texSetUsed; i++) {
+ genMode = strideData->texCoordPosition[i];
+ if ((genMode == TEX_OBJ_LINEAR) ||
+ ((genMode != vb->texCoordPosition[i]) &&
+ (genMode != TEX_GEN_AUTO))) {
+ // For object linear mode user can set the plane
+ // equations so we need to change texture coordinate.
+ break;
+ }
+ }
+ if (i == d3dCtx->texSetUsed) {
+ vb->render(d3dCtx);
+#ifdef TEXDEBUG
+ printf("Skip VB Copy\n");
+#endif
+ return;
+ }
+ }
+ }
+
+ // Note that DWORD (use for color) is of same size
+ // as float (use for vertex/normal)
+
+ hr = vb->buffer->Lock(0, 0, (BYTE**)&vbptr, 0);
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKVBFAIL, hr);
+ // recreate it next time
+ vb->release();
+ return;
+ }
+
+ d3dCtx->pVB = vb;
+ // The current VB is not yet used.
+ vb->stripLen = 0;
+
+ switch (geo_type) {
+ case GEO_TYPE_TRI_STRIP_SET:
+ d3dRenderType = D3DPT_TRIANGLESTRIP;
+ renderTypeSet = true;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("Tri strip set %d\n", vcount);
+ }
+#endif
+ // fall through
+ case GEO_TYPE_TRI_FAN_SET:
+ if (renderTypeSet == false) {
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("Tri fan set %d\n", vcount);
+ }
+#endif
+ d3dRenderType = D3DPT_TRIANGLEFAN;
+ renderTypeSet = true;
+ }
+ // fall through
+ case GEO_TYPE_LINE_STRIP_SET:
+ {
+ if (renderTypeSet == false) {
+ d3dRenderType = D3DPT_LINESTRIP;
+ renderTypeSet = true;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("Tri line set %d \n", vcount);
+ }
+#endif
+ }
+
+ jfieldID strip_field = env->GetFieldID(geoClass,
+ "stripVertexCounts", "[I");
+ jarray sarray = (jarray)env->GetObjectField(geo, strip_field);
+ jsize strip_len = (jsize)env->GetArrayLength(sarray);
+
+ jint* strips = (jint *)env->GetPrimitiveArrayCritical(sarray, NULL);
+
+ int nlastStrip = 0;
+ int totalLen = 0;
+ int oldTotalLen = 0;
+ int vsum = 0;
+
+ vb->primitiveType = d3dRenderType;
+
+ if (vcount <= vb->vcount) {
+ copyVertexToVB(d3dCtx, strideData, vcount,
+ &vbptr, cDirty, false, xform, nxform);
+ vb->addStrides(strip_len, strips);
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("Strip Length %d : ", strip_len);
+ for (int k=0; k < strip_len; k++) {
+ printf("%d ", strips[k]);
+ }
+ printf("\n");
+ }
+#endif
+ } else {
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("Strip Length %d : ", strip_len);
+ }
+#endif
+
+ for (i = 0; i < strip_len; i++) {
+ if (strideData->fpositionPtr) {
+ strideData->fpositionPtr +=
+ strideData->positionStride*nlastStrip;
+ } else {
+ strideData->dpositionPtr +=
+ strideData->positionStride*nlastStrip;
+ }
+
+ if (strideData->normalPtr) {
+ strideData->normalPtr +=
+ strideData->normalStride*nlastStrip;
+ }
+
+ if (strideData->fdiffusePtr) {
+ strideData->fdiffusePtr +=
+ strideData->diffuseStride*nlastStrip;
+ } else if (strideData->bdiffusePtr) {
+ strideData->bdiffusePtr +=
+ strideData->diffuseStride*nlastStrip;
+ }
+
+
+ if (strideData->textureCoordsPtr[0]) {
+ for (j=0; j < texSetUsed; j++) {
+ strideData->textureCoordsPtr[j] +=
+ strideData->textureCoordsStride[j]* nlastStrip;
+ }
+ }
+
+
+ nlastStrip = strips[i];
+ oldTotalLen = totalLen;
+ totalLen += nlastStrip;
+
+ if (totalLen > vcount) {
+ // This should not happen since
+ // setValidVertexCount is disable
+ // in v1.3. We should always have
+ // (sum of strips[] < vcount)
+ nlastStrip = (vcount - (totalLen - nlastStrip));
+ totalLen = vcount;
+ }
+
+ if (nlastStrip <= 0) {
+ continue;
+ }
+
+
+ if (vbptr == NULL) {
+ // This happen when the lastStrip copy
+ // is greater than maxVertexLimit.
+ // So we Unlock the last buffer
+ vbptr = allocateVB(d3dCtx, device,
+ vcount - oldTotalLen,
+ maxVertexLimit, &cDirty);
+ vsum = 0;
+ if (vbptr == NULL) {
+ break; // render whatever geometry the current VB have
+ }
+ }
+#ifdef VBDEBUG
+ if (createNew) {
+ printf(" %d ", nlastStrip);
+ }
+#endif
+ if ((vsum + nlastStrip) <= d3dCtx->pVB->vcount) {
+ // There is space available to put in vertices
+ vsum += nlastStrip;
+ copyVertexToVB(d3dCtx, strideData, nlastStrip,
+ &vbptr, cDirty, true, xform, nxform);
+ } else {
+ // Need to create a new VB
+ if (nlastStrip <= maxVertexLimit) {
+ // No need to split strip in multiple VB
+ if (d3dCtx->pVB->stripLen > 0) {
+ if (vbptr != NULL) {
+ d3dCtx->pVB->buffer->Unlock();
+ }
+ vbptr = allocateVB(d3dCtx, device,
+ vcount - oldTotalLen,
+ maxVertexLimit, &cDirty);
+ if (vbptr == NULL) {
+ break;
+ }
+ vsum = 0;
+ }
+ vsum += nlastStrip;
+ copyVertexToVB(d3dCtx, strideData, nlastStrip,
+ &vbptr, cDirty, true,
+ xform, nxform);
+ } else {
+ d3dCtx->pVB->buffer->Unlock();
+ vbptr = NULL;
+ vsum = 0;
+ // Multiple VBs for large vertex size
+ splitVertexToMultipleVB(d3dCtx, strideData,
+ nlastStrip,
+ maxVertexLimit,
+ cDirty, xform, nxform);
+ vbptr = NULL;
+ }
+ }
+ }
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("\n");
+ }
+#endif
+ }
+ env->ReleasePrimitiveArrayCritical(sarray, strips, NULL);
+ }
+ break;
+ case GEO_TYPE_QUAD_SET:
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("quad set %d\n", vcount);
+ }
+#endif
+
+ if (buildDL ||
+ (d3dCtx->fillMode != D3DFILL_WIREFRAME)) {
+ /*
+ * Note we can't just check
+ * if (d3dCtx->fillMode != D3DFILL_WIREFRAME)
+ * since the fillMode may set back to
+ * non-line mode AFTER build display list
+ * In fact it is gaurantee that when displaylist
+ * mode is used we are not in line mode
+ */
+
+ // break down solid into two triangles
+ if (createQuadIndices(d3dCtx, vcount)) {
+ // It happens when
+ // vcount*3/2 != d3dCtx->quadIndexBufferSize
+ // to conform with index buffer Limitation in
+ // graphics card. So we adjust using a smaller
+ // maxVertexLimit when spliting into
+ // multiple Vertex Buffers.
+ maxVertexLimit = 2*d3dCtx->quadIndexBufferSize/3;
+ vb->maxVertexLimit = maxVertexLimit;
+ vb->vcount = vb->maxVertexLimit;
+ }
+ d3dRenderType = D3DPT_TRIANGLELIST;
+ vb->isIndexPrimitive = true;
+ renderTypeSet = true;
+ // fall through
+ } else { // line mode
+ // we don't want to see extra line appear in the
+ // diagonal of quads if it splits into two
+ // triangles. This is REALLY SLOW !!!
+ int len = vcount >> 2;
+ int offsetPos = 0;
+ int offsetNorm = 0;
+ int offsetColor = 0;
+ int strideOffsetPos = strideData->positionStride << 2;
+ int strideOffsetNorm = strideData->normalStride << 2;
+ int strideOffsetColor = strideData->diffuseStride << 2;
+ jfloat *pdf = strideData->fpositionPtr;
+ jdouble *pdd = strideData->dpositionPtr;
+ jfloat *pn = strideData->normalPtr;
+ jfloat *pcf = strideData->fdiffusePtr;
+ jbyte *pcb = strideData->bdiffusePtr;
+ jfloat* pt[D3DDP_MAXTEXCOORD];
+
+ pt[0] = NULL;
+
+ if (((vertexFormat & D3DFVF_DIFFUSE) == 0) &&
+ (!d3dCtx->isLightEnable)) {
+ d3dCtx->setAmbientLightMaterial();
+ }
+
+ vb->buffer->Unlock();
+ vbptr = NULL;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("quad set polygon line %d\n", vcount);
+ }
+#endif
+
+ for (i=0; i < texSetUsed; i++) {
+ pt[i] = (FLOAT *) strideData->textureCoordsPtr[i];
+ }
+
+ jfloat *fptr;
+ jdouble *dptr;
+ jbyte *bptr;
+ jfloat *fspt;
+ jdouble *dspt;
+ int posStride = strideData->positionStride;
+ D3DVERTEX worldCoord[3];
+ D3DTLVERTEX screenCoord[3];
+
+ vb->primitiveType = D3DPT_FORCE_DWORD;
+
+ if (d3dCtx->lineModeIndexBuffer == NULL) {
+ createLineModeIndexBuffer(d3dCtx);
+ }
+
+ for (i = 0; i < (vcount >> 2); i++) {
+ if (pdf) {
+ fspt = fptr = pdf + offsetPos;
+ strideData->fpositionPtr = fptr;
+ } else {
+ dspt = dptr = pdd + offsetPos;
+ strideData->dpositionPtr = dptr;
+ }
+
+ if (pn) {
+ fptr = pn + offsetNorm;
+ strideData->normalPtr = fptr;
+ }
+
+ if (pcf) {
+ fptr = pcf + offsetColor;
+ strideData->fdiffusePtr = fptr;
+ } else if (pcb) {
+ bptr = pcb + offsetColor;
+ strideData->bdiffusePtr = bptr;
+ }
+
+ if (pt[0]) {
+ for (j=0; j < texSetUsed; j++) {
+ DWORD stride3 = 3*strideData->textureCoordsStride[j];
+ fptr = pt[j] + i*(strideData->textureCoordsStride[j] << 2);
+ strideData->textureCoordsPtr[j] = fptr;
+ }
+ }
+ if (d3dCtx->cullMode != D3DCULL_NONE) {
+ // Do back face culling here
+ if (pdf) {
+ worldCoord[0].x = fspt[0];
+ worldCoord[0].y = fspt[1];
+ worldCoord[0].z = fspt[2];
+ fspt += posStride;
+ worldCoord[1].x = fspt[0];
+ worldCoord[1].y = fspt[1];
+ worldCoord[1].z = fspt[2];
+ fspt += posStride;
+ worldCoord[2].x = fspt[0];
+ worldCoord[2].y = fspt[1];
+ worldCoord[2].z = fspt[2];
+ } else {
+ worldCoord[0].x = dspt[0];
+ worldCoord[0].y = dspt[1];
+ worldCoord[0].z = dspt[2];
+ dspt += posStride;
+ worldCoord[1].x = dspt[0];
+ worldCoord[1].y = dspt[1];
+ worldCoord[1].z = dspt[2];
+ dspt += posStride;
+ worldCoord[2].x = dspt[0];
+ worldCoord[2].y = dspt[1];
+ worldCoord[2].z = dspt[2];
+ }
+ d3dCtx->transform(&worldCoord[0], &screenCoord[0]);
+ d3dCtx->transform(&worldCoord[1], &screenCoord[1]);
+ d3dCtx->transform(&worldCoord[2], &screenCoord[2]);
+ screenCoord[0].sx -= screenCoord[1].sx;
+ screenCoord[0].sy -= screenCoord[1].sy;
+ screenCoord[2].sx -= screenCoord[1].sx;
+ screenCoord[2].sy -= screenCoord[1].sy;
+ if (d3dCtx->cullMode == D3DCULL_CW) {
+ // clip back face
+ if ((screenCoord[0].sx*screenCoord[2].sy -
+ screenCoord[2].sx*screenCoord[0].sy) >= 0) {
+ DrawPolygonLine(d3dCtx,
+ device,
+ vertexFormat,
+ strideData);
+ }
+ } else { // Clip front face
+ if ((screenCoord[0].sx*screenCoord[2].sy -
+ screenCoord[2].sx*screenCoord[0].sy) <= 0) {
+ DrawPolygonLine(d3dCtx,
+ device,
+ vertexFormat,
+ strideData);
+ }
+ }
+ } else {
+ // cullMode == D3DCULL_NONE
+ DrawPolygonLine(d3dCtx,
+ device,
+ vertexFormat,
+ strideData);
+ }
+ offsetPos += strideOffsetPos;
+ offsetNorm += strideOffsetNorm;
+ offsetColor += strideOffsetColor;
+ }
+
+ if (((vertexFormat & D3DFVF_DIFFUSE) == 0) &&
+ (!d3dCtx->isLightEnable)) {
+ d3dCtx->restoreDefaultLightMaterial();
+ }
+ // Don't call vb->Renderer() at the end
+ return;
+ }
+ // fallthrough
+ case GEO_TYPE_TRI_SET:
+ if (renderTypeSet == false) {
+ d3dRenderType = D3DPT_TRIANGLELIST;
+ renderTypeSet = true;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("tri set %d\n", vcount);
+ }
+#endif
+ }
+ // fallthrough
+ case GEO_TYPE_LINE_SET:
+ if (renderTypeSet == false) {
+ d3dRenderType = D3DPT_LINELIST;
+ renderTypeSet = true;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("line set %d\n", vcount);
+ }
+#endif
+ }
+ // fallthrough
+ case GEO_TYPE_POINT_SET:
+ if (renderTypeSet == false) {
+ d3dRenderType = D3DPT_POINTLIST;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("point set %d\n", vcount);
+ }
+#endif
+ }
+ vb->primitiveType = d3dRenderType;
+
+ if (vcount <= vb->vcount) {
+ copyVertexToVB(d3dCtx, strideData, vcount, &vbptr,
+ cDirty, true, xform, nxform);
+ } else {
+ if (vbptr != NULL) {
+ vb->buffer->Unlock();
+ vbptr = NULL;
+ }
+
+ splitVertexToMultipleVB(d3dCtx, strideData, vcount,
+ maxVertexLimit,
+ cDirty, xform, nxform);
+ vbptr = NULL;
+ }
+ break;
+ default:
+ printf("GeometryArrayRetained_execute:unknown geo_type %ld \n", geo_type);
+ }
+
+ if (vbptr != NULL) {
+ // d3dCtx->pVB is the last reference in VB list
+ d3dCtx->pVB->buffer->Unlock();
+ }
+
+ for (i=0; i < d3dCtx->texSetUsed; i++) {
+ d3dCtx->pVB->texCoordPosition[i] =
+ strideData->texCoordPosition[i];
+ }
+
+ if (!buildDL) {
+ // Not in displaylist mode, directly render VB
+ // vb is the root reference in VB list
+ vb->render(d3dCtx);
+ }
+}
+
+
+void renderIndexGeometry(JNIEnv *env,
+ D3dCtx *d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ jobject geo,
+ jint geo_type,
+ D3DDRAWPRIMITIVESTRIDEDDATA *strideData,
+ DWORD vertexFormat,
+ jint vcount,
+ jint indexCount,
+ jdouble* xform,
+ jdouble* nxform,
+ jint cDirty)
+{
+ D3DPRIMITIVETYPE d3dRenderType;
+ BOOL renderTypeSet = false;
+ BOOL expandQuadIndex = false;
+ int i;
+ LPD3DVERTEXBUFFER vb = NULL;
+ D3dVertexBufferVector *vbVector;
+ float *vbptr;
+
+#ifdef VBDEBUG
+ BOOL createNew = false;
+#endif
+
+ if (indexCount <= 0) {
+ return;
+ }
+
+ jclass geoClass = env->GetObjectClass(geo);
+ DWORD maxVertexLimit =
+ min(d3dCtx->deviceInfo->maxVertexCount[geo_type],
+ d3dCtx->deviceInfo->maxVertexIndex);
+ DWORD texSetUsed = d3dCtx->texSetUsed;
+ HRESULT hr;
+ BOOL needPointFlag = (geo_type == GEO_TYPE_INDEXED_POINT_SET) ||
+ ((geo_type != GEO_TYPE_INDEXED_LINE_STRIP_SET) &&
+ (geo_type != GEO_TYPE_INDEXED_LINE_SET) &&
+ (d3dCtx->fillMode == D3DFILL_POINT));
+
+ BOOL buildDL = (d3dCtx->currDisplayListID > 0);
+
+ if (geo_type == GEO_TYPE_INDEXED_QUAD_SET) {
+ // Since the index we create with be 1.5 times the original index
+ maxVertexLimit = 2*maxVertexLimit/3;
+ }
+
+
+ lockGeometry();
+
+ if (!buildDL) {
+ jfieldID fieldID = env->GetFieldID(geoClass, "pVertexBuffers", "J");
+ vbVector = reinterpret_cast<D3dVertexBufferVector *>
+ (env->GetLongField(geo, fieldID));
+
+ if (vbVector == NULL) {
+ // This is the first time rendering is invoked on the
+ // first GeometryArray
+ vbVector = new D3dVertexBufferVector();
+ if (vbVector == NULL) {
+ D3dCtx::d3dWarning(OUTOFMEMORY);
+ unlockGeometry();
+ return;
+ }
+ env->SetLongField(geo, fieldID, reinterpret_cast<long>(vbVector));
+ } else {
+ // Found the vb in the list of vbVector
+ for (LPD3DVERTEXBUFFER *s = vbVector->begin();
+ s != vbVector->end(); ++s) {
+ if ((*s)->ctx == d3dCtx) {
+ vb = *s;
+ break;
+ }
+ }
+ }
+ }
+
+ if (vb == NULL) {
+ // This is the first time rendering is invoked
+ // using this ctx
+ vb = new D3dVertexBuffer();
+
+ if (vb == NULL) {
+ D3dCtx::d3dWarning(OUTOFMEMORY);
+ unlockGeometry();
+ return;
+ }
+ vb->ctx = d3dCtx;
+ vb->maxVertexLimit = maxVertexLimit;
+
+ if (!buildDL) {
+ vb->vbVector = vbVector;
+
+ // add it to the GeometryArray pVertexBuffers list
+ vbVector->push_back(vb);
+
+ // add it to the ctx lists
+ vb->next = d3dCtx->vertexBufferTable.next;
+ vb->previous = &(d3dCtx->vertexBufferTable);
+ d3dCtx->vertexBufferTable.next = vb;
+ if (vb->next != NULL) {
+ vb->next->previous = vb;
+ }
+ }
+ }
+
+ if (((vb->indexBuffer != NULL) &&
+ (vb->totalIndexCount < indexCount)) ||
+ ((vb->buffer != NULL) &&
+ ((vb->vertexFormat != vertexFormat) ||
+ (vb->totalVertexCount < vcount) ||
+ (!vb->isPointFlagUsed && needPointFlag)))) {
+ // immediate release VB and reconstruct a new one
+ vb->release();
+ }
+
+
+ if (vb->buffer == NULL) {
+ vb->stride = D3DXGetFVFVertexSize(vertexFormat);
+ vb->vertexFormat = vertexFormat;
+ vb->totalVertexCount = vcount;
+ vb->isIndexPrimitive = true;
+ vb->vcount = (vcount >= maxVertexLimit ? maxVertexLimit : vcount);
+#ifdef VBDEBUG
+ printf("Create primary VertexBuffer of size %d, display list ID %d, pointFlag %d\n",
+ vb->vcount, d3dCtx->currDisplayListID, needPointFlag);
+#endif
+
+ if (!needPointFlag) {
+ hr = device->CreateVertexBuffer(vb->stride*vb->vcount,
+ D3DUSAGE_WRITEONLY,
+ vertexFormat,
+ D3DPOOL_DEFAULT,
+ &vb->buffer);
+ } else {
+ hr = device->CreateVertexBuffer(vb->stride*vb->vcount,
+ D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS,
+ vertexFormat,
+ D3DPOOL_DEFAULT,
+ &vb->buffer);
+ vb->isPointFlagUsed = true;
+ }
+
+ if (FAILED(hr)) {
+ vb->buffer = NULL;
+ D3dCtx::d3dWarning(CREATEVBFAIL, hr);
+ unlockGeometry();
+ return;
+ }
+#ifdef VBDEBUG
+ createNew = true;
+#endif
+ cDirty = javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED;
+ }
+
+ if (vb->indexBuffer == NULL) {
+
+ vb->totalIndexCount = indexCount;
+ vb->indexCount = (indexCount >= maxVertexLimit ?
+ maxVertexLimit : indexCount);
+
+ if (geo_type == GEO_TYPE_INDEXED_QUAD_SET) {
+ // Since we will construct another index with
+ // 1.5 times of the original.
+ vb->indexCount = (3*vb->indexCount) >> 1;
+ vb->totalIndexCount = (3*indexCount) >> 1;
+ }
+
+
+ if (indexCount <= 0xffff) {
+ hr = device->CreateIndexBuffer(vb->indexCount*sizeof(WORD),
+ D3DUSAGE_WRITEONLY,
+ D3DFMT_INDEX16,
+ D3DPOOL_DEFAULT,
+ &vb->indexBuffer);
+ } else {
+ hr = device->CreateIndexBuffer(vb->indexCount*sizeof(UINT),
+ D3DUSAGE_WRITEONLY,
+ D3DFMT_INDEX32,
+ D3DPOOL_DEFAULT,
+ &vb->indexBuffer);
+ }
+
+ if (FAILED(hr)) {
+ vb->indexBuffer = NULL;
+ D3dCtx::d3dWarning(CREATEINDEXVBFAIL, hr);
+ unlockGeometry();
+ return;
+ }
+
+ cDirty |= javax_media_j3d_GeometryArrayRetained_INDEX_CHANGED;
+ }
+
+ unlockGeometry();
+
+ if (buildDL) {
+ // In display list mode, add it to the displayList ID table
+ d3dCtx->displayListTable[d3dCtx->currDisplayListID]->add(vb);
+ } else {
+
+ if (vb->primitiveType == D3DPT_FORCE_DWORD) {
+ // This happens when previous frame use Quad Line
+ // so buffer not yet initialize
+ cDirty =
+ javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED |
+ javax_media_j3d_GeometryArrayRetained_INDEX_CHANGED;
+ }
+
+ if (!cDirty &&
+ ((geo_type != GEO_TYPE_INDEXED_QUAD_SET) ||
+ (d3dCtx->fillMode != D3DFILL_WIREFRAME))) {
+ for (i=0; i < d3dCtx->texSetUsed; i++) {
+ if ((strideData->texCoordPosition[i] !=
+ vb->texCoordPosition[i])
+ &&
+ (strideData->texCoordPosition[i] != TEX_GEN_AUTO)) {
+ break;
+ }
+ }
+ if (i == d3dCtx->texSetUsed) {
+ vb->render(d3dCtx);
+ return;
+ }
+ }
+ }
+
+ // Note that DWORD (use for color) is of same size
+ // as float (use for vertex/normal)
+ hr = vb->buffer->Lock(0, 0, (BYTE**)&vbptr, 0);
+ if (FAILED(hr)) {
+ D3dCtx::d3dWarning(LOCKVBFAIL, hr);
+ // recreate it next time
+ vb->release();
+ return;
+ }
+
+ d3dCtx->pVB = vb;
+
+ // The current VB is not yet used.
+ vb->stripLen = 0;
+
+ switch (geo_type) {
+ case GEO_TYPE_INDEXED_TRI_STRIP_SET:
+ d3dRenderType = D3DPT_TRIANGLESTRIP;
+ renderTypeSet = true;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("Tri strip set %d\n", vcount);
+ }
+#endif
+ // fall through
+ case GEO_TYPE_INDEXED_TRI_FAN_SET:
+ if (renderTypeSet == false) {
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("Tri fan set %d\n", vcount);
+ }
+#endif
+ d3dRenderType = D3DPT_TRIANGLEFAN;
+ renderTypeSet = true;
+ }
+ // fall through
+ case GEO_TYPE_INDEXED_LINE_STRIP_SET:
+ {
+ if (renderTypeSet == false) {
+ d3dRenderType = D3DPT_LINESTRIP;
+ renderTypeSet = true;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("Tri line set %d \n", vcount);
+ }
+#endif
+ }
+
+ jfieldID strip_field = env->GetFieldID(geoClass,
+ "stripIndexCounts", "[I");
+ jarray sarray = (jarray)env->GetObjectField(geo, strip_field);
+ jsize strip_len = (jsize)env->GetArrayLength(sarray);
+
+ jint* strips = (jint *)env->GetPrimitiveArrayCritical(sarray, NULL);
+ int nlastStrip = 0;
+
+ vb->primitiveType = d3dRenderType;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("Strip Length %d : ", strip_len);
+ }
+#endif
+
+ if ((vb->totalIndexCount <= vb->indexCount) &&
+ (vcount <= vb->vcount)) {
+ copyIndexVertexToVB(d3dCtx, strideData,
+ indexCount, cDirty, false, false);
+ copyVertexToVB(d3dCtx, strideData, vcount,
+ &vbptr, cDirty, false, xform, nxform);
+ vb->addStrides(strip_len, strips);
+ } else {
+ vb->buffer->Unlock();
+ vbptr = NULL;
+ strideData->indexPtr += strideData->initialIndexIndex;
+ strideData->initialIndexIndex = 0;
+ for (i = 0; i < strip_len; i++) {
+ strideData->indexPtr += nlastStrip;
+
+ nlastStrip = strips[i];
+
+ if (nlastStrip <= 0) {
+ continue;
+ }
+#ifdef VBDEBUG
+ if (createNew) {
+ printf(" %d", nlastStrip);
+ }
+#endif
+ if (nlastStrip <= vb->indexCount) {
+ reIndexifyIndexVertexToVBs(d3dCtx, strideData,
+ nlastStrip, vcount,
+ cDirty,
+ false,
+ maxVertexLimit,
+ xform, nxform);
+ } else {
+ // Multiple VBs for large vertex size
+ splitIndexVertexToMultipleVB(d3dCtx,
+ strideData,
+ nlastStrip,
+ vcount,
+ maxVertexLimit,
+ cDirty,
+ false,
+ xform, nxform);
+ }
+ SafeDelete(d3dCtx->reIndexifyTable);
+ }
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("\n");
+ }
+#endif
+ }
+ env->ReleasePrimitiveArrayCritical(sarray, strips, NULL);
+ }
+
+ break;
+ case GEO_TYPE_INDEXED_QUAD_SET:
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("quad set %d\n", vcount);
+ }
+#endif
+ if (buildDL ||
+ (d3dCtx->fillMode != D3DFILL_WIREFRAME)) {
+ d3dRenderType = D3DPT_TRIANGLELIST;
+ renderTypeSet = true;
+ expandQuadIndex = true;
+ // fall through
+ } else { // polygon line mode
+ // we don't want to see extra line appear in the
+ // diagonal of quads if it splits into two
+ // triangles. This is REALLY SLOW !!!
+ int posStride = strideData->positionStride;
+ D3DVERTEX worldCoord[3];
+ D3DTLVERTEX screenCoord[3];
+ jint *idxPtr = strideData->indexPtr;
+ jfloat *fspt;
+ jdouble *dspt;
+ jint idx0, idx1, idx2, idx3;
+
+ if (((vertexFormat & D3DFVF_DIFFUSE) == 0) &&
+ (!d3dCtx->isLightEnable)) {
+ d3dCtx->setAmbientLightMaterial();
+ }
+
+ vb->buffer->Unlock();
+ vbptr = NULL;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("indexed quad set polygon line %d\n", vcount);
+ }
+#endif
+ if (d3dCtx->lineModeIndexBuffer == NULL) {
+ createLineModeIndexBuffer(d3dCtx);
+ }
+
+ vb->primitiveType = D3DPT_FORCE_DWORD;
+
+ for (i = 0; i < (indexCount >> 2); i++) {
+ if (d3dCtx->cullMode != D3DCULL_NONE) {
+ // Do back face culling here
+ idx0 = *idxPtr++;
+ idx1 = *idxPtr++;
+ idx2 = *idxPtr++;
+ idx3 = *idxPtr++;
+ if (strideData->fpositionPtr) {
+ fspt = strideData->fpositionPtr + posStride*idx0;
+ worldCoord[0].x = *fspt++;
+ worldCoord[0].y = *fspt++;
+ worldCoord[0].z = *fspt++;
+ fspt = strideData->fpositionPtr + posStride*idx1;
+ worldCoord[1].x = *fspt++;
+ worldCoord[1].y = *fspt++;
+ worldCoord[1].z = *fspt++;
+ fspt = strideData->fpositionPtr + posStride*idx2;
+ worldCoord[2].x = *fspt++;
+ worldCoord[2].y = *fspt++;
+ worldCoord[2].z = *fspt++;
+ } else {
+ dspt = strideData->dpositionPtr + posStride*idx0;
+ worldCoord[0].x = *dspt++;
+ worldCoord[0].y = *dspt++;
+ worldCoord[0].z = *dspt++;
+ dspt = strideData->dpositionPtr + posStride*idx1;
+ worldCoord[1].x = *dspt++;
+ worldCoord[1].y = *dspt++;
+ worldCoord[1].z = *dspt++;
+ dspt = strideData->dpositionPtr + posStride*idx2;
+ worldCoord[2].x = *dspt++;
+ worldCoord[2].y = *dspt++;
+ worldCoord[2].z = *dspt++;
+ }
+
+ d3dCtx->transform(&worldCoord[0], &screenCoord[0]);
+ d3dCtx->transform(&worldCoord[1], &screenCoord[1]);
+ d3dCtx->transform(&worldCoord[2], &screenCoord[2]);
+ screenCoord[0].sx -= screenCoord[1].sx;
+ screenCoord[0].sy -= screenCoord[1].sy;
+ screenCoord[2].sx -= screenCoord[1].sx;
+ screenCoord[2].sy -= screenCoord[1].sy;
+ if (d3dCtx->cullMode == D3DCULL_CW) {
+ if ((screenCoord[0].sx*screenCoord[2].sy -
+ screenCoord[2].sx*screenCoord[0].sy) >= 0) {
+ DrawIndexPolygonLine(d3dCtx,
+ device,
+ vertexFormat,
+ strideData,
+ idx0, idx1,
+ idx2, idx3);
+ }
+ } else { // Clip front face
+ if ((screenCoord[0].sx*screenCoord[2].sy -
+ screenCoord[2].sx*screenCoord[0].sy) <= 0) {
+ DrawIndexPolygonLine(d3dCtx,
+ device,
+ vertexFormat,
+ strideData,
+ idx0, idx1,
+ idx2, idx3);
+ }
+ }
+ } else {
+ // cullMode == D3DCULL_NONE
+ DrawIndexPolygonLine(d3dCtx,
+ device,
+ vertexFormat,
+ strideData,
+ idx0, idx1,
+ idx2, idx3);
+ }
+ }
+ if (((vertexFormat & D3DFVF_DIFFUSE) == 0) &&
+ (!d3dCtx->isLightEnable)) {
+ d3dCtx->restoreDefaultLightMaterial();
+ }
+ // Don't call vb->Renderer() at the end
+ return;
+ }
+ // fall through
+ case GEO_TYPE_INDEXED_TRI_SET:
+ if (renderTypeSet == false) {
+ d3dRenderType = D3DPT_TRIANGLELIST;
+ renderTypeSet = true;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("tri set %d\n", vcount);
+ }
+#endif
+ }
+ // fallthrough
+ case GEO_TYPE_INDEXED_LINE_SET:
+ if (renderTypeSet == false) {
+ d3dRenderType = D3DPT_LINELIST;
+ renderTypeSet = true;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("line set %d\n", vcount);
+ }
+#endif
+ }
+ // fallthrough
+ case GEO_TYPE_INDEXED_POINT_SET:
+ if (renderTypeSet == false) {
+ d3dRenderType = D3DPT_POINTLIST;
+#ifdef VBDEBUG
+ if (createNew) {
+ printf("point set %d\n", vcount);
+ }
+#endif
+ }
+ vb->primitiveType = d3dRenderType;
+
+ if (vb->totalIndexCount <= vb->indexCount) {
+ if (vcount <= vb->vcount) {
+ copyIndexVertexToVB(d3dCtx, strideData,
+ indexCount,
+ cDirty, true, expandQuadIndex);
+ copyVertexToVB(d3dCtx, strideData, vcount, &vbptr,
+ cDirty, false, xform, nxform);
+ } else {
+ vb->buffer->Unlock();
+ vbptr = NULL;
+ reIndexifyIndexVertexToVBs(d3dCtx, strideData,
+ indexCount, vcount,
+ cDirty,
+ expandQuadIndex,
+ maxVertexLimit,
+ xform, nxform);
+ SafeDelete(d3dCtx->reIndexifyTable);
+ }
+ } else {
+ vb->buffer->Unlock();
+ vbptr = NULL;
+ splitIndexVertexToMultipleVB(d3dCtx,
+ strideData,
+ indexCount,
+ vcount,
+ maxVertexLimit,
+ cDirty,
+ expandQuadIndex,
+ xform, nxform);
+ SafeDelete(d3dCtx->reIndexifyTable);
+ }
+ break;
+ default:
+ printf("IndexedGeometryArrayRetained_execute:unknown geo_type %ld \n", geo_type);
+ }
+
+ if (vbptr != NULL) {
+ // d3dCtx->pVB is the last reference in VB list
+ d3dCtx->pVB->buffer->Unlock();
+ }
+
+ // Save new texture position to detect any change
+ // in next round.
+ for (i=0; i < d3dCtx->texSetUsed; i++) {
+ d3dCtx->pVB->texCoordPosition[i] =
+ strideData->texCoordPosition[i];
+ }
+
+ if (!buildDL) {
+ // Not in displaylist mode, directly render VB
+ // vb is the root reference in VB list
+ vb->render(d3dCtx);
+ }
+}
+
+
+/*
+ * Set the default texture coordinate pointers when automatically
+ * texture generation is used or when there is application error
+ */
+inline void setDefaultTextureCoordPointers(D3dCtx *d3dCtx,
+ D3DDRAWPRIMITIVESTRIDEDDATA *strideData,
+ DWORD* vertexFormat,
+ jint ts,
+ int genMode,
+ int tus)
+{
+ strideData->textureCoordsPtr[tus] = &defaultTexCoord[0];
+ strideData->textureCoordsStride[tus] = 0;
+ strideData->texCoordPosition[tus] = genMode;
+ d3dCtx->texStride[tus] = ts;
+ *vertexFormat |= (TexFormatSizeTable[ts] << (tus*2 + 16));
+}
+
+
+/*
+ * Set the textureCoordStride & textureCoordsPtr in strideData
+ */
+void setTextureCoordPointers(JNIEnv *env,
+ D3dCtx* d3dCtx,
+ LPDIRECT3DDEVICE8 device,
+ D3DDRAWPRIMITIVESTRIDEDDATA *strideData,
+ jint pass,
+ jint texoff,
+ jint texStride,
+ jint ts,
+ jboolean textureDefined,
+ jintArray tcoordsetmap,
+ jint texCoordMapLength,
+ jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ DWORD* vertexFormat,
+ // Used by executeGeometryArray() &
+ // executeIndexedGeometryArray() only
+ jfloat* verts,
+ // Used by executeGeometryArrayVA() &
+ // executeIndexedGeometryArrayVA() only
+ jfloat** texCoordPointer,
+ // Used by executeGeometryArrayVA() only
+ jintArray texindices)
+
+{
+ jint *texUnitStateMap = NULL;
+ jint *texCoordSetMapOffset = NULL;
+ jint *initialTexIndices = NULL;
+ jint *texCoordSetMap = NULL;
+ jint textureUnitIndex;
+ int genMode;
+ jint offsetOrTexset;
+ BOOL nonVAGeom = (verts != NULL);
+ int texSetInVB = 0;
+
+ /*
+ * In case of automatic texture generation,
+ * (vformat & GA_TEXTURE_COORDINATE) may equal to zero so we
+ * can't wrap around this whole block with the condition.
+ */
+ d3dCtx->texSetUsed = 0;
+
+ // For GA buildGA(), numActiveTexUnit is 1 even though texture
+ // is not used. This is only accurate for execute() immediate case.
+ if (numActiveTexUnit <= 0) {
+ return;
+ }
+
+ if (texCoordMapLength > 0) {
+ if (nonVAGeom) {
+ // In executeGeometryArray() or executeIndexedGeometryArray()
+ texCoordSetMapOffset = (jint *) env->GetPrimitiveArrayCritical(texUnitOffset, NULL);
+ } else {
+ // In executeGeometryArrayVA() or executeIndexedGeometryArrayVA()
+ texCoordSetMap = (jint *)
+ env->GetPrimitiveArrayCritical(tcoordsetmap, NULL);
+ }
+
+ }
+
+ if (texindices != NULL) {
+ // In executeGeometryArrayVA()
+ initialTexIndices = (jint *) env->GetPrimitiveArrayCritical(texindices, NULL);
+ }
+
+ if (pass >= 0) {
+ /*
+ * Single texture coordinate used or in multi-pass mode.
+ * In multi-pass mode, texture stage 0 is set so we
+ * should not use
+ * setTextureStage(d3dCtx, device, 0, pass);
+ */
+
+ genMode = setTextureStage(d3dCtx, device, 0, 0);
+
+#ifdef TEXDEBUG
+ printf("*** Single Pass *** %d, nonVAGeom %d, buildDL %d, numActiveTexUnit, texCoordMapLength %d, texDef %d, genMode %d \n", pass, nonVAGeom, (d3dCtx->currDisplayListID > 0), numActiveTexUnit, texCoordMapLength, textureDefined, genMode);
+#endif
+
+ if ((texCoordMapLength > 0) &&
+ (pass < texCoordMapLength)) {
+ offsetOrTexset = (nonVAGeom ?
+ texCoordSetMapOffset[pass] : texCoordSetMap[pass]);
+ } else {
+ // TexUnitState is not used or disable,
+ // so by default we use texUnitIndex 0
+ offsetOrTexset = 0;
+ }
+
+ if (genMode != TEX_OBJ_LINEAR) {
+ // Only Object Linear Mode will not use DisplayList at
+ // all. That mean genMode must be correctly set before
+ // enter this Geometry execute() function/
+ // In non displaylist mode genMode may not set correctly
+ // when so we can't rely on it.
+ if (textureDefined) {
+ if (offsetOrTexset != -1) {
+ if (nonVAGeom) {
+ // In executeGeometryArray() or executeIndexedGeometryArray()
+ strideData->textureCoordsPtr[0] =
+ &verts[texoff + offsetOrTexset];
+ } else if (initialTexIndices != NULL) {
+ // executeGeometryArrayVA()
+ strideData->textureCoordsPtr[0] =
+ &(texCoordPointer[offsetOrTexset][initialTexIndices[offsetOrTexset]*texStride]);
+ } else { // executeIndexedGeometryArrayVA()
+ strideData->textureCoordsPtr[0] =
+ &(texCoordPointer[offsetOrTexset][0]);
+ }
+
+ strideData->textureCoordsStride[0] = texStride;
+ *vertexFormat |= (TexFormatSizeTable[ts] << 16);
+ d3dCtx->texSetUsed = 1;
+ strideData->texCoordPosition[0] = offsetOrTexset;
+ d3dCtx->texStride[0] = ts;
+ setTexTransformStageFlag(d3dCtx, device, 0, ts, genMode);
+#ifdef TEXDEBUG
+ printf("[pass 0] Non Object Linear, texDefined, ts=%d\n", ts);
+#endif
+ }
+ } else {
+ // may be automatic texture generation used
+ // TexSetUsed remain unchange i.e. 0 since we will not
+ // allocate VB space for texture coords.
+ setTexTransformStageFlag(d3dCtx, device, 0,
+ d3dCtx->texCoordFormat[0], genMode);
+#ifdef TEXDEBUG
+ printf("[pass 0] Non Object Linear, No texDefined, ts=%d\n",
+ d3dCtx->texCoordFormat[0]);
+#endif
+ }
+ } else {
+ // Automatic texture generation Object Linear
+ // strideData->textureCoordsPtr[0] &
+ // strideData->textureCoordsStride[0]
+ // are not use in VertexBuffer texture copy so
+ // it doesn't matter to set them using default.
+ setDefaultTextureCoordPointers(d3dCtx, strideData,
+ vertexFormat,
+ d3dCtx->texCoordFormat[0],
+ genMode, 0);
+ setTexTransformStageFlag(d3dCtx, device, 0,
+ d3dCtx->texCoordFormat[0], genMode);
+ d3dCtx->texSetUsed = 1;
+#ifdef TEXDEBUG
+ printf("[pass 0] Object Linear, ts=%d\n", d3dCtx->texCoordFormat[0]);
+#endif
+ }
+ texSetInVB = d3dCtx->texSetUsed;
+
+ } else {
+ // DisplayList is used for multiple texture single pass mode
+ // Or when go through the VertexArray in OGL, pass = -1
+ int tus;
+#ifdef TEXDEBUG
+ printf("*** Multiple Pass *** %d, nonVAGeom %d, buildDL %d, numActiveTexUnit %d, texCoordMapLength %d, texDef %d\n", pass,
+ nonVAGeom, (d3dCtx->currDisplayListID > 0),
+ numActiveTexUnit, texCoordMapLength, textureDefined);
+#endif
+
+ if (tunitstatemap != NULL) {
+ texUnitStateMap = (jint *) env->GetPrimitiveArrayCritical(tunitstatemap, NULL);
+ }
+ for (textureUnitIndex = 0; textureUnitIndex < numActiveTexUnit;
+ textureUnitIndex++) {
+
+ tus = (texUnitStateMap != NULL ?
+ texUnitStateMap[textureUnitIndex]: textureUnitIndex);
+
+ if (d3dCtx->currDisplayListID > 0) {
+ genMode = setTextureStage(d3dCtx, device,
+ textureUnitIndex, tus);
+ } else {
+ // This happen when we switch from displayList to
+ // vertexArray mode. The displayList is already
+ // built with 1-1 mapping so we can't use the
+ // textureUnitIndex Mapping
+ genMode = setTextureStage(d3dCtx, device,
+ textureUnitIndex,
+ textureUnitIndex);
+ }
+#ifdef TEXDEBUG
+ printf("[pass %d] genMode %d, tus %d\n", textureUnitIndex,
+ genMode, tus);
+#endif
+ if (genMode != TEX_OBJ_LINEAR) {
+ if (textureDefined) {
+ if (tus < texCoordMapLength) {
+ offsetOrTexset = (nonVAGeom ?
+ texCoordSetMapOffset[tus]:texCoordSetMap[tus]);
+
+ if (offsetOrTexset != -1) {
+ if (nonVAGeom) {
+ strideData->textureCoordsPtr[textureUnitIndex] =
+ &verts[texoff + offsetOrTexset];
+ } else if (initialTexIndices != NULL) {
+ strideData->textureCoordsPtr[textureUnitIndex] =
+ &(texCoordPointer[offsetOrTexset][initialTexIndices[offsetOrTexset]*texStride]);
+ } else {
+ strideData->textureCoordsPtr[textureUnitIndex] =
+ &(texCoordPointer[offsetOrTexset][0]);
+ }
+ strideData->textureCoordsStride[textureUnitIndex] = texStride;
+ strideData->texCoordPosition[textureUnitIndex]
+ = offsetOrTexset;
+ *vertexFormat |= (TexFormatSizeTable[ts] << (textureUnitIndex*2 + 16));
+ d3dCtx->texStride[textureUnitIndex] = ts;
+ setTexTransformStageFlag(d3dCtx, device,
+ textureUnitIndex,
+ ts, genMode);
+ texSetInVB++;
+#ifdef TEXDEBUG
+ printf("[pass %d] Non Object Linear, texDefined, ts=%d, tus %d\n", textureUnitIndex, ts, tus);
+#endif
+ } else {
+ // This texture status is disable, this
+ // should not happen in D3D since
+ // TextureBin always compact unused state
+ // - unless when DisplayList is build and
+ // automatic texture generation
+ // used. Since if DL use
+ // updateAttributes() not yet invoke to
+ // set genMode correctly.
+ if (debug && (d3dCtx->currDisplayListID <= 0)) {
+ printf("[Java3D] TextureBin not compact textureUnitState correctly, numActiveTex %d, disableUnit %d, current mapped Texture Unit %d\n", numActiveTexUnit, tus, textureUnitIndex);
+ }
+ setDefaultTextureCoordPointers(d3dCtx, strideData,
+ vertexFormat, ts,
+ genMode,
+ textureUnitIndex);
+ setTexTransformStageFlag(d3dCtx, device,
+ textureUnitIndex,
+ ts, genMode);
+ texSetInVB++;
+#ifdef TEXDEBUG
+ printf("[pass %d] Non Object Linear, texDefined, ts=%d\n", textureUnitIndex, ts);
+#endif
+ }
+ } else {
+ // Internal error, should not happen.
+ if (debug) {
+ printf("[Java3D] TextureCoordMapLength length %d, is smaller than texture unit %d, map texture unit %d\n", texCoordMapLength, tus, textureUnitIndex);
+ }
+ setDefaultTextureCoordPointers(d3dCtx, strideData,
+ vertexFormat, ts,
+ TEX_GEN_INVALID,
+ textureUnitIndex);
+ setTexTransformStageFlag(d3dCtx, device,
+ textureUnitIndex, ts,
+ genMode);
+
+ texSetInVB++;
+#ifdef TEXDEBUG
+ printf("[pass %d] Non Object Linear, texDefined, offset/texset = -1, ts=%d\n", textureUnitIndex, ts);
+#endif
+ }
+ } else {
+ // May be in automatically texture coordinate
+ // generation mode.
+ // May have trouble if automatically texture
+ // coordinate not used. Note that we pass ts = 0
+ // so that copyVertexToVB() will not inc. the
+ // stride for this unused tex stage.
+
+ // It is also the case in buildGA() case when
+ // numActiveTexUnit is 1 by default even though
+ // texture is not used.
+ /*
+ if ((d3dCtx->currDisplayListID <= 0) &&
+ (genMode == TEX_GEN_NONE)) {
+ // application error, use default TexCoord
+ setDefaultTextureCoordPointers(d3dCtx, strideData,
+ vertexFormat,
+ ts,
+ TEX_GEN_NONE,
+ textureUnitIndex);
+ texSetInVB++;
+ }
+ */
+
+ setDefaultTextureCoordPointers(d3dCtx, strideData,
+ vertexFormat,
+ 0,
+ // This must be < 0
+ TEX_GEN_AUTO,
+ textureUnitIndex);
+ setTexTransformStageFlag(d3dCtx, device, textureUnitIndex,
+ d3dCtx->texCoordFormat[textureUnitIndex], genMode);
+
+
+#ifdef TEXDEBUG
+ printf("[pass %d] Non Object Linear, No texDefined, ts=0\n", textureUnitIndex);
+#endif
+ }
+ } else {
+ // Automatic Texture generation Object Linear is used
+ setDefaultTextureCoordPointers(d3dCtx, strideData,
+ vertexFormat,
+ d3dCtx->texCoordFormat[textureUnitIndex],
+ genMode,
+ textureUnitIndex);
+ setTexTransformStageFlag(d3dCtx, device, textureUnitIndex,
+ d3dCtx->texCoordFormat[textureUnitIndex], genMode);
+ texSetInVB++;
+#ifdef TEXDEBUG
+ printf("[pass %d] Object Linear, No texDefined, ts=%d\n", textureUnitIndex, d3dCtx->texCoordFormat[textureUnitIndex]);
+#endif
+ }
+ }
+ d3dCtx->texSetUsed = numActiveTexUnit;
+#ifdef TEXDEBUG
+ printf("No of texSetInVB %d, numActiveTexUnit %d\n",
+ texSetInVB, numActiveTexUnit);
+#endif
+ if (texUnitStateMap != NULL) {
+ env->ReleasePrimitiveArrayCritical(tunitstatemap, texUnitStateMap, NULL);
+ }
+ }
+
+ if (texCoordSetMapOffset != NULL) {
+ env->ReleasePrimitiveArrayCritical(texUnitOffset,
+ texCoordSetMapOffset, NULL);
+ }
+
+ if (texCoordSetMap != NULL) {
+ env->ReleasePrimitiveArrayCritical(tcoordsetmap,
+ texCoordSetMap, NULL);
+ }
+
+ if (initialTexIndices != NULL) {
+ env->ReleasePrimitiveArrayCritical(texindices,
+ initialTexIndices, NULL);
+ }
+
+ // texSetInVB <= d3dCtx->TexSetUsed
+ *vertexFormat |= getVertexFormat(texSetInVB);
+}
+
+
+
+void executeGeometryArrayVA(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean modAlpha,
+ float alpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint vdefined,
+ jint initialCoordIndex,
+ jfloat* fverts,
+ jdouble* dverts,
+ jint initialColorIndex,
+ jfloat* fclrs,
+ jbyte* bclrs,
+ jint initialNormalIndex,
+ jfloat* norms,
+ int pass, // or texUnitIndex
+ int texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jintArray texindices,
+ jint texStride,
+ jfloat** texCoordPointer,
+ jdoubleArray xform,
+ jdoubleArray nxform,
+ jint cDirty)
+{
+ D3DDRAWPRIMITIVESTRIDEDDATA strideData;
+ DWORD vertexFormat = 0;
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+ GetDevice();
+
+ ZeroMemory(&strideData, sizeof(D3DDRAWPRIMITIVESTRIDEDDATA));
+
+ strideData.modulateAlpha = modAlpha;
+ strideData.alpha = alpha;
+
+
+ // setup coordinate pointers
+ if (floatCoordDefined || doubleCoordDefined) {
+ vertexFormat |= D3DFVF_XYZ;
+
+ if (floatCoordDefined) {
+ strideData.fpositionPtr = &fverts[initialCoordIndex*3];
+ } else if (doubleCoordDefined) {
+ strideData.dpositionPtr = &dverts[initialCoordIndex*3];
+ }
+
+ strideData.positionStride = 3;
+
+ } else {
+ // nothing worth doing if no coordinates define
+ return;
+ }
+
+ // setup normal pointers
+ if (normalsDefined) {
+ vertexFormat |= D3DFVF_NORMAL;
+ strideData.normalPtr = &norms[initialNormalIndex*3];
+ strideData.normalStride = 3;
+ }
+
+
+ // setup color pointers
+ if (!(floatColorsDefined || byteColorsDefined)
+ || ignoreVertexColors) {
+ // Use Material color
+ // Assume VertexBuffer will recreate when ignoreVertexColors
+ // property changed. Otherwise we need to remove
+ // the following one line
+ vertexFormat &= ~D3DFVF_DIFFUSE;
+ } else {
+ if ((vformat & GA_WITH_ALPHA) != 0) {
+ strideData.diffuseStride = 4;
+ strideData.useAlpha = true;
+ } else {
+ strideData.diffuseStride = 3;
+ strideData.useAlpha = false;
+ }
+ if (floatColorsDefined) {
+ strideData.fdiffusePtr = &fclrs[initialColorIndex*strideData.diffuseStride];
+ } else {
+ strideData.bdiffusePtr = &bclrs[initialColorIndex*strideData.diffuseStride];
+ }
+
+ vertexFormat |= D3DFVF_DIFFUSE;
+ }
+
+ int ts = 2; // In case of automatic texture generation
+
+ if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) {
+ ts = 3;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) {
+ ts = 4;
+ }
+
+
+ // setup texture pointer
+ setTextureCoordPointers(env, d3dCtx, device,
+ &strideData,
+ pass, 0, texStride, ts,
+ textureDefined,
+ tcoordsetmap,
+ texCoordMapLength,
+ NULL,
+ numActiveTexUnit,
+ tunitstatemap,
+ &vertexFormat,
+ NULL, texCoordPointer,
+ texindices);
+
+
+
+ jdouble* xform_ptr = NULL;
+ jdouble* nxform_ptr = NULL;
+
+ if (xform != NULL) {
+ xform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(xform, NULL);
+
+ }
+
+ if (nxform != NULL) {
+ nxform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(nxform, NULL);
+ }
+
+ // Construct/update VertexBuffer, render() if not in display list mode
+ renderGeometry(env, d3dCtx, device, geo, geo_type, &strideData,
+ vertexFormat, vcount, xform_ptr, nxform_ptr, cDirty);
+
+ if (xform_ptr != NULL) {
+ env->ReleasePrimitiveArrayCritical(xform, xform_ptr, 0);
+ }
+ if (nxform_ptr != NULL) {
+ env->ReleasePrimitiveArrayCritical(nxform, nxform_ptr, 0);
+ }
+
+}
+
+
+
+
+/* execute geometry array with java array format */
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeVABuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint vdefined,
+ jint initialCoordIndex,
+ jobject vcoords,
+ jint initialColorIndex,
+ jobject cdataBuffer,
+ jfloatArray cfdata,
+ jbyteArray cbdata,
+ jint initialNormalIndex,
+ jobject ndata,
+ jint pass,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jintArray texindices,
+ jint texStride,
+ jobjectArray texCoords,
+ jint cdirty)
+{
+
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL ;
+ jbyte *bclrs = NULL;
+ jfloat *fclrs = NULL, *norms = NULL;
+ jfloat* texCoordPointer[D3DDP_MAXTEXCOORD];
+ jarray texobjs[D3DDP_MAXTEXCOORD];
+ int i;
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (jarray)env->GetObjectArrayElement(texCoords, i);
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ fverts = (jfloat *)env->GetDirectBufferAddress( vcoords );
+ } else if (doubleCoordDefined) {
+ dverts = (jdouble *)env->GetDirectBufferAddress( vcoords );
+ }
+
+ if(fverts == NULL && dverts == NULL)
+ return;
+
+ /* get color array */
+ if (floatColorsDefined) {
+ if(cfdata != NULL) {
+ fclrs = (jfloat *) env->GetPrimitiveArrayCritical( cfdata, NULL);
+ } else {
+ fclrs = (jfloat *) env->GetDirectBufferAddress (cdataBuffer);
+
+ }
+ }
+ else if (byteColorsDefined) {
+ if(cbdata != NULL) {
+ bclrs = (jbyte *) env->GetPrimitiveArrayCritical( cbdata, NULL);
+ } else {
+ bclrs = (jbyte *) env->GetDirectBufferAddress(cdataBuffer);
+ }
+ }
+
+ /* get normal array */
+ if (normalsDefined) {
+ norms = (jfloat *)env->GetDirectBufferAddress(ndata);
+ }
+
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texobjs[i] != NULL)
+ texCoordPointer[i] = (jfloat*)env->GetDirectBufferAddress(texobjs[i]);
+ else
+ texCoordPointer[i] = NULL;
+
+ }
+ }
+
+ executeGeometryArrayVA(env, obj, ctx, geo, geo_type,
+ isNonUniformScale, false, 0,
+ multiScreen, ignoreVertexColors,
+ vcount, vformat, vdefined, initialCoordIndex,
+ fverts, dverts, initialColorIndex,
+ fclrs, bclrs, initialNormalIndex,
+ norms, pass, texCoordMapLength,
+ tcoordsetmap,numActiveTexUnit, tunitstatemap,
+ texindices,texStride,texCoordPointer, NULL,
+ NULL, cdirty);
+
+ if(floatColorsDefined && cfdata != NULL)
+ env->ReleasePrimitiveArrayCritical( cfdata, fclrs, 0);
+ else if(byteColorsDefined && cbdata != NULL)
+ env->ReleasePrimitiveArrayCritical(cbdata, bclrs, 0);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeVA(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint vdefined,
+ jint initialCoordIndex,
+ jfloatArray vfcoords,
+ jdoubleArray vdcoords,
+ jint initialColorIndex,
+ jfloatArray cfdata,
+ jbyteArray cbdata,
+ jint initialNormalIndex,
+ jfloatArray ndata,
+ jint pass, // or texUnitIndex
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jintArray texindices,
+ jint texStride,
+ jobjectArray texCoords,
+ jint cDirty)
+ {
+
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL;
+ jfloat *fclrs = NULL;
+ jbyte *bclrs = NULL;
+ jfloat *norms = NULL;
+ jfloat* texCoordPointer[D3DDP_MAXTEXCOORD];
+ jarray texobjs[D3DDP_MAXTEXCOORD];
+ int i;
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (jarray)env->GetObjectArrayElement( texCoords, i);
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ fverts= (jfloat *) env->GetPrimitiveArrayCritical( vfcoords, NULL);
+ } else if (doubleCoordDefined) {
+ dverts= (jdouble *) env->GetPrimitiveArrayCritical( vdcoords, NULL);
+ }
+
+ if ((fverts == NULL) && (dverts == NULL)) {
+ return;
+ }
+
+ /* get color array */
+ if (floatColorsDefined) {
+ fclrs = (jfloat *) env->GetPrimitiveArrayCritical( cfdata, NULL);
+ } else if (byteColorsDefined) {
+ bclrs = (jbyte *)env->GetPrimitiveArrayCritical( cbdata, NULL);
+ }
+
+ /* get normal array */
+ if (normalsDefined) {
+ norms = (jfloat *) env->GetPrimitiveArrayCritical(ndata, NULL);
+ }
+
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texobjs[i] != NULL) {
+ texCoordPointer[i] = (jfloat*)env->GetPrimitiveArrayCritical(texobjs[i], NULL);
+ } else {
+ texCoordPointer[i] = NULL;
+ }
+
+ }
+ }
+ executeGeometryArrayVA(env, obj, ctx, geo, geo_type,
+ isNonUniformScale, false, 0,
+ multiScreen, ignoreVertexColors,
+ vcount, vformat, vdefined, initialCoordIndex,
+ fverts, dverts, initialColorIndex,
+ fclrs, bclrs, initialNormalIndex,
+ norms, pass, texCoordMapLength,
+ tcoordsetmap,numActiveTexUnit, tunitstatemap,
+ texindices,texStride,texCoordPointer,
+ NULL, NULL, cDirty);
+
+ if (floatCoordDefined) {
+ env->ReleasePrimitiveArrayCritical( vfcoords, fverts, 0);
+ }
+ else if (doubleCoordDefined) {
+ env->ReleasePrimitiveArrayCritical( vdcoords, dverts, 0);
+ }
+
+ if (floatColorsDefined) {
+ env->ReleasePrimitiveArrayCritical( cfdata, fclrs, 0);
+ }
+ else if (byteColorsDefined) {
+ env->ReleasePrimitiveArrayCritical( cbdata, bclrs, 0);
+ }
+
+ if (normalsDefined) {
+ env->ReleasePrimitiveArrayCritical( ndata, norms, 0);
+ }
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texCoordPointer[i] != NULL) {
+ env->ReleasePrimitiveArrayCritical(texobjs[i], texCoordPointer[i], 0);
+ }
+ }
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_setGlobalAlpha(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jfloat alpha)
+{
+ // not use in D3D
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_disableGlobalAlpha(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint vformat,
+ jboolean useAlpha,
+ jboolean ignoreVertexColors)
+{
+ // not use in D3D
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_setVertexFormat(
+ JNIEnv *env,
+ jobject obj,
+ jint vformat,
+ jboolean useAlpha,
+ jboolean ignoreVertexColors,
+ jlong ctx)
+{
+ // not use in D3D
+}
+
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_GeometryArrayRetained_globalAlphaSUN
+ (JNIEnv *env, jobject obj, jlong ctx)
+{
+ return JNI_FALSE;
+}
+
+
+
+void executeGeometryArray(JNIEnv *env,
+ jobject obj, jlong ctx,
+ jobject geo, jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean modAlpha, // buildGA, should alpha be mode
+ jfloat alpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint startVIndex,
+ jint vcount, jint vformat, jint texCoordSetCount,
+ jintArray texCoordSetMapArray,
+ jint texCoordMapLength,
+ jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jfloat* verts, jfloatArray carray, jint pass,
+ jdoubleArray xform, jdoubleArray nxform,
+ jint cDirty,
+ jboolean useAlpha) // Should alpha be sent down
+{
+ D3DDRAWPRIMITIVESTRIDEDDATA strideData;
+ DWORD vertexFormat = 0;
+ jint stride, coordoff, normoff, coloroff, texoff;
+ int texStride, ts = 0;
+
+ GetDevice();
+
+ ZeroMemory(&strideData, sizeof(D3DDRAWPRIMITIVESTRIDEDDATA));
+
+ strideData.modulateAlpha = modAlpha;
+ strideData.alpha = alpha;
+
+ /* This matches the code in GeometryArrayRetained.java */
+ stride = coordoff = normoff = coloroff = texoff = 0;
+
+ if ((vformat & GA_COORDINATES) != 0) {
+ stride += 3;
+ vertexFormat |= D3DFVF_XYZ;
+ } else {
+ // nothing worth doing if no coordinates define
+ return;
+ }
+
+ if ((vformat & GA_NORMALS) != 0) {
+ stride += 3;
+ coordoff += 3;
+ vertexFormat |= D3DFVF_NORMAL;
+ }
+
+ if ((vformat & GA_COLOR) != 0) {
+ if ((vformat & GA_WITH_ALPHA) != 0 ) {
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ } else { // Handle the case of executeInterleaved 3f
+ stride += 3;
+ normoff += 3;
+ coordoff += 3;
+ }
+ vertexFormat |= D3DFVF_DIFFUSE;
+ }
+
+ // In case of automatic texture generation
+ ts = 2;
+
+ if (vformat & GA_TEXTURE_COORDINATE) {
+ if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) {
+ texStride = texCoordSetCount << 1;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) {
+ ts = 3;
+ texStride = texCoordSetCount*3;
+ } else { // GA_TEXTURE_COORDINATE_4
+ ts = 4;
+ texStride = texCoordSetCount << 2;
+ }
+ stride += texStride;
+ normoff += texStride;
+ coloroff += texStride;
+ coordoff += texStride;
+ }
+
+ jfloat *cverts = NULL;
+
+ texoff = startVIndex*stride;
+ coordoff += texoff;
+ normoff += texoff;
+
+ if (carray != NULL) {
+ // separate color array is used
+ coloroff = startVIndex*4;
+ } else {
+ coloroff += texoff;
+ }
+
+ // setup coordinates pointer
+ strideData.fpositionPtr = &verts[coordoff];
+ strideData.positionStride = stride;
+
+ // setup color pointer
+ if (((vformat & GA_COLOR) == 0) || ignoreVertexColors) {
+ // Use Material color
+ // Assume VertexBuffer will recreate when ignoreVertexColors
+ // property changed. Otherwise we need to remove
+ // the following one line
+ vertexFormat &= ~D3DFVF_DIFFUSE;
+ } else {
+ if (carray == NULL) {
+ strideData.fdiffusePtr = &verts[coloroff];
+ strideData.diffuseStride = stride;
+ strideData.useAlpha = (vformat & GA_WITH_ALPHA);
+ } else {
+ cverts = (jfloat*) env->GetPrimitiveArrayCritical(carray, NULL);
+ strideData.fdiffusePtr = &cverts[coloroff];
+ strideData.diffuseStride = 4;
+ strideData.useAlpha = true;
+ }
+ }
+
+
+ // setup normal pointer
+ if ((vformat & GA_NORMALS) != 0) {
+ strideData.normalPtr = &verts[normoff];
+ strideData.normalStride = stride;
+ }
+
+ // setup texture pointer
+ setTextureCoordPointers(env, d3dCtx, device,
+ &strideData,
+ pass, texoff, stride, ts,
+ (vformat & GA_TEXTURE_COORDINATE),
+ NULL,
+ texCoordMapLength,
+ texUnitOffset,
+ numActiveTexUnit,
+ tunitstatemap,
+ &vertexFormat,
+ verts, NULL, NULL);
+
+
+ jdouble* xform_ptr = NULL;
+ jdouble* nxform_ptr = NULL;
+
+ if (xform != NULL) {
+ xform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(xform, NULL);
+
+ }
+
+ if (nxform != NULL) {
+ nxform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(nxform, NULL);
+ }
+
+ renderGeometry(env, d3dCtx, device, geo, geo_type, &strideData,
+ vertexFormat, vcount, xform_ptr, nxform_ptr, cDirty);
+
+ if (xform_ptr != NULL) {
+ env->ReleasePrimitiveArrayCritical(xform, xform_ptr, 0);
+ }
+ if (nxform_ptr != NULL) {
+ env->ReleasePrimitiveArrayCritical(nxform, nxform_ptr, 0);
+ }
+
+
+ /* env->ReleasePrimitiveArrayCritical(varray, verts, NULL); */
+
+ if (cverts != NULL) {
+ env->ReleasePrimitiveArrayCritical(carray, cverts, NULL);
+ }
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGA(JNIEnv *env,
+ jobject obj, jlong ctx, jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean updateAlpha, float alpha,
+ jboolean ignoreVertexColors,
+ jint startVIndex,
+ jint vcount, jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMapArray,
+ jint texCoordMapLength,
+ jintArray texUnitOffset,
+ jdoubleArray xform, jdoubleArray nxform,
+ jfloatArray varray)
+{
+
+ jfloat *verts = NULL;
+
+ if (varray != NULL) {
+ verts = (jfloat *) env->GetPrimitiveArrayCritical(varray, NULL);
+ }
+
+ if (verts == NULL) {
+ return;
+ }
+
+ if (((vformat & GA_COLOR) != 0) &&
+ ((vformat & GA_BY_REFERENCE) == 0)) {
+ // alpha component is added for buildGA
+ vformat |= GA_WITH_ALPHA;
+ }
+
+
+ executeGeometryArray(env,
+ obj, ctx, geo, geo_type, isNonUniformScale,
+ updateAlpha,
+ alpha,
+ false,
+ ignoreVertexColors,
+ startVIndex,
+ vcount,
+ vformat,
+ texCoordSetCount,
+ texCoordSetMapArray,
+ texCoordMapLength,
+ texUnitOffset,
+ texCoordMapLength,
+ NULL,
+ verts, NULL,
+ -1,
+ xform, nxform,
+ javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED,
+ false);
+
+ env->ReleasePrimitiveArrayCritical( varray, verts, 0);
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_execute(JNIEnv *env,
+ jobject obj, jlong ctx,
+ jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean useAlpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint startVIndex,
+ jint vcount, jint vformat, jint texCoordSetCount,
+ jintArray texCoordSetMapArray,
+ jint texCoordMapLength, jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jfloatArray varray, jfloatArray carray,
+ jint texUnitIndex, jint cDirty)
+{
+ jfloat *verts = NULL;
+
+ if (varray != NULL) {
+ verts = (jfloat *) env->GetPrimitiveArrayCritical( varray, NULL);
+ }
+
+ if (verts == NULL) {
+ return;
+ }
+
+ executeGeometryArray(env, obj, ctx, geo, geo_type,
+ isNonUniformScale,
+ false,
+ 0, multiScreen,
+ ignoreVertexColors, startVIndex,
+ vcount, vformat, texCoordSetCount,
+ texCoordSetMapArray,
+ texCoordMapLength, texUnitOffset,
+ numActiveTexUnit, tunitstatemap,
+ verts, carray, texUnitIndex, NULL, NULL, cDirty,useAlpha);
+
+ env->ReleasePrimitiveArrayCritical( varray, verts, 0);
+
+}
+
+
+/* interleaved data with nio buffer as data format */
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeInterleavedBuffer(JNIEnv *env,
+ jobject obj, jlong ctx, jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean useAlpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint startVIndex,
+ jint vcount, jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMapArray, jint texCoordMapLength,
+ jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jobject varray, jfloatArray carray,
+ jint texUnitIndex, jint cDirty) {
+
+ jfloat *verts = NULL;
+
+ /* get the direct buffer address */
+ if (varray != NULL) {
+ verts = (jfloat *) env->GetDirectBufferAddress(varray);
+ }
+
+ if (verts == NULL) {
+ return;
+ }
+
+ /* call executeGeometryArray */
+ executeGeometryArray(env, obj, ctx, geo, geo_type,
+ isNonUniformScale,
+ false,
+ 0, multiScreen,
+ ignoreVertexColors, startVIndex,
+ vcount, vformat, texCoordSetCount,
+ texCoordSetMapArray,
+ texCoordMapLength, texUnitOffset,
+ numActiveTexUnit, tunitstatemap,
+ verts, carray, texUnitIndex, NULL, NULL, cDirty,useAlpha);
+
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_freeD3DArray
+ (JNIEnv *env, jobject geo, jboolean deleteVB)
+{
+
+ lockGeometry();
+
+ jclass geoClass = (jclass) env->GetObjectClass(geo);
+ // Free VertexBuffer associate with this GeometryArray
+ jfieldID fieldID = env->GetFieldID(geoClass, "pVertexBuffers", "J");
+
+ D3dVertexBufferVector *vbVector =
+ reinterpret_cast<D3dVertexBufferVector*> (env->GetLongField(geo, fieldID));
+
+
+ if (vbVector != NULL) {
+ // clearLive() invoke this in Renderer thread
+ for (LPD3DVERTEXBUFFER *s = vbVector->begin();
+ s != vbVector->end(); ++s) {
+ // This notify vb that parent vector is already free
+ // so there is no need to remove itself from vbVector
+ (*s)->vbVector = NULL;
+ (*s)->ctx->freeVB(*s);
+ }
+ env->SetLongField(geo, fieldID, 0);
+ vbVector->clear();
+ delete vbVector;
+ }
+
+ unlockGeometry();
+}
+
+
+
+void executeIndexedGeometryArray(JNIEnv *env,
+ jobject obj, jlong ctx,
+ jobject geo, jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean modAlpha, // buildGA, should alpha be mode
+ jfloat alpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMapArray,
+ jint texCoordMapLength,
+ jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jfloat* verts, jfloatArray carray, jint pass,
+ jdoubleArray xform, jdoubleArray nxform,
+ jint cDirty,
+ jboolean useAlpha,
+ jint initialIndexIndex,
+ jint indexCount,
+ jintArray indexCoord) // Should alpha be sent down
+{
+ D3DDRAWPRIMITIVESTRIDEDDATA strideData;
+ DWORD vertexFormat = 0;
+ jint stride, coordoff, normoff, coloroff, texoff;
+ int texStride, ts = 0;
+
+ GetDevice();
+
+ ZeroMemory(&strideData, sizeof(D3DDRAWPRIMITIVESTRIDEDDATA));
+
+ strideData.modulateAlpha = modAlpha;
+ strideData.alpha = alpha;
+
+ /* This matches the code in GeometryArrayRetained.java */
+ stride = coordoff = normoff = coloroff = texoff = 0;
+
+ if ((vformat & GA_COORDINATES) != 0) {
+ stride += 3;
+ vertexFormat |= D3DFVF_XYZ;
+ } else {
+ // nothing worth doing if no coordinates define
+ return;
+ }
+
+ if ((vformat & GA_NORMALS) != 0) {
+ stride += 3;
+ coordoff += 3;
+ vertexFormat |= D3DFVF_NORMAL;
+ }
+
+ if ((vformat & GA_COLOR) != 0) {
+ if ((vformat & GA_WITH_ALPHA) != 0 ) {
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ } else { // Handle the case of executeInterleaved 3f
+ stride += 3;
+ normoff += 3;
+ coordoff += 3;
+ }
+ vertexFormat |= D3DFVF_DIFFUSE;
+ }
+
+ // In case of automatic texture generation
+ ts = 2;
+
+ if (vformat & GA_TEXTURE_COORDINATE) {
+ if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) {
+ texStride = texCoordSetCount << 1;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) {
+ ts = 3;
+ texStride = texCoordSetCount*3;
+ } else { // GA_TEXTURE_COORDINATE_4
+ ts = 4;
+ texStride = texCoordSetCount << 2;
+ }
+ stride += texStride;
+ normoff += texStride;
+ coloroff += texStride;
+ coordoff += texStride;
+ }
+
+ jfloat *cverts = NULL;
+
+ if (carray != NULL) {
+ // separate color array is used
+ coloroff = 0;
+ } else {
+ coloroff += texoff;
+ }
+
+ // setup coordinates pointer
+ strideData.fpositionPtr = &verts[coordoff];
+ strideData.positionStride = stride;
+
+ // setup color pointer
+ if (((vformat & GA_COLOR) == 0) || ignoreVertexColors) {
+ // Use Material color
+ // Assume VertexBuffer will recreate when ignoreVertexColors
+ // property changed. Otherwise we need to remove
+ // the following one line
+ vertexFormat &= ~D3DFVF_DIFFUSE;
+ } else {
+ if (carray == NULL) {
+ strideData.fdiffusePtr = &verts[coloroff];
+ strideData.diffuseStride = stride;
+ strideData.useAlpha = (vformat & GA_WITH_ALPHA);
+ } else {
+ cverts = (jfloat*) env->GetPrimitiveArrayCritical(carray, NULL);
+ strideData.fdiffusePtr = &cverts[coloroff];
+ strideData.diffuseStride = 4;
+ strideData.useAlpha = true;
+ }
+ }
+
+
+ // setup normal pointer
+ if ((vformat & GA_NORMALS) != 0) {
+ strideData.normalPtr = &verts[normoff];
+ strideData.normalStride = stride;
+ }
+
+
+ // setup texture pointer
+ setTextureCoordPointers(env, d3dCtx, device,
+ &strideData,
+ pass, texoff, stride, ts,
+ (vformat & GA_TEXTURE_COORDINATE),
+ NULL,
+ texCoordMapLength,
+ texUnitOffset,
+ numActiveTexUnit,
+ tunitstatemap,
+ &vertexFormat,
+ verts, NULL, NULL);
+
+ // setup index pointer
+ strideData.indexPtr = (jint *) env->GetPrimitiveArrayCritical(indexCoord, NULL);
+ strideData.initialIndexIndex = initialIndexIndex;
+
+
+ jdouble* xform_ptr = NULL;
+ jdouble* nxform_ptr = NULL;
+
+ if (xform != NULL) {
+ xform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(xform, NULL);
+
+ }
+
+ if (nxform != NULL) {
+ nxform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(nxform, NULL);
+ }
+
+ renderIndexGeometry(env, d3dCtx, device, geo, geo_type, &strideData,
+ vertexFormat, vcount, indexCount,
+ xform_ptr, nxform_ptr, cDirty);
+
+
+
+ if (xform_ptr != NULL) {
+ env->ReleasePrimitiveArrayCritical(xform, xform_ptr, 0);
+ }
+ if (nxform_ptr != NULL) {
+ env->ReleasePrimitiveArrayCritical(nxform, nxform_ptr, 0);
+ }
+
+ if (cverts != NULL) {
+ env->ReleasePrimitiveArrayCritical(carray, cverts, NULL);
+ }
+
+ env->ReleasePrimitiveArrayCritical(indexCoord,
+ strideData.indexPtr, NULL);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometry(
+ JNIEnv *env,
+ jobject obj, jlong ctx,
+ jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean useAlpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint indexCount,
+ jint vcount,
+ jint vformat, jint texCoordSetCount,
+ jintArray texCoordSetMapArray,
+ jint texCoordMapLength, jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jfloatArray varray, jfloatArray carray,
+ jint texUnitIndex, jint cDirty,
+ jintArray indexCoord)
+{
+ jfloat *verts = NULL;
+
+ if (varray != NULL) {
+ verts = (jfloat *) env->GetPrimitiveArrayCritical( varray, NULL);
+ }
+
+ if (verts == NULL) {
+ return;
+ }
+
+ executeIndexedGeometryArray(env, obj, ctx, geo, geo_type,
+ isNonUniformScale,
+ false, 0, multiScreen,
+ ignoreVertexColors,
+ vcount,
+ vformat, texCoordSetCount,
+ texCoordSetMapArray,
+ texCoordMapLength,
+ texUnitOffset,
+ numActiveTexUnit,
+ tunitstatemap,
+ verts,
+ carray,
+ texUnitIndex,
+ NULL, NULL,
+ cDirty,
+ useAlpha,
+ initialIndexIndex,
+ indexCount,
+ indexCoord);
+
+ env->ReleasePrimitiveArrayCritical( varray, verts, 0);
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryBuffer(
+ JNIEnv *env,
+ jobject obj, jlong ctx,
+ jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean useAlpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint indexCount,
+ jint vcount,
+ jint vformat, jint texCoordSetCount,
+ jintArray texCoordSetMapArray,
+ jint texCoordMapLength, jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jobject varray, jfloatArray carray,
+ jint texUnitIndex, jint cDirty,
+ jintArray indexCoord)
+{
+ jfloat *verts = NULL;
+
+ /* get the direct buffer address */
+ if (varray != NULL) {
+ verts = (jfloat *) env->GetDirectBufferAddress(varray );
+ }
+
+ if (verts == NULL)
+ return;
+
+ executeIndexedGeometryArray(env, obj, ctx, geo, geo_type,
+ isNonUniformScale,
+ false, 0, multiScreen,
+ ignoreVertexColors,
+ vcount,
+ vformat, texCoordSetCount,
+ texCoordSetMapArray,
+ texCoordMapLength,
+ texUnitOffset,
+ numActiveTexUnit,
+ tunitstatemap,
+ verts,
+ carray,
+ texUnitIndex,
+ NULL, NULL,
+ cDirty,
+ useAlpha,
+ initialIndexIndex,
+ indexCount,
+ indexCoord);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_buildIndexedGeometry(
+ JNIEnv *env,
+ jobject obj, jlong ctx, jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale, jboolean updateAlpha, float alpha,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint indexCount,
+ jint vertexCount,
+ jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMapArray,
+ jint texCoordMapLength,
+ jintArray texUnitOffset,
+ jdoubleArray xform, jdoubleArray nxform,
+ jfloatArray varray, jintArray indexCoord)
+{
+
+ jfloat *verts = NULL;
+
+ if (varray != NULL) {
+ verts = (jfloat *) env->GetPrimitiveArrayCritical( varray, NULL);
+ }
+
+ if (verts == NULL) {
+ return;
+ }
+
+ if ((vformat & GA_COLOR) != 0) {
+ // alpha component is added for buildGA
+ vformat |= GA_WITH_ALPHA;
+ }
+
+ executeIndexedGeometryArray(env, obj, ctx, geo, geo_type,
+ isNonUniformScale,
+ updateAlpha, alpha,
+ false,
+ ignoreVertexColors,
+ vertexCount,
+ vformat,
+ texCoordSetCount,
+ texCoordSetMapArray,
+ texCoordMapLength,
+ texUnitOffset,
+ texCoordMapLength,
+ NULL,
+ verts,
+ NULL, -1,
+ xform, nxform,
+ javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED|
+ javax_media_j3d_GeometryArrayRetained_INDEX_CHANGED,
+ false,
+ initialIndexIndex,
+ indexCount,
+ indexCoord);
+
+ env->ReleasePrimitiveArrayCritical( varray, verts, 0);
+
+}
+
+
+
+void executeIndexedGeometryArrayVA(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint indexCount,
+ jint vertexCount,
+ jint vformat,
+ jint vdefined,
+ jfloat* fverts,
+ jdouble* dverts,
+ jfloat* fclrs,
+ jbyte* bclrs,
+ jfloat* norms,
+ jint pass,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jint texStride,
+ jfloat** texCoordPointer,
+ jint cDirty,
+ jintArray indexCoord)
+{
+ D3DDRAWPRIMITIVESTRIDEDDATA strideData;
+ DWORD vertexFormat = 0;
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+ GetDevice();
+
+ ZeroMemory(&strideData, sizeof(D3DDRAWPRIMITIVESTRIDEDDATA));
+
+ // setup coordinate pointers
+ if (floatCoordDefined || doubleCoordDefined) {
+ vertexFormat |= D3DFVF_XYZ;
+
+ if (floatCoordDefined ) {
+ strideData.fpositionPtr = &fverts[0];
+ } else if (doubleCoordDefined) {
+ strideData.dpositionPtr = &dverts[0];
+ }
+ strideData.positionStride = 3;
+
+ } else {
+ // nothing worth doing if no coordinates define
+ return;
+ }
+
+ // setup normal pointers
+ if (normalsDefined) {
+ vertexFormat |= D3DFVF_NORMAL;
+ strideData.normalPtr = &norms[0];
+ strideData.normalStride = 3;
+ }
+
+ // setup color pointers
+ if (!(floatColorsDefined || byteColorsDefined)
+ || ignoreVertexColors) {
+ // Use Material color
+ // Assume VertexBuffer will recreate when ignoreVertexColors
+ // property changed. Otherwise we need to remove
+ // the following one line
+ vertexFormat &= ~D3DFVF_DIFFUSE;
+ } else {
+ if ((vformat & GA_WITH_ALPHA) != 0) {
+ strideData.diffuseStride = 4;
+ strideData.useAlpha = true;
+ } else {
+ strideData.diffuseStride = 3;
+ strideData.useAlpha = false;
+ }
+ if (floatColorsDefined) {
+ strideData.fdiffusePtr = &fclrs[0];
+ } else {
+ strideData.bdiffusePtr = &bclrs[0];
+ }
+
+ vertexFormat |= D3DFVF_DIFFUSE;
+ }
+
+
+ int ts = 2; // In case of automatic texture generation
+
+ if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) {
+ ts = 3;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) {
+ ts = 4;
+ }
+
+ // setup texture pointer
+ setTextureCoordPointers(env, d3dCtx, device,
+ &strideData,
+ pass, 0,
+ texStride, ts,
+ textureDefined,
+ tcoordsetmap,
+ texCoordMapLength,
+ NULL,
+ numActiveTexUnit,
+ tunitstatemap,
+ &vertexFormat,
+ NULL, texCoordPointer,
+ NULL);
+
+ // setup index pointer
+ strideData.indexPtr = (jint *) env->GetPrimitiveArrayCritical(indexCoord, NULL);
+ strideData.initialIndexIndex = initialIndexIndex;
+
+ // Construct/update VertexBuffer, render() if not in display list mode
+ renderIndexGeometry(env, d3dCtx, device, geo, geo_type, &strideData,
+ vertexFormat, vertexCount, indexCount,
+ NULL, NULL, cDirty);
+
+ env->ReleasePrimitiveArrayCritical(indexCoord,
+ strideData.indexPtr, NULL);
+
+
+}
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryVA(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint indexCount,
+ jint vertexCount,
+ jint vformat,
+ jint vdefined,
+ jfloatArray vfcoords,
+ jdoubleArray vdcoords,
+ jfloatArray cfdata,
+ jbyteArray cbdata,
+ jfloatArray ndata,
+ jint pass,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jint texStride,
+ jobjectArray texCoords,
+ jint cDirty,
+ jintArray indexCoord)
+{
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL;
+ jfloat *fclrs = NULL;
+ jbyte *bclrs = NULL;
+ jfloat *norms = NULL;
+ jfloat* texCoordPointer[D3DDP_MAXTEXCOORD];
+ jarray texobjs[D3DDP_MAXTEXCOORD];
+ int i;
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (jarray)env->GetObjectArrayElement( texCoords, i);
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ fverts= (jfloat *) env->GetPrimitiveArrayCritical( vfcoords, NULL);
+ } else if (doubleCoordDefined) {
+ dverts= (jdouble *) env->GetPrimitiveArrayCritical( vdcoords, NULL);
+ }
+
+ if ((fverts == NULL) && (dverts == NULL)) {
+ return;
+ }
+
+ /* get color array */
+ if (floatColorsDefined) {
+ fclrs = (jfloat *) env->GetPrimitiveArrayCritical( cfdata, NULL);
+ } else if (byteColorsDefined) {
+ bclrs = (jbyte *)env->GetPrimitiveArrayCritical( cbdata, NULL);
+ }
+
+ /* get normal array */
+ if (normalsDefined) {
+ norms = (jfloat *) env->GetPrimitiveArrayCritical(ndata, NULL);
+ }
+
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texobjs[i] != NULL) {
+ texCoordPointer[i] =
+ (jfloat*)env->GetPrimitiveArrayCritical(texobjs[i], NULL);
+ } else {
+ texCoordPointer[i] = NULL;
+ }
+
+ }
+ }
+
+
+ executeIndexedGeometryArrayVA(env,
+ obj,
+ ctx,
+ geo,
+ geo_type,
+ isNonUniformScale,
+ multiScreen,
+ ignoreVertexColors,
+ initialIndexIndex,
+ indexCount,
+ vertexCount,
+ vformat,
+ vdefined,
+ fverts,
+ dverts,
+ fclrs,
+ bclrs,
+ norms,
+ pass,
+ texCoordMapLength,
+ tcoordsetmap,
+ numActiveTexUnit,
+ tunitstatemap,
+ texStride,
+ texCoordPointer,
+ cDirty,
+ indexCoord);
+
+ // Free memory
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texCoordPointer[i] != NULL) {
+ env->ReleasePrimitiveArrayCritical(texobjs[i], texCoordPointer[i], NULL);
+ }
+ }
+ }
+
+ if (floatColorsDefined) {
+ env->ReleasePrimitiveArrayCritical(cfdata, fclrs, 0);
+ } else if (byteColorsDefined) {
+ env->ReleasePrimitiveArrayCritical(cbdata, bclrs, 0);
+ }
+
+ if (normalsDefined) {
+ env->ReleasePrimitiveArrayCritical(ndata, norms, 0);
+ }
+
+ if (floatCoordDefined) {
+ env->ReleasePrimitiveArrayCritical(vfcoords, fverts, 0);
+ } else if (doubleCoordDefined) {
+ env->ReleasePrimitiveArrayCritical(vdcoords, dverts, 0);
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryVABuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint indexCount,
+ jint vertexCount,
+ jint vformat,
+ jint vdefined,
+ jobject vcoords,
+ jobject cdataBuffer,
+ jfloatArray cfdata,
+ jbyteArray cbdata,
+ jobject ndata,
+ jint pass,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jint texStride,
+ jobjectArray texCoords,
+ jint cDirty,
+ jintArray indexCoord)
+{
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL;
+ jfloat *fclrs = NULL;
+ jbyte *bclrs = NULL;
+ jfloat *norms = NULL;
+ jfloat* texCoordPointer[D3DDP_MAXTEXCOORD];
+ jarray texobjs[D3DDP_MAXTEXCOORD];
+ int i;
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (jarray)env->GetObjectArrayElement( texCoords, i);
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ fverts = (jfloat *)env->GetDirectBufferAddress( vcoords );
+ } else if (doubleCoordDefined) {
+ dverts = (jdouble *)env->GetDirectBufferAddress( vcoords );
+ }
+
+ if ((fverts == NULL) && (dverts == NULL)) {
+ return;
+ }
+
+ /* get color array */
+ if (floatColorsDefined) {
+ if(cfdata != NULL) {
+ fclrs = (jfloat *) env->GetPrimitiveArrayCritical( cfdata, NULL);
+ } else {
+ fclrs = (jfloat *) env->GetDirectBufferAddress (cdataBuffer);
+ }
+ } else if (byteColorsDefined) {
+ if (cbdata != NULL) {
+ bclrs = (jbyte *) env->GetPrimitiveArrayCritical( cbdata, NULL);
+ } else {
+ bclrs = (jbyte *) env->GetDirectBufferAddress(cdataBuffer);
+ }
+ }
+
+ /* get normal array */
+ if (normalsDefined) {
+ norms = (jfloat *)env->GetDirectBufferAddress(ndata);
+ }
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texobjs[i] != NULL)
+ texCoordPointer[i] = (jfloat*)env->GetDirectBufferAddress(texobjs[i]);
+ else
+ texCoordPointer[i] = NULL;
+
+ }
+ }
+
+
+ executeIndexedGeometryArrayVA(
+ env,
+ obj,
+ ctx,
+ geo,
+ geo_type,
+ isNonUniformScale,
+ multiScreen,
+ ignoreVertexColors,
+ initialIndexIndex,
+ indexCount,
+ vertexCount,
+ vformat,
+ vdefined,
+ fverts,
+ dverts,
+ fclrs,
+ bclrs,
+ norms,
+ pass,
+ texCoordMapLength,
+ tcoordsetmap,
+ numActiveTexUnit,
+ tunitstatemap,
+ texStride,
+ texCoordPointer,
+ cDirty,
+ indexCoord);
+
+ if (floatColorsDefined && cfdata != NULL) {
+ env->ReleasePrimitiveArrayCritical( cfdata, fclrs, 0);
+ } else if (byteColorsDefined && cbdata != NULL) {
+ env->ReleasePrimitiveArrayCritical(cbdata, bclrs, 0);
+ }
+}
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGAForBuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean updateAlpha,
+ jfloat alpha,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint vdefined,
+ jint initialCoordIndex,
+ jobject vcoords,
+ jint initialColorIndex,
+ jobject cdataBuffer,
+ jint initialNormalIndex,
+ jobject ndata,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jintArray texindices,
+ jint texStride,
+ jobjectArray texCoords,
+ jdoubleArray xform,
+ jdoubleArray nxform)
+{
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL ;
+ jbyte *bclrs = NULL;
+ jfloat *fclrs = NULL, *norms = NULL;
+ jfloat* texCoordPointer[D3DDP_MAXTEXCOORD];
+ jarray texobjs[D3DDP_MAXTEXCOORD];
+ int i;
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (jarray)env->GetObjectArrayElement(texCoords, i);
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ fverts = (jfloat *)env->GetDirectBufferAddress( vcoords );
+ } else if (doubleCoordDefined) {
+ dverts = (jdouble *)env->GetDirectBufferAddress( vcoords );
+ }
+
+ if ((fverts == NULL) && (dverts == NULL)) {
+ return;
+ }
+
+ /* get color array */
+ if (floatColorsDefined) {
+ fclrs = (jfloat *) env->GetDirectBufferAddress(cdataBuffer);
+ } else if (byteColorsDefined) {
+ bclrs = (jbyte *) env->GetDirectBufferAddress(cdataBuffer);
+ }
+
+ /* get normal array */
+ if (normalsDefined) {
+ norms = (jfloat *)env->GetDirectBufferAddress(ndata);
+ }
+
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texobjs[i] != NULL)
+ texCoordPointer[i] = (jfloat*)env->GetDirectBufferAddress(texobjs[i]);
+ else
+ texCoordPointer[i] = NULL;
+
+ }
+ }
+
+ executeGeometryArrayVA(env, obj, ctx, geo, geo_type,
+ isNonUniformScale, updateAlpha, alpha,
+ false, ignoreVertexColors,
+ vcount, vformat, vdefined, initialCoordIndex,
+ fverts, dverts, initialColorIndex,
+ fclrs, bclrs, initialNormalIndex,
+ norms, -1, texCoordMapLength,
+ tcoordsetmap,texCoordMapLength, NULL,
+ texindices,texStride,texCoordPointer,
+ xform, nxform,
+ javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGAForByRef(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean updateAlpha,
+ jfloat alpha,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint vdefined,
+ jint initialCoordIndex,
+ jfloatArray vfcoords,
+ jdoubleArray vdcoords,
+ jint initialColorIndex,
+ jfloatArray cfdata,
+ jbyteArray cbdata,
+ jint initialNormalIndex,
+ jfloatArray ndata,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jintArray texindices,
+ jint texStride,
+ jobjectArray texCoords,
+ jdoubleArray xform,
+ jdoubleArray nxform)
+{
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL;
+ jfloat *fclrs = NULL;
+ jbyte *bclrs = NULL;
+ jfloat *norms = NULL;
+ jfloat* texCoordPointer[D3DDP_MAXTEXCOORD];
+ jarray texobjs[D3DDP_MAXTEXCOORD];
+ int i;
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (jarray)env->GetObjectArrayElement( texCoords, i);
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ fverts= (jfloat *) env->GetPrimitiveArrayCritical( vfcoords, NULL);
+ } else if (doubleCoordDefined) {
+ dverts= (jdouble *) env->GetPrimitiveArrayCritical( vdcoords, NULL);
+ }
+
+ if ((fverts == NULL) && (dverts == NULL)) {
+ return;
+ }
+
+ /* get color array */
+ if (floatColorsDefined) {
+ fclrs = (jfloat *) env->GetPrimitiveArrayCritical( cfdata, NULL);
+ } else if (byteColorsDefined) {
+ bclrs = (jbyte *)env->GetPrimitiveArrayCritical( cbdata, NULL);
+ }
+
+ /* get normal array */
+ if (normalsDefined) {
+ norms = (jfloat *) env->GetPrimitiveArrayCritical(ndata, NULL);
+ }
+
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texobjs[i] != NULL) {
+ texCoordPointer[i] = (jfloat*)env->GetPrimitiveArrayCritical(texobjs[i], NULL);
+ } else {
+ texCoordPointer[i] = NULL;
+ }
+
+ }
+ }
+
+
+ executeGeometryArrayVA(env, obj, ctx, geo, geo_type,
+ isNonUniformScale, updateAlpha, alpha,
+ false, ignoreVertexColors,
+ vcount, vformat, vdefined, initialCoordIndex,
+ fverts, dverts, initialColorIndex,
+ fclrs, bclrs, initialNormalIndex,
+ norms, -1, texCoordMapLength,
+ tcoordsetmap,texCoordMapLength, NULL,
+ texindices,texStride,texCoordPointer,
+ xform, nxform,
+ javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED);
+
+ if (floatCoordDefined) {
+ env->ReleasePrimitiveArrayCritical( vfcoords, fverts, 0);
+ }
+ else if (doubleCoordDefined) {
+ env->ReleasePrimitiveArrayCritical( vdcoords, dverts, 0);
+ }
+
+ if (floatColorsDefined) {
+ env->ReleasePrimitiveArrayCritical( cfdata, fclrs, 0);
+ }
+ else if (byteColorsDefined) {
+ env->ReleasePrimitiveArrayCritical( cbdata, bclrs, 0);
+ }
+
+ if (normalsDefined) {
+ env->ReleasePrimitiveArrayCritical( ndata, norms, 0);
+ }
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texCoordPointer[i] != NULL) {
+ env->ReleasePrimitiveArrayCritical(texobjs[i], texCoordPointer[i], 0);
+ }
+ }
+ }
+}
diff --git a/src/native/d3d/GraphicsContext3D.cpp b/src/native/d3d/GraphicsContext3D.cpp
new file mode 100644
index 0000000..db89b3d
--- /dev/null
+++ b/src/native/d3d/GraphicsContext3D.cpp
@@ -0,0 +1,150 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_GraphicsContext3D_readRasterNative(
+ JNIEnv *env, jobject obj, jlong ctx,
+ jint type, jint xOffset, jint yOffset,
+ jint wRaster, jint hRaster, jint hCanvas, jint format,
+ jobject image, jobject depth, jobject gc)
+{
+
+ GetDevice();
+
+ jclass gc_class = env->GetObjectClass(gc);
+ jfieldID id;
+
+ if ((type & javax_media_j3d_Raster_RASTER_COLOR) != 0) {
+ jclass image_class = env->GetObjectClass(image);
+
+ if (image_class == NULL) {
+ return;
+ }
+
+ id = env->GetFieldID(gc_class, "byteBuffer","[B");
+ jarray byteData_array = (jarray) env->GetObjectField(gc, id);
+ jbyte *byteData;
+
+ if ((d3dCtx->d3dPresent.SwapEffect == D3DSWAPEFFECT_DISCARD)
+ // For offScreen rendering, swapBuffer never invoked
+ // so it is safe to use backBuffer
+ && (!d3dCtx->offScreen)
+ // If fail to createFrontBuffer, fallback to use
+ // backSurface. There is no gaurantee this fallback
+ // will work, but at least in non-debug DirectX library
+ // it works.
+ && ((d3dCtx->frontSurface != NULL) ||
+ (d3dCtx->frontSurface == NULL) &&
+ d3dCtx->createFrontBuffer())) {
+
+
+ HRESULT hr = device->GetFrontBuffer(d3dCtx->frontSurface);
+ if (FAILED(hr)) {
+ printf("GetFrontBuffer fail %s\n", DXGetErrorString8(hr));
+ return;
+ }
+
+ byteData = (jbyte *)
+ env->GetPrimitiveArrayCritical(byteData_array, NULL);
+
+ if (!d3dCtx->bFullScreen) {
+ // We need to invoke GetWindowRect() everytime
+ // since message resize() will not receive
+ // when Canvas3D inside browers.
+ d3dCtx->getScreenRect(d3dCtx->hwnd, &d3dCtx->windowRect);
+ copyDataFromSurface(format,
+ xOffset + d3dCtx->windowRect.left,
+ yOffset + d3dCtx->windowRect.top,
+ wRaster,
+ hRaster,
+ byteData,
+ d3dCtx->frontSurface);
+ } else {
+ copyDataFromSurface(format, xOffset, yOffset,
+ wRaster, hRaster, byteData,
+ d3dCtx->frontSurface);
+ }
+ } else {
+ if (d3dCtx->backSurface == NULL) {
+ HRESULT hr = device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO,
+ &d3dCtx->backSurface);
+ if (FAILED(hr)) {
+ printf("GetBackBuffer fail %s\n", DXGetErrorString8(hr));
+ return;
+ }
+ }
+ byteData = (jbyte *)
+ env->GetPrimitiveArrayCritical(byteData_array, NULL);
+
+ copyDataFromSurface(format, xOffset, yOffset, wRaster,
+ hRaster, byteData, d3dCtx->backSurface);
+ }
+
+
+
+ env->ReleasePrimitiveArrayCritical(byteData_array, byteData, 0);
+ }
+
+ if ((type & javax_media_j3d_Raster_RASTER_DEPTH) != 0) {
+ jclass depth_class = env->GetObjectClass(depth);
+
+ if (depth_class == NULL) {
+ return;
+ }
+
+ id = env->GetFieldID(depth_class, "width", "I");
+ int wDepth = env->GetIntField(depth, id);
+ id = env->GetFieldID(depth_class, "type", "I");
+ int depth_type = env->GetIntField(depth, id);
+
+ if (d3dCtx->depthStencilSurface == NULL) {
+ HRESULT hr =
+ device->GetDepthStencilSurface(&d3dCtx->depthStencilSurface);
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("[Java3D] Fail to get depth stencil surface %s\n",
+ DXGetErrorString8(hr));
+ }
+ return;
+ }
+ }
+
+ if (depth_type == javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_INT) {
+ id = env->GetFieldID(gc_class, "intBuffer","[I");
+ jarray intData_array = (jarray) env->GetObjectField(gc, id);
+ jint *intData = (jint *)
+ env->GetPrimitiveArrayCritical(intData_array, NULL);
+
+ // yOffset is adjusted for OpenGL - Y upward
+
+ copyDepthFromSurface(xOffset, yOffset, wRaster,
+ hRaster, intData, d3dCtx->depthStencilSurface);
+
+ env->ReleasePrimitiveArrayCritical(intData_array, intData, 0);
+
+ } else { // javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_FLOAT
+ id = env->GetFieldID(gc_class, "floatBuffer","[F");
+ jarray floatData_array = (jarray) env->GetObjectField(gc, id);
+ jfloat *floatData = (jfloat *)
+ env->GetPrimitiveArrayCritical(floatData_array, NULL);
+
+ // yOffset is adjusted for OpenGL - Y upward
+ copyDepthFromSurface(xOffset, yOffset, wRaster,
+ hRaster, floatData, d3dCtx->depthStencilSurface);
+
+ env->ReleasePrimitiveArrayCritical(floatData_array,
+ floatData, 0);
+ }
+ }
+}
diff --git a/src/native/d3d/Lights.cpp b/src/native/d3d/Lights.cpp
new file mode 100644
index 0000000..f865c6b
--- /dev/null
+++ b/src/native/d3d/Lights.cpp
@@ -0,0 +1,155 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+ #define D3DLIGHT_RANGE_MAX sqrt(FLT_MAX)
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_DirectionalLightRetained_updateLight(
+ JNIEnv *env,
+ jobject light,
+ jlong ctx,
+ jint lightSlot,
+ jfloat red,
+ jfloat green,
+ jfloat blue,
+ jfloat dirx,
+ jfloat diry,
+ jfloat dirz)
+{
+ D3DLIGHT8 d3dLight;
+
+ GetDevice();
+
+ d3dLight.Type = D3DLIGHT_DIRECTIONAL;
+
+ d3dLight.Direction.x = dirx;
+ d3dLight.Direction.y = diry;
+ d3dLight.Direction.z = dirz;
+
+ // Although spec. said this value is ignore, but
+ // if we don't set it the debug version will fail
+ // to set directional light
+ d3dLight.Range = D3DLIGHT_RANGE_MAX;
+ // D3D will not clamp to range [0, 1] automatically like OGL did
+ /*
+ Clamp(red);
+ Clamp(green);
+ Clamp(blue);
+ */
+ CopyColor(d3dLight.Diffuse, red, green, blue, 1.0f);
+ CopyColor(d3dLight.Ambient, 0.0f, 0.0f, 0.0f, 1.0f);
+ CopyColor(d3dLight.Specular, red, green, blue, 1.0f);
+
+ device->SetLight(lightSlot, &d3dLight);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_PointLightRetained_updateLight(
+ JNIEnv *env,
+ jobject light,
+ jlong ctx,
+ jint lightSlot,
+ jfloat red,
+ jfloat green,
+ jfloat blue,
+ jfloat attenx,
+ jfloat atteny,
+ jfloat attenz,
+ jfloat posx,
+ jfloat posy,
+ jfloat posz)
+{
+ D3DLIGHT8 d3dLight;
+
+ GetDevice();
+
+ d3dLight.Type = D3DLIGHT_POINT;
+
+ d3dLight.Position.x = posx;
+ d3dLight.Position.y = posy;
+ d3dLight.Position.z = posz;
+ /*
+ Clamp(red);
+ Clamp(green);
+ Clamp(blue);
+ */
+ CopyColor(d3dLight.Diffuse, red, green, blue, 1.0f);
+ CopyColor(d3dLight.Ambient, 0.0f, 0.0f, 0.0f, 1.0f);
+ CopyColor(d3dLight.Specular, red, green, blue, 1.0f);
+
+ d3dLight.Attenuation0 = attenx;
+ d3dLight.Attenuation1 = atteny;
+ d3dLight.Attenuation2 = attenz;
+ d3dLight.Range = D3DLIGHT_RANGE_MAX;
+
+ device->SetLight(lightSlot, &d3dLight);
+}
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_SpotLightRetained_updateLight(
+ JNIEnv *env,
+ jobject light,
+ jlong ctx,
+ jint lightSlot,
+ jfloat red,
+ jfloat green,
+ jfloat blue,
+ jfloat attenx,
+ jfloat atteny,
+ jfloat attenz,
+ jfloat posx,
+ jfloat posy,
+ jfloat posz,
+ jfloat spreadAngle,
+ jfloat concentration,
+ jfloat dirx,
+ jfloat diry,
+ jfloat dirz)
+{
+ D3DLIGHT8 d3dLight;
+
+ GetDevice();
+
+ d3dLight.Type = D3DLIGHT_SPOT;
+ d3dLight.Direction.x = dirx;
+ d3dLight.Direction.y = diry;
+ d3dLight.Direction.z = dirz;
+ d3dLight.Position.x = posx;
+ d3dLight.Position.y = posy;
+ d3dLight.Position.z = posz;
+ /*
+ Clamp(red);
+ Clamp(green);
+ Clamp(blue);
+ */
+ CopyColor(d3dLight.Diffuse, red, green, blue, 1.0f);
+ CopyColor(d3dLight.Ambient, 0.0f, 0.0f, 0.0f, 1.0f);
+ CopyColor(d3dLight.Specular, red, green, blue, 1.0f);
+
+ d3dLight.Attenuation0 = attenx;
+ d3dLight.Attenuation1 = atteny;
+ d3dLight.Attenuation2 = attenz;
+ d3dLight.Range = D3DLIGHT_RANGE_MAX;
+ d3dLight.Theta = 0;
+ d3dLight.Phi = spreadAngle*2;
+ if (d3dLight.Phi > PI) {
+ d3dLight.Phi = PI;
+ }
+ d3dLight.Falloff = concentration;
+
+ device->SetLight(lightSlot, &d3dLight);
+}
+
diff --git a/src/native/d3d/NativeAPIInfo.c b/src/native/d3d/NativeAPIInfo.c
new file mode 100644
index 0000000..3bc622c
--- /dev/null
+++ b/src/native/d3d/NativeAPIInfo.c
@@ -0,0 +1,23 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include <jni.h>
+
+#include "javax_media_j3d_MasterControl.h"
+
+
+JNIEXPORT
+jint JNICALL Java_javax_media_j3d_NativeAPIInfo_getRenderingAPI(
+ JNIEnv *env, jobject obj)
+{
+ return (jint)javax_media_j3d_MasterControl_RENDER_DIRECT3D;
+}
diff --git a/src/native/d3d/NativeConfigTemplate3D.cpp b/src/native/d3d/NativeConfigTemplate3D.cpp
new file mode 100644
index 0000000..e29f018
--- /dev/null
+++ b/src/native/d3d/NativeConfigTemplate3D.cpp
@@ -0,0 +1,140 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isStereoAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jlong display,
+ jint screen,
+ jint pixelFormat)
+{
+ // DirectX 8.0 don't support stereo
+ return false;
+
+}
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isDoubleBufferAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jlong display,
+ jint screen,
+ jint pixelFormat)
+{
+ // D3D always support double buffer
+ return true;
+}
+
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingMultiSamplesAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jlong display,
+ jint screen,
+ jint pixelFormat)
+{
+ BOOL antialiasingSupport = false;
+
+ lock();
+ if (d3dDriverList == NULL) {
+ D3dDriverInfo::initialize(env);
+ }
+
+ if (d3dDriverList != NULL) {
+ D3dDriverInfo *driverInfo = d3dDriverList[screen];
+ for (int i=0; i < numDeviceTypes; i++) {
+ D3dDeviceInfo *pDeviceInfo = driverInfo->d3dDeviceList[i];
+ if (pDeviceInfo->desktopCompatible &&
+ pDeviceInfo->supportAntialiasing()) {
+ antialiasingSupport = true;
+ break;
+ }
+ }
+ }
+ unlock();
+ return antialiasingSupport;
+}
+extern "C" JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingAccumAvailable(JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jlong display,
+ jint screen,
+ jint pixelFormat)
+{
+ return JNI_FALSE;
+}
+
+extern "C" JNIEXPORT
+jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_choosePixelFormat(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctx,
+ jint screen,
+ jintArray attrList)
+{
+ int depth, red, green, blue;
+ int retValue = -1;
+
+ jint *mx_ptr = (jint *) env->GetPrimitiveArrayCritical(attrList, NULL);
+ red = mx_ptr[RED_SIZE];
+ green = mx_ptr[GREEN_SIZE];
+ blue = mx_ptr[BLUE_SIZE];
+ depth = mx_ptr[DEPTH_SIZE];
+
+ env->ReleasePrimitiveArrayCritical(attrList, mx_ptr, 0);
+
+ if (mx_ptr[STEREO] != REQUIRED) {
+ lock();
+
+ if (d3dDriverList == NULL) {
+ D3dDriverInfo::initialize(env);
+ }
+
+ if (d3dDriverList != NULL) {
+ BOOL bFullScreen;
+ D3dDriverInfo *pDriver = d3dDriverList[screen];
+ D3dDeviceInfo *deviceInfo =
+ D3dCtx::setDeviceInfo(pDriver, &bFullScreen, depth);
+
+ if (deviceInfo != NULL) {
+ if ((depth <= deviceInfo->maxZBufferDepthSize) &&
+ (red <= pDriver->redDepth) &&
+ (green <= pDriver->greenDepth) &&
+ (blue <= pDriver->blueDepth)) {
+ retValue = depth;
+ }
+ }
+ }
+ unlock();
+ }
+
+ if (mx_ptr[ANTIALIASING] == REQUIRED) {
+ if (Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingMultiSamplesAvailable(
+ env, obj, ctx, 0, screen, 0) == JNI_TRUE)
+ {
+ retValue |= (1 << 31);
+ } else {
+ retValue = -1;
+ }
+ }
+
+ return retValue;
+}
+
diff --git a/src/native/d3d/NativeWSInfo.cpp b/src/native/d3d/NativeWSInfo.cpp
new file mode 100644
index 0000000..2cd0646
--- /dev/null
+++ b/src/native/d3d/NativeWSInfo.cpp
@@ -0,0 +1,92 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+
+
+#ifdef STRICT
+typedef WNDPROC PROC_TYPE;
+#else
+typedef FARPROC PROC_TYPE;
+#endif
+
+
+static PROC_TYPE g_lpDefWindowProcChild;
+static long oldWindowHandle = 0;
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_NativeWSInfo_subclass(
+ JNIEnv * env,
+ jobject obj,
+ jint hwnd)
+{
+ // For some reason, setting the callback before
+ // setCooperative level will cause setCooperative level
+ // to hang when start in fullscreen mode
+ // So we delay it later.
+}
+
+// Handle child move request
+static LRESULT CALLBACK canvas3dWndProcChild(
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ /*
+ switch (message) {
+ case WM_NCPAINT:
+ // handle switch mode from 256 back to >= 16 bits color mode
+ DWORD status;
+ if (hSema != NULL) {
+ status = WaitForSingleObject(hSema, 0);
+ if (status == WAIT_OBJECT_0) {
+ // This prevent deadlock, otherwise the window event
+ // thread will hangs if lock already acquired
+ // during window resize/toggle.
+ D3dCtx *ctx = findCtx(hwnd);
+ if (ctx != NULL) {
+ ctx->retryRestoreSurface = true;
+ }
+ unlock();
+ }
+ }
+ break;
+ }
+ */
+ return CallWindowProc(g_lpDefWindowProcChild, hwnd, message,
+ wParam, lParam);
+}
+
+
+VOID setWindowCallback(HWND topHwnd, HWND hwnd)
+{
+ // For some reasons, setting proc for the same handle
+ // will crash the application. So we work around this
+ // by checking the old window handle before setting the
+ // new one.
+ // long newWindowHandle;
+ /*
+ if (oldWindowHandle == 0) {
+ oldWindowHandle = GetWindowLong((HWND) hwnd, GWL_WNDPROC);
+ }
+
+ newWindowHandle = GetWindowLong((HWND) hwnd, GWL_WNDPROC);
+ if (newWindowHandle == oldWindowHandle) {
+ g_lpDefWindowProcChild = (PROC_TYPE)
+ SetWindowLong((HWND) hwnd, GWL_WNDPROC,
+ (LONG) canvas3dWndProcChild);
+ }
+ */
+}
+
diff --git a/src/native/d3d/RasterRetained.cpp b/src/native/d3d/RasterRetained.cpp
new file mode 100644
index 0000000..cbe6b7a
--- /dev/null
+++ b/src/native/d3d/RasterRetained.cpp
@@ -0,0 +1,255 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include "StdAfx.h"
+
+D3dImageComponent RasterList;
+D3dImageComponent BackgroundImageList;
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_RasterRetained_execute(JNIEnv *env,
+ jobject obj, jlong ctx, jobject geo,
+ jboolean updateAlpha, jfloat alpha,
+ jint type, jint w_raster, jint h_raster,
+ jint x_offset, jint y_offset, jfloat x, jfloat y, jfloat z,
+ jbyteArray imageYdown)
+{
+ jfieldID id;
+ int width, height;
+ int hashCode;
+ D3DVERTEX worldCoord;
+ D3DTLVERTEX screenCoord;
+
+ GetDevice();
+
+ int startx = x_offset;
+ int starty = y_offset;
+ int endx = x_offset + w_raster;
+ int endy = y_offset + h_raster;
+
+ jclass geo_class = env->GetObjectClass(geo);
+
+ if ((type == javax_media_j3d_Raster_RASTER_COLOR) ||
+ (type == javax_media_j3d_Raster_RASTER_COLOR_DEPTH)) {
+
+ int alphaChanged = 0; // used so we can get alpha data from
+ // JNI before using it so we can use
+ // GetPrimitiveArrayCritical
+
+ id = env->GetFieldID(geo_class, "image",
+ "Ljavax/media/j3d/ImageComponent2DRetained;");
+ jobject image = env->GetObjectField(geo, id);
+
+
+ jclass image_class = env->GetObjectClass(image);
+
+ if (image_class == NULL) {
+ return;
+ }
+ /*
+ id = env->GetFieldID(image_class, "surfaceDirty", "I");
+ if (env->GetIntField(image, id) == NOTLIVE) {
+ return;
+ }
+ */
+ id = env->GetFieldID(image_class, "width", "I");
+ width = env->GetIntField(image, id);
+ id = env->GetFieldID(image_class, "height", "I");
+ height = env->GetIntField(image, id);
+
+ id = env->GetFieldID(image_class, "hashId", "I");
+ hashCode = env->GetIntField(image, id);
+
+ // clipping
+ if (startx > width) {
+ startx = width;
+ } else if (startx < 0) {
+ startx = 0;
+ }
+ if (starty > height) {
+ starty = height;
+ } else if (starty < 0) {
+ starty = 0;
+ }
+ if (endx > width) {
+ endx = width;
+ } else if (endx < 0) {
+ endx = 0;
+ }
+ if (endy > height) {
+ endy = height;
+ } else if (endy < 0) {
+ endy = 0;
+ }
+
+ // raster position is upper left corner, default for Java3D
+ // ImageComponent currently has the data reverse in Y
+ worldCoord.x = x;
+ worldCoord.y = y;
+ worldCoord.z = z;
+
+ lockImage();
+
+ D3dImageComponent* d3dImage =
+ D3dImageComponent::find(&RasterList, d3dCtx, hashCode);
+
+ LPDIRECT3DTEXTURE8 surf = NULL ;
+
+ if ((d3dImage == NULL) || (d3dImage->surf == NULL)) {
+
+ surf = createSurfaceFromImage(env, image, ctx,
+ width, height, imageYdown);
+
+ if (surf == NULL) {
+ if (d3dImage != NULL) {
+ D3dImageComponent::remove(&RasterList, d3dImage);
+ }
+ unlockImage();
+ return;
+ }
+ if (d3dImage == NULL) {
+ d3dImage = D3dImageComponent::add(&RasterList, d3dCtx, hashCode, surf);
+
+ if (d3dImage == NULL) {
+ return;
+ }
+
+ } else {
+ d3dImage->surf = surf;
+ }
+ }
+
+ d3dCtx->transform(&worldCoord, &screenCoord);
+ if ((screenCoord.sz >= 0) && (screenCoord.sz <= 1)) {
+ screenCoord.sx -= 0.5f;
+ screenCoord.sy -= 0.5f;
+ drawTextureRect(d3dCtx, device, d3dImage->surf, screenCoord,
+ startx, starty, endx, endy,
+ endx - startx, endy - starty, false);
+ }
+ unlockImage();
+
+ }
+
+ if ((type == javax_media_j3d_Raster_RASTER_DEPTH) ||
+ (type == javax_media_j3d_Raster_RASTER_COLOR_DEPTH)) {
+ id = env->GetFieldID(geo_class, "depthComponent",
+ "Ljavax/media/j3d/DepthComponentRetained;");
+
+ jobject depth = env->GetObjectField(geo, id);
+ jclass depth_class = env->GetObjectClass(depth);
+
+ if (depth_class == NULL) {
+ return;
+ }
+ id = env->GetFieldID(depth_class, "type", "I");
+ int depth_type = env->GetIntField(depth, id);
+ id = env->GetFieldID(depth_class, "width", "I");
+ width = env->GetIntField(depth, id);
+ id = env->GetFieldID(depth_class, "height", "I");
+ height = env->GetIntField(depth, id);
+
+
+
+ // clipping
+ if (startx > width) {
+ startx = width;
+ } else if (startx < 0) {
+ startx = 0;
+ }
+ if (starty > height) {
+ starty = height;
+ } else if (starty < 0) {
+ starty = 0;
+ }
+ if (endx > width) {
+ endx = width;
+ } else if (endx < 0) {
+ endx = 0;
+ }
+ if (endy > height) {
+ endy = height;
+ } else if (endy < 0) {
+ endy = 0;
+ }
+
+ int h = endy - starty;
+ int w = endx - startx;
+
+ // raster position is upper left corner, default for Java3D
+ // ImageComponent currently has the data reverse in Y
+ if ((h > 0) && (w > 0)) {
+ worldCoord.x = x;
+ worldCoord.y = y;
+ worldCoord.z = z;
+
+ d3dCtx->transform(&worldCoord, &screenCoord);
+
+ if (d3dCtx->depthStencilSurface == NULL) {
+ HRESULT hr =
+ device->GetDepthStencilSurface(&d3dCtx->depthStencilSurface);
+ if (FAILED(hr)) {
+ if (debug) {
+ printf("[Java3D] Fail to get depth stencil surface %s\n",
+ DXGetErrorString8(hr));
+ }
+ return;
+ }
+ }
+
+ if (depth_type == javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_INT) {
+ id = env->GetFieldID(depth_class, "depthData","[I");
+ jintArray intData_array = (jintArray) env->GetObjectField(depth, id);
+ jint * intData = (jint *) env->GetPrimitiveArrayCritical(
+ intData_array, NULL);
+ copyDepthToSurface(d3dCtx,
+ device,
+ screenCoord.sx,
+ screenCoord.sy,
+ x_offset, y_offset,
+ w, h,width, height,
+ intData, d3dCtx->depthStencilSurface);
+ env->ReleasePrimitiveArrayCritical(intData_array,
+ intData, 0);
+ } else { // javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_FLOAT
+
+ id = env->GetFieldID(depth_class, "depthData","[F");
+ jfloatArray floatData_array = (jfloatArray)
+ env->GetObjectField(depth, id);
+
+ jfloat *floatData = (jfloat *) env->GetPrimitiveArrayCritical(
+ floatData_array, NULL);
+ copyDepthToSurface(d3dCtx,
+ device,
+ screenCoord.sx,
+ screenCoord.sy,
+ x_offset, y_offset,
+ w, h, width, height,
+ floatData, d3dCtx->depthStencilSurface);
+ env->ReleasePrimitiveArrayCritical(floatData_array,
+ floatData, 0);
+ }
+ }
+ }
+}
+
+
+
+extern "C" JNIEXPORT
+void JNICALL Java_javax_media_j3d_RasterRetained_executeTiled(JNIEnv *env,
+ jobject obj, jlong ctx, jobject geo,
+ jint format, jint w_raster, jint h_raster,
+ jint x_offset, jint y_offset, jint deltaw, jint deltah,
+ jfloat x, jfloat y, jfloat z, jbyteArray tile)
+{
+ // This is is not used by both OGL and D3D
+}
diff --git a/src/native/d3d/StdAfx.h b/src/native/d3d/StdAfx.h
new file mode 100644
index 0000000..76a4b00
--- /dev/null
+++ b/src/native/d3d/StdAfx.h
@@ -0,0 +1,54 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#if !defined(AFX_STDAFX_H)
+#define AFX_STDAFX_H
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
+
+// Windows Header Files:
+#include <afx.h>
+#include <winbase.h>
+#include <windows.h>
+#include <multimon.h>
+
+// C RunTime Header Files
+#include <stdlib.h>
+#include <malloc.h>
+#include <memory.h>
+#include <tchar.h>
+#include <string.h>
+#include <jni.h>
+#include <math.h>
+#define D3D_OVERLOADS
+#include <d3d8.h>
+#include <dxerr8.h>
+#include <d3dx8.h>
+#include <vector>
+#include <algorithm>
+using namespace std ;
+
+// Local header file
+#include "gldefs.h"
+#include "D3dDeviceInfo.hpp"
+#include "D3dDriverInfo.hpp"
+#include "D3dCtx.hpp"
+#include "D3dUtil.hpp"
+#include "D3dVertexBuffer.hpp"
+#include "D3dDisplayList.hpp"
+#include "D3dImageComponent.hpp"
+#endif
diff --git a/src/native/d3d/build-windows-i586-gcc.xml b/src/native/d3d/build-windows-i586-gcc.xml
new file mode 100644
index 0000000..fd4fdf0
--- /dev/null
+++ b/src/native/d3d/build-windows-i586-gcc.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Win32 ant file for d3d renderer -->
diff --git a/src/native/d3d/build-windows-i586-vc.xml b/src/native/d3d/build-windows-i586-vc.xml
new file mode 100644
index 0000000..7836f67
--- /dev/null
+++ b/src/native/d3d/build-windows-i586-vc.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Win32 ant file for d3d renderer -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native renderer build [${bldType}]"/>
+
+ <!-- Create the build directories for sparc -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/d3d/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/bin"/>
+
+ <property name="javaInclude"
+ location="${java.home}/../include"/>
+
+ <property name="javaWin32Include"
+ location="${java.home}/../include/win32"/>
+
+ <property name="oglsrc" location="${src}/native/ogl"/>
+ <property name="d3dsrc" location="${src}/native/d3d"/>
+
+ <!-- Compile the c source files-->
+ <exec dir="${build}/${platform}/${bldType}/native/d3d/objs" executable="cl">
+ <arg line="-I&quot;${javaInclude}&quot; -I&quot;${javaWin32Include}&quot; -I&quot;${src}/native/ogl&quot; -I&quot;${javahCoreTarget}&quot; -nologo -MT -W3 -GX -Ox -YX -FD ${bldFlag} -DD3D -DJ3D_BUILDVERTICES -c &quot;${oglsrc}/DrawingSurfaceObjectAWT.c&quot; &quot;${oglsrc}/MasterControl.c&quot; &quot;${d3dsrc}/D3dVertexBuffer.cpp&quot; &quot;${d3dsrc}/D3dDisplayList.cpp&quot; &quot;${d3dsrc}/D3dDriverInfo.cpp&quot; &quot;${d3dsrc}/D3dDeviceInfo.cpp&quot; &quot;${d3dsrc}/D3dCtx.cpp&quot; &quot;${d3dsrc}/D3dUtil.cpp&quot; &quot;${d3dsrc}/D3dImageComponent.cpp&quot; &quot;${d3dsrc}/GeometryArrayRetained.cpp&quot; &quot;${d3dsrc}/Canvas3D.cpp&quot; &quot;${d3dsrc}/GraphicsContext3D.cpp&quot; &quot;${d3dsrc}/CompressedGeometryRetained.cpp&quot; &quot;${d3dsrc}/Attributes.cpp&quot; &quot;${d3dsrc}/Lights.cpp&quot; &quot;${d3dsrc}/NativeConfigTemplate3D.cpp&quot; &quot;${d3dsrc}/NativeWSInfo.cpp&quot; &quot;${d3dsrc}/NativeAPIInfo.c&quot; &quot;${d3dsrc}/RasterRetained.cpp&quot;"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/d3d/objs" executable="link">
+ <arg line="-nologo -dll -subsystem:windows -pdb:none -machine:I386 /ignore:4089 -out:j3dcore-d3d.dll D3dVertexBuffer.obj D3dDisplayList.obj D3dDriverInfo.obj D3dDeviceInfo.obj D3dCtx.obj D3dUtil.obj D3dImageComponent.obj GeometryArrayRetained.obj Canvas3D.obj GraphicsContext3D.obj CompressedGeometryRetained.obj Attributes.obj Lights.obj NativeConfigTemplate3D.obj NativeWSInfo.obj NativeAPIInfo.obj RasterRetained.obj DrawingSurfaceObjectAWT.obj MasterControl.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib d3d8.lib d3dx8.lib dxerr8.lib dxguid.lib user32.lib delayimp.lib -DELAYLOAD:jawt.dll -LIBPATH:&quot;${java.home}\..\lib&quot; jawt.lib"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/d3d/objs/j3dcore-d3d.dll"
+ todir="${build}/${platform}/${bldType}/bin"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/bin"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/bin/j3dcore-d3d.dll"
+ todir="${dist}/${platform}/bin"/>
+
+ </target>
+
+</project>
diff --git a/src/native/ogl/Attributes.c b/src/native/ogl/Attributes.c
new file mode 100644
index 0000000..397593e
--- /dev/null
+++ b/src/native/ogl/Attributes.c
@@ -0,0 +1,3505 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <jni.h>
+
+#include "gldefs.h"
+
+#ifdef DEBUG
+/* Uncomment the following for VERBOSE debug messages */
+/* #define VERBOSE */
+#endif /* DEBUG */
+
+
+/*
+ * Screen door transparency table.
+ */
+const unsigned int screen_door[17][32] = {
+/* 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,
+ },
+};
+
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_LinearFogRetained_update(
+ JNIEnv *env,
+ jobject fog,
+ jlong ctxInfo,
+ jfloat red,
+ jfloat green,
+ jfloat blue,
+ jdouble fdist,
+ jdouble bdist)
+{
+
+ float color[3];
+#ifdef VERBOSE
+ fprintf(stderr, "LinearFog is on: %f %f %f %f %f\n",
+ red, green, blue, fdist, bdist);
+#endif
+
+ color[0] = red;
+ color[1] = green;
+ color[2] = blue;
+ glFogi(GL_FOG_MODE, GL_LINEAR);
+ glFogfv(GL_FOG_COLOR, color);
+ glFogf(GL_FOG_START, (float) fdist);
+ glFogf(GL_FOG_END, (float) bdist);
+ glEnable(GL_FOG);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_ExponentialFogRetained_update(
+ JNIEnv *env,
+ jobject fog,
+ jlong ctxInfo,
+ jfloat red,
+ jfloat green,
+ jfloat blue,
+ jfloat density)
+{
+
+ float color[3];
+#ifdef VERBOSE
+ fprintf(stderr, "ExponentialFog is on: %f %f %f %f\n",
+ red, green, blue, density);
+#endif
+
+ color[0] = red;
+ color[1] = green;
+ color[2] = blue;
+ glFogi(GL_FOG_MODE, GL_EXP);
+ glFogfv(GL_FOG_COLOR, color);
+ glFogf(GL_FOG_DENSITY, density);
+ glEnable(GL_FOG);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_ModelClipRetained_update(
+ JNIEnv *env,
+ jobject modelClip,
+ jlong ctxInfo,
+ jint planeNum,
+ jboolean enableFlag,
+ jdouble A,
+ jdouble B,
+ jdouble C,
+ jdouble D)
+{
+
+ double equation[4];
+ GLenum pl = GL_CLIP_PLANE0 + planeNum;
+
+#ifdef VERBOSE
+ fprintf(stderr, "ModelClip is on: %d %d %f %f %f %f\n",
+ planeNum, enableFlag, A, B, C, D);
+#endif
+
+ /* OpenGL clip planes are opposite to J3d clip planes
+ */
+ if (enableFlag) {
+ equation[0] = -A;
+ equation[1] = -B;
+ equation[2] = -C;
+ equation[3] = -D;
+ glClipPlane(pl, equation);
+ glEnable(pl);
+ } else
+ glDisable(pl);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setModelViewMatrix(
+ JNIEnv * env,
+ jobject obj,
+ jlong ctxInfo,
+ jdoubleArray viewMatrix,
+ jdoubleArray modelMatrix)
+{
+ jdouble *vmatrix_pointer;
+ jdouble *mmatrix_pointer;
+ JNIEnv table = *env;
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ vmatrix_pointer = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env,
+ viewMatrix , NULL);
+ mmatrix_pointer = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env,
+ modelMatrix , NULL);
+
+
+ glMatrixMode(GL_MODELVIEW);
+
+
+ if (ctxProperties->arb_transpose_matrix) {
+ ctxProperties->glLoadTransposeMatrixdARB(vmatrix_pointer);
+ ctxProperties->glMultTransposeMatrixdARB(mmatrix_pointer);
+ } else {
+ double v[16];
+ double m[16];
+
+ COPY_TRANSPOSE(vmatrix_pointer, v);
+ COPY_TRANSPOSE(mmatrix_pointer, m);
+
+ glLoadMatrixd(v);
+ glMultMatrixd(m);
+#ifdef VERBOSE
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Canvas3D.setModelViewMatrix()\n");
+ fprintf(stderr, "-----------------------------\n");
+ fprintf(stderr, "VIEW : %f %f %f %f\n", v[0], v[4], v[8], v[12]);
+ fprintf(stderr, " : %f %f %f %f\n", v[1], v[5], v[9], v[13]);
+ fprintf(stderr, " : %f %f %f %f\n", v[2], v[6], v[10], v[14]);
+ fprintf(stderr, " : %f %f %f %f\n", v[3], v[7], v[11], v[15]);
+ fprintf(stderr, "\n");
+ fprintf(stderr, "MODEL : %f %f %f %f\n", m[0], m[4], m[8], m[12]);
+ fprintf(stderr, " : %f %f %f %f\n", m[1], m[5], m[9], m[13]);
+ fprintf(stderr, " : %f %f %f %f\n", m[2], m[6], m[10], m[14]);
+ fprintf(stderr, " : %f %f %f %f\n", m[3], m[7], m[11], m[15]);
+ fprintf(stderr, "\n\n");
+#endif
+ }
+ (*(table->ReleasePrimitiveArrayCritical))(env, viewMatrix,
+ vmatrix_pointer, 0);
+ (*(table->ReleasePrimitiveArrayCritical))(env, modelMatrix,
+ mmatrix_pointer, 0);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setProjectionMatrix(
+ JNIEnv * env,
+ jobject obj,
+ jlong ctxInfo,
+ jdoubleArray projMatrix)
+{
+ jdouble *matrix_pointer;
+ JNIEnv table = *env;
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ matrix_pointer = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env,
+ projMatrix, NULL);
+
+ glMatrixMode(GL_PROJECTION);
+
+ if (ctxProperties->arb_transpose_matrix) {
+ /*
+ * Invert the Z value in clipping coordinates because OpenGL uses
+ * left-handed clipping coordinates, while Java3D defines right-handed
+ * coordinates everywhere.
+ */
+ matrix_pointer[8] *= -1.0;
+ matrix_pointer[9] *= -1.0;
+ matrix_pointer[10] *= -1.0;
+ matrix_pointer[11] *= -1.0;
+ ctxProperties->glLoadTransposeMatrixdARB(matrix_pointer);
+ matrix_pointer[8] *= -1.0;
+ matrix_pointer[9] *= -1.0;
+ matrix_pointer[10] *= -1.0;
+ matrix_pointer[11] *= -1.0;
+ } else {
+ double p[16];
+
+ COPY_TRANSPOSE(matrix_pointer, 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;
+
+ glLoadMatrixd(p);
+#ifdef VERBOSE
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Canvas3D.setProjectionMatrix()\n");
+ fprintf(stderr, "------------------------------\n");
+ fprintf(stderr, "PROJECTION : %f %f %f %f\n", p[0], p[4], p[8], p[12]);
+ fprintf(stderr, " : %f %f %f %f\n", p[1], p[5], p[9], p[13]);
+ fprintf(stderr, " : %f %f %f %f\n", p[2], p[6], p[10], p[14]);
+ fprintf(stderr, " : %f %f %f %f\n", p[3], p[7], p[11], p[15]);
+ fprintf(stderr, "\n\n");
+#endif
+
+ }
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, projMatrix,
+ matrix_pointer, 0);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setViewport(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint x,
+ jint y,
+ jint width,
+ jint height)
+{
+
+ glViewport(x, y, width, height);
+}
+
+#ifdef WIN32
+#define M_PI 3.14159265358979323846
+#endif
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setSceneAmbient(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jfloat red,
+ jfloat green,
+ jfloat blue)
+{
+ float color[4];
+
+ color[0] = red;
+ color[1] = green;
+ color[2] = blue;
+ color[3] = 1.0f;
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, color);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setLightEnables(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jlong enable_mask,
+ jint nlights)
+{
+ int i;
+
+#ifdef VERBOSE
+ fprintf(stderr, "Canvas3D.updateLightEnables: mask = 0x%x, 0x%x\n",
+ (int) ((enable_mask >> 32) & 0xffffffff),
+ (int) (enable_mask & 0xffffffff));
+#endif
+
+ for (i=0; i<nlights; i++) {
+ if (enable_mask & (1<<i)) {
+ glEnable(GL_LIGHT0 + i);
+ }
+ else {
+ glDisable(GL_LIGHT0 + i);
+ }
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setLightingEnable(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jboolean lightingOn)
+{
+ if (lightingOn) {
+ glEnable(GL_LIGHTING);
+#ifdef VERBOSE
+ fprintf(stderr, "ENABLE LIGHTING\n\n");
+#endif
+ } else {
+ glDisable(GL_LIGHTING);
+#ifdef VERBOSE
+ fprintf(stderr, "DISABLE LIGHTING\n\n");
+#endif
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_disableFog(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo)
+{
+#ifdef VERBOSE
+ fprintf(stderr, "Disable Fog\n");
+#endif
+ glDisable(GL_FOG);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_disableModelClip(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo)
+{
+#ifdef VERBOSE
+ fprintf(stderr, "Disable ModelClip\n");
+#endif
+ glDisable(GL_CLIP_PLANE0);
+ glDisable(GL_CLIP_PLANE1);
+ glDisable(GL_CLIP_PLANE2);
+ glDisable(GL_CLIP_PLANE3);
+ glDisable(GL_CLIP_PLANE4);
+ glDisable(GL_CLIP_PLANE5);
+}
+
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetRenderingAttributes(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jboolean db_write_enable_override,
+ jboolean db_enable_override)
+{
+ if (db_write_enable_override == JNI_FALSE) {
+ glDepthMask(GL_TRUE);
+ }
+ if (db_enable_override == JNI_FALSE) {
+ glEnable(GL_DEPTH_TEST);
+ }
+ glAlphaFunc(GL_ALWAYS, 0.0f);
+ glEnable(GL_COLOR_MATERIAL);
+ glDisable(GL_COLOR_LOGIC_OP);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_RenderingAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jboolean db_write_enable_override,
+ jboolean db_enable_override,
+ jboolean db_enable,
+ jboolean db_write_enable,
+ jfloat at_value,
+ jint at_func,
+ jboolean ignoreVertexColors,
+ jboolean rasterOpEnable,
+ jint rasterOp)
+{
+ if (db_enable_override == JNI_FALSE) {
+ if (db_enable == JNI_TRUE) {
+ glEnable(GL_DEPTH_TEST);
+ } else {
+ glDisable(GL_DEPTH_TEST);
+ }
+ }
+
+ if (db_write_enable_override == JNI_FALSE) {
+ if (db_write_enable == JNI_TRUE ) {
+ glDepthMask(GL_TRUE);
+ } else {
+ glDepthMask(GL_FALSE);
+ }
+ }
+
+ if (at_func == javax_media_j3d_RenderingAttributes_ALWAYS) {
+ glDisable(GL_ALPHA_TEST);
+ } else {
+ glEnable(GL_ALPHA_TEST);
+ }
+
+ if (ignoreVertexColors == JNI_TRUE) {
+ glDisable(GL_COLOR_MATERIAL);
+ }
+ else {
+ glEnable(GL_COLOR_MATERIAL);
+ }
+
+ switch (at_func) {
+ case javax_media_j3d_RenderingAttributes_ALWAYS:
+ glAlphaFunc(GL_ALWAYS, at_value);
+ break;
+ case javax_media_j3d_RenderingAttributes_NEVER:
+ glAlphaFunc(GL_NEVER, at_value);
+ break;
+ case javax_media_j3d_RenderingAttributes_EQUAL:
+ glAlphaFunc(GL_EQUAL, at_value);
+ break;
+ case javax_media_j3d_RenderingAttributes_NOT_EQUAL:
+ glAlphaFunc(GL_NOTEQUAL, at_value);
+ break;
+ case javax_media_j3d_RenderingAttributes_LESS:
+ glAlphaFunc(GL_LESS, at_value);
+ break;
+ case javax_media_j3d_RenderingAttributes_LESS_OR_EQUAL:
+ glAlphaFunc(GL_LEQUAL, at_value);
+ break;
+ case javax_media_j3d_RenderingAttributes_GREATER:
+ glAlphaFunc(GL_GREATER, at_value);
+ break;
+ case javax_media_j3d_RenderingAttributes_GREATER_OR_EQUAL:
+ glAlphaFunc(GL_GEQUAL, at_value);
+ break;
+ }
+
+ if (rasterOpEnable == JNI_TRUE) {
+ glEnable(GL_COLOR_LOGIC_OP);
+ switch (rasterOp) {
+ case javax_media_j3d_RenderingAttributes_ROP_COPY:
+ glLogicOp(GL_COPY);
+ break;
+ case javax_media_j3d_RenderingAttributes_ROP_XOR:
+ glLogicOp(GL_XOR);
+ break;
+ }
+ } else
+ glDisable(GL_COLOR_LOGIC_OP);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetPolygonAttributes(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo)
+{
+ glCullFace(GL_BACK);
+ glEnable(GL_CULL_FACE);
+
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ glPolygonOffset(0.0f, 0.0f);
+ glDisable(GL_POLYGON_OFFSET_POINT);
+ glDisable(GL_POLYGON_OFFSET_LINE);
+ glDisable(GL_POLYGON_OFFSET_FILL);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_PolygonAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jint polygonMode,
+ jint cullFace,
+ jboolean backFaceNormalFlip,
+ jfloat polygonOffset,
+ jfloat polygonOffsetFactor)
+{
+ if (cullFace == javax_media_j3d_PolygonAttributes_CULL_NONE) {
+ glDisable(GL_CULL_FACE);
+ } else {
+ if (cullFace == javax_media_j3d_PolygonAttributes_CULL_BACK) {
+ glCullFace(GL_BACK);
+ } else {
+ glCullFace(GL_FRONT);
+ }
+ glEnable(GL_CULL_FACE);
+ }
+
+ if (backFaceNormalFlip == JNI_TRUE && (cullFace != javax_media_j3d_PolygonAttributes_CULL_BACK)) {
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+ } else {
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+ }
+
+ if (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_POINT) {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
+ } else if (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_LINE) {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ } else {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
+
+ glPolygonOffset(polygonOffsetFactor, polygonOffset);
+
+ if((polygonOffsetFactor != 0.0) || (polygonOffset != 0.0)) {
+ /* fprintf(stderr, "set polygonOffSet\n"); */
+ switch (polygonMode) {
+ case javax_media_j3d_PolygonAttributes_POLYGON_POINT:
+ glEnable(GL_POLYGON_OFFSET_POINT);
+ glDisable(GL_POLYGON_OFFSET_LINE);
+ glDisable(GL_POLYGON_OFFSET_FILL);
+ break;
+ case javax_media_j3d_PolygonAttributes_POLYGON_LINE:
+ glEnable(GL_POLYGON_OFFSET_LINE);
+ glDisable(GL_POLYGON_OFFSET_POINT);
+ glDisable(GL_POLYGON_OFFSET_FILL);
+ break;
+ case javax_media_j3d_PolygonAttributes_POLYGON_FILL:
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glDisable(GL_POLYGON_OFFSET_POINT);
+ glDisable(GL_POLYGON_OFFSET_LINE);
+ break;
+ }
+ }
+ else {
+ glDisable(GL_POLYGON_OFFSET_POINT);
+ glDisable(GL_POLYGON_OFFSET_LINE);
+ glDisable(GL_POLYGON_OFFSET_FILL);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetLineAttributes(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo)
+/* comment out until called in java code
+ jfloat lineWidth,
+ jint linePattern,
+ jboolean lineAntialiasing)
+*/
+{
+ glLineWidth(1.0f);
+ glDisable(GL_LINE_STIPPLE);
+
+ /* TODO: Polygon Mode check, blend enable */
+ glDisable (GL_LINE_SMOOTH);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_LineAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jfloat lineWidth,
+ jint linePattern,
+ jint linePatternMask,
+ jint linePatternScaleFactor,
+ jboolean lineAntialiasing)
+{
+ glLineWidth(lineWidth);
+
+ if (linePattern == javax_media_j3d_LineAttributes_PATTERN_SOLID) {
+ glDisable(GL_LINE_STIPPLE);
+ } else {
+ if (linePattern == javax_media_j3d_LineAttributes_PATTERN_DASH) { /* dashed lines */
+ glLineStipple(1, 0x00ff);
+ } else if (linePattern == javax_media_j3d_LineAttributes_PATTERN_DOT) { /* dotted lines */
+ glLineStipple(1, 0x0101);
+ } else if (linePattern == javax_media_j3d_LineAttributes_PATTERN_DASH_DOT) { /* dash-dotted lines */
+ glLineStipple(1, 0x087f);
+ } else if (linePattern == javax_media_j3d_LineAttributes_PATTERN_USER_DEFINED) { /* user-defined mask */
+ glLineStipple(linePatternScaleFactor, (GLushort) linePatternMask);
+ }
+ glEnable(GL_LINE_STIPPLE);
+ }
+
+ /* TODO: Polygon Mode check, blend enable */
+ if (lineAntialiasing == JNI_TRUE) {
+ glEnable (GL_LINE_SMOOTH);
+ } else {
+ glDisable (GL_LINE_SMOOTH);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetPointAttributes(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo)
+{
+ glPointSize(1.0f);
+
+ /* TODO: Polygon Mode check, blend enable */
+ glDisable (GL_POINT_SMOOTH);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_PointAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jfloat pointSize,
+ jboolean pointAntialiasing)
+{
+ glPointSize(pointSize);
+
+ /* TODO: Polygon Mode check, blend enable */
+ if (pointAntialiasing == JNI_TRUE) {
+ glEnable (GL_POINT_SMOOTH);
+ } else {
+ glDisable (GL_POINT_SMOOTH);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetTexCoordGeneration(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo)
+{
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_Q);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TexCoordGenerationRetained_updateNative(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jboolean enable,
+ jint genMode,
+ jint format,
+ jfloat planeSx,
+ jfloat planeSy,
+ jfloat planeSz,
+ jfloat planeSw,
+ jfloat planeTx,
+ jfloat planeTy,
+ jfloat planeTz,
+ jfloat planeTw,
+ jfloat planeRx,
+ jfloat planeRy,
+ jfloat planeRz,
+ jfloat planeRw,
+ jfloat planeQx,
+ jfloat planeQy,
+ jfloat planeQz,
+ jfloat planeQw,
+ jdoubleArray vworldToEc)
+{
+ float planeS[4], planeT[4], planeR[4], planeQ[4];
+ JNIEnv table = *env;
+ jdouble *mat;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (enable == JNI_TRUE) {
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) {
+ glEnable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_Q);
+ } else if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) {
+ glEnable(GL_TEXTURE_GEN_R);
+ glEnable(GL_TEXTURE_GEN_Q);
+ } else {
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_Q);
+ }
+
+ if (genMode != javax_media_j3d_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 == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) {
+ planeR[0] = planeRx; planeR[1] = planeRy;
+ planeR[2] = planeRz; planeR[3] = planeRw;
+ } else if (format == javax_media_j3d_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 javax_media_j3d_TexCoordGeneration_OBJECT_LINEAR:
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, planeS);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, planeT);
+
+ if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) {
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_R, GL_OBJECT_PLANE, planeR);
+ } else if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) {
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_R, GL_OBJECT_PLANE, planeR);
+ glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_Q, GL_OBJECT_PLANE, planeQ);
+ }
+ break;
+ case javax_media_j3d_TexCoordGeneration_EYE_LINEAR:
+
+ mat = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env,
+ vworldToEc, NULL);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+
+ if (ctxProperties->arb_transpose_matrix) {
+ ctxProperties->glLoadTransposeMatrixdARB(mat);
+ } else {
+ jdouble v[16];
+ COPY_TRANSPOSE(mat, v);
+ glLoadMatrixd(v);
+ }
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, vworldToEc,
+ mat, 0);
+
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ glTexGenfv(GL_S, GL_EYE_PLANE, planeS);
+ glTexGenfv(GL_T, GL_EYE_PLANE, planeT);
+
+ if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) {
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ glTexGenfv(GL_R, GL_EYE_PLANE, planeR);
+ } else if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) {
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ glTexGenfv(GL_R, GL_EYE_PLANE, planeR);
+ glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ glTexGenfv(GL_Q, GL_EYE_PLANE, planeQ);
+ }
+ glPopMatrix();
+ break;
+ case javax_media_j3d_TexCoordGeneration_SPHERE_MAP:
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) {
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ } else if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) {
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ }
+
+ break;
+ case javax_media_j3d_TexCoordGeneration_NORMAL_MAP:
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
+ if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) {
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
+ } else if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) {
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
+ glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
+ }
+ break;
+ case javax_media_j3d_TexCoordGeneration_REFLECTION_MAP:
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
+ if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) {
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
+ } else if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) {
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
+ glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
+ }
+ break;
+ }
+ } else {
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ glDisable(GL_TEXTURE_GEN_R);
+ glDisable(GL_TEXTURE_GEN_Q);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetTextureAttributes(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo)
+{
+ float color[] = {0.0, 0.0, 0.0, 0.0};
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ glPushAttrib(GL_MATRIX_MODE);
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glPopAttrib();
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+
+ if(ctxProperties->textureRegisterCombinersAvailable)
+ glDisable(GL_REGISTER_COMBINERS_NV);
+
+ if(ctxProperties->textureColorTableAvailable)
+ glDisable(GL_TEXTURE_COLOR_TABLE_SGI);
+ /* GL_SGI_texture_color_table */
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jdoubleArray transform,
+ jboolean isIdentity,
+ jint textureMode,
+ jint perspCorrectionMode,
+ jfloat textureBlendColorRed,
+ jfloat textureBlendColorGreen,
+ jfloat textureBlendColorBlue,
+ jfloat textureBlendColorAlpha,
+ jint textureFormat)
+{
+ jdouble *mx_ptr;
+ float color[4];
+ JNIEnv table = *env;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (perspCorrectionMode == javax_media_j3d_TextureAttributes_NICEST) {
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ } else {
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ }
+
+ /* set OGL texture matrix */
+ glPushAttrib(GL_MATRIX_MODE);
+ glMatrixMode(GL_TEXTURE);
+
+ mx_ptr = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env, transform,
+ NULL);
+ if (isIdentity) {
+ glLoadIdentity();
+ } else if (ctxProperties->arb_transpose_matrix) {
+ ctxProperties->glLoadTransposeMatrixdARB(mx_ptr);
+ } else {
+ double mx[16];
+ COPY_TRANSPOSE(mx_ptr, mx);
+ glLoadMatrixd(mx);
+ }
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, transform, mx_ptr, 0);
+
+ glPopAttrib();
+
+ /* set texture color */
+ color[0] = textureBlendColorRed;
+ color[1] = textureBlendColorGreen;
+ color[2] = textureBlendColorBlue;
+ color[3] = textureBlendColorAlpha;
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
+
+ /* set texture environment mode */
+
+ switch (textureMode) {
+ case javax_media_j3d_TextureAttributes_MODULATE:
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ break;
+ case javax_media_j3d_TextureAttributes_DECAL:
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+ break;
+ case javax_media_j3d_TextureAttributes_BLEND:
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
+ break;
+ case javax_media_j3d_TextureAttributes_REPLACE:
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE:
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
+ ctxProperties->combine_enum);
+ break;
+ }
+
+ if(ctxProperties->textureColorTableAvailable)
+ glDisable(GL_TEXTURE_COLOR_TABLE_SGI);
+ /* GL_SGI_texture_color_table */
+}
+
+GLenum getCombinerArg(jint arg, GLenum textureUnit, GLenum combUnit) {
+ GLenum comb;
+
+ switch (arg) {
+ case javax_media_j3d_TextureAttributes_COMBINE_OBJECT_COLOR:
+ if (combUnit == GL_COMBINER0_NV) {
+ comb = GL_PRIMARY_COLOR_NV;
+ } else {
+ comb = GL_SPARE0_NV;
+ }
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_TEXTURE_COLOR:
+ comb = textureUnit;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_CONSTANT_COLOR:
+ comb = GL_CONSTANT_COLOR0_NV;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_PREVIOUS_TEXTURE_UNIT_STATE:
+ comb = textureUnit -1;
+ break;
+ }
+
+ return (comb);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateNativeRegisterCombiners(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jdoubleArray transform,
+ jboolean isIdentity,
+ jint textureMode,
+ jint perspCorrectionMode,
+ jfloat textureBlendColorRed,
+ jfloat textureBlendColorGreen,
+ jfloat textureBlendColorBlue,
+ jfloat textureBlendColorAlpha,
+ jint textureFormat,
+ jint combineRgbMode,
+ jint combineAlphaMode,
+ jintArray combineRgbSrc,
+ jintArray combineAlphaSrc,
+ jintArray combineRgbFcn,
+ jintArray combineAlphaFcn,
+ jint combineRgbScale,
+ jint combineAlphaScale)
+{
+ jdouble *mx_ptr;
+ float color[4];
+ JNIEnv table = *env;
+ GLenum textureUnit;
+ GLenum combinerUnit;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jint * rgbSrc;
+ GLenum color1, color2;
+ GLenum fragment;
+
+ if (perspCorrectionMode == javax_media_j3d_TextureAttributes_NICEST) {
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ } else {
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ }
+
+ /* set OGL texture matrix */
+ glPushAttrib(GL_MATRIX_MODE);
+ glMatrixMode(GL_TEXTURE);
+
+ mx_ptr = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env, transform,
+ NULL);
+ if (isIdentity) {
+ glLoadIdentity();
+ } else if (ctxProperties->arb_transpose_matrix) {
+ ctxProperties->glLoadTransposeMatrixdARB(mx_ptr);
+ } else {
+ double mx[16];
+ COPY_TRANSPOSE(mx_ptr, mx);
+ glLoadMatrixd(mx);
+ }
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, transform, mx_ptr, 0);
+
+ glPopAttrib();
+
+ /* set texture color */
+ color[0] = textureBlendColorRed;
+ color[1] = textureBlendColorGreen;
+ color[2] = textureBlendColorBlue;
+ color[3] = textureBlendColorAlpha;
+ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
+
+ /* set texture environment mode */
+ glEnable(GL_REGISTER_COMBINERS_NV);
+ textureUnit = ctxProperties->currentTextureUnit;
+ combinerUnit = ctxProperties->currentCombinerUnit;
+ if (combinerUnit == GL_COMBINER0_NV) {
+ fragment = GL_PRIMARY_COLOR_NV;
+ } else {
+ fragment = GL_SPARE0_NV;
+ }
+
+ switch (textureMode) {
+ case javax_media_j3d_TextureAttributes_MODULATE:
+
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_A_NV, fragment,
+ GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_B_NV, textureUnit,
+ GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA,
+ GL_VARIABLE_A_NV, fragment,
+ GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA,
+ GL_VARIABLE_B_NV, textureUnit,
+ GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
+
+ ctxProperties->glCombinerOutputNV(combinerUnit, GL_RGB,
+ GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
+ GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
+ ctxProperties->glCombinerOutputNV(combinerUnit, GL_ALPHA,
+ GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
+ GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
+ break;
+
+ case javax_media_j3d_TextureAttributes_DECAL:
+
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_A_NV, fragment,
+ GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_B_NV, textureUnit,
+ GL_UNSIGNED_INVERT_NV, GL_ALPHA);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_C_NV, textureUnit,
+ GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_D_NV, textureUnit,
+ GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
+
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA,
+ GL_VARIABLE_A_NV, fragment,
+ GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA,
+ GL_VARIABLE_B_NV, GL_ZERO,
+ GL_UNSIGNED_INVERT_NV, GL_ALPHA);
+
+ ctxProperties->glCombinerOutputNV(combinerUnit, GL_RGB,
+ GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV,
+ GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
+ ctxProperties->glCombinerOutputNV(combinerUnit, GL_ALPHA,
+ GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
+ GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
+ break;
+
+ case javax_media_j3d_TextureAttributes_BLEND:
+
+ ctxProperties->glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, color);
+
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_A_NV, fragment,
+ GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_B_NV, textureUnit,
+ GL_UNSIGNED_INVERT_NV, GL_RGB);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_C_NV, GL_CONSTANT_COLOR0_NV,
+ GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_D_NV, textureUnit,
+ GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA,
+ GL_VARIABLE_A_NV, fragment,
+ GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA,
+ GL_VARIABLE_B_NV, textureUnit,
+ GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
+
+ ctxProperties->glCombinerOutputNV(combinerUnit, GL_RGB,
+ GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV,
+ GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
+ ctxProperties->glCombinerOutputNV(combinerUnit, GL_ALPHA,
+ GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
+ GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
+ break;
+
+ case javax_media_j3d_TextureAttributes_REPLACE:
+
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_A_NV, textureUnit,
+ GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_B_NV, GL_ZERO,
+ GL_UNSIGNED_INVERT_NV, GL_RGB);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA,
+ GL_VARIABLE_A_NV, textureUnit,
+ GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA,
+ GL_VARIABLE_B_NV, GL_ZERO,
+ GL_UNSIGNED_INVERT_NV, GL_ALPHA);
+
+ ctxProperties->glCombinerOutputNV(combinerUnit, GL_RGB,
+ GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
+ GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
+ ctxProperties->glCombinerOutputNV(combinerUnit, GL_ALPHA,
+ GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
+ GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
+ break;
+
+ case javax_media_j3d_TextureAttributes_COMBINE:
+ if (combineRgbMode ==
+ javax_media_j3d_TextureAttributes_COMBINE_DOT3) {
+ rgbSrc = (jint *)(*(table->GetPrimitiveArrayCritical))(
+ env, combineRgbSrc, NULL);
+ color1 = getCombinerArg(rgbSrc[0], textureUnit, combinerUnit);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_A_NV, color1,
+ GL_EXPAND_NORMAL_NV, GL_RGB);
+ color2 = getCombinerArg(rgbSrc[1], textureUnit, combinerUnit);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB,
+ GL_VARIABLE_B_NV, color2,
+ GL_EXPAND_NORMAL_NV, GL_RGB);
+ (*(table->ReleasePrimitiveArrayCritical))(env, combineRgbSrc,
+ rgbSrc, 0);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA,
+ GL_VARIABLE_A_NV, GL_ZERO,
+ GL_UNSIGNED_INVERT_NV, GL_ALPHA);
+ ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA,
+ GL_VARIABLE_B_NV, GL_ZERO,
+ GL_UNSIGNED_INVERT_NV, GL_ALPHA);
+
+ ctxProperties->glCombinerOutputNV(combinerUnit, GL_RGB,
+ GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
+ GL_NONE/*SCALE_BY_FOUR_NV*/, GL_NONE, GL_TRUE,
+ GL_FALSE, GL_FALSE);
+ ctxProperties->glCombinerOutputNV(combinerUnit, GL_ALPHA,
+ GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
+ GL_NONE, GL_NONE, GL_FALSE,
+ GL_FALSE, GL_FALSE);
+ }
+ break;
+ }
+
+
+ ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_A_NV,
+ GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_B_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
+ ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_C_NV,
+ GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_D_NV,
+ GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_E_NV,
+ GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_F_NV,
+ GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
+ ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_G_NV,
+ GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
+
+ if(ctxProperties->textureColorTableAvailable)
+ glDisable(GL_TEXTURE_COLOR_TABLE_SGI);
+ /* GL_SGI_texture_color_table */
+}
+
+void getGLCombineMode(GraphicsContextPropertiesInfo *ctxInfo,
+ jint combineRgbMode, jint combineAlphaMode,
+ jint *GLrgbMode, jint *GLalphaMode) {
+
+ switch (combineRgbMode) {
+ case javax_media_j3d_TextureAttributes_COMBINE_REPLACE:
+ *GLrgbMode = GL_REPLACE;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_MODULATE:
+ *GLrgbMode = GL_MODULATE;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_ADD:
+ *GLrgbMode = GL_ADD;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_ADD_SIGNED:
+ *GLrgbMode = ctxInfo->combine_add_signed_enum;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_SUBTRACT:
+ *GLrgbMode = ctxInfo->combine_subtract_enum;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE:
+ *GLrgbMode = ctxInfo->combine_interpolate_enum;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_DOT3:
+ *GLrgbMode = ctxInfo->combine_dot3_rgb_enum;
+ break;
+ default:
+ break;
+ }
+
+ switch (combineAlphaMode) {
+ case javax_media_j3d_TextureAttributes_COMBINE_REPLACE:
+ *GLalphaMode = GL_REPLACE;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_MODULATE:
+ *GLalphaMode = GL_MODULATE;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_ADD:
+ *GLalphaMode = GL_ADD;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_ADD_SIGNED:
+ *GLalphaMode = ctxInfo->combine_add_signed_enum;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_SUBTRACT:
+ *GLalphaMode = ctxInfo->combine_subtract_enum;
+ break;
+ case javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE:
+ *GLalphaMode = ctxInfo->combine_interpolate_enum;
+ break;
+ case javax_media_j3d_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 == javax_media_j3d_TextureAttributes_COMBINE_DOT3) {
+ *GLrgbMode = ctxInfo->combine_dot3_rgba_enum;
+ } else {
+ *GLalphaMode = GL_REPLACE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
+
+/* mapping from java enum to gl enum
+ */
+
+jint _gl_combineRgbSrcIndex[] = {
+ GL_SOURCE0_RGB_ARB,
+ GL_SOURCE1_RGB_ARB,
+ GL_SOURCE2_RGB_ARB,
+};
+
+jint _gl_combineAlphaSrcIndex[] = {
+ GL_SOURCE0_ALPHA_ARB,
+ GL_SOURCE1_ALPHA_ARB,
+ GL_SOURCE2_ALPHA_ARB,
+};
+
+jint _gl_combineRgbOpIndex[] = {
+ GL_OPERAND0_RGB_ARB,
+ GL_OPERAND1_RGB_ARB,
+ GL_OPERAND2_RGB_ARB,
+};
+
+jint _gl_combineAlphaOpIndex[] = {
+ GL_OPERAND0_ALPHA_ARB,
+ GL_OPERAND1_ALPHA_ARB,
+ GL_OPERAND2_ALPHA_ARB,
+};
+
+jint _gl_combineSrc[] = {
+ GL_PRIMARY_COLOR_ARB, /* TextureAttributes.COMBINE_OBJECT_COLOR */
+ GL_TEXTURE, /* TextureAttributes.COMBINE_TEXTURE */
+ GL_CONSTANT_ARB, /* TextureAttributes.COMBINE_CONSTANT_COLOR */
+ GL_PREVIOUS_ARB, /* TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE */
+};
+
+jint _gl_combineFcn[] = {
+ GL_SRC_COLOR, /* TextureAttributes.COMBINE_SRC_COLOR */
+ GL_ONE_MINUS_SRC_COLOR, /* TextureAttributes.COMBINE_ONE_MINUS_SRC_COLOR */
+ GL_SRC_ALPHA, /* TextureAttributes.COMBINE_SRC_ALPHA */
+ GL_ONE_MINUS_SRC_ALPHA, /* TextureAttributes.COMBINE_ONE_MINUS_SRC_ALPHA */
+};
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateCombinerNative(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxProperties,
+ jint combineRgbMode,
+ jint combineAlphaMode,
+ jintArray combineRgbSrc,
+ jintArray combineAlphaSrc,
+ jintArray combineRgbFcn,
+ jintArray combineAlphaFcn,
+ jint combineRgbScale,
+ jint combineAlphaScale) {
+
+
+ JNIEnv table = *env;
+ GraphicsContextPropertiesInfo *ctxInfo =
+ (GraphicsContextPropertiesInfo *)ctxProperties;
+ jint *rgbSrc, *alphaSrc, *rgbFcn, *alphaFcn;
+ jint GLrgbMode, GLalphaMode;
+ jint nargs, i;
+
+ rgbSrc = (jint *)(*(table->GetPrimitiveArrayCritical))(
+ env, combineRgbSrc, NULL);
+ alphaSrc = (jint *)(*(table->GetPrimitiveArrayCritical))(
+ env, combineAlphaSrc, NULL);
+ rgbFcn = (jint *)(*(table->GetPrimitiveArrayCritical))(
+ env, combineRgbFcn, NULL);
+ alphaFcn = (jint *)(*(table->GetPrimitiveArrayCritical))(
+ env, combineAlphaFcn, NULL);
+
+ getGLCombineMode(ctxInfo, combineRgbMode, combineAlphaMode,
+ &GLrgbMode, &GLalphaMode);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GLrgbMode);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GLalphaMode);
+
+ if (combineRgbMode == javax_media_j3d_TextureAttributes_COMBINE_REPLACE) {
+ nargs = 1;
+ } else if (combineRgbMode == javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE) {
+ nargs = 3;
+ } else {
+ nargs = 2;
+ }
+
+ for (i = 0; i < nargs; i++) {
+ glTexEnvi(GL_TEXTURE_ENV, _gl_combineRgbSrcIndex[i],
+ _gl_combineSrc[rgbSrc[i]]);
+ glTexEnvi(GL_TEXTURE_ENV, _gl_combineRgbOpIndex[i],
+ _gl_combineFcn[rgbFcn[i]]);
+ }
+
+ if (combineAlphaMode == javax_media_j3d_TextureAttributes_COMBINE_REPLACE) {
+ nargs = 1;
+ } else if (combineAlphaMode == javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE) {
+ nargs = 3;
+ } else {
+ nargs = 2;
+ }
+
+ for (i = 0; i < nargs; i++) {
+ glTexEnvi(GL_TEXTURE_ENV, _gl_combineAlphaSrcIndex[i],
+ _gl_combineSrc[alphaSrc[i]]);
+ glTexEnvi(GL_TEXTURE_ENV, _gl_combineAlphaOpIndex[i],
+ _gl_combineFcn[alphaFcn[i]]);
+ }
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, combineRgbScale);
+ glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, combineAlphaScale);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, combineRgbSrc, rgbSrc, 0);
+ (*(table->ReleasePrimitiveArrayCritical))(env, combineAlphaSrc, alphaSrc, 0);
+ (*(table->ReleasePrimitiveArrayCritical))(env, combineRgbFcn, rgbFcn, 0);
+ (*(table->ReleasePrimitiveArrayCritical))(env, combineAlphaFcn, alphaFcn, 0);
+
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateTextureColorTableNative(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jint numComponents,
+ jint colorTableSize,
+ jintArray textureColorTable)
+{
+ JNIEnv table = *env;
+ jint *ctable;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if(ctxProperties->textureColorTableAvailable) {
+ ctable = (jint *)(*(table->GetPrimitiveArrayCritical))(env,
+ textureColorTable, NULL);
+ if (numComponents == 3) {
+ ctxProperties->glColorTable(GL_TEXTURE_COLOR_TABLE_SGI, GL_RGB,
+ colorTableSize, GL_RGB, GL_INT, ctable);
+ } else {
+ ctxProperties->glColorTable(GL_TEXTURE_COLOR_TABLE_SGI, GL_RGBA,
+ colorTableSize, GL_RGBA, GL_INT, ctable);
+ }
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, textureColorTable, ctable, 0);
+ glEnable(GL_TEXTURE_COLOR_TABLE_SGI);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_updateMaterial(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jfloat colorRed,
+ jfloat colorGreen,
+ jfloat colorBlue,
+ jfloat transparency)
+{
+ float color[4];
+
+ color[0] = colorRed;
+ color[1] = colorGreen;
+ color[2] = colorBlue;
+ color[3] = transparency;
+ glColor4fv(color);
+ glDisable(GL_LIGHTING);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_MaterialRetained_updateNative(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jfloat colorRed,
+ jfloat colorGreen,
+ jfloat colorBlue,
+ jfloat transparency,
+ jfloat aRed,
+ jfloat aGreen,
+ jfloat aBlue,
+ jfloat eRed,
+ jfloat eGreen,
+ jfloat eBlue,
+ jfloat dRed,
+ jfloat dGreen,
+ jfloat dBlue,
+ jfloat sRed,
+ jfloat sGreen,
+ jfloat sBlue,
+ jfloat shininess,
+ jint colorTarget,
+ jboolean lightEnable)
+{
+ float color[4];
+
+ color[3] = 1.0f;
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &shininess);
+ if (colorTarget == javax_media_j3d_Material_DIFFUSE) {
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ }
+ else if (colorTarget == javax_media_j3d_Material_AMBIENT) {
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
+ }
+ else if (colorTarget == javax_media_j3d_Material_EMISSIVE) {
+ glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
+ }
+ else if (colorTarget == javax_media_j3d_Material_SPECULAR) {
+ glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
+ }
+ else if (colorTarget == javax_media_j3d_Material_AMBIENT_AND_DIFFUSE) {
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ }
+
+ color[0] = eRed; color[1] = eGreen; color[2] = eBlue;
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
+
+ color[0] = aRed; color[1] = aGreen; color[2] = aBlue;
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
+
+ color[0] = sRed; color[1] = sGreen; color[2] = sBlue;
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
+
+ if (lightEnable == JNI_TRUE) {
+ color[0] = dRed; color[1] = dGreen; color[2] = dBlue;
+ } else {
+ color[0] = colorRed; color[1] = colorGreen; color[2] = colorBlue;
+ }
+ color[3] = transparency;
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
+ glColor4fv(color);
+
+ if (lightEnable) {
+ glEnable(GL_LIGHTING);
+ } else {
+ glDisable(GL_LIGHTING);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetTransparency(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jint geometryType,
+ jint polygonMode,
+ jboolean lineAA,
+ jboolean pointAA)
+{
+ if (((((geometryType & javax_media_j3d_RenderMolecule_LINE) != 0) ||
+ (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_LINE))
+ && lineAA == JNI_TRUE) ||
+ ((((geometryType & javax_media_j3d_RenderMolecule_POINT) != 0) ||
+ (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_POINT))
+ && pointAA == JNI_TRUE)) {
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ } else {
+ glDisable (GL_BLEND);
+ }
+ glDisable(GL_POLYGON_STIPPLE);
+
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TransparencyAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject tr,
+ jlong ctxInfo,
+ jfloat transparency,
+ jint geometryType,
+ jint polygonMode,
+ jboolean lineAA,
+ jboolean pointAA,
+ jint transparencyMode,
+ jint srcBlendFunction,
+ jint dstBlendFunction)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (transparencyMode != javax_media_j3d_TransparencyAttributes_SCREEN_DOOR) {
+ glDisable(GL_POLYGON_STIPPLE);
+ } else {
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple((GLubyte *)(screen_door[(int)((transparency)*16)]));
+ }
+
+ if ((transparencyMode < javax_media_j3d_TransparencyAttributes_SCREEN_DOOR) ||
+ ((((geometryType & javax_media_j3d_RenderMolecule_LINE) != 0) ||
+ (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_LINE))
+ && lineAA == JNI_TRUE) ||
+ ((((geometryType & javax_media_j3d_RenderMolecule_POINT) != 0) ||
+ (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_POINT))
+ && pointAA == JNI_TRUE)) {
+ glEnable (GL_BLEND);
+ /* valid range of blendFunction 0..3 is already verify in Java code. */
+ glBlendFunc(ctxProperties->blendFunctionTable[srcBlendFunction],
+ ctxProperties->blendFunctionTable[dstBlendFunction]);
+ } else {
+ glDisable (GL_BLEND);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetColoringAttributes(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jfloat colorRed,
+ jfloat colorGreen,
+ jfloat colorBlue,
+ jfloat transparency,
+ jboolean lightEnable)
+{
+
+ float color[4];
+
+ if (lightEnable != JNI_TRUE) {
+ color[0] = colorRed; color[1] = colorGreen; color[2] = colorBlue;
+ color[3] = transparency;
+ glColor4fv(color);
+
+ }
+ glShadeModel(GL_SMOOTH);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_ColoringAttributesRetained_updateNative(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jfloat dRed,
+ jfloat dGreen,
+ jfloat dBlue,
+ jfloat colorRed,
+ jfloat colorGreen,
+ jfloat colorBlue,
+ jfloat transparency,
+ jboolean lightEnable,
+ jint shadeModel)
+{
+
+ float color[4];
+
+ if (lightEnable == JNI_TRUE) {
+ color[0] = dRed; color[1] = dGreen; color[2] = dBlue;
+ } else {
+ color[0] = colorRed; color[1] = colorGreen; color[2] = colorBlue;
+ }
+ color[3] = transparency;
+
+ glColor4fv(color);
+ if (shadeModel == javax_media_j3d_ColoringAttributes_SHADE_FLAT) {
+ glShadeModel(GL_FLAT);
+ } else {
+ glShadeModel(GL_SMOOTH);
+ }
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_resetTextureNative(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint texUnitIndex)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if(ctxProperties->arb_multitexture) {
+
+ if (texUnitIndex >= 0) {
+ ctxProperties->glActiveTextureARB(texUnitIndex + GL_TEXTURE0_ARB);
+ ctxProperties->glClientActiveTextureARB(texUnitIndex + GL_TEXTURE0_ARB);
+ }
+ }
+
+ glDisable(GL_TEXTURE_1D);
+ glDisable(GL_TEXTURE_2D);
+
+ if(ctxProperties->texture3DAvailable) {
+ glDisable(ctxProperties->texture_3D_ext_enum);
+ }
+
+ if(ctxProperties->textureCubeMapAvailable) {
+ glDisable(ctxProperties->texture_cube_map_ext_enum);
+ }
+}
+
+
+/*
+ * A set of common updateTexture functions shared among Texture2D, Texture3D,
+ * and TextureCubeMap for setting texture parameters
+ */
+void updateTextureFilterModes(
+ GraphicsContextPropertiesInfo *ctxProperties,
+ jint target,
+ jint minFilter,
+ jint magFilter) {
+
+ /* set texture min filter */
+ switch(minFilter) {
+ case javax_media_j3d_Texture_FASTEST:
+ case javax_media_j3d_Texture_BASE_LEVEL_POINT:
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ break;
+ case javax_media_j3d_Texture_BASE_LEVEL_LINEAR:
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ break;
+ case javax_media_j3d_Texture_MULTI_LEVEL_POINT:
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST_MIPMAP_NEAREST);
+ break;
+ case javax_media_j3d_Texture_NICEST:
+ case javax_media_j3d_Texture_MULTI_LEVEL_LINEAR:
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_LINEAR);
+ break;
+ case javax_media_j3d_Texture_FILTER4:
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
+ ctxProperties->filter4_enum);
+ break;
+
+ }
+
+ /* set texture mag filter */
+ switch(magFilter){
+ case javax_media_j3d_Texture_FASTEST:
+ case javax_media_j3d_Texture_BASE_LEVEL_POINT:
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ break;
+ case javax_media_j3d_Texture_NICEST:
+ case javax_media_j3d_Texture_BASE_LEVEL_LINEAR:
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ break;
+ case javax_media_j3d_Texture_LINEAR_SHARPEN:
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+ ctxProperties->linear_sharpen_enum);
+ break;
+ case javax_media_j3d_Texture_LINEAR_SHARPEN_RGB:
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+ ctxProperties->linear_sharpen_rgb_enum);
+ break;
+ case javax_media_j3d_Texture_LINEAR_SHARPEN_ALPHA:
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+ ctxProperties->linear_sharpen_alpha_enum);
+ break;
+ case javax_media_j3d_Texture2D_LINEAR_DETAIL:
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+ ctxProperties->linear_detail_enum);
+ break;
+ case javax_media_j3d_Texture2D_LINEAR_DETAIL_RGB:
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+ ctxProperties->linear_detail_rgb_enum);
+ break;
+ case javax_media_j3d_Texture2D_LINEAR_DETAIL_ALPHA:
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+ ctxProperties->linear_detail_alpha_enum);
+ break;
+ case javax_media_j3d_Texture_FILTER4:
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+ ctxProperties->filter4_enum);
+ break;
+ }
+}
+
+
+void updateTextureLodRange(
+ GraphicsContextPropertiesInfo *ctxProperties,
+ jint target,
+ jint baseLevel,
+ jint maximumLevel,
+ float minimumLod, float maximumLod) {
+
+ /*
+ * checking of the availability of the extension is already done
+ * in the java side
+ */
+ glTexParameteri(target, ctxProperties->texture_base_level_enum,
+ baseLevel);
+ glTexParameteri(target, ctxProperties->texture_max_level_enum,
+ maximumLevel);
+ glTexParameterf(target, ctxProperties->texture_min_lod_enum,
+ minimumLod);
+ glTexParameterf(target, ctxProperties->texture_max_lod_enum,
+ maximumLod);
+}
+
+void updateTextureLodOffset(
+ GraphicsContextPropertiesInfo *ctxProperties,
+ jint target,
+ float lodOffsetS, float lodOffsetT, float lodOffsetR) {
+
+ /*
+ * checking of the availability of the extension is already done
+ * in the java side
+ */
+ glTexParameterf(target, GL_TEXTURE_LOD_BIAS_S_SGIX, lodOffsetS);
+ glTexParameterf(target, GL_TEXTURE_LOD_BIAS_T_SGIX, lodOffsetT);
+ glTexParameterf(target, GL_TEXTURE_LOD_BIAS_R_SGIX, lodOffsetR);
+}
+
+
+void updateTextureBoundary(
+ GraphicsContextPropertiesInfo *ctxProperties,
+ jint target,
+ jint boundaryModeS,
+ jint boundaryModeT,
+ jint boundaryModeR,
+ jfloat boundaryRed,
+ jfloat boundaryGreen,
+ jfloat boundaryBlue,
+ jfloat boundaryAlpha)
+{
+ float color[4];
+
+ /* set texture wrap parameter */
+ switch (boundaryModeS){
+ case javax_media_j3d_Texture_WRAP:
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ break;
+ case javax_media_j3d_Texture_CLAMP:
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ break;
+ case javax_media_j3d_Texture_CLAMP_TO_EDGE:
+ glTexParameteri(target, GL_TEXTURE_WRAP_S,
+ ctxProperties->texture_clamp_to_edge_enum);
+ break;
+ case javax_media_j3d_Texture_CLAMP_TO_BOUNDARY:
+ glTexParameteri(target, GL_TEXTURE_WRAP_S,
+ ctxProperties->texture_clamp_to_border_enum);
+ break;
+ }
+
+ switch (boundaryModeT) {
+ case javax_media_j3d_Texture_WRAP:
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ break;
+ case javax_media_j3d_Texture_CLAMP:
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ break;
+ case javax_media_j3d_Texture_CLAMP_TO_EDGE:
+ glTexParameteri(target, GL_TEXTURE_WRAP_T,
+ ctxProperties->texture_clamp_to_edge_enum);
+ break;
+ case javax_media_j3d_Texture_CLAMP_TO_BOUNDARY:
+ glTexParameteri(target, GL_TEXTURE_WRAP_T,
+ ctxProperties->texture_clamp_to_border_enum);
+ break;
+ }
+
+ /* applies to Texture3D only */
+ if (boundaryModeR != -1) {
+ switch (boundaryModeR) {
+ case javax_media_j3d_Texture_WRAP:
+ glTexParameteri(target,
+ ctxProperties->texture_wrap_r_ext_enum, GL_REPEAT);
+ break;
+
+ case javax_media_j3d_Texture_CLAMP:
+ glTexParameteri(target,
+ ctxProperties->texture_wrap_r_ext_enum, GL_CLAMP);
+ break;
+ case javax_media_j3d_Texture_CLAMP_TO_EDGE:
+ glTexParameteri(target,
+ ctxProperties->texture_wrap_r_ext_enum,
+ ctxProperties->texture_clamp_to_edge_enum);
+ break;
+ case javax_media_j3d_Texture_CLAMP_TO_BOUNDARY:
+ glTexParameteri(target,
+ ctxProperties->texture_wrap_r_ext_enum,
+ ctxProperties->texture_clamp_to_border_enum);
+ break;
+ }
+ }
+
+ if (boundaryModeS == javax_media_j3d_Texture_CLAMP ||
+ boundaryModeT == javax_media_j3d_Texture_CLAMP ||
+ boundaryModeR == javax_media_j3d_Texture_CLAMP) {
+ /* set texture border color */
+ color[0] = boundaryRed;
+ color[1] = boundaryGreen;
+ color[2] = boundaryBlue;
+ color[3] = boundaryAlpha;
+ glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, color);
+ }
+}
+
+void updateTextureSharpenFunc(
+ JNIEnv *env,
+ GraphicsContextPropertiesInfo *ctxProperties,
+ jint target,
+ jint numPts,
+ jfloatArray pts)
+{
+ /*
+ * checking of the availability of sharpen texture functionality
+ * is already done in the java side
+ */
+
+ JNIEnv table = *env;
+ jfloat *funcPts = NULL;
+
+ if (numPts > 0) {
+ funcPts = (jfloat *)(*(table->GetPrimitiveArrayCritical))(
+ env, pts, NULL);
+ }
+
+ ctxProperties->glSharpenTexFuncSGIS(target, numPts, funcPts);
+
+ if (funcPts != NULL) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, pts, funcPts, 0);
+ }
+}
+
+
+void updateTextureFilter4Func(
+ JNIEnv *env,
+ GraphicsContextPropertiesInfo *ctxProperties,
+ jint target,
+ jint numPts,
+ jfloatArray pts)
+{
+ /*
+ * checking of the availability of filter4 functionality
+ * is already done in the java side
+ */
+
+ JNIEnv table = *env;
+ jfloat *funcPts = NULL;
+
+ if (numPts > 0) {
+ funcPts = (jfloat *)(*(table->GetPrimitiveArrayCritical))(
+ env, pts, NULL);
+ }
+
+ ctxProperties->glTexFilterFuncSGIS(target, ctxProperties->filter4_enum,
+ numPts, funcPts);
+
+ if (funcPts != NULL) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, pts, funcPts, 0);
+ }
+}
+
+void updateTextureAnisotropicFilter(
+ JNIEnv *env,
+ GraphicsContextPropertiesInfo *ctxProperties,
+ jint target,
+ jfloat degree)
+{
+ /*
+ * checking of the availability of anisotropic filter functionality
+ * is already done in the java side
+ */
+ glTexParameterf(target,
+ ctxProperties->texture_filter_anisotropic_ext_enum,
+ degree);
+}
+
+
+/*
+ * common function to define 2D texture image for different target
+ */
+void updateTexture2DImage(
+ JNIEnv *env,
+ GraphicsContextPropertiesInfo *ctxProperties,
+ jint target,
+ jint numLevels,
+ jint level,
+ jint internalFormat,
+ jint format,
+ jint width,
+ jint height,
+ jint boundaryWidth,
+ jbyteArray imageYup)
+{
+ GLenum oglFormat = 0, oglInternalFormat=0;
+ JNIEnv table = *env;
+ jbyte *byteData;
+ jshort *shortData;
+
+ switch (internalFormat) {
+ case INTENSITY:
+ oglInternalFormat = GL_INTENSITY;
+ break;
+ case LUMINANCE:
+ oglInternalFormat = GL_LUMINANCE;
+ break;
+ case ALPHA:
+ oglInternalFormat = GL_ALPHA;
+ break;
+ case LUMINANCE_ALPHA:
+ oglInternalFormat = GL_LUMINANCE_ALPHA;
+ break;
+ case J3D_RGB:
+ oglInternalFormat = GL_RGB;
+ break;
+ case J3D_RGBA:
+ oglInternalFormat = GL_RGBA;
+ break;
+ }
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ /* all RGB types are stored as RGBA */
+ oglFormat = GL_RGBA;
+ break;
+ case FORMAT_BYTE_RGB:
+ oglFormat = GL_RGB;
+ break;
+
+ case FORMAT_BYTE_ABGR:
+ if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */
+ oglFormat = GL_ABGR_EXT;
+ }
+ break;
+
+ case FORMAT_BYTE_BGR:
+ if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */
+ oglFormat = ctxProperties->bgr_ext_enum;
+ }
+ break;
+
+ case FORMAT_BYTE_LA:
+ /* all LA types are stored as LA8 */
+ oglFormat = GL_LUMINANCE_ALPHA;
+ break;
+ case FORMAT_BYTE_GRAY:
+ case FORMAT_USHORT_GRAY:
+ if (oglInternalFormat == GL_ALPHA) {
+ oglFormat = GL_ALPHA;
+ } else {
+ oglFormat = GL_LUMINANCE;
+ }
+ break;
+ }
+ /*
+ fprintf(stderr,"native updateTextureImage\n");
+ fprintf(stderr,"internalFormat = %x\n",internalFormat);
+ fprintf(stderr,"format = %x\n",format);
+ fprintf(stderr,"oglFormat = %x\n",oglFormat);
+ fprintf(stderr,"oglInternalFormat = %x\n",oglInternalFormat);
+ fprintf(stderr,"boundaryWidth= %d\n", boundaryWidth);
+ */
+ if (imageYup != NULL) {
+ if (format != FORMAT_USHORT_GRAY) {
+ byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env,
+ imageYup,
+ NULL);
+ /*
+ {
+ jbyte *c = byteData;
+ int i, j;
+ for (i = 0; i < 1; i++) {
+ for (j = 0; j < 8; j++, c++) {
+ fprintf(stderr, "%x ",*c);
+ }
+ fprintf(stderr, "\n");
+ }
+ }
+ */
+ }
+ else { /* unsigned short */
+ shortData = (jshort *)(*(table->GetPrimitiveArrayCritical))(env,
+ imageYup,
+ NULL);
+ }
+ }
+ else {
+ byteData = NULL;
+ shortData = NULL;
+ }
+ if (format != FORMAT_USHORT_GRAY) {
+ glTexImage2D(target, level, oglInternalFormat,
+ width, height, boundaryWidth,
+ oglFormat, GL_UNSIGNED_BYTE, (GLvoid *)byteData);
+ }
+ else {
+ glTexImage2D(target, level, oglInternalFormat,
+ width, height, boundaryWidth,
+ oglFormat, GL_UNSIGNED_SHORT, (GLvoid *)shortData);
+ }
+
+ if (imageYup != NULL) {
+ if (format != FORMAT_USHORT_GRAY) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, imageYup, byteData, 0);
+ }
+ else {
+ (*(table->ReleasePrimitiveArrayCritical))(env, imageYup, shortData, 0);
+ }
+ }
+
+ /* No idea why we need following call. */
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+}
+
+
+/*
+ * common function to update 2D texture image for different target
+ */
+
+void updateTexture2DSubImage(
+ JNIEnv *env,
+ GraphicsContextPropertiesInfo *ctxProperties,
+ jint target,
+ jint level,
+ jint xoffset,
+ jint yoffset,
+ jint internalFormat,
+ jint format,
+ jint imgXOffset,
+ jint imgYOffset,
+ jint tilew,
+ jint width,
+ jint height,
+ jbyteArray image) {
+
+ GLenum oglFormat = 0, oglInternalFormat=0;
+ JNIEnv table = *env;
+ jbyte *byteData, *tmpByte;
+ jshort *shortData, *tmpShort;
+ jint numBytes = 0;
+ jboolean pixelStore = JNI_FALSE;
+
+
+ switch (internalFormat) {
+ case INTENSITY:
+ oglInternalFormat = GL_INTENSITY;
+ break;
+ case LUMINANCE:
+ oglInternalFormat = GL_LUMINANCE;
+ break;
+ case ALPHA:
+ oglInternalFormat = GL_ALPHA;
+ break;
+ case LUMINANCE_ALPHA:
+ oglInternalFormat = GL_LUMINANCE_ALPHA;
+ break;
+ case J3D_RGB:
+ oglInternalFormat = GL_RGB;
+ break;
+ case J3D_RGBA:
+ oglInternalFormat = GL_RGBA;
+ break;
+ }
+
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ /* all RGB types are stored as RGBA */
+ oglFormat = GL_RGBA;
+ numBytes = 4;
+ break;
+ case FORMAT_BYTE_RGB:
+ oglFormat = GL_RGB;
+ numBytes = 3;
+ break;
+
+ case FORMAT_BYTE_ABGR:
+ if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */
+ oglFormat = GL_ABGR_EXT;
+ numBytes = 4;
+ }
+ break;
+ case FORMAT_BYTE_BGR:
+ if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */
+ oglFormat = ctxProperties->bgr_ext_enum;
+ numBytes = 3;
+ }
+ break;
+
+ case FORMAT_BYTE_LA:
+ /* all LA types are stored as LA8 */
+ oglFormat = GL_LUMINANCE_ALPHA;
+ numBytes = 2;
+ break;
+ case FORMAT_BYTE_GRAY:
+ if (oglInternalFormat == GL_ALPHA) {
+ oglFormat = GL_ALPHA;
+ } else {
+ oglFormat = GL_LUMINANCE;
+ }
+ numBytes = 1;
+ case FORMAT_USHORT_GRAY:
+ if (oglInternalFormat == GL_ALPHA) {
+ oglFormat = GL_ALPHA;
+ } else {
+ oglFormat = GL_LUMINANCE;
+ }
+ numBytes = 2;
+ break;
+ }
+ /*
+ fprintf(stderr,"format = %x\n",format);
+ fprintf(stderr,"oglFormat = %x\n",oglFormat);
+ fprintf(stderr, "imgXOffset = %d\n",imgXOffset);
+ fprintf(stderr, "imgYOffset = %d\n",imgYOffset);
+ fprintf(stderr, "xoffset = %d\n",xoffset);
+ fprintf(stderr, "yoffset = %d\n",yoffset);
+ fprintf(stderr, "tilew = %d\n",tilew);
+ fprintf(stderr, "numBytes = %d\n",numBytes);
+ fprintf(stderr, "width = %d\n",width);
+ fprintf(stderr, "height = %d\n",height);
+ */
+ if (imgXOffset > 0 || (width < tilew)) {
+ pixelStore = JNI_TRUE;
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, tilew);
+ }
+
+ if (format != FORMAT_USHORT_GRAY) {
+ int off = 0;
+ byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env,
+ image,
+ NULL);
+ /* offset by the imageOffset */
+ off = (tilew * imgYOffset + imgXOffset) * numBytes;
+ tmpByte = byteData+(off);
+
+/*
+printf("tmpByte: %x %x %x %x\n", *(tmpByte), *(tmpByte+1),
+ *(tmpByte+2), *(tmpByte+3));
+*/
+
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height,
+ oglFormat, GL_UNSIGNED_BYTE, (GLvoid *)tmpByte);
+ (*(table->ReleasePrimitiveArrayCritical))(env, image, byteData, 0);
+ } else { /* unsigned short */
+ shortData = (jshort *)(*(table->GetPrimitiveArrayCritical))(env,
+ image,
+ NULL);
+ tmpShort = (jshort*)((jbyte*)shortData+
+ (tilew * imgYOffset + imgXOffset)*numBytes);
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height,
+ oglFormat, GL_UNSIGNED_SHORT, (GLvoid *)tmpShort);
+ (*(table->ReleasePrimitiveArrayCritical))(env, image, shortData, 0);
+ }
+ if (pixelStore) {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_bindTexture(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint objectId,
+ jboolean enable)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->textureCubeMapAvailable) {
+ glDisable(ctxProperties->texture_cube_map_ext_enum);
+ }
+ if (ctxProperties->texture3DAvailable) {
+ glDisable(ctxProperties->texture_3D_ext_enum);
+ }
+
+ if (enable == JNI_FALSE) {
+ glDisable(GL_TEXTURE_2D);
+
+ } else {
+ glBindTexture(GL_TEXTURE_2D, objectId);
+ glEnable(GL_TEXTURE_2D);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureFilterModes(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint minFilter,
+ jint magFilter)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureFilterModes(ctxProperties, GL_TEXTURE_2D,
+ minFilter, magFilter);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureLodRange(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint baseLevel,
+ jint maximumLevel,
+ jfloat minimumLOD,
+ jfloat maximumLOD)
+{
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureLodRange(ctxProperties, GL_TEXTURE_2D,
+ baseLevel, maximumLevel,
+ minimumLOD, maximumLOD);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureLodOffset(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jfloat lodOffsetS,
+ jfloat lodOffsetT,
+ jfloat lodOffsetR)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureLodOffset(ctxProperties, GL_TEXTURE_2D,
+ lodOffsetS, lodOffsetT, lodOffsetR);
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureBoundary(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint boundaryModeS,
+ jint boundaryModeT,
+ jfloat boundaryRed,
+ jfloat boundaryGreen,
+ jfloat boundaryBlue,
+ jfloat boundaryAlpha)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureBoundary(ctxProperties, GL_TEXTURE_2D,
+ boundaryModeS, boundaryModeT, -1,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureSharpenFunc(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint numPts,
+ jfloatArray pts)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureSharpenFunc(env, ctxProperties, GL_TEXTURE_2D, numPts, pts);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureFilter4Func(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint numPts,
+ jfloatArray pts)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureFilter4Func(env, ctxProperties, GL_TEXTURE_2D, numPts, pts);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureAnisotropicFilter(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jfloat degree)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureAnisotropicFilter(env, ctxProperties, GL_TEXTURE_2D, degree);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture2DRetained_updateTextureSubImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint level,
+ jint xoffset,
+ jint yoffset,
+ jint internalFormat,
+ jint format,
+ jint imgXOffset,
+ jint imgYOffset,
+ jint tilew,
+ jint width,
+ jint height,
+ jbyteArray image) {
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ updateTexture2DSubImage(env, ctxProperties, GL_TEXTURE_2D,
+ level, xoffset, yoffset,
+ internalFormat, format,
+ imgXOffset, imgYOffset, tilew, width, height,
+ image);
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture2DRetained_updateTextureImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint numLevels,
+ jint level,
+ jint internalFormat,
+ jint format,
+ jint width,
+ jint height,
+ jint boundaryWidth,
+ jbyteArray imageYup)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTexture2DImage(env, ctxProperties, GL_TEXTURE_2D,
+ numLevels, level, internalFormat, format,
+ width, height, boundaryWidth, imageYup);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture2DRetained_updateDetailTextureParameters(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint mode,
+ jint level,
+ jint nPts,
+ jfloatArray funcPts)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ float *pts = NULL;
+ JNIEnv table = *env;
+
+ if (ctxProperties->textureDetailAvailable) {
+ switch (mode) {
+ case javax_media_j3d_Texture2D_DETAIL_ADD:
+ glTexParameterf(GL_TEXTURE_2D,
+ ctxProperties->texture_detail_mode_enum, GL_ADD);
+ break;
+ case javax_media_j3d_Texture2D_DETAIL_MODULATE:
+ glTexParameterf(GL_TEXTURE_2D,
+ ctxProperties->texture_detail_mode_enum, GL_MODULATE);
+ break;
+ }
+
+ glTexParameteri(GL_TEXTURE_2D,
+ ctxProperties->texture_detail_level_enum, -level);
+
+ if (nPts > 0) {
+ pts = (jfloat *)(*(table->GetPrimitiveArrayCritical))(env,
+ funcPts, NULL);
+ }
+ ctxProperties->glDetailTexFuncSGIS(GL_TEXTURE_2D, nPts, pts);
+
+ if (pts != NULL) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, funcPts, pts, 0);
+ }
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_DetailTextureImage_bindTexture(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint objectId)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->textureDetailAvailable) {
+ glBindTexture(ctxProperties->texture_detail_ext_enum, objectId);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_DetailTextureImage_updateTextureSubImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint level,
+ jint xoffset,
+ jint yoffset,
+ jint internalFormat,
+ jint format,
+ jint imgXOffset,
+ jint imgYOffset,
+ jint tilew,
+ jint width,
+ jint height,
+ jbyteArray image) {
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->textureDetailAvailable) {
+ updateTexture2DSubImage(env, ctxProperties,
+ ctxProperties->texture_detail_ext_enum,
+ level, xoffset, yoffset,
+ internalFormat, format,
+ imgXOffset, imgYOffset, tilew, width, height,
+ image);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_DetailTextureImage_updateTextureImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint numLevels,
+ jint level,
+ jint internalFormat,
+ jint format,
+ jint width,
+ jint height,
+ jint boundaryWidth,
+ jbyteArray imageYup)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->textureDetailAvailable) {
+ updateTexture2DImage(env, ctxProperties,
+ ctxProperties->texture_detail_ext_enum,
+ numLevels, level, internalFormat, format,
+ width, height, boundaryWidth, imageYup);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_bindTexture(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint objectId,
+ jboolean enable)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->textureCubeMapAvailable) {
+ /* textureCubeMap will take precedure over 3D Texture */
+ glDisable(ctxProperties->texture_cube_map_ext_enum);
+ }
+
+ if (enable == JNI_FALSE) {
+ if(ctxProperties->texture3DAvailable) {
+ glDisable(ctxProperties->texture_3D_ext_enum);
+ }
+
+ } else {
+ if(ctxProperties->texture3DAvailable){
+ glBindTexture(ctxProperties->texture_3D_ext_enum, objectId);
+ glEnable(ctxProperties->texture_3D_ext_enum);
+ }
+ }
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureFilterModes(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint minFilter,
+ jint magFilter)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureFilterModes(ctxProperties, GL_TEXTURE_3D,
+ minFilter, magFilter);
+}
+
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureLodRange(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint baseLevel,
+ jint maximumLevel,
+ jfloat minimumLOD,
+ jfloat maximumLOD)
+{
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureLodRange(ctxProperties, GL_TEXTURE_3D,
+ baseLevel, maximumLevel,
+ minimumLOD, maximumLOD);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureLodOffset(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jfloat lodOffsetS,
+ jfloat lodOffsetT,
+ jfloat lodOffsetR)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureLodOffset(ctxProperties, GL_TEXTURE_3D,
+ lodOffsetS, lodOffsetT, lodOffsetR);
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureBoundary(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint boundaryModeS,
+ jint boundaryModeT,
+ jint boundaryModeR,
+ jfloat boundaryRed,
+ jfloat boundaryGreen,
+ jfloat boundaryBlue,
+ jfloat boundaryAlpha)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureBoundary(ctxProperties, GL_TEXTURE_3D,
+ boundaryModeS, boundaryModeT, boundaryModeR,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureSharpenFunc(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint numPts,
+ jfloatArray pts)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureSharpenFunc(env, ctxProperties, GL_TEXTURE_3D, numPts, pts);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureFilter4Func(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint numPts,
+ jfloatArray pts)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureFilter4Func(env, ctxProperties, GL_TEXTURE_3D, numPts, pts);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureAnisotropicFilter(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jfloat degree)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureAnisotropicFilter(env, ctxProperties, GL_TEXTURE_3D, degree);
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint numLevels,
+ jint level,
+ jint internalFormat,
+ jint format,
+ jint width,
+ jint height,
+ jint depth,
+ jint boundaryWidth,
+ jbyteArray imageYup)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if(ctxProperties->texture3DAvailable) {
+
+ GLenum oglFormat = 0, oglInternalFormat=0;
+ JNIEnv table = *env;
+ jbyte *byteData;
+ jshort *shortData;
+
+ switch (internalFormat) {
+ case INTENSITY:
+ oglInternalFormat = GL_INTENSITY;
+ break;
+ case LUMINANCE:
+ oglInternalFormat = GL_LUMINANCE;
+ break;
+ case ALPHA:
+ oglInternalFormat = GL_ALPHA;
+ break;
+ case LUMINANCE_ALPHA:
+ oglInternalFormat = GL_LUMINANCE_ALPHA;
+ break;
+ case J3D_RGB:
+ oglInternalFormat = GL_RGB;
+ break;
+ case J3D_RGBA:
+ oglInternalFormat = GL_RGBA;
+ break;
+ }
+
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ /* all RGB types are stored as RGBA */
+ oglFormat = GL_RGBA;
+ break;
+ case FORMAT_BYTE_RGB:
+ oglFormat = GL_RGB;
+ break;
+
+ case FORMAT_BYTE_ABGR:
+ if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */
+ oglFormat = GL_ABGR_EXT;
+ }
+ break;
+ case FORMAT_BYTE_BGR:
+ if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */
+ oglFormat = ctxProperties->bgr_ext_enum;
+ }
+ break;
+ case FORMAT_BYTE_LA:
+ /* all LA types are stored as LA8 */
+ oglFormat = GL_LUMINANCE_ALPHA;
+ break;
+ case FORMAT_BYTE_GRAY:
+ case FORMAT_USHORT_GRAY:
+ if (oglInternalFormat == GL_ALPHA) {
+ oglFormat = GL_ALPHA;
+ } else {
+ oglFormat = GL_LUMINANCE;
+ }
+ break;
+ }
+
+ /*
+ fprintf(stderr,"internalFormat = %x\n",internalFormat);
+ fprintf(stderr,"format = %x\n",format);
+ fprintf(stderr,"oglFormat = %x\n",oglFormat);
+ fprintf(stderr,"oglInternalFormat = %x\n",oglInternalFormat);
+ */
+ if (imageYup != NULL) {
+ if (format != FORMAT_USHORT_GRAY) {
+ byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env,
+ imageYup,
+ NULL);
+ }
+ else { /* unsigned short */
+ shortData = (jshort *)(*(table->GetPrimitiveArrayCritical))(env,
+ imageYup,
+ NULL);
+
+ }
+ } else {
+ byteData = NULL;
+ shortData = NULL;
+ }
+
+ if (format != FORMAT_USHORT_GRAY) {
+
+ ctxProperties->glTexImage3DEXT(ctxProperties->texture_3D_ext_enum,
+ level, oglInternalFormat,
+ width, height, depth, boundaryWidth,
+ oglFormat, GL_UNSIGNED_BYTE,
+ (GLvoid *)byteData);
+ }
+ else {
+ ctxProperties->glTexImage3DEXT(ctxProperties->texture_3D_ext_enum,
+ level, oglInternalFormat,
+ width, height, depth, boundaryWidth,
+ oglFormat, GL_UNSIGNED_SHORT,
+ (GLvoid *)shortData);
+ }
+ if (imageYup != NULL) {
+ if (format != FORMAT_USHORT_GRAY) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, imageYup, byteData, 0);
+ } else { /* unsigned short */
+ (*(table->ReleasePrimitiveArrayCritical))(env, imageYup, shortData, 0);
+
+ }
+ }
+
+ /* No idea why we need following call. */
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ }
+
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureSubImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint level,
+ jint xoffset,
+ jint yoffset,
+ jint zoffset,
+ jint internalFormat,
+ jint format,
+ jint imgXOffset,
+ jint imgYOffset,
+ jint imgZOffset,
+ jint tilew,
+ jint tileh,
+ jint width,
+ jint height,
+ jint depth,
+ jbyteArray image) {
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->texture3DAvailable) {
+ GLenum oglFormat = 0, oglInternalFormat=0;
+ JNIEnv table = *env;
+ jbyte *byteData, *tmpByte;
+ jshort *shortData, *tmpShort;
+ jint numBytes = 0;
+ jboolean pixelStore = JNI_FALSE;
+
+ switch (internalFormat) {
+ case INTENSITY:
+ oglInternalFormat = GL_INTENSITY;
+ break;
+ case LUMINANCE:
+ oglInternalFormat = GL_LUMINANCE;
+ break;
+ case ALPHA:
+ oglInternalFormat = GL_ALPHA;
+ break;
+ case LUMINANCE_ALPHA:
+ oglInternalFormat = GL_LUMINANCE_ALPHA;
+ break;
+ case J3D_RGB:
+ oglInternalFormat = GL_RGB;
+ break;
+ case J3D_RGBA:
+ oglInternalFormat = GL_RGBA;
+ break;
+ }
+
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ /* all RGB types are stored as RGBA */
+ oglFormat = GL_RGBA;
+ numBytes = 4;
+ break;
+ case FORMAT_BYTE_RGB:
+ oglFormat = GL_RGB;
+ numBytes = 3;
+ break;
+
+ case FORMAT_BYTE_ABGR:
+ if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */
+ oglFormat = GL_ABGR_EXT;
+ numBytes = 4;
+ }
+ break;
+ case FORMAT_BYTE_BGR:
+ if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */
+ oglFormat = ctxProperties->bgr_ext_enum;
+ numBytes = 3;
+ }
+ break;
+
+ case FORMAT_BYTE_LA:
+ /* all LA types are stored as LA8 */
+ oglFormat = GL_LUMINANCE_ALPHA;
+ numBytes = 2;
+ break;
+ case FORMAT_BYTE_GRAY:
+ if (oglInternalFormat == GL_ALPHA) {
+ oglFormat = GL_ALPHA;
+ } else {
+ oglFormat = GL_LUMINANCE;
+ }
+ numBytes = 1;
+ case FORMAT_USHORT_GRAY:
+ if (oglInternalFormat == GL_ALPHA) {
+ oglFormat = GL_ALPHA;
+ } else {
+ oglFormat = GL_LUMINANCE;
+ }
+ numBytes = 2;
+ break;
+ }
+ /*
+ fprintf(stderr,"format = %x\n",format);
+ fprintf(stderr,"oglFormat = %x\n",oglFormat);
+ fprintf(stderr, "imgXOffset = %d\n",imgXOffset);
+ fprintf(stderr, "imgYOffset = %d\n",imgYOffset);
+ fprintf(stderr, "imgZOffset = %d\n",imgZOffset);
+ fprintf(stderr, "xoffset = %d\n",xoffset);
+ fprintf(stderr, "yoffset = %d\n",yoffset);
+ fprintf(stderr, "zoffset = %d\n",zoffset);
+ fprintf(stderr, "tilew = %d\n",tilew);
+ fprintf(stderr, "tileh = %d\n",tilew);
+ fprintf(stderr, "numBytes = %d\n",numBytes);
+ fprintf(stderr, "width = %d\n",width);
+ fprintf(stderr, "height = %d\n",height);
+ fprintf(stderr, "depth = %d\n",depth);
+ */
+ if (imgXOffset > 0 || (width < tilew)) {
+ pixelStore = JNI_TRUE;
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, tilew);
+ }
+
+ if (format != FORMAT_USHORT_GRAY) {
+ byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env,
+ image, NULL);
+
+ tmpByte = byteData +
+ (tilew * tileh * imgZOffset +
+ tilew * imgYOffset + imgXOffset) * numBytes;
+
+ ctxProperties->glTexSubImage3DEXT(
+ ctxProperties->texture_3D_ext_enum,
+ level, xoffset, yoffset, zoffset,
+ width, height, depth,
+ oglFormat, GL_UNSIGNED_BYTE,
+ (GLvoid *)tmpByte);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, image, byteData, 0);
+ } else { /* unsigned short */
+ shortData = (jshort *)(*(table->GetPrimitiveArrayCritical))(env,
+ image, NULL);
+ tmpShort = (jshort*)((jbyte*)shortData+
+ (tilew * tileh * imgZOffset +
+ tilew * imgYOffset + imgXOffset)*numBytes);
+
+ ctxProperties->glTexSubImage3DEXT(
+ ctxProperties->texture_3D_ext_enum,
+ level, xoffset, yoffset, zoffset,
+ width, height, depth,
+ oglFormat, GL_UNSIGNED_SHORT,
+ (GLvoid *)tmpShort);
+ (*(table->ReleasePrimitiveArrayCritical))(env, image, shortData, 0);
+ }
+ if (pixelStore) {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ }
+ }
+}
+
+
+/*
+ * mapping from java enum to gl enum
+ */
+
+jint _gl_textureCubeMapFace[] = {
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT,
+};
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_bindTexture(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint objectId,
+ jboolean enable)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ /*
+ * TextureCubeMap will take precedure over 3D Texture so
+ * there is no need to disable 3D Texture here.
+ */
+ if (ctxProperties->textureCubeMapAvailable) {
+ if (enable == JNI_FALSE) {
+ glDisable(ctxProperties->texture_cube_map_ext_enum);
+ } else {
+ glBindTexture(ctxProperties->texture_cube_map_ext_enum, objectId);
+ glEnable(ctxProperties->texture_cube_map_ext_enum);
+ }
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureFilterModes(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint minFilter,
+ jint magFilter)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->textureCubeMapAvailable) {
+ updateTextureFilterModes(ctxProperties,
+ ctxProperties->texture_cube_map_ext_enum,
+ minFilter, magFilter);
+ }
+}
+
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureLodRange(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint baseLevel,
+ jint maximumLevel,
+ jfloat minimumLOD,
+ jfloat maximumLOD)
+{
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureLodRange(ctxProperties,
+ ctxProperties->texture_cube_map_ext_enum,
+ baseLevel, maximumLevel,
+ minimumLOD, maximumLOD);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureLodOffset(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jfloat lodOffsetS,
+ jfloat lodOffsetT,
+ jfloat lodOffsetR)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ updateTextureLodOffset(ctxProperties,
+ ctxProperties->texture_cube_map_ext_enum,
+ lodOffsetS, lodOffsetT, lodOffsetR);
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureBoundary(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint boundaryModeS,
+ jint boundaryModeT,
+ jfloat boundaryRed,
+ jfloat boundaryGreen,
+ jfloat boundaryBlue,
+ jfloat boundaryAlpha)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->textureCubeMapAvailable) {
+ updateTextureBoundary(ctxProperties,
+ ctxProperties->texture_cube_map_ext_enum,
+ boundaryModeS, boundaryModeT, -1,
+ boundaryRed, boundaryGreen,
+ boundaryBlue, boundaryAlpha);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureSharpenFunc(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint numPts,
+ jfloatArray pts)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->textureCubeMapAvailable) {
+ updateTextureSharpenFunc(env, ctxProperties,
+ ctxProperties->texture_cube_map_ext_enum,
+ numPts, pts);
+ }
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureFilter4Func(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint numPts,
+ jfloatArray pts)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->textureCubeMapAvailable) {
+ updateTextureFilter4Func(env, ctxProperties,
+ ctxProperties->texture_cube_map_ext_enum,
+ numPts, pts);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureAnisotropicFilter(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jfloat degree)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->textureCubeMapAvailable) {
+ updateTextureAnisotropicFilter(env, ctxProperties,
+ ctxProperties->texture_cube_map_ext_enum,
+ degree);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureSubImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint face,
+ jint level,
+ jint xoffset,
+ jint yoffset,
+ jint internalFormat,
+ jint format,
+ jint imgXOffset,
+ jint imgYOffset,
+ jint tilew,
+ jint width,
+ jint height,
+ jbyteArray image) {
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ updateTexture2DSubImage(env, ctxProperties, _gl_textureCubeMapFace[face],
+ level, xoffset, yoffset, internalFormat,
+ format, imgXOffset, imgYOffset, tilew,
+ width, height, image);
+}
+
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureImage(
+ JNIEnv *env,
+ jobject texture,
+ jlong ctxInfo,
+ jint face,
+ jint numLevels,
+ jint level,
+ jint internalFormat,
+ jint format,
+ jint width,
+ jint height,
+ jint boundaryWidth,
+ jbyteArray imageYup)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ updateTexture2DImage(env, ctxProperties, _gl_textureCubeMapFace[face],
+ numLevels, level, internalFormat, format,
+ width, height, boundaryWidth, imageYup);
+}
+
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_Canvas3D_decal1stChildSetup(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo)
+{
+ glEnable(GL_STENCIL_TEST);
+ glClearStencil(0x0);
+ glClear(GL_STENCIL_BUFFER_BIT);
+ glStencilFunc (GL_ALWAYS, 0x1, 0x1);
+ glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
+ if (glIsEnabled(GL_DEPTH_TEST))
+ return JNI_TRUE;
+ else
+ return JNI_FALSE;
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_decalNthChildSetup(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo)
+{
+ glDisable(GL_DEPTH_TEST);
+ glStencilFunc (GL_EQUAL, 0x1, 0x1);
+ glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_decalReset(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jboolean depthBufferEnable)
+{
+ glDisable(GL_STENCIL_TEST);
+ if (depthBufferEnable == JNI_TRUE)
+ glEnable(GL_DEPTH_TEST);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_ctxUpdateEyeLightingEnable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jboolean localEyeLightingEnable)
+{
+ if (localEyeLightingEnable == JNI_TRUE) {
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+ } else {
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_updateSeparateSpecularColorEnable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jboolean enable)
+{
+ /*
+ * This method will not be called if the rendering layer does not support
+ * separate specular color control. The checking of the availability
+ * of the functionality is done in Renderer at rendering time
+ */
+
+ /* 1.2 feature only */
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if(ctxProperties->seperate_specular_color) {
+ if (enable == JNI_TRUE) {
+ glLightModeli(ctxProperties->light_model_color_control_enum,
+ ctxProperties->seperate_specular_color_enum);
+ } else {
+ glLightModeli(ctxProperties->light_model_color_control_enum, ctxProperties->single_color_enum);
+ }
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_TextureUnitStateRetained_updateTextureUnitState(
+ JNIEnv *env,
+ jobject cv,
+ jlong ctxInfo,
+ jint index,
+ jboolean enable)
+{
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if(ctxProperties->arb_multitexture) {
+ if (index >= 0) {
+ ctxProperties->glActiveTextureARB(index + GL_TEXTURE0_ARB);
+ ctxProperties->glClientActiveTextureARB(GL_TEXTURE0_ARB + index);
+ if (ctxProperties->textureRegisterCombinersAvailable) {
+ ctxProperties->currentTextureUnit = index + GL_TEXTURE0_ARB;
+ ctxProperties->currentCombinerUnit = index + GL_COMBINER0_NV;
+ if (ctxProperties->glCombinerParameteriNV!=NULL)
+ ctxProperties->glCombinerParameteriNV(
+ GL_NUM_GENERAL_COMBINERS_NV, index + 1);
+
+ }
+ }
+ } /* GL_ARB_multitexture */
+
+ if (enable == JNI_FALSE) {
+ /* if not enabled, then don't enable any tex mapping */
+
+ glDisable(GL_TEXTURE_1D);
+ glDisable(GL_TEXTURE_2D);
+
+ if(ctxProperties->texture3DAvailable)
+ glDisable(ctxProperties->texture_3D_ext_enum);
+
+ if(ctxProperties->textureCubeMapAvailable)
+ glDisable(ctxProperties->texture_cube_map_ext_enum);
+ }
+
+ /*
+ * if it is enabled, the enable flag will be taken care of
+ * in the bindTexture call
+ */
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setDepthFunc(
+ JNIEnv * env,
+ jobject obj,
+ jlong ctxInfo,
+ jint func)
+{
+ if (func == javax_media_j3d_RenderingAttributesRetained_LESS)
+ glDepthFunc(GL_LESS);
+ else if (func == javax_media_j3d_RenderingAttributesRetained_LEQUAL)
+ glDepthFunc(GL_LEQUAL);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setBlendColor(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jfloat colorRed,
+ jfloat colorGreen,
+ jfloat colorBlue,
+ jfloat colorAlpha)
+{
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->blend_color_ext) {
+ /*
+ fprintf(stderr, "setBlendColor is on: %f %f %f %f\n",
+ colorRed, colorGreen, colorBlue, colorAlpha);
+ */
+
+ ctxProperties->glBlendColor(colorRed, colorGreen, colorBlue, colorAlpha);
+ }
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setBlendFunc(
+ JNIEnv * env,
+ jobject obj,
+ jlong ctxInfo,
+ jint srcBlendFunction,
+ jint dstBlendFunction)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ glEnable(GL_BLEND);
+ glBlendFunc(ctxProperties->blendFunctionTable[srcBlendFunction],
+ ctxProperties->blendFunctionTable[dstBlendFunction]);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setFogEnableFlag(
+ JNIEnv * env,
+ jobject obj,
+ jlong ctxInfo,
+ jboolean enable)
+{
+ if (enable == JNI_TRUE)
+ glEnable(GL_FOG);
+ else
+ glDisable(GL_FOG);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_activeTextureUnit(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint index)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if(ctxProperties->arb_multitexture){
+ ctxProperties->glActiveTextureARB(GL_TEXTURE0_ARB + index);
+ ctxProperties->glClientActiveTextureARB(GL_TEXTURE0_ARB + index);
+ /* GL_ARB_multitexture */
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_updateTexUnitStateMap(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint numActiveTexUnit,
+ jintArray texUnitStateMapArray)
+{
+ /*
+ * texture unit state map is explicitly handled in
+ * execute; for display list, texture unit has to match
+ * texture unit state.
+ */
+}
diff --git a/src/native/ogl/Canvas3D.c b/src/native/ogl/Canvas3D.c
new file mode 100644
index 0000000..86d037d
--- /dev/null
+++ b/src/native/ogl/Canvas3D.c
@@ -0,0 +1,3388 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <jni.h>
+
+
+#include "gldefs.h"
+
+#ifdef DEBUG
+/* Uncomment the following for VERBOSE debug messages */
+/* #define VERBOSE */
+#endif /* DEBUG */
+
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef BOOL
+#define BOOL int
+#endif
+
+static char *gl_VERSION;
+static char *gl_VENDOR;
+
+void initializeCtxInfo(JNIEnv *env, GraphicsContextPropertiesInfo* ctxInfo);
+void cleanupCtxInfo(GraphicsContextPropertiesInfo* ctxInfo);
+
+/*
+ * Class: javax_media_j3d_Canvas3D
+ * Method: getTextureColorTableSize
+ * Signature: ()I
+ */
+int getTextureColorTableSize(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ char *extensionStr,
+ int minorVersion);
+
+
+#ifdef WIN32
+ extern HDC getMonitorDC(int screen);
+#endif
+
+/*
+ * extract the version numbers
+ * when return , numbers[0] contains major version number
+ * numbers[1] contains minor version number
+ */
+void extractVersionInfo(char *versionStr, int* numbers){
+ char *majorNumStr;
+ char *minorNumStr;
+ majorNumStr = strtok(versionStr, (char *)".");
+ minorNumStr = strtok(0, (char *)".");
+ if (majorNumStr != NULL)
+ numbers[0] = atoi(majorNumStr);
+ if (minorNumStr != NULL)
+ numbers[1] = atoi(minorNumStr);
+
+ /* fprintf(stderr, "majorNumStr = %d, minNumStr = %d \n", numbers[0], numbers[1]); */
+ return;
+}
+
+/*
+ * check if the extension is supported
+ */
+int isExtensionSupported(const char *allExtensions, const char *extension)
+{
+ const char *start;
+ const char *where, *terminator;
+
+ /* Extension names should not have spaces. */
+ where = (const char *) strchr(extension, ' ');
+ if (where || *extension == '\0')
+ return 0;
+
+ /*
+ * It takes a bit of care to be fool-proof about parsing the
+ * OpenGL extensions string. Don't be fooled by sub-strings,
+ * etc.
+ */
+ start = allExtensions;
+ for (;;) {
+ where = (const char *) strstr((const char *) start, extension);
+ if (!where)
+ break;
+ terminator = where + strlen(extension);
+ if (where == start || *(where - 1) == ' ')
+ if (*terminator == ' ' || *terminator == '\0')
+ return 1;
+ start = terminator;
+ }
+ return 0;
+}
+
+void checkTextureExtensions(
+ JNIEnv *env,
+ jobject obj,
+ char *tmpExtensionStr,
+ int versionNumber,
+ GraphicsContextPropertiesInfo* ctxInfo) {
+
+ if(isExtensionSupported(tmpExtensionStr, "GL_ARB_multitexture")) {
+ ctxInfo->arb_multitexture = JNI_TRUE ;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_MULTI_TEXTURE;
+ glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &ctxInfo->textureUnitCount);
+
+ }
+
+ if(isExtensionSupported(tmpExtensionStr,"GL_SGI_texture_color_table" )){
+ ctxInfo->textureColorTableAvailable = JNI_TRUE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COLOR_TABLE;
+
+ /* get texture color table size */
+ /* need to check later */
+ ctxInfo->textureColorTableSize = getTextureColorTableSize(env, obj, (jlong)ctxInfo, tmpExtensionStr, versionNumber);
+ if (ctxInfo->textureColorTableSize <= 0) {
+ ctxInfo->textureColorTableAvailable = JNI_FALSE;
+ ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_COLOR_TABLE;
+ }
+ if (ctxInfo->textureColorTableSize > 256) {
+ ctxInfo->textureColorTableSize = 256;
+ }
+ }
+
+ if(isExtensionSupported(tmpExtensionStr,"GL_ARB_texture_env_combine" )){
+ ctxInfo->textureEnvCombineAvailable = JNI_TRUE;
+ ctxInfo->textureCombineSubtractAvailable = JNI_TRUE;
+
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE_SUBTRACT;
+ ctxInfo->combine_enum = GL_COMBINE_ARB;
+ ctxInfo->combine_add_signed_enum = GL_ADD_SIGNED_ARB;
+ ctxInfo->combine_interpolate_enum = GL_INTERPOLATE_ARB;
+ ctxInfo->combine_subtract_enum = GL_SUBTRACT_ARB;
+
+ } else if(isExtensionSupported(tmpExtensionStr,"GL_EXT_texture_env_combine" )){
+ ctxInfo->textureEnvCombineAvailable = JNI_TRUE;
+ ctxInfo->textureCombineSubtractAvailable = JNI_FALSE;
+
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE;
+ ctxInfo->combine_enum = GL_COMBINE_EXT;
+ ctxInfo->combine_add_signed_enum = GL_ADD_SIGNED_EXT;
+ ctxInfo->combine_interpolate_enum = GL_INTERPOLATE_EXT;
+
+ /* EXT_texture_env_combine does not include subtract */
+ ctxInfo->combine_subtract_enum = 0;
+ }
+
+ if(isExtensionSupported(tmpExtensionStr,"GL_NV_register_combiners" )) {
+ ctxInfo->textureRegisterCombinersAvailable = JNI_TRUE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_REGISTER_COMBINERS;
+#if defined(SOLARIS) || defined(__linux__)
+ ctxInfo->glCombinerInputNV =
+ (MYPFNGLCOMBINERINPUTNV) glCombinerInputNV;
+ ctxInfo->glFinalCombinerInputNV =
+ (MYPFNGLFINALCOMBINERINPUTNV) glFinalCombinerInputNV;
+ ctxInfo->glCombinerOutputNV =
+ (MYPFNGLCOMBINEROUTPUTNV) glCombinerOutputNV;
+ ctxInfo->glCombinerParameterfvNV =
+ (MYPFNGLCOMBINERPARAMETERFVNV) glCombinerParameterfvNV;
+ ctxInfo->glCombinerParameterivNV =
+ (MYPFNGLCOMBINERPARAMETERIVNV) glCombinerParameterivNV;
+ ctxInfo->glCombinerParameterfNV =
+ (MYPFNGLCOMBINERPARAMETERFNV) glCombinerParameterfNV;
+ ctxInfo->glCombinerParameteriNV =
+ (MYPFNGLCOMBINERPARAMETERINV) glCombinerParameteriNV;
+ if (ctxInfo->glCombinerInputNV == NULL ||
+ ctxInfo->glFinalCombinerInputNV == NULL ||
+ ctxInfo->glCombinerOutputNV == NULL ||
+ ctxInfo->glCombinerParameterfvNV == NULL ||
+ ctxInfo->glCombinerParameterivNV == NULL ||
+ ctxInfo->glCombinerParameterfNV == NULL ||
+ ctxInfo->glCombinerParameteriNV == NULL) {
+ /* lets play safe: */
+ ctxInfo->textureExtMask &=
+ ~javax_media_j3d_Canvas3D_TEXTURE_REGISTER_COMBINERS;
+ ctxInfo->textureRegisterCombinersAvailable = JNI_FALSE;
+ }
+#endif
+
+#ifdef WIN32
+ ctxInfo->glCombinerInputNV =
+ (MYPFNGLCOMBINERINPUTNV) wglGetProcAddress("glCombinerInputNV");
+ ctxInfo->glFinalCombinerInputNV =
+ (MYPFNGLFINALCOMBINERINPUTNV) wglGetProcAddress("glFinalCombinerInputNV");
+ ctxInfo->glCombinerOutputNV =
+ (MYPFNGLCOMBINEROUTPUTNV) wglGetProcAddress("glCombinerOutputNV");
+ ctxInfo->glCombinerParameterfvNV =
+ (MYPFNGLCOMBINERPARAMETERFVNV) wglGetProcAddress("glCombinerParameterfvNV");
+ ctxInfo->glCombinerParameterivNV =
+ (MYPFNGLCOMBINERPARAMETERIVNV) wglGetProcAddress("glCombinerParameterivNV");
+ ctxInfo->glCombinerParameterfNV =
+ (MYPFNGLCOMBINERPARAMETERFNV) wglGetProcAddress("glCombinerParameterfNV");
+ ctxInfo->glCombinerParameteriNV =
+ (MYPFNGLCOMBINERPARAMETERINV) wglGetProcAddress("glCombinerParameteriNV");
+
+ /*
+ if (ctxInfo->glCombinerInputNV == NULL) {
+ printf("glCombinerInputNV == NULL\n");
+ }
+ if (ctxInfo->glFinalCombinerInputNV == NULL) {
+ printf("glFinalCombinerInputNV == NULL\n");
+ }
+ if (ctxInfo->glCombinerOutputNV == NULL) {
+ printf("ctxInfo->glCombinerOutputNV == NULL\n");
+ }
+ if (ctxInfo->glCombinerParameterfvNV == NULL) {
+ printf("ctxInfo->glCombinerParameterfvNV == NULL\n");
+ }
+ if (ctxInfo->glCombinerParameterivNV == NULL) {
+ printf("ctxInfo->glCombinerParameterivNV == NULL\n");
+ }
+ if (ctxInfo->glCombinerParameterfNV == NULL) {
+ printf("ctxInfo->glCombinerParameterfNV == NULL\n");
+ }
+ if (ctxInfo->glCombinerParameteriNV == NULL) {
+ printf("ctxInfo->glCombinerParameteriNV == NULL\n");
+ }
+ */
+ if ((ctxInfo->glCombinerInputNV == NULL) ||
+ (ctxInfo->glFinalCombinerInputNV == NULL) ||
+ (ctxInfo->glCombinerOutputNV == NULL) ||
+ (ctxInfo->glCombinerParameterfvNV == NULL) ||
+ (ctxInfo->glCombinerParameterivNV == NULL) ||
+ (ctxInfo->glCombinerParameterfNV == NULL) ||
+ (ctxInfo->glCombinerParameteriNV == NULL)) {
+ ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_REGISTER_COMBINERS;
+ ctxInfo->textureRegisterCombinersAvailable = JNI_FALSE;
+ }
+
+#endif
+
+ }
+
+ if(isExtensionSupported(tmpExtensionStr,"GL_ARB_texture_env_dot3" )) {
+ ctxInfo->textureCombineDot3Available = JNI_TRUE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE_DOT3;
+ ctxInfo->combine_dot3_rgb_enum = GL_DOT3_RGB_ARB;
+ ctxInfo->combine_dot3_rgba_enum = GL_DOT3_RGBA_ARB;
+ } else if(isExtensionSupported(tmpExtensionStr,"GL_EXT_texture_env_dot3" )) {
+ ctxInfo->textureCombineDot3Available = JNI_TRUE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE_DOT3;
+ ctxInfo->combine_dot3_rgb_enum = GL_DOT3_RGB_EXT;
+ ctxInfo->combine_dot3_rgba_enum = GL_DOT3_RGBA_EXT;
+ }
+
+ if (isExtensionSupported(tmpExtensionStr, "GL_ARB_texture_cube_map")) {
+ ctxInfo->texture_cube_map_ext_enum = GL_TEXTURE_CUBE_MAP_ARB;
+ ctxInfo->textureCubeMapAvailable = JNI_TRUE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_CUBE_MAP;
+ } else if (isExtensionSupported(tmpExtensionStr, "GL_EXT_texture_cube_map")) {
+ ctxInfo->texture_cube_map_ext_enum = GL_TEXTURE_CUBE_MAP_EXT;
+ ctxInfo->textureCubeMapAvailable = JNI_TRUE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_CUBE_MAP;
+ }
+
+ if (isExtensionSupported(tmpExtensionStr, "GL_SGIS_sharpen_texture")) {
+ ctxInfo->textureSharpenAvailable = JNI_TRUE;
+ ctxInfo->linear_sharpen_enum = GL_LINEAR_SHARPEN_SGIS;
+ ctxInfo->linear_sharpen_rgb_enum = GL_LINEAR_SHARPEN_COLOR_SGIS;
+ ctxInfo->linear_sharpen_alpha_enum = GL_LINEAR_SHARPEN_ALPHA_SGIS;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_SHARPEN;
+#if defined(SOLARIS) || defined(__linux__)
+ ctxInfo->glSharpenTexFuncSGIS =
+ (MYPFNGLSHARPENTEXFUNCSGI) glSharpenTexFuncSGIS;
+#endif
+#ifdef WIN32
+ ctxInfo->glSharpenTexFuncSGIS = (MYPFNGLSHARPENTEXFUNCSGI)
+ wglGetProcAddress("glSharpenTexFuncSGIS");
+ if (ctxInfo->glSharpenTexFuncSGIS == NULL) {
+ /* printf("ctxInfo->glSharpenTexFuncSGIS == NULL\n"); */
+ ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_SHARPEN;
+ ctxInfo->textureSharpenAvailable = JNI_FALSE;
+ }
+#endif
+ }
+
+ if (isExtensionSupported(tmpExtensionStr, "GL_SGIS_detail_texture")) {
+ ctxInfo->textureDetailAvailable = JNI_TRUE;
+ ctxInfo->texture_detail_ext_enum = GL_DETAIL_TEXTURE_2D_SGIS;
+ ctxInfo->linear_detail_enum = GL_LINEAR_DETAIL_SGIS;
+ ctxInfo->linear_detail_rgb_enum = GL_LINEAR_DETAIL_COLOR_SGIS;
+ ctxInfo->linear_detail_alpha_enum = GL_LINEAR_DETAIL_ALPHA_SGIS;
+ ctxInfo->texture_detail_mode_enum = GL_DETAIL_TEXTURE_MODE_SGIS;
+ ctxInfo->texture_detail_level_enum = GL_DETAIL_TEXTURE_LEVEL_SGIS;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_DETAIL;
+#if defined(SOLARIS) || defined(__linux__)
+ ctxInfo->glDetailTexFuncSGIS =
+ (MYPFNGLDETAILTEXFUNCSGI) glDetailTexFuncSGIS;
+#endif
+#ifdef WIN32
+ ctxInfo->glDetailTexFuncSGIS = (MYPFNGLDETAILTEXFUNCSGI)
+ wglGetProcAddress("glDetailTexFuncSGIS");
+ if (ctxInfo->glDetailTexFuncSGIS == NULL) {
+ /* printf("ctxInfo->glDetailTexFuncSGIS == NULL\n"); */
+ ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_DETAIL;
+ ctxInfo->textureDetailAvailable = JNI_FALSE;
+ }
+#endif
+ }
+
+ if (isExtensionSupported(tmpExtensionStr, "GL_SGIS_texture_filter4")) {
+ ctxInfo->textureFilter4Available = JNI_TRUE;
+ ctxInfo->filter4_enum = GL_FILTER4_SGIS;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_FILTER4;
+#if defined(SOLARIS) || defined(__linux__)
+ ctxInfo->glTexFilterFuncSGIS =
+ (MYPFNGLTEXFILTERFUNCSGI) glTexFilterFuncSGIS;
+#endif
+#ifdef WIN32
+ ctxInfo->glTexFilterFuncSGIS = (MYPFNGLTEXFILTERFUNCSGI)
+ wglGetProcAddress("glTexFilterFuncSGIS");
+ if (ctxInfo->glTexFilterFuncSGIS == NULL) {
+ /* printf("ctxInfo->glTexFilterFuncSGIS == NULL\n"); */
+ ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_FILTER4;
+ ctxInfo->textureFilter4Available = JNI_FALSE;
+ }
+#endif
+ }
+
+ if (isExtensionSupported(tmpExtensionStr,
+ "GL_EXT_texture_filter_anisotropic")) {
+ ctxInfo->textureAnisotropicFilterAvailable = JNI_TRUE;
+ ctxInfo->texture_filter_anisotropic_ext_enum =
+ GL_TEXTURE_MAX_ANISOTROPY_EXT;
+ ctxInfo->max_texture_filter_anisotropy_enum =
+ GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT;
+ ctxInfo->textureExtMask |=
+ javax_media_j3d_Canvas3D_TEXTURE_ANISOTROPIC_FILTER;
+ }
+
+ if (isExtensionSupported(tmpExtensionStr,
+ "GL_ARB_texture_border_clamp")) {
+ ctxInfo->texture_clamp_to_border_enum = GL_CLAMP_TO_BORDER_ARB;
+ } else if (isExtensionSupported(tmpExtensionStr,
+ "GL_SGIS_texture_border_clamp")) {
+ ctxInfo->texture_clamp_to_border_enum = GL_CLAMP_TO_BORDER_SGIS;
+ } else {
+ ctxInfo->texture_clamp_to_border_enum = GL_CLAMP;
+ }
+
+ if (isExtensionSupported(tmpExtensionStr,
+ "GL_SGIX_texture_lod_bias")) {
+ ctxInfo->textureLodBiasAvailable = JNI_TRUE;
+ ctxInfo->textureExtMask |=
+ javax_media_j3d_Canvas3D_TEXTURE_LOD_OFFSET;
+ }
+}
+
+BOOL getJavaBoolEnv(JNIEnv *env, char* envStr)
+{
+ JNIEnv table = *env;
+ jclass cls;
+ jfieldID fieldID;
+ jobject obj;
+
+ cls = (jclass) (*(table->FindClass))(env, "javax/media/j3d/VirtualUniverse");
+
+ if (cls == NULL) {
+ return FALSE;
+ }
+
+ fieldID = (jfieldID) (*(table->GetStaticFieldID))(env, cls, "mc",
+ "Ljavax/media/j3d/MasterControl;");
+ if (fieldID == NULL) {
+ return FALSE;
+ }
+
+ obj = (*(table->GetStaticObjectField))(env, cls, fieldID);
+
+ if (obj == NULL) {
+ return FALSE;
+ }
+
+ cls = (jclass) (*(table->FindClass))(env, "javax/media/j3d/MasterControl");
+
+ if (cls == NULL) {
+ return FALSE;
+ }
+
+ fieldID = (jfieldID) (*(table->GetFieldID))(env, cls, envStr, "Z");
+
+ if (fieldID == NULL ) {
+ return FALSE;
+ }
+
+ return (*(table->GetBooleanField))(env, obj, fieldID);
+}
+
+
+/*
+ * get properties from current context
+ */
+BOOL getPropertiesFromCurrentContext(
+ JNIEnv *env,
+ jobject obj,
+ GraphicsContextPropertiesInfo *ctxInfo,
+ jlong hdc,
+ int pixelFormat,
+ long display,
+ jlong vinfo)
+{
+ JNIEnv table = *env;
+
+ /* version and extension */
+ char *glversion;
+ char *extensionStr;
+ char *tmpVersionStr;
+ char *tmpExtensionStr;
+ int versionNumbers[2];
+ char *cgHwStr = 0;
+ int stencilSize;
+
+#ifdef WIN32
+ PFNWGLGETPIXELFORMATATTRIBIVEXTPROC wglGetPixelFormatAttribivEXT = NULL;
+ PIXELFORMATDESCRIPTOR pfd;
+ int attr[3];
+ int piValues[2];
+#endif
+
+ /* get OpenGL version */
+ glversion = (char *)glGetString(GL_VERSION);
+ if (glversion == NULL) {
+ fprintf(stderr, "glversion == null\n");
+ return FALSE;
+ }
+ gl_VERSION = glversion;
+ tmpVersionStr = strdup(glversion);
+ gl_VENDOR = (char *)glGetString(GL_VENDOR);
+ if (gl_VENDOR == NULL) {
+ gl_VENDOR = "<unkown vendor>";
+ }
+
+ /* Get the extension */
+ extensionStr = (char *)glGetString(GL_EXTENSIONS);
+ if (extensionStr == NULL) {
+ fprintf(stderr, "extensionStr == null\n");
+ return FALSE;
+ }
+ tmpExtensionStr = strdup(extensionStr);
+
+ ctxInfo->versionStr = strdup(glversion);
+ ctxInfo->extensionStr = strdup(extensionStr);
+
+
+ /* find out the version, major and minor version number */
+ extractVersionInfo(tmpVersionStr, versionNumbers);
+
+ /* *********************************************************/
+ /* setup the graphics context properties */
+ if (versionNumbers[1] >= 2) { /* check 1.2 core and above */
+ /* 1.2 core */
+ ctxInfo->rescale_normal_ext = JNI_TRUE;
+ ctxInfo->rescale_normal_ext_enum = GL_RESCALE_NORMAL;
+ ctxInfo->bgr_ext = JNI_TRUE;
+ ctxInfo->bgr_ext_enum = GL_BGR;
+ ctxInfo->texture3DAvailable = JNI_TRUE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_3D;
+#if defined(SOLARIS) || defined(__linux__)
+ ctxInfo->glTexImage3DEXT = (MYPFNGLTEXIMAGE3DPROC )glTexImage3D;
+ ctxInfo->glTexSubImage3DEXT = (MYPFNGLTEXSUBIMAGE3DPROC )glTexSubImage3D;
+#endif
+#ifdef WIN32
+ ctxInfo->glTexImage3DEXT = (MYPFNGLTEXIMAGE3DPROC )wglGetProcAddress("glTexImage3D");
+ ctxInfo->glTexSubImage3DEXT = (MYPFNGLTEXSUBIMAGE3DPROC )wglGetProcAddress("glTexSubImage3D");
+ if ((ctxInfo->glTexImage3DEXT == NULL) || (ctxInfo->glTexSubImage3DEXT == NULL)) {
+ ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_3D;
+ ctxInfo->texture3DAvailable = JNI_FALSE;
+ }
+#endif
+ ctxInfo->texture_3D_ext_enum = GL_TEXTURE_3D;
+ ctxInfo->texture_wrap_r_ext_enum = GL_TEXTURE_WRAP_R;
+ ctxInfo->texture_clamp_to_edge_enum = GL_CLAMP_TO_EDGE;
+
+ if(isExtensionSupported(tmpExtensionStr, "GL_ARB_imaging")){
+ ctxInfo->blend_color_ext = JNI_TRUE;
+ ctxInfo->blendFunctionTable[7] = GL_CONSTANT_COLOR;
+#if defined(SOLARIS) || defined(__linux__)
+ ctxInfo->glBlendColor = (MYPFNGLBLENDCOLORPROC )glBlendColor;
+#endif
+#ifdef WIN32
+ ctxInfo->glBlendColor = (MYPFNGLBLENDCOLORPROC )wglGetProcAddress("glBlendColor");
+ if (ctxInfo->glBlendColor == NULL) {
+ ctxInfo->blend_color_ext = JNI_FALSE;
+ }
+#endif
+ }
+
+ ctxInfo->seperate_specular_color = JNI_TRUE;
+ ctxInfo->light_model_color_control_enum = GL_LIGHT_MODEL_COLOR_CONTROL;
+ ctxInfo->single_color_enum = GL_SINGLE_COLOR;
+ ctxInfo->seperate_specular_color_enum = GL_SEPARATE_SPECULAR_COLOR;
+
+ ctxInfo->textureLodAvailable = JNI_TRUE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_LOD_RANGE;
+ ctxInfo->texture_min_lod_enum = GL_TEXTURE_MIN_LOD;
+ ctxInfo->texture_max_lod_enum = GL_TEXTURE_MAX_LOD;
+ ctxInfo->texture_base_level_enum = GL_TEXTURE_BASE_LEVEL;
+ ctxInfo->texture_max_level_enum = GL_TEXTURE_MAX_LEVEL;
+
+ /* ... */
+
+ } else { /* check 1.1 extension */
+ if(isExtensionSupported(tmpExtensionStr,"GL_EXT_rescale_normal")){
+ ctxInfo->rescale_normal_ext = JNI_TRUE;
+ ctxInfo->rescale_normal_ext_enum = GL_RESCALE_NORMAL_EXT;
+ }
+ if(isExtensionSupported(tmpExtensionStr,"GL_BGR_EXT")) {
+ ctxInfo->bgr_ext = 1;
+ ctxInfo->bgr_ext_enum = GL_BGR_EXT;
+ }
+
+ if(isExtensionSupported(tmpExtensionStr,"GL_EXT_texture3D" )){
+ ctxInfo->texture3DAvailable = JNI_TRUE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_3D;
+ ctxInfo->texture_3D_ext_enum = GL_TEXTURE_3D_EXT;
+ ctxInfo->texture_wrap_r_ext_enum = GL_TEXTURE_WRAP_R_EXT;
+#if defined(SOLARIS) || defined(__linux__)
+ ctxInfo->glTexImage3DEXT = (MYPFNGLTEXIMAGE3DPROC )glTexImage3DEXT;
+ ctxInfo->glTexSubImage3DEXT = (MYPFNGLTEXSUBIMAGE3DPROC )glTexSubImage3DEXT;
+ /* Fallback to non-EXT variants, needed for older
+ NVIDIA drivers which announce GL_EXT_texture3D but
+ don't have the EXT variants */
+ if (ctxInfo->glTexImage3DEXT == NULL ||
+ ctxInfo->glTexSubImage3DEXT == NULL) {
+
+ ctxInfo->glTexImage3DEXT =
+ (MYPFNGLTEXIMAGE3DPROC) glTexImage3D;
+ ctxInfo->glTexSubImage3DEXT =
+ (MYPFNGLTEXSUBIMAGE3DPROC) glTexSubImage3D;
+
+ if (ctxInfo->glTexImage3DEXT == NULL ||
+ ctxInfo->glTexSubImage3DEXT == NULL) {
+
+ ctxInfo->textureExtMask &=
+ ~javax_media_j3d_Canvas3D_TEXTURE_3D;
+ ctxInfo->texture3DAvailable = JNI_FALSE;
+ }
+ }
+
+#endif
+#ifdef WIN32
+ ctxInfo->glTexImage3DEXT = (MYPFNGLTEXIMAGE3DPROC )wglGetProcAddress("glTexImage3DEXT");
+ ctxInfo->glTexSubImage3DEXT = (MYPFNGLTEXSUBIMAGE3DPROC )wglGetProcAddress("glTexSubImage3DEXT");
+ if ((ctxInfo->glTexImage3DEXT == NULL) || (ctxInfo->glTexSubImage3DEXT == NULL)) {
+ ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_3D;
+ ctxInfo->texture3DAvailable = JNI_FALSE;
+ }
+#endif
+ }
+
+
+ if(isExtensionSupported(tmpExtensionStr, "GL_EXT_texture_edge_clamp")) {
+ ctxInfo->texture_clamp_to_edge_enum = GL_CLAMP_TO_EDGE_EXT;
+ } else if(isExtensionSupported(tmpExtensionStr, "GL_SGIS_texture_edge_clamp")) {
+ ctxInfo->texture_clamp_to_edge_enum = GL_CLAMP_TO_EDGE_SGIS;
+ } else {
+ /* fallback to GL_CLAMP */
+ ctxInfo->texture_clamp_to_edge_enum = GL_CLAMP;
+ }
+
+
+ if(isExtensionSupported(tmpExtensionStr, "GL_EXT_blend_color")){
+ ctxInfo->blend_color_ext = JNI_TRUE;
+#if defined(SOLARIS) || defined(__linux__)
+ ctxInfo->glBlendColor = (MYPFNGLBLENDCOLOREXTPROC )glBlendColorEXT;
+#endif
+#ifdef WIN32
+ ctxInfo->glBlendColor = (MYPFNGLBLENDCOLOREXTPROC )wglGetProcAddress("glBlendColorEXT");
+ if (ctxInfo->glBlendColor == NULL) {
+ ctxInfo->blend_color_ext = JNI_FALSE;
+ }
+#endif
+ ctxInfo->blendFunctionTable[7] = GL_CONSTANT_COLOR_EXT;
+ }
+
+ if(isExtensionSupported(tmpExtensionStr,"GL_EXT_separate_specular_color" )){
+ ctxInfo->seperate_specular_color = JNI_TRUE;
+ ctxInfo->light_model_color_control_enum = GL_LIGHT_MODEL_COLOR_CONTROL_EXT;
+ ctxInfo->single_color_enum = GL_SINGLE_COLOR_EXT;
+ ctxInfo->seperate_specular_color_enum = GL_SEPARATE_SPECULAR_COLOR_EXT ;
+ }
+
+ if (isExtensionSupported(tmpExtensionStr,"GL_SGIS_texture_lod")) {
+ ctxInfo->textureLodAvailable = JNI_TRUE;
+ ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_LOD_RANGE;
+ ctxInfo->texture_min_lod_enum = GL_TEXTURE_MIN_LOD_SGIS;
+ ctxInfo->texture_max_lod_enum = GL_TEXTURE_MAX_LOD_SGIS;
+ ctxInfo->texture_base_level_enum = GL_TEXTURE_BASE_LEVEL_SGIS;
+ ctxInfo->texture_max_level_enum = GL_TEXTURE_MAX_LEVEL_SGIS;
+ }
+
+
+ /* ... */
+ }
+
+
+
+ /* check extensions for remaining of 1.1 and 1.2 */
+ if(isExtensionSupported(tmpExtensionStr, "GL_EXT_multi_draw_arrays")){
+ ctxInfo->multi_draw_arrays_ext = JNI_TRUE;
+ }
+ if(isExtensionSupported(tmpExtensionStr, "GL_SUN_multi_draw_arrays")){
+ ctxInfo->multi_draw_arrays_sun = JNI_TRUE;
+ }
+
+
+ if (isExtensionSupported(tmpExtensionStr, "GL_EXT_compiled_vertex_array") &&
+ getJavaBoolEnv(env, "isCompliedVertexArray")) {
+ ctxInfo->compiled_vertex_array_ext = JNI_TRUE;
+ }
+
+
+ if(isExtensionSupported(tmpExtensionStr, "GLX_SUN_video_resize")){
+ ctxInfo->videoResizeAvailable = JNI_TRUE;
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_SUN_VIDEO_RESIZE;
+ }
+
+ if(isExtensionSupported(tmpExtensionStr, "GL_SUN_global_alpha")){
+ ctxInfo->global_alpha_sun = JNI_TRUE;
+ }
+
+ if(isExtensionSupported(tmpExtensionStr, "GL_SUNX_constant_data")){
+ ctxInfo->constant_data_sun = JNI_TRUE;
+ }
+
+ if(isExtensionSupported(tmpExtensionStr, "GL_EXT_abgr")) {
+ ctxInfo->abgr_ext = JNI_TRUE;
+ }
+
+ if(isExtensionSupported(tmpExtensionStr, "GL_ARB_transpose_matrix")) {
+ ctxInfo->arb_transpose_matrix = JNI_TRUE;
+ }
+
+ if(isExtensionSupported(tmpExtensionStr, "GL_SUNX_geometry_compression")) {
+ ctxInfo->geometry_compression_sunx = JNI_TRUE ;
+ }
+
+#if defined(SOLARIS) || defined(__linux__)
+ /*
+ * setup ARB_multisample, under windows this is setup in
+ * NativeConfigTemplate when pixel format is choose
+ */
+ if (isExtensionSupported(tmpExtensionStr, "GL_ARB_multisample")){
+ ctxInfo->arb_multisample = JNI_TRUE;
+
+ }
+#endif
+
+#ifdef WIN32
+ wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)
+ wglGetProcAddress("wglGetPixelFormatAttribivARB");
+
+ if (wglGetPixelFormatAttribivEXT == NULL) {
+ wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)
+ wglGetProcAddress("wglGetPixelFormatAttribivEXT");
+ }
+
+ ctxInfo->arb_multisample = JNI_FALSE;
+ if (wglGetPixelFormatAttribivEXT != NULL) {
+ attr[0] = WGL_SAMPLE_BUFFERS_ARB;
+ attr[1] = WGL_SAMPLES_ARB;
+ attr[2] = 0;
+
+ if (wglGetPixelFormatAttribivEXT((HDC) hdc, pixelFormat, 0, 2, attr, piValues)) {
+ if ((piValues[0] == TRUE) && (piValues[1] > 1)) {
+ ctxInfo->arb_multisample = JNI_TRUE;
+ }
+ }
+ }
+#endif
+
+ /*
+ * Disable multisample by default since OpenGL will enable
+ * it by default if the surface is multisample capable.
+ */
+ if (ctxInfo->arb_multisample && !ctxInfo->implicit_multisample) {
+ glDisable(MULTISAMPLE_ARB);
+ }
+ /*
+ * checking of the texture extensions is done in checkTextureExtensions(),
+ * so that the same function can be used for queryContext as well
+ */
+ checkTextureExtensions(env, obj, tmpExtensionStr, versionNumbers[1],
+ ctxInfo);
+
+
+
+
+ /* ... */
+
+ /* *********************************************************/
+ /* Set up rescale_normal if extension supported */
+ if (ctxInfo->rescale_normal_ext ) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_RESCALE_NORMAL;
+ }
+
+ /* Setup the multi_draw_array */
+ if(ctxInfo->multi_draw_arrays_ext) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_MULTI_DRAW_ARRAYS;
+ } else if (ctxInfo->multi_draw_arrays_sun) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_SUN_MULTI_DRAW_ARRAYS;
+ }
+ if(ctxInfo->compiled_vertex_array_ext) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_COMPILED_VERTEX_ARRAYS;
+ }
+
+
+ /* Setup GL_SUN_gloabl_alpha */
+ if (ctxInfo->global_alpha_sun) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_SUN_GLOBAL_ALPHA;
+ }
+
+ /* Setup GL_SUNX_constant_data */
+ if (ctxInfo->constant_data_sun) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_SUN_CONSTANT_DATA;
+ }
+
+ /* Setup GL_EXT_abgr */
+ if (ctxInfo->abgr_ext) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_ABGR;
+ }
+
+ /* Setup GL_BGR_EXT */
+ if (ctxInfo->bgr_ext) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_BGR;
+ }
+
+ /* Setup GL_ARB_transpose_matrix */
+ if (ctxInfo->arb_transpose_matrix) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_ARB_TRANSPOSE_MATRIX;
+ }
+
+ /*
+ * Check for compressed geometry extensions and see if hardware
+ * acceleration is supported in the runtime environment.
+ */
+ if (ctxInfo->geometry_compression_sunx) {
+ cgHwStr = (char *)glGetString(GL_COMPRESSED_GEOM_ACCELERATED_SUNX) ;
+ }
+
+ if (cgHwStr == 0 || strstr(cgHwStr, " ")) {
+ ctxInfo->geometry_compression_accelerated = 0 ;
+
+ } else {
+ char *tmp = strdup(cgHwStr) ;
+
+ ctxInfo->geometry_compression_accelerated_major_version =
+ atoi(strtok(tmp, ".")) ;
+ ctxInfo->geometry_compression_accelerated_minor_version =
+ atoi(strtok(0, ".")) ;
+ ctxInfo->geometry_compression_accelerated_subminor_version =
+ atoi(strtok(0, ".")) ;
+
+ free(tmp) ;
+ ctxInfo->geometry_compression_accelerated = 1 ;
+ }
+
+
+ /* Setup GL_EXT_separate_specular_color */
+ if(ctxInfo->seperate_specular_color) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_SEPARATE_SPECULAR_COLOR;
+ }
+
+ if (ctxInfo->constant_data_sun) {
+ /* glPixelStorei(GL_UNPACK_CONSTANT_DATA_SUNX, GL_TRUE); */
+ }
+
+ if(ctxInfo->arb_multisample) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_ARB_MULTISAMPLE;
+ }
+
+ /* setup those functions pointers */
+#ifdef WIN32
+
+ if (ctxInfo->multi_draw_arrays_ext) {
+ ctxInfo->glMultiDrawArraysEXT = (MYPFNGLMULTIDRAWARRAYSEXTPROC)wglGetProcAddress("glMultiDrawArraysEXT");
+ ctxInfo->glMultiDrawElementsEXT = (MYPFNGLMULTIDRAWELEMENTSEXTPROC)wglGetProcAddress("glMultiDrawElementsEXT");
+ if ((ctxInfo->glMultiDrawArraysEXT == NULL) ||
+ (ctxInfo->glMultiDrawElementsEXT == NULL)) {
+ ctxInfo->multi_draw_arrays_ext = JNI_FALSE;
+ }
+ }
+ else if (ctxInfo->multi_draw_arrays_sun) {
+ ctxInfo->glMultiDrawArraysEXT = (MYPFNGLMULTIDRAWARRAYSEXTPROC)wglGetProcAddress("glMultiDrawArraysSUN");
+ ctxInfo->glMultiDrawElementsEXT = (MYPFNGLMULTIDRAWELEMENTSEXTPROC)wglGetProcAddress("glMultiDrawElementsSUN");
+ if ((ctxInfo->glMultiDrawArraysEXT == NULL) ||
+ (ctxInfo->glMultiDrawElementsEXT == NULL)) {
+ ctxInfo->multi_draw_arrays_sun = JNI_FALSE;
+ }
+
+ }
+ if (ctxInfo->compiled_vertex_array_ext) {
+ ctxInfo->glLockArraysEXT = (MYPFNGLLOCKARRAYSEXTPROC)wglGetProcAddress("glLockArraysEXT");
+ ctxInfo->glUnlockArraysEXT = (MYPFNGLUNLOCKARRAYSEXTPROC)wglGetProcAddress("glUnlockArraysEXT");
+ if ((ctxInfo->glLockArraysEXT == NULL) ||
+ (ctxInfo->glUnlockArraysEXT == NULL)) {
+ ctxInfo->compiled_vertex_array_ext = JNI_FALSE;
+ }
+ }
+
+ if (ctxInfo->arb_multitexture) {
+ ctxInfo->glClientActiveTextureARB = (MYPFNGLCLIENTACTIVETEXTUREARBPROC)wglGetProcAddress("glClientActiveTextureARB");
+ ctxInfo->glMultiTexCoord2fvARB = (MYPFNGLMULTITEXCOORD2FVARBPROC)wglGetProcAddress("glMultiTexCoord2fvARB");
+ ctxInfo->glMultiTexCoord3fvARB = (MYPFNGLMULTITEXCOORD3FVARBPROC)wglGetProcAddress("glMultiTexCoord3fvARB");
+ ctxInfo->glMultiTexCoord4fvARB = (MYPFNGLMULTITEXCOORD4FVARBPROC)wglGetProcAddress("glMultiTexCoord4fvARB");
+ ctxInfo->glActiveTextureARB = (MYPFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
+ /*
+ if (ctxInfo->glClientActiveTextureARB == NULL) {
+ printf("ctxInfo->glClientActiveTextureARB == NULL\n");
+ }
+ if (ctxInfo->glMultiTexCoord2fvARB == NULL) {
+ printf("ctxInfo->glMultiTexCoord2fvARB == NULL\n");
+ }
+ if (ctxInfo->glMultiTexCoord3fvARB == NULL) {
+ printf("ctxInfo->glMultiTexCoord3fvARB == NULL\n");
+ }
+ if (ctxInfo->glMultiTexCoord4fvARB == NULL) {
+ printf("ctxInfo->glMultiTexCoord4fvARB == NULL\n");
+ }
+ if (ctxInfo->glActiveTextureARB == NULL) {
+ printf("ctxInfo->glActiveTextureARB == NULL\n");
+ }
+ */
+ if ((ctxInfo->glClientActiveTextureARB == NULL) ||
+ (ctxInfo->glMultiTexCoord2fvARB == NULL) ||
+ (ctxInfo->glMultiTexCoord3fvARB == NULL) ||
+ (ctxInfo->glMultiTexCoord4fvARB == NULL) ||
+ (ctxInfo->glActiveTextureARB == NULL)) {
+ ctxInfo->arb_multitexture = JNI_FALSE;
+ }
+ }
+
+ if(ctxInfo->arb_transpose_matrix) {
+ ctxInfo->glLoadTransposeMatrixdARB = (MYPFNGLLOADTRANSPOSEMATRIXDARBPROC)wglGetProcAddress("glLoadTransposeMatrixdARB");
+ ctxInfo->glMultTransposeMatrixdARB = (MYPFNGLMULTTRANSPOSEMATRIXDARBPROC)wglGetProcAddress("glMultTransposeMatrixdARB");
+ /*
+ if (ctxInfo->glLoadTransposeMatrixdARB == NULL) {
+ printf("ctxInfo->glLoadTransposeMatrixdARB == NULL\n");
+ }
+ if (ctxInfo->glMultTransposeMatrixdARB == NULL) {
+ printf("ctxInfo->glMultTransposeMatrixdARB == NULL\n");
+ }
+ */
+ if ((ctxInfo->glLoadTransposeMatrixdARB == NULL) ||
+ (ctxInfo->glMultTransposeMatrixdARB == NULL)) {
+ ctxInfo->arb_transpose_matrix = JNI_FALSE;
+ }
+ }
+
+ if (ctxInfo->global_alpha_sun) {
+ ctxInfo->glGlobalAlphaFactorfSUN = (MYPFNGLGLOBALALPHAFACTORFSUNPROC )wglGetProcAddress("glGlobalAlphaFactorfSUN");
+
+ if (ctxInfo->glGlobalAlphaFactorfSUN == NULL) {
+ /* printf("ctxInfo->glGlobalAlphaFactorfSUN == NULL\n");*/
+ ctxInfo->global_alpha_sun = JNI_FALSE;
+ }
+ }
+
+
+ DescribePixelFormat((HDC) hdc, pixelFormat, sizeof(pfd), &pfd);
+
+ stencilSize = pfd.cStencilBits;
+#endif
+
+#if defined(SOLARIS) || defined(__linux__)
+ if(ctxInfo->multi_draw_arrays_ext) {
+ ctxInfo->glMultiDrawArraysEXT = glMultiDrawArraysEXT;
+ ctxInfo->glMultiDrawElementsEXT = glMultiDrawElementsEXT;
+ }
+ else if (ctxInfo->multi_draw_arrays_sun) {
+ ctxInfo->glMultiDrawArraysEXT = glMultiDrawArraysSUN;
+ ctxInfo->glMultiDrawElementsEXT = glMultiDrawElementsSUN;
+ }
+ if(ctxInfo->compiled_vertex_array_ext) {
+ ctxInfo->glLockArraysEXT = glLockArraysEXT;
+ ctxInfo->glUnlockArraysEXT = glUnlockArraysEXT;
+ }
+
+ if(ctxInfo->arb_multitexture){
+ ctxInfo->glClientActiveTextureARB = glClientActiveTextureARB;
+ ctxInfo->glMultiTexCoord2fvARB = glMultiTexCoord2fvARB;
+ ctxInfo->glMultiTexCoord3fvARB = glMultiTexCoord3fvARB;
+ ctxInfo->glMultiTexCoord4fvARB = glMultiTexCoord4fvARB;
+ ctxInfo->glActiveTextureARB = glActiveTextureARB;
+ }
+ if(ctxInfo->arb_transpose_matrix) {
+ ctxInfo->glLoadTransposeMatrixdARB = glLoadTransposeMatrixdARB;
+ ctxInfo->glMultTransposeMatrixdARB = glMultTransposeMatrixdARB;
+ }
+ if(ctxInfo->global_alpha_sun)
+ ctxInfo->glGlobalAlphaFactorfSUN = glGlobalAlphaFactorfSUN;
+
+
+ glXGetConfig((Display *) display, (XVisualInfo *) vinfo, GLX_STENCIL_SIZE, &stencilSize);
+
+#endif
+
+ if (stencilSize > 1) {
+ ctxInfo->extMask |= javax_media_j3d_Canvas3D_STENCIL_BUFFER;
+ }
+
+
+ /* ... */
+
+ /* clearing up the memory */
+ free(tmpExtensionStr);
+ free(tmpVersionStr);
+ return TRUE;
+}
+
+
+/*
+ * put properties to the java side
+ */
+void setupCanvasProperties(
+ JNIEnv *env,
+ jobject obj,
+ GraphicsContextPropertiesInfo *ctxInfo)
+{
+ jclass cv_class;
+ jfieldID rsc_field;
+ JNIEnv table = *env;
+ GLint param;
+
+ cv_class = (jclass) (*(table->GetObjectClass))(env, obj);
+
+ /* set the canvas.multiTexAccelerated flag */
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "multiTexAccelerated", "Z");
+ (*(table->SetBooleanField))(env, obj, rsc_field, ctxInfo->arb_multitexture);
+
+ if (ctxInfo->arb_multitexture) {
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "numTexUnitSupported", "I");
+ (*(table->SetIntField))(env, obj, rsc_field, ctxInfo->textureUnitCount);
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "numTexCoordSupported", "I");
+ (*(table->SetIntField))(env, obj, rsc_field, ctxInfo->textureUnitCount);
+ }
+
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "extensionsSupported", "I");
+ (*(table->SetIntField))(env, obj, rsc_field, ctxInfo->extMask);
+
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "textureExtendedFeatures", "I");
+ (*(table->SetIntField))(env, obj, rsc_field, ctxInfo->textureExtMask);
+
+ /* get texture color table size */
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "textureColorTableSize", "I");
+ (*(table->SetIntField))(env, obj, rsc_field, ctxInfo->textureColorTableSize);
+
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "nativeGraphicsVersion", "Ljava/lang/String;");
+ (*(table->SetObjectField))(env, obj, rsc_field, (*env)->NewStringUTF(env, ctxInfo->versionStr));
+
+ if (ctxInfo->textureAnisotropicFilterAvailable) {
+
+ float degree;
+
+ glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &degree);
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "anisotropicDegreeMax", "F");
+ (*(table->SetFloatField))(env, obj, rsc_field, degree);
+ }
+
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "textureBoundaryWidthMax", "I");
+ (*(table->SetIntField))(env, obj, rsc_field, 1);
+
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &param);
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "textureWidthMax", "I");
+ (*(table->SetIntField))(env, obj, rsc_field, param);
+
+ rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "textureHeightMax", "I");
+ (*(table->SetIntField))(env, obj, rsc_field, param);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_destroyContext(
+ JNIEnv *env,
+ jclass cl,
+ jlong display,
+ jint window,
+ jlong ctxInfo)
+{
+ GraphicsContextPropertiesInfo* s = (GraphicsContextPropertiesInfo* )ctxInfo;
+ jlong context = s->context;
+
+#ifdef WIN32
+ /*
+ * It is possible the window is removed by removeNotify()
+ * before the following is invoked :
+ * wglMakeCurrent((HDC)window, NULL);
+ * This will cause WinMe crash on swapBuffers()
+ */
+ wglDeleteContext((HGLRC)context);
+#endif /* WIN32 */
+
+#if defined(SOLARIS) || defined(__linux__)
+ /*
+ glXMakeCurrent((Display *)display, (GLXDrawable)window, NULL);
+ */
+ glXDestroyContext((Display *)display, (GLXContext)context);
+#endif /* SOLARIS */
+ /* cleanup CtxInfo and free its memory */
+ cleanupCtxInfo(s);
+
+ free(s);
+
+
+}
+
+/*
+ * A dummy WndProc for dummy window
+ */
+#ifdef WIN32
+LONG WINAPI WndProc( HWND hWnd, UINT msg,
+ WPARAM wParam, LPARAM lParam )
+{
+
+ /* This function handles any messages that we didn't. */
+ /* (Which is most messages) It belongs to the OS. */
+ return DefWindowProc( hWnd, msg, wParam, lParam );
+}
+#endif /*end of WIN32 */
+
+
+
+
+JNIEXPORT
+jlong JNICALL Java_javax_media_j3d_Canvas3D_createContext(
+ JNIEnv *env,
+ jobject obj,
+ jlong display,
+ jint window,
+ jint vid,
+ jlong visInfo,
+ jlong sharedCtxInfo,
+ jboolean isSharedCtx,
+ jboolean offScreen)
+{
+ jlong gctx;
+ jlong sharedCtx;
+
+ static GLboolean first_time = GL_TRUE;
+ static GLboolean force_normalize = GL_FALSE;
+
+ GraphicsContextPropertiesInfo *ctxInfo = NULL;
+ GraphicsContextPropertiesInfo *sharedCtxStructure;
+ int PixelFormatID=0;
+
+#if defined(SOLARIS) || defined(__linux__)
+ GLXContext ctx;
+ jlong hdc;
+
+ if(sharedCtxInfo == 0)
+ sharedCtx = 0;
+ else {
+ sharedCtxStructure = (GraphicsContextPropertiesInfo *)sharedCtxInfo;
+ sharedCtx = sharedCtxStructure->context;
+ }
+
+ if (display == 0) {
+ fprintf(stderr, "Canvas3D_createContext: display is null\n");
+ ctx = NULL;
+ }
+ else if (visInfo == 0) {
+ /*
+ * visInfo must be a valid pointer to an XVisualInfo struct returned
+ * by glXChooseVisual() for a physical screen. The visual id in vid
+ * is not sufficient for handling OpenGL with Xinerama mode disabled:
+ * it doesn't distinguish between the physical screens making up the
+ * virtual screen when the X server is running in Xinerama mode.
+ */
+ fprintf(stderr, "Canvas3D_createContext: visual is null\n");
+ ctx = NULL;
+ }
+ else {
+ ctx = glXCreateContext((Display *)display, (XVisualInfo *)visInfo,
+ (GLXContext)sharedCtx, True);
+ }
+
+
+ if (ctx == NULL) {
+ fprintf(stderr, "Canvas3D_createContext: couldn't create context\n");
+ return 0;
+ }
+
+ if (!glXMakeCurrent((Display *)display, (GLXDrawable)window,
+ (GLXContext)ctx)) {
+ fprintf( stderr, "Canvas3D_createContext: couldn't make current\n");
+ return 0;
+ }
+
+ gctx = (jlong)ctx;
+#endif /* SOLARIS */
+
+#ifdef WIN32
+ HGLRC hrc; /* HW Rendering Context */
+ HDC hdc; /* HW Device Context */
+ jboolean rescale = JNI_FALSE;
+ JNIEnv table = *env;
+ DWORD err;
+ LPTSTR errString;
+
+
+ static PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR),
+ 1, /* Version number */
+ PFD_DRAW_TO_WINDOW |
+ PFD_SUPPORT_OPENGL|
+ PFD_DOUBLEBUFFER,
+ PFD_TYPE_RGBA,
+ 24, /* 24 bit color depth */
+ 0, 0, 0, /* RGB bits and pixel sizes */
+ 0, 0, 0, /* Do not care about them */
+ 0, 0, /* no alpha buffer info */
+ 0, 0, 0, 0, 0, /* no accumulation buffer */
+ 32, /* 16 bit depth buffer */
+ 0, /* no stencil buffer */
+ 0, /* no auxiliary buffers */
+ PFD_MAIN_PLANE, /* layer type */
+ 0, /* reserved, must be 0 */
+ 0, /* no layer mask */
+ 0, /* no visible mask */
+ 0 /* no damage mask */
+ };
+
+ jboolean result;
+
+ /* hWnd = (HWND) window; */
+ /* or could use: hDC = GetDC(hWnd); */
+
+ if(sharedCtxInfo == 0)
+ sharedCtx = 0;
+ else {
+ sharedCtxStructure = (GraphicsContextPropertiesInfo *)sharedCtxInfo;
+ sharedCtx = sharedCtxStructure->context;
+ }
+
+
+ hdc = (HDC) window;
+
+ if (offScreen) {
+ pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL |
+ PFD_SUPPORT_GDI;
+ vid = -1;
+ sharedCtx = 0;
+ }
+
+ /* vid of -1 means no vid was specified - do the old way */
+ if (vid == -1) {
+ /* choose the "pixel format", terminology is equivalent */
+ /* to UNIX "visual" */
+ PixelFormatID = ChoosePixelFormat(hdc, &pfd);
+
+ if(PixelFormatID == 0) {
+ fprintf(stderr,"\nERROR: pixel format ID = 0");
+ return 0;
+ }
+ }
+ else {
+ PixelFormatID = vid;
+ }
+
+
+ SetPixelFormat(hdc, PixelFormatID, &pfd);
+
+ hrc = wglCreateContext( hdc );
+
+ if (!hrc) {
+ err = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, 0, (LPTSTR)&errString, 0, NULL);
+
+ fprintf(stderr, "wglCreateContext Failed: %s\n", errString);
+ return 0;
+ }
+
+ if (sharedCtx != 0) {
+ wglShareLists( (HGLRC) sharedCtx, hrc );
+ }
+
+ result = wglMakeCurrent(hdc, hrc);
+
+ if (!result) {
+ err = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, 0, (LPTSTR)&errString, 0, NULL);
+ fprintf(stderr, "wglMakeCurrent Failed: %s\n", errString);
+ return 0;
+ }
+
+ gctx = (jlong)hrc;
+#endif /* WIN32 */
+
+ /* allocate the structure */
+ ctxInfo = (GraphicsContextPropertiesInfo *)malloc(sizeof(GraphicsContextPropertiesInfo));
+
+ /* initialize the structure */
+ initializeCtxInfo(env, ctxInfo);
+ ctxInfo->context = gctx;
+
+ if (!getPropertiesFromCurrentContext(env, obj, ctxInfo, (jlong) hdc, PixelFormatID, display, (jlong) visInfo)) {
+ return 0;
+ }
+
+
+ /* setup structure */
+
+ if(!isSharedCtx){
+ /* Setup field in Java side */
+ setupCanvasProperties(env, obj, ctxInfo);
+ }
+
+ /* Set up rescale_normal if extension supported */
+ if (first_time && getJavaBoolEnv(env, "isForceNormalized")) {
+ force_normalize = GL_TRUE;
+ first_time = GL_FALSE;
+ }
+
+ if (force_normalize) {
+ /* Disable rescale normal */
+ ctxInfo->rescale_normal_ext = GL_FALSE;
+ }
+
+ if (ctxInfo->rescale_normal_ext ) {
+ glEnable(ctxInfo->rescale_normal_ext_enum);
+ }
+ else {
+ glEnable(GL_NORMALIZE);
+ }
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_COLOR_MATERIAL);
+ glReadBuffer(GL_FRONT);
+ return ((jlong)ctxInfo);
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_useCtx(
+ JNIEnv *env,
+ jclass cl,
+ jlong ctxInfo,
+ jlong display,
+ jint window)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+#if defined(SOLARIS) || defined(__linux__)
+ glXMakeCurrent((Display *)display, (GLXDrawable)window, (GLXContext)ctx);
+#endif
+
+#ifdef WIN32
+ wglMakeCurrent((HDC) window, (HGLRC) ctx);
+#endif
+}
+
+JNIEXPORT
+jint JNICALL Java_javax_media_j3d_Canvas3D_getNumCtxLights(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo)
+{
+ GLint nlights;
+
+ glGetIntegerv(GL_MAX_LIGHTS, &nlights);
+ return((jint)nlights);
+}
+
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_composite(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint px,
+ jint py,
+ jint minX,
+ jint minY,
+ jint maxX,
+ jint maxY,
+ jint rasWidth,
+ jbyteArray imageYdown,
+ jint winWidth,
+ jint winHeight)
+{
+ GLenum gltype;
+ JNIEnv table;
+ jbyte *byteData;
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+ GLboolean tex3d, texCubeMap;
+
+ table = *env;
+
+#ifdef VERBOSE
+ fprintf(stderr, "Canvas3D.composite()\n");
+#endif
+ /* temporarily disable fragment operations */
+ /* TODO: the GL_TEXTURE_BIT may not be necessary */
+ glPushAttrib(GL_ENABLE_BIT|GL_TEXTURE_BIT|GL_DEPTH_BUFFER_BIT);
+
+ if(ctxProperties->texture3DAvailable)
+ tex3d = glIsEnabled(ctxProperties->texture_3D_ext_enum);
+
+ if(ctxProperties->textureCubeMapAvailable)
+ texCubeMap = glIsEnabled(ctxProperties->texture_cube_map_ext_enum);
+
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_FOG);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_TEXTURE_2D);
+ if(ctxProperties->texture3DAvailable)
+ glDisable(ctxProperties->texture_3D_ext_enum);
+ if(ctxProperties->textureCubeMapAvailable)
+ glDisable(ctxProperties->texture_cube_map_ext_enum);
+
+ glEnable(GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* loaded identity modelview and projection matrix */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0, (double)winWidth, 0.0, (double)winHeight, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ /* start from upper left corner */
+ glRasterPos2i(px + minX, winHeight-(py + minY));
+
+ glPixelZoom(1.0, -1.0);
+
+ byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env,
+ imageYdown,
+ NULL);
+ /* if abgr_ext is supported then the data will be in that format */
+ if (ctxProperties->abgr_ext) {
+ gltype = GL_ABGR_EXT;
+ } else {
+ gltype = GL_RGBA;
+ }
+
+ /*
+ * set the actual width of data which is the width of the canvas
+ * because what needs to be drawn may be smaller than the canvas
+ */
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, rasWidth);
+
+ /*
+ * we only need to skip pixels if width of the area to draw is smaller
+ * than the width of the raster
+ */
+
+ /*
+ * skip this many rows in the data because the size of what
+ * needs to be drawn may be smaller than the canvas
+ */
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, minY);
+ /*
+ * skip this many pixels in the data before drawing because
+ * the size of what needs to be drawn may be smaller than the
+ * canvas
+ */
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, minX);
+
+
+ glDrawPixels(maxX - minX, maxY - minY,
+ gltype, GL_UNSIGNED_BYTE, byteData);
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+
+ glMatrixMode(GL_PROJECTION);
+
+ glLoadIdentity();
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, imageYdown, byteData, 0);
+
+ /* re-enable fragment operation if necessary */
+ if(ctxProperties->texture3DAvailable)
+ if (tex3d) glEnable(ctxProperties->texture_3D_ext_enum);
+
+ if(ctxProperties->textureCubeMapAvailable)
+ if (texCubeMap) glEnable(ctxProperties->texture_cube_map_ext_enum);
+
+ /* Java 3D always clears the Z-buffer */
+ glDepthMask(GL_TRUE);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glPopAttrib();
+}
+
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_Canvas3D_initTexturemapping(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint texWidth,
+ jint texHeight,
+ jint objectId)
+{
+ GraphicsContextPropertiesInfo *ctxProperties =
+ (GraphicsContextPropertiesInfo *)ctxInfo;
+ GLint gltype;
+ GLint width;
+
+ gltype = (ctxProperties->abgr_ext ? GL_ABGR_EXT : GL_RGBA);
+
+ glBindTexture(GL_TEXTURE_2D, objectId);
+
+
+ glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, texWidth,
+ texHeight, 0, gltype, GL_UNSIGNED_BYTE, NULL);
+
+ glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0,
+ GL_TEXTURE_WIDTH, &width);
+
+ if (width <= 0) {
+ return JNI_FALSE;
+ }
+
+ /* init texture size only without filling the pixels */
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth,
+ texHeight, 0, gltype, GL_UNSIGNED_BYTE, NULL);
+
+
+ return JNI_TRUE;
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_texturemapping(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint px,
+ jint py,
+ jint minX,
+ jint minY,
+ jint maxX,
+ jint maxY,
+ jint texWidth,
+ jint texHeight,
+ jint rasWidth,
+ jint format,
+ jint objectId,
+ jbyteArray imageYdown,
+ jint winWidth,
+ jint winHeight)
+{
+ JNIEnv table;
+ GLint gltype;
+ GLfloat texMinU,texMinV,texMaxU,texMaxV;
+ GLfloat mapMinX,mapMinY,mapMaxX,mapMaxY;
+ GLfloat halfWidth,halfHeight;
+ jbyte *byteData;
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+ GLboolean tex3d, texCubeMap;
+
+ table = *env;
+ gltype = GL_RGBA;
+
+ /* temporary disable fragment operation */
+ glPushAttrib(GL_ENABLE_BIT|GL_TEXTURE_BIT|GL_DEPTH_BUFFER_BIT);
+
+ if (ctxProperties->texture3DAvailable) {
+ tex3d = glIsEnabled(ctxProperties->texture_3D_ext_enum);
+ }
+
+ if (ctxProperties->textureCubeMapAvailable) {
+ texCubeMap = glIsEnabled(ctxProperties->texture_cube_map_ext_enum);
+ }
+ glDisable(GL_ALPHA_TEST);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_FOG);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_TEXTURE_2D);
+ if (ctxProperties->texture3DAvailable) {
+ glDisable(ctxProperties->texture_3D_ext_enum);
+ }
+ if (ctxProperties->textureCubeMapAvailable) {
+ glDisable(ctxProperties->texture_cube_map_ext_enum);
+ }
+ /* glGetIntegerv(GL_TEXTURE_BINDING_2D,&binding); */
+ glDepthMask(GL_FALSE);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glBindTexture(GL_TEXTURE_2D, objectId);
+ /* set up texture parameter */
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+#ifdef VERBOSE
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+#endif
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnable(GL_TEXTURE_2D);
+
+ /* glGetIntegerv (GL_VIEWPORT, viewport); */
+
+ /* loaded identity modelview and projection matrix */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glOrtho(0.0, (double)winWidth, 0.0, (double)winHeight,0.0, 0.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env,
+ imageYdown,
+ NULL);
+
+ if (ctxProperties->abgr_ext) {
+ gltype = GL_ABGR_EXT;
+ } else {
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ gltype = GL_RGBA;
+ break;
+ case FORMAT_BYTE_RGB:
+ gltype = GL_RGB;
+ break;
+ }
+ }
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, rasWidth);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, minX);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, minY);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, minX, minY,
+ maxX - minX, maxY - minY,
+ gltype, GL_UNSIGNED_BYTE,
+ byteData);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, imageYdown, byteData, 0);
+
+ texMinU = (float) minX/ (float) texWidth;
+ texMinV = (float) minY/ (float) texHeight;
+ texMaxU = (float) maxX/ (float) texWidth;
+ texMaxV = (float) maxY/ (float) texHeight;
+ halfWidth = (GLfloat)winWidth/2.0f;
+ halfHeight = (GLfloat)winHeight/2.0f;
+
+ mapMinX = (float) (((px + minX)- halfWidth)/halfWidth);
+ mapMinY = (float) ((halfHeight - (py + maxY))/halfHeight);
+ mapMaxX = (float) ((px + maxX - halfWidth)/halfWidth);
+ mapMaxY = (float) ((halfHeight - (py + minY))/halfHeight);
+
+#ifdef VERBOSE
+ printf("(texMinU,texMinV,texMaxU,texMaxV) = (%3.2f,%3.2f,%3.2f,%3.2f)\n",
+ texMinU,texMinV,texMaxU,texMaxV);
+ printf("(mapMinX,mapMinY,mapMaxX,mapMaxY) = (%3.2f,%3.2f,%3.2f,%3.2f)\n",
+ mapMinX,mapMinY,mapMaxX,mapMaxY);
+
+#endif
+ glBegin(GL_QUADS);
+
+ glTexCoord2f(texMinU, texMaxV); glVertex2f(mapMinX,mapMinY);
+ glTexCoord2f(texMaxU, texMaxV); glVertex2f(mapMaxX,mapMinY);
+ glTexCoord2f(texMaxU, texMinV); glVertex2f(mapMaxX,mapMaxY);
+ glTexCoord2f(texMinU, texMinV); glVertex2f(mapMinX,mapMaxY);
+ glEnd();
+
+ /* re-enable fragment operation if necessary */
+ if (ctxProperties->texture3DAvailable)
+ if (tex3d) glEnable(ctxProperties->texture_3D_ext_enum);
+
+ if (ctxProperties->textureCubeMapAvailable)
+ if (texCubeMap) glEnable(ctxProperties->texture_cube_map_ext_enum);
+
+
+ /* Java 3D always clears the Z-buffer */
+ glDepthMask(GL_TRUE);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ glPopAttrib();
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_clear(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jfloat r,
+ jfloat g,
+ jfloat b,
+ jint winWidth,
+ jint winHeight,
+ jobject pa2d,
+ jint imageScaleMode,
+ jbyteArray pixels_obj)
+
+{
+ jclass pa2d_class;
+ jfieldID format_field, width_field, height_field;
+ int format, width, height;
+ GLubyte * pixels;
+ JNIEnv table;
+ GLenum gltype;
+ float xzoom, yzoom, zoom;
+ float rasterX, rasterY;
+ int repeatX, repeatY, i, j;
+ int row_length, skip_pixels, skip_rows, subwidth, subheight;
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+ table = *env;
+
+#ifdef VERBOSE
+ fprintf(stderr, "Canvas3D.clear()\n");
+#endif
+
+ if(!pa2d) {
+ glClearColor((float)r, (float)g, (float)b, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ else {
+ GLboolean tex3d, texCubeMap;
+
+ /* Do a cool image blit */
+ pa2d_class = (jclass) (*(table->GetObjectClass))(env, pa2d);
+ format_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class,
+ "storedYdownFormat", "I");
+ width_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class,
+ "width", "I");
+ height_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class,
+ "height", "I");
+
+ format = (int) (*(table->GetIntField))(env, pa2d, format_field);
+ width = (int) (*(table->GetIntField))(env, pa2d, width_field);
+ height = (int) (*(table->GetIntField))(env, pa2d, height_field);
+
+ pixels = (GLubyte *) (*(table->GetPrimitiveArrayCritical))(env,
+ pixels_obj, NULL);
+
+ /* temporarily disable fragment operations */
+ /* TODO: the GL_TEXTURE_BIT may not be necessary */
+ glPushAttrib(GL_ENABLE_BIT|GL_TEXTURE_BIT);
+
+ if(ctxProperties->texture3DAvailable)
+ tex3d = glIsEnabled(ctxProperties->texture_3D_ext_enum);
+
+ if(ctxProperties->textureCubeMapAvailable)
+ texCubeMap = glIsEnabled(ctxProperties->texture_cube_map_ext_enum);
+
+ glDisable(GL_ALPHA_TEST);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_FOG);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_TEXTURE_2D);
+ if(ctxProperties->texture3DAvailable)
+ glDisable(ctxProperties->texture_3D_ext_enum);
+
+ if(ctxProperties->textureCubeMapAvailable)
+ glDisable(ctxProperties->texture_cube_map_ext_enum);
+
+ /* loaded identity modelview and projection matrix */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ gltype = GL_RGBA;
+ break;
+ case FORMAT_BYTE_RGB:
+ gltype = GL_RGB;
+ break;
+
+ case FORMAT_BYTE_ABGR:
+ if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */
+ gltype = GL_ABGR_EXT;
+ }
+ break;
+
+ case FORMAT_BYTE_BGR:
+ if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */
+ gltype = ctxProperties->bgr_ext_enum ;
+ }
+ break;
+
+ case FORMAT_BYTE_LA:
+ gltype = GL_LUMINANCE_ALPHA;
+ break;
+ case FORMAT_BYTE_GRAY:
+ case FORMAT_USHORT_GRAY:
+ /* TODO: throw exception */
+ break;
+ }
+
+ /* start from upper left corner */
+ glRasterPos3f(-1.0, 1.0, 0.0);
+
+ /* setup the pixel zoom */
+ xzoom = (float)winWidth/width;
+ yzoom = (float)winHeight/height;
+ switch(imageScaleMode){
+ case javax_media_j3d_Background_SCALE_NONE:
+ if(xzoom > 1.0f || yzoom > 1.0f)
+ {
+ /* else don't need to clear the background with background color */
+ glClearColor((float)r, (float)g, (float)b, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ glPixelZoom(1.0, -1.0);
+ glDrawPixels(width, height, gltype, GL_UNSIGNED_BYTE,
+ pixels);
+
+ break;
+ case javax_media_j3d_Background_SCALE_FIT_MIN:
+ if(xzoom != yzoom ) {
+ glClearColor((float)r, (float)g, (float)b, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ zoom = xzoom < yzoom? xzoom:yzoom;
+ glPixelZoom(zoom, -zoom);
+ glDrawPixels(width, height, gltype, GL_UNSIGNED_BYTE,
+ pixels);
+
+ break;
+ case javax_media_j3d_Background_SCALE_FIT_MAX:
+ zoom = xzoom > yzoom? xzoom:yzoom;
+ glPixelZoom(zoom, -zoom);
+ glDrawPixels(width, height, gltype, GL_UNSIGNED_BYTE,
+ pixels);
+
+ break;
+ case javax_media_j3d_Background_SCALE_FIT_ALL:
+ glPixelZoom(xzoom, -yzoom);
+ glDrawPixels(width, height, gltype, GL_UNSIGNED_BYTE,
+ pixels);
+ break;
+ case javax_media_j3d_Background_SCALE_REPEAT:
+ glPixelZoom(1.0, -1.0);
+ /* get those raster positions */
+ repeatX = winWidth/width;
+ if(repeatX * width < winWidth)
+ repeatX++;
+ repeatY = winHeight/height;
+ if(repeatY * height < winHeight)
+ repeatY++;
+ for(i = 0; i < repeatX; i++)
+ for(j = 0; j < repeatY; j++) {
+ rasterX = -1.0f + (float)width/winWidth * i * 2;
+ rasterY = 1.0f - (float)height/winHeight * j * 2;
+ glRasterPos3f(rasterX, rasterY, 0.0);
+ glDrawPixels(width, height, gltype, GL_UNSIGNED_BYTE,
+ pixels);
+ }
+ break;
+
+ case javax_media_j3d_Background_SCALE_NONE_CENTER:
+ if(xzoom > 1.0f || yzoom > 1.0f){
+ glClearColor((float)r, (float)g, (float)b, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ if(xzoom >= 1.0f){
+ rasterX = -(float)width/winWidth;
+ subwidth = width;
+ }
+ else {
+ rasterX = -1.0;
+ row_length = width;
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+ skip_pixels = (width-winWidth)/2;
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
+ subwidth = winWidth;
+ }
+ if(yzoom >= 1.0f){
+ rasterY = (float)height/winHeight;
+ subheight = height;
+ }
+ else {
+ rasterY = 1.0f;
+ skip_rows = (height-winHeight)/2;
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
+ subheight = winHeight;
+ }
+ glRasterPos3f(rasterX, rasterY, 0.0);
+ glPixelZoom(1.0, -1.0);
+ glDrawPixels(subwidth, subheight, gltype, GL_UNSIGNED_BYTE,
+ pixels);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ break;
+ }
+ /* re-enable fragment operation if necessary */
+ glPopAttrib();
+
+ if(ctxProperties->texture3DAvailable)
+ if (tex3d) glEnable(ctxProperties->texture_3D_ext_enum);
+
+ if(ctxProperties->textureCubeMapAvailable)
+ if (texCubeMap) glEnable(ctxProperties->texture_cube_map_ext_enum);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, pixels_obj,
+ (jbyte *)pixels, 0);
+ }
+ /* Java 3D always clears the Z-buffer */
+ glPushAttrib(GL_DEPTH_BUFFER_BIT);
+ glDepthMask(GL_TRUE);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ glPopAttrib();
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_textureclear(JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint maxX,
+ jint maxY,
+ jfloat r,
+ jfloat g,
+ jfloat b,
+ jint winWidth,
+ jint winHeight,
+ jint objectId,
+ jint imageScaleMode,
+ jobject pa2d,
+ jboolean update)
+{
+ jclass pa2d_class;
+ jfieldID pixels_field, format_field, width_field, height_field;
+ jbyteArray pixels_obj;
+ int format, width, height;
+ GLubyte * pixels;
+ JNIEnv table;
+ GLenum gltype;
+ GLfloat texMinU, texMinV, texMaxU, texMaxV, adjustV;
+ GLfloat mapMinX, mapMinY, mapMaxX, mapMaxY;
+ GLfloat halfWidth, halfHeight;
+ float xzoom, yzoom, zoom;
+ int i, j;
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ table = *env;
+
+ /* update = 1; */
+
+#ifdef VERBOSE
+ fprintf(stderr, "Canvas3D.textureclear()\n");
+#endif
+ if(!pa2d){
+ glClearColor((float)r, (float)g, (float)b, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ /* glPushAttrib(GL_DEPTH_BUFFER_BIT); */
+ if (pa2d) {
+ GLboolean tex3d, texCubeMap;
+
+
+ /* Do a cool image blit */
+ pa2d_class = (jclass) (*(table->GetObjectClass))(env, pa2d);
+
+ pixels_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class,
+ "imageYup", "[B");
+ format_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class,
+ "storedYupFormat", "I");
+ pixels_obj = (jbyteArray)(*(table->GetObjectField))(env, pa2d,
+ pixels_field);
+
+ width_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class,
+ "width", "I");
+ height_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class,
+ "height", "I");
+
+ format = (int) (*(table->GetIntField))(env, pa2d, format_field);
+ width = (int) (*(table->GetIntField))(env, pa2d, width_field);
+ height = (int) (*(table->GetIntField))(env, pa2d, height_field);
+ pixels = (GLubyte *) (*(table->GetPrimitiveArrayCritical))(env,
+ pixels_obj, NULL);
+
+#ifdef VERBOSE
+ fprintf(stderr, "width = %d height = %d \n", width, height);
+#endif
+
+ /* temporary disable fragment operation */
+ glPushAttrib(GL_ENABLE_BIT|GL_TEXTURE_BIT|GL_POLYGON_BIT);
+
+ if(ctxProperties->texture3DAvailable)
+ tex3d = glIsEnabled(ctxProperties->texture_3D_ext_enum);
+ if(ctxProperties->textureCubeMapAvailable)
+ texCubeMap = glIsEnabled(ctxProperties->texture_cube_map_ext_enum);
+ glDisable(GL_ALPHA_TEST);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_FOG);
+ glDisable(GL_LIGHTING);
+
+ if(ctxProperties->texture3DAvailable)
+ glDisable(ctxProperties->texture_3D_ext_enum);
+
+ if(ctxProperties->textureCubeMapAvailable)
+ glDisable(ctxProperties->texture_cube_map_ext_enum);
+
+ Java_javax_media_j3d_Canvas3D_resetTexCoordGeneration(env, obj, ctxInfo);
+
+ glEnable(GL_TEXTURE_2D);
+
+ /* reset the polygon mode */
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ glDepthMask(GL_FALSE);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glBindTexture(GL_TEXTURE_2D, objectId);
+
+ /* set up texture parameter */
+ if(update){
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ }
+#ifdef VERBOSE
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+#endif
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+
+
+ if(update){
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ gltype = GL_RGBA;
+#ifdef VERBOSE
+ fprintf(stderr, "FORMAT_BYTE_RGBA\n");
+#endif
+ break;
+ case FORMAT_BYTE_RGB:
+ gltype = GL_RGB;
+#ifdef VERBOSE
+ fprintf(stderr, "FORMAT_BYTE_RGB\n");
+#endif
+ break;
+
+ /* GL_ABGR_EXT */
+ case FORMAT_BYTE_ABGR:
+ if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */
+ gltype = GL_ABGR_EXT;
+ }
+ break;
+
+ /* GL_BGR_EXT or GL_BGR */
+ case FORMAT_BYTE_BGR:
+ if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */
+ gltype = ctxProperties->bgr_ext_enum;
+ }
+ break;
+
+ case FORMAT_BYTE_LA:
+ gltype = GL_LUMINANCE_ALPHA;
+ break;
+ case FORMAT_BYTE_GRAY:
+ case FORMAT_USHORT_GRAY:
+ /* TODO: throw exception */
+ break;
+ }
+
+ /* texture map here! */
+ glTexImage2D(GL_TEXTURE_2D, 0, gltype, width,
+ height, 0, gltype, GL_UNSIGNED_BYTE,
+ pixels);
+ }
+ /* loaded identity modelview and projection matrix */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glMatrixMode(GL_TEXTURE);
+ glPushMatrix();
+ glLoadIdentity();
+
+ xzoom = (float)winWidth/maxX;
+ yzoom = (float)winHeight/maxY;
+ switch(imageScaleMode) {
+ case javax_media_j3d_Background_SCALE_NONE:
+ if(xzoom > 1.0f || yzoom > 1.0f){
+ glClearColor((float)r, (float)g, (float)b, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ texMinU = 0.0f;
+ texMinV = 0.0f;
+ texMaxU = 1.0f;
+ texMaxV = 1.0f;
+ halfWidth = (GLfloat)winWidth/2.0f;
+ halfHeight = (GLfloat)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 javax_media_j3d_Background_SCALE_FIT_MIN:
+ if(xzoom != yzoom){
+ glClearColor((float)r, (float)g, (float)b, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ zoom = xzoom < yzoom? 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 javax_media_j3d_Background_SCALE_FIT_MAX:
+ zoom = xzoom > yzoom? xzoom: yzoom;
+ /*fprintf(stderr, "zoom: %f, xzoom: %f, yzoom: %f\n", zoom, 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 javax_media_j3d_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 javax_media_j3d_Background_SCALE_REPEAT:
+ /* glScalef(1.0f, -1.0f, 1.0f); */
+ 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 javax_media_j3d_Background_SCALE_NONE_CENTER:
+ if(xzoom > 1.0f || yzoom > 1.0f){
+ glClearColor((float)r, (float)g, (float)b, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ 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;
+ }
+#ifdef VERBOSE
+ printf("adjustV = %3.2f\n",adjustV);
+ printf("(texMinU,texMinV,texMaxU,texMaxV) = (%3.2f,%3.2f,%3.2f,%3.2f)\n",
+ texMinU,texMinV,texMaxU,texMaxV);
+ printf("(mapMinX,mapMinY,mapMaxX,mapMaxY) = (%3.2f,%3.2f,%3.2f,%3.2f)\n",
+ mapMinX,mapMinY,mapMaxX,mapMaxY);
+#endif
+
+
+ glBegin(GL_QUADS);
+#ifdef VERBOSE
+ /* glTexCoord2f(0.2, 0.2); glVertex2f(0.0,0.0); */
+ /* glTexCoord2f(0.4, 0.2); glVertex2f(0.2,0.0); */
+ /* glTexCoord2f(0.4, 0.4); glVertex2f(0.2,0.2); */
+ /* glTexCoord2f(0.2, 0.4); glVertex2f(0.0,0.2); */
+ glColor3f(1.0, 0.0, 0.0);
+#endif
+ glTexCoord2f(texMinU, texMinV); glVertex2f(mapMinX,mapMinY);
+ glTexCoord2f(texMaxU, texMinV); glVertex2f(mapMaxX,mapMinY);
+ glTexCoord2f(texMaxU, texMaxV); glVertex2f(mapMaxX,mapMaxY);
+ glTexCoord2f(texMinU, texMaxV); glVertex2f(mapMinX,mapMaxY);
+ glEnd();
+
+ /* Restore texture Matrix transform */
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ /* re-enable fragment operation if necessary */
+ glPopAttrib();
+ if(ctxProperties->texture3DAvailable)
+ if (tex3d) glEnable(ctxProperties->texture_3D_ext_enum);
+
+ if(ctxProperties->textureCubeMapAvailable)
+ if (texCubeMap) glEnable(ctxProperties->texture_cube_map_ext_enum);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, pixels_obj,
+ (jbyte *)pixels, 0);
+ }
+
+ /* Java 3D always clears the Z-buffer */
+ glPushAttrib(GL_DEPTH_BUFFER_BIT);
+ glDepthMask(GL_TRUE);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ glPopAttrib();
+
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setRenderMode(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint mode,
+ jboolean dbEnable)
+{
+ GLint drawBuf;
+
+ if (dbEnable) {
+ drawBuf = GL_BACK;
+ switch (mode) {
+ case 0: /* FIELD_LEFT */
+ drawBuf = GL_BACK_LEFT;
+ break;
+ case 1: /* FIELD_RIGHT */
+ drawBuf = GL_BACK_RIGHT;
+ break;
+ case 2: /* FIELD_ALL */
+ drawBuf = GL_BACK;
+ break;
+ }
+ }
+ else {
+ drawBuf = GL_FRONT;
+ switch (mode) {
+ case 0: /* FIELD_LEFT */
+ drawBuf = GL_FRONT_LEFT;
+ break;
+ case 1: /* FIELD_RIGHT */
+ drawBuf = GL_FRONT_RIGHT;
+ break;
+ case 2: /* FIELD_ALL */
+ drawBuf = GL_FRONT;
+ break;
+ }
+ }
+
+#ifdef VERBOSE
+ switch (drawBuf) {
+ case GL_FRONT_LEFT:
+ fprintf(stderr, "glDrawBuffer(GL_FRONT_LEFT)\n");
+ break;
+ case GL_FRONT_RIGHT:
+ fprintf(stderr, "glDrawBuffer(GL_FRONT_RIGHT)\n");
+ break;
+ case GL_FRONT:
+ fprintf(stderr, "glDrawBuffer(GL_FRONT)\n");
+ break;
+ case GL_BACK_LEFT:
+ fprintf(stderr, "glDrawBuffer(GL_BACK_LEFT)\n");
+ break;
+ case GL_BACK_RIGHT:
+ fprintf(stderr, "glDrawBuffer(GL_BACK_RIGHT)\n");
+ break;
+ case GL_BACK:
+ fprintf(stderr, "glDrawBuffer(GL_BACK)\n");
+ break;
+ default:
+ fprintf(stderr, "Unknown glDrawBuffer!!!\n");
+ break;
+ }
+#endif
+
+ glDrawBuffer(drawBuf);
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_clearAccum(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo)
+{
+
+ glClear(GL_ACCUM_BUFFER_BIT);
+
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_accum(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jfloat value)
+{
+
+ glReadBuffer(GL_BACK);
+
+ glAccum(GL_ACCUM, (float)value);
+
+ glReadBuffer(GL_FRONT);
+
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_accumReturn(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo)
+{
+
+ glAccum(GL_RETURN, 1.0);
+
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setDepthBufferWriteEnable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jboolean mode)
+{
+ if (mode)
+ glDepthMask(GL_TRUE);
+ else
+ glDepthMask(GL_FALSE);
+
+}
+
+
+JNIEXPORT
+jint JNICALL Java_javax_media_j3d_Canvas3D_swapBuffers(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong display,
+ jint win)
+{
+
+#if defined(SOLARIS) || defined(__linux__)
+ glXSwapBuffers((Display *)display, (Window)win);
+
+#endif
+
+#ifdef WIN32
+ HDC hdc;
+
+ hdc = (HDC) win;
+
+ SwapBuffers(hdc);
+#endif
+ /*
+ * It would be nice to do a glFinish here, but we can't do this
+ * in the ViewThread Java thread in MT-aware OGL libraries without
+ * switching from the ViewThread to the Renderer thread an extra time
+ * per frame. Instead, we do glFinish after every rendering but before
+ * swap in the Renderer thread.
+ */
+ /* glFinish(); */
+ return 0;
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_syncRender(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jboolean waitFlag)
+{
+
+ if (waitFlag == JNI_TRUE)
+ glFinish();
+ else
+ glFlush();
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_newDisplayList(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint id)
+{
+
+ glNewList(id, GL_COMPILE);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_endDisplayList(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo)
+{
+
+ glEndList();
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_setGlobalAlpha(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jfloat alpha)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ /* GL_GLOBAL_ALPHA_SUN */
+ if(ctxProperties->global_alpha_sun){
+ glEnable(GL_GLOBAL_ALPHA_SUN);
+ ctxProperties->glGlobalAlphaFactorfSUN(alpha);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_disableGlobalAlpha(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo)
+{
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ /* GL_GLOBAL_ALPHA_SUN */
+ if(ctxProperties->global_alpha_sun){
+ glDisable(GL_GLOBAL_ALPHA_SUN);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_callDisplayList(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint id,
+ jboolean isNonUniformScale)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ /* resale_normal_ext */
+ if (ctxProperties->rescale_normal_ext && isNonUniformScale) {
+ glEnable(GL_NORMALIZE);
+ }
+
+ glCallList(id);
+
+ if (ctxProperties->rescale_normal_ext && isNonUniformScale) {
+ glDisable(GL_NORMALIZE);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_freeDisplayList(
+ JNIEnv *env,
+ jclass cl,
+ jlong ctxInfo,
+ jint id)
+{
+
+ glDeleteLists(id, 1);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_freeTexture(
+ JNIEnv *env,
+ jclass cl,
+ jlong ctxInfo,
+ jint id)
+{
+ GLuint texObj;
+
+ if(id > 0) {
+ texObj = id;
+ glDeleteTextures(1, &texObj);
+ }
+ else
+ fprintf(stderr, "try to delete tex with texid <= 0. \n");
+
+}
+
+
+
+JNIEXPORT jint JNICALL Java_javax_media_j3d_Canvas3D_getTextureUnitCount(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ return ctxProperties->textureUnitCount;
+}
+
+/*
+ * Method: getTextureColorTableSize
+ */
+int getTextureColorTableSize(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ char *extensionStr,
+ int minorVersion)
+{
+ GraphicsContextPropertiesInfo* ctxProperties = (GraphicsContextPropertiesInfo* )ctxInfo;
+ int size;
+
+ if(minorVersion >= 2 && isExtensionSupported(extensionStr, "GL_ARB_imaging")){
+
+#ifdef WIN32
+ ctxProperties->glColorTable = (MYPFNGLCOLORTABLEPROC)wglGetProcAddress("glColorTable");
+ ctxProperties->glGetColorTableParameteriv =
+ (MYPFNGLGETCOLORTABLEPARAMETERIVPROC)wglGetProcAddress("glGetColorTableParameteriv");
+#endif
+#if defined(SOLARIS) || defined(__linux__)
+ ctxProperties->glColorTable = glColorTable;
+ ctxProperties->glGetColorTableParameteriv = glGetColorTableParameteriv;
+#endif
+
+ } else if(isExtensionSupported(extensionStr, "GL_SGI_color_table")) {
+#ifdef WIN32
+ ctxProperties->glColorTable = (MYPFNGLCOLORTABLEPROC)wglGetProcAddress("glColorTableSGI");
+ ctxProperties->glGetColorTableParameteriv =
+ (MYPFNGLGETCOLORTABLEPARAMETERIVPROC)wglGetProcAddress("glGetColorTableParameterivSGI");
+#endif
+#if defined(SOLARIS) || defined(__linux__)
+ ctxProperties->glColorTable = glColorTableSGI;
+ ctxProperties->glGetColorTableParameteriv = glGetColorTableParameterivSGI;
+#endif
+
+ } else {
+ return 0;
+ }
+
+ if ((ctxProperties->glColorTable == NULL) ||
+ (ctxProperties->glGetColorTableParameteriv == NULL)) {
+ return 0;
+ }
+
+ ctxProperties->glColorTable(GL_PROXY_TEXTURE_COLOR_TABLE_SGI, GL_RGBA, 256, GL_RGB,
+ GL_INT, NULL);
+ ctxProperties->glGetColorTableParameteriv(GL_PROXY_TEXTURE_COLOR_TABLE_SGI,
+ GL_COLOR_TABLE_WIDTH_SGI, &size);
+ return size;
+}
+
+/* we want to use this if available: */
+#define GLX_SGIX_pbuffer 1
+
+#ifndef GLX_VERSION_1_3
+#ifdef GLX_SGIX_pbuffer
+#ifdef __linux__
+typedef XID GLXPbuffer;
+typedef struct __GLXFBConfigRec *GLXFBConfig;
+typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
+extern GLXFBConfig * glXChooseFBConfig (Display *dpy, int screen, const int *attrib_list, int *nelements);
+extern GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attrib_list);
+extern void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuf);
+extern GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, const int *attribList, int *nitems);
+extern GLXPbuffer glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfig config, unsigned int width, unsigned int height, const int *attribList);
+extern void glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbuffer pbuf);
+#define GLX_DRAWABLE_TYPE 0x8010
+#define GLX_PBUFFER_BIT 0x00000004
+#define GLX_RENDER_TYPE 0x8011
+#define GLX_RGBA_BIT 0x00000001
+#define GLX_MAX_PBUFFER_WIDTH 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT 0x8017
+#define GLX_PRESERVED_CONTENTS 0x801B
+#define GLX_PBUFFER_HEIGHT 0x8040 /* New for GLX 1.3 */
+#define GLX_PBUFFER_WIDTH 0x8041 /* New for GLX 1.3 */
+#define GLX_LARGEST_PBUFFER 0x801C
+#define GLX_LARGEST_PBUFFER_SGIX GLX_LARGEST_PBUFFER
+#else
+
+#define GLX_DRAWABLE_TYPE GLX_DRAWABLE_TYPE_SGIX
+#define GLX_PBUFFER_BIT GLX_PBUFFER_BIT_SGIX
+#define GLX_RENDER_TYPE GLX_RENDER_TYPE_SGIX
+#define GLX_RGBA_BIT GLX_RGBA_BIT_SGIX
+#endif
+#endif /* GLX_SGIX_pbuffer */
+#else
+#ifdef __linux__
+typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
+#endif /* __linux__ */
+#endif /* GLX_VERSION_1_3 */
+
+#if defined(SOLARIS) || defined(__linux__)
+#pragma weak glXChooseFBConfig
+#pragma weak glXCreatePbuffer
+#pragma weak glXDestroyPbuffer
+#pragma weak glXChooseFBConfigSGIX
+#pragma weak glXCreateGLXPbufferSGIX
+#pragma weak glXDestroyGLXPbufferSGIX
+#endif /* SOLARIS */
+
+
+
+/* For dvr support */
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_videoResize(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong display,
+ jint win,
+ jfloat dvrFactor)
+{
+
+#if defined(SOLARIS) || defined(__linux__)
+ /* Not need to do ext. supported checking. This check is done in java. */
+
+ /* fprintf(stderr, "Canvas3D.c -- glXVideoResize -- %d %f\n", win, dvrFactor); */
+ glXVideoResizeSUN((Display *)display, (Window)win, (float) dvrFactor);
+#endif
+
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_videoResizeCompensation(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jboolean enable)
+{
+
+#if defined(SOLARIS) || defined(__linux__)
+ GraphicsContextPropertiesInfo *ctxProperties =
+ (GraphicsContextPropertiesInfo *)ctxInfo;
+
+ if (ctxProperties->videoResizeAvailable) {
+ if(enable == JNI_TRUE) {
+ /* fprintf(stderr, "videoResizeCompensation - glEnable"); */
+ glEnable(GL_VIDEO_RESIZE_COMPENSATION_SUN);
+ }
+ else {
+ /* fprintf(stderr, "videoResizeCompensation - glDisable"); */
+ glDisable(GL_VIDEO_RESIZE_COMPENSATION_SUN);
+ }
+ }
+
+#endif
+
+}
+
+JNIEXPORT
+jint JNICALL Java_javax_media_j3d_Canvas3D_createOffScreenBuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong display,
+ jint vid,
+ jint width,
+ jint height)
+{
+
+#if defined(SOLARIS) || defined(__linux__)
+ XVisualInfo *vinfo, template;
+ int nitems, depth, redSize;
+ Display *dpy;
+ static GLboolean pbufferSupported = GL_FALSE;
+ static GLboolean pbufferExtSupported = GL_FALSE;
+ int major, minor;
+ const char *extStr;
+ int status;
+
+ dpy = (Display *)display;
+
+ if (dpy == NULL)
+ dpy = XOpenDisplay(NULL);
+
+ template.visualid = vid;
+ vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems);
+ if (nitems != 1) {
+ fprintf(stderr, "Warning Canvas3D_createContext got unexpected number of matching visuals %d\n", nitems);
+ }
+
+ glXGetConfig (dpy, vinfo, GLX_BUFFER_SIZE, &depth);
+ glXGetConfig (dpy, vinfo, GLX_RED_SIZE, &redSize);
+
+ if (status = glXQueryVersion(dpy, &major, &minor)) {
+
+#if 0
+ /* don't use the 1.3 pbuffer interface for now. */
+ if ((major > 1) || (major == 1 && minor >= 3))
+ pbufferSupported = GL_TRUE;
+ else
+#endif
+ {
+ extStr = glXQueryExtensionsString(dpy, DefaultScreen(dpy));
+ if ((extStr != NULL) && (strstr(extStr, "GLX_SGIX_pbuffer"))) {
+ pbufferExtSupported = GL_TRUE;
+ }
+ }
+ }
+
+#if defined(GLX_VERSION_1_3) || defined(GLX_SGIX_pbuffer)
+ if (pbufferExtSupported || pbufferSupported) {
+
+
+ int attrCount, configAttr[10], numConfig, val;
+ GLXPbuffer pbuff;
+
+ /* Initialize the attribute list to be used for choosing FBConfig */
+ attrCount = 0;
+ configAttr[attrCount++] = GLX_DRAWABLE_TYPE;
+ configAttr[attrCount++] = GLX_PBUFFER_BIT;
+ configAttr[attrCount++] = GLX_RENDER_TYPE;
+ configAttr[attrCount++] = GLX_RGBA_BIT;
+ configAttr[attrCount++] = GLX_RED_SIZE;
+ configAttr[attrCount++] = redSize;
+ configAttr[attrCount++] = None;
+/*
+ configAttr[attrCount++] = GLX_DEPTH_SIZE;
+ configAttr[attrCount++] = depth;
+*/
+
+
+#ifdef GLX_VERSION_1_3
+ if (pbufferSupported) {
+ GLXFBConfig *fbconfiglst;
+
+ fbconfiglst = glXChooseFBConfig(dpy, DefaultScreen(dpy),
+ configAttr, &numConfig);
+
+ if (numConfig < 1) {
+ fprintf(stderr, "# of configs returned is %d\n", numConfig);
+ return None;
+ }
+
+ attrCount = 0;
+ configAttr[attrCount++] = GLX_PBUFFER_WIDTH;
+ configAttr[attrCount++] = width;
+ configAttr[attrCount++] = GLX_PBUFFER_HEIGHT;
+ configAttr[attrCount++] = height;
+ configAttr[attrCount++] = GLX_PRESERVED_CONTENTS;
+ configAttr[attrCount++] = GL_TRUE;
+ configAttr[attrCount++] = None;
+
+
+ pbuff = glXCreatePbuffer(dpy, fbconfiglst[0], configAttr);
+ }
+#endif /* GLX_VERSION_1_3 */
+
+#ifdef GLX_SGIX_pbuffer
+ if (pbufferExtSupported && !pbufferSupported) {
+ GLXFBConfigSGIX *fbconfiglst;
+
+
+ /* Determine what config to use according to config_attr */
+ fbconfiglst = glXChooseFBConfigSGIX(dpy, DefaultScreen(dpy),
+ configAttr, &numConfig);
+
+ if (numConfig < 1) {
+ fprintf(stderr, "# of configs returned is %d\n", numConfig);
+ return None;
+ }
+
+ attrCount = 0;
+ configAttr[attrCount++] = GLX_PRESERVED_CONTENTS;
+ configAttr[attrCount++] = GL_TRUE;
+ configAttr[attrCount++] = None;
+ pbuff = glXCreateGLXPbufferSGIX(dpy, fbconfiglst[0], width, height,
+ configAttr );
+ }
+#endif /* GLX_SGIX_pbuffer */
+ if (pbuff == None) {
+ fprintf(stderr, "glXCreateGLXPbuffer() returns None\n");
+ }
+
+ return pbuff;
+
+ } else
+#endif /* GLX_VERSION_1_3 || GLX_SGIX_pbuffer */
+
+ {
+ Pixmap pixmap;
+ GLXPixmap glxpixmap;
+
+ /* fall back to pixmap */
+ pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height,
+ vinfo->depth);
+
+ glxpixmap = glXCreateGLXPixmap(dpy, vinfo, pixmap);
+ if (glxpixmap == None) {
+ fprintf(stderr, "glXCreateGLXPixmap() returns None\n");
+ }
+
+ return glxpixmap;
+ }
+
+#endif /* SOLARIS */
+
+#ifdef WIN32
+ int PixelFormatID=0;
+ int dpy = (int)display;
+ HDC hdc; /* HW Device Context */
+ jboolean rescale = JNI_FALSE;
+ JNIEnv table = *env;
+
+ HBITMAP hbitmap, oldhbitmap;
+
+ BITMAPINFOHEADER bih;
+ void *ppvBits;
+ int err;
+ LPTSTR errString;
+ HDC hdcMonitor;
+
+ /* create a DIB */
+ memset(&bih, 0, sizeof(BITMAPINFOHEADER));
+
+ bih.biSize = sizeof(BITMAPINFOHEADER);
+ bih.biWidth = width;
+ bih.biHeight = height;
+ bih.biPlanes = 1;
+ bih.biBitCount = 24;
+ bih.biCompression = BI_RGB;
+
+ /* create a new device context */
+
+ if (dpy == 0) {
+ hdc = CreateCompatibleDC(0);
+ } else {
+ /*
+ * Should be getMonitorDC(screen)
+ * but display and screen are the same under windows
+ * They are return from NativeScreenInfo
+ */
+ hdcMonitor = getMonitorDC((int) display);
+ hdc = CreateCompatibleDC(hdcMonitor);
+ DeleteDC(hdcMonitor);
+
+ }
+ hbitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bih,
+ DIB_PAL_COLORS, &ppvBits, NULL, 0);
+
+ if (!hbitmap) {
+ err = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, 0, (LPTSTR)&errString, 0, NULL);
+ fprintf(stderr, "CreateDIBSection failed: %s\n", errString);
+ }
+
+ oldhbitmap = SelectObject(hdc, hbitmap);
+
+ /* Choosing and setting of pixel format is done in createContext */
+
+ return ((jint)hdc);
+#endif /* WIN32 */
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong display,
+ jint window)
+{
+#if defined(SOLARIS) || defined(__linux__)
+ Display *dpy = (Display*)display;
+
+ GLboolean pbufferSupported = GL_FALSE;
+ GLboolean pbufferExtSupported = GL_TRUE;
+ int major, minor;
+ char *extStr;
+
+ if (glXQueryVersion(dpy, &major, &minor)) {
+
+#if 0
+ /* don't use the 1.3 pbuffer interface for now. */
+ if ((major > 1) || (major == 1 && minor >= 3))
+ pbufferSupported = GL_TRUE;
+ else
+#endif
+ {
+ extStr = (char *)glXQueryExtensionsString(dpy,
+ DefaultScreen(dpy));
+ if ((extStr != NULL) && (strstr(extStr, "GLX_SGIX_pbuffer"))) {
+ pbufferExtSupported = GL_TRUE;
+ }
+ }
+ }
+
+#if defined(GLX_VERSION_1_3) || defined(GLX_SGIX_pbuffer)
+
+ if (pbufferSupported) {
+ glXDestroyPbuffer(dpy, (GLXPbuffer)window);
+ } else if (pbufferExtSupported) {
+ glXDestroyGLXPbufferSGIX(dpy, (GLXPbuffer)window);
+ } else
+#endif
+
+ {
+ glXDestroyGLXPixmap(dpy, (GLXPixmap)window);
+ }
+#endif /* SOLARIS */
+
+#ifdef WIN32
+ HBITMAP oldhbitmap;
+ HDC hdc = (HDC) window;
+
+ oldhbitmap = SelectObject(hdc, NULL);
+ DeleteObject(oldhbitmap);
+ DeleteDC(hdc);
+#endif /* WIN32 */
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_readOffScreenBuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint format,
+ jint width,
+ jint height)
+{
+ JNIEnv table = *env;
+ jclass cv_class;
+ jfieldID byteData_field;
+ jbyteArray byteData_array;
+ jbyte *byteData;
+ int type;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ glPixelStorei(GL_PACK_ROW_LENGTH, width);
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+ cv_class = (jclass) (*(table->GetObjectClass))(env, obj);
+ byteData_field = (jfieldID) (*(table->GetFieldID))(env, cv_class,
+ "byteBuffer", "[B");
+ byteData_array = (jbyteArray)(*(table->GetObjectField))(env, obj,
+ byteData_field);
+ byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env,
+ byteData_array, NULL);
+
+
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ type = GL_RGBA;
+ break;
+ case FORMAT_BYTE_RGB:
+ type = GL_RGB;
+ break;
+
+ /* GL_ABGR_EXT */
+ case FORMAT_BYTE_ABGR:
+ if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */
+ type = GL_ABGR_EXT;
+ }
+ break;
+
+ /* GL_BGR_EXT */
+ case FORMAT_BYTE_BGR:
+ if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */
+ type = ctxProperties->bgr_ext_enum;
+ }
+ break;
+
+ case FORMAT_BYTE_LA:
+ type = GL_LUMINANCE_ALPHA;
+ break;
+ case FORMAT_BYTE_GRAY:
+ case FORMAT_USHORT_GRAY:
+ /* TODO: throw exception */
+ break;
+ }
+
+
+ glReadPixels(0, 0, width, height, type, GL_UNSIGNED_BYTE, byteData);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, byteData_array,
+ byteData, 0);
+}
+
+void initializeCtxInfo(JNIEnv *env , GraphicsContextPropertiesInfo* ctxInfo){
+ ctxInfo->context = 0;
+
+ /* version and extension info */
+ ctxInfo->versionStr = NULL;
+ ctxInfo->extensionStr = NULL;
+ ctxInfo->versionNumbers[0] = 1;
+ ctxInfo->versionNumbers[1] = 1;
+
+ /* both in 1.2 core part and 1.1 extensions */
+ ctxInfo->rescale_normal_ext = JNI_FALSE;
+ ctxInfo->bgr_ext = JNI_FALSE;
+ ctxInfo->texture3DAvailable = JNI_FALSE;
+ ctxInfo->seperate_specular_color = JNI_FALSE;
+
+ /* 1.2 and GL_ARB_imaging */
+ ctxInfo->blend_color_ext = JNI_FALSE;
+ ctxInfo->color_table_ext = JNI_FALSE;
+ ctxInfo->blendFunctionTable[0] = GL_ZERO;
+ ctxInfo->blendFunctionTable[1] = GL_ONE;
+ ctxInfo->blendFunctionTable[2] = GL_SRC_ALPHA;
+ ctxInfo->blendFunctionTable[3] = GL_ONE_MINUS_SRC_ALPHA;
+ ctxInfo->blendFunctionTable[4] = GL_DST_COLOR;
+ ctxInfo->blendFunctionTable[5] = GL_SRC_COLOR;
+ ctxInfo->blendFunctionTable[6] = GL_ONE_MINUS_SRC_COLOR;
+ ctxInfo->blendFunctionTable[7] = GL_SRC_COLOR;
+
+ /* 1.1 extensions or 1.2 extensions */
+ /* sun extensions */
+ ctxInfo->multi_draw_arrays_sun = JNI_FALSE;
+ ctxInfo->compiled_vertex_array_ext = JNI_FALSE;
+
+ ctxInfo->videoResizeAvailable = JNI_FALSE;
+ ctxInfo->global_alpha_sun = JNI_FALSE;
+ ctxInfo->constant_data_sun = JNI_FALSE;
+ ctxInfo->geometry_compression_sunx = JNI_FALSE;
+
+ /* EXT extensions */
+ ctxInfo->abgr_ext = JNI_FALSE;
+
+ ctxInfo->multi_draw_arrays_ext = JNI_FALSE;
+
+ ctxInfo->implicit_multisample = getJavaBoolEnv(env, "implicitAntialiasing");
+
+ /* ARB extensions */
+ ctxInfo->arb_transpose_matrix = JNI_FALSE;
+ ctxInfo->arb_multitexture = JNI_FALSE;
+
+ ctxInfo->arb_multisample = JNI_FALSE;
+ ctxInfo->textureUnitCount = 1;
+ ctxInfo->textureEnvCombineAvailable = JNI_FALSE;
+ ctxInfo->textureCombineDot3Available = JNI_FALSE;
+ ctxInfo->textureCombineSubtractAvailable = JNI_FALSE;
+ ctxInfo->textureCubeMapAvailable = JNI_FALSE;
+
+ /* NV extensions */
+ ctxInfo->textureRegisterCombinersAvailable = JNI_FALSE;
+
+ /* SGI extensions */
+ ctxInfo->textureSharpenAvailable = JNI_FALSE;
+ ctxInfo->textureDetailAvailable = JNI_FALSE;
+ ctxInfo->textureFilter4Available = JNI_FALSE;
+ ctxInfo->textureAnisotropicFilterAvailable = JNI_FALSE;
+ ctxInfo->textureColorTableAvailable = JNI_FALSE;
+ ctxInfo->textureColorTableSize = 0;
+ ctxInfo->textureLodAvailable = JNI_FALSE;
+ ctxInfo->textureLodBiasAvailable = JNI_FALSE;
+
+ ctxInfo->geometry_compression_accelerated = JNI_FALSE;
+ ctxInfo->geometry_compression_accelerated_major_version = 0;
+ ctxInfo->geometry_compression_accelerated_minor_version = 0;
+ ctxInfo->geometry_compression_accelerated_subminor_version = 0;
+
+ /* extension mask */
+ ctxInfo->extMask = 0;
+ ctxInfo->textureExtMask = 0;
+
+ ctxInfo->glBlendColor = NULL;
+ ctxInfo->glBlendColorEXT = NULL;
+ ctxInfo->glColorTable = NULL;
+ ctxInfo->glGetColorTableParameteriv = NULL;
+ ctxInfo->glTexImage3DEXT = NULL;
+ ctxInfo->glTexSubImage3DEXT = NULL;
+ ctxInfo->glClientActiveTextureARB = NULL;
+ ctxInfo->glMultiDrawArraysEXT = NULL;
+ ctxInfo->glMultiDrawElementsEXT = NULL;
+ ctxInfo->glLockArraysEXT = NULL;
+ ctxInfo->glUnlockArraysEXT = NULL;
+ ctxInfo->glMultiTexCoord2fvARB = NULL;
+ ctxInfo->glMultiTexCoord3fvARB = NULL;
+ ctxInfo->glMultiTexCoord4fvARB = NULL;
+ ctxInfo->glLoadTransposeMatrixdARB = NULL;
+ ctxInfo->glMultTransposeMatrixdARB = NULL;
+ ctxInfo->glActiveTextureARB = NULL;
+ ctxInfo->glGlobalAlphaFactorfSUN = NULL;
+
+ ctxInfo->glCombinerInputNV = NULL;
+ ctxInfo->glCombinerOutputNV = NULL;
+ ctxInfo->glFinalCombinerInputNV = NULL;
+ ctxInfo->glCombinerParameterfvNV = NULL;
+ ctxInfo->glCombinerParameterivNV= NULL;
+ ctxInfo->glCombinerParameterfNV = NULL;
+ ctxInfo->glCombinerParameteriNV = NULL;
+
+ ctxInfo->glSharpenTexFuncSGIS = NULL;
+ ctxInfo->glDetailTexFuncSGIS = NULL;
+ ctxInfo->glTexFilterFuncSGIS = NULL;
+}
+
+void cleanupCtxInfo(GraphicsContextPropertiesInfo* ctxInfo){
+ if( ctxInfo->versionStr != NULL)
+ free(ctxInfo->versionStr);
+ if( ctxInfo->extensionStr != NULL)
+ free(ctxInfo->extensionStr);
+ ctxInfo->versionStr = NULL;
+ ctxInfo->extensionStr = NULL;
+}
+
+#ifdef WIN32
+HWND createDummyWindow(const char* szAppName) {
+ static char szTitle[]="A Simple C OpenGL Program";
+ WNDCLASS wc; /* windows class sruct */
+
+ HWND hWnd;
+
+ /* Fill in window class structure with parameters that */
+ /* describe the main window. */
+
+ wc.style =
+ CS_HREDRAW | CS_VREDRAW;/* Class style(s). */
+ wc.lpfnWndProc =
+ (WNDPROC)WndProc; /* Window Procedure */
+ wc.cbClsExtra = 0; /* No per-class extra data. */
+ wc.cbWndExtra = 0; /* No per-window extra data. */
+ wc.hInstance =
+ NULL; /* Owner of this class */
+ wc.hIcon = NULL; /* Icon name */
+ wc.hCursor =
+ NULL;/* Cursor */
+ wc.hbrBackground =
+ (HBRUSH)(COLOR_WINDOW+1);/* Default color */
+ wc.lpszMenuName = NULL; /* Menu from .RC */
+ wc.lpszClassName =
+ szAppName; /* Name to register as
+
+ /* Register the window class */
+
+ if(RegisterClass( &wc )==0)
+ fprintf(stdout, "Couldn't register class\n");
+
+ /* Create a main window for this application instance. */
+
+ hWnd = CreateWindow(
+ szAppName, /* app name */
+ szTitle, /* Text for window title bar */
+ WS_OVERLAPPEDWINDOW/* Window style */
+ /* NEED THESE for OpenGL calls to work!*/
+ | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ NULL, /* no parent window */
+ NULL, /* Use the window class menu.*/
+ NULL, /* This instance owns this window */
+ NULL /* We don't use any extra data */
+ );
+
+ /* If window could not be created, return zero */
+ if ( !hWnd ){
+ fprintf(stdout, "Couldn't Create window\n");
+ return NULL;
+ }
+ return hWnd;
+}
+#endif
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext(
+ JNIEnv *env,
+ jobject obj,
+ jlong display,
+ jint window,
+ jint vid,
+ jboolean offScreen,
+ jint width,
+ jint height)
+{
+ JNIEnv table = *env;
+ jlong gctx;
+ long newWin;
+ int PixelFormatID=0;
+ GraphicsContextPropertiesInfo* ctxInfo = (GraphicsContextPropertiesInfo *)malloc(sizeof(GraphicsContextPropertiesInfo));
+
+#if defined(SOLARIS) || defined(__linux__)
+ XVisualInfo *vinfo, template;
+ int nitems;
+ GLXContext ctx;
+ int result;
+ Window root;
+ Window glWin;
+ XSetWindowAttributes win_attrs;
+ Colormap cmap;
+ unsigned long win_mask;
+ jlong hdc;
+
+ template.visualid = vid;
+ vinfo = XGetVisualInfo((Display *)display, VisualIDMask, &template, &nitems);
+ if (nitems != 1) {
+ fprintf(stderr, "Warning Canvas3D_createQueryContext got unexpected number of matching visuals %d\n", nitems);
+ }
+
+ ctx = glXCreateContext((Display *)display, vinfo, NULL, True);
+ if (ctx == NULL) {
+ fprintf(stderr, "Error Canvas3D_createQueryContext: couldn't create context.\n");
+ }
+
+
+ /* create window if window == 0 and offscreen == true */
+ if(window == 0 && !offScreen) {
+
+ root = RootWindow((Display *)display, vinfo->screen);
+
+ /* Create a colormap */
+ cmap = XCreateColormap((Display *)display, root, vinfo->visual, AllocNone);
+
+ /* Create a window */
+ win_attrs.colormap = cmap;
+ win_attrs.border_pixel = 0;
+ win_attrs.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask;
+ win_mask = CWColormap | CWBorderPixel | CWEventMask;
+ glWin = XCreateWindow((Display *)display, root, 0, 0, width, height, 0, vinfo->depth,
+ InputOutput, vinfo->visual, win_mask, &win_attrs);
+ newWin = (unsigned long)glWin;
+ }
+ else if(window == 0 && offScreen){
+ newWin = Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( env, obj, 0, display, vid, width, height);
+ }
+ else if(window != 0) {
+ newWin = window;
+ }
+
+ result = glXMakeCurrent((Display *)display, (GLXDrawable)newWin, (GLXContext)ctx);
+ if (result == GL_FALSE)
+ fprintf(stderr, "glXMakeCurrent fails\n");
+ gctx = (jlong)ctx;
+#endif
+
+#ifdef WIN32
+ HGLRC hrc; /* HW Rendering Context */
+ HDC hdc; /* HW Device Context */
+ DWORD err;
+ LPTSTR errString;
+ HWND hWnd;
+ static char szAppName[] = "OpenGL";
+ jlong vinfo = 0;
+
+ static PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR),
+ 1, /* Version number */
+ PFD_DRAW_TO_WINDOW |
+ PFD_SUPPORT_OPENGL|
+ PFD_DOUBLEBUFFER,
+ PFD_TYPE_RGBA,
+ 24, /* 24 bit color depth */
+ 0, 0, 0, /* RGB bits and pixel sizes */
+ 0, 0, 0, /* Donnot care about them */
+ 0, 0, /* no alpha buffer info */
+ 0, 0, 0, 0, 0, /* no accumulation buffer */
+ 32, /* 16 bit depth buffer */
+ 0, /* no stencil buffer */
+ 0, /* no auxiliary buffers */
+ PFD_MAIN_PLANE, /* layer type */
+ 0, /* reserved, must be 0 */
+ 0, /* no layer mask */
+ 0, /* no visible mask */
+ 0 /* no damage mask */
+ };
+
+ jboolean result;
+
+ /* onscreen rendering and window is 0 now */
+ if(window == 0 && !offScreen){
+ hWnd = createDummyWindow((const char *)szAppName);
+ if (!hWnd)
+ return;
+ hdc = GetDC(hWnd);
+ }
+ else if(window == 0 && offScreen){
+ hdc = (HDC)Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( env, obj, 0, display, vid, width, height);
+ pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL |
+ PFD_SUPPORT_GDI;
+ vid = -1;
+ }
+ else if(window != 0 && offScreen){
+ pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL |
+ PFD_SUPPORT_GDI;
+ vid = -1;
+ hdc = (HDC) window;
+ }
+ else if(window !=0 && !offScreen){
+ hdc = (HDC) window;
+ }
+
+ newWin = (int)hdc;
+
+ /* vid of -1 means no vid was specified - do the old way */
+ if (vid == -1) {
+ /*
+ * choose the "pixel format", terminology is equivalent
+ * to UNIX "visual"
+ */
+ PixelFormatID = ChoosePixelFormat(hdc, &pfd);
+
+ if(PixelFormatID == 0) {
+ fprintf(stderr,"\nERROR: pixel format ID = 0");
+ return;
+ }
+ }
+ else
+ PixelFormatID = vid;
+
+ SetPixelFormat(hdc, PixelFormatID, &pfd);
+
+ hrc = wglCreateContext( hdc );
+
+ if (!hrc) {
+ err = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, 0, (LPTSTR)&errString, 0, NULL);
+
+ fprintf(stderr, "wglCreateContext Failed: %s\n", errString);
+ }
+
+
+ result = wglMakeCurrent(hdc, hrc);
+
+ if (!result) {
+ err = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, 0, (LPTSTR)&errString, 0, NULL);
+ fprintf(stderr, "wglMakeCurrent Failed: %s\n", errString);
+ }
+
+ gctx = (jlong)hrc;
+
+#endif
+
+ initializeCtxInfo(env, ctxInfo);
+ ctxInfo->context = gctx;
+
+ /* get current context properties */
+ if (getPropertiesFromCurrentContext(env, obj, ctxInfo, (jlong) hdc, PixelFormatID, display, (jlong) vinfo)) {
+ /* put the properties to the Java side */
+ setupCanvasProperties(env, obj, ctxInfo);
+ }
+
+
+ /* clear up the context , colormap and window if appropriate */
+ if(window == 0 && !offScreen){
+#if defined(SOLARIS) || defined(__linux__)
+ Java_javax_media_j3d_Canvas3D_destroyContext(env, obj, display, newWin, (jlong)ctxInfo);
+ XDestroyWindow((Display *)display, glWin);
+ XFreeColormap((Display *)display, cmap);
+#endif /* SOLARIS */
+#ifdef WIN32
+ /* Release DC */
+ ReleaseDC(hWnd, hdc);
+ /* Destroy context */
+ /* This will free ctxInfo also */
+ Java_javax_media_j3d_Canvas3D_destroyContext(env, obj, display,newWin, (jlong)ctxInfo);
+ DestroyWindow(hWnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+#endif /* WIN32 */
+ }
+ else if(window == 0 && offScreen) {
+ Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer(env, obj, gctx, display, newWin);
+ Java_javax_media_j3d_Canvas3D_destroyContext(env, obj, display, newWin, (jlong)ctxInfo);
+ }
+ else if(window != 0){
+ Java_javax_media_j3d_Canvas3D_destroyContext(env, obj, display, newWin, (jlong)ctxInfo);
+ }
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_beginScene(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo)
+{
+ /* Not used by OGL version */
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_Canvas3D_endScene(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo)
+{
+ /* This function is a no-op */
+ /*
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ */
+}
+
+/* Setup the multisampling for full scene antialiasing */
+JNIEXPORT void JNICALL Java_javax_media_j3d_Canvas3D_setFullSceneAntialiasing
+(JNIEnv *env, jobject obj, jlong ctxInfo, jboolean enable)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ if (ctxProperties->arb_multisample && !ctxProperties->implicit_multisample) {
+ if(enable == JNI_TRUE) {
+ glEnable(MULTISAMPLE_ARB);
+ }
+ else {
+ glDisable(MULTISAMPLE_ARB);
+
+ }
+ }
+
+}
+
+
+/*
+ * Return false if <= 8 bit color under windows
+ */
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_Canvas3D_validGraphicsMode(
+ JNIEnv *env,
+ jobject obj)
+{
+#ifdef WIN32
+ DEVMODE devMode;
+
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);
+ return (devMode.dmBitsPerPel > 8);
+#endif
+
+#if defined(SOLARIS) || defined(__linux__)
+ return TRUE;
+#endif
+}
diff --git a/src/native/ogl/CompressedGeometryRetained.c b/src/native/ogl/CompressedGeometryRetained.c
new file mode 100644
index 0000000..36ca164
--- /dev/null
+++ b/src/native/ogl/CompressedGeometryRetained.c
@@ -0,0 +1,70 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include <stdio.h>
+#include <jni.h>
+#include "gldefs.h"
+
+#ifdef SOLARIS
+#pragma weak glDrawCompressedGeomSUNX
+
+#else
+static void glDrawCompressedGeomSUNX(GLint size, GLubyte *data) {
+ fprintf(stderr, "Warning: glDrawCompressedGeomSUNX() not supported\n") ;
+}
+#endif /* SOLARIS */
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_CompressedGeometryRetained_execute
+ (JNIEnv *env, jobject obj, jlong ctxInfo, jint version, jint bufferType,
+ jint bufferContents, jint renderFlags, jint offset, jint size,
+ jbyteArray geometry)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ jbyte *cg = (*env)->GetPrimitiveArrayCritical(env, geometry, 0) ;
+
+ /* ignore offset and pass header at 0 along with cg data */
+ if(ctxProperties->geometry_compression_sunx)
+ glDrawCompressedGeomSUNX((GLint)(size + 48), (GLubyte *)cg) ;
+
+ (*env)->ReleasePrimitiveArrayCritical(env, geometry, cg, 0) ;
+}
+
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_CompressedGeometryRetained_decompressByRef
+ (JNIEnv *env, jobject obj, jlong ctxInfo)
+{
+ return JNI_FALSE ;
+}
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_CompressedGeometryRetained_decompressHW
+ (JNIEnv *env, jobject obj, jlong ctxInfo, jint majorVersion, jint minorVersion)
+{
+ /*
+ * Return true if hardware decompression is supported for the given
+ * version number of the compressed geometry.
+ */
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ return
+ (ctxProperties->geometry_compression_accelerated == 1) &&
+ ((majorVersion < ctxProperties->geometry_compression_accelerated_major_version) ||
+ ((majorVersion == ctxProperties->geometry_compression_accelerated_major_version) &&
+ (minorVersion <= ctxProperties->geometry_compression_accelerated_minor_version))) ;
+}
diff --git a/src/native/ogl/DrawingSurfaceObjectAWT.c b/src/native/ogl/DrawingSurfaceObjectAWT.c
new file mode 100644
index 0000000..71e4376
--- /dev/null
+++ b/src/native/ogl/DrawingSurfaceObjectAWT.c
@@ -0,0 +1,268 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <jawt_md.h>
+
+#ifdef DEBUG
+/* Uncomment the following for VERBOSE debug messages */
+/* #define VERBOSE */
+#endif /* DEBUG */
+
+
+#if defined(SOLARIS) || defined(__linux__)
+#pragma weak JAWT_GetAWT
+#endif
+
+#ifdef SOLARIS
+#pragma weak XDgaGetXineramaInfo
+
+/*
+ * The following include file contains the definitions of unsupported,
+ * undocumented data structures and functions used to implement Xinerama.
+ * They are also used by the Solaris implementations of OpenGL and AWT. This
+ * is an interim solution until they are made part of the X Window System
+ * standard or replaced with a fully supported API.
+ */
+#include "panoramiXext.h"
+#endif /* SOLARIS */
+
+
+JNIEXPORT jlong JNICALL
+Java_javax_media_j3d_MasterControl_getAWT(
+ JNIEnv *env, jobject obj)
+{
+ JAWT *awt;
+
+ awt = (JAWT*) malloc(sizeof(JAWT));
+ if (awt == NULL) {
+ fprintf(stderr, "malloc failed\n");
+ return 0;
+ }
+
+ awt->version = JAWT_VERSION_1_4;
+
+ if (JAWT_GetAWT(env, awt) == JNI_FALSE) {
+ fprintf(stderr, "AWT not found\n");
+ return 0;
+ }
+ return (jlong)awt;
+}
+
+JNIEXPORT
+jlong JNICALL
+Java_javax_media_j3d_DrawingSurfaceObjectAWT_getDrawingSurfaceAWT(
+ JNIEnv *env,
+ jobject obj,
+ jobject canvas,
+ jlong awtObj)
+{
+ JAWT *awt = (JAWT*) awtObj;
+ JAWT_DrawingSurface *ds;
+
+ ds = awt->GetDrawingSurface(env, canvas);
+ if (ds == NULL) {
+ fprintf(stderr, "NULL drawing surface\n");
+ return 0;
+ }
+ return (jlong)ds;
+}
+
+
+JNIEXPORT
+jint JNICALL
+Java_javax_media_j3d_DrawingSurfaceObjectAWT_getDrawingSurfaceWindowIdAWT(
+ JNIEnv *env,
+ jobject obj,
+ jobject canvas,
+ jlong dsObj,
+ jlong dsiObj,
+ jlong display,
+ jint screen,
+ jboolean xineramaDisabled)
+{
+ JAWT_DrawingSurface *ds = (JAWT_DrawingSurface*) dsObj;
+ JAWT_DrawingSurfaceInfo *dsi = (JAWT_DrawingSurfaceInfo *) dsiObj;
+ jint window;
+
+#ifdef WIN32
+ JAWT_Win32DrawingSurfaceInfo *wds =
+ (JAWT_Win32DrawingSurfaceInfo*) dsi->platformInfo;
+ window = (jint)wds->hdc;
+#endif /* WIN32 */
+
+#ifdef SOLARIS
+ JAWT_X11DrawingSurfaceInfo *xds =
+ (JAWT_X11DrawingSurfaceInfo*) dsi->platformInfo;
+ window = (jint)xds->drawable;
+
+ if (xineramaDisabled) {
+ XineramaInfo xineramaInfo;
+
+#ifdef VERBOSE
+ fprintf(stderr, "getDrawingSurfaceWindowIdAWT: Xinerama disabled\n");
+#endif /* VERBOSE */
+
+ /*
+ * The existence of the weak symbol XDgaGetXineramaInfo is checked in
+ * the native MasterControl.initializeJ3D(); execution will not get
+ * here if it is unbound.
+ */
+ if (XDgaGetXineramaInfo((Display *)display,
+ xds->drawable, &xineramaInfo)) {
+
+ /* return Xinerama subwid instead of primary Xinerama wid */
+ window = (jint)xineramaInfo.subs[screen].wid;
+
+#ifdef VERBOSE
+ fprintf(stderr,
+ " subwid for display %d screen %d window %d: %d\n",
+ (Display *)display, screen, xds->drawable, window);
+#endif /* VERBOSE */
+ }
+ else {
+ window = (jint)xds->drawable;
+ fprintf(stderr, "Get Xinerama subwid, screen %d failed\n", screen);
+ }
+ }
+#endif /* SOLARIS */
+
+#ifdef __linux__
+ JAWT_X11DrawingSurfaceInfo *xds =
+ (JAWT_X11DrawingSurfaceInfo*) dsi->platformInfo;
+ window = (jint)xds->drawable;
+#endif /* __linux__ */
+
+ /*
+ * Don't free DrawingSurfaceInfo here, otherwise
+ * HDC will free in windows JDK1.4 and window
+ * is invalid.
+ */
+ ds->env = env;
+ ds->Unlock(ds);
+
+ return window;
+}
+
+
+
+JNIEXPORT
+jlong JNICALL
+Java_javax_media_j3d_DrawingSurfaceObjectAWT_getDrawingSurfaceInfo(
+ JNIEnv *env,
+ jobject obj,
+ jlong dsObj)
+{
+ JAWT_DrawingSurface *ds = (JAWT_DrawingSurface*) dsObj;
+ JAWT_DrawingSurfaceInfo *dsi;
+ jint lock;
+
+ ds->env = env;
+ lock = ds->Lock(ds);
+ if ((lock & JAWT_LOCK_ERROR) != 0) {
+ fprintf(stderr, "Error locking surface\n");
+ return 0;
+ }
+
+ dsi = ds->GetDrawingSurfaceInfo(ds);
+
+ if (dsi == NULL) {
+ fprintf(stderr, "Error GetDrawingSurfaceInfo\n");
+ ds->Unlock(ds);
+ return 0;
+ }
+ return (jlong)dsi;
+}
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_DrawingSurfaceObjectAWT_lockAWT(
+ JNIEnv *env,
+ jobject obj,
+ jlong drawingSurface)
+{
+ JAWT_DrawingSurface *ds = (JAWT_DrawingSurface*)drawingSurface;
+ jint lock;
+
+ ds->env = env;
+ lock = ds->Lock(ds);
+
+ if ((lock & JAWT_LOCK_ERROR) != 0) {
+ return JNI_FALSE;
+ } else if ((lock & JAWT_LOCK_SURFACE_CHANGED) != 0) {
+ ds->Unlock(ds);
+ return JNI_FALSE;
+ } else {
+ return JNI_TRUE;
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_DrawingSurfaceObjectAWT_unlockAWT(
+ JNIEnv *env,
+ jobject obj,
+ jlong drawingSurface)
+{
+ JAWT_DrawingSurface *ds = (JAWT_DrawingSurface*)drawingSurface;
+ ds->env = env;
+ ds->Unlock(ds);
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_DrawingSurfaceObjectAWT_lockGlobal(
+ JNIEnv *env,
+ jclass obj,
+ jlong awt)
+{
+ ((JAWT *) awt)->Lock(env);
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_DrawingSurfaceObjectAWT_unlockGlobal(
+ JNIEnv *env,
+ jclass obj,
+ jlong awt)
+{
+ ((JAWT *) awt)->Unlock(env);
+}
+
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_DrawingSurfaceObjectAWT_freeResource(
+ JNIEnv *env,
+ jobject obj,
+ jlong awtObj,
+ jlong drawingSurface,
+ jlong drawingSurfaceInfo)
+{
+ JAWT *awt = (JAWT*) awtObj;
+ JAWT_DrawingSurface *ds = (JAWT_DrawingSurface*)drawingSurface;
+ JAWT_DrawingSurfaceInfo *dsi = (JAWT_DrawingSurfaceInfo *) drawingSurfaceInfo;
+
+ ds->env = env;
+ ds->FreeDrawingSurfaceInfo(dsi);
+ awt->FreeDrawingSurface(ds);
+}
+
+
+
diff --git a/src/native/ogl/GeometryArrayRetained.c b/src/native/ogl/GeometryArrayRetained.c
new file mode 100644
index 0000000..ccc0a31
--- /dev/null
+++ b/src/native/ogl/GeometryArrayRetained.c
@@ -0,0 +1,3599 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include <stdio.h>
+#include <jni.h>
+
+#include "gldefs.h"
+
+#ifdef WIN32
+#include <wingdi.h>
+
+#endif /* WIN32 */
+
+#ifdef DEBUG
+/* Uncomment the following for VERBOSE debug messages */
+/* #define VERBOSE */
+#endif /* DEBUG */
+
+
+static float EPS = 0.0001f;
+
+#define INTERLEAVEDARRAYS_TEST() \
+ useInterleavedArrays = 1; \
+ switch (vformat) { \
+ case GA_COORDINATES : \
+ iaFormat = GL_V3F; break; \
+ case (GA_COORDINATES | GA_NORMALS) : \
+ iaFormat = GL_N3F_V3F; break; \
+ case (GA_COORDINATES | GA_TEXTURE_COORDINATE_2) :\
+ iaFormat = GL_T2F_V3F; break; \
+ case (GA_COORDINATES | GA_NORMALS | GA_COLOR) : \
+ case (GA_COORDINATES | GA_NORMALS | GA_COLOR | GA_WITH_ALPHA) :\
+ iaFormat = GL_C4F_N3F_V3F; break; \
+ case (GA_COORDINATES | GA_NORMALS | GA_TEXTURE_COORDINATE_2) :\
+ iaFormat = GL_T2F_N3F_V3F; break; \
+ case (GA_COORDINATES | GA_NORMALS | GA_COLOR | GA_TEXTURE_COORDINATE_2):\
+ case (GA_COORDINATES | GA_NORMALS | GA_COLOR | GA_WITH_ALPHA | GA_TEXTURE_COORDINATE_2):\
+ iaFormat = GL_T2F_C4F_N3F_V3F; break;\
+ default: \
+ useInterleavedArrays = 0; break; \
+ }
+
+
+
+/* This hardcoded value should be fixed for 1.3 */
+#define NUM_TEXTURE_UNITS 64
+
+
+extern void enableTexCoordPointer(GraphicsContextPropertiesInfo *, int, int,
+ int, int, void *);
+extern void disableTexCoordPointer(GraphicsContextPropertiesInfo *, int);
+
+/*
+ * texUnitIndex < 0 implies send all texture unit state info in one pass
+ * texUnitIndex >= 0 implies one texture unit state info in one pass using
+ * the underlying texture unit 0
+ */
+void
+executeTexture(int texUnitIndex, int texCoordSetMapLen,
+ int texSize, int bstride, int texCoordoff,
+ jint texCoordSetMapOffset[],
+ jint numActiveTexUnit, jint texUnitStateMap[],
+ float verts[], jlong ctxInfo)
+{
+ int i;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+ int tus; /* texture unit state index */
+
+ if (texUnitIndex < 0) {
+ if(ctxProperties->arb_multitexture) {
+
+ for (i = 0; i < numActiveTexUnit; i++) {
+ /*
+ * NULL texUnitStateMap means
+ * one to one mapping from texture unit to
+ * texture unit state. It is NULL in build display list,
+ * when the mapping is according to the texCoordSetMap
+ */
+ if (texUnitStateMap != NULL) {
+ tus = texUnitStateMap[i];
+ } else {
+ tus = i;
+ }
+ /*
+ * it's possible that texture unit state index (tus)
+ * is greater than the texCoordSetMapOffsetLen, in this
+ * case, just disable TexCoordPointer.
+ */
+ if ((tus < texCoordSetMapLen) &&
+ (texCoordSetMapOffset[tus] != -1)) {
+ enableTexCoordPointer(ctxProperties, i,
+ texSize, GL_FLOAT, bstride,
+ &(verts[texCoordoff + texCoordSetMapOffset[tus]]));
+
+ } else {
+ disableTexCoordPointer(ctxProperties, i);
+ }
+ }
+ }/* GL_ARB_multitexture */
+
+ else {
+
+#ifdef VERBOSE
+ if (numActiveTexUnit > 1) {
+ fprintf(stderr, "No multi-texture support\n");
+ }
+#endif /* VERBOSE */
+
+ if (texUnitStateMap != NULL) {
+ tus = texUnitStateMap[0];
+ } else {
+ tus = 0;
+ }
+ if (texCoordSetMapOffset[tus] != -1) {
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(texSize, GL_FLOAT, bstride,
+ &(verts[texCoordoff + texCoordSetMapOffset[tus]]));
+
+ } else {
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+ } else {
+ if ((texUnitIndex < texCoordSetMapLen) &&
+ (texCoordSetMapOffset[texUnitIndex] != -1)) {
+ enableTexCoordPointer(ctxProperties, 0,
+ texSize, GL_FLOAT, bstride,
+ &(verts[texCoordoff + texCoordSetMapOffset[texUnitIndex]]));
+ } else {
+ disableTexCoordPointer(ctxProperties, 0);
+ }
+ }
+}
+
+
+/*
+ * glLockArrays() is invoked only for indexed geometry, and the
+ * vertexCount is guarenteed to be >= 0.
+ */
+static void
+lockArray(GraphicsContextPropertiesInfo *ctxProperties,
+ int vertexCount) {
+
+ if (ctxProperties->compiled_vertex_array_ext) {
+ ctxProperties->glLockArraysEXT(0, vertexCount);
+ }
+}
+
+static void
+unlockArray(GraphicsContextPropertiesInfo *ctxProperties)
+{
+ if (ctxProperties->compiled_vertex_array_ext) {
+ ctxProperties->glUnlockArraysEXT();
+ }
+}
+
+
+void
+executeGeometryArray(JNIEnv *env,
+ jobject obj, jlong ctxInfo, jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean useAlpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint startVIndex,
+ jint vcount, jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMap, jint texCoordSetMapLen,
+ jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray texUnitStateMapArray,
+ jfloatArray varray, jobject varrayBuffer, jfloatArray carray,
+ jint texUnitIndex, jint cDirty)
+{
+ jclass geo_class;
+ JNIEnv table;
+
+ jfloat *verts, *startVertex, *clrs, *startClrs;
+ jint i;
+ size_t bstride, cbstride;
+ jsize strip_len;
+ GLsizei *strips;
+ GLenum iaFormat;
+ int useInterleavedArrays;
+ int primType;
+ jint stride, coordoff, normoff, coloroff, texCoordoff;
+ int alphaNeedsUpdate = 0; /* used so we can get alpha data from */
+ /* JNI before using it so we can use */
+ /* GetPrimitiveArrayCritical */
+ jfieldID strip_field;
+ jarray sarray;
+
+ jint texSize, texStride, *texCoordSetMapOffset = NULL,
+ *texUnitStateMap = NULL;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ jarray start_array;
+ jfieldID start_field;
+ GLint *start;
+ int cstride = 0;
+ table = *env;
+
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+
+ /* This matches the code in GeometryArrayRetained.java */
+ stride = coordoff = normoff = coloroff = texCoordoff = 0;
+ if ((vformat & GA_COORDINATES) != 0) {
+ stride += 3;
+ }
+ if ((vformat & GA_NORMALS) != 0) {
+ stride += 3;
+ coordoff += 3;
+ }
+ if ((vformat & GA_COLOR) != 0) {
+ if ((vformat & GA_WITH_ALPHA) != 0 ) {
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ }
+ else { /* Handle the case of executeInterleaved 3f */
+ stride += 3;
+ normoff += 3;
+ coordoff += 3;
+ }
+ }
+ if ((vformat & GA_TEXTURE_COORDINATE) != 0) {
+ if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) {
+ texSize = 2;
+ texStride = 2 * texCoordSetCount;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) {
+ texSize = 3;
+ texStride = 3 * texCoordSetCount;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) {
+ texSize = 4;
+ texStride = 4 * texCoordSetCount;
+ }
+ stride += texStride;
+ normoff += texStride;
+ coloroff += texStride;
+ coordoff += texStride;
+ }
+
+ bstride = stride*sizeof(float);
+
+ /*
+ * Call other JNI functions before entering Critical region
+ * i.e., GetPrimitiveArrayCritical
+ */
+
+ if (geo_type == GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_LINE_STRIP_SET) {
+
+ strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripVertexCounts", "[I");
+ sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field);
+ strip_len = (jsize)(*(table->GetArrayLength))(env, sarray);
+
+
+ start_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripStartOffsetIndices", "[I");
+ start_array = (jarray)(*(table->GetObjectField))(env, geo,
+ start_field);
+ }
+
+ /* begin critical region */
+ if(varray != NULL) {
+ verts = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, varray, NULL);
+ if(verts == NULL)
+ return;
+ }
+ else if(varrayBuffer != NULL) {
+ verts = (jfloat *) (*(table->GetDirectBufferAddress))(env, varrayBuffer );
+ if(verts == NULL)
+ return;
+ }
+
+ /* using byRef interleaved array and has a separate pointer, then .. */
+ cstride = stride;
+ if (carray != NULL) {
+ clrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, carray, NULL);
+ cstride = 4;
+
+ }
+ else {
+ clrs = &(verts[coloroff]);
+ }
+
+
+ cbstride = cstride * sizeof(float);
+ if (texCoordSetMapLen >0) {
+ texCoordSetMapOffset = (jint *) (*(table->GetPrimitiveArrayCritical))(env, texUnitOffset, NULL);
+ }
+
+ if (texUnitStateMapArray != NULL) {
+ texUnitStateMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env, texUnitStateMapArray, NULL);
+ }
+
+ /* Enable normalize for non-uniform scale (which rescale can't handle) */
+ if (ctxProperties->rescale_normal_ext && isNonUniformScale) {
+ glEnable(GL_NORMALIZE);
+ }
+
+
+ startVertex = verts + (stride * startVIndex);
+ startClrs = clrs + (cstride * startVIndex);
+
+ /*** Handle non-indexed strip GeometryArray first *******/
+ if (geo_type == GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_LINE_STRIP_SET) {
+
+
+ strips = (GLsizei *) (*(table->GetPrimitiveArrayCritical))(env, sarray,
+ NULL);
+
+ if ((ignoreVertexColors == JNI_TRUE) || (carray != NULL) ||
+ ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = 0;
+ } else {
+ INTERLEAVEDARRAYS_TEST()
+ }
+ if (useInterleavedArrays) {
+ glInterleavedArrays(iaFormat, bstride, startVertex);
+ } else {
+ if (vformat & GA_NORMALS) {
+ glNormalPointer(GL_FLOAT, bstride, &(startVertex[normoff]));
+ }
+ if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) {
+ if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) {
+ glColorPointer(4, GL_FLOAT, cbstride, startClrs);
+ } else {
+ /*
+ for (i = 0; i < vcount; i++) {
+ fprintf(stderr, "r = %f, g = %f, b = %f\n", verts[i*bstride +coloroff], verts[i*bstride +coloroff+1],verts[i*bstride +coloroff+2]);
+ }
+ */
+ glColorPointer(3, GL_FLOAT, cbstride, startClrs);
+ }
+ }
+ if (vformat & GA_COORDINATES) {
+ /*
+ for (i = 0; i < vcount; i++) {
+ fprintf(stderr, "x = %f, y = %f, z = %f\n", verts[i*bstride +coordoff], verts[i*bstride +coordoff+1],verts[i*bstride +coordoff+2]);
+ }
+ */
+ glVertexPointer(3, GL_FLOAT, bstride, &(startVertex[coordoff]));
+ }
+
+ if (vformat & GA_TEXTURE_COORDINATE) {
+
+ executeTexture(texUnitIndex, texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetMapOffset,
+ numActiveTexUnit, texUnitStateMap,
+ startVertex, ctxInfo);
+ }
+ }
+
+ switch (geo_type) {
+ case GEO_TYPE_TRI_STRIP_SET :
+ primType = GL_TRIANGLE_STRIP;
+ break;
+ case GEO_TYPE_TRI_FAN_SET :
+ primType = GL_TRIANGLE_FAN;
+ break;
+ case GEO_TYPE_LINE_STRIP_SET :
+ primType = GL_LINE_STRIP;
+ break;
+ }
+ /*
+ fprintf(stderr, "strip_len = %d\n",strip_len);
+ for (i=0; i < strip_len;i++) {
+ fprintf(stderr, "strips[i] = %d\n",strips[i]);
+ }
+ */
+
+
+ start = (GLint *)(*(table->GetPrimitiveArrayCritical))(env,
+ start_array, NULL);
+
+ if (ctxProperties->multi_draw_arrays_ext || ctxProperties->multi_draw_arrays_sun) {
+ /*
+ * Only used in the "by_copy case, so its ok to
+ * to temporarily modify
+ */
+
+ ctxProperties->glMultiDrawArraysEXT(primType, start, strips, strip_len);
+ } else {
+ for (i=0; i < strip_len;i++) {
+ glDrawArrays(primType, start[i], strips[i]);
+ }
+ }
+ (*(table->ReleasePrimitiveArrayCritical))(env, start_array, start,
+ 0);
+ (*(table->ReleasePrimitiveArrayCritical))(env, sarray, strips, 0);
+ }
+ /******* Handle non-indexed non-striped GeometryArray now *****/
+ else if ((geo_type == GEO_TYPE_QUAD_SET) ||
+ (geo_type == GEO_TYPE_TRI_SET) ||
+ (geo_type == GEO_TYPE_POINT_SET) ||
+ (geo_type == GEO_TYPE_LINE_SET))
+ {
+
+
+ if ((ignoreVertexColors == JNI_TRUE) || (carray != NULL) ||
+ ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = 0;
+ } else {
+ INTERLEAVEDARRAYS_TEST()
+ }
+
+ if (useInterleavedArrays) {
+ glInterleavedArrays(iaFormat, bstride, startVertex);
+ } else {
+ if (vformat & GA_NORMALS) {
+ glNormalPointer(GL_FLOAT, bstride, &(startVertex[normoff]));
+ }
+ if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) {
+ if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) {
+
+ glColorPointer(4, GL_FLOAT, cbstride, startClrs);
+ } else {
+ glColorPointer(3, GL_FLOAT, cbstride, startClrs);
+ }
+ }
+ if (vformat & GA_COORDINATES) {
+ glVertexPointer(3, GL_FLOAT, bstride, &(startVertex[coordoff]));
+ }
+
+ if (vformat & GA_TEXTURE_COORDINATE) {
+
+ executeTexture(texUnitIndex, texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetMapOffset,
+ numActiveTexUnit, texUnitStateMap,
+ startVertex, ctxInfo);
+ }
+ }
+ switch (geo_type){
+ case GEO_TYPE_QUAD_SET : glDrawArrays(GL_QUADS, 0, vcount);break;
+ case GEO_TYPE_TRI_SET : glDrawArrays(GL_TRIANGLES, 0, vcount);break;
+ case GEO_TYPE_POINT_SET : glDrawArrays(GL_POINTS, 0, vcount);break;
+ case GEO_TYPE_LINE_SET: glDrawArrays(GL_LINES, 0, vcount);break;
+ }
+ }
+ /* clean up if we turned on normalize */
+
+ if (ctxProperties->rescale_normal_ext && isNonUniformScale) {
+ glDisable(GL_NORMALIZE);
+ }
+
+ if (carray != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, carray, clrs, 0);
+
+ if (texCoordSetMapLen > 0)
+ (*(table->ReleasePrimitiveArrayCritical))(env, texUnitOffset,
+ texCoordSetMapOffset, 0);
+
+ if (texUnitStateMap != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, texUnitStateMapArray,
+ texUnitStateMap, 0);
+ if(varray != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, varray, verts, 0);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_execute(JNIEnv *env,
+ jobject obj, jlong ctxInfo, jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean useAlpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint startVIndex,
+ jint vcount, jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMap, jint texCoordSetMapLen,
+ jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray texUnitStateMapArray,
+ jfloatArray varray, jfloatArray carray,
+ jint texUnitIndex, jint cDirty) {
+
+
+ /* call executeGeometryArray */
+ executeGeometryArray(env, obj, ctxInfo, geo, geo_type, isNonUniformScale, useAlpha,
+ multiScreen, ignoreVertexColors, startVIndex, vcount, vformat,
+ texCoordSetCount, texCoordSetMap, texCoordSetMapLen,
+ texUnitOffset, numActiveTexUnit, texUnitStateMapArray,
+ varray, NULL, carray, texUnitIndex, cDirty);
+
+}
+
+/* interleaved data with nio buffer as data format */
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeInterleavedBuffer(JNIEnv *env,
+ jobject obj, jlong ctxInfo, jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean useAlpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint startVIndex,
+ jint vcount, jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMap, jint texCoordSetMapLen,
+ jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray texUnitStateMapArray,
+ jobject varray, jfloatArray carray,
+ jint texUnitIndex, jint cDirty) {
+
+ /* call executeGeometryArray */
+ executeGeometryArray(env, obj, ctxInfo, geo, geo_type, isNonUniformScale, useAlpha,
+ multiScreen, ignoreVertexColors, startVIndex, vcount, vformat,
+ texCoordSetCount, texCoordSetMap, texCoordSetMapLen,
+ texUnitOffset, numActiveTexUnit, texUnitStateMapArray,
+ NULL, varray, carray, texUnitIndex, cDirty);
+
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGA(JNIEnv *env,
+ jobject obj, jlong ctxInfo, jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale, jboolean updateAlpha, float alpha,
+ jboolean ignoreVertexColors,
+ jint startVIndex,
+ jint vcount, jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMapArray,
+ jint texCoordSetMapLen,
+ jintArray texUnitOffset,
+ jdoubleArray xform, jdoubleArray nxform,
+ jfloatArray varray)
+{
+ jclass geo_class;
+ JNIEnv table;
+ jboolean useAlpha = JNI_FALSE;
+
+ jfloat *verts;
+ jint i, j;
+ size_t bstride;
+ jint texStride, *texCoordSetMapOffset;
+ GLsizei *strips;
+ jfloat vertex[3];
+ jfloat normal[3];
+ jfloat w, winv;
+
+ jsize strip_len;
+ int primType;
+ jint stride, coordoff, normoff, coloroff, texCoordoff;
+ jfieldID strip_field;
+ jarray sarray;
+ jint initialOffset = 0;
+ jint saveVformat = 0;
+ float color[4];
+ jdouble *xform_ptr = NULL;
+ jdouble *nxform_ptr = NULL;
+
+
+ jint k;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ table = *env;
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+ /* This matches the code in GeometryArrayRetained.java */
+ stride = coordoff = normoff = coloroff = texCoordoff = 0;
+ if ((vformat & GA_COORDINATES) != 0) {
+ stride += 3;
+ }
+ if ((vformat & GA_NORMALS) != 0) {
+ stride += 3;
+ coordoff += 3;
+ }
+
+ if ((vformat & GA_COLOR) != 0) {
+ if ((vformat & GA_BY_REFERENCE) != 0) {
+ if (vformat & GA_WITH_ALPHA) {
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ }
+ else {
+ stride += 3;
+ normoff += 3;
+ coordoff += 3;
+ }
+ }
+ else {
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ }
+ }
+
+ if ((vformat & GA_TEXTURE_COORDINATE) != 0) {
+ if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) {
+ texStride = 2 * texCoordSetCount;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) {
+ texStride = 3 * texCoordSetCount;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) {
+ texStride = 4 * texCoordSetCount;
+ }
+ stride += texStride;
+ normoff += texStride;
+ coloroff += texStride;
+ coordoff += texStride;
+ }
+
+ bstride = stride*sizeof(float);
+ /* Start send down from the startVIndex */
+ initialOffset = startVIndex * stride;
+ normoff += initialOffset;
+ coloroff += initialOffset;
+ coordoff += initialOffset;
+ texCoordoff += initialOffset;
+
+ /*
+ * process alpha for geometryArray without alpha
+ */
+ if (updateAlpha == JNI_TRUE && ignoreVertexColors == JNI_FALSE) {
+ useAlpha = JNI_TRUE;
+ }
+
+ /*
+ * call other JNI functions before entering Critical region
+ * i.e., GetPrimitiveArrayCritical
+ */
+ if (geo_type == GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_LINE_STRIP_SET) {
+
+ strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripVertexCounts", "[I");
+ sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field);
+ strip_len = (jsize)(*(table->GetArrayLength))(env, sarray);
+ }
+
+
+ /* begin critical region */
+ verts = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, varray, NULL);
+
+ if (texCoordSetMapLen >0) {
+ texCoordSetMapOffset = (jint *)(*(table->GetPrimitiveArrayCritical))
+ (env, texUnitOffset, NULL);
+ }
+
+
+ /* get the static transform if exists */
+ if (xform != NULL) {
+ xform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))(
+ env, xform, NULL);
+ }
+
+ /* get the static normals transform if exists */
+ if (nxform != NULL) {
+ nxform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))(
+ env, nxform, NULL);
+ }
+
+
+ if (geo_type == GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_LINE_STRIP_SET) {
+
+
+ switch (geo_type) {
+ case GEO_TYPE_TRI_STRIP_SET :
+ primType = GL_TRIANGLE_STRIP;
+ break;
+ case GEO_TYPE_TRI_FAN_SET :
+ primType = GL_TRIANGLE_FAN;
+ break;
+ case GEO_TYPE_LINE_STRIP_SET :
+ primType = GL_LINE_STRIP;
+ break;
+ }
+
+
+ strips = (GLsizei *) (*(table->GetPrimitiveArrayCritical))(env, sarray, NULL);
+ saveVformat = vformat;
+ if (ignoreVertexColors == JNI_TRUE) {
+ vformat &= ~GA_COLOR;
+ }
+ for (i = 0; i < strip_len; i++) {
+ glBegin(primType);
+ for (j = 0; j < strips[i]; j++) {
+ if (vformat & GA_NORMALS) {
+ if (nxform_ptr != NULL) {
+ normal[0] = (float) (nxform_ptr[0] * verts[normoff] +
+ nxform_ptr[1] * verts[normoff+1] +
+ nxform_ptr[2] * verts[normoff+2]);
+ normal[1] = (float ) (nxform_ptr[4] * verts[normoff] +
+ nxform_ptr[5] * verts[normoff+1] +
+ nxform_ptr[6] * verts[normoff+2]);
+ normal[2] = (float) (nxform_ptr[8] * verts[normoff] +
+ nxform_ptr[9] * verts[normoff+1] +
+ nxform_ptr[10] * verts[normoff+2]);
+/*
+printf("orig: < %g %g %g > transformed: < %g %g %g >\n",
+ verts[normoff], verts[normoff+1], verts[normoff+2],
+ normal[0], normal[1], normal[2]);
+*/
+ glNormal3fv(normal);
+ } else {
+ glNormal3fv(&verts[normoff]);
+ }
+ }
+ if (vformat & GA_COLOR) {
+ if (useAlpha ) {
+ color[0] = verts[coloroff];
+ color[1] = verts[coloroff+1];
+ color[2] = verts[coloroff+2];
+ color[3] = verts[coloroff+3] * alpha;
+ glColor4fv(&color[0]);
+ }
+ else {
+ if (vformat & GA_WITH_ALPHA) { /* alpha is present */
+ glColor4fv(&verts[coloroff]);
+ }
+ else {
+ glColor3fv(&verts[coloroff]);
+ }
+ }
+ }
+
+ if (vformat & GA_TEXTURE_COORDINATE) {
+
+ if (texCoordSetMapLen > 0) {
+
+ if (ctxProperties->arb_multitexture) {
+ if (vformat & GA_TEXTURE_COORDINATE_2) {
+ for (k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ ctxProperties->glMultiTexCoord2fvARB(
+ GL_TEXTURE0_ARB + k,
+ &verts[texCoordoff +
+ texCoordSetMapOffset[k]]);
+ }
+ }
+ } else if (vformat & GA_TEXTURE_COORDINATE_3) {
+ for (k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ ctxProperties->glMultiTexCoord3fvARB(
+ GL_TEXTURE0_ARB + k,
+ &verts[texCoordoff +
+ texCoordSetMapOffset[k]]);
+ }
+ }
+ } else {
+ for (k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ ctxProperties->glMultiTexCoord4fvARB(
+ GL_TEXTURE0_ARB + k,
+ &verts[texCoordoff +
+ texCoordSetMapOffset[k]]);
+ }
+ }
+ }
+ }
+ else { /* GL_ARB_multitexture */
+
+ if (texCoordSetMapOffset[0] != -1) {
+ if (vformat & GA_TEXTURE_COORDINATE_2) {
+ glTexCoord2fv(&verts[texCoordoff +
+ texCoordSetMapOffset[0]]);
+ } else if (vformat & GA_TEXTURE_COORDINATE_3) {
+ glTexCoord3fv(&verts[texCoordoff +
+ texCoordSetMapOffset[0]]);
+ } else {
+ glTexCoord4fv(&verts[texCoordoff +
+ texCoordSetMapOffset[0]]);
+ }
+ }
+ } /* GL_ARB_multitexture */
+ }
+ /*
+ * texCoordSetMapLen can't be 0 if texture coordinates
+ * is to be specified
+ */
+ }
+ if (vformat & GA_COORDINATES) {
+ if (xform_ptr != NULL) {
+
+ /*
+ * transform the vertex data with the
+ * static transform
+ */
+ w = (float ) (xform_ptr[12] * verts[coordoff] +
+ xform_ptr[13] * verts[coordoff+1] +
+ xform_ptr[14] * verts[coordoff+2] +
+ xform_ptr[15]);
+ winv = 1.0f/w;
+ vertex[0] = (float ) (xform_ptr[0] * verts[coordoff] +
+ xform_ptr[1] * verts[coordoff+1] +
+ xform_ptr[2] * verts[coordoff+2] +
+ xform_ptr[3]) * winv;
+ vertex[1] = (float) (xform_ptr[4] * verts[coordoff] +
+ xform_ptr[5] * verts[coordoff+1] +
+ xform_ptr[6] * verts[coordoff+2] +
+ xform_ptr[7]) * winv;
+ vertex[2] = (float) (xform_ptr[8] * verts[coordoff] +
+ xform_ptr[9] * verts[coordoff+1] +
+ xform_ptr[10] * verts[coordoff+2] +
+ xform_ptr[11]) * winv;
+/*
+printf("orig: < %g %g %g > transformed: < %g %g %g >\n",
+ verts[coordoff], verts[coordoff+1], verts[coordoff+2],
+ vertex[0], vertex[1], vertex[2]);
+*/
+ glVertex3fv(vertex);
+ } else {
+ glVertex3fv(&verts[coordoff]);
+ }
+ }
+ normoff += stride;
+ coloroff += stride;
+ coordoff += stride;
+ texCoordoff += stride;
+ }
+ glEnd();
+ }
+ /* Restore the vertex format */
+ vformat = saveVformat;
+ (*(table->ReleasePrimitiveArrayCritical))(env, sarray, strips,
+ 0);
+
+ }
+ else if ((geo_type == GEO_TYPE_QUAD_SET) ||
+ (geo_type == GEO_TYPE_TRI_SET) ||
+ (geo_type == GEO_TYPE_POINT_SET) ||
+ (geo_type == GEO_TYPE_LINE_SET)) {
+
+ switch (geo_type) {
+ case GEO_TYPE_QUAD_SET :
+ primType = GL_QUADS;
+ break;
+ case GEO_TYPE_TRI_SET :
+ primType = GL_TRIANGLES;
+ break;
+ case GEO_TYPE_POINT_SET :
+ primType = GL_POINTS;
+ break;
+ case GEO_TYPE_LINE_SET :
+ primType = GL_LINES;
+ break;
+
+ }
+
+ saveVformat = vformat;
+ if (ignoreVertexColors == JNI_TRUE) {
+ vformat &= ~GA_COLOR;
+ }
+ glBegin(primType);
+ for (j = 0; j < vcount; j++) {
+ if (vformat & GA_NORMALS) {
+ if (nxform_ptr != NULL) {
+ normal[0] = (float) (nxform_ptr[0] * verts[normoff] +
+ nxform_ptr[1] * verts[normoff+1] +
+ nxform_ptr[2] * verts[normoff+2]);
+ normal[1] = (float) (nxform_ptr[4] * verts[normoff] +
+ nxform_ptr[5] * verts[normoff+1] +
+ nxform_ptr[6] * verts[normoff+2]);
+ normal[2] = (float) (nxform_ptr[8] * verts[normoff] +
+ nxform_ptr[9] * verts[normoff+1] +
+ nxform_ptr[10] * verts[normoff+2]);
+/*
+printf("orig: < %g %g %g > transformed: < %g %g %g >\n",
+ verts[normoff], verts[normoff+1], verts[normoff+2],
+ normal[0], normal[1], normal[2]);
+*/
+ glNormal3fv(normal);
+ } else {
+ glNormal3fv(&verts[normoff]);
+ }
+ }
+ if (vformat & GA_COLOR) {
+ if (useAlpha ) {
+ if (vformat & GA_WITH_ALPHA) {
+ color[0] = verts[coloroff];
+ color[1] = verts[coloroff+1];
+ color[2] = verts[coloroff+2];
+ color[3] = verts[coloroff+3] * alpha;
+ }
+ else {
+ color[0] = verts[coloroff];
+ color[1] = verts[coloroff+1];
+ color[2] = verts[coloroff+2];
+ color[3] = alpha;
+ }
+ glColor4fv(&color[0]);
+
+ }
+ else {
+ if (vformat & GA_WITH_ALPHA) { /* alpha is present */
+ glColor4fv(&verts[coloroff]);
+ }
+ else {
+ glColor3fv(&verts[coloroff]);
+ }
+ }
+ }
+
+ if (vformat & GA_TEXTURE_COORDINATE) {
+
+ if (texCoordSetMapLen > 0) {
+
+ if(ctxProperties->arb_multitexture) {
+ if (vformat & GA_TEXTURE_COORDINATE_2) {
+ for (k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ ctxProperties->glMultiTexCoord2fvARB(
+ GL_TEXTURE0_ARB + k,
+ &verts[texCoordoff +
+ texCoordSetMapOffset[k]]);
+ }
+ }
+ } else if (vformat & GA_TEXTURE_COORDINATE_3) {
+ for (k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ ctxProperties->glMultiTexCoord3fvARB(
+ GL_TEXTURE0_ARB + k,
+ &verts[texCoordoff +
+ texCoordSetMapOffset[k]]);
+ }
+ }
+ } else {
+ for (k = 0; k < texCoordSetMapLen; k++) {
+ if (texCoordSetMapOffset[k] != -1) {
+ ctxProperties->glMultiTexCoord4fvARB(
+ GL_TEXTURE0_ARB + k,
+ &verts[texCoordoff +
+ texCoordSetMapOffset[k]]);
+ }
+ }
+ }
+ }
+ else { /* GL_ARB_multitexture */
+
+ if (texCoordSetMapOffset[0] != -1) {
+ if (vformat & GA_TEXTURE_COORDINATE_2) {
+ glTexCoord2fv(&verts[texCoordoff +
+ texCoordSetMapOffset[0]]);
+ } else if (vformat & GA_TEXTURE_COORDINATE_3) {
+ glTexCoord3fv(&verts[texCoordoff +
+ texCoordSetMapOffset[0]]);
+ } else {
+ glTexCoord4fv(&verts[texCoordoff +
+ texCoordSetMapOffset[0]]);
+ }
+ }
+ } /* GL_ARB_multitexture */
+ }
+
+ /*
+ * texCoordSetMapLen can't be 0 if texture coordinates
+ * is to be specified
+ */
+ }
+
+ if (vformat & GA_COORDINATES) {
+ if (xform_ptr != NULL) {
+
+ /*
+ * transform the vertex data with the
+ * static transform
+ */
+ w = (float) (xform_ptr[12] * verts[coordoff] +
+ xform_ptr[13] * verts[coordoff+1] +
+ xform_ptr[14] * verts[coordoff+2] +
+ xform_ptr[15]);
+ winv = 1.0f/w;
+ vertex[0] = (float) (xform_ptr[0] * verts[coordoff] +
+ xform_ptr[1] * verts[coordoff+1] +
+ xform_ptr[2] * verts[coordoff+2] +
+ xform_ptr[3]) * winv;
+ vertex[1] = (float) (xform_ptr[4] * verts[coordoff] +
+ xform_ptr[5] * verts[coordoff+1] +
+ xform_ptr[6] * verts[coordoff+2] +
+ xform_ptr[7]) * winv;
+ vertex[2] = (float) (xform_ptr[8] * verts[coordoff] +
+ xform_ptr[9] * verts[coordoff+1] +
+ xform_ptr[10] * verts[coordoff+2] +
+ xform_ptr[11]) * winv;
+/*
+printf("orig: < %g %g %g > transformed: < %g %g %g >\n",
+ verts[coordoff], verts[coordoff+1], verts[coordoff+2],
+ vertex[0], vertex[1], vertex[2]);
+*/
+ glVertex3fv(vertex);
+ } else {
+ glVertex3fv(&verts[coordoff]);
+ }
+ }
+ normoff += stride;
+ coloroff += stride;
+ coordoff += stride;
+ texCoordoff += stride;
+ }
+ glEnd();
+ }
+ /* Restore the vertex format */
+ vformat = saveVformat;
+
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, varray, verts, 0);
+
+ if (texCoordSetMapLen > 0)
+ (*(table->ReleasePrimitiveArrayCritical))(env, texUnitOffset,
+ texCoordSetMapOffset, 0);
+
+ if (xform_ptr != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, xform, xform_ptr, 0);
+
+ if (nxform_ptr != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, nxform, nxform_ptr, 0);
+}
+
+void enableTexCoordPointer(
+ GraphicsContextPropertiesInfo *ctxProperties,
+ int texUnit,
+ int texSize,
+ int texDataType,
+ int stride,
+ void *pointer) {
+
+ if (ctxProperties->arb_multitexture) {
+ ctxProperties->glClientActiveTextureARB(texUnit + GL_TEXTURE0_ARB);
+ }
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(texSize, texDataType, stride, pointer);
+}
+
+
+void disableTexCoordPointer(
+ GraphicsContextPropertiesInfo *ctxProperties,
+ int texUnit) {
+
+ if (ctxProperties->glClientActiveTextureARB != NULL) {
+ ctxProperties->glClientActiveTextureARB(texUnit + GL_TEXTURE0_ARB);
+ }
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+void executeGeometryArrayVA(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint vdefined,
+ jint initialCoordIndex,
+ jfloat* fverts,
+ jdouble* dverts,
+ jint initialColorIndex,
+ jfloat* fclrs,
+ jbyte* bclrs,
+ jint initialNormalIndex,
+ jfloat* norms,
+ jint pass,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jint* texUnitStateMap,
+ jintArray texindices,
+ jint texStride,
+ jfloat** texCoordPointer,
+ jint cdirty,
+ jarray sarray,
+ jsize strip_len,
+ jarray start_array)
+{
+ int primType;
+ JNIEnv table;
+ jint i;
+ GLsizei *strips;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ GLint *start;
+
+ jint coordoff, coloroff, normoff;
+ int texSet;
+ jint *texCoordSetMap;
+ jint* initialTexIndices;
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+ table = *env;
+
+ /* Enable normalize for non-uniform scale (which rescale can't handle) */
+ if (ctxProperties->rescale_normal_ext && isNonUniformScale) {
+ glEnable(GL_NORMALIZE);
+ }
+
+ coordoff = 3 * initialCoordIndex;
+ /* Define the data pointers */
+ if (floatCoordDefined) {
+ glVertexPointer(3, GL_FLOAT, 0, &(fverts[coordoff]));
+ } else if (doubleCoordDefined){
+ glVertexPointer(3, GL_DOUBLE, 0, &(dverts[coordoff]));
+ }
+
+ if (floatColorsDefined) {
+ if (vformat & GA_WITH_ALPHA) {
+ coloroff = 4 * initialColorIndex;
+ glColorPointer(4, GL_FLOAT, 0, &(fclrs[coloroff]));
+ } else {
+ coloroff = 3 * initialColorIndex;
+ glColorPointer(3, GL_FLOAT, 0, &(fclrs[coloroff]));
+ }
+ } else if (byteColorsDefined) {
+ if (vformat & GA_WITH_ALPHA) {
+ coloroff = 4 * initialColorIndex;
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, &(bclrs[coloroff]));
+ } else {
+ coloroff = 3 * initialColorIndex;
+ glColorPointer(3, GL_UNSIGNED_BYTE, 0, &(bclrs[coloroff]));
+ }
+ }
+ if (normalsDefined) {
+ normoff = 3 * initialNormalIndex;
+ glNormalPointer(GL_FLOAT, 0, &(norms[normoff]));
+ }
+
+ if (textureDefined) {
+
+ int j = 0, tus = 0;
+ float *ptexCoords;
+
+ initialTexIndices = (jint *) (*(table->GetPrimitiveArrayCritical))(env,texindices, NULL);
+
+ texCoordSetMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env,tcoordsetmap, NULL);
+ if (pass < 0) {
+ for (i = 0; i < numActiveTexUnit; i++) {
+ tus = texUnitStateMap[i];
+ if ((tus < texCoordMapLength) && (
+ ((texSet=texCoordSetMap[tus]) != -1))) {
+
+ ptexCoords = texCoordPointer[texSet];
+
+ enableTexCoordPointer(ctxProperties, i, texStride,
+ GL_FLOAT, 0,
+ &ptexCoords[texStride * initialTexIndices[texSet]]);
+
+ } else {
+ disableTexCoordPointer(ctxProperties, i);
+ }
+ }
+ }
+ else {
+ texUnitStateMap = NULL;
+ texSet = texCoordSetMap[pass];
+ if (texSet != -1) {
+ ptexCoords = texCoordPointer[texSet];
+ enableTexCoordPointer(ctxProperties, 0, texStride,
+ GL_FLOAT, 0,
+ &ptexCoords[texStride * initialTexIndices[texSet]]);
+
+ /*
+ * in a non-multitexturing case, only the first texture
+ * unit is used, it will be the core library responsibility
+ * to disable all texture units before enabling "the"
+ * texture unit for multi-pass purpose
+ */
+ } else {
+ disableTexCoordPointer(ctxProperties, 0);
+ }
+ }
+ }
+
+ if (geo_type == GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_LINE_STRIP_SET) {
+
+ strips = (GLint *) (*(table->GetPrimitiveArrayCritical))(env, sarray,
+ NULL);
+
+ switch (geo_type) {
+ case GEO_TYPE_TRI_STRIP_SET :
+ primType = GL_TRIANGLE_STRIP;
+ break;
+ case GEO_TYPE_TRI_FAN_SET :
+ primType = GL_TRIANGLE_FAN;
+ break;
+ case GEO_TYPE_LINE_STRIP_SET :
+ primType = GL_LINE_STRIP;
+ break;
+ }
+
+ start = (GLint *)(*(table->GetPrimitiveArrayCritical))(env,
+ start_array, NULL);
+ if (ctxProperties->multi_draw_arrays_ext || ctxProperties->multi_draw_arrays_sun) {
+
+ /*
+ fprintf(stderr, "strip_len = %d \n",strip_len);
+ for (i=0; i < strip_len;i++) {
+ fprintf(stderr, "numVertices = %d\n",strips[i]);
+ fprintf(stderr, "start = %d \n",start[i]);
+ }
+ */
+ ctxProperties->glMultiDrawArraysEXT(primType, start, strips, strip_len);
+ } else {
+ for (i=0; i < strip_len;i++) {
+ glDrawArrays(primType, start[i], strips[i]);
+ }
+ }
+ (*(table->ReleasePrimitiveArrayCritical))(env, start_array, start,
+ 0);
+ (*(table->ReleasePrimitiveArrayCritical))(env, sarray, strips, 0);
+ }
+ else {
+ switch (geo_type){
+ case GEO_TYPE_QUAD_SET : glDrawArrays(GL_QUADS, 0, vcount);break;
+ case GEO_TYPE_TRI_SET : glDrawArrays(GL_TRIANGLES, 0, vcount);break;
+ case GEO_TYPE_POINT_SET : glDrawArrays(GL_POINTS, 0, vcount);break;
+ case GEO_TYPE_LINE_SET: glDrawArrays(GL_LINES, 0, vcount);break;
+ }
+ }
+ /* clean up if we turned on normalize */
+ if (ctxProperties->rescale_normal_ext && isNonUniformScale) {
+ glDisable(GL_NORMALIZE);
+ }
+
+
+ if (textureDefined) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, tcoordsetmap, texCoordSetMap, 0);
+ (*(table->ReleasePrimitiveArrayCritical))(env, texindices, initialTexIndices, 0);
+ }
+}
+
+/* execute geometry array with java array format */
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeVA(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint vdefined,
+ jint initialCoordIndex,
+ jfloatArray vfcoords,
+ jdoubleArray vdcoords,
+ jint initialColorIndex,
+ jfloatArray cfdata,
+ jbyteArray cbdata,
+ jint initialNormalIndex,
+ jfloatArray ndata,
+ jint pass,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jintArray texindices,
+ jint texStride,
+ jobjectArray texCoords,
+ jint cdirty)
+{
+
+ jfieldID strip_field;
+ jarray sarray;
+ jsize strip_len;
+ jclass geo_class;
+
+ jarray start_array;
+ jfieldID start_field;
+
+ JNIEnv table = *env;
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL;
+ jbyte *bclrs = NULL;
+ jfloat *fclrs = NULL, *norms = NULL;
+ jfloat* texCoordPointer[NUM_TEXTURE_UNITS];
+ jarray texobjs[NUM_TEXTURE_UNITS];
+ jint* texUnitStateMap = NULL;
+ int i;
+
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (*(table->GetObjectArrayElement))(env, texCoords, i);
+ }
+ }
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+ if (geo_type == GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_LINE_STRIP_SET) {
+
+ strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripVertexCounts", "[I");
+ sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field);
+ strip_len = (jsize)(*(table->GetArrayLength))(env, sarray);
+
+ start_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripStartOffsetIndices", "[I");
+ start_array = (jarray)(*(table->GetObjectField))(env, geo,
+ start_field);
+ }
+
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texobjs[i] != NULL)
+ texCoordPointer[i] = (jfloat*)(*(table->GetPrimitiveArrayCritical))(env,texobjs[i], NULL);
+ else
+ texCoordPointer[i] = NULL;
+ }
+ if (pass < 0) {
+ texUnitStateMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env,tunitstatemap, NULL);
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ fverts= (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, vfcoords, NULL);
+ } else if (doubleCoordDefined) {
+ dverts= (jdouble *) (*(table->GetPrimitiveArrayCritical))(env, vdcoords, NULL);
+ }
+
+ /* get color array */
+ if (floatColorsDefined) {
+ fclrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, cfdata, NULL);
+ } else if (byteColorsDefined) {
+ bclrs = (jbyte *) (*(table->GetPrimitiveArrayCritical))(env, cbdata, NULL);
+ }
+
+ /* get normal array */
+ if (normalsDefined) {
+ norms = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env,ndata, NULL);
+ }
+
+ executeGeometryArrayVA(env, obj, ctxInfo, geo, geo_type,
+ isNonUniformScale, multiScreen, ignoreVertexColors,
+ vcount, vformat, vdefined, initialCoordIndex,
+ fverts, dverts, initialColorIndex,
+ fclrs, bclrs, initialNormalIndex,
+ norms, pass, texCoordMapLength,
+ tcoordsetmap,numActiveTexUnit, texUnitStateMap,
+ texindices,texStride,texCoordPointer,cdirty, sarray, strip_len, start_array);
+
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texCoordPointer[i] != NULL) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, texobjs[i], texCoordPointer[i], 0);
+ }
+ }
+ if (texUnitStateMap != NULL) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, tunitstatemap, texUnitStateMap, 0);
+ }
+ }
+
+ if (normalsDefined) {
+ (*env)->ReleasePrimitiveArrayCritical(env, ndata, norms, 0);
+ }
+
+
+ if (floatColorsDefined) {
+ (*env)->ReleasePrimitiveArrayCritical(env, cfdata, fclrs, 0);
+ }
+ else if (byteColorsDefined) {
+ (*env)->ReleasePrimitiveArrayCritical(env, cbdata, bclrs, 0);
+ }
+
+
+ if (floatCoordDefined) {
+ (*env)->ReleasePrimitiveArrayCritical(env, vfcoords, fverts, 0);
+ }
+ else if (doubleCoordDefined) {
+ (*env)->ReleasePrimitiveArrayCritical(env, vdcoords, dverts, 0);
+ }
+
+}
+
+/* execute geometry array with java array format */
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeVABuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint vdefined,
+ jint initialCoordIndex,
+ jobject vcoords,
+ jint initialColorIndex,
+ jobject cdataBuffer,
+ jfloatArray cfdata,
+ jbyteArray cbdata,
+ jint initialNormalIndex,
+ jobject ndata,
+ jint pass,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jintArray texindices,
+ jint texStride,
+ jobjectArray texCoords,
+ jint cdirty)
+{
+ jfieldID strip_field;
+ jarray sarray;
+ jsize strip_len;
+ jclass geo_class;
+
+ jarray start_array;
+ jfieldID start_field;
+
+ JNIEnv table = *env;
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL ;
+ jbyte *bclrs = NULL;
+ jfloat *fclrs = NULL, *norms = NULL;
+ jfloat* texCoordPointer[NUM_TEXTURE_UNITS];
+ jarray texobjs[NUM_TEXTURE_UNITS];
+ jint* texUnitStateMap = NULL;
+ int i;
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (*(table->GetObjectArrayElement))(env, texCoords, i);
+ }
+ }
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+ if (geo_type == GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_LINE_STRIP_SET) {
+
+ strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripVertexCounts", "[I");
+ sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field);
+ strip_len = (jsize)(*(table->GetArrayLength))(env, sarray);
+
+ start_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripStartOffsetIndices", "[I");
+ start_array = (jarray)(*(table->GetObjectField))(env, geo,
+ start_field);
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ fverts= (jfloat *)(*(table->GetDirectBufferAddress))(env, vcoords );
+ } else if (doubleCoordDefined) {
+ dverts= (jdouble *)(*(table->GetDirectBufferAddress))(env, vcoords );
+ }
+
+ if(fverts == NULL && dverts == NULL) {
+ return;
+ }
+
+
+ /* get color array */
+ if (floatColorsDefined) {
+ if(cfdata != NULL)
+ fclrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, cfdata, NULL);
+ else
+ fclrs = (jfloat *)(*(table->GetDirectBufferAddress))(env, cdataBuffer);
+ }
+ else if (byteColorsDefined) {
+ if(cbdata != NULL)
+ bclrs = (jbyte *) (*(table->GetPrimitiveArrayCritical))(env, cbdata, NULL);
+ else
+ bclrs = (jbyte *)(*(table->GetDirectBufferAddress))(env, cdataBuffer);
+ }
+
+ /* get normal array */
+ if (normalsDefined) {
+ norms = (jfloat *)(*(table->GetDirectBufferAddress))(env, ndata);
+ }
+
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texobjs[i] != NULL)
+ texCoordPointer[i] = (jfloat*)(*(table->GetDirectBufferAddress))(env,texobjs[i]);
+ else
+ texCoordPointer[i] = NULL;
+ }
+ if (pass < 0) {
+ texUnitStateMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env,tunitstatemap, NULL);
+ }
+ }
+
+
+ executeGeometryArrayVA(env, obj, ctxInfo, geo, geo_type,
+ isNonUniformScale, multiScreen, ignoreVertexColors,
+ vcount, vformat, vdefined, initialCoordIndex,
+ fverts, dverts, initialColorIndex,
+ fclrs, bclrs, initialNormalIndex,
+ norms, pass, texCoordMapLength,
+ tcoordsetmap,numActiveTexUnit, texUnitStateMap,
+ texindices,texStride,texCoordPointer,cdirty, sarray, strip_len, start_array);
+
+ if (textureDefined) {
+ if (texUnitStateMap != NULL) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, tunitstatemap, texUnitStateMap, 0);
+ }
+ }
+
+ if(floatColorsDefined && cfdata != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, cfdata, fclrs, 0);
+ else if(byteColorsDefined && cbdata != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, cbdata, bclrs, 0);
+}
+
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_disableGlobalAlpha(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint vformat,
+ jboolean useAlpha,
+ jboolean ignoreVertexColors)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ if(ctxProperties->global_alpha_sun){
+ if (ignoreVertexColors == JNI_FALSE && vformat & 0x04) {
+ if (useAlpha && ctxProperties->global_alpha_sun ) {
+ glDisable(GL_GLOBAL_ALPHA_SUN);
+ }
+ }
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_setVertexFormat(
+ JNIEnv *env,
+ jobject obj,
+ jint vformat,
+ jboolean useAlpha,
+ jboolean ignoreVertexColors,
+ jlong ctxInfo) {
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ /* Enable and disable the appropriate pointers */
+ if (vformat & GA_NORMALS) {
+ glEnableClientState(GL_NORMAL_ARRAY);
+ }
+ else {
+ glDisableClientState(GL_NORMAL_ARRAY);
+ }
+ if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) {
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
+ else {
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ }
+
+ if (ctxProperties->global_alpha_sun) {
+ if (useAlpha) {
+ glEnable(GL_GLOBAL_ALPHA_SUN);
+ }
+ else {
+ glDisable(GL_GLOBAL_ALPHA_SUN);
+ }
+ }
+
+
+ if (vformat & GA_COORDINATES) {
+ glEnableClientState(GL_VERTEX_ARRAY);
+ }
+ else {
+ glDisableClientState(GL_VERTEX_ARRAY);
+ }
+}
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_GeometryArrayRetained_globalAlphaSUN
+ (JNIEnv *env, jobject obj, jlong ctxInfo)
+{
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ if (ctxProperties->global_alpha_sun == 1)
+ return JNI_TRUE ;
+ else
+ return JNI_FALSE ;
+}
+
+
+
+void executeIndexedGeometryArray(JNIEnv *env,
+ jobject obj, jlong ctxInfo, jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean useAlpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint indexCount,
+ jint vertexCount,
+ jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMap, jint texCoordSetMapLen,
+ jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray texUnitStateMapArray,
+ jfloatArray varray, jobject varrayBuffer, jfloatArray carray,
+ jint texUnitIndex, jint cDirty,
+ jintArray indexCoord)
+{
+ jclass geo_class;
+ JNIEnv table;
+
+ jfloat *verts,*clrs;
+ jint *indices;
+ jint i;
+ size_t bstride, cbstride;
+ jsize strip_len;
+ GLsizei *countArray;
+ int offset;
+ GLenum iaFormat;
+ int useInterleavedArrays;
+ int primType;
+ jint stride, coordoff, normoff, coloroff, texCoordoff;
+ int alphaNeedsUpdate = 0; /* used so we can get alpha data from */
+ /* JNI before using it so we can use */
+ /* GetPrimitiveArrayCritical */
+ jfieldID strip_field;
+ jarray sarray;
+ jint* tmpDrawElementsIndices[100];
+
+ jint** multiDrawElementsIndices = NULL;
+ jint allocated = 0;
+
+ jint texSize, texStride, *texCoordSetMapOffset = NULL,
+ *texUnitStateMap = NULL;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ int cstride = 0;
+ table = *env;
+
+ /* fprintf(stderr, "Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometry \n");*/
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+ /* This matches the code in GeometryArrayRetained.java */
+ stride = coordoff = normoff = coloroff = texCoordoff = 0;
+ if ((vformat & GA_COORDINATES) != 0) {
+ stride += 3;
+ }
+ if ((vformat & GA_NORMALS) != 0) {
+ stride += 3;
+ coordoff += 3;
+ }
+ if ((vformat & GA_COLOR) != 0) {
+ if ((vformat & GA_WITH_ALPHA) != 0 ) {
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ }
+ else { /* Handle the case of executeInterleaved 3f */
+ stride += 3;
+ normoff += 3;
+ coordoff += 3;
+ }
+ }
+ if ((vformat & GA_TEXTURE_COORDINATE) != 0) {
+ if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) {
+ texSize = 2;
+ texStride = 2 * texCoordSetCount;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) {
+ texSize = 3;
+ texStride = 3 * texCoordSetCount;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) {
+ texSize = 4;
+ texStride = 4 * texCoordSetCount;
+ }
+ stride += texStride;
+ normoff += texStride;
+ coloroff += texStride;
+ coordoff += texStride;
+ }
+
+ bstride = stride*sizeof(float);
+
+ /*
+ * call other JNI functions before entering Critical region
+ * i.e., GetPrimitiveArrayCritical
+ */
+
+
+ if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+
+ strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripIndexCounts", "[I");
+ sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field);
+ strip_len = (jsize)(*(table->GetArrayLength))(env, sarray);
+
+
+ }
+
+ /* begin critical region */
+ if(varray != NULL)
+ verts = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, varray, NULL);
+ else if(varrayBuffer != NULL)
+ verts = (jfloat *) (*(table->GetDirectBufferAddress))(env, varrayBuffer);
+
+ indices = (jint *) (*(table->GetPrimitiveArrayCritical))(env, indexCoord, NULL);
+
+
+ /* using byRef interleaved array and has a separate pointer, then .. */
+ cstride = stride;
+ if (carray != NULL) {
+ clrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, carray, NULL);
+ cstride = 4;
+
+ }
+ else {
+ clrs = &(verts[coloroff]);
+ }
+ cbstride = cstride * sizeof(float);
+ if (texCoordSetMapLen >0) {
+ texCoordSetMapOffset = (jint *) (*(table->GetPrimitiveArrayCritical))(env, texUnitOffset, NULL);
+ }
+
+ if (texUnitStateMapArray != NULL) {
+ texUnitStateMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env, texUnitStateMapArray, NULL);
+ }
+
+ /* Enable normalize for non-uniform scale (which rescale can't handle) */
+ if (ctxProperties->rescale_normal_ext && isNonUniformScale) {
+ glEnable(GL_NORMALIZE);
+ }
+
+ /*** Handle non-indexed strip GeometryArray first *******/
+ if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+
+
+ countArray = (GLsizei *) (*(table->GetPrimitiveArrayCritical))(env, sarray,
+ NULL);
+
+ if ((ignoreVertexColors == JNI_TRUE) || (carray != NULL) ||
+ ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = 0;
+ } else {
+ INTERLEAVEDARRAYS_TEST()
+ }
+ if (useInterleavedArrays) {
+ glInterleavedArrays(iaFormat, bstride, verts);
+ } else {
+ if (vformat & GA_NORMALS) {
+ glNormalPointer(GL_FLOAT, bstride, &(verts[normoff]));
+ }
+ if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) {
+ if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) {
+ glColorPointer(4, GL_FLOAT, cbstride, clrs);
+ } else {
+ /*
+ for (i = 0; i < 4; i++) {
+ fprintf(stderr, "r = %f, g = %f, b = %f\n", verts[i*stride +coloroff], verts[i*stride +coloroff+1],verts[i*stride +coloroff+2]);
+ }
+ */
+ glColorPointer(3, GL_FLOAT, cbstride, clrs);
+ }
+ }
+ if (vformat & GA_COORDINATES) {
+ /*
+ for (i = 0; i < 4; i++) {
+ fprintf(stderr, "x = %f, y = %f, z = %f\n", verts[i*stride +coordoff], verts[i*stride +coordoff+1],verts[i*stride +coordoff+2]);
+ }
+ */
+ glVertexPointer(3, GL_FLOAT, bstride, &(verts[coordoff]));
+ }
+
+ if (vformat & GA_TEXTURE_COORDINATE) {
+
+/* TODO: texCoordoff == 0 ???*/
+ executeTexture(texUnitIndex, texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetMapOffset,
+ numActiveTexUnit, texUnitStateMap,
+ verts, ctxInfo);
+ }
+ }
+
+ switch (geo_type) {
+ case GEO_TYPE_INDEXED_TRI_STRIP_SET :
+ primType = GL_TRIANGLE_STRIP;
+ break;
+ case GEO_TYPE_INDEXED_TRI_FAN_SET :
+ primType = GL_TRIANGLE_FAN;
+ break;
+ case GEO_TYPE_INDEXED_LINE_STRIP_SET :
+ primType = GL_LINE_STRIP;
+ break;
+ }
+ /*
+ fprintf(stderr, "strip_len = %d\n",strip_len);
+ for (i=0; i < strip_len;i++) {
+ fprintf(stderr, "strips[i] = %d\n",strips[i]);
+ }
+ */
+
+ lockArray(ctxProperties, vertexCount);
+
+ if (ctxProperties->multi_draw_arrays_ext || ctxProperties->multi_draw_arrays_sun) {
+ if (strip_len > 100) {
+ multiDrawElementsIndices = (jint**)malloc(strip_len * sizeof(int*));
+ allocated = 1;
+ }
+ else {
+ multiDrawElementsIndices =(jint**) &tmpDrawElementsIndices;
+ }
+
+ offset = initialIndexIndex;
+ for (i=0; i < strip_len;i++) {
+ multiDrawElementsIndices[i] = &indices[offset];
+ offset += countArray[i];
+ }
+ ctxProperties->glMultiDrawElementsEXT(primType, countArray, GL_UNSIGNED_INT,(const void **)multiDrawElementsIndices, strip_len);
+
+ } else {
+ offset = initialIndexIndex;
+ for (i=0; i < strip_len;i++) {
+
+ glDrawElements(primType, countArray[i], GL_UNSIGNED_INT, &indices[offset]);
+ offset += countArray[i];
+ }
+ }
+ (*(table->ReleasePrimitiveArrayCritical))(env, sarray, countArray, 0);
+ if (allocated) {
+ free(multiDrawElementsIndices);
+ }
+
+ }
+ /******* Handle non-indexed non-striped GeometryArray now *****/
+ else if ((geo_type == GEO_TYPE_INDEXED_QUAD_SET) ||
+ (geo_type == GEO_TYPE_INDEXED_TRI_SET) ||
+ (geo_type == GEO_TYPE_INDEXED_POINT_SET) ||
+ (geo_type == GEO_TYPE_INDEXED_LINE_SET))
+ {
+ if ((ignoreVertexColors == JNI_TRUE) || (carray != NULL) ||
+ ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = 0;
+ } else {
+ INTERLEAVEDARRAYS_TEST()
+ }
+ if (useInterleavedArrays) {
+ glInterleavedArrays(iaFormat, bstride, verts);
+ } else {
+ if (vformat & GA_NORMALS) {
+ glNormalPointer(GL_FLOAT, bstride, &(verts[normoff]));
+ }
+ if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) {
+ if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) {
+
+ glColorPointer(4, GL_FLOAT, cbstride, clrs);
+ } else {
+ glColorPointer(3, GL_FLOAT, cbstride, clrs);
+ }
+ }
+ if (vformat & GA_COORDINATES) {
+ glVertexPointer(3, GL_FLOAT, bstride, &(verts[coordoff]));
+ }
+
+ if (vformat & GA_TEXTURE_COORDINATE) {
+
+/* TODO: texCoordoff == 0 ???*/
+ executeTexture(texUnitIndex, texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetMapOffset,
+ numActiveTexUnit, texUnitStateMap,
+ verts, ctxInfo);
+ }
+ }
+
+
+ lockArray(ctxProperties, vertexCount);
+
+ switch (geo_type){
+ case GEO_TYPE_INDEXED_QUAD_SET : glDrawElements(GL_QUADS,indexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ case GEO_TYPE_INDEXED_TRI_SET : glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ case GEO_TYPE_INDEXED_POINT_SET : glDrawElements(GL_POINTS, indexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ case GEO_TYPE_INDEXED_LINE_SET: glDrawElements(GL_LINES, indexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ }
+ }
+
+ unlockArray(ctxProperties);
+
+ /* clean up if we turned on normalize */
+
+ if (ctxProperties->rescale_normal_ext && isNonUniformScale) {
+ glDisable(GL_NORMALIZE);
+ }
+ if(varray != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, varray, verts, 0);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, indexCoord, indices, 0);
+
+ if (carray != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, carray, clrs, 0);
+
+ if (texCoordSetMapLen > 0)
+ (*(table->ReleasePrimitiveArrayCritical))(env, texUnitOffset,
+ texCoordSetMapOffset, 0);
+
+ if (texUnitStateMap != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, texUnitStateMapArray,
+ texUnitStateMap, 0);
+}
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometry(JNIEnv *env,
+ jobject obj, jlong ctxInfo, jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean useAlpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint indexCount,
+ jint vertexCount,
+ jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMap, jint texCoordSetMapLen,
+ jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray texUnitStateMapArray,
+ jfloatArray varray, jfloatArray carray,
+ jint texUnitIndex, jint cDirty,
+ jintArray indexCoord)
+{
+ executeIndexedGeometryArray(env, obj, ctxInfo, geo, geo_type,
+ isNonUniformScale, useAlpha, multiScreen,
+ ignoreVertexColors,
+ initialIndexIndex,
+ indexCount,
+ vertexCount,
+ vformat,
+ texCoordSetCount,
+ texCoordSetMap, texCoordSetMapLen,
+ texUnitOffset,
+ numActiveTexUnit,
+ texUnitStateMapArray,
+ varray, NULL, carray,
+ texUnitIndex, cDirty,
+ indexCoord);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryBuffer(JNIEnv *env,
+ jobject obj, jlong ctxInfo, jobject geo, jint geo_type,
+ jboolean isNonUniformScale, jboolean useAlpha,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint indexCount,
+ jint vertexCount,
+ jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMap, jint texCoordSetMapLen,
+ jintArray texUnitOffset,
+ jint numActiveTexUnit,
+ jintArray texUnitStateMapArray,
+ jobject varray, jfloatArray carray,
+ jint texUnitIndex, jint cDirty,
+ jintArray indexCoord)
+{
+ executeIndexedGeometryArray(env, obj, ctxInfo, geo, geo_type,
+ isNonUniformScale, useAlpha, multiScreen,
+ ignoreVertexColors,
+ initialIndexIndex,
+ indexCount,
+ vertexCount,
+ vformat,
+ texCoordSetCount,
+ texCoordSetMap, texCoordSetMapLen,
+ texUnitOffset,
+ numActiveTexUnit,
+ texUnitStateMapArray,
+ NULL, varray, carray,
+ texUnitIndex, cDirty,
+ indexCoord);
+}
+
+
+void executeIndexedGeometryArrayVA(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint validIndexCount,
+ jint vertexCount,
+ jint vformat,
+ jint vdefined,
+ jfloat* fverts,
+ jdouble* dverts,
+ jfloat* fclrs,
+ jbyte* bclrs,
+ jfloat* norms,
+ jint pass,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jint texStride,
+ jfloat** texCoordPointer,
+ jint cdirty,
+ jintArray indexCoord,
+ jarray sarray,
+ jsize strip_len)
+ {
+ int primType;
+ JNIEnv table;
+ jint i;
+ jint* tmpDrawElementsIndices[100];
+ jint** multiDrawElementsIndices = NULL;
+ jint allocated = 0;
+ jint *indices;
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ int texSet;
+ jint *texCoordSetMap, *texUnitStateMap;
+ GLsizei *countArray;
+ jint offset = 0;
+ table = *env;
+
+ /* Enable normalize for non-uniform scale (which rescale can't handle) */
+ if (ctxProperties->rescale_normal_ext && isNonUniformScale) {
+ glEnable(GL_NORMALIZE);
+ }
+
+ /* Define the data pointers */
+ if (floatCoordDefined) {
+ glVertexPointer(3, GL_FLOAT, 0, fverts);
+ } else if (doubleCoordDefined){
+ glVertexPointer(3, GL_DOUBLE, 0, dverts);
+ }
+ if (floatColorsDefined) {
+ if (vformat & GA_WITH_ALPHA) {
+ glColorPointer(4, GL_FLOAT, 0, fclrs);
+ } else {
+ glColorPointer(3, GL_FLOAT, 0, fclrs);
+ }
+ } else if (byteColorsDefined) {
+ if (vformat & GA_WITH_ALPHA) {
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, bclrs);
+ } else {
+ glColorPointer(3, GL_UNSIGNED_BYTE, 0, bclrs);
+ }
+ }
+ if (normalsDefined) {
+ glNormalPointer(GL_FLOAT, 0, norms);
+ }
+
+ if (textureDefined) {
+
+ int j = 0, tus = 0;
+ float *ptexCoords;
+
+ texCoordSetMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env,tcoordsetmap, NULL);
+ if (pass < 0) {
+ texUnitStateMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env,tunitstatemap, NULL);
+ for (i = 0; i < numActiveTexUnit; i++) {
+ tus = texUnitStateMap[i];
+ if ((tus < texCoordMapLength) && (
+ ((texSet=texCoordSetMap[tus]) != -1))) {
+
+ ptexCoords = texCoordPointer[texSet];
+
+ enableTexCoordPointer(ctxProperties, i, texStride,
+ GL_FLOAT, 0,
+ ptexCoords);
+
+ } else {
+
+ disableTexCoordPointer(ctxProperties, i);
+ }
+ }
+ }
+ else {
+ texUnitStateMap = NULL;
+ texSet = texCoordSetMap[pass];
+ if (texSet != -1) {
+ ptexCoords = texCoordPointer[texSet];
+ enableTexCoordPointer(ctxProperties, 0, texStride,
+ GL_FLOAT, 0,
+ ptexCoords);
+
+ /*
+ * in a non-multitexturing case, only the first texture
+ * unit is used, it will be the core library responsibility
+ * to disable all texture units before enabling "the"
+ * texture unit for multi-pass purpose
+ */
+ }
+ }
+ }
+ indices = (jint *) (*(table->GetPrimitiveArrayCritical))(env, indexCoord, NULL);
+
+ lockArray(ctxProperties, vertexCount);
+
+ if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+
+ countArray = (GLint *) (*(table->GetPrimitiveArrayCritical))(env, sarray,
+ NULL);
+
+ switch (geo_type) {
+ case GEO_TYPE_INDEXED_TRI_STRIP_SET :
+ primType = GL_TRIANGLE_STRIP;
+ break;
+ case GEO_TYPE_INDEXED_TRI_FAN_SET :
+ primType = GL_TRIANGLE_FAN;
+ break;
+ case GEO_TYPE_INDEXED_LINE_STRIP_SET :
+ primType = GL_LINE_STRIP;
+ break;
+ }
+
+
+
+ if (ctxProperties->multi_draw_arrays_ext || ctxProperties->multi_draw_arrays_sun) {
+ if (strip_len > 100) {
+ multiDrawElementsIndices = (jint**)malloc(strip_len * sizeof(int*));
+ allocated = 1;
+ }
+ else {
+ multiDrawElementsIndices = (jint**)&tmpDrawElementsIndices;
+ }
+
+ offset = initialIndexIndex;
+ for (i=0; i < strip_len;i++) {
+ multiDrawElementsIndices[i] = &indices[offset];
+ offset += countArray[i];
+ }
+ ctxProperties->glMultiDrawElementsEXT(primType, countArray, GL_UNSIGNED_INT,(const void **)multiDrawElementsIndices, strip_len);
+
+ } else {
+ offset = initialIndexIndex;
+ for (i=0; i < strip_len;i++) {
+ glDrawElements(primType, countArray[i], GL_UNSIGNED_INT, &indices[offset]);
+ offset += countArray[i];
+ }
+ }
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, sarray, countArray, 0);
+ if (allocated) {
+ free(multiDrawElementsIndices);
+ }
+ }
+ else {
+ switch (geo_type){
+ case GEO_TYPE_INDEXED_QUAD_SET : glDrawElements(GL_QUADS,validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ case GEO_TYPE_INDEXED_TRI_SET : glDrawElements(GL_TRIANGLES, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ case GEO_TYPE_INDEXED_POINT_SET : glDrawElements(GL_POINTS, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ case GEO_TYPE_INDEXED_LINE_SET: glDrawElements(GL_LINES, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ }
+ }
+
+ unlockArray(ctxProperties);
+
+ /* clean up if we turned on normalize */
+ if (ctxProperties->rescale_normal_ext && isNonUniformScale) {
+ glDisable(GL_NORMALIZE);
+ }
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, indexCoord, indices, 0);
+
+ if (textureDefined) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, tcoordsetmap, texCoordSetMap, 0);
+ if (texUnitStateMap != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, tunitstatemap, texUnitStateMap, 0);
+ }
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryVA(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint validIndexCount,
+ jint vertexCount,
+ jint vformat,
+ jint vdefined,
+ jfloatArray vfcoords,
+ jdoubleArray vdcoords,
+ jfloatArray cfdata,
+ jbyteArray cbdata,
+ jfloatArray ndata,
+ jint pass,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jint texStride,
+ jobjectArray texCoords,
+ jint cdirty,
+ jintArray indexCoord)
+{
+ jfieldID strip_field;
+ jarray sarray;
+ jsize strip_len;
+ JNIEnv table;
+ jint i;
+ jclass geo_class;
+
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL;
+ jbyte *bclrs = NULL;
+ jfloat *fclrs = NULL, *norms = NULL;
+ jfloat* texCoordPointer[NUM_TEXTURE_UNITS];
+ jarray texobjs[NUM_TEXTURE_UNITS];
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+ table = *env;
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (jarray)(*(table->GetObjectArrayElement))(env, texCoords, i);
+ }
+ }
+ if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+
+ strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripIndexCounts", "[I");
+ sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field);
+ strip_len = (jsize)(*(table->GetArrayLength))(env, sarray);
+
+ }
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texobjs[i] != NULL)
+ texCoordPointer[i] = (jfloat*)(*(table->GetPrimitiveArrayCritical))(env,texobjs[i], NULL);
+ else
+ texCoordPointer[i] = NULL;
+
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ fverts= (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, vfcoords, NULL);
+ } else if (doubleCoordDefined) {
+ dverts= (jdouble *) (*(table->GetPrimitiveArrayCritical))(env, vdcoords, NULL);
+ }
+
+ /* get color array */
+ if (floatColorsDefined) {
+ fclrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, cfdata, NULL);
+ } else if (byteColorsDefined) {
+ bclrs = (jbyte *) (*(table->GetPrimitiveArrayCritical))(env, cbdata, NULL);
+ }
+
+ /* get normal array */
+ if (normalsDefined) {
+ norms = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env,ndata, NULL);
+ }
+
+ executeIndexedGeometryArrayVA(env,
+ obj,
+ ctxInfo,
+ geo,
+ geo_type,
+ isNonUniformScale,
+ multiScreen,
+ ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ vertexCount,
+ vformat,
+ vdefined,
+ fverts,
+ dverts,
+ fclrs,
+ bclrs,
+ norms,
+ pass,
+ texCoordMapLength,
+ tcoordsetmap,
+ numActiveTexUnit,
+ tunitstatemap,
+ texStride,
+ texCoordPointer,
+ cdirty,
+ indexCoord,
+ sarray,
+ strip_len);
+
+ if (floatCoordDefined) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, vfcoords, fverts, 0);
+ }
+ else if (doubleCoordDefined) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, vdcoords, dverts, 0);
+ }
+
+ if (floatColorsDefined) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, cfdata, fclrs, 0);
+ }
+ else if (byteColorsDefined) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, cbdata, bclrs, 0);
+ }
+
+ if (normalsDefined) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, ndata, norms, 0);
+ }
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texCoordPointer[i] != NULL) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, texobjs[i], texCoordPointer[i], 0);
+ }
+ }
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryVABuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean multiScreen,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint validIndexCount,
+ jint vertexCount,
+ jint vformat,
+ jint vdefined,
+ jobject vcoords,
+ jobject cdataBuffer,
+ jfloatArray cfdata,
+ jbyteArray cbdata,
+ jobject ndata,
+ jint pass,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jint numActiveTexUnit,
+ jintArray tunitstatemap,
+ jint texStride,
+ jobjectArray texCoords,
+ jint cdirty,
+ jintArray indexCoord)
+{
+ jfieldID strip_field;
+ jarray sarray;
+ jsize strip_len;
+ JNIEnv table;
+ jint i;
+ jclass geo_class;
+
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL;
+ jbyte *bclrs = NULL;
+ jfloat *fclrs = NULL, *norms = NULL;
+ jfloat* texCoordPointer[NUM_TEXTURE_UNITS];
+ jarray texobjs[NUM_TEXTURE_UNITS];
+
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+ table = *env;
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (jarray)(*(table->GetObjectArrayElement))(env, texCoords, i);
+ }
+ }
+ if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+
+ strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripIndexCounts", "[I");
+ sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field);
+ strip_len = (jsize)(*(table->GetArrayLength))(env, sarray);
+
+ }
+ /* get texture arrays */
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texobjs[i] != NULL)
+ texCoordPointer[i] = (jfloat*)(*(table->GetDirectBufferAddress))(env,texobjs[i]);
+ else
+ texCoordPointer[i] = NULL;
+
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ fverts= (jfloat *)(*(table->GetDirectBufferAddress))(env, vcoords );
+ } else if (doubleCoordDefined) {
+ dverts= (jdouble *)(*(table->GetDirectBufferAddress))(env, vcoords );
+ }
+
+ /* get color array */
+ if (floatColorsDefined) {
+ if(cfdata != NULL)
+ fclrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, cfdata, NULL);
+ else
+ fclrs = (jfloat *)(*(table->GetDirectBufferAddress))(env, cdataBuffer);
+ }
+ else if (byteColorsDefined) {
+ if(cbdata != NULL)
+ bclrs = (jbyte *) (*(table->GetPrimitiveArrayCritical))(env, cbdata, NULL);
+ else
+ bclrs = (jbyte *)(*(table->GetDirectBufferAddress))(env, cdataBuffer);
+ }
+
+ /* get normal array */
+ if (normalsDefined) {
+ norms = (jfloat *)(*(table->GetDirectBufferAddress))(env, ndata);
+ }
+
+ executeIndexedGeometryArrayVA(env,
+ obj,
+ ctxInfo,
+ geo,
+ geo_type,
+ isNonUniformScale,
+ multiScreen,
+ ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ vertexCount,
+ vformat,
+ vdefined,
+ fverts,
+ dverts,
+ fclrs,
+ bclrs,
+ norms,
+ pass,
+ texCoordMapLength,
+ tcoordsetmap,
+ numActiveTexUnit,
+ tunitstatemap,
+ texStride,
+ texCoordPointer,
+ cdirty,
+ indexCoord,
+ sarray,
+ strip_len);
+
+ if(floatColorsDefined && cfdata != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, cfdata, fclrs, 0);
+ else if(byteColorsDefined && cbdata != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, cbdata, bclrs, 0);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_buildIndexedGeometry(JNIEnv *env,
+ jobject obj, jlong ctxInfo, jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale, jboolean updateAlpha, float alpha,
+ jboolean ignoreVertexColors,
+ jint initialIndexIndex,
+ jint validIndexCount,
+ jint vertexCount,
+ jint vformat,
+ jint texCoordSetCount,
+ jintArray texCoordSetMapArray,
+ jint texCoordSetMapLen,
+ jintArray texUnitOffset,
+ jdoubleArray xform, jdoubleArray nxform,
+ jfloatArray varray, jintArray indexCoord)
+{
+
+ jclass geo_class;
+ JNIEnv table;
+ jboolean useAlpha = JNI_FALSE;
+
+ jfloat *verts;
+ jint *indices;
+ jint i;
+ size_t bstride;
+ jint texStride, *texCoordSetMapOffset, texSize;
+ GLsizei *countArray;
+ GLenum iaFormat;
+ int useInterleavedArrays;
+ jsize strip_len;
+ int primType;
+ jint stride, coordoff, normoff, coloroff, texCoordoff;
+ jfieldID strip_field;
+ jarray sarray;
+ jdouble *xform_ptr = NULL;
+ jdouble *nxform_ptr = NULL;
+ jfloat *tmpCoordArray = NULL, *tmpNormalArray = NULL;
+ jint* tmpDrawElementsIndices[100];
+
+ jint** multiDrawElementsIndices = NULL;
+ jint allocated = 0;
+ int offset = 0;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ table = *env;
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+ /* This matches the code in GeometryArrayRetained.java */
+ stride = coordoff = normoff = coloroff = texCoordoff = 0;
+ if ((vformat & GA_COORDINATES) != 0) {
+ glEnableClientState(GL_VERTEX_ARRAY);
+ stride += 3;
+ }
+ else {
+ glDisableClientState(GL_VERTEX_ARRAY);
+ }
+ if ((vformat & GA_NORMALS) != 0) {
+ glEnableClientState(GL_NORMAL_ARRAY);
+ stride += 3;
+ coordoff += 3;
+ }
+ else {
+ glDisableClientState(GL_NORMAL_ARRAY);
+ }
+
+ if ((vformat & GA_COLOR) != 0) {
+ glEnableClientState(GL_COLOR_ARRAY);
+ stride += 4;
+ normoff += 4;
+ coordoff += 4;
+ }
+ else {
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+ if ((vformat & GA_TEXTURE_COORDINATE) != 0) {
+ if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) {
+ texSize = 2;
+ texStride = 2 * texCoordSetCount;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) {
+ texSize = 3;
+ texStride = 3 * texCoordSetCount;
+ } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) {
+ texSize = 4;
+ texStride = 4 * texCoordSetCount;
+ }
+ stride += texStride;
+ normoff += texStride;
+ coloroff += texStride;
+ coordoff += texStride;
+ }
+
+ bstride = stride*sizeof(float);
+
+ /*
+ * process alpha for geometryArray without alpha
+ */
+ if (updateAlpha == JNI_TRUE && ignoreVertexColors == JNI_FALSE) {
+ useAlpha = JNI_TRUE;
+ }
+
+ /*
+ * call other JNI functions before entering Critical region
+ * i.e., GetPrimitiveArrayCritical
+ */
+ if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+
+ strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripIndexCounts", "[I");
+ sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field);
+ strip_len = (jsize)(*(table->GetArrayLength))(env, sarray);
+ }
+
+
+
+ /* begin critical region */
+ verts = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, varray, NULL);
+
+ indices = (jint *) (*(table->GetPrimitiveArrayCritical))(env, indexCoord, NULL);
+
+ if (texCoordSetMapLen >0) {
+ texCoordSetMapOffset = (jint *)(*(table->GetPrimitiveArrayCritical))
+ (env, texUnitOffset, NULL);
+ }
+
+
+ /* get the static transform if exists */
+ if (xform != NULL) {
+ xform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))(
+ env, xform, NULL);
+
+ }
+
+
+ /* get the static normals transform if exists */
+ if (nxform != NULL) {
+ nxform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))(
+ env, nxform, NULL);
+ }
+
+
+ /*
+ * Check if normal is present and nxform_ptr id non-null, if yes,
+ * create a new normal array and apply the xform
+ */
+ if ((vformat & GA_NORMALS) != 0 && (nxform_ptr != NULL)) {
+ /* create a temporary array for normals */
+ tmpNormalArray = (jfloat*) malloc(vertexCount * sizeof(float) * 3);
+ for (i = 0; i < vertexCount*3; i+=3) {
+ tmpNormalArray[i] = (float) (nxform_ptr[0] * verts[normoff] +
+ nxform_ptr[1] * verts[normoff+1] +
+ nxform_ptr[2] * verts[normoff+2]);
+ tmpNormalArray[i+1] = (float) (nxform_ptr[4] * verts[normoff] +
+ nxform_ptr[5] * verts[normoff+1] +
+ nxform_ptr[6] * verts[normoff+2]);
+ tmpNormalArray[i+2] = (float) (nxform_ptr[8] * verts[normoff] +
+ nxform_ptr[9] * verts[normoff+1] +
+ nxform_ptr[10] * verts[normoff+2]);
+ normoff += stride;
+ }
+ }
+
+ if ((vformat & GA_COORDINATES) != 0 && xform_ptr != NULL) {
+ /* create a temporary array for normals */
+ tmpCoordArray = (jfloat*) malloc(vertexCount * sizeof(float) * 3);
+ for (i = 0; i < vertexCount*3; i+=3) {
+ tmpCoordArray[i] = (float) (xform_ptr[0] * verts[coordoff] +
+ xform_ptr[1] * verts[coordoff+1] +
+ xform_ptr[2] * verts[coordoff+2]);
+ tmpCoordArray[i+1] = (float) (xform_ptr[4] * verts[coordoff] +
+ xform_ptr[5] * verts[coordoff+1] +
+ xform_ptr[6] * verts[coordoff+2]);
+ tmpCoordArray[i+2] = (float) (xform_ptr[8] * verts[coordoff] +
+ xform_ptr[9] * verts[coordoff+1] +
+ xform_ptr[10] * verts[coordoff+2]);
+ coordoff += stride;
+ }
+ }
+
+
+ if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) {
+
+
+ switch (geo_type) {
+ case GEO_TYPE_INDEXED_TRI_STRIP_SET :
+ primType = GL_TRIANGLE_STRIP;
+ break;
+ case GEO_TYPE_INDEXED_TRI_FAN_SET :
+ primType = GL_TRIANGLE_FAN;
+ break;
+ case GEO_TYPE_INDEXED_LINE_STRIP_SET :
+ primType = GL_LINE_STRIP;
+ break;
+ }
+
+
+ countArray = (GLsizei *) (*(table->GetPrimitiveArrayCritical))(env, sarray,
+ NULL);
+
+ if ((ignoreVertexColors == JNI_TRUE) || (xform_ptr != NULL) ||
+ ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = 0;
+ } else {
+ INTERLEAVEDARRAYS_TEST()
+ }
+
+ if (useInterleavedArrays) {
+ glInterleavedArrays(iaFormat, bstride, verts);
+ } else {
+ if (vformat & GA_NORMALS) {
+ if (nxform_ptr == NULL) {
+ glNormalPointer(GL_FLOAT, bstride, &(verts[normoff]));
+ }
+ else {
+ glNormalPointer(GL_FLOAT, 3 * sizeof(float), tmpNormalArray);
+ }
+ }
+ if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) {
+ if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) {
+ glColorPointer(4, GL_FLOAT, bstride, &(verts[coloroff]));
+ } else {
+ /*
+ for (i = 0; i < vcount; i++) {
+ fprintf(stderr, "r = %f, g = %f, b = %f\n", verts[i*bstride +coloroff], verts[i*bstride +coloroff+1],verts[i*bstride +coloroff+2]);
+ }
+ */
+ glColorPointer(3, GL_FLOAT, bstride, &(verts[coloroff]));
+ }
+ }
+ if (vformat & GA_COORDINATES) {
+ if (xform_ptr == NULL) {
+ /*
+ for (i = 0; i < vcount; i++) {
+ fprintf(stderr, "x = %f, y = %f, z = %f\n", verts[i*bstride +coordoff], verts[i*bstride +coordoff+1],verts[i*bstride +coordoff+2]);
+ }
+ */
+ glVertexPointer(3, GL_FLOAT, bstride, &(verts[coordoff]));
+ }
+ else {
+ glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), tmpCoordArray);
+ }
+ }
+
+ if (vformat & GA_TEXTURE_COORDINATE) {
+
+ executeTexture(-1, texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetMapOffset,
+ texCoordSetMapLen, NULL,
+ verts, ctxInfo);
+ }
+ }
+
+ switch (geo_type) {
+ case GEO_TYPE_INDEXED_TRI_STRIP_SET :
+ primType = GL_TRIANGLE_STRIP;
+ break;
+ case GEO_TYPE_INDEXED_TRI_FAN_SET :
+ primType = GL_TRIANGLE_FAN;
+ break;
+ case GEO_TYPE_INDEXED_LINE_STRIP_SET :
+ primType = GL_LINE_STRIP;
+ break;
+ }
+
+ lockArray(ctxProperties, vertexCount);
+
+ if (ctxProperties->multi_draw_arrays_ext || ctxProperties->multi_draw_arrays_sun) {
+ if (strip_len > 100) {
+ multiDrawElementsIndices = (jint**)malloc(strip_len * sizeof(int*));
+ allocated = 1;
+ }
+ else {
+ multiDrawElementsIndices =(jint**) &tmpDrawElementsIndices;
+ }
+
+ offset = initialIndexIndex;
+ for (i=0; i < strip_len;i++) {
+ multiDrawElementsIndices[i] = &indices[offset];
+ offset += countArray[i];
+ }
+ ctxProperties->glMultiDrawElementsEXT(primType, countArray, GL_UNSIGNED_INT,(const void **)multiDrawElementsIndices, strip_len);
+
+ } else {
+ offset = initialIndexIndex;
+ for (i=0; i < strip_len;i++) {
+ glDrawElements(primType, countArray[i], GL_UNSIGNED_INT, &indices[offset]);
+ offset += countArray[i];
+ }
+ }
+ (*(table->ReleasePrimitiveArrayCritical))(env, sarray, countArray, 0);
+ if (allocated) {
+ free(multiDrawElementsIndices);
+ }
+
+
+ }
+ else if ((geo_type == GEO_TYPE_INDEXED_QUAD_SET) ||
+ (geo_type == GEO_TYPE_INDEXED_TRI_SET) ||
+ (geo_type == GEO_TYPE_INDEXED_POINT_SET) ||
+ (geo_type == GEO_TYPE_INDEXED_LINE_SET)) {
+
+ switch (geo_type) {
+ case GEO_TYPE_INDEXED_QUAD_SET :
+ primType = GL_QUADS;
+ break;
+ case GEO_TYPE_INDEXED_TRI_SET :
+ primType = GL_TRIANGLES;
+ break;
+ case GEO_TYPE_INDEXED_POINT_SET :
+ primType = GL_POINTS;
+ break;
+ case GEO_TYPE_INDEXED_LINE_SET :
+ primType = GL_LINES;
+ break;
+
+ }
+
+ if ((ignoreVertexColors == JNI_TRUE) || (xform_ptr != NULL) ||
+ ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) ||
+ (texCoordSetCount > 1)))) {
+ useInterleavedArrays = 0;
+ } else {
+ INTERLEAVEDARRAYS_TEST()
+ }
+
+ if (useInterleavedArrays) {
+ glInterleavedArrays(iaFormat, bstride, verts);
+ } else {
+ if (vformat & GA_NORMALS) {
+
+ if (nxform_ptr == NULL) {
+ glNormalPointer(GL_FLOAT, bstride, &(verts[normoff]));
+ }
+ else {
+ glNormalPointer(GL_FLOAT, 3 * sizeof(float), tmpNormalArray);
+ }
+ }
+ if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) {
+ if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) {
+ glColorPointer(4, GL_FLOAT, bstride, &(verts[coloroff]));
+ } else {
+ glColorPointer(3, GL_FLOAT, bstride, &(verts[coloroff]));
+ }
+ }
+ if (vformat & GA_COORDINATES) {
+
+ if (xform_ptr == NULL) {
+ glVertexPointer(3, GL_FLOAT, bstride, &(verts[coordoff]));
+ }
+ else {
+ glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), tmpCoordArray);
+ }
+ }
+
+ if (vformat & GA_TEXTURE_COORDINATE) {
+ executeTexture(-1, texCoordSetMapLen,
+ texSize, bstride, texCoordoff,
+ texCoordSetMapOffset,
+ texCoordSetMapLen, NULL,
+ verts, ctxInfo);
+ }
+ }
+ lockArray(ctxProperties, vertexCount);
+ switch (geo_type){
+ case GEO_TYPE_INDEXED_QUAD_SET : glDrawElements(GL_QUADS,validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ case GEO_TYPE_INDEXED_TRI_SET : glDrawElements(GL_TRIANGLES, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ case GEO_TYPE_INDEXED_POINT_SET : glDrawElements(GL_POINTS, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ case GEO_TYPE_INDEXED_LINE_SET: glDrawElements(GL_LINES, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break;
+ }
+ }
+
+ unlockArray(ctxProperties);
+
+ if (tmpNormalArray != NULL) {
+ free(tmpNormalArray);
+ }
+ if (tmpCoordArray != NULL) {
+ free(tmpCoordArray);
+ }
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, varray, verts, 0);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, indexCoord, indices, 0);
+
+
+ if (texCoordSetMapLen > 0)
+ (*(table->ReleasePrimitiveArrayCritical))(env, texUnitOffset,
+ texCoordSetMapOffset, 0);
+
+ if (xform_ptr != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, xform, xform_ptr, 0);
+
+ if (nxform_ptr != NULL)
+ (*(table->ReleasePrimitiveArrayCritical))(env, nxform, nxform_ptr, 0);
+}
+
+
+/* execute geometry array with java array format */
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGAForByRef(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean updateAlpha,
+ jfloat alpha,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint vdefined,
+ jint initialCoordIndex,
+ jfloatArray vfcoords,
+ jdoubleArray vdcoords,
+ jint initialColorIndex,
+ jfloatArray cfdata,
+ jbyteArray cbdata,
+ jint initialNormalIndex,
+ jfloatArray ndata,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jintArray texindices,
+ jint texStride,
+ jobjectArray texCoords,
+ jdoubleArray xform,
+ jdoubleArray nxform)
+{
+ jclass geo_class;
+ JNIEnv table;
+ jboolean useAlpha = JNI_FALSE;
+ jfieldID strip_field;
+ jarray sarray;
+ jint i;
+ jsize strip_len;
+ jarray start_array;
+ jfieldID start_field;
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL;
+ jbyte *bclrs = NULL;
+ jfloat *fclrs = NULL, *norms = NULL;
+ jdouble *xform_ptr = NULL;
+ jdouble *nxform_ptr = NULL;
+ jfloat *tmpFloatCoordArray = NULL, *tmpNormalArray = NULL, *tmpFloatColors = NULL;
+ jdouble *tmpDoubleCoordArray = NULL;
+ jbyte* tmpByteColors= NULL;
+ jfloat* fvptr = NULL, *nptr = NULL, *fcptr = NULL;
+ jdouble* dvptr = NULL;
+ jbyte* bcptr = NULL;
+ jfloat* texCoordPointer[NUM_TEXTURE_UNITS];
+ jarray texobjs[NUM_TEXTURE_UNITS];
+ jint *tunitstatemap = NULL;
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+ int offset = 0;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ table = *env;
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (*(table->GetObjectArrayElement))(env, texCoords, i);
+ }
+ }
+
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+ /*
+ * process alpha for geometryArray without alpha
+ */
+ if (updateAlpha == JNI_TRUE && ignoreVertexColors== JNI_FALSE) {
+ useAlpha = JNI_TRUE;
+ }
+
+ /*
+ * call other JNI functions before entering Critical region
+ * i.e., GetPrimitiveArrayCritical
+ */
+ if (geo_type == GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_LINE_STRIP_SET) {
+
+ strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripVertexCounts", "[I");
+ sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field);
+ strip_len = (jsize)(*(table->GetArrayLength))(env, sarray);
+ start_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripStartOffsetIndices", "[I");
+ start_array = (jarray)(*(table->GetObjectField))(env, geo,
+ start_field);
+ }
+
+ if (ignoreVertexColors == JNI_TRUE) {
+ vformat &= ~GA_COLOR;
+ floatColorsDefined = JNI_FALSE;
+ byteColorsDefined = JNI_FALSE;
+ }
+ /* get texture arrays */
+ if (textureDefined) {
+ tunitstatemap = (int *)malloc(texCoordMapLength * sizeof(int));
+ for (i = 0; i < texCoordMapLength; i++) {
+ tunitstatemap[i] = i;
+ if (texobjs[i] != NULL)
+ texCoordPointer[i] = (jfloat*)(*(table->GetPrimitiveArrayCritical))(env,texobjs[i], NULL);
+ else
+ texCoordPointer[i] = NULL;
+
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ glEnableClientState(GL_VERTEX_ARRAY);
+ fverts= (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, vfcoords, NULL);
+ fvptr = fverts;
+ } else if (doubleCoordDefined) {
+ glEnableClientState(GL_VERTEX_ARRAY);
+ dverts= (jdouble *) (*(table->GetPrimitiveArrayCritical))(env, vdcoords, NULL);
+ dvptr = dverts;
+ }
+ else {
+ glDisableClientState(GL_VERTEX_ARRAY);
+ }
+
+
+ /* get color array */
+ if (floatColorsDefined) {
+ glEnableClientState(GL_COLOR_ARRAY);
+ fclrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, cfdata, NULL);
+ fcptr = fclrs;
+ } else if (byteColorsDefined) {
+ glEnableClientState(GL_COLOR_ARRAY);
+ bclrs = (jbyte *) (*(table->GetPrimitiveArrayCritical))(env, cbdata, NULL);
+ bcptr = bclrs;
+ }
+ else {
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+ /* get normal array */
+ if (normalsDefined) {
+ glEnableClientState(GL_NORMAL_ARRAY);
+ norms = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env,ndata, NULL);
+ nptr = norms;
+ }
+ else {
+ glDisableClientState(GL_NORMAL_ARRAY);
+ }
+
+ /* get the static transform if exists */
+ if (xform != NULL) {
+ xform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))(
+ env, xform, NULL);
+
+ }
+
+
+ /* get the static normals transform if exists */
+ if (nxform != NULL) {
+ nxform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))(
+ env, nxform, NULL);
+ }
+
+ /*
+ * Check if normal is present and nxform_ptr id non-null, if yes,
+ * create a new normal array and apply the xform
+ */
+ if (normalsDefined) {
+ if(nxform_ptr != NULL) {
+ /* create a temporary array for normals */
+ tmpNormalArray = (jfloat*) malloc(vcount * sizeof(float) * 3);
+ for (i = initialNormalIndex; i < vcount*3; i+=3) {
+ tmpNormalArray[i] = (float) (nxform_ptr[0] * norms[i] +
+ nxform_ptr[1] * norms[i+1] +
+ nxform_ptr[2] * norms[i+2]);
+ tmpNormalArray[i+1] = (float) (nxform_ptr[4] * norms[i] +
+ nxform_ptr[5] * norms[i+1] +
+ nxform_ptr[6] * norms[i+2]);
+ tmpNormalArray[i+2] = (float) (nxform_ptr[8] * norms[i] +
+ nxform_ptr[9] * norms[i+1] +
+ nxform_ptr[10] * norms[i+2]);
+ }
+ nptr = tmpNormalArray;
+ }
+
+ }
+
+ if (xform_ptr != NULL) {
+ if (floatCoordDefined) {
+ /* create a temporary array for normals */
+ tmpFloatCoordArray = (jfloat*) malloc(vcount * sizeof(float) * 3);
+ for (i = initialCoordIndex; i < vcount*3; i+=3) {
+ tmpFloatCoordArray[i] = (float) (xform_ptr[0] * fverts[i] +
+ xform_ptr[1] * fverts[i+1] +
+ xform_ptr[2] * fverts[i+2]);
+ tmpFloatCoordArray[i+1] = (float) (xform_ptr[4] * fverts[i] +
+ xform_ptr[5] * fverts[i+1] +
+ xform_ptr[6] * fverts[i+2]);
+ tmpFloatCoordArray[i+2] = (float) (xform_ptr[8] * fverts[i] +
+ xform_ptr[9] * fverts[i+1] +
+ xform_ptr[10] * fverts[i+2]);
+ }
+ fvptr = tmpFloatCoordArray;
+ }
+ else {
+ tmpDoubleCoordArray = (jdouble*) malloc(vcount * sizeof(double) * 3);
+ for (i = initialCoordIndex; i < vcount*3; i+=3) {
+ tmpDoubleCoordArray[i] = (double) (xform_ptr[0] * dverts[i] +
+ xform_ptr[1] * dverts[i+1] +
+ xform_ptr[2] * dverts[i+2]);
+ tmpDoubleCoordArray[i+1] = (double) (xform_ptr[4] * dverts[i] +
+ xform_ptr[5] * dverts[i+1] +
+ xform_ptr[6] * dverts[i+2]);
+ tmpDoubleCoordArray[i+2] = (double) (xform_ptr[8] * dverts[i] +
+ xform_ptr[9] * dverts[i+1] +
+ xform_ptr[10] * dverts[i+2]);
+ }
+ dvptr = tmpDoubleCoordArray;
+ }
+
+ }
+ /*
+ fprintf(stderr, "floatColorsDefined = %d, useAlpha = %d\n",
+ floatColorsDefined,useAlpha);
+ */
+ if (floatColorsDefined && useAlpha) {
+ tmpFloatColors = (jfloat*)malloc(vcount*sizeof(float) * 4);
+ if ((vformat & GA_WITH_ALPHA) != 0) {
+ /* fprintf(stderr, "with Alpha\n") */
+ for (i = initialColorIndex; i < vcount*4; i+=4) {
+ tmpFloatColors[i] = fclrs[i];
+ tmpFloatColors[i+1] = fclrs[i+1];
+ tmpFloatColors[i+2] = fclrs[i+2];
+ tmpFloatColors[i+3] = (float)(alpha* fclrs[i+3]);
+ }
+ }
+ else {
+ /* fprintf(stderr, "without Alpha\n") */
+ int k = 0;
+ for (i = initialColorIndex; i < vcount*4; i+=4) {
+ tmpFloatColors[i] = fclrs[k++];
+ tmpFloatColors[i+1] = fclrs[k++];
+ tmpFloatColors[i+2] = fclrs[k++];
+ tmpFloatColors[i+3] = (float)(alpha);
+ }
+ }
+ fcptr = tmpFloatColors;
+ vformat |= GA_WITH_ALPHA;
+ }
+ else if (byteColorsDefined && useAlpha) {
+ tmpByteColors = (jbyte*)malloc(vcount*sizeof(jbyte) * 4);
+ if ((vformat & GA_WITH_ALPHA) != 0) {
+ for (i = initialColorIndex; i < vcount*4; i+=4) {
+ tmpByteColors[i] = bclrs[i];
+ tmpByteColors[i+1] = bclrs[i+1];
+ tmpByteColors[i+2] =bclrs[i+2];
+ tmpByteColors[i+3] = (jbyte) (alpha * ((int)bclrs[i+3] & 0xff));
+ }
+ }
+ else {
+ int k = 0;
+ for (i = initialColorIndex; i < vcount*4; i+=4) {
+ tmpByteColors[i] = bclrs[k++];
+ tmpByteColors[i+1] = bclrs[k++];
+ tmpByteColors[i+2] =bclrs[k++];
+ tmpByteColors[i+3] = (jbyte) (alpha * 255.0);
+ }
+ }
+ bcptr = tmpByteColors;
+ vformat |= GA_WITH_ALPHA;
+
+ }
+ executeGeometryArrayVA(env, obj, ctxInfo, geo, geo_type,
+ isNonUniformScale, JNI_FALSE, ignoreVertexColors,
+ vcount, vformat, vdefined, initialCoordIndex,
+ fvptr, dvptr, initialColorIndex,
+ fcptr, bcptr, initialNormalIndex,
+ nptr, -1, texCoordMapLength,
+ tcoordsetmap, texCoordMapLength, tunitstatemap,
+ texindices,texStride,texCoordPointer,0, sarray,
+ strip_len, start_array);
+ if (textureDefined) {
+ if (tunitstatemap != NULL) {
+ free(tunitstatemap);
+ }
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texCoordPointer[i] != NULL) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, texobjs[i], texCoordPointer[i], 0);
+ }
+ }
+ }
+
+ if (normalsDefined) {
+ (*env)->ReleasePrimitiveArrayCritical(env, ndata, norms, 0);
+ if (tmpNormalArray != NULL) {
+ free(tmpNormalArray);
+ }
+ }
+
+
+ if (floatColorsDefined) {
+ (*env)->ReleasePrimitiveArrayCritical(env, cfdata, fclrs, 0);
+ if (tmpFloatColors != NULL) {
+ free(tmpFloatColors);
+ }
+ }
+ else if (byteColorsDefined) {
+ (*env)->ReleasePrimitiveArrayCritical(env, cbdata, bclrs, 0);
+ if (tmpByteColors != NULL) {
+ free(tmpByteColors);
+ }
+ }
+
+
+ if (floatCoordDefined) {
+ (*env)->ReleasePrimitiveArrayCritical(env, vfcoords, fverts, 0);
+ if (tmpFloatCoordArray != NULL) {
+ free(tmpFloatCoordArray);
+ }
+ }
+ else if (doubleCoordDefined) {
+ (*env)->ReleasePrimitiveArrayCritical(env, vdcoords, dverts, 0);
+ if (tmpDoubleCoordArray != NULL) {
+ free(tmpFloatCoordArray);
+ }
+ }
+}
+
+
+/* execute geometry array with java array format */
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGAForBuffer(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jobject geo,
+ jint geo_type,
+ jboolean isNonUniformScale,
+ jboolean updateAlpha,
+ jfloat alpha,
+ jboolean ignoreVertexColors,
+ jint vcount,
+ jint vformat,
+ jint vdefined,
+ jint initialCoordIndex,
+ jobject vcoords,
+ jint initialColorIndex,
+ jobject cdataBuffer,
+ jint initialNormalIndex,
+ jobject ndata,
+ jint texCoordMapLength,
+ jintArray tcoordsetmap,
+ jintArray texindices,
+ jint texStride,
+ jobjectArray texCoords,
+ jdoubleArray xform,
+ jdoubleArray nxform)
+{
+ jclass geo_class;
+ JNIEnv table;
+ jboolean useAlpha = JNI_FALSE;
+ jfieldID strip_field;
+ jarray sarray;
+ jint i;
+ jsize strip_len;
+ jarray start_array;
+ jfieldID start_field;
+ jfloat *fverts = NULL;
+ jdouble *dverts = NULL;
+ jbyte *bclrs = NULL;
+ jfloat *fclrs = NULL, *norms = NULL;
+ jdouble *xform_ptr = NULL;
+ jdouble *nxform_ptr = NULL;
+ jfloat *tmpFloatCoordArray = NULL, *tmpNormalArray = NULL, *tmpFloatColors = NULL;
+ jdouble *tmpDoubleCoordArray = NULL;
+ jbyte* tmpByteColors= NULL;
+ jfloat* fvptr = NULL, *nptr = NULL, *fcptr = NULL;
+ jdouble* dvptr = NULL;
+ jbyte* bcptr = NULL;
+ jfloat* texCoordPointer[NUM_TEXTURE_UNITS];
+ jarray texobjs[NUM_TEXTURE_UNITS];
+ jint *tunitstatemap = NULL;
+ jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0);
+ jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0);
+ jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0);
+ jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0);
+ jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0);
+ jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0);
+ int offset = 0;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ table = *env;
+ if (textureDefined) {
+ for (i = 0; i < texCoordMapLength; i++) {
+ texobjs[i] = (*(table->GetObjectArrayElement))(env, texCoords, i);
+ }
+ }
+
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+
+ /*
+ * process alpha for geometryArray without alpha
+ */
+ if (updateAlpha == JNI_TRUE && ignoreVertexColors== JNI_FALSE) {
+ useAlpha = JNI_TRUE;
+ }
+
+ /*
+ * call other JNI functions before entering Critical region
+ * i.e., GetPrimitiveArrayCritical
+ */
+ if (geo_type == GEO_TYPE_TRI_STRIP_SET ||
+ geo_type == GEO_TYPE_TRI_FAN_SET ||
+ geo_type == GEO_TYPE_LINE_STRIP_SET) {
+
+ strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripVertexCounts", "[I");
+ sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field);
+ strip_len = (jsize)(*(table->GetArrayLength))(env, sarray);
+ start_field = (jfieldID) (*(table->GetFieldID))(env, geo_class,
+ "stripStartOffsetIndices", "[I");
+ start_array = (jarray)(*(table->GetObjectField))(env, geo,
+ start_field);
+ }
+
+ if (ignoreVertexColors == JNI_TRUE) {
+ vformat &= ~GA_COLOR;
+ floatColorsDefined = JNI_FALSE;
+ byteColorsDefined = JNI_FALSE;
+ }
+ /* get texture arrays */
+ if (textureDefined) {
+ tunitstatemap = (int *)malloc( texCoordMapLength * sizeof(int));
+ for (i = 0; i < texCoordMapLength; i++) {
+ tunitstatemap[i] = i;
+ if (texobjs[i] != NULL)
+ texCoordPointer[i] = (jfloat*)(*(table->GetPrimitiveArrayCritical))(env,texobjs[i], NULL);
+ else
+ texCoordPointer[i] = NULL;
+
+ }
+ }
+
+ /* get coordinate array */
+ if (floatCoordDefined) {
+ glEnableClientState(GL_VERTEX_ARRAY);
+ fverts= (jfloat *)(*(table->GetDirectBufferAddress))(env, vcoords );
+ fvptr = fverts;
+ } else if (doubleCoordDefined) {
+ glEnableClientState(GL_VERTEX_ARRAY);
+ dverts= (jdouble *)(*(table->GetDirectBufferAddress))(env, vcoords );
+ dvptr = dverts;
+ }
+ else {
+ glDisableClientState(GL_VERTEX_ARRAY);
+ }
+
+ if(fverts == NULL && dverts == NULL) {
+ return;
+ }
+ /* get color array */
+ if (floatColorsDefined) {
+ glEnableClientState(GL_COLOR_ARRAY);
+ fclrs = (jfloat *)(*(table->GetDirectBufferAddress))(env, cdataBuffer);
+ fcptr = fclrs;
+ } else if (byteColorsDefined) {
+ glEnableClientState(GL_COLOR_ARRAY);
+ bclrs = (jbyte *)(*(table->GetDirectBufferAddress))(env, cdataBuffer);
+ bcptr = bclrs;
+ }
+ else {
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+ /* get normal array */
+ if (normalsDefined) {
+ glEnableClientState(GL_NORMAL_ARRAY);
+ norms = (jfloat *)(*(table->GetDirectBufferAddress))(env, ndata);
+ nptr = norms;
+ }
+ else {
+ glDisableClientState(GL_NORMAL_ARRAY);
+ }
+ /* get the static transform if exists */
+ if (xform != NULL) {
+ xform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))(
+ env, xform, NULL);
+
+ }
+
+
+ /* get the static normals transform if exists */
+ if (nxform != NULL) {
+ nxform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))(
+ env, nxform, NULL);
+ }
+
+
+ /*
+ * Check if normal is present and nxform_ptr id non-null, if yes,
+ * create a new normal array and apply the xform
+ */
+ if (normalsDefined) {
+ if(nxform_ptr != NULL) {
+ /* create a temporary array for normals */
+ tmpNormalArray = (jfloat*) malloc(vcount * sizeof(float) * 3);
+ for (i = initialNormalIndex; i < vcount*3; i+=3) {
+ tmpNormalArray[i] = (float) (nxform_ptr[0] * norms[i] +
+ nxform_ptr[1] * norms[i+1] +
+ nxform_ptr[2] * norms[i+2]);
+ tmpNormalArray[i+1] = (float) (nxform_ptr[4] * norms[i] +
+ nxform_ptr[5] * norms[i+1] +
+ nxform_ptr[6] * norms[i+2]);
+ tmpNormalArray[i+2] = (float) (nxform_ptr[8] * norms[i] +
+ nxform_ptr[9] * norms[i+1] +
+ nxform_ptr[10] * norms[i+2]);
+ }
+ nptr = tmpNormalArray;
+ }
+
+ }
+
+ if (xform_ptr != NULL) {
+ if (floatCoordDefined) {
+ /* create a temporary array for normals */
+ tmpFloatCoordArray = (jfloat*) malloc(vcount * sizeof(float) * 3);
+ for (i = initialCoordIndex; i < vcount*3; i+=3) {
+ tmpFloatCoordArray[i] = (float) (xform_ptr[0] * fverts[i] +
+ xform_ptr[1] * fverts[i+1] +
+ xform_ptr[2] * fverts[i+2]);
+ tmpFloatCoordArray[i+1] = (float) (xform_ptr[4] * fverts[i] +
+ xform_ptr[5] * fverts[i+1] +
+ xform_ptr[6] * fverts[i+2]);
+ tmpFloatCoordArray[i+2] = (float) (xform_ptr[8] * fverts[i] +
+ xform_ptr[9] * fverts[i+1] +
+ xform_ptr[10] * fverts[i+2]);
+ }
+ fvptr = tmpFloatCoordArray;
+ }
+ else {
+ tmpDoubleCoordArray = (jdouble*) malloc(vcount * sizeof(double) * 3);
+ for (i = initialCoordIndex; i < vcount*3; i+=3) {
+ tmpDoubleCoordArray[i] = (double) (xform_ptr[0] * dverts[i] +
+ xform_ptr[1] * dverts[i+1] +
+ xform_ptr[2] * dverts[i+2]);
+ tmpDoubleCoordArray[i+1] = (double) (xform_ptr[4] * dverts[i] +
+ xform_ptr[5] * dverts[i+1] +
+ xform_ptr[6] * dverts[i+2]);
+ tmpDoubleCoordArray[i+2] = (double) (xform_ptr[8] * dverts[i] +
+ xform_ptr[9] * dverts[i+1] +
+ xform_ptr[10] * dverts[i+2]);
+ }
+ dvptr = tmpDoubleCoordArray;
+ }
+
+ }
+ if (floatColorsDefined && useAlpha) {
+ tmpFloatColors = (jfloat*)malloc(vcount*sizeof(float) * 4);
+ if ((vformat & GA_WITH_ALPHA) != 0) {
+ for (i = initialColorIndex; i < vcount*4; i+=4) {
+ tmpFloatColors[i] = fclrs[i];
+ tmpFloatColors[i+1] = fclrs[i+1];
+ tmpFloatColors[i+2] = fclrs[i+2];
+ tmpFloatColors[i+3] = (float)(alpha* fclrs[i+3]);
+ }
+ }
+ else {
+ int k = 0;
+ for (i = initialColorIndex; i < vcount*4; i+=4) {
+ tmpFloatColors[i] = fclrs[k++];
+ tmpFloatColors[i+1] = fclrs[k++];
+ tmpFloatColors[i+2] = fclrs[k++];
+ tmpFloatColors[i+3] = (float)(alpha);
+ }
+ }
+ fcptr = tmpFloatColors;
+ vformat |= GA_WITH_ALPHA;
+ }
+ else if (byteColorsDefined && useAlpha) {
+ tmpByteColors = (jbyte*)malloc(vcount*sizeof(jbyte) * 4);
+ if ((vformat & GA_WITH_ALPHA) != 0) {
+ for (i = initialColorIndex; i < vcount*4; i+=4) {
+ tmpByteColors[i] = bclrs[i];
+ tmpByteColors[i+1] = bclrs[i+1];
+ tmpByteColors[i+2] =bclrs[i+2];
+ tmpByteColors[i+3] = (jbyte) (alpha * ((int)bclrs[i+3] & 0xff));
+ }
+ }
+ else {
+ int k = 0;
+ for (i = initialColorIndex; i < vcount*4; i+=4) {
+ tmpByteColors[i] = bclrs[k++];
+ tmpByteColors[i+1] = bclrs[k++];
+ tmpByteColors[i+2] =bclrs[k++];
+ tmpByteColors[i+3] = (jbyte) (alpha * 255.0);
+ }
+ }
+ bcptr = tmpByteColors;
+ vformat |= GA_WITH_ALPHA;
+
+ }
+ executeGeometryArrayVA(env, obj, ctxInfo, geo, geo_type,
+ isNonUniformScale, JNI_FALSE, ignoreVertexColors,
+ vcount, vformat, vdefined, initialCoordIndex,
+ fvptr, dvptr, initialColorIndex,
+ fcptr, bcptr, initialNormalIndex,
+ nptr, -1, texCoordMapLength,
+ tcoordsetmap, texCoordMapLength, tunitstatemap,
+ texindices,texStride,texCoordPointer,0, sarray, strip_len, start_array);
+ if (textureDefined) {
+ if (tunitstatemap != NULL) {
+ free(tunitstatemap);
+ }
+ for (i = 0; i < texCoordMapLength; i++) {
+ if (texCoordPointer[i] != NULL) {
+ (*(table->ReleasePrimitiveArrayCritical))(env, texobjs[i], texCoordPointer[i], 0);
+ }
+ }
+ }
+
+ if (tmpNormalArray != NULL) {
+ free(tmpNormalArray);
+ }
+
+
+ if (tmpFloatColors != NULL) {
+ free(tmpFloatColors);
+ }
+ else if (tmpByteColors != NULL) {
+ free(tmpByteColors);
+ }
+
+
+ if (tmpFloatCoordArray != NULL) {
+ free(tmpFloatCoordArray);
+ }
+ else if (tmpDoubleCoordArray != NULL) {
+ free(tmpFloatCoordArray);
+ }
+}
+
+
diff --git a/src/native/ogl/GraphicsContext3D.c b/src/native/ogl/GraphicsContext3D.c
new file mode 100644
index 0000000..9d800f8
--- /dev/null
+++ b/src/native/ogl/GraphicsContext3D.c
@@ -0,0 +1,171 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include <stdio.h>
+#include <jni.h>
+
+#include "gldefs.h"
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_GraphicsContext3D_readRasterNative(
+ JNIEnv *env, jobject obj, jlong ctxInfo,
+ jint type, jint xOffset, jint yOffset,
+ jint wRaster, jint hRaster, jint hCanvas,
+ jint format, jobject image, jobject depth, jobject ctx)
+{
+ JNIEnv table;
+ int yAdjusted;
+ jclass ctx_class;
+ GLenum gltype;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong d3dctx = ctxProperties->context;
+
+ table = *env;
+
+ glPixelStorei(GL_PACK_ROW_LENGTH, wRaster);
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ yAdjusted = hCanvas - hRaster - yOffset;
+
+ ctx_class = (jclass) (*(table->GetObjectClass))(env, ctx);
+
+ if ((type & javax_media_j3d_Raster_RASTER_COLOR) != 0) {
+
+ jclass image_class;
+
+ jfieldID byteData_field;
+ jarray byteData_array;
+ jbyte *byteData;
+
+ byteData_field = (jfieldID)(*(table->GetFieldID))(env,
+ ctx_class, "byteBuffer","[B");
+ byteData_array = (jarray)(*(table->GetObjectField))(env, ctx,
+ byteData_field);
+
+ image_class = (jclass) (*(table->GetObjectClass))(env, image);
+
+ if (image_class == NULL) {
+ return;
+ }
+
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ gltype = GL_RGBA;
+ break;
+ case FORMAT_BYTE_RGB:
+ gltype = GL_RGB;
+ break;
+
+ case FORMAT_BYTE_ABGR:
+ if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */
+ gltype = GL_ABGR_EXT;
+ }
+ break;
+
+ case FORMAT_BYTE_BGR:
+ if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */
+ gltype = ctxProperties->bgr_ext_enum;
+ }
+ break;
+ case FORMAT_BYTE_LA:
+ gltype = GL_LUMINANCE_ALPHA;
+ break;
+ case FORMAT_BYTE_GRAY:
+ case FORMAT_USHORT_GRAY:
+ /* TODO: throw exception */
+ break;
+ }
+ byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env,
+ byteData_array, NULL);
+ glReadPixels(xOffset, yAdjusted, wRaster, hRaster,
+ gltype, GL_UNSIGNED_BYTE, byteData);
+
+ /*
+ {
+ int i, j , *intData;
+ fprintf(stderr, "format = %d, wRaster = %d, hRaster = %d\n\n", format, wRaster, hRaster);
+ intData = (int*)byteData;
+ for (i = 0; i < wRaster; i++) {
+ for (j = 0; j < hRaster; j++, intData++) {
+ fprintf(stderr, " 0x%x", *intData);
+ }
+ fprintf(stderr, "\n");
+ }
+ }
+ */
+ (*(table->ReleasePrimitiveArrayCritical))(env, byteData_array,
+ byteData, 0);
+ }
+
+
+ if ((type & javax_media_j3d_Raster_RASTER_DEPTH) != 0) {
+
+ jclass depth_class;
+ jfieldID wDepth_field, depth_type_field;
+ jint depth_type, wDepth;
+
+ depth_class = (jclass) (*(table->GetObjectClass))(env, depth);
+
+ if (depth_class == NULL) {
+ return;
+ }
+
+ wDepth_field = (jfieldID) (*(table->GetFieldID))(env, depth_class,
+ "width", "I");
+ wDepth = (jint)(*(table->GetIntField))(env, depth, wDepth_field);
+
+ depth_type_field = (jfieldID) (*(table->GetFieldID))(env,
+ depth_class, "type", "I");
+ depth_type = (jint)(*(table->GetIntField))(env, depth,
+ depth_type_field);
+
+ if (depth_type == javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_INT) {
+ jfieldID intData_field;
+ jarray intData_array;
+ jint *intData;
+
+ intData_field = (jfieldID)(*(table->GetFieldID))(env,
+ ctx_class, "intBuffer","[I");
+ intData_array = (jarray)(*(table->GetObjectField))(env, ctx,
+ intData_field);
+
+ intData = (jint *)(*(table->GetPrimitiveArrayCritical))(env,
+ intData_array, NULL);
+
+ /* yOffset is adjusted for OpenGL - Y upward */
+ glReadPixels(xOffset, yAdjusted, wRaster, hRaster,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, intData);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, intData_array,
+ intData, 0);
+ } else { /* javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_FLOAT */
+ jfieldID floatData_field;
+ jarray floatData_array;
+ jfloat *floatData;
+
+ floatData_field = (jfieldID)(*(table->GetFieldID))(env,
+ ctx_class, "floatBuffer","[F");
+ floatData_array = (jarray)(*(table->GetObjectField))(env, ctx,
+ floatData_field);
+ floatData = (jfloat *)(*(table->GetPrimitiveArrayCritical))(env,
+ floatData_array, NULL);
+
+ /* yOffset is adjusted for OpenGL - Y upward */
+ glReadPixels(xOffset, yAdjusted, wRaster, hRaster,
+ GL_DEPTH_COMPONENT, GL_FLOAT, floatData);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env, floatData_array,
+ floatData, 0);
+ }
+ }
+}
+
diff --git a/src/native/ogl/Lights.c b/src/native/ogl/Lights.c
new file mode 100644
index 0000000..89ab98e
--- /dev/null
+++ b/src/native/ogl/Lights.c
@@ -0,0 +1,168 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <jni.h>
+
+#include "gldefs.h"
+
+#ifdef DEBUG
+/* Uncomment the following for VERBOSE debug messages */
+/* #define VERBOSE */
+#endif /* DEBUG */
+
+
+const float black[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_DirectionalLightRetained_updateLight(
+ JNIEnv *env,
+ jobject light,
+ jlong ctxInfo,
+ jint lightSlot,
+ jfloat red,
+ jfloat green,
+ jfloat blue,
+ jfloat dirx,
+ jfloat diry,
+ jfloat dirz)
+{
+ int lightNum;
+ float values[4];
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+#ifdef VERBOSE
+ fprintf(stderr,
+ "Directional Light %d: %f %f %f direction, %f %f %f color\n",
+ lightSlot, dirx, diry, dirz, red, green, blue);
+#endif
+ lightNum = GL_LIGHT0 + lightSlot;
+ values[0] = red;
+ values[1] = green;
+ values[2] = blue;
+ values[3] = 1.0f;
+ glLightfv(lightNum, GL_DIFFUSE, values);
+ glLightfv(lightNum, GL_SPECULAR, values);
+ values[0] = -dirx;
+ values[1] = -diry;
+ values[2] = -dirz;
+ values[3] = 0.0f;
+ glLightfv(lightNum, GL_POSITION, values);
+ glLightfv(lightNum, GL_AMBIENT, black);
+ glLightf(lightNum, GL_CONSTANT_ATTENUATION, 1.0f);
+ glLightf(lightNum, GL_LINEAR_ATTENUATION, 0.0f);
+ glLightf(lightNum, GL_QUADRATIC_ATTENUATION, 0.0f);
+ glLightf(lightNum, GL_SPOT_EXPONENT, 0.0f);
+ glLightf(lightNum, GL_SPOT_CUTOFF, 180.0f);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_PointLightRetained_updateLight(
+ JNIEnv *env,
+ jobject light,
+ jlong ctxInfo,
+ jint lightSlot,
+ jfloat red,
+ jfloat green,
+ jfloat blue,
+ jfloat attenx,
+ jfloat atteny,
+ jfloat attenz,
+ jfloat posx,
+ jfloat posy,
+ jfloat posz)
+{
+ int lightNum;
+ float values[4];
+
+#ifdef VERBOSE
+ fprintf(stderr, "Positional Light %d: %f %f %f position, %f %f %f color\n\t %f %f %f attenuation\n",
+ lightSlot, posx, posy, posz, red, green, blue,
+ attenx, atteny, attenz);
+#endif
+
+ lightNum = GL_LIGHT0 + lightSlot;
+ values[0] = red;
+ values[1] = green;
+ values[2] = blue;
+ values[3] = 1.0f;
+ glLightfv(lightNum, GL_DIFFUSE, values);
+ glLightfv(lightNum, GL_SPECULAR, values);
+ glLightfv(lightNum, GL_AMBIENT, black);
+ values[0] = posx;
+ values[1] = posy;
+ values[2] = posz;
+ glLightfv(lightNum, GL_POSITION, values);
+ glLightf(lightNum, GL_CONSTANT_ATTENUATION, attenx);
+ glLightf(lightNum, GL_LINEAR_ATTENUATION, atteny);
+ glLightf(lightNum, GL_QUADRATIC_ATTENUATION, attenz);
+ glLightf(lightNum, GL_SPOT_EXPONENT, 0.0f);
+ glLightf(lightNum, GL_SPOT_CUTOFF, 180.0f);
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_SpotLightRetained_updateLight(
+ JNIEnv *env,
+ jobject light,
+ jlong ctxInfo,
+ jint lightSlot,
+ jfloat red,
+ jfloat green,
+ jfloat blue,
+ jfloat attenx,
+ jfloat atteny,
+ jfloat attenz,
+ jfloat posx,
+ jfloat posy,
+ jfloat posz,
+ jfloat spreadAngle,
+ jfloat concentration,
+ jfloat dirx,
+ jfloat diry,
+ jfloat dirz)
+{
+ int lightNum;
+ float values[4];
+
+#ifdef VERBOSE
+ fprintf(stderr, "Spot Light %d: %f %f %f position, %f %f %f color\n\t %f %f %f attenuation\n\t %f %f %f direction, %f spreadAngle, %f concentration\n",
+ lightSlot, posx, posy, posz, red, green, blue,
+ attenx, atteny, attenz, dirx, diry, dirz,
+ spreadAngle*180.0 / M_PI, concentration);
+#endif
+ lightNum = GL_LIGHT0 + lightSlot;
+ values[0] = red;
+ values[1] = green;
+ values[2] = blue;
+ values[3] = 1.0f;
+ glLightfv(lightNum, GL_DIFFUSE, values);
+ glLightfv(lightNum, GL_SPECULAR, values);
+ glLightfv(lightNum, GL_AMBIENT, black);
+ values[0] = posx;
+ values[1] = posy;
+ values[2] = posz;
+ glLightfv(lightNum, GL_POSITION, values);
+ glLightf(lightNum, GL_CONSTANT_ATTENUATION, attenx);
+ glLightf(lightNum, GL_LINEAR_ATTENUATION, atteny);
+ glLightf(lightNum, GL_QUADRATIC_ATTENUATION, attenz);
+ values[0] = dirx;
+ values[1] = diry;
+ values[2] = dirz;
+ glLightfv(lightNum, GL_SPOT_DIRECTION, values);
+ glLightf(lightNum, GL_SPOT_EXPONENT, concentration);
+ glLightf(lightNum, GL_SPOT_CUTOFF, (float) (spreadAngle * 180.0f / M_PI));
+}
+
diff --git a/src/native/ogl/MasterControl.c b/src/native/ogl/MasterControl.c
new file mode 100644
index 0000000..3f8dcc5
--- /dev/null
+++ b/src/native/ogl/MasterControl.c
@@ -0,0 +1,261 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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.
+ */
+
+#ifdef DEBUG
+#define DPRINT(args) fprintf args
+#else
+#define DPRINT(args)
+#endif /* DEBUG */
+
+#include <jni.h>
+#include <math.h>
+#include <string.h>
+#include "gldefs.h"
+
+#ifdef WIN32
+#include <windows.h>
+#include <winbase.h>
+#endif /* WIN32 */
+
+#if defined(SOLARIS) || defined(__linux__)
+#include <unistd.h>
+#ifdef SOLARIS
+#include <thread.h>
+#else
+#include <pthread.h>
+#endif
+#include <dlfcn.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#pragma weak glXInitThreadsSUN
+#pragma weak glXDisableXineramaSUN
+#pragma weak XPanoramiXQueryExtension
+
+#ifdef SOLARIS
+extern int glXInitThreadsSUN();
+extern int glXDisableXineramaSUN(Display *dpy);
+
+
+/*
+ * The following is currently an unsupported, undocumented function to query
+ * whether the X server is running with Xinerama support. This is an interim
+ * solution until it is made part of the X Window System standard or replaced
+ * with a fully supported API. It is currently available in the libXext
+ * shipped with Solaris 9 and patched versions of Solaris 7 and 8. dlsym() is
+ * used to check for its existence.
+ */
+extern Bool XPanoramiXQueryExtension(Display *dpy,
+ int *event_base, int *error_base);
+#endif /* SOLARIS */
+#endif /* SOLARIS || __linux__ */
+
+/* defined in Canvas3D.c */
+extern int isExtensionSupported(const char *allExtensions,
+ const char *extension);
+
+JNIEXPORT jboolean JNICALL
+Java_javax_media_j3d_MasterControl_initializeJ3D(
+ JNIEnv *env, jobject obj, jboolean disableXinerama)
+{
+ jboolean glIsMTSafe = JNI_FALSE;
+
+#ifdef WIN32
+ glIsMTSafe = JNI_TRUE;
+ return glIsMTSafe;
+#endif /* WIN32 */
+
+#ifdef __linux__
+ glIsMTSafe = JNI_TRUE;
+ return glIsMTSafe;
+#endif /* __linux__ */
+
+#ifdef SOLARIS
+ Display* dpy;
+ int event_base, error_base;
+ const char *glxExtStr = NULL;
+
+ dpy = XOpenDisplay(NULL);
+ glxExtStr = glXGetClientString((Display*)dpy, GLX_EXTENSIONS);
+
+#ifdef GLX_SUN_init_threads
+ if(isExtensionSupported(glxExtStr, "GLX_SUN_init_threads")) {
+ if (glXInitThreadsSUN()) {
+ glIsMTSafe = JNI_TRUE;
+ }
+ else {
+ DPRINT((stderr, "Failed initializing OpenGL for MT rendering.\n"));
+ DPRINT((stderr, "glXInitThreadsSUN returned false.\n"));
+ }
+ }
+ else {
+ DPRINT((stderr, "Failed to initialize OpenGL for MT rendering.\n"));
+ DPRINT((stderr, "GLX_SUN_init_threads not available.\n"));
+ }
+#endif /* GLX_SUN_init_threads */
+
+ if (disableXinerama) {
+ DPRINT((stderr, "Property j3d.disableXinerama true "));
+
+ if ((! dlsym(RTLD_DEFAULT, "XPanoramiXQueryExtension")) ||
+ (! dlsym(RTLD_DEFAULT, "XDgaGetXineramaInfo"))) {
+
+ DPRINT((stderr, "but required API not available.\n"));
+ return glIsMTSafe;
+ }
+
+ if (XPanoramiXQueryExtension(dpy, &event_base, &error_base)) {
+ DPRINT((stderr, "and Xinerama is in use.\n"));
+#ifdef GLX_SUN_disable_xinerama
+ if(isExtensionSupported(glxExtStr, "GLX_SUN_disable_xinerama")) {
+
+ if (glXDisableXineramaSUN((Display *)dpy)) {
+ jclass cls = (*env)->GetObjectClass(env, obj);
+ jfieldID disabledField =
+ (*env)->GetFieldID(env, cls, "xineramaDisabled", "Z");
+
+ (*env)->SetBooleanField(env, obj, disabledField, JNI_TRUE);
+ DPRINT((stderr, "Successfully disabled Xinerama.\n"));
+ }
+ else {
+ DPRINT((stderr, "Failed to disable Xinerama: "));
+ DPRINT((stderr, "glXDisableXineramaSUN returns false.\n"));
+ }
+ } else {
+ DPRINT((stderr, "Failed to disable Xinerama: "));
+ DPRINT((stderr, "GLX_SUN_disable_xinerama not available.\n"));
+ }
+#endif /* GLX_SUN_disable_xinerama */
+ } else {
+ DPRINT((stderr, "but Xinerama is not in use.\n"));
+ }
+ }
+#endif /* SOLARIS */
+
+ return glIsMTSafe;
+}
+
+
+#ifdef WIN32
+DWORD countBits(DWORD mask)
+{
+ DWORD count = 0;
+ int i;
+
+ for (i=sizeof(DWORD)*8-1; i >=0 ; i--) {
+ if ((mask & 0x01) > 0) {
+ count++;
+ }
+ mask >>= 1;
+ }
+ return count;
+}
+
+#endif /* WIN32 */
+
+/*
+ * Class: javax_media_j3d_MasterControl
+ * Method: getNumberOfProcessor
+ * Signature: ()I
+ *
+ * This function get the number of active processor in the system
+ */
+JNIEXPORT jint JNICALL Java_javax_media_j3d_MasterControl_getNumberOfProcessor
+ (JNIEnv *env, jobject obj)
+{
+#if defined(SOLARIS) || defined(__linux__)
+ return sysconf(_SC_NPROCESSORS_ONLN);
+#endif /* SOLARIS || __linux__ */
+
+#ifdef WIN32
+ SYSTEM_INFO sysInfo;
+
+ GetSystemInfo(&sysInfo);
+ return countBits(sysInfo.dwActiveProcessorMask);
+#endif /* WIN32 */
+}
+
+
+/*
+ * Class: javax_media_j3d_MasterControl
+ * Method: getThreadConcurrency
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_javax_media_j3d_MasterControl_getThreadConcurrency(JNIEnv *env,
+ jobject obj)
+{
+ /*
+ * Return the number of concurrent threads that can be run,
+ * -1 if unknown.
+ */
+
+#ifdef SOLARIS
+ return (jint) thr_getconcurrency();
+#endif /* SOLARIS */
+
+#ifdef WIN32
+ return -1;
+#endif /* WIN32 */
+}
+
+
+/*
+ * Class: javax_media_j3d_MasterControl
+ * Method: setThreadConcurrency
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_javax_media_j3d_MasterControl_setThreadConcurrency(JNIEnv *env,
+ jobject obj,
+ jint newLevel)
+{
+#ifdef SOLARIS
+ thr_setconcurrency((int)newLevel);
+#endif /* SOLARIS */
+
+#ifdef WIN32
+ /* No-op on windows */
+#endif /* WIN32 */
+
+#ifdef __linux__
+ /* No-op on linux */
+#endif /* __linux__ */
+}
+
+
+
+JNIEXPORT
+jint JNICALL Java_javax_media_j3d_MasterControl_getMaximumLights(
+ JNIEnv *env,
+ jobject obj
+ ) {
+
+#ifdef SOLARIS
+ return 32;
+#endif /* SOLARIS */
+
+#ifdef WIN32
+ return 8;
+#endif /* WIN32 */
+
+#ifdef __linux__
+ return 8;
+#endif /* __linux__ */
+}
diff --git a/src/native/ogl/NativeAPIInfo.c b/src/native/ogl/NativeAPIInfo.c
new file mode 100644
index 0000000..8cd0841
--- /dev/null
+++ b/src/native/ogl/NativeAPIInfo.c
@@ -0,0 +1,38 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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.
+ */
+
+#include <jni.h>
+
+#include "javax_media_j3d_MasterControl.h"
+
+JNIEXPORT
+jint JNICALL Java_javax_media_j3d_NativeAPIInfo_getRenderingAPI(
+ JNIEnv *env, jobject obj)
+{
+#ifdef WIN32
+ return (jint)javax_media_j3d_MasterControl_RENDER_OPENGL_WIN32;
+#endif /* WIN32 */
+
+#ifdef SOLARIS
+ return (jint)javax_media_j3d_MasterControl_RENDER_OPENGL_SOLARIS;
+#endif /* SOLARIS */
+
+#ifdef __linux__
+ return (jint)javax_media_j3d_MasterControl_RENDER_OPENGL_LINUX;
+#endif /* __linux__ */
+}
diff --git a/src/native/ogl/NativeConfigTemplate3D.c b/src/native/ogl/NativeConfigTemplate3D.c
new file mode 100644
index 0000000..66a5324
--- /dev/null
+++ b/src/native/ogl/NativeConfigTemplate3D.c
@@ -0,0 +1,1277 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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.
+ */
+
+#include <jni.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "gldefs.h"
+
+#if defined(SOLARIS) || defined(__linux__)
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+/* check if the extension is supported */
+extern int isExtensionSupported(const char *allExtensions, const char *extension);
+
+#if defined(SOLARIS) || defined(__linux__)
+
+XVisualInfo *findVisualInfoSwitchDoubleBufferAndStereo(jlong display,
+ jint screen,
+ int* glxAttrs,
+ int sVal, int sIndex,
+ int dbVal, int dbIndex ) {
+ int stereoLoop;
+ int doubleBufferLoop;
+ XVisualInfo *vis_info = NULL;
+
+ int i, j;
+ /*
+ * set all "enums" to user's preferred state
+ */
+ if (dbVal == REQUIRED || dbVal == PREFERRED)
+ glxAttrs[dbIndex] = GLX_DOUBLEBUFFER;
+ else
+ glxAttrs[dbIndex] = GLX_USE_GL;
+
+ if (sVal == REQUIRED || sVal == PREFERRED)
+ glxAttrs[sIndex] = GLX_STEREO;
+ else
+ glxAttrs[sIndex] = GLX_USE_GL;
+
+ vis_info = glXChooseVisual((Display*)display, screen, glxAttrs);
+ if (vis_info == NULL) {
+ /*
+ * coudn't match visual with default values - try
+ * enabling UNNECESSARY attributes.
+ */
+ if(sVal == UNNECESSARY)
+ stereoLoop = 1;
+ else
+ stereoLoop = 0;
+
+ if(dbVal == UNNECESSARY)
+ doubleBufferLoop = 1;
+ else
+ doubleBufferLoop = 0;
+
+ i = 0;
+ while(i <= stereoLoop && vis_info == NULL ) {
+ if (sVal == UNNECESSARY)
+ glxAttrs[sIndex] = i? GLX_STEREO : GLX_USE_GL;
+ j = 0;
+ while(j <= doubleBufferLoop && vis_info == NULL) {
+ if(dbVal == UNNECESSARY) {
+ glxAttrs[dbIndex] = j? GLX_USE_GL: GLX_DOUBLEBUFFER;
+ }
+ vis_info = glXChooseVisual((Display*)display, screen, glxAttrs);
+ j++;
+ } /* end of doubleBufferLoop */
+ i++;
+ } /* end of stereoLoop */
+ }
+
+ if (vis_info == NULL) {
+ /*
+ * still coudn't match visual with default values - try
+ * disabling PREFERRED attributes.
+ */
+ /* restore default values */
+ if (sVal == REQUIRED || sVal == PREFERRED)
+ glxAttrs[sIndex] = GLX_STEREO;
+ else
+ glxAttrs[sIndex] = GLX_USE_GL;
+
+ if (dbVal == REQUIRED || dbVal == PREFERRED)
+ glxAttrs[dbIndex] = GLX_DOUBLEBUFFER;
+ else
+ glxAttrs[dbIndex] = GLX_USE_GL;
+
+ if(sVal == PREFERRED)
+ stereoLoop = 1;
+ else
+ stereoLoop = 0;
+
+ if(dbVal == PREFERRED)
+ doubleBufferLoop = 1;
+ else
+ doubleBufferLoop = 0;
+
+ i = 0;
+ while(i <= stereoLoop && vis_info == NULL ) {
+ if (sVal == PREFERRED)
+ glxAttrs[sIndex] = i? GLX_USE_GL : GLX_STEREO ;
+ j = 0;
+ while(j <= doubleBufferLoop && vis_info == NULL) {
+ if(dbVal == PREFERRED) {
+ glxAttrs[dbIndex] = j? GLX_DOUBLEBUFFER : GLX_USE_GL;
+ }
+ vis_info = glXChooseVisual((Display*)display, screen, glxAttrs);
+ j++;
+ } /* end of doubleBufferLoop */
+ i++;
+ } /* end of stereoLoop */
+ }
+
+ if (vis_info == NULL) {
+
+ /*
+ * STILL coudn't match visual with default values - try
+ * disabling PREFERRED attributes and enabling UNNECESSARY.
+ */
+
+ /* restore default values */
+ if (sVal == REQUIRED || sVal == PREFERRED)
+ glxAttrs[sIndex] = GLX_STEREO;
+ else
+ glxAttrs[sIndex] = GLX_USE_GL;
+
+ if (dbVal == REQUIRED || dbVal == PREFERRED)
+ glxAttrs[dbIndex] = GLX_DOUBLEBUFFER;
+ else
+ glxAttrs[dbIndex] = GLX_USE_GL;
+
+ if(sVal != REQUIRED)
+ stereoLoop = 1;
+ else
+ stereoLoop = 0;
+
+ if(dbVal != REQUIRED)
+ doubleBufferLoop = 1;
+ else
+ doubleBufferLoop = 0;
+
+ i = 0;
+ while(i <= stereoLoop && vis_info == NULL ) {
+ if (sVal == PREFERRED || sVal == UNNECESSARY)
+ glxAttrs[sIndex] = i? GLX_USE_GL : GLX_STEREO ;
+ j = 0;
+ while(j <= doubleBufferLoop && vis_info == NULL) {
+ if(dbVal == PREFERRED || dbVal == UNNECESSARY) {
+ glxAttrs[dbIndex] = j? GLX_DOUBLEBUFFER : GLX_USE_GL;
+ }
+ vis_info = glXChooseVisual((Display*)display, screen, glxAttrs);
+ j++;
+ } /* end of doubleBufferLoop */
+ i++;
+ } /* end of stereoLoop */
+ }
+ return vis_info;
+}
+
+/*
+ * Uses the past in array to choose the best OpenGL visual.
+ * When the "best" visual cannot be used, the "enums" (three
+ * state attributes) are looped through setting/resetting in all
+ * combinations in hopes of finding an valid visual.
+ */
+JNIEXPORT
+jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_chooseOglVisual(
+ JNIEnv *env,
+ jobject obj,
+ jlong display,
+ jint screen,
+ jintArray attrList,
+ jlongArray vInfArray)
+{
+ VisualID vis_id = 0;
+ jint *mx_ptr;
+ int glxAttrs[256]; /* value, attr pair plus a None */
+ int index;
+ XVisualInfo *vis_info = NULL;
+
+ /* use to cycle through when attr is not REQUIRED */
+ int sVal;
+ int sIndex;
+
+ int dbVal;
+ int dbIndex;
+
+ int antialiasVal;
+ int antialiasIndex;
+
+ const char *glxExtensions = NULL;
+ jlong *visInfo = (*env)->GetLongArrayElements(env, vInfArray, NULL);
+
+ mx_ptr = (jint *)(*env)->GetPrimitiveArrayCritical(env, attrList, NULL);
+
+ /*
+ * convert Java 3D values to GLX
+ */
+ index = 0;
+ glxAttrs[index++] = GLX_RGBA; /* only interested in RGB visuals */
+ glxAttrs[index++] = GLX_RED_SIZE;
+ glxAttrs[index++] = mx_ptr[RED_SIZE];
+ glxAttrs[index++] = GLX_GREEN_SIZE;
+ glxAttrs[index++] = mx_ptr[GREEN_SIZE];
+ glxAttrs[index++] = GLX_BLUE_SIZE;
+ glxAttrs[index++] = mx_ptr[BLUE_SIZE];
+ glxAttrs[index++] = GLX_DEPTH_SIZE;
+ glxAttrs[index++] = mx_ptr[DEPTH_SIZE];
+
+
+ dbIndex = index++;
+ dbVal = mx_ptr[DOUBLEBUFFER];
+
+ sIndex = index++;
+ sVal = mx_ptr[STEREO];
+
+ antialiasIndex = index++;
+ antialiasVal = mx_ptr[ANTIALIASING];
+
+ /* glxAttrs[index] = None; */
+
+ (*env)->ReleasePrimitiveArrayCritical(env, attrList, mx_ptr, 0);
+
+
+ if(antialiasVal == REQUIRED || antialiasVal== PREFERRED) {
+ /* try GLX_ARB_multisample */
+ glxExtensions = (const char *)glXGetClientString((Display*)display, GLX_EXTENSIONS);
+
+
+ if(isExtensionSupported(glxExtensions, "GLX_ARB_multisample")){
+ /* path 1: */
+ /* Query the visual with mulitsamples */
+
+ index = antialiasIndex;
+ glxAttrs[index++] = GLX_SAMPLE_BUFFERS_ARB;
+ glxAttrs[index++] = 1;
+ glxAttrs[index++] = GLX_SAMPLES_ARB;
+ glxAttrs[index++] = 1;
+ glxAttrs[index++] = None;
+ vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex,
+ dbVal, dbIndex);
+
+ if(vis_info != NULL) {
+ vis_id = XVisualIDFromVisual(vis_info->visual);
+ visInfo[0] = (jlong)vis_info;
+ (*env)->ReleaseLongArrayElements(env, vInfArray, visInfo, 0);
+ return vis_id;
+ }
+ }
+ }
+
+ /* normal path */
+ if ( antialiasVal == REQUIRED || antialiasVal == PREFERRED) {
+ /* step 1 : enable antialiasing */
+ index = antialiasIndex;
+ glxAttrs[index++] = GLX_ACCUM_RED_SIZE;
+ glxAttrs[index++] = 8;
+ glxAttrs[index++] = GLX_ACCUM_GREEN_SIZE;
+ glxAttrs[index++] = 8;
+ glxAttrs[index++] = GLX_ACCUM_BLUE_SIZE;
+ glxAttrs[index++] = 8;
+ glxAttrs[index++] = None;
+ vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex,
+ dbVal, dbIndex);
+
+ if( vis_info == NULL) {
+ /* try disable antialiasing if it is PREFERRED */
+ if(antialiasVal == PREFERRED) {
+ glxAttrs[antialiasIndex] = None;
+ vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex,
+ dbVal, dbIndex);
+ }
+ }
+
+ visInfo[0] = (jlong)vis_info;
+ (*env)->ReleaseLongArrayElements(env, vInfArray, visInfo, 0);
+
+ if( vis_info != NULL) {
+ vis_id = XVisualIDFromVisual(vis_info->visual);
+ return vis_id;
+ } else {
+ return 0;
+ }
+ }
+
+
+ glxAttrs[antialiasIndex] = None;
+ vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex,
+ dbVal, dbIndex);
+
+ visInfo[0] = (jlong)vis_info;
+ (*env)->ReleaseLongArrayElements(env, vInfArray, visInfo, 0);
+
+ if( vis_info != NULL) {
+ vis_id = XVisualIDFromVisual(vis_info->visual);
+ return vis_id;
+ } else {
+ return 0;
+ }
+}
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_freeVisual(
+ JNIEnv *env,
+ jclass class, /* this is a static native method */
+ jlong visInfo)
+{
+ XFree((XVisualInfo *)visInfo);
+}
+
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isStereoAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong display,
+ jint screen,
+ jint vid)
+{
+ Display *dpy = (Display*) display;
+ XVisualInfo *vinfo, template;
+ int nitems;
+ int stereoFlag;
+ static GLboolean first_time = GL_TRUE;
+ static GLboolean force_no_stereo = GL_FALSE;
+
+ if (first_time) {
+ if (getenv("J3D_NO_STEREO") != NULL) {
+ fprintf(stderr, "Java 3D: stereo mode disabled\n");
+ force_no_stereo = GL_TRUE;
+ }
+ first_time = GL_FALSE;
+ }
+
+ if (force_no_stereo)
+ return JNI_FALSE;
+
+ template.visualid = vid;
+ vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems);
+ if (nitems != 1) {
+ fprintf(stderr, "Warning Canvas3D_isStereoAvailable got unexpected number of matching visuals %d\n", nitems);
+ }
+
+ glXGetConfig(dpy, vinfo, GLX_STEREO, &stereoFlag);
+
+ return (stereoFlag ? JNI_TRUE : JNI_FALSE);
+}
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isDoubleBufferAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong display,
+ jint screen,
+ jint vid)
+{
+ Display *dpy = (Display*) display;
+ XVisualInfo *vinfo, template;
+ int nitems;
+ int doubleBufferFlag;
+
+ template.visualid = vid;
+ vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems);
+ if (nitems != 1) {
+ fprintf(stderr, "Warning Canvas3D_isDoubleBufferAvailable got unexpected number of matching visuals %d\n", nitems);
+ }
+
+ glXGetConfig(dpy, vinfo, GLX_DOUBLEBUFFER, &doubleBufferFlag);
+
+ return (doubleBufferFlag ? JNI_TRUE : JNI_FALSE);
+}
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingAccumAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong display,
+ jint screen,
+ jint vid)
+{
+ Display *dpy = (Display*) display;
+ XVisualInfo *vinfo, template;
+ int nitems;
+ int numAccumRedBits;
+
+ template.visualid = vid;
+ vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems);
+ if (nitems != 1) {
+ fprintf(stderr, "Warning Canvas3D_isSceneAntialiasingAvailable got unexpected number of matching visuals %d\n", nitems);
+ }
+
+ glXGetConfig(dpy, vinfo, GLX_ACCUM_RED_SIZE, &numAccumRedBits);
+
+ return (numAccumRedBits > 0 ? JNI_TRUE : JNI_FALSE);
+}
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingMultiSamplesAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong display,
+ jint screen,
+ jint vid)
+{
+ Display *dpy = (Display*) display;
+ XVisualInfo *vinfo, template;
+ int nitems;
+
+ const char *glxExtensions;
+ int numSampleBuffers;
+ int numSamples;
+
+ template.visualid = vid;
+ vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems);
+ if (nitems != 1) {
+ fprintf(stderr, "Warning Canvas3D_isSceneAntialiasingAvailable got unexpected number of matching visuals %d\n", nitems);
+ }
+ /* try GLX_ARB_multisample */
+ glxExtensions = (const char *)glXGetClientString((Display*)display, GLX_EXTENSIONS);
+
+ if(isExtensionSupported(glxExtensions, "GLX_ARB_multisample")){
+ glXGetConfig(dpy, vinfo, GLX_SAMPLE_BUFFERS_ARB, &numSampleBuffers);
+ glXGetConfig(dpy, vinfo, GLX_SAMPLES_ARB, &numSamples);
+ if(numSampleBuffers > 0 && numSamples > 1){
+ return JNI_TRUE;
+ }
+ }
+
+ return JNI_FALSE;
+}
+
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_J3dGraphicsConfig_isValidVisualID(
+ JNIEnv *env,
+ jclass cls,
+ jlong display,
+ jint vid)
+{
+ XVisualInfo template;
+ int nitems;
+
+ template.visualid = vid;
+ XGetVisualInfo((Display *)display, VisualIDMask, &template, &nitems);
+ return (nitems == 1);
+
+}
+#endif /* SOLARIS || __linux__ */
+
+
+#ifdef WIN32
+
+extern HWND createDummyWindow(const char* szAppName);
+
+/*
+void printPixelDescriptor(PIXELFORMATDESCRIPTOR *pfd)
+{
+
+ printf("color : r=%d, g=%d, b=%d, a=%d, shift r=%d, g=%d, b=%d, a=%d\n",
+ pfd->cRedBits, pfd->cGreenBits, pfd->cBlueBits, pfd->cAlphaBits,
+ pfd->cRedShift, pfd->cGreenShift, pfd->cBlueShift, pfd->cAlphaShift);
+ printf("Accum r=%d, g=%d, b=%d, a=%d, depth %d, stencil %d, AuxBuffers %d\n",
+ pfd->cAccumRedBits, pfd->cAccumGreenBits, pfd->cAccumBlueBits,
+ pfd->cAccumAlphaBits, pfd->cDepthBits, pfd->cStencilBits, pfd->cAuxBuffers);
+ printf("iLayerType %x, bReserved %x, dwLayerMask %x, dwVisibleMask %x, dwDamageMask %x\n",
+ pfd->iLayerType, pfd->bReserved, pfd->dwLayerMask, pfd->dwVisibleMask, pfd->dwDamageMask);
+ if (pfd->dwFlags & PFD_SUPPORT_OPENGL) {
+ printf("SUPPORT_OPENGL ");
+ }
+ if (pfd->dwFlags & PFD_DRAW_TO_WINDOW) {
+ printf("DRAW_TO_WINDOW ");
+ }
+ if (pfd->dwFlags & PFD_DRAW_TO_BITMAP) {
+ printf("DRAW_TO_BITMAP ");
+ }
+ if (pfd->dwFlags & PFD_SUPPORT_GDI) {
+ printf("SUPPORT_GDI ");
+ }
+ if (pfd->dwFlags & PFD_SUPPORT_GDI) {
+ printf("NEED_PALETTE ");
+ }
+ if (pfd->dwFlags & PFD_SUPPORT_GDI) {
+ printf("NEED_SYSTEM_PALETTE ");
+ }
+ if (pfd->dwFlags & PFD_STEREO) {
+ printf("STEREO ");
+ }
+ if (pfd->dwFlags & PFD_SUPPORT_GDI) {
+ printf("SWAP_LAYER_BUFFERS ");
+ }
+ if (pfd->dwFlags & PFD_GENERIC_FORMAT) {
+ printf("PFD_GENERIC_FORMAT ");
+ }
+ if (pfd->dwFlags & PFD_GENERIC_ACCELERATED) {
+ printf("PFD_GENERIC_FORMAT ");
+ }
+ if (pfd->dwFlags & PFD_DOUBLEBUFFER) {
+ printf("PFD_DOUBLEBUFFER ");
+ }
+ printf("\n");
+
+}
+
+*/
+
+BOOL isSupportedWGL(const char * extensions, const char *extension_string) {
+ /* get the list of supported extensions */
+ const char *p = extensions;
+
+ /* search for extension_string in the list */
+ while(p = strstr(p, extension_string)){
+ const char *q = p + strlen(extension_string);
+
+ /* must be terminated by <space> or <nul> */
+ if(*q == ' ' || *q == '\0') {
+ return TRUE;
+ }
+
+ /* try to find another match */
+ p = q;
+ }
+ return FALSE;
+}
+
+HDC getMonitorDC(int screen)
+{
+ return CreateDC("DISPLAY", NULL, NULL, NULL);
+}
+
+int findPixelFormatSwitchDoubleBufferAndStereo (PIXELFORMATDESCRIPTOR* pfd, HDC hdc, int *mx_ptr)
+{
+
+ int pf;
+
+ pf = ChoosePixelFormat(hdc, pfd);
+
+ /* Check if pixel format support min. requirement */
+ DescribePixelFormat(hdc, pf, sizeof(*pfd), pfd);
+
+ if ((pfd->cRedBits < (unsigned char) mx_ptr[RED_SIZE]) ||
+ (pfd->cGreenBits < (unsigned char) mx_ptr[GREEN_SIZE]) ||
+ (pfd->cBlueBits < (unsigned char) mx_ptr[BLUE_SIZE]) ||
+ (pfd->cDepthBits < (unsigned char) mx_ptr[DEPTH_SIZE]) ||
+ ((mx_ptr[DOUBLEBUFFER] == REQUIRED) && ((pfd->dwFlags & PFD_DOUBLEBUFFER) == 0)) ||
+ ((mx_ptr[STEREO] == REQUIRED) && ((pfd->dwFlags & PFD_STEREO) == 0)))
+ {
+ return -1;
+ }
+
+ if ((mx_ptr[ANTIALIASING] == REQUIRED) &&
+ ((pfd->cAccumRedBits <= 0) ||
+ (pfd->cAccumGreenBits <= 0) ||
+ (pfd->cAccumBlueBits <= 0)))
+ {
+ return -1;
+ }
+ return pf;
+}
+
+
+void printErrorMessage(char *message)
+{
+ DWORD err;
+ char * errString;
+
+ err = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, 0, (LPTSTR)&errString, 0, NULL);
+ fprintf(stderr, "%s - %s\n", message, errString);
+ LocalFree(errString);
+}
+
+/* Prefer multiSample in following order
+ 4, 5, 6, 3, 7, 8, 2, 9, 10, 11, ...
+*/
+int getMultiSampleScore(int s)
+{
+ static int multiSampleScore[9] = {9999, 9999, 6, 3, 0, 1, 2, 4, 5};
+
+ if (s < 9) {
+ return multiSampleScore[s];
+ }
+ return s-2;
+}
+
+
+/* Max no of format wglChoosePixelFormatEXT can return */
+#define NFORMAT 100
+
+int getExtPixelFormat(int *nativeConfigAttrs)
+{
+ static const BOOL debug = FALSE;
+ static char szAppName[] = "Choose Pixel Format";
+
+ static PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR),
+ 1, /* Version number */
+ PFD_DRAW_TO_WINDOW |
+ PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ 16, /* 16 bit color depth */
+ 0, 0, 0, /* RGB bits and pixel sizes */
+ 0, 0, 0, /* Do not care about them */
+ 0, 0, /* no alpha buffer info */
+ 0, 0, 0, 0, 0, /* no accumulation buffer */
+ 8, /* 8 bit depth buffer */
+ 0, /* no stencil buffer */
+ 0, /* no auxiliary buffers */
+ PFD_MAIN_PLANE, /* layer type */
+ 0, /* reserved, must be 0 */
+ 0, /* no layer mask */
+ 0, /* no visible mask */
+ 0 /* no damage mask */
+ };
+
+ HWND hwnd;
+ HGLRC hrc;
+ HDC hdc;
+ int attr[22];
+ int piValues[12];
+ int i, idx;
+ int pNumFormats[NFORMAT], nAvailableFormat;
+ const char* supportedExtensions;
+ int score;
+ int highestScore, highestScorePF;
+ int highestScoreAlpha, lowestScoreMultiSample;
+
+ /* declare function pointers for WGL functions */
+ PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT = NULL;
+ PFNWGLCHOOSEPIXELFORMATEXTPROC wglChoosePixelFormatEXT = NULL;
+ PFNWGLGETPIXELFORMATATTRIBIVEXTPROC wglGetPixelFormatAttribivEXT = NULL;
+
+ /*
+ * Select any pixel format and bound current context to
+ * it so that we can get the wglChoosePixelFormatARB entry point.
+ * Otherwise wglxxx entry point will always return null.
+ * That's why we need to create a dummy window also.
+ */
+ hwnd = createDummyWindow((const char *)szAppName);
+
+ if (!hwnd) {
+ return -1;
+ }
+ hdc = GetDC(hwnd);
+
+ pNumFormats[0] = ChoosePixelFormat(hdc, &pfd);
+ if (!pNumFormats[0]) {
+ printErrorMessage("Failed in ChoosePixelFormat");
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+
+ SetPixelFormat(hdc, pNumFormats[0], &pfd);
+
+ hrc = wglCreateContext(hdc);
+ if (!hrc) {
+ printErrorMessage("Failed in wglCreateContext");
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+
+ if (!wglMakeCurrent(hdc, hrc)) {
+ printErrorMessage("Failed in wglMakeCurrent");
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+
+ wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
+ wglGetProcAddress("wglGetExtensionsStringARB");
+
+ if (wglGetExtensionsStringEXT == NULL) {
+ wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
+ wglGetProcAddress("wglGetExtensionsStringEXT");
+ if (wglGetExtensionsStringEXT == NULL) {
+ if (debug) {
+ printf("wglGetExtensionsStringEXT/ARB not support !\n");
+ }
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+ if (debug) {
+ printf("Support wglGetExtensionsStringEXT\n");
+ }
+ } else {
+ if (debug) {
+ printf("Support wglGetExtensionsStringARB\n");
+ }
+ }
+
+ /* get the list of supported extensions */
+ supportedExtensions = (const char *)wglGetExtensionsStringEXT(hdc);
+
+ if (debug) {
+ fprintf(stderr, "WGL Supported extensions: %s.\n", supportedExtensions);
+ }
+
+ if (!isSupportedWGL(supportedExtensions, "WGL_ARB_multisample") &&
+ !isSupportedWGL(supportedExtensions, "WGL_EXT_multisample") &&
+ !isSupportedWGL(supportedExtensions, "WGL_SGIS_multisample")) {
+
+ /* Under Wildcat III it doesn't use wglGetExtensionString */
+ supportedExtensions = (char *) glGetString(GL_EXTENSIONS);
+
+ if (debug) {
+ fprintf(stderr, "GL Supported extensions: %s.\n", supportedExtensions);
+ }
+
+ if (!isSupportedWGL(supportedExtensions, "GL_ARB_multisample") &&
+ !isSupportedWGL(supportedExtensions, "GL_EXT_multisample") &&
+ !isSupportedWGL(supportedExtensions, "GL_SGIS_multisample")) {
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+ }
+
+ wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC)
+ wglGetProcAddress("wglChoosePixelFormatARB");
+
+ if (wglChoosePixelFormatEXT == NULL) {
+ wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC)
+ wglGetProcAddress("wglChoosePixelFormatEXT");
+ if (wglChoosePixelFormatEXT == NULL) {
+ if (debug) {
+ printf("wglChoosePixelFormatARB/EXT not support !\n");
+ }
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+ if (debug) {
+ printf("Support wglChoosePixelFormatEXT\n");
+ }
+ } else {
+ if (debug) {
+ printf("Support wglChoosePixelFormatARB\n");
+ }
+ }
+
+ idx = 0;
+ attr[idx++] = WGL_SUPPORT_OPENGL_EXT;
+ attr[idx++] = TRUE;
+ attr[idx++] = WGL_DRAW_TO_WINDOW_EXT;
+ attr[idx++] = TRUE;
+ attr[idx++] = WGL_RED_BITS_EXT;
+ attr[idx++] = nativeConfigAttrs[RED_SIZE];
+ attr[idx++] = WGL_GREEN_BITS_EXT;
+ attr[idx++] = nativeConfigAttrs[GREEN_SIZE];
+ attr[idx++] = WGL_BLUE_BITS_EXT;
+ attr[idx++] = nativeConfigAttrs[BLUE_SIZE];
+ attr[idx++] = WGL_DEPTH_BITS_EXT;
+ attr[idx++] = nativeConfigAttrs[DEPTH_SIZE];
+
+ if (nativeConfigAttrs[DOUBLEBUFFER] == REQUIRED) {
+ attr[idx++] = WGL_DOUBLE_BUFFER_EXT;
+ attr[idx++] = TRUE;
+ }
+ if (nativeConfigAttrs[STEREO] == REQUIRED) {
+ attr[idx++] = WGL_STEREO_EXT;
+ attr[idx++] = TRUE;
+ }
+
+ if (nativeConfigAttrs[ANTIALIASING] == REQUIRED) {
+ attr[idx++] = WGL_SAMPLE_BUFFERS_ARB;
+ attr[idx++] = TRUE;
+ attr[idx++] = WGL_SAMPLES_ARB;
+ attr[idx++] = 2;
+ }
+
+ /*
+ * Terminate by 2 zeros to avoid driver bugs
+ * that assume attributes always come in pairs.
+ */
+ attr[idx++] = 0;
+ attr[idx++] = 0;
+
+ if (!wglChoosePixelFormatEXT(hdc, (const int *)attr, NULL, NFORMAT,
+ pNumFormats, &nAvailableFormat)) {
+ printErrorMessage("Failed in wglChoosePixelFormatEXT");
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+
+ if (debug) {
+ printf("No. of available pixel format is: %d\n", nAvailableFormat);
+ }
+
+ if (nAvailableFormat <= 0) {
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+
+ wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)
+ wglGetProcAddress("wglGetPixelFormatAttribivARB");
+
+ if (wglGetPixelFormatAttribivEXT == NULL) {
+ wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)
+ wglGetProcAddress("wglGetPixelFormatAttribivEXT");
+
+ if (wglGetPixelFormatAttribivEXT == NULL) {
+ if (debug) {
+ printf("wglGetPixelFormatAttribivEXT/ARB not support !\n");
+ }
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+ if (debug) {
+ printf("Support wglGetPixelFormatAttribivEXT\n");
+ }
+ } else {
+ if (debug) {
+ printf("Support wglGetPixelFormatAttribivARB\n");
+ }
+ }
+
+ idx = 0;
+ attr[idx++] = WGL_ACCELERATION_EXT;
+ attr[idx++] = WGL_RED_BITS_EXT;
+ attr[idx++] = WGL_GREEN_BITS_EXT;
+ attr[idx++] = WGL_BLUE_BITS_EXT;
+ attr[idx++] = WGL_ALPHA_BITS_EXT;
+ attr[idx++] = WGL_DEPTH_BITS_EXT;
+ attr[idx++] = WGL_STENCIL_BITS_EXT;
+ attr[idx++] = WGL_SAMPLE_BUFFERS_ARB;
+ attr[idx++] = WGL_SAMPLES_ARB;
+ attr[idx++] = WGL_DOUBLE_BUFFER_EXT;
+ attr[idx++] = WGL_STEREO_EXT;
+ attr[idx] = 0;
+
+ /* Select the best pixel format based on score */
+ highestScore = 0;
+ highestScorePF = -1;
+ highestScoreAlpha = 0;
+ lowestScoreMultiSample = 9999;
+
+ for (i=0; i < nAvailableFormat; i++) {
+ if (!wglGetPixelFormatAttribivEXT(hdc, pNumFormats[i], 0, idx, attr, piValues)) {
+ printErrorMessage("Failed in wglGetPixelFormatAttribivEXT");
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+ if (debug) {
+ printf("Format %d\n", pNumFormats[i]);
+
+ if (piValues[0] == WGL_FULL_ACCELERATION_EXT) {
+ printf("WGL_FULL_ACCELERATION_EXT");
+ } else if (piValues[0] == WGL_GENERIC_ACCELERATION_EXT) {
+ printf("WGL_GENERIC_ACCELERATION_EXT");
+ } else {
+ printf("WGL_NO_ACCELERATION_EXT");
+ }
+
+ printf(" R %d, G %d, B %d, A %d, Depth %d, Stencil %d",
+ piValues[1], piValues[2], piValues[3], piValues[4],
+ piValues[5], piValues[6]);
+
+ if (piValues[7] == TRUE) {
+ printf(" MultiSample %d", piValues[8]);
+ }
+
+ if (piValues[9] == TRUE) {
+ printf(" DoubleBuffer");
+ }
+
+ if (piValues[10] == TRUE) {
+ printf(" Stereo");
+ }
+ printf("\n");
+ }
+
+ /* Red, Green, Blue are fixed under windows so they are not checked */
+ score = 0;
+
+ if (piValues[0] == WGL_FULL_ACCELERATION_EXT) {
+ score += 20000;
+ } else if (piValues[0] == WGL_GENERIC_ACCELERATION_EXT) {
+ score += 10000;
+ }
+ if ((nativeConfigAttrs[DOUBLEBUFFER] == PREFERRED) &&
+ (piValues[9] == TRUE)) {
+ score += 5000;
+ }
+ if (piValues[4] > 0) { /* Alpha */
+ score += 2500;
+ }
+ if ((nativeConfigAttrs[STEREO] == PREFERRED) &&
+ (piValues[10] == TRUE)) {
+ score += 1250;
+ }
+ if ((nativeConfigAttrs[ANTIALIASING] == PREFERRED) &&
+ (piValues[7] == TRUE)) {
+ score += 624;
+ }
+
+ /* Stencil bit * 10 + Depth bit */
+ score += piValues[6]*10 + piValues[5];
+
+ if (score > highestScore) {
+ highestScore = score;
+ highestScorePF = i;
+ highestScoreAlpha = piValues[4];
+ lowestScoreMultiSample = getMultiSampleScore(piValues[8]);
+ } else if (score == highestScore) {
+ if (piValues[4] > highestScoreAlpha) {
+ highestScore = score;
+ highestScorePF = i;
+ highestScoreAlpha = piValues[4];
+ lowestScoreMultiSample = getMultiSampleScore(piValues[8]);
+ } else if (piValues[4] == highestScoreAlpha) {
+ if (getMultiSampleScore(piValues[8]) < lowestScoreMultiSample) {
+ highestScore = score;
+ highestScorePF = i;
+ highestScoreAlpha = piValues[4];
+ lowestScoreMultiSample = getMultiSampleScore(piValues[8]);
+ }
+ }
+ }
+
+ }
+
+ if (debug) {
+ printf("Select Pixel Format %d\n", pNumFormats[highestScorePF]);
+ }
+
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return pNumFormats[highestScorePF];
+}
+
+
+JNIEXPORT
+jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_choosePixelFormat(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint screen,
+ jintArray attrList)
+{
+ int *mx_ptr;
+ int dbVal; /* value for double buffering */
+ int sVal; /* value for stereo */
+ HDC hdc;
+ int pf; /* PixelFormat */
+ PIXELFORMATDESCRIPTOR pfd;
+
+ mx_ptr = (int *)(*env)->GetIntArrayElements(env, attrList, NULL);
+
+ if (mx_ptr[ANTIALIASING] != UNNECESSARY) {
+ pf = getExtPixelFormat(mx_ptr);
+ if (pf > 0) {
+ return pf;
+ }
+
+ /* fallback to use standard ChoosePixelFormat and accumulation buffer */
+ }
+
+ hdc = getMonitorDC(screen);
+
+ ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
+ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ pfd.nVersion = 1; /*TODO: when would this change? */
+ pfd.iPixelType = PFD_TYPE_RGBA;
+
+ /*
+ * Convert Java 3D values to PixelFormat
+ */
+
+ pfd.cRedBits = (unsigned char) mx_ptr[RED_SIZE];
+ pfd.cGreenBits = (unsigned char) mx_ptr[GREEN_SIZE];
+ pfd.cBlueBits = (unsigned char) mx_ptr[BLUE_SIZE];
+ pfd.cDepthBits = (unsigned char) mx_ptr[DEPTH_SIZE];
+
+ if (mx_ptr[DOUBLEBUFFER] == REQUIRED || mx_ptr[DOUBLEBUFFER] == PREFERRED)
+ dbVal = PFD_DOUBLEBUFFER;
+ else
+ dbVal = PFD_DOUBLEBUFFER_DONTCARE;
+
+ sVal = 0;
+ if (mx_ptr[STEREO] == REQUIRED || mx_ptr[STEREO] == PREFERRED) {
+ sVal = PFD_STEREO;
+ } else {
+ sVal = 0;
+ }
+
+ pfd.dwFlags = dbVal | sVal | PFD_SUPPORT_OPENGL;
+ pfd.cStencilBits = 2;
+
+ if (mx_ptr[ANTIALIASING] == REQUIRED || mx_ptr[ANTIALIASING] == PREFERRED) {
+ pfd.cAccumRedBits = 8;
+ pfd.cAccumGreenBits = 8;
+ pfd.cAccumBlueBits = 8;
+ }
+
+ pf = findPixelFormatSwitchDoubleBufferAndStereo(&pfd, hdc, mx_ptr);
+
+ if (pf == -1) {
+ /* try disable stencil buffer */
+ pfd.cStencilBits = 0;
+ pf = findPixelFormatSwitchDoubleBufferAndStereo(&pfd, hdc, mx_ptr);
+
+ if (pf == -1) {
+ /* try disable accumulate buffer */
+ if (mx_ptr[ANTIALIASING] == PREFERRED) {
+ pfd.cStencilBits = 2;
+ pfd.cAccumRedBits = 0;
+ pfd.cAccumGreenBits = 0;
+ pfd.cAccumBlueBits = 0;
+ pf = findPixelFormatSwitchDoubleBufferAndStereo(&pfd, hdc, mx_ptr);
+
+ if (pf == -1) {
+ /* try disable stencil buffer */
+ pfd.cStencilBits = 0;
+ pf = findPixelFormatSwitchDoubleBufferAndStereo(&pfd, hdc, mx_ptr);
+ }
+ }
+ }
+ }
+
+ DeleteDC(hdc);
+
+ (*env)->ReleaseIntArrayElements(env, attrList, mx_ptr, JNI_ABORT);
+ return pf;
+}
+
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isStereoAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong display,
+ jint screen,
+ jint pixelFormat)
+{
+ HDC hdc; /* HW Device Context */
+
+ PIXELFORMATDESCRIPTOR pfd;
+
+ static GLboolean first_time = GL_TRUE;
+ static GLboolean force_no_stereo = GL_FALSE;
+
+ if (first_time) {
+ if (getenv("J3D_NO_STEREO") != NULL) {
+ fprintf(stderr, "Java 3D: stereo mode disabled\n");
+ force_no_stereo = GL_TRUE;
+ }
+ first_time = GL_FALSE;
+ }
+
+ if (force_no_stereo)
+ return JNI_FALSE;
+
+ hdc = getMonitorDC(screen);
+
+ /* Check the chosen PixelFormat to see if it is stereo capable */
+ DescribePixelFormat(hdc, pixelFormat, sizeof(pfd), &pfd);
+
+ DeleteDC(hdc);
+ if (pfd.dwFlags & PFD_STEREO)
+ return JNI_TRUE;
+ else
+ return JNI_FALSE;
+
+ return JNI_TRUE;
+}
+
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isDoubleBufferAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong display,
+ jint screen,
+ jint pixelFormat)
+{
+ HDC hdc; /* HW Device Context */
+
+ PIXELFORMATDESCRIPTOR pfd;
+
+ hdc = getMonitorDC(screen);
+
+ /* Check the chosen PixelFormat to see if it is doubleBuffer capable */
+ DescribePixelFormat(hdc, pixelFormat, sizeof(pfd), &pfd);
+
+ DeleteDC(hdc);
+ if (pfd.dwFlags & PFD_DOUBLEBUFFER)
+ return JNI_TRUE;
+ else
+ return JNI_FALSE;
+}
+
+
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingAccumAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong display,
+ jint screen,
+ jint pixelFormat)
+{
+ HDC hdc; /* HW Device Context */
+ PIXELFORMATDESCRIPTOR pfd;
+
+ hdc = getMonitorDC(screen);
+ /* Check the chosen PixelFormat to see if it is sceneAntialiasing capable */
+ DescribePixelFormat(hdc, pixelFormat, sizeof(pfd), &pfd);
+
+ DeleteDC(hdc);
+ if (pfd.cAccumRedBits > 0)
+ return JNI_TRUE;
+ else
+ return JNI_FALSE;
+}
+
+JNIEXPORT
+jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingMultiSamplesAvailable(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong display,
+ jint screen,
+ jint pixelFormat)
+{
+ static char szAppName[] = "Choose Pixel Format";
+ HWND hwnd;
+ HGLRC hrc;
+ HDC hdc;
+ int attr[3];
+ int piValues[2];
+ int pf;
+ BOOL support;
+
+ static PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR),
+ 1, /* Version number */
+ PFD_DRAW_TO_WINDOW |
+ PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ 16, /* 16 bit color depth */
+ 0, 0, 0, /* RGB bits and pixel sizes */
+ 0, 0, 0, /* Do not care about them */
+ 0, 0, /* no alpha buffer info */
+ 0, 0, 0, 0, 0, /* no accumulation buffer */
+ 8, /* 8 bit depth buffer */
+ 0, /* no stencil buffer */
+ 0, /* no auxiliary buffers */
+ PFD_MAIN_PLANE, /* layer type */
+ 0, /* reserved, must be 0 */
+ 0, /* no layer mask */
+ 0, /* no visible mask */
+ 0 /* no damage mask */
+ };
+
+ PFNWGLGETPIXELFORMATATTRIBIVEXTPROC wglGetPixelFormatAttribivEXT = NULL;
+
+ hwnd = createDummyWindow((const char *)szAppName);
+
+ if (!hwnd) {
+ return -1;
+ }
+ hdc = GetDC(hwnd);
+
+ pf = ChoosePixelFormat(hdc, &pfd);
+ if (!pf) {
+ printErrorMessage("Failed in ChoosePixelFormat");
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+
+ SetPixelFormat(hdc, pf, &pfd);
+
+ hrc = wglCreateContext(hdc);
+ if (!hrc) {
+ printErrorMessage("Failed in wglCreateContext");
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+
+ if (!wglMakeCurrent(hdc, hrc)) {
+ printErrorMessage("Failed in wglMakeCurrent");
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return -1;
+ }
+
+ wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)
+ wglGetProcAddress("wglGetPixelFormatAttribivARB");
+
+ if (wglGetPixelFormatAttribivEXT == NULL) {
+ wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)
+ wglGetProcAddress("wglGetPixelFormatAttribivEXT");
+
+ if (wglGetPixelFormatAttribivEXT == NULL) {
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return FALSE;
+ }
+ }
+
+ attr[0] = WGL_SAMPLE_BUFFERS_ARB;
+ attr[1] = WGL_SAMPLES_ARB;
+ attr[2] = 0;
+ support = FALSE;
+
+ if (wglGetPixelFormatAttribivEXT(hdc, pixelFormat, 0, 2, attr, piValues)) {
+ if ((piValues[0] == TRUE) && (piValues[1] > 1)) {
+ support = TRUE;
+ }
+ }
+
+ ReleaseDC(hwnd, hdc);
+ wglDeleteContext(hrc);
+ DestroyWindow(hwnd);
+ UnregisterClass(szAppName, (HINSTANCE)NULL);
+ return support;
+}
+#endif /* WIN32 */
diff --git a/src/native/ogl/NativeScreenInfo.c b/src/native/ogl/NativeScreenInfo.c
new file mode 100644
index 0000000..c92900c
--- /dev/null
+++ b/src/native/ogl/NativeScreenInfo.c
@@ -0,0 +1,65 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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.
+ */
+
+#include <jni.h>
+#include <math.h>
+
+#include "gldefs.h"
+
+#if defined(SOLARIS) || defined(__linux__)
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#if defined(SOLARIS) || defined(__linux__)
+/*
+ * Class: javax_media_j3d_NativeScreenInfo
+ * Method: openDisplay
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL
+Java_javax_media_j3d_NativeScreenInfo_openDisplay(
+ JNIEnv *env,
+ jobject obj)
+{
+ Display* dpy;
+ dpy = XOpenDisplay(NULL);
+ return (jlong)dpy;
+}
+
+
+/*
+ * Class: javax_media_j3d_NativeScreenInfo
+ * Method: getDefaultScreen
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL
+Java_javax_media_j3d_NativeScreenInfo_getDefaultScreen(
+ JNIEnv *env,
+ jobject obj,
+ jlong display)
+{
+ Display* dpy = (Display*)display;
+ return (jint)DefaultScreen(dpy);
+}
+#endif
diff --git a/src/native/ogl/NativeWSInfo.c b/src/native/ogl/NativeWSInfo.c
new file mode 100644
index 0000000..be1a1fc
--- /dev/null
+++ b/src/native/ogl/NativeWSInfo.c
@@ -0,0 +1,78 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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.
+ */
+
+#include <jni.h>
+#include <math.h>
+
+#include "gldefs.h"
+
+#if defined(SOLARIS) || defined(__linux__)
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#ifdef WIN32
+
+/*
+ * Workaround for bug 4169320: Resizing a Java 3D canvas
+ * on Win95 crashes the application
+ */
+
+#ifdef STRICT
+static WNDPROC g_lpDefWindowProc;
+#else
+static FARPROC g_lpDefWindowProc;
+#endif
+
+static
+LRESULT CALLBACK canvas3dWndProc(
+ HWND hWnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ switch (message) {
+ case WM_WINDOWPOSCHANGED:
+ return 0;
+ default:
+ return CallWindowProc(g_lpDefWindowProc, hWnd, message,
+ wParam, lParam);
+ }
+}
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_NativeWSInfo_subclass(
+ JNIEnv * env,
+ jobject obj,
+ jint hWnd)
+{
+#ifdef STRICT
+ g_lpDefWindowProc = (WNDPROC) SetWindowLong((HWND) hWnd, GWL_WNDPROC,
+ (LONG) canvas3dWndProc);
+#else
+ g_lpDefWindowProc = (FARPROC) SetWindowLong((HWND) hWnd, GWL_WNDPROC,
+ (LONG) canvas3dWndProc);
+#endif
+}
+
+#endif
diff --git a/src/native/ogl/RasterRetained.c b/src/native/ogl/RasterRetained.c
new file mode 100644
index 0000000..775bb2f
--- /dev/null
+++ b/src/native/ogl/RasterRetained.c
@@ -0,0 +1,392 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#include <stdio.h>
+#include <jni.h>
+
+#include "gldefs.h"
+
+#ifdef DEBUG
+/* Uncomment the following for VERBOSE debug messages */
+/* #define VERBOSE */
+#endif /* DEBUG */
+
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_RasterRetained_execute(JNIEnv *env,
+ jobject obj, jlong ctxInfo, jobject geo,
+ jboolean updateAlpha, jfloat alpha,
+ jint type, jint w_raster, jint h_raster,
+ jint x_offset, jint y_offset, jfloat x, jfloat y, jfloat z, jbyteArray imageYdown)
+
+
+{
+ jclass geo_class;
+ JNIEnv table;
+
+ jfieldID w_field, h_field;
+ int width, height;
+
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ table = *env;
+
+ geo_class = (jclass) (*(table->GetObjectClass))(env, geo);
+
+#ifdef VERBOSE
+ fprintf(stderr,
+ "x %g ,y %g ,z %g ,w_raster %d,h_raster %d, x_offset %d, y_offset %d\n",
+ x,y,z,w_raster,h_raster,x_offset,y_offset);
+#endif
+
+ if ((type == javax_media_j3d_Raster_RASTER_COLOR) ||
+ (type == javax_media_j3d_Raster_RASTER_COLOR_DEPTH)) {
+ jobject image;
+ jclass image_class;
+ jfieldID image_field, format_field;
+ jbyte *byteData;
+ int format;
+ int glformat;
+
+ image_field = (jfieldID)(*(table->GetFieldID))(env, geo_class,
+ "image","Ljavax/media/j3d/ImageComponent2DRetained;");
+ image = (jobject) (*(table->GetObjectField))(env, geo, image_field);
+
+ if (image == NULL) {
+ return;
+ }
+ image_class = (jclass) (*(table->GetObjectClass))(env, image);
+
+ format_field = (jfieldID) (*(table->GetFieldID))(env, image_class,
+ "storedYdownFormat", "I");
+ format = (jint)(*(table->GetIntField))(env, image, format_field);
+ w_field = (jfieldID) (*(table->GetFieldID))(env, image_class,
+ "width", "I");
+ width = (jint)(*(table->GetIntField))(env, image, w_field);
+ h_field = (jfieldID)(*(table->GetFieldID))(env, image_class,
+ "height", "I");
+ height = (jint)(*(table->GetIntField))(env, image, h_field);
+
+
+ /*
+ * raster position is upper left corner, default for Java3D
+ * ImageComponent currently has the data reverse in Y
+ */
+ glPixelZoom(1.0, -1.0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
+ if (x_offset >= 0) {
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, x_offset);
+ if (x_offset + w_raster > width) {
+ w_raster = width - x_offset;
+ }
+ } else {
+ w_raster += x_offset;
+ if (w_raster > width) {
+ w_raster = width;
+ }
+ }
+ if (y_offset >= 0) {
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, y_offset);
+ if (y_offset + h_raster > height) {
+ h_raster = height - y_offset;
+ }
+ } else {
+ h_raster += y_offset;
+ if (h_raster > height) {
+ h_raster = height;
+ }
+ }
+
+
+
+ glRasterPos3f(x, y, z);
+
+ byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env,
+ imageYdown, NULL);
+
+/*
+ {
+ int i, j, *intData;
+
+ fprintf(stderr, "format = %d, w_raster = %d, h_raster = %d\n\n", format, w_raster, h_raster);
+ intData = (int*)byteData;
+ for (i = 0; i < w_raster; i++) {
+ for (j = 0; j < h_raster; j++, intData++) {
+ fprintf(stderr, " 0x%x", *intData);
+ }
+ fprintf(stderr, "\n");
+ }
+ }
+ */
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ glformat = GL_RGBA;
+ break;
+ case FORMAT_BYTE_RGB:
+ glformat = GL_RGB;
+ break;
+
+ case FORMAT_BYTE_ABGR:
+ if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */
+ glformat = GL_ABGR_EXT;
+ }
+ break;
+ case FORMAT_BYTE_BGR:
+ if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */
+ glformat = ctxProperties->bgr_ext_enum;
+ }
+ break;
+ case FORMAT_BYTE_LA:
+ glformat = GL_LUMINANCE_ALPHA;
+ break;
+ case FORMAT_BYTE_GRAY:
+ case FORMAT_USHORT_GRAY:
+ /* TODO: throw exception */
+ break;
+ }
+ glDrawPixels(w_raster, h_raster, glformat, GL_UNSIGNED_BYTE,
+ byteData);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env,
+ imageYdown, byteData, 0);
+ }
+
+ if ((type == javax_media_j3d_Raster_RASTER_DEPTH) ||
+ (type == javax_media_j3d_Raster_RASTER_COLOR_DEPTH)) {
+ GLint draw_buf;
+ jobject depth;
+ jclass depth_class;
+ jfieldID depth_field, depth_type_field;
+ int depth_type;
+
+ depth_field = (jfieldID)(*(table->GetFieldID))(env, geo_class,
+ "depthComponent","Ljavax/media/j3d/DepthComponentRetained;");
+
+ depth = (jobject) (*(table->GetObjectField))(env, geo, depth_field);
+ if (depth == NULL) {
+ return;
+ }
+ depth_class = (jclass) (*(table->GetObjectClass))(env, depth);
+
+ depth_type_field = (jfieldID) (*(table->GetFieldID))(env,
+ depth_class, "type", "I");
+ depth_type = (jint)(*(table->GetIntField))(env, depth,
+ depth_type_field);
+
+ w_field = (jfieldID) (*(table->GetFieldID))(env, depth_class,
+ "width", "I");
+ width = (jint)(*(table->GetIntField))(env, depth, w_field);
+ h_field = (jfieldID)(*(table->GetFieldID))(env, depth_class,
+ "height", "I");
+ height = (jint)(*(table->GetIntField))(env, depth, h_field);
+
+
+ glGetIntegerv(GL_DRAW_BUFFER, &draw_buf);
+ /* disable draw buffer */
+ glDrawBuffer(GL_NONE);
+ /* glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); */
+
+ /*
+ * raster position is upper left corner, default for Java3D
+ * ImageComponent currently has the data reverse in Y
+ */
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
+ if (x_offset >= 0) {
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, x_offset);
+ if (x_offset + w_raster > width) {
+ w_raster = width - x_offset;
+ }
+ } else {
+ w_raster += x_offset;
+ if (w_raster > width) {
+ w_raster = width;
+ }
+ }
+ if (y_offset >= 0) {
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, y_offset);
+ if (y_offset + h_raster > height) {
+ h_raster = height - y_offset;
+ }
+ } else {
+ h_raster += y_offset;
+ if (h_raster > height) {
+ h_raster = height;
+ }
+ }
+
+
+ if (depth_type == javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_INT) {
+ jfieldID intData_field;
+ jintArray intData_array;
+ jint *intData;
+
+ intData_field = (jfieldID)(*(table->GetFieldID))(env,
+ depth_class, "depthData","[I");
+
+ intData_array = (jintArray)(*(table->GetObjectField))(env, depth,
+ intData_field);
+ intData = (jint *)(*(table->GetPrimitiveArrayCritical))(env,
+ intData_array, NULL);
+ glDrawPixels(w_raster, h_raster, GL_DEPTH_COMPONENT,
+ GL_UNSIGNED_INT, intData);
+ (*(table->ReleasePrimitiveArrayCritical))(env, intData_array,
+ intData, 0);
+ } else { /* javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_FLOAT */
+ jfieldID floatData_field;
+ jfloatArray floatData_array;
+ jfloat *floatData;
+
+ floatData_field = (jfieldID)(*(table->GetFieldID))(env,
+ depth_class, "depthData","[F");
+ floatData_array = (jfloatArray)(*(table->GetObjectField))(env, depth,
+ floatData_field);
+ floatData = (jfloat *)(*(table->GetPrimitiveArrayCritical))(env,
+ floatData_array, NULL);
+ glDrawPixels(w_raster, h_raster, GL_DEPTH_COMPONENT,
+ GL_FLOAT, floatData);
+ (*(table->ReleasePrimitiveArrayCritical))(env, floatData_array,
+ floatData, 0);
+ }
+
+ /* re-enable draw buffer */
+ glDrawBuffer(draw_buf);
+
+ }
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+
+}
+
+
+#if 0
+
+JNIEXPORT
+void JNICALL Java_javax_media_j3d_RasterRetained_executeTiled(JNIEnv *env,
+ jobject obj, jlong ctxInfo, jobject geo,
+ jint format, jint w_raster, jint h_raster,
+ jint x_offset, jint y_offset, jint deltaw, jint deltah, jfloat x, jfloat y, jfloat z, jbyteArray tile)
+
+
+{
+ jclass geo_class;
+ JNIEnv table;
+ jint j;
+ int alphaChanged = 0; /* used so we can get alpha data from */
+ /* JNI before using it so we can use */
+ /* GetPrimitiveArrayCritical */
+ jobject image;
+ jclass image_class;
+ jfieldID byteData_field, image_field, format_field;
+ jbyteArray byteData_array;
+ jbyte *byteData;
+ int glformat;
+ float rasterPos[3];
+ GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo;
+ jlong ctx = ctxProperties->context;
+
+ table = *env;
+
+
+#ifdef VERBOSE
+ fprintf(stderr,
+ "x %g ,y %g ,z %g ,w_raster %d,h_raster %d, x_offset %d, y_offset %d\n",
+ x,y,z,w_raster,h_raster,x_offset,y_offset);
+#endif
+
+
+ /*
+ * raster position is upper left corner, default for Java3D
+ * ImageComponent currently has the data reverse in Y
+ */
+ glPixelZoom(1.0, -1.0);
+ /* glPixelStorei(GL_UNPACK_ROW_LENGTH, width);*/
+ if (x_offset >= 0) {
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, x_offset);
+ if (x_offset + w_raster > width) {
+ w_raster = width - x_offset;
+ }
+ } else {
+ w_raster += x_offset;
+ if (w_raster > width) {
+ w_raster = width;
+ }
+ }
+ if (y_offset >= 0) {
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, y_offset);
+ if (y_offset + h_raster > height) {
+ h_raster = height - y_offset;
+ }
+ } else {
+ h_raster += y_offset;
+ if (h_raster > height) {
+ h_raster = height;
+ }
+ }
+
+ if (deltaw == 0 && deltah == 0) {
+ glRasterPos3f(x, y, z);
+ }
+ else {
+ glGetFloatv(GL_CURRENT_RASTER_POSITION,rasterPos);
+ rasterPos[0] += (float)deltaw;
+ rasterPos[1] += (float)deltah;
+ glRasterPos3f(rasterPos[0], rasterPos[1], rasterPos[2]);
+ }
+
+
+
+ byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env,
+ tile, NULL);
+ switch (format) {
+ case FORMAT_BYTE_RGBA:
+ glformat = GL_RGBA;
+ break;
+ case FORMAT_BYTE_RGB:
+ glformat = GL_RGB;
+ break;
+
+ case FORMAT_BYTE_ABGR:
+ if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */
+ glformat = GL_ABGR_EXT;
+ }
+ break;
+
+
+ case FORMAT_BYTE_BGR:
+ if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */
+ glformat = ctxProperties->bgr_ext_enum;
+ }
+ break;
+
+ case FORMAT_BYTE_LA:
+ glformat = GL_LUMINANCE_ALPHA;
+ break;
+ case FORMAT_BYTE_GRAY:
+ case FORMAT_USHORT_GRAY:
+ /* TODO: throw exception */
+ break;
+ }
+ fprintf(stderr, "w_raster = %d, h_raster = %d, glformat = %d\n",w_raster, h_raster, glformat);
+ glDrawPixels(w_raster, h_raster, glformat, GL_UNSIGNED_BYTE,
+ byteData);
+
+ (*(table->ReleasePrimitiveArrayCritical))(env,
+ tile, byteData, 0);
+
+ /* glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);*/
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+
+}
+#endif
diff --git a/src/native/ogl/build-linux-i586.xml b/src/native/ogl/build-linux-i586.xml
new file mode 100644
index 0000000..1148118
--- /dev/null
+++ b/src/native/ogl/build-linux-i586.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native ogl renderer files for Solaris -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native renderer build [${bldType}]"/>
+
+ <!-- Create the build directories for linux -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/ogl/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/lib/i386"/>
+
+ <property name="oglsrc" location="${src}/native/ogl"/>
+
+ <!-- Compile the c source files-->
+ <!-- Inhibit all warning for 32 bit build. Any warning will be caught in the 64 bit build -->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs" executable="gcc">
+ <arg line="-w -m32 -mcpu=i386 -I${java.home}/../include -I${java.home}/../include/linux -I/usr/openwin/include -I${javahCoreTarget} -${bldFlag} -DLINUX -c ${oglsrc}/DrawingSurfaceObjectAWT.c ${oglsrc}/Canvas3D.c ${oglsrc}/GraphicsContext3D.c ${oglsrc}/NativeWSInfo.c ${oglsrc}/NativeScreenInfo.c ${oglsrc}/NativeConfigTemplate3D.c ${oglsrc}/MasterControl.c ${oglsrc}/RasterRetained.c ${oglsrc}/CompressedGeometryRetained.c ${oglsrc}/GeometryArrayRetained.c ${oglsrc}/Attributes.c ${oglsrc}/Lights.c ${oglsrc}/NativeAPIInfo.c"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs" executable="ld">
+ <arg line="DrawingSurfaceObjectAWT.o Canvas3D.o GraphicsContext3D.o NativeWSInfo.o NativeScreenInfo.o NativeConfigTemplate3D.o MasterControl.o RasterRetained.o CompressedGeometryRetained.o GeometryArrayRetained.o Attributes.o Lights.o NativeAPIInfo.o -G -z lazyload -L/usr/X11R6/lib -ldl -lGL -lX11 -lXext -lm -lnsl -lc -R/usr/openwin/lib -L${java.home}/lib/i386 -ljawt -L${java.home}/lib/i386/server -ljvm -o libj3dcore-ogl.so"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/ogl/objs/libj3dcore-ogl.so"
+ todir="${build}/${platform}/${bldType}/lib/i386"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/lib/i386"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/lib/i386/libj3dcore-ogl.so"
+ todir="${dist}/${platform}/lib/i386"/>
+
+ </target>
+
+</project>
diff --git a/src/native/ogl/build-solaris-sparc-forte.xml b/src/native/ogl/build-solaris-sparc-forte.xml
new file mode 100644
index 0000000..86d46d7
--- /dev/null
+++ b/src/native/ogl/build-solaris-sparc-forte.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native ogl renderer files for Solaris -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native renderer build [${bldType}]"/>
+
+ <!-- Create the build directories for sparc -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/ogl/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/lib/sparc"/>
+
+ <property name="oglsrc" location="${src}/native/ogl"/>
+
+ <!-- Compile the c source files-->
+ <!-- Inhibit all warning for 32 bit build. Any warning will be caught in the 64 bit build -->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs" executable="cc">
+ <arg line="-v -xCC -xchip=ultra -xarch=v8a -I${java.home}/../include -I${java.home}/../include/solaris -I/usr/openwin/include -I${javahCoreTarget} -${bldFlag} -DSOLARIS -c ${oglsrc}/DrawingSurfaceObjectAWT.c ${oglsrc}/Canvas3D.c ${oglsrc}/GraphicsContext3D.c ${oglsrc}/NativeWSInfo.c ${oglsrc}/NativeScreenInfo.c ${oglsrc}/NativeConfigTemplate3D.c ${oglsrc}/MasterControl.c ${oglsrc}/RasterRetained.c ${oglsrc}/CompressedGeometryRetained.c ${oglsrc}/GeometryArrayRetained.c ${oglsrc}/Attributes.c ${oglsrc}/Lights.c ${oglsrc}/NativeAPIInfo.c"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs" executable="ld">
+ <arg line="DrawingSurfaceObjectAWT.o Canvas3D.o GraphicsContext3D.o NativeWSInfo.o NativeScreenInfo.o NativeConfigTemplate3D.o MasterControl.o RasterRetained.o CompressedGeometryRetained.o GeometryArrayRetained.o Attributes.o Lights.o NativeAPIInfo.o -G -z lazyload -L/usr/openwin/lib -ldga -ldl -lGL -lX11 -lXext -lm -lsocket -lnsl -lc -R/usr/openwin/lib -L${java.home}/lib/sparc -ljawt -L${java.home}/lib/sparc/server -ljvm -o libj3dcore-ogl.so"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/ogl/objs/libj3dcore-ogl.so"
+ todir="${build}/${platform}/${bldType}/lib/sparc"/>
+
+<!-- ********************************************************************** -->
+ <echo message="Executing 64 bit native renderer build [${bldType}]"/>
+
+ <!-- Create the build directories for sparcv9 -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/ogl/objs/sparcv9"/>
+ <mkdir dir="${build}/${platform}/${bldType}/lib/sparcv9"/>
+
+ <!-- Compile the c source files-->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs/sparcv9" executable="cc">
+ <arg line="-v -xCC -xchip=ultra -xarch=v9a -I${java.home}/../include -I${java.home}/../include/solaris -I/usr/openwin/include -I${javahCoreTarget} -${bldFlag} -DSOLARIS -c ${oglsrc}/DrawingSurfaceObjectAWT.c ${oglsrc}/Canvas3D.c ${oglsrc}/GraphicsContext3D.c ${oglsrc}/NativeWSInfo.c ${oglsrc}/NativeScreenInfo.c ${oglsrc}/NativeConfigTemplate3D.c ${oglsrc}/MasterControl.c ${oglsrc}/RasterRetained.c ${oglsrc}/CompressedGeometryRetained.c ${oglsrc}/GeometryArrayRetained.c ${oglsrc}/Attributes.c ${oglsrc}/Lights.c ${oglsrc}/NativeAPIInfo.c"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs/sparcv9" executable="ld">
+ <arg line="DrawingSurfaceObjectAWT.o Canvas3D.o GraphicsContext3D.o NativeWSInfo.o NativeScreenInfo.o NativeConfigTemplate3D.o MasterControl.o RasterRetained.o CompressedGeometryRetained.o GeometryArrayRetained.o Attributes.o Lights.o NativeAPIInfo.o -G -z lazyload -L/usr/openwin/lib/sparcv9 -ldga -ldl -lGL -lX11 -lXext -lm -lsocket -lnsl -lc -R/usr/openwin/lib/sparcv9 -L${java.home}/lib/sparcv9 -ljawt -L${java.home}/lib/sparcv9/server -ljvm -o libj3dcore-ogl.so"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/ogl/objs/sparcv9/libj3dcore-ogl.so"
+ todir="${build}/${platform}/${bldType}/lib/sparcv9"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/lib/sparc"/>
+ <mkdir dir="${dist}/${platform}/lib/sparcv9"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/lib/sparc/libj3dcore-ogl.so"
+ todir="${dist}/${platform}/lib/sparc"/>
+
+ <copy file="${build}/${platform}/opt/lib/sparcv9/libj3dcore-ogl.so"
+ todir="${dist}/${platform}/lib/sparcv9"/>
+ </target>
+
+</project>
diff --git a/src/native/ogl/build-solaris-sparc-gcc.xml b/src/native/ogl/build-solaris-sparc-gcc.xml
new file mode 100644
index 0000000..33f8ebe
--- /dev/null
+++ b/src/native/ogl/build-solaris-sparc-gcc.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native ogl renderer files for Solaris -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native renderer build [${bldType}]"/>
+
+ <!-- Create the build directories for sparc -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/ogl/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/lib/sparc"/>
+
+ <property name="oglsrc" location="${src}/native/ogl"/>
+
+ <!-- Compile the c source files-->
+ <!-- Inhibit all warning for 32 bit build. Any warning will be caught in the 64 bit build -->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs" executable="gcc">
+ <arg line="-w -m32 -mcpu=v9 -I${java.home}/../include -I${java.home}/../include/solaris -I/usr/openwin/include -I${javahCoreTarget} -${bldFlag} -DSOLARIS -c ${oglsrc}/DrawingSurfaceObjectAWT.c ${oglsrc}/Canvas3D.c ${oglsrc}/GraphicsContext3D.c ${oglsrc}/NativeWSInfo.c ${oglsrc}/NativeScreenInfo.c ${oglsrc}/NativeConfigTemplate3D.c ${oglsrc}/MasterControl.c ${oglsrc}/RasterRetained.c ${oglsrc}/CompressedGeometryRetained.c ${oglsrc}/GeometryArrayRetained.c ${oglsrc}/Attributes.c ${oglsrc}/Lights.c ${oglsrc}/NativeAPIInfo.c"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs" executable="ld">
+ <arg line="DrawingSurfaceObjectAWT.o Canvas3D.o GraphicsContext3D.o NativeWSInfo.o NativeScreenInfo.o NativeConfigTemplate3D.o MasterControl.o RasterRetained.o CompressedGeometryRetained.o GeometryArrayRetained.o Attributes.o Lights.o NativeAPIInfo.o -G -z lazyload -L/usr/openwin/lib -ldga -ldl -lGL -lX11 -lXext -lm -lsocket -lnsl -lc -R/usr/openwin/lib -L${java.home}/lib/sparc -ljawt -L${java.home}/lib/sparc/server -ljvm -o libj3dcore-ogl.so"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/ogl/objs/libj3dcore-ogl.so"
+ todir="${build}/${platform}/${bldType}/lib/sparc"/>
+
+<!-- ********************************************************************** -->
+ <echo message="Executing 64 bit native renderer build [${bldType}]"/>
+
+ <!-- Create the build directories for sparcv9 -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/ogl/objs/sparcv9"/>
+ <mkdir dir="${build}/${platform}/${bldType}/lib/sparcv9"/>
+
+ <!-- Compile the c source files-->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs/sparcv9" executable="gcc">
+ <arg line="-m64 -mcpu=v9 -I${java.home}/../include -I${java.home}/../include/solaris -I/usr/openwin/include -I${javahCoreTarget} -${bldFlag} -DSOLARIS -c ${oglsrc}/DrawingSurfaceObjectAWT.c ${oglsrc}/Canvas3D.c ${oglsrc}/GraphicsContext3D.c ${oglsrc}/NativeWSInfo.c ${oglsrc}/NativeScreenInfo.c ${oglsrc}/NativeConfigTemplate3D.c ${oglsrc}/MasterControl.c ${oglsrc}/RasterRetained.c ${oglsrc}/CompressedGeometryRetained.c ${oglsrc}/GeometryArrayRetained.c ${oglsrc}/Attributes.c ${oglsrc}/Lights.c ${oglsrc}/NativeAPIInfo.c"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs/sparcv9" executable="ld">
+ <arg line="DrawingSurfaceObjectAWT.o Canvas3D.o GraphicsContext3D.o NativeWSInfo.o NativeScreenInfo.o NativeConfigTemplate3D.o MasterControl.o RasterRetained.o CompressedGeometryRetained.o GeometryArrayRetained.o Attributes.o Lights.o NativeAPIInfo.o -G -z lazyload -L/usr/openwin/lib/sparcv9 -ldga -ldl -lGL -lX11 -lXext -lm -lsocket -lnsl -lc -R/usr/openwin/lib/sparcv9 -L${java.home}/lib/sparcv9 -ljawt -L${java.home}/lib/sparcv9/server -ljvm -o libj3dcore-ogl.so"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/ogl/objs/sparcv9/libj3dcore-ogl.so"
+ todir="${build}/${platform}/${bldType}/lib/sparcv9"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/lib/sparc"/>
+ <mkdir dir="${dist}/${platform}/lib/sparcv9"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/lib/sparc/libj3dcore-ogl.so"
+ todir="${dist}/${platform}/lib/sparc"/>
+
+ <copy file="${build}/${platform}/opt/lib/sparcv9/libj3dcore-ogl.so"
+ todir="${dist}/${platform}/lib/sparcv9"/>
+ </target>
+
+</project>
diff --git a/src/native/ogl/build-windows-i586-gcc.xml b/src/native/ogl/build-windows-i586-gcc.xml
new file mode 100644
index 0000000..95d768e
--- /dev/null
+++ b/src/native/ogl/build-windows-i586-gcc.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native ogl renderer files for Windows-i586 -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native renderer build [${bldType}]"/>
+
+ <!-- Create the build directories for sparc -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/ogl/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/bin"/>
+
+ <property name="javaInclude"
+ location="${java.home}/../include"/>
+
+ <property name="javaWin32Include"
+ location="${java.home}/../include/win32"/>
+
+ <property name="oglsrc" location="${src}/native/ogl"/>
+
+ <!-- Compile the c source files-->
+ <!-- Inhibit all warning for native build. Remove -w to switch warning on -->
+
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs" executable="gcc">
+ <arg line="-w -D_WINGDI_ -D_JNI_IMPLEMENTATION_ -I&quot;${javaInclude}&quot; -I&quot;${javaWin32Include}&quot; -I&quot;${javahCoreTarget}&quot; ${bldFlag} -c &quot;${oglsrc}/DrawingSurfaceObjectAWT.c&quot; &quot;${oglsrc}/Canvas3D.c&quot; &quot;${oglsrc}/GraphicsContext3D.c&quot; &quot;${oglsrc}/NativeWSInfo.c&quot; &quot;${oglsrc}/NativeScreenInfo.c&quot; &quot;${oglsrc}/NativeConfigTemplate3D.c&quot; &quot;${oglsrc}/MasterControl.c&quot; &quot;${oglsrc}/RasterRetained.c&quot; &quot;${oglsrc}/CompressedGeometryRetained.c&quot; &quot;${oglsrc}/GeometryArrayRetained.c&quot; &quot;${oglsrc}/Attributes.c&quot; &quot;${oglsrc}/Lights.c&quot; &quot;${oglsrc}/NativeAPIInfo.c&quot;"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs" executable="gcc">
+ <arg line="-shared -o j3dcore-ogl.dll DrawingSurfaceObjectAWT.o Canvas3D.o GraphicsContext3D.o NativeWSInfo.o NativeScreenInfo.o NativeConfigTemplate3D.o MasterControl.o RasterRetained.o CompressedGeometryRetained.o GeometryArrayRetained.o Attributes.o Lights.o NativeAPIInfo.o -Wl,--kill-at -L&quot;${java.home}\..\lib&quot; -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lopengl32 -ljawt"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/ogl/objs/j3dcore-ogl.dll"
+ todir="${build}/${platform}/${bldType}/bin"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/bin"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/bin/j3dcore-ogl.dll"
+ todir="${dist}/${platform}/bin"/>
+
+ </target>
+
+</project>
diff --git a/src/native/ogl/build-windows-i586-vc.xml b/src/native/ogl/build-windows-i586-vc.xml
new file mode 100644
index 0000000..1890d8a
--- /dev/null
+++ b/src/native/ogl/build-windows-i586-vc.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native ogl renderer files for Windows-i586 -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native renderer build [${bldType}]"/>
+
+ <!-- Create the build directories for sparc -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/ogl/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/bin"/>
+
+ <property name="javaInclude"
+ location="${java.home}/../include"/>
+
+ <property name="javaWin32Include"
+ location="${java.home}/../include/win32"/>
+
+ <property name="oglsrc" location="${src}/native/ogl"/>
+
+ <!-- Compile the c source files-->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs" executable="cl">
+ <arg line="-I&quot;${javaInclude}&quot; -I&quot;${javaWin32Include}&quot; -I&quot;${javahCoreTarget}&quot; -nologo -MT -W3 -GX -Ox -YX -FD ${bldFlag} -c &quot;${oglsrc}/DrawingSurfaceObjectAWT.c&quot; &quot;${oglsrc}/Canvas3D.c&quot; &quot;${oglsrc}/GraphicsContext3D.c&quot; &quot;${oglsrc}/NativeWSInfo.c&quot; &quot;${oglsrc}/NativeScreenInfo.c&quot; &quot;${oglsrc}/NativeConfigTemplate3D.c&quot; &quot;${oglsrc}/MasterControl.c&quot; &quot;${oglsrc}/RasterRetained.c&quot; &quot;${oglsrc}/CompressedGeometryRetained.c&quot; &quot;${oglsrc}/GeometryArrayRetained.c&quot; &quot;${oglsrc}/Attributes.c&quot; &quot;${oglsrc}/Lights.c&quot; &quot;${oglsrc}/NativeAPIInfo.c&quot;"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/ogl/objs" executable="link">
+ <arg line="-nologo -dll -subsystem:windows -pdb:none -machine:I386 -out:j3dcore-ogl.dll DrawingSurfaceObjectAWT.obj Canvas3D.obj GraphicsContext3D.obj NativeWSInfo.obj NativeScreenInfo.obj NativeConfigTemplate3D.obj MasterControl.obj RasterRetained.obj CompressedGeometryRetained.obj GeometryArrayRetained.obj Attributes.obj Lights.obj NativeAPIInfo.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib delayimp.lib -DELAYLOAD:jawt.dll -LIBPATH:&quot;${java.home}\..\lib&quot; jawt.lib"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/ogl/objs/j3dcore-ogl.dll"
+ todir="${build}/${platform}/${bldType}/bin"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/bin"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/bin/j3dcore-ogl.dll"
+ todir="${dist}/${platform}/bin"/>
+
+ </target>
+
+</project>
diff --git a/src/native/ogl/gl_1_2.h b/src/native/ogl/gl_1_2.h
new file mode 100644
index 0000000..b540d3e
--- /dev/null
+++ b/src/native/ogl/gl_1_2.h
@@ -0,0 +1,191 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#ifndef __gl_1_2_h_
+#define __gl_1_2_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * 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.
+ */
+
+#ifndef GL_VERSION_1_2
+
+#ifndef GL_BGR
+#define GL_BGR 0x80E0
+#endif
+
+#ifndef GL_BGRA
+#define GL_BGRA 0x80E1
+#endif
+
+
+#ifndef GL_LIGHT_MODEL_COLOR_CONTROL
+#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#endif
+
+#ifndef GL_SEPARATE_SPECULAR_COLOR
+#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#endif
+
+#ifndef GL_SINGLE_COLOR
+#define GL_SINGLE_COLOR 0x81F9
+#endif
+
+#endif /* GL_VERSION_1_2 */
+
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_COMBINE_ARB 0x8570
+#define GL_COMBINE_RGB_ARB 0x8571
+#define GL_COMBINE_ALPHA_ARB 0x8572
+#define GL_RGB_SCALE_ARB 0x8573
+#define GL_ADD_SIGNED_ARB 0x8574
+#define GL_INTERPOLATE_ARB 0x8575
+#define GL_SUBTRACT_ARB 0x84E7
+#define GL_CONSTANT_ARB 0x8576
+#define GL_PRIMARY_COLOR_ARB 0x8577
+#define GL_PREVIOUS_ARB 0x8578
+#define GL_SOURCE0_RGB_ARB 0x8580
+#define GL_SOURCE1_RGB_ARB 0x8581
+#define GL_SOURCE2_RGB_ARB 0x8582
+#define GL_SOURCE0_ALPHA_ARB 0x8588
+#define GL_SOURCE1_ALPHA_ARB 0x8589
+#define GL_SOURCE2_ALPHA_ARB 0x858A
+#define GL_OPERAND0_RGB_ARB 0x8590
+#define GL_OPERAND1_RGB_ARB 0x8591
+#define GL_OPERAND2_RGB_ARB 0x8592
+#define GL_OPERAND0_ALPHA_ARB 0x8598
+#define GL_OPERAND1_ALPHA_ARB 0x8599
+#define GL_OPERAND2_ALPHA_ARB 0x859A
+#endif /* GL_ARB_texture_env_combine */
+
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_DOT3_RGB_ARB 0x86AE
+#define GL_DOT3_RGBA_ARB 0x86AF
+#endif /* GL_ARB_texture_env_dot3 */
+
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_DOT3_RGB_EXT 0x8740
+#define GL_DOT3_RGBA_EXT 0x8741
+#endif /* GL_EXT_texture_env_dot3 */
+
+#ifndef GL_EXT_texture_edge_clamp
+#define GL_CLAMP_TO_EDGE_EXT 0x812F
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_ARB 0x812D
+#endif
+
+#ifndef GL_ARB_multisample
+#if defined(SOLARIS) || defined(__linux__)
+#define GLX_SAMPLE_BUFFERS_ARB 100000
+#define GLX_SAMPLES_ARB 100001
+#endif
+#ifdef WIN32
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+#define MULTISAMPLE_ARB 0x809D
+#define SAMPLE_ALPHA_TO_COVERATE_ARB 0x809E
+#define SAMPLE_ALPHA_TO_ONE_ARB 0x809F
+#define SAMPLE_COVERAGE_ARB 0x80A0
+#define MULTISAMPLE_BIT_ARB 0x20000000
+#define SAMPLE_BUFFERS_ARB 0x80A8
+#define SAMPLES_ARB 0x80A9
+#define SAMPLE_COVERAGE_VALUE_ARB 0x80AA
+#define SAMPLE_COVERAGE_INVERT_ARB 0x80AB
+#endif /* GL_ARB_multisample */
+
+#ifndef MULTISAMPLE_ARB
+#define MULTISAMPLE_ARB 0x809D
+#endif
+
+#ifdef WIN32
+
+/* define those EXT_pixel_format enums from 3DLabs register developer web site */
+#ifndef WGL_SUPPORT_OPENGL_EXT
+#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
+#define WGL_DRAW_TO_WINDOW_EXT 0x2001
+#define WGL_DRAW_TO_BITMAP_EXT 0x2002
+#define WGL_ACCELERATION_EXT 0x2003
+#define WGL_NEED_PALETTE_EXT 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
+#define WGL_SWAP_METHOD_EXT 0x2007
+#define WGL_NUMBER_OVERLAYS_EXT 0x2008
+#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
+#define WGL_TRANSPARENT_EXT 0x200A
+#define WGL_TRANSPARENT_VALUE_EXT 0x200B
+#define WGL_SHARE_DEPTH_EXT 0x200C
+#define WGL_SHARE_STENCIL_EXT 0x200D
+#define WGL_SHARE_ACCUM_EXT 0x200E
+#define WGL_SUPPORT_GDI_EXT 0x200F
+#define WGL_SUPPORT_OPENGL_EXT 0x2010
+#define WGL_DOUBLE_BUFFER_EXT 0x2011
+#define WGL_STEREO_EXT 0x2012
+#define WGL_PIXEL_TYPE_EXT 0x2013
+#define WGL_COLOR_BITS_EXT 0x2014
+#define WGL_RED_BITS_EXT 0x2015
+#define WGL_RED_SHIFT_EXT 0x2016
+#define WGL_GREEN_BITS_EXT 0x2017
+#define WGL_GREEN_SHIFT_EXT 0x2018
+#define WGL_BLUE_BITS_EXT 0x2019
+#define WGL_BLUE_SHIFT_EXT 0x201A
+#define WGL_ALPHA_BITS_EXT 0x201B
+#define WGL_ALPHA_SHIFT_EXT 0x201C
+#define WGL_ACCUM_BITS_EXT 0x201D
+#define WGL_ACCUM_RED_BITS_EXT 0x201E
+#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
+#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
+#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
+#define WGL_DEPTH_BITS_EXT 0x2022
+#define WGL_STENCIL_BITS_EXT 0x2023
+#define WGL_AUX_BUFFERS_EXT 0x2024
+#define WGL_NO_ACCELERATION_EXT 0x2025
+#define WGL_GENERIC_ACCELERATION_EXT 0x2026
+#define WGL_FULL_ACCELERATION_EXT 0x2027
+#define WGL_SWAP_EXCHANGE_EXT 0x2028
+#define WGL_SWAP_COPY_EXT 0x2029
+#define WGL_SWAP_UNDEFINED_EXT 0x202A
+#define WGL_TYPE_RGBA_EXT 0x202B
+#define WGL_TYPE_COLORINDEX_EXT 0x202C
+#endif /* WGL_SUPPORT_OPENGL_EXT */
+
+/* define those ARB_pixel_format enums */
+#ifndef WGL_SUPPORT_OPENGL_ARB
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_DEPTH_BITS_ARB 0x2022
+#endif /* WGL_SUPPORT_OPENGL_ARB */
+
+#endif /* WIN32 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/native/ogl/gldefs.h b/src/native/ogl/gldefs.h
new file mode 100644
index 0000000..6658201
--- /dev/null
+++ b/src/native/ogl/gldefs.h
@@ -0,0 +1,645 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#ifndef _Java3D_gldefs_h_
+#define _Java3D_gldefs_h_
+
+/*
+ * 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.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(SOLARIS) || defined(__linux__)
+#define GLX_GLEXT_PROTOTYPES
+#define GLX_GLXEXT_PROTOTYPES
+#include <limits.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include "gl_1_2.h"
+#include "glext.h"
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+
+#ifndef _WIN32
+#define _WIN32
+#endif
+
+#define M_PI 3.14159265358979323846
+
+/* Some constant defined in those javax_media_j3d_*.h */
+/* TODO: remove those constant when D3D automatically include those *.h files */
+#ifdef D3D
+
+/* used in GeometryArrayRetained, execute geometry in by REFERENCE case */
+#ifndef javax_media_j3d_GeometryArrayRetained_COORD_FLOAT
+#define javax_media_j3d_GeometryArrayRetained_COORD_FLOAT 1L
+#endif
+#ifndef javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE
+#define javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE 2L
+#endif
+#ifndef javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT
+#define javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT 4L
+#endif
+#ifndef javax_media_j3d_GeometryArrayRetained_COLOR_BYTE
+#define javax_media_j3d_GeometryArrayRetained_COLOR_BYTE 8L
+#endif
+#ifndef javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT
+#define javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT 16L
+#endif
+#ifndef javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT
+#define javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT 32L
+#endif
+
+#endif /* end of ifdef D3D */
+
+#ifndef D3D
+#include <GL/gl.h>
+#include "gl_1_2.h"
+#include "glext.h"
+#endif
+
+#endif /* WIN32 */
+
+/* include those .h files generated by javah */
+#include "javax_media_j3d_Background.h"
+#include "javax_media_j3d_Canvas3D.h"
+#include "javax_media_j3d_ColoringAttributes.h"
+#include "javax_media_j3d_ColoringAttributesRetained.h"
+#include "javax_media_j3d_CompressedGeometryRetained.h"
+#include "javax_media_j3d_DepthComponentRetained.h"
+#include "javax_media_j3d_DetailTextureImage.h"
+#include "javax_media_j3d_DirectionalLightRetained.h"
+#include "javax_media_j3d_DisplayListRenderMethod.h"
+#include "javax_media_j3d_DrawingSurfaceObjectAWT.h"
+#include "javax_media_j3d_ExponentialFogRetained.h"
+#include "javax_media_j3d_GeometryRetained.h"
+#include "javax_media_j3d_GeometryArray.h"
+#include "javax_media_j3d_GeometryArrayRetained.h"
+#include "javax_media_j3d_GraphicsContext3D.h"
+#include "javax_media_j3d_ImageComponent.h"
+#include "javax_media_j3d_ImageComponentRetained.h"
+#include "javax_media_j3d_ImageComponent2DRetained.h"
+#include "javax_media_j3d_IndexedGeometryArrayRetained.h"
+#include "javax_media_j3d_LineAttributes.h"
+#include "javax_media_j3d_LineAttributesRetained.h"
+#include "javax_media_j3d_LinearFogRetained.h"
+#include "javax_media_j3d_MasterControl.h"
+#include "javax_media_j3d_Material.h"
+#include "javax_media_j3d_MaterialRetained.h"
+#include "javax_media_j3d_ModelClipRetained.h"
+#include "javax_media_j3d_NativeConfigTemplate3D.h"
+#include "javax_media_j3d_NodeRetained.h"
+#include "javax_media_j3d_PointAttributesRetained.h"
+#include "javax_media_j3d_PointLightRetained.h"
+#include "javax_media_j3d_PolygonAttributes.h"
+#include "javax_media_j3d_PolygonAttributesRetained.h"
+#include "javax_media_j3d_Raster.h"
+#include "javax_media_j3d_RasterRetained.h"
+#include "javax_media_j3d_Renderer.h"
+#include "javax_media_j3d_RenderingAttributes.h"
+#include "javax_media_j3d_RenderingAttributesRetained.h"
+#include "javax_media_j3d_RenderMolecule.h"
+#include "javax_media_j3d_SpotLightRetained.h"
+#include "javax_media_j3d_TexCoordGeneration.h"
+#include "javax_media_j3d_TexCoordGenerationRetained.h"
+#include "javax_media_j3d_Texture.h"
+#include "javax_media_j3d_Texture2D.h"
+#include "javax_media_j3d_Texture2DRetained.h"
+#include "javax_media_j3d_Texture3DRetained.h"
+#include "javax_media_j3d_TextureAttributes.h"
+#include "javax_media_j3d_TextureAttributesRetained.h"
+#include "javax_media_j3d_TextureCubeMapRetained.h"
+#include "javax_media_j3d_TextureRetained.h"
+#include "javax_media_j3d_TextureUnitStateRetained.h"
+#include "javax_media_j3d_TransparencyAttributes.h"
+#include "javax_media_j3d_TransparencyAttributesRetained.h"
+
+#ifndef GL_SUNX_geometry_compression
+#define GL_COMPRESSED_GEOM_ACCELERATED_SUNX 0x81D0
+#endif /* GL_SUNX_geometry_compression */
+
+/*
+ * Define these constants here as a workaround for conflicting
+ * glext.h files between Mesa and Solaris
+ */
+
+#ifndef GL_CLAMP_TO_BORDER_SGIS
+#define GL_CLAMP_TO_BORDER_SGIS 0x812D
+#endif
+
+#ifndef GL_VIDEO_RESIZE_COMPENSATION_SUN
+#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD
+#endif
+
+/*
+ * End constant workaround
+ */
+
+
+/* Used to compare floating point values close to 0.0 */
+#define J3D_SMALL_FLOAT 0.00001f
+
+/*
+ * General purpose assertion macro
+ */
+#define J3D_ASSERT(expr) \
+ if (!(expr)) { \
+ fprintf(stderr, \
+ "\nAssertion failed in module '%s' at line %d\n", \
+ __FILE__, __LINE__); \
+ fprintf(stderr, "\t%s\n\n", #expr); \
+ }
+
+#define EPSILON 1e-2
+#define J3D_FNE(a,b) ((a)>((b)+EPSILON)||(a)<((b)-EPSILON))
+
+
+/*
+ * Macro to copy and transpose one matrix to another.
+ *
+ * NOTE: the source and dest must not be the same (no aliasing check
+ * is performed).
+ */
+#define COPY_TRANSPOSE(src,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]; \
+}
+
+
+/*
+ * These match the constants in GeometryRetained
+ */
+
+#define GEO_TYPE_NONE javax_media_j3d_GeometryRetained_GEO_TYPE_NONE
+#define GEO_TYPE_QUAD_SET javax_media_j3d_GeometryRetained_GEO_TYPE_QUAD_SET
+#define GEO_TYPE_TRI_SET javax_media_j3d_GeometryRetained_GEO_TYPE_TRI_SET
+#define GEO_TYPE_POINT_SET javax_media_j3d_GeometryRetained_GEO_TYPE_POINT_SET
+#define GEO_TYPE_LINE_SET javax_media_j3d_GeometryRetained_GEO_TYPE_LINE_SET
+#define GEO_TYPE_TRI_STRIP_SET javax_media_j3d_GeometryRetained_GEO_TYPE_TRI_STRIP_SET
+#define GEO_TYPE_TRI_FAN_SET javax_media_j3d_GeometryRetained_GEO_TYPE_TRI_FAN_SET
+#define GEO_TYPE_LINE_STRIP_SET javax_media_j3d_GeometryRetained_GEO_TYPE_LINE_STRIP_SET
+#define GEO_TYPE_INDEXED_QUAD_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_QUAD_SET
+#define GEO_TYPE_INDEXED_TRI_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_TRI_SET
+#define GEO_TYPE_INDEXED_POINT_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_POINT_SET
+#define GEO_TYPE_INDEXED_LINE_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_LINE_SET
+#define GEO_TYPE_INDEXED_TRI_STRIP_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_TRI_STRIP_SET
+#define GEO_TYPE_INDEXED_TRI_FAN_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_TRI_FAN_SET
+#define GEO_TYPE_INDEXED_LINE_STRIP_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_LINE_STRIP_SET
+#define GEO_TYPE_RASTER javax_media_j3d_GeometryRetained_GEO_TYPE_RASTER
+#define GEO_TYPE_TEXT3D javax_media_j3d_GeometryRetained_GEO_TYPE_TEXT3D
+#define GEO_TYPE_COMPRESSED javax_media_j3d_GeometryRetained_GEO_TYPE_COMPRESSED
+#define GEO_TYPE_TOTAL javax_media_j3d_GeometryRetained_GEO_TYPE_TOTAL
+
+/*
+ * These match the constants in ImageComponent
+ */
+
+#define FORMAT_RGB javax_media_j3d_ImageComponent_FORMAT_RGB
+#define FORMAT_RGBA javax_media_j3d_ImageComponent_FORMAT_RGBA
+#define FORMAT_RGB5 javax_media_j3d_ImageComponent_FORMAT_RGB5
+#define FORMAT_RGB5_A1 javax_media_j3d_ImageComponent_FORMAT_RGB5_A1
+#define FORMAT_RGB4 javax_media_j3d_ImageComponent_FORMAT_RGB4
+#define FORMAT_RGBA4 javax_media_j3d_ImageComponent_FORMAT_RGBA4
+#define FORMAT_LUM4_ALPHA4 javax_media_j3d_ImageComponent_FORMAT_LUM4_ALPHA4
+#define FORMAT_LUM8_ALPHA8 javax_media_j3d_ImageComponent_FORMAT_LUM8_ALPHA8
+#define FORMAT_R3_G3_B2 javax_media_j3d_ImageComponent_FORMAT_R3_G3_B2
+#define FORMAT_CHANNEL8 javax_media_j3d_ImageComponent_FORMAT_CHANNEL8
+
+
+/* now the imagecomponent formats are reduced the ones below */
+#define FORMAT_BYTE_RGBA javax_media_j3d_ImageComponentRetained_BYTE_RGBA
+#define FORMAT_BYTE_ABGR javax_media_j3d_ImageComponentRetained_BYTE_ABGR
+#define FORMAT_BYTE_GRAY javax_media_j3d_ImageComponentRetained_BYTE_GRAY
+#define FORMAT_USHORT_GRAY javax_media_j3d_ImageComponentRetained_USHORT_GRAY
+#define FORMAT_BYTE_LA javax_media_j3d_ImageComponentRetained_BYTE_LA
+#define FORMAT_BYTE_BGR javax_media_j3d_ImageComponentRetained_BYTE_BGR
+#define FORMAT_BYTE_RGB javax_media_j3d_ImageComponentRetained_BYTE_RGB
+
+
+/* These match the definitions in GeometryArray.java */
+/* These have a GA prefix to avoid confusion with TEXTURE_COORDINATE_2 above */
+#define GA_COORDINATES javax_media_j3d_GeometryArray_COORDINATES
+#define GA_NORMALS javax_media_j3d_GeometryArray_NORMALS
+#define GA_COLOR javax_media_j3d_GeometryArray_COLOR
+#define GA_WITH_ALPHA javax_media_j3d_GeometryArray_WITH_ALPHA
+#define GA_TEXTURE_COORDINATE_2 javax_media_j3d_GeometryArray_TEXTURE_COORDINATE_2
+#define GA_TEXTURE_COORDINATE_3 javax_media_j3d_GeometryArray_TEXTURE_COORDINATE_3
+#define GA_TEXTURE_COORDINATE_4 javax_media_j3d_GeometryArray_TEXTURE_COORDINATE_4
+#define GA_TEXTURE_COORDINATE javax_media_j3d_GeometryArray_TEXTURE_COORDINATE
+#define GA_BY_REFERENCE javax_media_j3d_GeometryArray_BY_REFERENCE
+
+
+
+/*
+ * These match the constants in NativeConfigTemplate3D
+ */
+
+#define RED_SIZE javax_media_j3d_NativeConfigTemplate3D_RED_SIZE
+#define GREEN_SIZE javax_media_j3d_NativeConfigTemplate3D_GREEN_SIZE
+#define BLUE_SIZE javax_media_j3d_NativeConfigTemplate3D_BLUE_SIZE
+#define ALPHA_SIZE javax_media_j3d_NativeConfigTemplate3D_ALPHA_SIZE
+#define ACCUM_BUFFER javax_media_j3d_NativeConfigTemplate3D_ACCUM_BUFFER
+#define DEPTH_SIZE javax_media_j3d_NativeConfigTemplate3D_DEPTH_SIZE
+ /* this maps to GLX_ACCUM_RED, */
+ /* GLX_ACCUM_GREEN and */
+ /* GLX_ACCUM_BLUE so NUM_ITEMS */
+ /* must be incremented by 3 for */
+ /* this attribute. */
+#define DOUBLEBUFFER javax_media_j3d_NativeConfigTemplate3D_DOUBLEBUFFER
+#define STEREO javax_media_j3d_NativeConfigTemplate3D_STEREO
+#define ANTIALIASING javax_media_j3d_NativeConfigTemplate3D_ANTIALIASING
+
+
+/* set this to the number of indices (from above) */
+#define NUM_ITEMS (javax_media_j3d_NativeConfigTemplate3D_NUM_ITEMS + 2)
+ /* total + 2 beacause of */
+ /* DEPTH_SIZE */
+
+/* values for "enum" entries for GraphicsConfiguration */
+#define REQUIRED 1
+#define PREFERRED 2
+#define UNNECESSARY 3
+
+
+
+#define INTENSITY javax_media_j3d_Texture_INTENSITY
+#define LUMINANCE javax_media_j3d_Texture_LUMINANCE
+#define ALPHA javax_media_j3d_Texture_ALPHA
+#define LUMINANCE_ALPHA javax_media_j3d_Texture_LUMINANCE_ALPHA
+#define J3D_RGB javax_media_j3d_Texture_RGB
+#define J3D_RGBA javax_media_j3d_Texture_RGBA
+
+#ifndef D3D
+#if defined(SOLARIS) || defined(__linux__)
+extern void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf);
+extern void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf);
+extern void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *);
+extern void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei);
+extern void APIENTRY glMultiDrawArraysSUN (GLenum, GLint *, GLsizei *, GLsizei);
+extern void APIENTRY glMultiDrawElementsEXT (GLenum, GLsizei *, GLenum, const GLvoid**, GLsizei);
+extern void APIENTRY glMultiDrawElementsSUN (GLenum, GLsizei *, GLenum, const GLvoid**, GLsizei);
+extern void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
+extern void APIENTRY glUnlockArraysEXT (void);
+
+
+extern void APIENTRY glClientActiveTextureARB (GLenum);
+extern void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *);
+extern void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *);
+extern void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *);
+extern void APIENTRY glGlobalAlphaFactorfSUN (GLfloat);
+extern void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *);
+extern void APIENTRY glMultTransposeMatrixdARB (const GLdouble *);
+extern void APIENTRY glActiveTextureARB (GLenum);
+extern void APIENTRY glSharpenTexFuncSGIS(GLenum, GLsizei, const GLfloat *);
+extern void APIENTRY glDetailTexFuncSGIS(GLenum, GLsizei, const GLfloat *);
+extern void APIENTRY glTexFilterFuncSGIS(GLenum, GLenum, GLsizei, const GLfloat *);
+extern void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum);
+extern void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean);
+extern void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum);
+extern void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *);
+extern void APIENTRY glCombinerParameterivNV (GLenum, const GLint *);
+extern void APIENTRY glCombinerParameterfNV (GLenum, GLfloat);
+extern void APIENTRY glCombinerParameteriNV (GLenum, GLint);
+
+extern void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+
+
+
+#ifndef GLX_SUN_video_resize
+#define GLX_SUN_video_resize 1
+extern int glXVideoResizeSUN( Display *, GLXDrawable, float);
+extern int glXgetVideoResizeSUN( Display *, GLXDrawable, float *);
+#endif
+
+#pragma weak glXVideoResizeSUN
+#pragma weak glBlendColor
+#pragma weak glBlendColorEXT
+#pragma weak glColorTable
+#pragma weak glColorTableSGI
+#pragma weak glGetColorTableParameterivSGI
+#pragma weak glGetColorTableParameteriv
+#pragma weak glMultiDrawArraysSUN
+#pragma weak glMultiDrawArraysEXT
+#pragma weak glMultiDrawElementsSUN
+#pragma weak glMultiDrawElementsEXT
+#pragma weak glLockArraysEXT
+#pragma weak glUnlockArraysEXT
+#pragma weak glClientActiveTextureARB
+#pragma weak glMultiTexCoord2fvARB
+#pragma weak glMultiTexCoord3fvARB
+#pragma weak glMultiTexCoord4fvARB
+#pragma weak glGlobalAlphaFactorfSUN
+#pragma weak glLoadTransposeMatrixdARB
+#pragma weak glMultTransposeMatrixdARB
+#pragma weak glActiveTextureARB
+#pragma weak glCombinerInputNV
+#pragma weak glCombinerOutputNV
+#pragma weak glFinalCombinerInputNV
+#pragma weak glCombinerParameterfvNV
+#pragma weak glCombinerParameterivNV
+#pragma weak glCombinerParameterfNV
+#pragma weak glCombinerParameteriNV
+#pragma weak glSharpenTexFuncSGIS
+#pragma weak glDetailTexFuncSGIS
+#pragma weak glTexFilterFuncSGIS
+/* [jk] mostly needed by older NVIDIA drivers */
+#pragma weak glTexImage3DEXT
+#pragma weak glTexSubImage3DEXT
+#pragma weak glTexImage3D
+#pragma weak glTexSubImage3D
+#endif /* SOLARIS */
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+
+#ifdef WIN32
+
+/* declare function prototype for WGL related functions*/
+typedef const char * (APIENTRY * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (HDC hdc);
+typedef BOOL (APIENTRY * PFNWGLCHOOSEPIXELFORMATEXTPROC)(HDC hdc,
+ const int *piAttribIList,
+ const FLOAT *pfAttriFList,
+ UINT nMaxFormats,
+ int *piFormats,
+ UINT *nNumFormats);
+typedef BOOL (APIENTRY * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)(HDC hdc,
+ int iPixelFormat,
+ int iLayerPlane,
+ UINT nAttributes,
+ const int *piAttributes,
+ int *piValues);
+
+
+
+#endif /* WIN32 */
+
+/* define function prototypes */
+typedef void (APIENTRY * MYPFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green,
+ GLclampf blue, GLclampf alpha);
+typedef void (APIENTRY * MYPFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green,
+ GLclampf blue, GLclampf alpha);
+typedef void (APIENTRY * MYPFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRY * MYPFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * MYPFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRY * MYPFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRY * MYPFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
+typedef void (APIENTRY * MYPFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum, GLsizei *, GLenum, const GLvoid**, GLsizei);
+typedef void (APIENTRY * MYPFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
+typedef void (APIENTRY * MYPFNGLUNLOCKARRAYSEXTPROC) (void);
+
+typedef void (APIENTRY * MYPFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRY * MYPFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRY * MYPFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRY * MYPFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+typedef void (APIENTRY * MYPFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+typedef void (APIENTRY * MYPFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRY * MYPFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRY * MYPFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+
+typedef void (APIENTRY * MYPFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor);
+
+typedef void (APIENTRY * MYPFNGLCOMBINERINPUTNV) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRY * MYPFNGLFINALCOMBINERINPUTNV) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRY * MYPFNGLCOMBINEROUTPUTNV) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+typedef void (APIENTRY * MYPFNGLCOMBINERPARAMETERFVNV) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * MYPFNGLCOMBINERPARAMETERIVNV) (GLenum pname, const GLint *params);
+typedef void (APIENTRY * MYPFNGLCOMBINERPARAMETERFNV) (GLenum pname, GLfloat param);
+typedef void (APIENTRY * MYPFNGLCOMBINERPARAMETERINV) (GLenum pname, GLint param);
+typedef void (APIENTRY * MYPFNGLSHARPENTEXFUNCSGI) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRY * MYPFNGLDETAILTEXFUNCSGI) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRY * MYPFNGLTEXFILTERFUNCSGI) (GLenum target, GLenum filter, GLsizei n, const GLfloat *points);
+
+/* define the structure to hold the properties of graphics context */
+typedef struct {
+ jlong context;
+
+ /* version and extension info */
+ char *versionStr;
+ char *extensionStr;
+ int versionNumbers[2];
+
+ /* both in 1.2 core part and 1.1 extensions */
+ /* GL_EXT_rescale_normal or GL_RESCALE_NORMAL */
+ jboolean rescale_normal_ext;
+ GLenum rescale_normal_ext_enum;
+
+ /* GL_BGR_EXT or GL_BGR */
+ jboolean bgr_ext;
+ GLenum bgr_ext_enum;
+
+ /* GL_EXT_texture3D or GL_TEXTURE3D */
+ jboolean texture3DAvailable;
+ GLenum texture_3D_ext_enum;
+ GLenum texture_wrap_r_ext_enum;
+
+ /* GL_ARB_imaging subset */
+ /* GL_EXT_blend_color or GL_BLEND_COLOR */
+ jboolean blend_color_ext;
+ GLenum blendFunctionTable[8];
+ /* GL_SGI_color_table or GL_COLOR_TABLE */
+ jboolean color_table_ext;
+
+ /* GL_EXT_separate_specular_color */
+ jboolean seperate_specular_color;
+ GLenum light_model_color_control_enum;
+ GLenum single_color_enum;
+ GLenum seperate_specular_color_enum;
+
+ /* GL_CLAMP_TO_EDGE or GL_EXT_texture_edge_clamp or
+ GL_SGIS_texture_edge_clamp */
+ GLenum texture_clamp_to_edge_enum;
+
+
+ /* GL_SGIS_texture_lod */
+ jboolean textureLodAvailable;
+ GLenum texture_min_lod_enum;
+ GLenum texture_max_lod_enum;
+ GLenum texture_base_level_enum;
+ GLenum texture_max_level_enum;
+
+
+ /* ***********1.1 extension or 1.2 extensions ********************/
+
+ /* GL_ARB_texture_border_clamp or GL_SGIS_texture_border_clamp */
+ GLenum texture_clamp_to_border_enum;
+
+ /* GL_SUN_multi_draw_arrays */
+ jboolean multi_draw_arrays_sun;
+
+ /* GLX_SUN_video_resize */
+ jboolean videoResizeAvailable;
+
+ /* GL_SUN_global_alpha */
+ jboolean global_alpha_sun;
+ /* GL_SUNX_constant_data */
+ jboolean constant_data_sun;
+ /* GL_SUNX_geometry_compression */
+ jboolean geometry_compression_sunx;
+
+ /* GL_EXT_abgr */
+ jboolean abgr_ext;
+ /* GL_EXT_multi_draw_arrays */
+ jboolean multi_draw_arrays_ext;
+
+ /* GL_EXT_compiled_vertex_array */
+ jboolean compiled_vertex_array_ext;
+
+ /* GL_ARB_transpose_matrix */
+ jboolean arb_transpose_matrix;
+
+ /* GL_ARB_multitexture */
+ jboolean arb_multitexture;
+ int textureUnitCount;
+
+ /* GL_SGI_texture_color_table */
+ jboolean textureColorTableAvailable;
+ int textureColorTableSize;
+
+ /* GL_ARB_texture_env_combine */
+ /* GL_EXT_texture_env_combine */
+ jboolean textureEnvCombineAvailable;
+ jboolean textureCombineDot3Available;
+ jboolean textureCombineSubtractAvailable;
+
+ /* GL_NV_register_combiners */
+ jboolean textureRegisterCombinersAvailable;
+ GLenum currentTextureUnit;
+ GLenum currentCombinerUnit;
+
+ /* save the enum for the combine modes since the enums between
+ ARB & EXT might be different.
+ */
+ GLenum combine_enum;
+ GLenum combine_add_signed_enum;
+ GLenum combine_interpolate_enum;
+ GLenum combine_subtract_enum;
+ GLenum combine_dot3_rgb_enum;
+ GLenum combine_dot3_rgba_enum;
+
+ /* GL_ARB_texture_cube_map */
+ /* GL_EXT_texture_cube_map */
+ jboolean textureCubeMapAvailable;
+ GLenum texture_cube_map_ext_enum;
+
+ /* GL_ARB_mulitsample */
+ jboolean arb_multisample;
+
+ /*
+ By default, full scene antialiasing is disable if
+ multisampling pixel format (or visual) is chosen.
+ To honor display driver multisampling antialiasing
+ setting (e.g. force scene antialiasing), set the
+ implicit multisample flag to true in this case.
+ This cause Java3D not to invoke any native
+ multisampling API to enable/disable scene antialiasing.
+ */
+ jboolean implicit_multisample;
+
+ /* GL_SGIS_sharpen_texture */
+ jboolean textureSharpenAvailable;
+ GLenum linear_sharpen_enum;
+ GLenum linear_sharpen_rgb_enum;
+ GLenum linear_sharpen_alpha_enum;
+
+ /* GL_SGIS_detail_texture */
+ jboolean textureDetailAvailable;
+ GLenum texture_detail_ext_enum;
+ GLenum linear_detail_enum;
+ GLenum linear_detail_rgb_enum;
+ GLenum linear_detail_alpha_enum;
+ GLenum texture_detail_mode_enum;
+ GLenum texture_detail_level_enum;
+
+ /* GL_SGIS_texture_filter4 */
+ jboolean textureFilter4Available;
+ GLenum filter4_enum;
+
+ /* GL_EXT_texture_filter_anisotropic */
+ jboolean textureAnisotropicFilterAvailable;
+ GLenum texture_filter_anisotropic_ext_enum;
+ GLenum max_texture_filter_anisotropy_enum;
+
+ /* GL_SGIX_texture_lod_bias */
+ jboolean textureLodBiasAvailable;
+
+ jboolean geometry_compression_accelerated;
+ int geometry_compression_accelerated_major_version;
+ int geometry_compression_accelerated_minor_version;
+ int geometry_compression_accelerated_subminor_version;
+
+ /* extension mask */
+ jint extMask;
+ jint textureExtMask;
+
+ /* function pointers */
+ MYPFNGLBLENDCOLORPROC glBlendColor;
+ MYPFNGLBLENDCOLOREXTPROC glBlendColorEXT;
+ MYPFNGLCOLORTABLEPROC glColorTable;
+ MYPFNGLGETCOLORTABLEPARAMETERIVPROC glGetColorTableParameteriv;
+ MYPFNGLTEXIMAGE3DPROC glTexImage3DEXT;
+ MYPFNGLTEXSUBIMAGE3DPROC glTexSubImage3DEXT;
+ MYPFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
+ MYPFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
+ MYPFNGLMULTIDRAWARRAYSEXTPROC glMultiDrawArraysEXT;
+ MYPFNGLMULTIDRAWELEMENTSEXTPROC glMultiDrawElementsEXT;
+ MYPFNGLLOCKARRAYSEXTPROC glLockArraysEXT;
+ MYPFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT;
+ MYPFNGLMULTITEXCOORD2FVARBPROC glMultiTexCoord2fvARB;
+ MYPFNGLMULTITEXCOORD3FVARBPROC glMultiTexCoord3fvARB;
+ MYPFNGLMULTITEXCOORD4FVARBPROC glMultiTexCoord4fvARB;
+ MYPFNGLLOADTRANSPOSEMATRIXDARBPROC glLoadTransposeMatrixdARB;
+ MYPFNGLMULTTRANSPOSEMATRIXDARBPROC glMultTransposeMatrixdARB;
+ MYPFNGLGLOBALALPHAFACTORFSUNPROC glGlobalAlphaFactorfSUN;
+
+ MYPFNGLCOMBINERINPUTNV glCombinerInputNV;
+ MYPFNGLCOMBINEROUTPUTNV glCombinerOutputNV;
+ MYPFNGLFINALCOMBINERINPUTNV glFinalCombinerInputNV;
+ MYPFNGLCOMBINERPARAMETERFVNV glCombinerParameterfvNV;
+ MYPFNGLCOMBINERPARAMETERIVNV glCombinerParameterivNV;
+ MYPFNGLCOMBINERPARAMETERFNV glCombinerParameterfNV;
+ MYPFNGLCOMBINERPARAMETERINV glCombinerParameteriNV;
+
+ MYPFNGLSHARPENTEXFUNCSGI glSharpenTexFuncSGIS;
+ MYPFNGLDETAILTEXFUNCSGI glDetailTexFuncSGIS;
+ MYPFNGLTEXFILTERFUNCSGI glTexFilterFuncSGIS;
+} GraphicsContextPropertiesInfo;
+
+#endif /* J3D_BUILDVERTICES */
+#endif /* _Java3D_gldefs_h_ */
diff --git a/src/native/ogl/glext.h b/src/native/ogl/glext.h
new file mode 100644
index 0000000..1a5b8b9
--- /dev/null
+++ b/src/native/ogl/glext.h
@@ -0,0 +1,3063 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#ifndef __glext_h_
+#define __glext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * 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.
+ */
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: This software was created using the
+** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
+** not been independently verified as being compliant with the OpenGL(R)
+** version 1.2.1 Specification.
+*/
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+
+/*************************************************************/
+
+/* Header file version number, required by OpenGL ABI for Linux */
+#define GL_GLEXT_VERSION 7
+
+#ifndef GL_VERSION_1_2
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_FUNC_ADD 0x8006
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_BLEND_EQUATION 0x8009
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_CONVOLUTION_1D 0x8010
+#define GL_CONVOLUTION_2D 0x8011
+#define GL_SEPARABLE_2D 0x8012
+#define GL_CONVOLUTION_BORDER_MODE 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS 0x8015
+#define GL_REDUCE 0x8016
+#define GL_CONVOLUTION_FORMAT 0x8017
+#define GL_CONVOLUTION_WIDTH 0x8018
+#define GL_CONVOLUTION_HEIGHT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
+#define GL_HISTOGRAM 0x8024
+#define GL_PROXY_HISTOGRAM 0x8025
+#define GL_HISTOGRAM_WIDTH 0x8026
+#define GL_HISTOGRAM_FORMAT 0x8027
+#define GL_HISTOGRAM_RED_SIZE 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
+#define GL_HISTOGRAM_SINK 0x802D
+#define GL_MINMAX 0x802E
+#define GL_MINMAX_FORMAT 0x802F
+#define GL_MINMAX_SINK 0x8030
+#define GL_TABLE_TOO_LARGE 0x8031
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_COLOR_MATRIX 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
+#define GL_COLOR_TABLE 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
+#define GL_PROXY_COLOR_TABLE 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define GL_COLOR_TABLE_SCALE 0x80D6
+#define GL_COLOR_TABLE_BIAS 0x80D7
+#define GL_COLOR_TABLE_FORMAT 0x80D8
+#define GL_COLOR_TABLE_WIDTH 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_TEXTURE0_ARB 0x84C0
+#define GL_TEXTURE1_ARB 0x84C1
+#define GL_TEXTURE2_ARB 0x84C2
+#define GL_TEXTURE3_ARB 0x84C3
+#define GL_TEXTURE4_ARB 0x84C4
+#define GL_TEXTURE5_ARB 0x84C5
+#define GL_TEXTURE6_ARB 0x84C6
+#define GL_TEXTURE7_ARB 0x84C7
+#define GL_TEXTURE8_ARB 0x84C8
+#define GL_TEXTURE9_ARB 0x84C9
+#define GL_TEXTURE10_ARB 0x84CA
+#define GL_TEXTURE11_ARB 0x84CB
+#define GL_TEXTURE12_ARB 0x84CC
+#define GL_TEXTURE13_ARB 0x84CD
+#define GL_TEXTURE14_ARB 0x84CE
+#define GL_TEXTURE15_ARB 0x84CF
+#define GL_TEXTURE16_ARB 0x84D0
+#define GL_TEXTURE17_ARB 0x84D1
+#define GL_TEXTURE18_ARB 0x84D2
+#define GL_TEXTURE19_ARB 0x84D3
+#define GL_TEXTURE20_ARB 0x84D4
+#define GL_TEXTURE21_ARB 0x84D5
+#define GL_TEXTURE22_ARB 0x84D6
+#define GL_TEXTURE23_ARB 0x84D7
+#define GL_TEXTURE24_ARB 0x84D8
+#define GL_TEXTURE25_ARB 0x84D9
+#define GL_TEXTURE26_ARB 0x84DA
+#define GL_TEXTURE27_ARB 0x84DB
+#define GL_TEXTURE28_ARB 0x84DC
+#define GL_TEXTURE29_ARB 0x84DD
+#define GL_TEXTURE30_ARB 0x84DE
+#define GL_TEXTURE31_ARB 0x84DF
+#define GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
+#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_MULTISAMPLE_ARB 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F
+#define GL_SAMPLE_COVERAGE_ARB 0x80A0
+#define GL_SAMPLE_BUFFERS_ARB 0x80A8
+#define GL_SAMPLES_ARB 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB
+#define GL_MULTISAMPLE_BIT_ARB 0x20000000
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_NORMAL_MAP_ARB 0x8511
+#define GL_REFLECTION_MAP_ARB 0x8512
+#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_COMPRESSED_ALPHA_ARB 0x84E9
+#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
+#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
+#define GL_COMPRESSED_RGB_ARB 0x84ED
+#define GL_COMPRESSED_RGBA_ARB 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
+#define GL_TEXTURE_IMAGE_SIZE_ARB 0x86A0
+#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_MAX_VERTEX_UNITS_ARB 0x86A4
+#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5
+#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6
+#define GL_VERTEX_BLEND_ARB 0x86A7
+#define GL_CURRENT_WEIGHT_ARB 0x86A8
+#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA
+#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB
+#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC
+#define GL_WEIGHT_ARRAY_ARB 0x86AD
+#define GL_MODELVIEW0_ARB 0x1700
+#define GL_MODELVIEW1_ARB 0x850A
+#define GL_MODELVIEW2_ARB 0x8722
+#define GL_MODELVIEW3_ARB 0x8723
+#define GL_MODELVIEW4_ARB 0x8724
+#define GL_MODELVIEW5_ARB 0x8725
+#define GL_MODELVIEW6_ARB 0x8726
+#define GL_MODELVIEW7_ARB 0x8727
+#define GL_MODELVIEW8_ARB 0x8728
+#define GL_MODELVIEW9_ARB 0x8729
+#define GL_MODELVIEW10_ARB 0x872A
+#define GL_MODELVIEW11_ARB 0x872B
+#define GL_MODELVIEW12_ARB 0x872C
+#define GL_MODELVIEW13_ARB 0x872D
+#define GL_MODELVIEW14_ARB 0x872E
+#define GL_MODELVIEW15_ARB 0x872F
+#define GL_MODELVIEW16_ARB 0x8730
+#define GL_MODELVIEW17_ARB 0x8731
+#define GL_MODELVIEW18_ARB 0x8732
+#define GL_MODELVIEW19_ARB 0x8733
+#define GL_MODELVIEW20_ARB 0x8734
+#define GL_MODELVIEW21_ARB 0x8735
+#define GL_MODELVIEW22_ARB 0x8736
+#define GL_MODELVIEW23_ARB 0x8737
+#define GL_MODELVIEW24_ARB 0x8738
+#define GL_MODELVIEW25_ARB 0x8739
+#define GL_MODELVIEW26_ARB 0x873A
+#define GL_MODELVIEW27_ARB 0x873B
+#define GL_MODELVIEW28_ARB 0x873C
+#define GL_MODELVIEW29_ARB 0x873D
+#define GL_MODELVIEW30_ARB 0x873E
+#define GL_MODELVIEW31_ARB 0x873F
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_ABGR_EXT 0x8000
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_CONSTANT_COLOR_EXT 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002
+#define GL_CONSTANT_ALPHA_EXT 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004
+#define GL_BLEND_COLOR_EXT 0x8005
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_POLYGON_OFFSET_EXT 0x8037
+#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038
+#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_ALPHA4_EXT 0x803B
+#define GL_ALPHA8_EXT 0x803C
+#define GL_ALPHA12_EXT 0x803D
+#define GL_ALPHA16_EXT 0x803E
+#define GL_LUMINANCE4_EXT 0x803F
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE12_EXT 0x8041
+#define GL_LUMINANCE16_EXT 0x8042
+#define GL_LUMINANCE4_ALPHA4_EXT 0x8043
+#define GL_LUMINANCE6_ALPHA2_EXT 0x8044
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_LUMINANCE12_ALPHA4_EXT 0x8046
+#define GL_LUMINANCE12_ALPHA12_EXT 0x8047
+#define GL_LUMINANCE16_ALPHA16_EXT 0x8048
+#define GL_INTENSITY_EXT 0x8049
+#define GL_INTENSITY4_EXT 0x804A
+#define GL_INTENSITY8_EXT 0x804B
+#define GL_INTENSITY12_EXT 0x804C
+#define GL_INTENSITY16_EXT 0x804D
+#define GL_RGB2_EXT 0x804E
+#define GL_RGB4_EXT 0x804F
+#define GL_RGB5_EXT 0x8050
+#define GL_RGB8_EXT 0x8051
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB12_EXT 0x8053
+#define GL_RGB16_EXT 0x8054
+#define GL_RGBA2_EXT 0x8055
+#define GL_RGBA4_EXT 0x8056
+#define GL_RGB5_A1_EXT 0x8057
+#define GL_RGBA8_EXT 0x8058
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGBA12_EXT 0x805A
+#define GL_RGBA16_EXT 0x805B
+#define GL_TEXTURE_RED_SIZE_EXT 0x805C
+#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D
+#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E
+#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061
+#define GL_REPLACE_EXT 0x8062
+#define GL_PROXY_TEXTURE_1D_EXT 0x8063
+#define GL_PROXY_TEXTURE_2D_EXT 0x8064
+#define GL_TEXTURE_TOO_LARGE_EXT 0x8065
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_SKIP_IMAGES_EXT 0x806B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_3D_EXT 0x806F
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_PROXY_TEXTURE_3D_EXT 0x8070
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_DEPTH_EXT 0x8071
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_TEXTURE_WRAP_R_EXT 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_FILTER4_SGIS 0x8146
+#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147
+#endif
+
+#ifndef GL_EXT_subtexture
+#endif
+
+#ifndef GL_EXT_copy_texture
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_HISTOGRAM_EXT 0x8024
+#define GL_PROXY_HISTOGRAM_EXT 0x8025
+#define GL_HISTOGRAM_WIDTH_EXT 0x8026
+#define GL_HISTOGRAM_FORMAT_EXT 0x8027
+#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C
+#define GL_HISTOGRAM_SINK_EXT 0x802D
+#define GL_MINMAX_EXT 0x802E
+#define GL_MINMAX_FORMAT_EXT 0x802F
+#define GL_MINMAX_SINK_EXT 0x8030
+#define GL_TABLE_TOO_LARGE_EXT 0x8031
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_CONVOLUTION_1D_EXT 0x8010
+#define GL_CONVOLUTION_2D_EXT 0x8011
+#define GL_SEPARABLE_2D_EXT 0x8012
+#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015
+#define GL_REDUCE_EXT 0x8016
+#define GL_CONVOLUTION_FORMAT_EXT 0x8017
+#define GL_CONVOLUTION_WIDTH_EXT 0x8018
+#define GL_CONVOLUTION_HEIGHT_EXT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_COLOR_MATRIX_SGI 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_COLOR_TABLE_SGI 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2
+#define GL_PROXY_COLOR_TABLE_SGI 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5
+#define GL_COLOR_TABLE_SCALE_SGI 0x80D6
+#define GL_COLOR_TABLE_BIAS_SGI 0x80D7
+#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8
+#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_PIXEL_TEXTURE_SGIS 0x8353
+#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354
+#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355
+#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_PIXEL_TEX_GEN_SGIX 0x8139
+#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130
+#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131
+#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132
+#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133
+#define GL_TEXTURE_4D_SGIS 0x8134
+#define GL_PROXY_TEXTURE_4D_SGIS 0x8135
+#define GL_TEXTURE_4DSIZE_SGIS 0x8136
+#define GL_TEXTURE_WRAP_Q_SGIS 0x8137
+#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138
+#define GL_TEXTURE_4D_BINDING_SGIS 0x814F
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC
+#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_CMYK_EXT 0x800C
+#define GL_CMYKA_EXT 0x800D
+#define GL_PACK_CMYK_HINT_EXT 0x800E
+#define GL_UNPACK_CMYK_HINT_EXT 0x800F
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_TEXTURE_PRIORITY_EXT 0x8066
+#define GL_TEXTURE_RESIDENT_EXT 0x8067
+#define GL_TEXTURE_1D_BINDING_EXT 0x8068
+#define GL_TEXTURE_2D_BINDING_EXT 0x8069
+#define GL_TEXTURE_3D_BINDING_EXT 0x806A
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095
+#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096
+#define GL_LINEAR_DETAIL_SGIS 0x8097
+#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098
+#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099
+#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A
+#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B
+#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_LINEAR_SHARPEN_SGIS 0x80AD
+#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE
+#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF
+#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_TEXTURE_MIN_LOD_SGIS 0x813A
+#define GL_TEXTURE_MAX_LOD_SGIS 0x813B
+#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C
+#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_MULTISAMPLE_SGIS 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F
+#define GL_SAMPLE_MASK_SGIS 0x80A0
+#define GL_1PASS_SGIS 0x80A1
+#define GL_2PASS_0_SGIS 0x80A2
+#define GL_2PASS_1_SGIS 0x80A3
+#define GL_4PASS_0_SGIS 0x80A4
+#define GL_4PASS_1_SGIS 0x80A5
+#define GL_4PASS_2_SGIS 0x80A6
+#define GL_4PASS_3_SGIS 0x80A7
+#define GL_SAMPLE_BUFFERS_SGIS 0x80A8
+#define GL_SAMPLES_SGIS 0x80A9
+#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA
+#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB
+#define GL_SAMPLE_PATTERN_SGIS 0x80AC
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_RESCALE_NORMAL_EXT 0x803A
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_VERTEX_ARRAY_EXT 0x8074
+#define GL_NORMAL_ARRAY_EXT 0x8075
+#define GL_COLOR_ARRAY_EXT 0x8076
+#define GL_INDEX_ARRAY_EXT 0x8077
+#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078
+#define GL_EDGE_FLAG_ARRAY_EXT 0x8079
+#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A
+#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B
+#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C
+#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D
+#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E
+#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F
+#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080
+#define GL_COLOR_ARRAY_SIZE_EXT 0x8081
+#define GL_COLOR_ARRAY_TYPE_EXT 0x8082
+#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083
+#define GL_COLOR_ARRAY_COUNT_EXT 0x8084
+#define GL_INDEX_ARRAY_TYPE_EXT 0x8085
+#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086
+#define GL_INDEX_ARRAY_COUNT_EXT 0x8087
+#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A
+#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B
+#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C
+#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D
+#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E
+#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F
+#define GL_COLOR_ARRAY_POINTER_EXT 0x8090
+#define GL_INDEX_ARRAY_POINTER_EXT 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_GENERATE_MIPMAP_SGIS 0x8191
+#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170
+#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171
+#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172
+#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173
+#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174
+#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175
+#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176
+#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177
+#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178
+#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D
+#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E
+#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_TEXTURE_COMPARE_SGIX 0x819A
+#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B
+#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C
+#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_CLAMP_TO_EDGE_SGIS 0x812F
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_SGIS 0x812D
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_FUNC_ADD_EXT 0x8006
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#define GL_BLEND_EQUATION_EXT 0x8009
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_FUNC_SUBTRACT_EXT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_INTERLACE_SGIX 0x8094
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E
+#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F
+#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140
+#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141
+#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142
+#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143
+#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144
+#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145
+#endif
+
+#ifndef GL_SGIS_texture_select
+#define GL_DUAL_ALPHA4_SGIS 0x8110
+#define GL_DUAL_ALPHA8_SGIS 0x8111
+#define GL_DUAL_ALPHA12_SGIS 0x8112
+#define GL_DUAL_ALPHA16_SGIS 0x8113
+#define GL_DUAL_LUMINANCE4_SGIS 0x8114
+#define GL_DUAL_LUMINANCE8_SGIS 0x8115
+#define GL_DUAL_LUMINANCE12_SGIS 0x8116
+#define GL_DUAL_LUMINANCE16_SGIS 0x8117
+#define GL_DUAL_INTENSITY4_SGIS 0x8118
+#define GL_DUAL_INTENSITY8_SGIS 0x8119
+#define GL_DUAL_INTENSITY12_SGIS 0x811A
+#define GL_DUAL_INTENSITY16_SGIS 0x811B
+#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C
+#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D
+#define GL_QUAD_ALPHA4_SGIS 0x811E
+#define GL_QUAD_ALPHA8_SGIS 0x811F
+#define GL_QUAD_LUMINANCE4_SGIS 0x8120
+#define GL_QUAD_LUMINANCE8_SGIS 0x8121
+#define GL_QUAD_INTENSITY4_SGIS 0x8122
+#define GL_QUAD_INTENSITY8_SGIS 0x8123
+#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124
+#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SPRITE_SGIX 0x8148
+#define GL_SPRITE_MODE_SGIX 0x8149
+#define GL_SPRITE_AXIS_SGIX 0x814A
+#define GL_SPRITE_TRANSLATION_SGIX 0x814B
+#define GL_SPRITE_AXIAL_SGIX 0x814C
+#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D
+#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_POINT_SIZE_MIN_EXT 0x8126
+#define GL_POINT_SIZE_MIN_SGIS 0x8126
+#define GL_POINT_SIZE_MAX_EXT 0x8127
+#define GL_POINT_SIZE_MAX_SGIS 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
+#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128
+#define GL_DISTANCE_ATTENUATION_EXT 0x8129
+#define GL_DISTANCE_ATTENUATION_SGIS 0x8129
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180
+#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179
+#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A
+#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B
+#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_FRAMEZOOM_SGIX 0x818B
+#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C
+#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#endif
+
+#ifndef GL_FfdMaskSGIX
+#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001
+#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194
+#define GL_TEXTURE_DEFORMATION_SGIX 0x8195
+#define GL_DEFORMATIONS_MASK_SGIX 0x8196
+#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_REFERENCE_PLANE_SGIX 0x817D
+#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_DEPTH_COMPONENT16_SGIX 0x81A5
+#define GL_DEPTH_COMPONENT24_SGIX 0x81A6
+#define GL_DEPTH_COMPONENT32_SGIX 0x81A7
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_FOG_FUNC_SGIS 0x812A
+#define GL_FOG_FUNC_POINTS_SGIS 0x812B
+#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_FOG_OFFSET_SGIX 0x8198
+#define GL_FOG_OFFSET_VALUE_SGIX 0x8199
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_IMAGE_SCALE_X_HP 0x8155
+#define GL_IMAGE_SCALE_Y_HP 0x8156
+#define GL_IMAGE_TRANSLATE_X_HP 0x8157
+#define GL_IMAGE_TRANSLATE_Y_HP 0x8158
+#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159
+#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A
+#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B
+#define GL_IMAGE_MAG_FILTER_HP 0x815C
+#define GL_IMAGE_MIN_FILTER_HP 0x815D
+#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E
+#define GL_CUBIC_HP 0x815F
+#define GL_AVERAGE_HP 0x8160
+#define GL_IMAGE_TRANSFORM_2D_HP 0x8161
+#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162
+#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_IGNORE_BORDER_HP 0x8150
+#define GL_CONSTANT_BORDER_HP 0x8151
+#define GL_REPLICATE_BORDER_HP 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154
+#endif
+
+#ifndef GL_INGR_palette_buffer
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE
+#endif
+
+#ifndef GL_EXT_color_subtable
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_VERTEX_DATA_HINT_PGI 0x1A22A
+#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B
+#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C
+#define GL_MAX_VERTEX_HINT_PGI 0x1A22D
+#define GL_COLOR3_BIT_PGI 0x00010000
+#define GL_COLOR4_BIT_PGI 0x00020000
+#define GL_EDGEFLAG_BIT_PGI 0x00040000
+#define GL_INDEX_BIT_PGI 0x00080000
+#define GL_MAT_AMBIENT_BIT_PGI 0x00100000
+#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000
+#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000
+#define GL_MAT_EMISSION_BIT_PGI 0x00800000
+#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000
+#define GL_MAT_SHININESS_BIT_PGI 0x02000000
+#define GL_MAT_SPECULAR_BIT_PGI 0x04000000
+#define GL_NORMAL_BIT_PGI 0x08000000
+#define GL_TEXCOORD1_BIT_PGI 0x10000000
+#define GL_TEXCOORD2_BIT_PGI 0x20000000
+#define GL_TEXCOORD3_BIT_PGI 0x40000000
+#define GL_TEXCOORD4_BIT_PGI 0x80000000
+#define GL_VERTEX23_BIT_PGI 0x00000004
+#define GL_VERTEX4_BIT_PGI 0x00000008
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8
+#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD
+#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE
+#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202
+#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203
+#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204
+#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C
+#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D
+#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E
+#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F
+#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210
+#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211
+#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216
+#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217
+#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218
+#define GL_FULL_STIPPLE_HINT_PGI 0x1A219
+#define GL_CLIP_NEAR_HINT_PGI 0x1A220
+#define GL_CLIP_FAR_HINT_PGI 0x1A221
+#define GL_WIDE_LINE_HINT_PGI 0x1A222
+#define GL_BACK_NORMALS_HINT_PGI 0x1A223
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_LIST_PRIORITY_SGIX 0x8182
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_IR_INSTRUMENT1_SGIX 0x817F
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E
+#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F
+#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SHADOW_AMBIENT_SGIX 0x80BF
+#endif
+
+#ifndef GL_EXT_index_texture
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_INDEX_MATERIAL_EXT 0x81B8
+#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9
+#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_INDEX_TEST_EXT 0x81B5
+#define GL_INDEX_TEST_FUNC_EXT 0x81B6
+#define GL_INDEX_TEST_REF_EXT 0x81B7
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_IUI_V2F_EXT 0x81AD
+#define GL_IUI_V3F_EXT 0x81AE
+#define GL_IUI_N3F_V2F_EXT 0x81AF
+#define GL_IUI_N3F_V3F_EXT 0x81B0
+#define GL_T2F_IUI_V2F_EXT 0x81B1
+#define GL_T2F_IUI_V3F_EXT 0x81B2
+#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3
+#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8
+#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_CULL_VERTEX_EXT 0x81AA
+#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB
+#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_YCRCB_422_SGIX 0x81BB
+#define GL_YCRCB_444_SGIX 0x81BC
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_FRAGMENT_LIGHTING_SGIX 0x8400
+#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401
+#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402
+#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403
+#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404
+#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405
+#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406
+#define GL_LIGHT_ENV_MODE_SGIX 0x8407
+#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408
+#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409
+#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A
+#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B
+#define GL_FRAGMENT_LIGHT0_SGIX 0x840C
+#define GL_FRAGMENT_LIGHT1_SGIX 0x840D
+#define GL_FRAGMENT_LIGHT2_SGIX 0x840E
+#define GL_FRAGMENT_LIGHT3_SGIX 0x840F
+#define GL_FRAGMENT_LIGHT4_SGIX 0x8410
+#define GL_FRAGMENT_LIGHT5_SGIX 0x8411
+#define GL_FRAGMENT_LIGHT6_SGIX 0x8412
+#define GL_FRAGMENT_LIGHT7_SGIX 0x8413
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167
+#define GL_TEXTURE_POST_SPECULAR_HP 0x8168
+#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8
+#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_PHONG_WIN 0x80EA
+#define GL_PHONG_HINT_WIN 0x80EB
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_FRAGMENT_MATERIAL_EXT 0x8349
+#define GL_FRAGMENT_NORMAL_EXT 0x834A
+#define GL_FRAGMENT_COLOR_EXT 0x834C
+#define GL_ATTENUATION_EXT 0x834D
+#define GL_SHADOW_ATTENUATION_EXT 0x834E
+#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F
+#define GL_TEXTURE_LIGHT_EXT 0x8350
+#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351
+#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352
+/* reuse GL_FRAGMENT_DEPTH_EXT */
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_ALPHA_MIN_SGIX 0x8320
+#define GL_ALPHA_MAX_SGIX 0x8321
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_BGR_EXT 0x80E0
+#define GL_BGRA_EXT 0x80E1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_ASYNC_MARKER_SGIX 0x8329
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C
+#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D
+#define GL_ASYNC_READ_PIXELS_SGIX 0x835E
+#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F
+#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360
+#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_ASYNC_HISTOGRAM_SGIX 0x832C
+#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D
+#endif
+
+#ifndef GL_INTEL_texture_scissor
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_PARALLEL_ARRAYS_INTEL 0x83F4
+#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5
+#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6
+#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7
+#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_OCCLUSION_TEST_HP 0x8165
+#define GL_OCCLUSION_TEST_RESULT_HP 0x8166
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330
+#define GL_PIXEL_MAG_FILTER_EXT 0x8331
+#define GL_PIXEL_MIN_FILTER_EXT 0x8332
+#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333
+#define GL_CUBIC_EXT 0x8334
+#define GL_AVERAGE_EXT 0x8335
+#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336
+#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337
+#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8
+#define GL_SINGLE_COLOR_EXT 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_COLOR_SUM_EXT 0x8458
+#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_PERTURB_EXT 0x85AE
+#define GL_TEXTURE_NORMAL_EXT 0x85AF
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
+#define GL_FOG_COORDINATE_EXT 0x8451
+#define GL_FRAGMENT_DEPTH_EXT 0x8452
+#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
+#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_SCREEN_COORDINATES_REND 0x8490
+#define GL_INVERTED_SCREEN_W_REND 0x8491
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_TANGENT_ARRAY_EXT 0x8439
+#define GL_BINORMAL_ARRAY_EXT 0x843A
+#define GL_CURRENT_TANGENT_EXT 0x843B
+#define GL_CURRENT_BINORMAL_EXT 0x843C
+#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E
+#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F
+#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440
+#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441
+#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442
+#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443
+#define GL_MAP1_TANGENT_EXT 0x8444
+#define GL_MAP2_TANGENT_EXT 0x8445
+#define GL_MAP1_BINORMAL_EXT 0x8446
+#define GL_MAP2_BINORMAL_EXT 0x8447
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_COMBINE_EXT 0x8570
+#define GL_COMBINE_RGB_EXT 0x8571
+#define GL_COMBINE_ALPHA_EXT 0x8572
+#define GL_RGB_SCALE_EXT 0x8573
+#define GL_ADD_SIGNED_EXT 0x8574
+#define GL_INTERPOLATE_EXT 0x8575
+#define GL_CONSTANT_EXT 0x8576
+#define GL_PRIMARY_COLOR_EXT 0x8577
+#define GL_PREVIOUS_EXT 0x8578
+#define GL_SOURCE0_RGB_EXT 0x8580
+#define GL_SOURCE1_RGB_EXT 0x8581
+#define GL_SOURCE2_RGB_EXT 0x8582
+#define GL_SOURCE3_RGB_EXT 0x8583
+#define GL_SOURCE4_RGB_EXT 0x8584
+#define GL_SOURCE5_RGB_EXT 0x8585
+#define GL_SOURCE6_RGB_EXT 0x8586
+#define GL_SOURCE7_RGB_EXT 0x8587
+#define GL_SOURCE0_ALPHA_EXT 0x8588
+#define GL_SOURCE1_ALPHA_EXT 0x8589
+#define GL_SOURCE2_ALPHA_EXT 0x858A
+#define GL_SOURCE3_ALPHA_EXT 0x858B
+#define GL_SOURCE4_ALPHA_EXT 0x858C
+#define GL_SOURCE5_ALPHA_EXT 0x858D
+#define GL_SOURCE6_ALPHA_EXT 0x858E
+#define GL_SOURCE7_ALPHA_EXT 0x858F
+#define GL_OPERAND0_RGB_EXT 0x8590
+#define GL_OPERAND1_RGB_EXT 0x8591
+#define GL_OPERAND2_RGB_EXT 0x8592
+#define GL_OPERAND3_RGB_EXT 0x8593
+#define GL_OPERAND4_RGB_EXT 0x8594
+#define GL_OPERAND5_RGB_EXT 0x8595
+#define GL_OPERAND6_RGB_EXT 0x8596
+#define GL_OPERAND7_RGB_EXT 0x8597
+#define GL_OPERAND0_ALPHA_EXT 0x8598
+#define GL_OPERAND1_ALPHA_EXT 0x8599
+#define GL_OPERAND2_ALPHA_EXT 0x859A
+#define GL_OPERAND3_ALPHA_EXT 0x859B
+#define GL_OPERAND4_ALPHA_EXT 0x859C
+#define GL_OPERAND5_ALPHA_EXT 0x859D
+#define GL_OPERAND6_ALPHA_EXT 0x859E
+#define GL_OPERAND7_ALPHA_EXT 0x859F
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_TRANSFORM_HINT_APPLE 0x85B1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_FOG_SCALE_SGIX 0x81FC
+#define GL_FOG_SCALE_VALUE_SGIX 0x81FD
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5
+#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_GLOBAL_ALPHA_SUN 0x81D9
+#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_RESTART_SUN 0x01
+#define GL_REPLACE_MIDDLE_SUN 0x02
+#define GL_REPLACE_OLDEST_SUN 0x03
+#define GL_TRIANGLE_LIST_SUN 0x81D7
+#define GL_REPLACEMENT_CODE_SUN 0x81D8
+#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0
+#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1
+#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2
+#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3
+#define GL_R1UI_V3F_SUN 0x85C4
+#define GL_R1UI_C4UB_V3F_SUN 0x85C5
+#define GL_R1UI_C3F_V3F_SUN 0x85C6
+#define GL_R1UI_N3F_V3F_SUN 0x85C7
+#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8
+#define GL_R1UI_T2F_V3F_SUN 0x85C9
+#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA
+#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB
+#endif
+
+ /* DVR support --This is a temporary solution. Hopefully the new
+ glext.h from ARB will have GL_SUN_video_resize_compensation
+ defined. */
+#ifndef GL_SUN_video_resize_compensation
+#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD
+#endif
+
+#ifndef GL_SUN_vertex
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_BLEND_DST_RGB_EXT 0x80C8
+#define GL_BLEND_SRC_RGB_EXT 0x80C9
+#define GL_BLEND_DST_ALPHA_EXT 0x80CA
+#define GL_BLEND_SRC_ALPHA_EXT 0x80CB
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_RED_MIN_CLAMP_INGR 0x8560
+#define GL_GREEN_MIN_CLAMP_INGR 0x8561
+#define GL_BLUE_MIN_CLAMP_INGR 0x8562
+#define GL_ALPHA_MIN_CLAMP_INGR 0x8563
+#define GL_RED_MAX_CLAMP_INGR 0x8564
+#define GL_GREEN_MAX_CLAMP_INGR 0x8565
+#define GL_BLUE_MAX_CLAMP_INGR 0x8566
+#define GL_ALPHA_MAX_CLAMP_INGR 0x8567
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INTERLACE_READ_INGR 0x8568
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_INCR_WRAP_EXT 0x8507
+#define GL_DECR_WRAP_EXT 0x8508
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_422_EXT 0x80CC
+#define GL_422_REV_EXT 0x80CD
+#define GL_422_AVERAGE_EXT 0x80CE
+#define GL_422_REV_AVERAGE_EXT 0x80CF
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NORMAL_MAP_NV 0x8511
+#define GL_REFLECTION_MAP_NV 0x8512
+#endif
+
+#ifndef GL_EXT_texture_cube_map
+#define GL_NORMAL_MAP_EXT 0x8511
+#define GL_REFLECTION_MAP_EXT 0x8512
+#define GL_TEXTURE_CUBE_MAP_EXT 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_WRAP_BORDER_SUN 0x81D4
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH
+#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502
+#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX
+#define GL_MODELVIEW_MATRIX1_EXT 0x8506
+#define GL_VERTEX_WEIGHTING_EXT 0x8509
+#define GL_MODELVIEW0_EXT GL_MODELVIEW
+#define GL_MODELVIEW1_EXT 0x850A
+#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B
+#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C
+#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D
+#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E
+#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F
+#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_MAX_SHININESS_NV 0x8504
+#define GL_MAX_SPOT_EXPONENT_NV 0x8505
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_NV 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E
+#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
+#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_REGISTER_COMBINERS_NV 0x8522
+#define GL_VARIABLE_A_NV 0x8523
+#define GL_VARIABLE_B_NV 0x8524
+#define GL_VARIABLE_C_NV 0x8525
+#define GL_VARIABLE_D_NV 0x8526
+#define GL_VARIABLE_E_NV 0x8527
+#define GL_VARIABLE_F_NV 0x8528
+#define GL_VARIABLE_G_NV 0x8529
+#define GL_CONSTANT_COLOR0_NV 0x852A
+#define GL_CONSTANT_COLOR1_NV 0x852B
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_SPARE0_NV 0x852E
+#define GL_SPARE1_NV 0x852F
+#define GL_DISCARD_NV 0x8530
+#define GL_E_TIMES_F_NV 0x8531
+#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532
+#define GL_UNSIGNED_IDENTITY_NV 0x8536
+#define GL_UNSIGNED_INVERT_NV 0x8537
+#define GL_EXPAND_NORMAL_NV 0x8538
+#define GL_EXPAND_NEGATE_NV 0x8539
+#define GL_HALF_BIAS_NORMAL_NV 0x853A
+#define GL_HALF_BIAS_NEGATE_NV 0x853B
+#define GL_SIGNED_IDENTITY_NV 0x853C
+#define GL_SIGNED_NEGATE_NV 0x853D
+#define GL_SCALE_BY_TWO_NV 0x853E
+#define GL_SCALE_BY_FOUR_NV 0x853F
+#define GL_SCALE_BY_ONE_HALF_NV 0x8540
+#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541
+#define GL_COMBINER_INPUT_NV 0x8542
+#define GL_COMBINER_MAPPING_NV 0x8543
+#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544
+#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545
+#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546
+#define GL_COMBINER_MUX_SUM_NV 0x8547
+#define GL_COMBINER_SCALE_NV 0x8548
+#define GL_COMBINER_BIAS_NV 0x8549
+#define GL_COMBINER_AB_OUTPUT_NV 0x854A
+#define GL_COMBINER_CD_OUTPUT_NV 0x854B
+#define GL_COMBINER_SUM_OUTPUT_NV 0x854C
+#define GL_MAX_GENERAL_COMBINERS_NV 0x854D
+#define GL_NUM_GENERAL_COMBINERS_NV 0x854E
+#define GL_COLOR_SUM_CLAMP_NV 0x854F
+#define GL_COMBINER0_NV 0x8550
+#define GL_COMBINER1_NV 0x8551
+#define GL_COMBINER2_NV 0x8552
+#define GL_COMBINER3_NV 0x8553
+#define GL_COMBINER4_NV 0x8554
+#define GL_COMBINER5_NV 0x8555
+#define GL_COMBINER6_NV 0x8556
+#define GL_COMBINER7_NV 0x8557
+/* reuse GL_TEXTURE0_ARB */
+/* reuse GL_TEXTURE1_ARB */
+/* reuse GL_ZERO */
+/* reuse GL_NONE */
+/* reuse GL_FOG */
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_FOG_DISTANCE_MODE_NV 0x855A
+#define GL_EYE_RADIAL_NV 0x855B
+#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C
+/* reuse GL_EYE_PLANE */
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_EMBOSS_LIGHT_NV 0x855D
+#define GL_EMBOSS_CONSTANT_NV 0x855E
+#define GL_EMBOSS_MAP_NV 0x855F
+#endif
+
+#ifndef GL_NV_blend_square
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_COMBINE4_NV 0x8503
+#define GL_SOURCE3_RGB_NV 0x8583
+#define GL_SOURCE3_ALPHA_NV 0x858B
+#define GL_OPERAND3_RGB_NV 0x8593
+#define GL_OPERAND3_ALPHA_NV 0x859B
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#endif
+
+#ifndef GL_MESA_window_pos
+#endif
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_CULL_VERTEX_IBM 103050
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_VERTEX_ARRAY_LIST_IBM 103070
+#define GL_NORMAL_ARRAY_LIST_IBM 103071
+#define GL_COLOR_ARRAY_LIST_IBM 103072
+#define GL_INDEX_ARRAY_LIST_IBM 103073
+#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074
+#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075
+#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076
+#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077
+#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080
+#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081
+#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082
+#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083
+#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084
+#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085
+#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086
+#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0
+#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1
+#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2
+#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3
+#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_YCRCB_SGIX 0x8318
+#define GL_YCRCBA_SGIX 0x8319
+#endif
+
+#ifndef GL_SGI_depth_pass_instrument
+#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310
+#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311
+#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0
+#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_MULTISAMPLE_3DFX 0x86B2
+#define GL_SAMPLE_BUFFERS_3DFX 0x86B3
+#define GL_SAMPLES_3DFX 0x86B4
+#define GL_MULTISAMPLE_BIT_3DFX 0x20000000
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#define GL_SAMPLE_MASK_EXT 0x80A0
+#define GL_1PASS_EXT 0x80A1
+#define GL_2PASS_0_EXT 0x80A2
+#define GL_2PASS_1_EXT 0x80A3
+#define GL_4PASS_0_EXT 0x80A4
+#define GL_4PASS_1_EXT 0x80A5
+#define GL_4PASS_2_EXT 0x80A6
+#define GL_4PASS_3_EXT 0x80A7
+#define GL_SAMPLE_BUFFERS_EXT 0x80A8
+#define GL_SAMPLES_EXT 0x80A9
+#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA
+#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB
+#define GL_SAMPLE_PATTERN_EXT 0x80AC
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_CONVOLUTION_HINT_SGIX 0x8316
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_PACK_RESAMPLE_SGIX 0x842C
+#define GL_UNPACK_RESAMPLE_SGIX 0x842D
+#define GL_RESAMPLE_REPLICATE_SGIX 0x842E
+#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F
+#define GL_RESAMPLE_DECIMATE_SGIX 0x8430
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0
+#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1
+#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2
+#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3
+#define GL_EYE_POINT_SGIS 0x81F4
+#define GL_OBJECT_POINT_SGIS 0x81F5
+#define GL_EYE_LINE_SGIS 0x81F6
+#define GL_OBJECT_LINE_SGIS 0x81F7
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF
+#endif
+
+
+/*************************************************************/
+
+#ifndef GL_VERSION_1_2
+ /* #define GL_VERSION_1_2 1, I am not sure about this one */
+
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf);
+extern void APIENTRY glBlendEquation (GLenum);
+extern void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *);
+extern void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *);
+extern void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *);
+extern void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei);
+extern void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *);
+extern void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *);
+extern void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei);
+extern void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat);
+extern void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *);
+extern void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint);
+extern void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *);
+extern void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei);
+extern void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei);
+extern void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *);
+extern void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *);
+extern void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *);
+extern void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *);
+extern void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *);
+extern void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *);
+extern void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *);
+extern void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *);
+extern void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean);
+extern void APIENTRY glMinmax (GLenum, GLenum, GLboolean);
+extern void APIENTRY glResetHistogram (GLenum);
+extern void APIENTRY glResetMinmax (GLenum);
+extern void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (APIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (APIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+typedef void (APIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+typedef void (APIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target);
+typedef void (APIENTRY * PFNGLRESETMINMAXPROC) (GLenum target);
+typedef void (APIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_ARB_multitexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glActiveTextureARB (GLenum);
+extern void APIENTRY glClientActiveTextureARB (GLenum);
+extern void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble);
+extern void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *);
+extern void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat);
+extern void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *);
+extern void APIENTRY glMultiTexCoord1iARB (GLenum, GLint);
+extern void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *);
+extern void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort);
+extern void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *);
+extern void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble);
+extern void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *);
+extern void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat);
+extern void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *);
+extern void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint);
+extern void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *);
+extern void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort);
+extern void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *);
+extern void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble);
+extern void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *);
+extern void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *);
+extern void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint);
+extern void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *);
+extern void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort);
+extern void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *);
+extern void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble);
+extern void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *);
+extern void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *);
+extern void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint);
+extern void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *);
+extern void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort);
+extern void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_ARB_transpose_matrix 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *);
+extern void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *);
+extern void APIENTRY glMultTransposeMatrixfARB (const GLfloat *);
+extern void APIENTRY glMultTransposeMatrixdARB (const GLdouble *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+typedef void (APIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_ARB_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glSampleCoverageARB (GLclampf, GLboolean);
+extern void APIENTRY glSamplePassARB (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRY * PFNGLSAMPLEPASSARBPROC) (GLenum pass);
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#define GL_ARB_texture_env_add 1
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_ARB_texture_cube_map 1
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_ARB_texture_compression 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);
+extern void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);
+extern void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *);
+extern void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *);
+extern void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *);
+extern void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *);
+extern void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, void *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, void *img);
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_EXT_abgr 1
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_EXT_blend_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_EXT_polygon_offset 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias);
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_EXT_texture 1
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_EXT_texture3D 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_SGIS_texture_filter4 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights);
+typedef void (APIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights);
+#endif
+
+#ifndef GL_EXT_subtexture
+#define GL_EXT_subtexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_EXT_copy_texture
+#define GL_EXT_copy_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint);
+extern void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint);
+extern void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei);
+extern void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+extern void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_EXT_histogram 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *);
+extern void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *);
+extern void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *);
+extern void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *);
+extern void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean);
+extern void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean);
+extern void APIENTRY glResetHistogramEXT (GLenum);
+extern void APIENTRY glResetMinmaxEXT (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target);
+typedef void (APIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_EXT_convolution 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat);
+extern void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *);
+extern void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint);
+extern void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *);
+extern void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei);
+extern void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei);
+extern void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *);
+extern void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *);
+extern void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *);
+extern void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+#endif
+
+#ifndef GL_EXT_color_matrix
+#define GL_EXT_color_matrix 1
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_SGI_color_table 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *);
+extern void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *);
+extern void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei);
+extern void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *);
+extern void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_SGIX_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glPixelTexGenSGIX (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_SGIS_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint);
+extern void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *);
+extern void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat);
+extern void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *);
+extern void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *);
+extern void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param);
+typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_SGIS_texture4D 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_SGI_texture_color_table 1
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_EXT_cmyka 1
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_EXT_texture_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *);
+extern void APIENTRY glBindTextureEXT (GLenum, GLuint);
+extern void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *);
+extern void APIENTRY glGenTexturesEXT (GLsizei, GLuint *);
+extern GLboolean APIENTRY glIsTextureEXT (GLuint);
+extern void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences);
+typedef void (APIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture);
+typedef void (APIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures);
+typedef void (APIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures);
+typedef GLboolean (APIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture);
+typedef void (APIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_SGIS_detail_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *);
+extern void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_SGIS_sharpen_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *);
+extern void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_EXT_packed_pixels 1
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_SGIS_texture_lod 1
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_SGIS_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean);
+extern void APIENTRY glSamplePatternSGIS (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_EXT_rescale_normal 1
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_EXT_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glArrayElementEXT (GLint);
+extern void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *);
+extern void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei);
+extern void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *);
+extern void APIENTRY glGetPointervEXT (GLenum, GLvoid* *);
+extern void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *);
+extern void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *);
+extern void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *);
+extern void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i);
+typedef void (APIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer);
+typedef void (APIENTRY * PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params);
+typedef void (APIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#define GL_EXT_misc_attribute 1
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_SGIS_generate_mipmap 1
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_SGIX_clipmap 1
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_SGIX_shadow 1
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_SGIS_texture_edge_clamp 1
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_SGIS_texture_border_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glBlendEquationEXT (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_EXT_blend_subtract 1
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#define GL_EXT_blend_logic_op 1
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_SGIX_interlace 1
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_SGIX_pixel_tiles 1
+#endif
+
+#ifndef GL_SGIX_texture_select
+#define GL_SGIX_texture_select 1
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SGIX_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat);
+extern void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *);
+extern void APIENTRY glSpriteParameteriSGIX (GLenum, GLint);
+extern void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_SGIX_texture_multi_buffer 1
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_EXT_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glPointParameterfEXT (GLenum, GLfloat);
+extern void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *);
+extern void APIENTRY glPointParameterfSGIS (GLenum, GLfloat);
+extern void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_SGIX_instruments 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern GLint APIENTRY glGetInstrumentsSGIX (void);
+extern void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *);
+extern GLint APIENTRY glPollInstrumentsSGIX (GLint *);
+extern void APIENTRY glReadInstrumentsSGIX (GLint);
+extern void APIENTRY glStartInstrumentsSGIX (void);
+extern void APIENTRY glStopInstrumentsSGIX (GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLint (APIENTRY * PFNGLGETINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRY * PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer);
+typedef GLint (APIENTRY * PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p);
+typedef void (APIENTRY * PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker);
+typedef void (APIENTRY * PFNGLSTARTINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRY * PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker);
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_SGIX_texture_scale_bias 1
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_SGIX_framezoom 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glFrameZoomSGIX (GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor);
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#define GL_SGIX_tag_sample_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glTagSampleBufferSGIX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_SGIX_polynomial_ffd 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *);
+extern void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *);
+extern void APIENTRY glDeformSGIX (GLbitfield);
+extern void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points);
+typedef void (APIENTRY * PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points);
+typedef void (APIENTRY * PFNGLDEFORMSGIXPROC) (GLbitfield mask);
+typedef void (APIENTRY * PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask);
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_SGIX_reference_plane 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glReferencePlaneSGIX (const GLdouble *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation);
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#define GL_SGIX_flush_raster 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glFlushRasterSGIX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_SGIX_depth_texture 1
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_SGIS_fog_function 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *);
+extern void APIENTRY glGetFogFuncSGIS (const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points);
+typedef void (APIENTRY * PFNGLGETFOGFUNCSGISPROC) (const GLfloat *points);
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_SGIX_fog_offset 1
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_HP_image_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint);
+extern void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat);
+extern void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *);
+extern void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *);
+extern void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *);
+extern void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_HP_convolution_border_modes 1
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_SGIX_texture_add_env 1
+#endif
+
+#ifndef GL_EXT_color_subtable
+#define GL_EXT_color_subtable 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_PGI_vertex_hints 1
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PGI_misc_hints 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glHintPGI (GLenum, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLHINTPGIPROC) (GLenum target, GLint mode);
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_EXT_paletted_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *);
+extern void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *);
+extern void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data);
+typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_EXT_clip_volume_hint 1
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_SGIX_list_priority 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *);
+extern void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *);
+extern void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat);
+extern void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *);
+extern void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint);
+extern void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param);
+typedef void (APIENTRY * PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_SGIX_ir_instrument1 1
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_SGIX_calligraphic_fragment 1
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_SGIX_texture_lod_bias 1
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SGIX_shadow_ambient 1
+#endif
+
+#ifndef GL_EXT_index_texture
+#define GL_EXT_index_texture 1
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_EXT_index_material 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glIndexMaterialEXT (GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_EXT_index_func 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glIndexFuncEXT (GLenum, GLclampf);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref);
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_EXT_index_array_formats 1
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_EXT_compiled_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glLockArraysEXT (GLint, GLsizei);
+extern void APIENTRY glUnlockArraysEXT (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
+typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_EXT_cull_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *);
+extern void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params);
+typedef void (APIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_SGIX_ycrcb 1
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_SGIX_fragment_lighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum);
+extern void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat);
+extern void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *);
+extern void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint);
+extern void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *);
+extern void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat);
+extern void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *);
+extern void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint);
+extern void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *);
+extern void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat);
+extern void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *);
+extern void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint);
+extern void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *);
+extern void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *);
+extern void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *);
+extern void APIENTRY glLightEnviSGIX (GLenum, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode);
+typedef void (APIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (APIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param);
+typedef void (APIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_IBM_rasterpos_clip 1
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_HP_texture_lighting 1
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_EXT_draw_range_elements 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_WIN_phong_shading 1
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_WIN_specular_fog 1
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_EXT_light_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glApplyTextureEXT (GLenum);
+extern void APIENTRY glTextureLightEXT (GLenum);
+extern void APIENTRY glTextureMaterialEXT (GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode);
+typedef void (APIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname);
+typedef void (APIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_SGIX_blend_alpha_minmax 1
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_EXT_bgra 1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_SGIX_async 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glAsyncMarkerSGIX (GLuint);
+extern GLint APIENTRY glFinishAsyncSGIX (GLuint *);
+extern GLint APIENTRY glPollAsyncSGIX (GLuint *);
+extern GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei);
+extern void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei);
+extern GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker);
+typedef GLint (APIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp);
+typedef GLint (APIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp);
+typedef GLuint (APIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range);
+typedef void (APIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range);
+typedef GLboolean (APIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker);
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_SGIX_async_pixel 1
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_SGIX_async_histogram 1
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_INTEL_parallel_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *);
+extern void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *);
+extern void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *);
+extern void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_HP_occlusion_test 1
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_EXT_pixel_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint);
+extern void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat);
+extern void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *);
+extern void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#define GL_EXT_pixel_transform_color_table 1
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_EXT_shared_texture_palette 1
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_EXT_separate_specular_color 1
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_EXT_secondary_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte);
+extern void APIENTRY glSecondaryColor3bvEXT (const GLbyte *);
+extern void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble);
+extern void APIENTRY glSecondaryColor3dvEXT (const GLdouble *);
+extern void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glSecondaryColor3fvEXT (const GLfloat *);
+extern void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint);
+extern void APIENTRY glSecondaryColor3ivEXT (const GLint *);
+extern void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort);
+extern void APIENTRY glSecondaryColor3svEXT (const GLshort *);
+extern void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte);
+extern void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *);
+extern void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint);
+extern void APIENTRY glSecondaryColor3uivEXT (const GLuint *);
+extern void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort);
+extern void APIENTRY glSecondaryColor3usvEXT (const GLushort *);
+extern void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v);
+typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_EXT_texture_perturb_normal 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glTextureNormalEXT (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei);
+extern void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
+typedef void (APIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_EXT_fog_coord 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glFogCoordfEXT (GLfloat);
+extern void APIENTRY glFogCoordfvEXT (const GLfloat *);
+extern void APIENTRY glFogCoorddEXT (GLdouble);
+extern void APIENTRY glFogCoorddvEXT (const GLdouble *);
+extern void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+typedef void (APIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+typedef void (APIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+typedef void (APIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
+typedef void (APIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_REND_screen_coordinates 1
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_EXT_coordinate_frame 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte);
+extern void APIENTRY glTangent3bvEXT (const GLbyte *);
+extern void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble);
+extern void APIENTRY glTangent3dvEXT (const GLdouble *);
+extern void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glTangent3fvEXT (const GLfloat *);
+extern void APIENTRY glTangent3iEXT (GLint, GLint, GLint);
+extern void APIENTRY glTangent3ivEXT (const GLint *);
+extern void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort);
+extern void APIENTRY glTangent3svEXT (const GLshort *);
+extern void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte);
+extern void APIENTRY glBinormal3bvEXT (const GLbyte *);
+extern void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble);
+extern void APIENTRY glBinormal3dvEXT (const GLdouble *);
+extern void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glBinormal3fvEXT (const GLfloat *);
+extern void APIENTRY glBinormal3iEXT (GLint, GLint, GLint);
+extern void APIENTRY glBinormal3ivEXT (const GLint *);
+extern void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort);
+extern void APIENTRY glBinormal3svEXT (const GLshort *);
+extern void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *);
+extern void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz);
+typedef void (APIENTRY * PFNGLTANGENT3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRY * PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz);
+typedef void (APIENTRY * PFNGLTANGENT3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRY * PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz);
+typedef void (APIENTRY * PFNGLTANGENT3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRY * PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz);
+typedef void (APIENTRY * PFNGLTANGENT3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRY * PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz);
+typedef void (APIENTRY * PFNGLTANGENT3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRY * PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz);
+typedef void (APIENTRY * PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRY * PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz);
+typedef void (APIENTRY * PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRY * PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz);
+typedef void (APIENTRY * PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRY * PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz);
+typedef void (APIENTRY * PFNGLBINORMAL3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRY * PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz);
+typedef void (APIENTRY * PFNGLBINORMAL3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_EXT_texture_env_combine 1
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_APPLE_specular_vector 1
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_APPLE_transform_hint 1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_SGIX_fog_scale 1
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_SUNX_constant_data 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glFinishTextureSUNX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void);
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_SUN_global_alpha 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glGlobalAlphaFactorbSUN (GLbyte);
+extern void APIENTRY glGlobalAlphaFactorsSUN (GLshort);
+extern void APIENTRY glGlobalAlphaFactoriSUN (GLint);
+extern void APIENTRY glGlobalAlphaFactorfSUN (GLfloat);
+extern void APIENTRY glGlobalAlphaFactordSUN (GLdouble);
+extern void APIENTRY glGlobalAlphaFactorubSUN (GLubyte);
+extern void APIENTRY glGlobalAlphaFactorusSUN (GLushort);
+extern void APIENTRY glGlobalAlphaFactoruiSUN (GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
+typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
+typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor);
+typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor);
+typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor);
+typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor);
+typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor);
+typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor);
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_SUN_triangle_list 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glReplacementCodeuiSUN (GLuint);
+extern void APIENTRY glReplacementCodeusSUN (GLushort);
+extern void APIENTRY glReplacementCodeubSUN (GLubyte);
+extern void APIENTRY glReplacementCodeuivSUN (const GLuint *);
+extern void APIENTRY glReplacementCodeusvSUN (const GLushort *);
+extern void APIENTRY glReplacementCodeubvSUN (const GLubyte *);
+extern void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_SUN_vertex
+#define GL_SUN_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat);
+extern void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *);
+extern void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *);
+extern void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *);
+extern void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *);
+extern void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *);
+extern void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *);
+extern void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *);
+extern void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *);
+extern void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *);
+extern void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *);
+extern void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *);
+extern void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *);
+extern void APIENTRY glReplacementCodeuiVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLenum *, const GLfloat *);
+extern void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLenum, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLenum *, const GLubyte *, const GLfloat *);
+extern void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *);
+extern void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *);
+extern void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *, const GLfloat *);
+extern void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *);
+extern void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *, const GLfloat *);
+extern void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLenum rc, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *v);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLenum rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLenum *rc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLenum rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLenum rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_EXT_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_INGR_color_clamp 1
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INGR_interlace_read 1
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_EXT_stencil_wrap 1
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_EXT_422_pixels 1
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NV_texgen_reflection 1
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_SUN_convolution_border_modes 1
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#define GL_EXT_texture_env_add 1
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_EXT_vertex_weighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glVertexWeightfEXT (GLfloat);
+extern void APIENTRY glVertexWeightfvEXT (const GLfloat *);
+extern void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight);
+typedef void (APIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight);
+typedef void (APIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_NV_light_max_exponent 1
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_NV_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glFlushVertexArrayRangeNV (void);
+extern void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void);
+typedef void (APIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei size, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_NV_register_combiners 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *);
+extern void APIENTRY glCombinerParameterfNV (GLenum, GLfloat);
+extern void APIENTRY glCombinerParameterivNV (GLenum, const GLint *);
+extern void APIENTRY glCombinerParameteriNV (GLenum, GLint);
+extern void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum);
+extern void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean);
+extern void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum);
+extern void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *);
+extern void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *);
+extern void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *);
+extern void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+typedef void (APIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_NV_fog_distance 1
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_NV_texgen_emboss 1
+#endif
+
+#ifndef GL_NV_blend_square
+#define GL_NV_blend_square 1
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_NV_texture_env_combine4 1
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#define GL_MESA_resize_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glResizeBuffersMESA (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void);
+#endif
+
+#ifndef GL_MESA_window_pos
+#define GL_MESA_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble);
+extern void APIENTRY glWindowPos2dvMESA (const GLdouble *);
+extern void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat);
+extern void APIENTRY glWindowPos2fvMESA (const GLfloat *);
+extern void APIENTRY glWindowPos2iMESA (GLint, GLint);
+extern void APIENTRY glWindowPos2ivMESA (const GLint *);
+extern void APIENTRY glWindowPos2sMESA (GLshort, GLshort);
+extern void APIENTRY glWindowPos2svMESA (const GLshort *);
+extern void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble);
+extern void APIENTRY glWindowPos3dvMESA (const GLdouble *);
+extern void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glWindowPos3fvMESA (const GLfloat *);
+extern void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint);
+extern void APIENTRY glWindowPos3ivMESA (const GLint *);
+extern void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort);
+extern void APIENTRY glWindowPos3svMESA (const GLshort *);
+extern void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble);
+extern void APIENTRY glWindowPos4dvMESA (const GLdouble *);
+extern void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat);
+extern void APIENTRY glWindowPos4fvMESA (const GLfloat *);
+extern void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint);
+extern void APIENTRY glWindowPos4ivMESA (const GLint *);
+extern void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort);
+extern void APIENTRY glWindowPos4svMESA (const GLshort *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y);
+typedef void (APIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y);
+typedef void (APIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v);
+typedef void (APIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_IBM_cull_vertex 1
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#define GL_IBM_multimode_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glMultiModeDrawArraysIBM (GLenum, const GLint *, const GLsizei *, GLsizei, GLint);
+extern void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* *, GLsizei, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+typedef void (APIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, GLint modestride);
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_IBM_vertex_array_lists 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint);
+extern void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint);
+extern void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint);
+extern void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint);
+extern void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint);
+extern void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint);
+extern void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint);
+extern void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride);
+typedef void (APIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_SGIX_subsample 1
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_SGIX_ycrcba 1
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#define GL_SGIX_ycrcb_subsample 1
+#endif
+
+#ifndef GL_SGIX_depth_pass_instrument
+#define GL_SGIX_depth_pass_instrument 1
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_3DFX_texture_compression_FXT1 1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_3DFX_multisample 1
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#define GL_3DFX_tbuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glTbufferMask3DFX (GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask);
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_EXT_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glSampleMaskEXT (GLclampf, GLboolean);
+extern void APIENTRY glSamplePatternEXT (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_SGI_vertex_preclip
+#define GL_SGI_vertex_preclip 1
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_SGIX_convolution_accuracy 1
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_SGIX_resample 1
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_SGIS_point_line_texgen 1
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_SGIS_texture_color_mask 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+#endif
+
+#ifndef GL_SGIX_igloo_interface
+#define GL_SGIX_igloo_interface 1
+#ifdef GL_GLEXT_PROTOTYPES
+extern void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRY * PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/native/ogl/panoramiXext.h b/src/native/ogl/panoramiXext.h
new file mode 100644
index 0000000..b5162a7
--- /dev/null
+++ b/src/native/ogl/panoramiXext.h
@@ -0,0 +1,102 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/* $TOG: panoramiXext.h /main/3 1998/02/13 13:08:51 kaleb $ */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+/*
+ * PanoramiX definitions
+ */
+
+/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */
+
+#define PANORAMIX_MAJOR_VERSION 1 /* current version number */
+#define PANORAMIX_MINOR_VERSION 0
+
+typedef struct {
+ Window window; /* PanoramiX window - may not exist */
+ int screen;
+ int State; /* PanroamiXOff, PanoramiXOn */
+ int width; /* width of this screen */
+ int height; /* height of this screen */
+ int ScreenCount; /* real physical number of screens */
+ XID eventMask; /* selected events for this client */
+} XPanoramiXInfo;
+
+extern XPanoramiXInfo *XPanoramiXAllocInfo (
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+#define XINERAMA_PLACE_TOP 1
+#define XINERAMA_PLACE_BOTTOM 2
+#define XINERAMA_PLACE_RIGHT 4
+#define XINERAMA_PLACE_LEFT 8
+
+#ifndef _XINERAMAINFO_
+#define _XINERAMAINFO_
+
+#define XinID int
+#define MAXSCREEN 16
+#define DELTA int
+#define POINT int
+
+typedef struct subwid
+{
+ XinID wid; /* sub window id */
+ DELTA dx,dy; /* delta in screen co-ord from virtual zero */
+ POINT x,y; /* location of window in screen co-ord */
+ DELTA wdx,wdy;/* size of window in screen co-ord */
+}SubWID, *pSubWID;
+
+typedef struct xineramainfo
+{
+ XinID wid; /* Window ID of requested virtual window */
+ SubWID subs[MAXSCREEN]; /* there will be 16 slots */
+}XineramaInfo, *pXineramaInfo;
+#endif
+
+#ifndef NO_PROTO_HERE
+Bool XDgaGetXineramaInfo(
+#if NeedFunctionPrototypes
+/* this brakes the server
+Display *, int, XID, XineramaInfo *
+*/
+#endif
+);
+#endif
diff --git a/src/native/share/build-linux-i586.xml b/src/native/share/build-linux-i586.xml
new file mode 100644
index 0000000..8968f9a
--- /dev/null
+++ b/src/native/share/build-linux-i586.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native utilities files for Linux -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native utilities build [${bldType}]"/>
+
+ <!-- Create the build directories linux -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/share/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/lib/i386"/>
+
+ <!-- Compile the c source files-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs" executable="gcc">
+ <arg line="-m32 -I/include -I${java.home}/../include -I${java.home}/../include/linux -I/usr/openwin/include -I${javahUtilsTarget} -${bldFlag} -DLINUX -c ${core_utils_src}/native/share/J3DTimer.c"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs" executable="ld">
+ <arg line="J3DTimer.o -G -z lazyload -lc -o libj3dutils.so"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/share/objs/libj3dutils.so"
+ todir="${build}/${platform}/${bldType}/lib/i386"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/lib/i386"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/lib/i386/libj3dutils.so"
+ todir="${dist}/${platform}/lib/i386"/>
+ </target>
+
+
+</project>
diff --git a/src/native/share/build-solaris-sparc-forte.xml b/src/native/share/build-solaris-sparc-forte.xml
new file mode 100644
index 0000000..873cf4b
--- /dev/null
+++ b/src/native/share/build-solaris-sparc-forte.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native utilities files for Solaris -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native utilities build [${bldType}]"/>
+
+ <!-- Create the build directories sparc -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/share/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/lib/sparc"/>
+
+ <!-- Compile the c source files-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs" executable="cc">
+ <arg line="-v -xCC -xchip=ultra -xarch=v8a -I/include -I${java.home}/../include -I${java.home}/../include/solaris -I/usr/openwin/include -I${javahUtilsTarget} -${bldFlag} -DSOLARIS -c ${core_utils_src}/native/share/J3DTimer.c"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs" executable="ld">
+ <arg line="J3DTimer.o -G -z lazyload -lposix4 -lc -o libj3dutils.so"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/share/objs/libj3dutils.so"
+ todir="${build}/${platform}/${bldType}/lib/sparc"/>
+
+<!-- ********************************************************************** -->
+ <echo message="Executing 64 bit native utilities build [${bldType}]"/>
+
+ <!-- Create the build directories sparcv9 -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/share/objs/sparcv9"/>
+ <mkdir dir="${build}/${platform}/${bldType}/lib/sparcv9"/>
+
+ <!-- Compile the c source files-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs/sparcv9" executable="cc">
+ <arg line="-v -xCC -xchip=ultra -xarch=v9a -I/include -I${java.home}/../include -I${java.home}/../include/solaris -I/usr/openwin/include -I${javahUtilsTarget} -${bldFlag} -DSOLARIS -c ${core_utils_src}/native/share/J3DTimer.c"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs/sparcv9" executable="ld">
+ <arg line="J3DTimer.o -G -z lazyload -lposix4 -lc -o libj3dutils.so"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/share/objs/sparcv9/libj3dutils.so"
+ todir="${build}/${platform}/${bldType}/lib/sparcv9"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/lib/sparc"/>
+ <mkdir dir="${dist}/${platform}/lib/sparcv9"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/lib/sparc/libj3dutils.so"
+ todir="${dist}/${platform}/lib/sparc"/>
+
+ <copy file="${build}/${platform}/opt/lib/sparcv9/libj3dutils.so"
+ todir="${dist}/${platform}/lib/sparcv9"/>
+ </target>
+
+
+</project>
diff --git a/src/native/share/build-solaris-sparc-gcc.xml b/src/native/share/build-solaris-sparc-gcc.xml
new file mode 100644
index 0000000..b3c78e2
--- /dev/null
+++ b/src/native/share/build-solaris-sparc-gcc.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native utilities files for Solaris -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native utilities build [${bldType}]"/>
+
+ <!-- Create the build directories sparc -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/share/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/lib/sparc"/>
+
+ <!-- Compile the c source files-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs" executable="gcc">
+ <arg line="-m32 -mcpu=v9 -mtune=v9 -I/include -I${java.home}/../include -I${java.home}/../include/solaris -I/usr/openwin/include -I${javahUtilsTarget} -${bldFlag} -DSOLARIS -c ${core_utils_src}/native/share/J3DTimer.c"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs" executable="ld">
+ <arg line="J3DTimer.o -G -z lazyload -lposix4 -lc -o libj3dutils.so"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/share/objs/libj3dutils.so"
+ todir="${build}/${platform}/${bldType}/lib/sparc"/>
+
+<!-- ********************************************************************** -->
+ <echo message="Executing 64 bit native utilities build [${bldType}]"/>
+
+ <!-- Create the build directories sparcv9 -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/share/objs/sparcv9"/>
+ <mkdir dir="${build}/${platform}/${bldType}/lib/sparcv9"/>
+
+ <!-- Compile the c source files-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs/sparcv9" executable="gcc">
+ <arg line="-m64 -mcpu=v9 -mtune=v9 -I/include -I${java.home}/../include -I${java.home}/../include/solaris -I/usr/openwin/include -I${javahUtilsTarget} -${bldFlag} -DSOLARIS -c ${core_utils_src}/native/share/J3DTimer.c"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs/sparcv9" executable="ld">
+ <arg line="J3DTimer.o -G -z lazyload -lposix4 -lc -o libj3dutils.so"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/share/objs/sparcv9/libj3dutils.so"
+ todir="${build}/${platform}/${bldType}/lib/sparcv9"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/lib/sparc"/>
+ <mkdir dir="${dist}/${platform}/lib/sparcv9"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/lib/sparc/libj3dutils.so"
+ todir="${dist}/${platform}/lib/sparc"/>
+
+ <copy file="${build}/${platform}/opt/lib/sparcv9/libj3dutils.so"
+ todir="${dist}/${platform}/lib/sparcv9"/>
+ </target>
+
+
+</project>
diff --git a/src/native/share/build-windows-i586-gcc.xml b/src/native/share/build-windows-i586-gcc.xml
new file mode 100644
index 0000000..b34144d
--- /dev/null
+++ b/src/native/share/build-windows-i586-gcc.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native utilities files for Windows-i586 -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native utilities build [${bldType}]"/>
+
+ <!-- Create the build directories sparc -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/share/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/bin"/>
+
+ <property name="javaInclude"
+ location="${java.home}/../include"/>
+
+ <property name="javaWin32Include"
+ location="${java.home}/../include/win32"/>
+
+ <property name="sharesrc"
+ location="${core_utils_src}/native/share"/>
+
+ <!-- Compile the c source files-->
+ <!-- Inhibit all warning for native build. Remove -w to switch warning on -->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs" executable="gcc">
+ <arg line="-w -D_WINGDI_ -D_JNI_IMPLEMENTATION_ -I&quot;${javaInclude}&quot; -I&quot;${javaWin32Include}&quot; -I&quot;${javahUtilsTarget}&quot; ${bldFlag} -c &quot;${sharesrc}/J3DTimer.c&quot;"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs" executable="gcc">
+ <arg line="-shared -o j3dutils.dll J3DTimer.o -Wl,--kill-at -L&quot;${java.home}\..\lib&quot; -ljawt"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/share/objs/j3dutils.dll"
+ todir="${build}/${platform}/${bldType}/bin"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/bin"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/bin/j3dutils.dll"
+ todir="${dist}/${platform}/bin"/>
+ </target>
+
+</project>
diff --git a/src/native/share/build-windows-i586-vc.xml b/src/native/share/build-windows-i586-vc.xml
new file mode 100644
index 0000000..8b4cde7
--- /dev/null
+++ b/src/native/share/build-windows-i586-vc.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<!-- Ant file for building native utilities files for Windows-i586 -->
+<project name="Java 3D" default="compile">
+
+ <target name="compile">
+
+ <echo message="Executing 32 bit native utilities build [${bldType}]"/>
+
+ <!-- Create the build directories sparc -->
+ <mkdir dir="${build}/${platform}/${bldType}/native/share/objs"/>
+ <mkdir dir="${build}/${platform}/${bldType}/bin"/>
+
+ <property name="javaInclude"
+ location="${java.home}/../include"/>
+
+ <property name="javaWin32Include"
+ location="${java.home}/../include/win32"/>
+
+ <property name="sharesrc"
+ location="${core_utils_src}/native/share"/>
+
+ <!-- Compile the c source files-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs" executable="cl">
+ <arg line="-I&quot;${javaInclude}&quot; -I&quot;${javaWin32Include}&quot; -I&quot;${javahUtilsTarget}&quot; ${bldFlag} -c &quot;${sharesrc}/J3DTimer.c&quot;"/>
+ </exec>
+
+ <!-- Create the library file-->
+ <exec dir="${build}/${platform}/${bldType}/native/share/objs" executable="link">
+ <arg line="-nologo -dll -subsystem:windows -pdb:none -machine:I386 -out:j3dutils.dll J3DTimer.obj delayimp.lib -LIBPATH:&quot;${java.home}\..\lib&quot; jawt.lib"/>
+ </exec>
+
+ <!-- Copy the copyright library file -->
+ <copy file="${build}/${platform}/${bldType}/native/share/objs/j3dutils.dll"
+ todir="${build}/${platform}/${bldType}/bin"/>
+
+ </target>
+
+ <target name="dist">
+ <!-- Create the distribution directory -->
+ <mkdir dir="${dist}/${platform}/bin"/>
+
+ <!-- Copy the library files -->
+ <copy file="${build}/${platform}/opt/bin/j3dutils.dll"
+ todir="${dist}/${platform}/bin"/>
+ </target>
+
+</project>