aboutsummaryrefslogtreecommitdiffstats
path: root/src/native/d3d/Canvas3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/native/d3d/Canvas3D.cpp')
-rw-r--r--src/native/d3d/Canvas3D.cpp1029
1 files changed, 1029 insertions, 0 deletions
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);
+}
+