aboutsummaryrefslogtreecommitdiffstats
path: root/src/native/d3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/native/d3d')
-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
27 files changed, 26026 insertions, 0 deletions
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>