/* * $RCSfile$ * * Copyright (c) 2007 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_NativePipeline_setDrawActive( JNIEnv *env, jobject obj, jint fd) { // This function is only used for Solaris OpenGL } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_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_NativePipeline_useSharedCtx( JNIEnv *env, jobject obj) { return JNI_FALSE; } extern "C" JNIEXPORT jlong JNICALL Java_javax_media_j3d_NativePipeline_createNewContext( JNIEnv *env, jobject obj, jobject cv, jlong display, jlong window, jlong fbConfigListPtr, jlong sharedCtx, jboolean isSharedCtx, jboolean offScreen, jboolean glslLibraryAvailable, jboolean cgLibraryAvailable) { HWND hwnd = WindowFromDC(reinterpret_cast(window)); lock(); int vid = 0; // TODO: get needed info from fbConfigListPtr D3dCtx* ctx = new D3dCtx(env, cv, hwnd, offScreen, vid); if (ctx == NULL) { printf("%s", getErrorMessage(OUTOFMEMORY)); unlock(); return 0; } if (offScreen) { jclass cls = (jclass) env->GetObjectClass(cv); jfieldID fieldId = env->GetFieldID(cls, "offScreenCanvasSize", "Ljava/awt/Dimension;"); jobject dimObj = env->GetObjectField(cv, 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, cv)) { delete ctx; unlock(); return 0; } d3dCtxList.push_back(ctx); unlock(); return reinterpret_cast(ctx); } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_createQueryContext( JNIEnv *env, jobject obj, jobject cv, jlong display, jlong window, jlong fbConfigListPtr, jboolean offScreen, jint width, jint height, jboolean glslLibraryAvailable, jboolean cgLibraryAvailable) { HWND hwnd = WindowFromDC(reinterpret_cast(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. int vid = 0; // TODO: get needed info from fbConfigListPtr D3dCtx* ctx = new D3dCtx(env, cv, hwnd, true, vid); if (ctx == NULL) { printf("%s", getErrorMessage(OUTOFMEMORY)); unlock(); return; } ctx->offScreenWidth = width; ctx->offScreenHeight = height; ctx->initialize(env, cv); delete ctx; unlock(); } extern "C" JNIEXPORT jboolean JNICALL Java_javax_media_j3d_NativePipeline_useCtx( JNIEnv *env, jobject obj, jlong ctx, jlong display, jlong window) { return JNI_TRUE; // D3D doesn't have notation of current context } extern "C" JNIEXPORT jint JNICALL Java_javax_media_j3d_NativePipeline_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 jboolean JNICALL Java_javax_media_j3d_NativePipeline_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_NativePipeline_freeTexture(env, NULL, ctx, objectId); } Java_javax_media_j3d_NativePipeline_bindTexture2D(env, texture, ctx, objectId, TRUE); Java_javax_media_j3d_NativePipeline_updateTexture2DImage(env, texture, ctx, 1, 0, J3D_RGBA, 0, texWidth, texHeight, 0, 0, NULL, JNI_FALSE); return (d3dCtx->textureTable[objectId] != NULL); } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_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 byteData, jint winWidth, jint winHeight) { GetDevice(); Java_javax_media_j3d_NativePipeline_bindTexture2D( env, texture, ctx, objectId, TRUE); Java_javax_media_j3d_NativePipeline_updateTexture2DSubImage( env, texture, ctx, 0, minX, minY, J3D_RGBA, format, minX, minY, rasWidth, maxX-minX, maxY-minY, IMAGE_DATA_TYPE_BYTE_ARRAY, byteData, JNI_FALSE); LPDIRECT3DTEXTURE9 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_NativePipeline_bindTexture2D( 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_NativePipeline_clear( JNIEnv *env, jobject obj, jlong ctx, jfloat r, jfloat g, jfloat b, jboolean clearStencil) { GetDevice(); // TODO ACES: The d3dCtx->stencilEnable and d3dCtx->stencilWriteEnable flags // are not used in the rest of the code. They are never set to a value, and // they are not looked at by most of the code. /* Java 3D always clears the Z-buffer */ if (!d3dCtx->zWriteEnable) { device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); } // Issue 239 - clear stencil, if requested if (clearStencil) { device->SetRenderState(D3DRS_STENCILENABLE, TRUE); device->SetRenderState(D3DRS_STENCILWRITEMASK, ~0); // clear stencil and ZBuffer HRESULT hr = device->Clear(0, NULL, D3DCLEAR_STENCIL | D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(r, g, b, 1.0f), 1.0, 0); if (hr == D3DERR_INVALIDCALL) { printf("[Java3D] Error cleaning Canvas3D stencil & ZBuffer\n"); } // printf("canvas3D clear stencil & ZBuffer\n"); // TODO: DO WE NEED TO RESTORE THE STENCIL ENABLE AND WRITE MASK??? // if (!d3dCtx->stencilEnable) { // device->SetRenderState(D3DRS_STENCILENABLE, FALSE); // } // if (!d3dCtx->stencilWriteEnable) { // device->SetRenderState(D3DRS_STENCILWRITEMASK, 0); // } } else { // clear ZBuffer only HRESULT hr = device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(r, g, b, 1.0f), 1.0, 0); if (hr == D3DERR_INVALIDCALL) { printf("[Java3D] Error cleaning Canvas3D ZBuffer\n"); } // printf("canvas3D clear ZBuffer\n"); } if (!d3dCtx->zWriteEnable) { device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); } } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_textureFillBackground( JNIEnv *env, jobject obj, jlong ctx, jfloat texMinU, jfloat texMaxU, jfloat texMinV, jfloat texMaxV, jfloat mapMinX, jfloat mapMaxX, jfloat mapMinY, jfloat mapMaxY, jboolean useBilinearFilter) { DWORD alphaTest, alphaBlend, cull, zBuffer, fog, lighting, stencil, specular; D3DXMATRIX Ortho2D; D3DXMATRIX ptm, wtm, vtm; COORDTEXVERTEX verts[4]; D3DXMATRIX texMatrix; int tus; GetDevice(); device->GetRenderState(D3DRS_ALPHATESTENABLE, &alphaTest); device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); device->GetRenderState(D3DRS_ALPHABLENDENABLE, &alphaBlend); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); device->GetRenderState(D3DRS_CULLMODE, &cull); device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); device->GetRenderState(D3DRS_ZENABLE, &zBuffer); device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); device->GetRenderState(D3DRS_FOGENABLE, &fog); device->SetRenderState(D3DRS_FOGENABLE, FALSE); device->GetRenderState(D3DRS_LIGHTING, &lighting); device->SetRenderState(D3DRS_LIGHTING, FALSE); device->GetRenderState(D3DRS_STENCILENABLE, &stencil); device->SetRenderState(D3DRS_STENCILENABLE, FALSE); device->GetRenderState(D3DRS_SPECULARENABLE, &specular); device->SetRenderState(D3DRS_SPECULARENABLE, FALSE); tus = d3dCtx->texUnitStage; if (tus >= d3dCtx->bindTextureIdLen) { if (debug) { printf("Internal Error: texUnitState %d, bindTextureIDLen %d\n", d3dCtx->texUnitStage, d3dCtx->bindTextureIdLen); } return; } if (d3dCtx->texTransformSet[tus]) { device->GetTransform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0 + tus), &texMatrix); device->SetTransform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0 + tus), &identityMatrix); } // TextureStage will be restore by caller. device->SetTextureStageState(tus, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU); /* Setup filter mode if needed */ if(useBilinearFilter) { /* fprintf(stderr, "Background : use bilinear filter\n"); */ device->SetSamplerState (tus, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState (tus, D3DSAMP_MIPFILTER, D3DTEXF_POINT); device->SetSamplerState (tus, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); } /* For debugging only else { fprintf(stderr, "Background : Not use bilinear filter\n"); } */ device->GetTransform(D3DTS_PROJECTION, &ptm); device->GetTransform(D3DTS_WORLD, &wtm); device->GetTransform(D3DTS_VIEW, &vtm); Ortho2D._11 = 1.0; Ortho2D._12 = 0.0; Ortho2D._13 = 0.0; Ortho2D._14 = 0.0; Ortho2D._21 = 0.0; Ortho2D._22 = 1.0; Ortho2D._23 = 0.0; Ortho2D._24 = 0.0; Ortho2D._31 = 0.0; Ortho2D._32 = 0.0; Ortho2D._33 = 0.5; Ortho2D._34 = 0.0; Ortho2D._41 = 0.0; Ortho2D._42 = 0.0; Ortho2D._43 = 0.5; Ortho2D._44 = 1.0; /* printf("Ortho2D matix : \n"); printf("%f, %f, %f, %f\n", Ortho2D._11, Ortho2D._12, Ortho2D._13, Ortho2D._14); printf("%f, %f, %f, %f\n", Ortho2D._21, Ortho2D._22, Ortho2D._23, Ortho2D._24); printf("%f, %f, %f, %f\n", Ortho2D._31, Ortho2D._32, Ortho2D._33, Ortho2D._34); printf("%f, %f, %f, %f\n", Ortho2D._41, Ortho2D._42, Ortho2D._43, Ortho2D._44); */ device->SetTransform(D3DTS_PROJECTION, &Ortho2D); device->SetTransform(D3DTS_WORLD, &identityMatrix); device->SetTransform(D3DTS_VIEW, &identityMatrix); verts[0].tu = texMinU; /* tumin; */ verts[0].tv = texMaxV; /* tvmax; */ verts[1].tu = texMinU; /* tumin; */ verts[1].tv = texMinV; /* tvmin; */ verts[2].tu = texMaxU; /* tumax; */ verts[2].tv = texMaxV; /* tvmax; */ verts[3].tu = texMaxU; /* tumax; */ verts[3].tv = texMinV; /* tvmin; */ verts[0].sx = mapMinX; verts[0].sy = mapMaxY; verts[0].sz = 0.999f; verts[1].sx = mapMinX; verts[1].sy = mapMinY; verts[1].sz = 0.999f; verts[2].sx = mapMaxX; verts[2].sy = mapMaxY; verts[2].sz = 0.999f; verts[3].sx = mapMaxX; verts[3].sy = mapMinY; verts[3].sz = 0.999f; /* printf("(texMinU,texMinV,texMaxU,texMaxV) = (%3.2f,%3.2f,%3.2f,%3.2f)\n", texMinU,texMinV,texMaxU,texMaxV); printf("(mapMinX,mapMinY,mapMaxX,mapMaxY) = (%3.2f,%3.2f,%3.2f,%3.2f)\n", mapMinX,mapMinY,mapMaxX,mapMaxY); */ device->SetVertexShader(NULL); device->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(COORDTEXVERTEX)); /* Restore renderstates */ device->SetRenderState(D3DRS_ALPHATESTENABLE, alphaTest); device->SetRenderState(D3DRS_CULLMODE, cull); device->SetRenderState(D3DRS_ZENABLE, zBuffer); device->SetRenderState(D3DRS_FOGENABLE, fog); device->SetRenderState(D3DRS_LIGHTING, lighting); device->SetRenderState(D3DRS_STENCILENABLE, stencil); device->SetRenderState(D3DRS_SPECULARENABLE, specular); /* Restore texture Matrix transform */ if (d3dCtx->texTransformSet[tus]) { device->SetTransform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0 + tus), &texMatrix); } device->SetTransform(D3DTS_PROJECTION, &ptm); device->SetTransform(D3DTS_WORLD, &wtm); device->SetTransform(D3DTS_VIEW, &vtm); } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_textureFillRaster(JNIEnv *env, jobject obj, jlong ctx, jfloat texMinU, jfloat texMaxU, jfloat texMinV, jfloat texMaxV, jfloat mapMinX, jfloat mapMaxX, jfloat mapMinY, jfloat mapMaxY, jfloat mapZ, jfloat alpha, jboolean useBilinearFilter) { DWORD cull, lighting; D3DXMATRIX Ortho2D; D3DXMATRIX ptm, wtm, vtm; COORDCLRTEXVERTEX verts[4]; D3DXMATRIX texMatrix; int tus; GetDevice(); device->GetRenderState(D3DRS_CULLMODE, &cull); device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); device->GetRenderState(D3DRS_LIGHTING, &lighting); device->SetRenderState(D3DRS_LIGHTING, FALSE); tus = d3dCtx->texUnitStage; if (tus >= d3dCtx->bindTextureIdLen) { if (debug) { printf("Internal Error: texUnitState %d, bindTextureIDLen %d\n", d3dCtx->texUnitStage, d3dCtx->bindTextureIdLen); } return; } // TextureStage will be restore by caller. device->SetTextureStageState(tus, D3DTSS_ALPHAOP, D3DTOP_MODULATE); device->SetTextureStageState(tus, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); device->SetTextureStageState(tus, D3DTSS_ALPHAARG2, D3DTA_CURRENT); /* Setup filter mode if needed */ if(useBilinearFilter) { /* fprintf(stderr, "Raster : use bilinear filter\n"); */ device->SetSamplerState (tus, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState (tus, D3DSAMP_MIPFILTER, D3DTEXF_POINT); device->SetSamplerState (tus, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); } /* For debugging only else { fprintf(stderr, "Raster : Not use bilinear filter\n"); } */ device->GetTransform(D3DTS_PROJECTION, &ptm); device->GetTransform(D3DTS_WORLD, &wtm); device->GetTransform(D3DTS_VIEW, &vtm); Ortho2D._11 = 2.0; Ortho2D._12 = 0.0; Ortho2D._13 = 0.0; Ortho2D._14 = 0.0; Ortho2D._21 = 0.0; Ortho2D._22 = 2.0; Ortho2D._23 = 0.0; Ortho2D._24 = 0.0; Ortho2D._31 = 0.0; Ortho2D._32 = 0.0; Ortho2D._33 = -1.0; Ortho2D._34 = 0.0; Ortho2D._41 = -1.0; Ortho2D._42 = -1.0; Ortho2D._43 = 0.0; Ortho2D._44 = 1.0; /* printf("Ortho2D matix : \n"); printf("%f, %f, %f, %f\n", Ortho2D._11, Ortho2D._12, Ortho2D._13, Ortho2D._14); printf("%f, %f, %f, %f\n", Ortho2D._21, Ortho2D._22, Ortho2D._23, Ortho2D._24); printf("%f, %f, %f, %f\n", Ortho2D._31, Ortho2D._32, Ortho2D._33, Ortho2D._34); printf("%f, %f, %f, %f\n", Ortho2D._41, Ortho2D._42, Ortho2D._43, Ortho2D._44); */ device->SetTransform(D3DTS_WORLD, &identityMatrix); device->SetTransform(D3DTS_VIEW, &identityMatrix); device->SetTransform(D3DTS_PROJECTION, &Ortho2D); verts[0].tu = texMinU; /* tumin; */ verts[0].tv = texMaxV; /* tvmax; */ verts[1].tu = texMinU; /* tumin; */ verts[1].tv = texMinV; /* tvmin; */ verts[2].tu = texMaxU; /* tumax; */ verts[2].tv = texMaxV; /* tvmax; */ verts[3].tu = texMaxU; /* tumax; */ verts[3].tv = texMinV; /* tvmin; */ D3DCOLOR alphaColor = 0xffffff | ((int)(alpha * 255.0f) << 24); verts[0].color = alphaColor; verts[0].sx = mapMinX; verts[0].sy = mapMaxY; verts[0].sz = mapZ; verts[1].color = alphaColor; verts[1].sx = mapMinX; verts[1].sy = mapMinY; verts[1].sz = mapZ; verts[2].color = alphaColor; verts[2].sx = mapMaxX; verts[2].sy = mapMaxY; verts[2].sz = mapZ; verts[3].color = alphaColor; verts[3].sx = mapMaxX; verts[3].sy = mapMinY; verts[3].sz = mapZ; /* printf("(texMinU,texMinV,texMaxU,texMaxV) = (%3.2f,%3.2f,%3.2f,%3.2f)\n", texMinU,texMinV,texMaxU,texMaxV); printf("(mapMinX,mapMinY,mapMaxX,mapMaxY) = (%3.2f,%3.2f,%3.2f,%3.2f)\n", mapMinX,mapMinY,mapMaxX,mapMaxY); printf("(mapZ) = (%3.2f)\n",mapZ); */ device->SetVertexShader(NULL); device->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_TEXCOORDSIZE2(0)); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(COORDCLRTEXVERTEX)); /* Restore renderstates */ device->SetRenderState(D3DRS_CULLMODE, cull); device->SetRenderState(D3DRS_LIGHTING, lighting); /* Restore texture Matrix transform */ device->SetTransform(D3DTS_PROJECTION, &ptm); device->SetTransform(D3DTS_WORLD, &wtm); device->SetTransform(D3DTS_VIEW, &vtm); } JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_executeRasterDepth(JNIEnv *env, jobject obj, jlong ctx, jfloat posX, jfloat posY, jfloat posZ, jint srcOffsetX, jint srcOffsetY, jint rasterWidth, jint rasterHeight, jint depthWidth, jint depthHeight, jint depthFormat, jobject depthData) { void *depthObjPtr; D3DVERTEX worldCoord; D3DTLVERTEX screenCoord; int endx = srcOffsetX + rasterWidth; int endy = srcOffsetY + rasterHeight; GetDevice(); /* printf("*** Canvas3D.executeRasterDepth() ***\n"); */ // clipping if (srcOffsetX > depthWidth) { srcOffsetX = depthWidth; } else if (srcOffsetX < 0) { srcOffsetX = 0; } if (srcOffsetY > depthHeight) { srcOffsetY = depthHeight; } else if (srcOffsetY < 0) { srcOffsetY = 0; } if (endx > depthWidth) { endx = depthWidth; } else if (endx < 0) { endx = 0; } if (endy > depthHeight) { endy = depthHeight; } else if (endy < 0) { endy = 0; } int h = endy - srcOffsetY; int w = endx - srcOffsetX; // raster position is upper left corner, default for Java3D // ImageComponent currently has the data reverse in Y if ((h > 0) && (w > 0)) { worldCoord.x = posX; worldCoord.y = posY; worldCoord.z = posZ; d3dCtx->transform(&worldCoord, &screenCoord); if (d3dCtx->depthStencilSurface == NULL) { HRESULT hr = device->GetDepthStencilSurface(&d3dCtx->depthStencilSurface); if (FAILED(hr)) { if (debug) { printf("[Java3D] Fail to get depth stencil surface %s\n", DXGetErrorString9(hr)); } return; } } depthObjPtr = (void *) env->GetPrimitiveArrayCritical((jarray)depthData, NULL); if (depthFormat == javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_INT) { copyDepthToSurface(d3dCtx, device, (int)(screenCoord.sx), (int)(screenCoord.sy), srcOffsetX, srcOffsetY, w, h, depthWidth, depthHeight, (jint *)depthObjPtr, d3dCtx->depthStencilSurface); } else { // javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_FLOAT copyDepthToSurface(d3dCtx, device, (int)(screenCoord.sx), (int)(screenCoord.sy), srcOffsetX, srcOffsetY, w, h, depthWidth, depthHeight, (jfloat *)depthObjPtr, d3dCtx->depthStencilSurface); } env->ReleasePrimitiveArrayCritical((jarray)depthData, depthObjPtr, 0); } } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_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_NativePipeline_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_NativePipeline_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_NativePipeline_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_NativePipeline_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 (ITER_VOID p = freePointerList1.begin(); p != freePointerList1.end(); ++p) { delete (*p); } freePointerList1.clear(); unlockSurfaceList(); } useFreePointerList0 = false; } else { if (freePointerList0.size() > 0) { lockSurfaceList(); for (ITER_VOID p = freePointerList0.begin(); p != freePointerList0.end(); ++p) { delete (*p); } freePointerList0.clear(); unlockSurfaceList(); } useFreePointerList0 = true; } } extern "C" JNIEXPORT jint JNICALL Java_javax_media_j3d_NativePipeline_swapBuffers( JNIEnv *env, jobject obj, jobject cv, jlong ctx, jlong display, jlong window) { 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", DXGetErrorString9(hr)); } retCode = d3dCtx->resetSurface(env, cv); GetDevice2(); hr = device->Present(NULL, NULL, NULL, NULL); if (FAILED(hr)) { if (debug) { printf("Buffer swap error %s \n", DXGetErrorString9(hr)); } } } } d3dCtx->freeList(); freePointerList(); return retCode; } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_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_NativePipeline_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_NativePipeline_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_NativePipeline_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_NativePipeline_freeDisplayList( JNIEnv *env, jobject obj, 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_NativePipeline_freeTexture( JNIEnv *env, jobject obj, 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 jint JNICALL Java_javax_media_j3d_NativePipeline_getTextureUnitCount( JNIEnv *env, jobject obj, jlong ctx) { GetCtx2(); return d3dCtx->deviceInfo->maxTextureUnitStageSupport; } extern "C" JNIEXPORT jlong JNICALL Java_javax_media_j3d_NativePipeline_createOffScreenBuffer( JNIEnv *env, jobject obj, jobject cv, jlong ctx, jlong display, jlong fbConfigListPtr, jint width, jint height) { // Issue 396. // createContext() will be invoked later in Renderer return 1; } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_destroyContext( JNIEnv *env, jobject obj, jlong display, jlong window, jlong ctx) { GetDevice(); lock(); d3dCtxList.erase(find(d3dCtxList.begin(), d3dCtxList.end(), d3dCtx)); delete d3dCtx; unlock(); Java_javax_media_j3d_NativePipeline_cleanupRenderer(env, obj); } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_destroyOffScreenBuffer( JNIEnv *env, jobject obj, jobject cv, jlong ctx, jlong display, jlong fbConfigListPtr, jlong window) { // do nothing, since the old buffer will destory // in createOffScreenBuffer // TODO : this means that we will hold onto the last off-screen buffer; // we should clean this up at some point } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_readOffScreenBuffer( JNIEnv *env, jobject obj, jobject cv, jlong ctx, jint format, jint dataType, jobject data, jint width, jint height) { void *imageObjPtr; GetDevice(); if (format == IMAGE_FORMAT_USHORT_GRAY) { printf("[Java 3D] readOffScreenBuffer not support IMAGE_FORMAT_USHORT_GRAY\n"); return; } if (d3dCtx->backSurface == NULL) { HRESULT hr = device->GetBackBuffer(0,0, D3DBACKBUFFER_TYPE_MONO, //iSwapChain is 0 &d3dCtx->backSurface); if (FAILED(hr)) { printf("[Java 3D] GetBackBuffer fail %s\n", DXGetErrorString9(hr)); return; } } if((dataType == IMAGE_DATA_TYPE_BYTE_ARRAY) || (dataType == IMAGE_DATA_TYPE_INT_ARRAY)) { imageObjPtr = (void *)env->GetPrimitiveArrayCritical((jarray)data, NULL); } else { imageObjPtr = (void *)env->GetDirectBufferAddress(data); } copyDataFromSurface(format, 0, 0, width, height, (jbyte *)imageObjPtr, d3dCtx->backSurface); if((dataType == IMAGE_DATA_TYPE_BYTE_ARRAY) || (dataType == IMAGE_DATA_TYPE_INT_ARRAY)) { env->ReleasePrimitiveArrayCritical((jarray)data, imageObjPtr, 0); } return; } extern "C" JNIEXPORT jint JNICALL Java_javax_media_j3d_NativePipeline_resizeD3DCanvas( JNIEnv *env, jobject obj, jobject cv, jlong ctx) { int status; GetCtx2(); lock(); status = d3dCtx->resize(env, cv); unlock(); return status; } extern "C" JNIEXPORT jint JNICALL Java_javax_media_j3d_NativePipeline_toggleFullScreenMode( JNIEnv *env, jobject obj, jobject cv, jlong ctx) { int status; GetCtx2(); lock(); status = d3dCtx->toggleMode(!d3dCtx->bFullScreen, env, cv); unlock(); if (status == RECREATEDFAIL) { return RECREATEDDRAW; } return status; } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_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_NativePipeline_cleanupRenderer( 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_NativePipeline_beginScene( JNIEnv *env, jobject obj, jlong ctx) { GetDevice(); device->BeginScene(); } extern "C" JNIEXPORT void JNICALL Java_javax_media_j3d_NativePipeline_endScene( JNIEnv *env, jobject obj, jlong ctx) { GetDevice(); device->EndScene(); } extern "C" JNIEXPORT jboolean JNICALL Java_javax_media_j3d_NativePipeline_validGraphicsMode( JNIEnv *env, jobject obj) { DEVMODE devMode; EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode); return (devMode.dmBitsPerPel > 8); }