diff options
Diffstat (limited to 'src/native/d3d/Attributes.cpp')
-rw-r--r-- | src/native/d3d/Attributes.cpp | 3014 |
1 files changed, 3014 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); + } +} |